xref: /freebsd/sys/netinet6/in6_rmx.c (revision 9a00f6d06757fb180e55bc18b65430fef8527bb6)
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 
674684d3cbSAlexander V. Chernikov #include "opt_mpath.h"
684684d3cbSAlexander V. Chernikov 
6982cd038dSYoshinobu Inoue #include <sys/param.h>
7082cd038dSYoshinobu Inoue #include <sys/systm.h>
7182cd038dSYoshinobu Inoue #include <sys/kernel.h>
72609ff41fSWarner Losh #include <sys/lock.h>
7382cd038dSYoshinobu Inoue #include <sys/queue.h>
7482cd038dSYoshinobu Inoue #include <sys/socket.h>
7582cd038dSYoshinobu Inoue #include <sys/socketvar.h>
7682cd038dSYoshinobu Inoue #include <sys/mbuf.h>
773120b9d4SKip Macy #include <sys/rwlock.h>
7882cd038dSYoshinobu Inoue #include <sys/syslog.h>
79d1dd20beSSam Leffler #include <sys/callout.h>
8082cd038dSYoshinobu Inoue 
8182cd038dSYoshinobu Inoue #include <net/if.h>
8276039bc8SGleb Smirnoff #include <net/if_var.h>
830c88be04SBjoern A. Zeeb #include <net/route.h>
84da187ddbSAlexander V. Chernikov #include <net/route/route_ctl.h>
85e7d8af4fSAlexander V. Chernikov #include <net/route/route_var.h>
86a6663252SAlexander V. Chernikov #include <net/route/nhop.h>
87a6663252SAlexander V. Chernikov #include <net/route/shared.h>
884b79449eSBjoern A. Zeeb 
8982cd038dSYoshinobu Inoue #include <netinet/in.h>
9082cd038dSYoshinobu Inoue #include <netinet/ip_var.h>
9182cd038dSYoshinobu Inoue #include <netinet/in_var.h>
9282cd038dSYoshinobu Inoue 
93686cdd19SJun-ichiro itojun Hagino #include <netinet/ip6.h>
9482cd038dSYoshinobu Inoue #include <netinet6/ip6_var.h>
9582cd038dSYoshinobu Inoue 
96686cdd19SJun-ichiro itojun Hagino #include <netinet/icmp6.h>
9731b3783cSHajimu UMEMOTO #include <netinet6/nd6.h>
9882cd038dSYoshinobu Inoue 
9982cd038dSYoshinobu Inoue #include <netinet/tcp.h>
10082cd038dSYoshinobu Inoue #include <netinet/tcp_seq.h>
10182cd038dSYoshinobu Inoue #include <netinet/tcp_timer.h>
10282cd038dSYoshinobu Inoue #include <netinet/tcp_var.h>
10382cd038dSYoshinobu Inoue 
104ead85fe4SAlexander V. Chernikov extern int	in6_inithead(void **head, int off, u_int fibnum);
105bc29160dSMarko Zec #ifdef VIMAGE
106bc29160dSMarko Zec extern int	in6_detachhead(void **head, int off);
107bc29160dSMarko Zec #endif
10882cd038dSYoshinobu Inoue 
109a6663252SAlexander V. Chernikov static int
110a6663252SAlexander V. Chernikov rib6_preadd(u_int fibnum, const struct sockaddr *addr, const struct sockaddr *mask,
111a6663252SAlexander V. Chernikov     struct nhop_object *nh)
112a6663252SAlexander V. Chernikov {
113a6663252SAlexander V. Chernikov 	uint16_t nh_type;
114a6663252SAlexander V. Chernikov 
115a6663252SAlexander V. Chernikov 	/* XXX: RTF_LOCAL */
116a6663252SAlexander V. Chernikov 
117a6663252SAlexander V. Chernikov 	/*
118a6663252SAlexander V. Chernikov 	 * Check route MTU:
119a6663252SAlexander V. Chernikov 	 * inherit interface MTU if not set or
120a6663252SAlexander V. Chernikov 	 * check if MTU is too large.
121a6663252SAlexander V. Chernikov 	 */
122a6663252SAlexander V. Chernikov 	if (nh->nh_mtu == 0) {
123a6663252SAlexander V. Chernikov 		nh->nh_mtu = IN6_LINKMTU(nh->nh_ifp);
124a6663252SAlexander V. Chernikov 	} else if (nh->nh_mtu > IN6_LINKMTU(nh->nh_ifp))
125a6663252SAlexander V. Chernikov 		nh->nh_mtu = IN6_LINKMTU(nh->nh_ifp);
126a6663252SAlexander V. Chernikov 
127a6663252SAlexander V. Chernikov 	/* Ensure that default route nhop has special flag */
128a6663252SAlexander V. Chernikov 	const struct sockaddr_in6 *mask6 = (const struct sockaddr_in6 *)mask;
12967220860SAlexander V. Chernikov 	if ((nhop_get_rtflags(nh) & RTF_HOST) == 0 && mask6 != NULL &&
130a6663252SAlexander V. Chernikov 	    IN6_IS_ADDR_UNSPECIFIED(&mask6->sin6_addr))
131a6663252SAlexander V. Chernikov 		nh->nh_flags |= NHF_DEFAULT;
132a6663252SAlexander V. Chernikov 
133a6663252SAlexander V. Chernikov 	/* Set nexthop type */
134a6663252SAlexander V. Chernikov 	if (nhop_get_type(nh) == 0) {
135a6663252SAlexander V. Chernikov 		if (nh->nh_flags & NHF_GATEWAY)
136a6663252SAlexander V. Chernikov 			nh_type = NH_TYPE_IPV6_ETHER_NHOP;
137a6663252SAlexander V. Chernikov 		else
138a6663252SAlexander V. Chernikov 			nh_type = NH_TYPE_IPV6_ETHER_RSLV;
139a6663252SAlexander V. Chernikov 
140a6663252SAlexander V. Chernikov 		nhop_set_type(nh, nh_type);
141a6663252SAlexander V. Chernikov 	}
142a6663252SAlexander V. Chernikov 
143a6663252SAlexander V. Chernikov 	return (0);
144a6663252SAlexander V. Chernikov }
145a6663252SAlexander V. Chernikov 
14682cd038dSYoshinobu Inoue /*
14782cd038dSYoshinobu Inoue  * Initialize our routing tree.
14882cd038dSYoshinobu Inoue  */
14981d5d46bSBjoern A. Zeeb 
15082cd038dSYoshinobu Inoue int
151ead85fe4SAlexander V. Chernikov in6_inithead(void **head, int off, u_int fibnum)
15282cd038dSYoshinobu Inoue {
15361eee0e2SAlexander V. Chernikov 	struct rib_head *rh;
154*9a00f6d0SAlexander V. Chernikov 	struct rib_subscription *rs;
15582cd038dSYoshinobu Inoue 
156ead85fe4SAlexander V. Chernikov 	rh = rt_table_init(offsetof(struct sockaddr_in6, sin6_addr) << 3,
157ead85fe4SAlexander V. Chernikov 	    AF_INET6, fibnum);
15861eee0e2SAlexander V. Chernikov 	if (rh == NULL)
1599f25cbe4SAlexander V. Chernikov 		return (0);
16082cd038dSYoshinobu Inoue 
161a6663252SAlexander V. Chernikov 	rh->rnh_preadd = rib6_preadd;
1624684d3cbSAlexander V. Chernikov #ifdef	RADIX_MPATH
1634684d3cbSAlexander V. Chernikov 	rt_mpath_init_rnh(rh);
1644684d3cbSAlexander V. Chernikov #endif
16561eee0e2SAlexander V. Chernikov 	*head = (void *)rh;
16681d5d46bSBjoern A. Zeeb 
167*9a00f6d0SAlexander V. Chernikov 	rs = rib_subscribe(fibnum, AF_INET6, nd6_subscription_cb, NULL,
168*9a00f6d0SAlexander V. Chernikov 	    RIB_NOTIFY_IMMEDIATE, true);
169*9a00f6d0SAlexander V. Chernikov 	KASSERT(rs != NULL, ("Unable to subscribe to fib %u\n", fibnum));
1704c7ba83fSAlexander V. Chernikov 
1719f25cbe4SAlexander V. Chernikov 	return (1);
17282cd038dSYoshinobu Inoue }
173bc29160dSMarko Zec 
174bc29160dSMarko Zec #ifdef VIMAGE
175bc29160dSMarko Zec int
176bc29160dSMarko Zec in6_detachhead(void **head, int off)
177bc29160dSMarko Zec {
178bc29160dSMarko Zec 
179a5243af2SBjoern A. Zeeb 	rt_table_destroy((struct rib_head *)(*head));
180a5243af2SBjoern A. Zeeb 
181a5243af2SBjoern A. Zeeb 	return (1);
182bc29160dSMarko Zec }
183bc29160dSMarko Zec #endif
184db566a23SBjoern A. Zeeb 
185