1caf43b02SWarner Losh /*- 251369649SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 351369649SPedro F. Giffuni * 482cd038dSYoshinobu Inoue * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 582cd038dSYoshinobu Inoue * All rights reserved. 682cd038dSYoshinobu Inoue * 782cd038dSYoshinobu Inoue * Redistribution and use in source and binary forms, with or without 882cd038dSYoshinobu Inoue * modification, are permitted provided that the following conditions 982cd038dSYoshinobu Inoue * are met: 1082cd038dSYoshinobu Inoue * 1. Redistributions of source code must retain the above copyright 1182cd038dSYoshinobu Inoue * notice, this list of conditions and the following disclaimer. 1282cd038dSYoshinobu Inoue * 2. Redistributions in binary form must reproduce the above copyright 1382cd038dSYoshinobu Inoue * notice, this list of conditions and the following disclaimer in the 1482cd038dSYoshinobu Inoue * documentation and/or other materials provided with the distribution. 1582cd038dSYoshinobu Inoue * 3. Neither the name of the project nor the names of its contributors 1682cd038dSYoshinobu Inoue * may be used to endorse or promote products derived from this software 1782cd038dSYoshinobu Inoue * without specific prior written permission. 1882cd038dSYoshinobu Inoue * 1982cd038dSYoshinobu Inoue * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 2082cd038dSYoshinobu Inoue * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2182cd038dSYoshinobu Inoue * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2282cd038dSYoshinobu Inoue * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2382cd038dSYoshinobu Inoue * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2482cd038dSYoshinobu Inoue * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2582cd038dSYoshinobu Inoue * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2682cd038dSYoshinobu Inoue * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2782cd038dSYoshinobu Inoue * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2882cd038dSYoshinobu Inoue * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2982cd038dSYoshinobu Inoue * SUCH DAMAGE. 30b48287a3SDavid E. O'Brien * 31b48287a3SDavid E. O'Brien * $KAME: in6_rmx.c,v 1.11 2001/07/26 06:53:16 jinmei Exp $ 3282cd038dSYoshinobu Inoue */ 3382cd038dSYoshinobu Inoue 34caf43b02SWarner Losh /*- 3582cd038dSYoshinobu Inoue * Copyright 1994, 1995 Massachusetts Institute of Technology 3682cd038dSYoshinobu Inoue * 3782cd038dSYoshinobu Inoue * Permission to use, copy, modify, and distribute this software and 3882cd038dSYoshinobu Inoue * its documentation for any purpose and without fee is hereby 3982cd038dSYoshinobu Inoue * granted, provided that both the above copyright notice and this 4082cd038dSYoshinobu Inoue * permission notice appear in all copies, that both the above 4182cd038dSYoshinobu Inoue * copyright notice and this permission notice appear in all 4282cd038dSYoshinobu Inoue * supporting documentation, and that the name of M.I.T. not be used 4382cd038dSYoshinobu Inoue * in advertising or publicity pertaining to distribution of the 4482cd038dSYoshinobu Inoue * software without specific, written prior permission. M.I.T. makes 4582cd038dSYoshinobu Inoue * no representations about the suitability of this software for any 4682cd038dSYoshinobu Inoue * purpose. It is provided "as is" without express or implied 4782cd038dSYoshinobu Inoue * warranty. 4882cd038dSYoshinobu Inoue * 4982cd038dSYoshinobu Inoue * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS 5082cd038dSYoshinobu Inoue * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, 5182cd038dSYoshinobu Inoue * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 5282cd038dSYoshinobu Inoue * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT 5382cd038dSYoshinobu Inoue * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 5482cd038dSYoshinobu Inoue * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 5582cd038dSYoshinobu Inoue * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 5682cd038dSYoshinobu Inoue * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 5782cd038dSYoshinobu Inoue * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 5882cd038dSYoshinobu Inoue * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 5982cd038dSYoshinobu Inoue * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 6082cd038dSYoshinobu Inoue * SUCH DAMAGE. 6182cd038dSYoshinobu Inoue * 6282cd038dSYoshinobu Inoue */ 6382cd038dSYoshinobu Inoue 64b48287a3SDavid E. O'Brien #include <sys/cdefs.h> 65b48287a3SDavid E. O'Brien __FBSDID("$FreeBSD$"); 66b48287a3SDavid E. O'Brien 6782cd038dSYoshinobu Inoue #include <sys/param.h> 6882cd038dSYoshinobu Inoue #include <sys/systm.h> 6982cd038dSYoshinobu Inoue #include <sys/kernel.h> 70609ff41fSWarner Losh #include <sys/lock.h> 7182cd038dSYoshinobu Inoue #include <sys/queue.h> 7282cd038dSYoshinobu Inoue #include <sys/socket.h> 7382cd038dSYoshinobu Inoue #include <sys/socketvar.h> 7482cd038dSYoshinobu Inoue #include <sys/mbuf.h> 753120b9d4SKip Macy #include <sys/rwlock.h> 7682cd038dSYoshinobu Inoue #include <sys/syslog.h> 77d1dd20beSSam Leffler #include <sys/callout.h> 7882cd038dSYoshinobu Inoue 7982cd038dSYoshinobu Inoue #include <net/if.h> 8076039bc8SGleb Smirnoff #include <net/if_var.h> 810c88be04SBjoern A. Zeeb #include <net/route.h> 8261eee0e2SAlexander V. Chernikov #include <net/route_var.h> 834b79449eSBjoern A. Zeeb 8482cd038dSYoshinobu Inoue #include <netinet/in.h> 8582cd038dSYoshinobu Inoue #include <netinet/ip_var.h> 8682cd038dSYoshinobu Inoue #include <netinet/in_var.h> 8782cd038dSYoshinobu Inoue 88686cdd19SJun-ichiro itojun Hagino #include <netinet/ip6.h> 8982cd038dSYoshinobu Inoue #include <netinet6/ip6_var.h> 9082cd038dSYoshinobu Inoue 91686cdd19SJun-ichiro itojun Hagino #include <netinet/icmp6.h> 9231b3783cSHajimu UMEMOTO #include <netinet6/nd6.h> 9382cd038dSYoshinobu Inoue 9482cd038dSYoshinobu Inoue #include <netinet/tcp.h> 9582cd038dSYoshinobu Inoue #include <netinet/tcp_seq.h> 9682cd038dSYoshinobu Inoue #include <netinet/tcp_timer.h> 9782cd038dSYoshinobu Inoue #include <netinet/tcp_var.h> 9882cd038dSYoshinobu Inoue 99*ead85fe4SAlexander V. Chernikov extern int in6_inithead(void **head, int off, u_int fibnum); 100bc29160dSMarko Zec #ifdef VIMAGE 101bc29160dSMarko Zec extern int in6_detachhead(void **head, int off); 102bc29160dSMarko Zec #endif 10382cd038dSYoshinobu Inoue 10482cd038dSYoshinobu Inoue /* 10582cd038dSYoshinobu Inoue * Do what we need to do when inserting a route. 10682cd038dSYoshinobu Inoue */ 10782cd038dSYoshinobu Inoue static struct radix_node * 10861eee0e2SAlexander V. Chernikov in6_addroute(void *v_arg, void *n_arg, struct radix_head *head, 10982cd038dSYoshinobu Inoue struct radix_node *treenodes) 11082cd038dSYoshinobu Inoue { 11182cd038dSYoshinobu Inoue struct rtentry *rt = (struct rtentry *)treenodes; 11282cd038dSYoshinobu Inoue struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)rt_key(rt); 11382cd038dSYoshinobu Inoue 11482cd038dSYoshinobu Inoue if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) 11582cd038dSYoshinobu Inoue rt->rt_flags |= RTF_MULTICAST; 11682cd038dSYoshinobu Inoue 11782cd038dSYoshinobu Inoue /* 11882cd038dSYoshinobu Inoue * A little bit of help for both IPv6 output and input: 11982cd038dSYoshinobu Inoue * For local addresses, we make sure that RTF_LOCAL is set, 12082cd038dSYoshinobu Inoue * with the thought that this might one day be used to speed up 12182cd038dSYoshinobu Inoue * ip_input(). 12282cd038dSYoshinobu Inoue * 12382cd038dSYoshinobu Inoue * We also mark routes to multicast addresses as such, because 12482cd038dSYoshinobu Inoue * it's easy to do and might be useful (but this is much more 12582cd038dSYoshinobu Inoue * dubious since it's so easy to inspect the address). (This 12682cd038dSYoshinobu Inoue * is done above.) 12782cd038dSYoshinobu Inoue * 12882cd038dSYoshinobu Inoue * XXX 12982cd038dSYoshinobu Inoue * should elaborate the code. 13082cd038dSYoshinobu Inoue */ 13182cd038dSYoshinobu Inoue if (rt->rt_flags & RTF_HOST) { 13282cd038dSYoshinobu Inoue if (IN6_ARE_ADDR_EQUAL(&satosin6(rt->rt_ifa->ifa_addr) 13382cd038dSYoshinobu Inoue ->sin6_addr, 13482cd038dSYoshinobu Inoue &sin6->sin6_addr)) { 13582cd038dSYoshinobu Inoue rt->rt_flags |= RTF_LOCAL; 13682cd038dSYoshinobu Inoue } 13782cd038dSYoshinobu Inoue } 13882cd038dSYoshinobu Inoue 1391a75e3b2SAlexander V. Chernikov if (rt->rt_ifp != NULL) { 1401a75e3b2SAlexander V. Chernikov 1411a75e3b2SAlexander V. Chernikov /* 1421a75e3b2SAlexander V. Chernikov * Check route MTU: 1431a75e3b2SAlexander V. Chernikov * inherit interface MTU if not set or 1441a75e3b2SAlexander V. Chernikov * check if MTU is too large. 1451a75e3b2SAlexander V. Chernikov */ 1461a75e3b2SAlexander V. Chernikov if (rt->rt_mtu == 0) { 147e3a7aa6fSGleb Smirnoff rt->rt_mtu = IN6_LINKMTU(rt->rt_ifp); 1481a75e3b2SAlexander V. Chernikov } else if (rt->rt_mtu > IN6_LINKMTU(rt->rt_ifp)) 1491a75e3b2SAlexander V. Chernikov rt->rt_mtu = IN6_LINKMTU(rt->rt_ifp); 1501a75e3b2SAlexander V. Chernikov } 15182cd038dSYoshinobu Inoue 1525dba456cSAlexander V. Chernikov return (rn_addroute(v_arg, n_arg, head, treenodes)); 15382cd038dSYoshinobu Inoue } 15482cd038dSYoshinobu Inoue 15582cd038dSYoshinobu Inoue /* 15682cd038dSYoshinobu Inoue * Initialize our routing tree. 15782cd038dSYoshinobu Inoue */ 15881d5d46bSBjoern A. Zeeb 15982cd038dSYoshinobu Inoue int 160*ead85fe4SAlexander V. Chernikov in6_inithead(void **head, int off, u_int fibnum) 16182cd038dSYoshinobu Inoue { 16261eee0e2SAlexander V. Chernikov struct rib_head *rh; 16382cd038dSYoshinobu Inoue 164*ead85fe4SAlexander V. Chernikov rh = rt_table_init(offsetof(struct sockaddr_in6, sin6_addr) << 3, 165*ead85fe4SAlexander V. Chernikov AF_INET6, fibnum); 16661eee0e2SAlexander V. Chernikov if (rh == NULL) 1679f25cbe4SAlexander V. Chernikov return (0); 16882cd038dSYoshinobu Inoue 16961eee0e2SAlexander V. Chernikov rh->rnh_addaddr = in6_addroute; 17061eee0e2SAlexander V. Chernikov *head = (void *)rh; 17181d5d46bSBjoern A. Zeeb 1729f25cbe4SAlexander V. Chernikov return (1); 17382cd038dSYoshinobu Inoue } 174bc29160dSMarko Zec 175bc29160dSMarko Zec #ifdef VIMAGE 176bc29160dSMarko Zec int 177bc29160dSMarko Zec in6_detachhead(void **head, int off) 178bc29160dSMarko Zec { 179bc29160dSMarko Zec 180a5243af2SBjoern A. Zeeb rt_table_destroy((struct rib_head *)(*head)); 181a5243af2SBjoern A. Zeeb 182a5243af2SBjoern A. Zeeb return (1); 183bc29160dSMarko Zec } 184bc29160dSMarko Zec #endif 185db566a23SBjoern A. Zeeb 186db566a23SBjoern A. Zeeb /* 187db566a23SBjoern A. Zeeb * Extended API for IPv6 FIB support. 188db566a23SBjoern A. Zeeb */ 189db566a23SBjoern A. Zeeb void 190db566a23SBjoern A. Zeeb in6_rtredirect(struct sockaddr *dst, struct sockaddr *gw, struct sockaddr *nm, 191db566a23SBjoern A. Zeeb int flags, struct sockaddr *src, u_int fibnum) 192db566a23SBjoern A. Zeeb { 193db566a23SBjoern A. Zeeb 194db566a23SBjoern A. Zeeb rtredirect_fib(dst, gw, nm, flags, src, fibnum); 195db566a23SBjoern A. Zeeb } 196db566a23SBjoern A. Zeeb 197db566a23SBjoern A. Zeeb int 198db566a23SBjoern A. Zeeb in6_rtrequest(int req, struct sockaddr *dst, struct sockaddr *gw, 199db566a23SBjoern A. Zeeb struct sockaddr *mask, int flags, struct rtentry **ret_nrt, u_int fibnum) 200db566a23SBjoern A. Zeeb { 201db566a23SBjoern A. Zeeb 202db566a23SBjoern A. Zeeb return (rtrequest_fib(req, dst, gw, mask, flags, ret_nrt, fibnum)); 203db566a23SBjoern A. Zeeb } 204db566a23SBjoern A. Zeeb 205db566a23SBjoern A. Zeeb void 206db566a23SBjoern A. Zeeb in6_rtalloc(struct route_in6 *ro, u_int fibnum) 207db566a23SBjoern A. Zeeb { 208db566a23SBjoern A. Zeeb 209db566a23SBjoern A. Zeeb rtalloc_ign_fib((struct route *)ro, 0ul, fibnum); 210db566a23SBjoern A. Zeeb } 211db566a23SBjoern A. Zeeb 212db566a23SBjoern A. Zeeb void 213db566a23SBjoern A. Zeeb in6_rtalloc_ign(struct route_in6 *ro, u_long ignflags, u_int fibnum) 214db566a23SBjoern A. Zeeb { 215db566a23SBjoern A. Zeeb 216db566a23SBjoern A. Zeeb rtalloc_ign_fib((struct route *)ro, ignflags, fibnum); 217db566a23SBjoern A. Zeeb } 218db566a23SBjoern A. Zeeb 219db566a23SBjoern A. Zeeb struct rtentry * 220db566a23SBjoern A. Zeeb in6_rtalloc1(struct sockaddr *dst, int report, u_long ignflags, u_int fibnum) 221db566a23SBjoern A. Zeeb { 222db566a23SBjoern A. Zeeb 223db566a23SBjoern A. Zeeb return (rtalloc1_fib(dst, report, ignflags, fibnum)); 224db566a23SBjoern A. Zeeb } 225