xref: /freebsd/sys/netinet6/in6_rmx.c (revision ead85fe415dd32e47eb57744c4b214e33ef89938)
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