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