in6_src.c revision 243148
198943Sluigi/*- 298943Sluigi * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 398943Sluigi * All rights reserved. 498943Sluigi * 598943Sluigi * Redistribution and use in source and binary forms, with or without 698943Sluigi * modification, are permitted provided that the following conditions 798943Sluigi * are met: 898943Sluigi * 1. Redistributions of source code must retain the above copyright 9116763Sluigi * notice, this list of conditions and the following disclaimer. 1098943Sluigi * 2. Redistributions in binary form must reproduce the above copyright 1198943Sluigi * notice, this list of conditions and the following disclaimer in the 12105775Smaxim * documentation and/or other materials provided with the distribution. 1398943Sluigi * 3. Neither the name of the project nor the names of its contributors 1498943Sluigi * may be used to endorse or promote products derived from this software 1598943Sluigi * without specific prior written permission. 1698943Sluigi * 1798943Sluigi * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 1898943Sluigi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1998943Sluigi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2098943Sluigi * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2198943Sluigi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2298943Sluigi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2398943Sluigi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2498943Sluigi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2598943Sluigi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2698943Sluigi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2798943Sluigi * SUCH DAMAGE. 2898943Sluigi * 2998943Sluigi * $KAME: in6_src.c,v 1.132 2003/08/26 04:42:27 keiichi Exp $ 3098943Sluigi */ 3198943Sluigi 3299622Sluigi/*- 3398943Sluigi * Copyright (c) 1982, 1986, 1991, 1993 3498943Sluigi * The Regents of the University of California. All rights reserved. 3598943Sluigi * 3698943Sluigi * Redistribution and use in source and binary forms, with or without 3798943Sluigi * modification, are permitted provided that the following conditions 3898943Sluigi * are met: 3998943Sluigi * 1. Redistributions of source code must retain the above copyright 4098943Sluigi * notice, this list of conditions and the following disclaimer. 4198943Sluigi * 2. Redistributions in binary form must reproduce the above copyright 4298943Sluigi * notice, this list of conditions and the following disclaimer in the 4398943Sluigi * documentation and/or other materials provided with the distribution. 4498943Sluigi * 4. Neither the name of the University nor the names of its contributors 4599622Sluigi * may be used to endorse or promote products derived from this software 4699622Sluigi * without specific prior written permission. 4798943Sluigi * 4898943Sluigi * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 4998943Sluigi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 5098943Sluigi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 5198943Sluigi * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 5298943Sluigi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 5398943Sluigi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 5498943Sluigi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 5598943Sluigi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 5698943Sluigi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5798943Sluigi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5898943Sluigi * SUCH DAMAGE. 5998943Sluigi * 6098943Sluigi * @(#)in_pcb.c 8.2 (Berkeley) 1/4/94 6198943Sluigi */ 6298943Sluigi 6398943Sluigi#include <sys/cdefs.h> 6498943Sluigi__FBSDID("$FreeBSD: head/sys/netinet6/in6_src.c 243148 2012-11-16 12:12:02Z ae $"); 6598943Sluigi 6698943Sluigi#include "opt_inet.h" 6798943Sluigi#include "opt_inet6.h" 6898943Sluigi#include "opt_mpath.h" 6998943Sluigi 7098943Sluigi#include <sys/param.h> 7198943Sluigi#include <sys/systm.h> 7298943Sluigi#include <sys/lock.h> 7398943Sluigi#include <sys/malloc.h> 7498943Sluigi#include <sys/mbuf.h> 7598943Sluigi#include <sys/priv.h> 76117241Sluigi#include <sys/protosw.h> 77117241Sluigi#include <sys/socket.h> 78117241Sluigi#include <sys/socketvar.h> 79117241Sluigi#include <sys/sockio.h> 8098943Sluigi#include <sys/sysctl.h> 8198943Sluigi#include <sys/errno.h> 8299475Sluigi#include <sys/time.h> 8399475Sluigi#include <sys/jail.h> 84101628Sluigi#include <sys/kernel.h> 85122971Ssam#include <sys/sx.h> 86122971Ssam 87122971Ssam#include <net/if.h> 88122971Ssam#include <net/if_dl.h> 89122971Ssam#include <net/route.h> 90122971Ssam#include <net/if_llatbl.h> 91122971Ssam#ifdef RADIX_MPATH 92122971Ssam#include <net/radix_mpath.h> 93101978Sluigi#endif 94122971Ssam 95101978Sluigi#include <netinet/in.h> 96101978Sluigi#include <netinet/in_var.h> 97101628Sluigi#include <netinet/in_systm.h> 98101628Sluigi#include <netinet/ip.h> 99117654Sluigi#include <netinet/in_pcb.h> 100117654Sluigi#include <netinet/ip_var.h> 101101628Sluigi#include <netinet/udp.h> 102117654Sluigi#include <netinet/udp_var.h> 103101628Sluigi 104101628Sluigi#include <netinet6/in6_var.h> 105101628Sluigi#include <netinet/ip6.h> 10699622Sluigi#include <netinet6/in6_pcb.h> 10799622Sluigi#include <netinet6/ip6_var.h> 10898943Sluigi#include <netinet6/scope6_var.h> 109120141Ssam#include <netinet6/nd6.h> 11098943Sluigi 11198943Sluigistatic struct mtx addrsel_lock; 112120141Ssam#define ADDRSEL_LOCK_INIT() mtx_init(&addrsel_lock, "addrsel_lock", NULL, MTX_DEF) 113120141Ssam#define ADDRSEL_LOCK() mtx_lock(&addrsel_lock) 114120141Ssam#define ADDRSEL_UNLOCK() mtx_unlock(&addrsel_lock) 115120141Ssam#define ADDRSEL_LOCK_ASSERT() mtx_assert(&addrsel_lock, MA_OWNED) 116120141Ssam 117120141Ssamstatic struct sx addrsel_sxlock; 118120182Ssam#define ADDRSEL_SXLOCK_INIT() sx_init(&addrsel_sxlock, "addrsel_sxlock") 119120182Ssam#define ADDRSEL_SLOCK() sx_slock(&addrsel_sxlock) 120120141Ssam#define ADDRSEL_SUNLOCK() sx_sunlock(&addrsel_sxlock) 121120141Ssam#define ADDRSEL_XLOCK() sx_xlock(&addrsel_sxlock) 122120141Ssam#define ADDRSEL_XUNLOCK() sx_xunlock(&addrsel_sxlock) 123120141Ssam 124120141Ssam#define ADDR_LABEL_NOTAPP (-1) 12598943Sluigistatic VNET_DEFINE(struct in6_addrpolicy, defaultaddrpolicy); 12698943Sluigi#define V_defaultaddrpolicy VNET(defaultaddrpolicy) 12798943Sluigi 128120141SsamVNET_DEFINE(int, ip6_prefer_tempaddr) = 0; 12998943Sluigi 13098943Sluigistatic int selectroute(struct sockaddr_in6 *, struct ip6_pktopts *, 13198943Sluigi struct ip6_moptions *, struct route_in6 *, struct ifnet **, 13298943Sluigi struct rtentry **, int, u_int); 13398943Sluigistatic int in6_selectif(struct sockaddr_in6 *, struct ip6_pktopts *, 13498943Sluigi struct ip6_moptions *, struct route_in6 *ro, struct ifnet **, 13598943Sluigi struct ifnet *, u_int); 13698943Sluigi 137102397Scjcstatic struct in6_addrpolicy *lookup_addrsel_policy(struct sockaddr_in6 *); 138109246Sdillon 13998943Sluigistatic void init_policy_queue(void); 14098943Sluigistatic int add_addrsel_policyent(struct in6_addrpolicy *); 14198943Sluigistatic int delete_addrsel_policyent(struct in6_addrpolicy *); 142102397Scjcstatic int walk_addrsel_policy(int (*)(struct in6_addrpolicy *, void *), 143109246Sdillon void *); 144105775Smaximstatic int dump_addrsel_policyent(struct in6_addrpolicy *, void *); 14598943Sluigistatic struct in6_addrpolicy *match_addrsel_policy(struct sockaddr_in6 *); 146105775Smaxim 14798943Sluigi/* 148102397Scjc * Return an IPv6 address, which is the most appropriate for a given 149109246Sdillon * destination and user specified options. 15098943Sluigi * If necessary, this function lookups the routing table and returns 151105775Smaxim * an entry to the caller for later use. 15298943Sluigi */ 15398943Sluigi#define REPLACE(r) do {\ 15498943Sluigi if ((r) < sizeof(V_ip6stat.ip6s_sources_rule) / \ 15598943Sluigi sizeof(V_ip6stat.ip6s_sources_rule[0])) /* check for safety */ \ 15698943Sluigi V_ip6stat.ip6s_sources_rule[(r)]++; \ 15798943Sluigi /* { \ 15898943Sluigi char ip6buf[INET6_ADDRSTRLEN], ip6b[INET6_ADDRSTRLEN]; \ 15998943Sluigi printf("in6_selectsrc: replace %s with %s by %d\n", ia_best ? ip6_sprintf(ip6buf, &ia_best->ia_addr.sin6_addr) : "none", ip6_sprintf(ip6b, &ia->ia_addr.sin6_addr), (r)); \ 16098943Sluigi } */ \ 16198943Sluigi goto replace; \ 16298943Sluigi} while(0) 16398943Sluigi#define NEXT(r) do {\ 16498943Sluigi if ((r) < sizeof(V_ip6stat.ip6s_sources_rule) / \ 16598943Sluigi sizeof(V_ip6stat.ip6s_sources_rule[0])) /* check for safety */ \ 16698943Sluigi V_ip6stat.ip6s_sources_rule[(r)]++; \ 16798943Sluigi /* { \ 16898943Sluigi char ip6buf[INET6_ADDRSTRLEN], ip6b[INET6_ADDRSTRLEN]; \ 16998943Sluigi printf("in6_selectsrc: keep %s against %s by %d\n", ia_best ? ip6_sprintf(ip6buf, &ia_best->ia_addr.sin6_addr) : "none", ip6_sprintf(ip6b, &ia->ia_addr.sin6_addr), (r)); \ 17098943Sluigi } */ \ 17198943Sluigi goto next; /* XXX: we can't use 'continue' here */ \ 17298943Sluigi} while(0) 17398943Sluigi#define BREAK(r) do { \ 17498943Sluigi if ((r) < sizeof(V_ip6stat.ip6s_sources_rule) / \ 17598943Sluigi sizeof(V_ip6stat.ip6s_sources_rule[0])) /* check for safety */ \ 17698943Sluigi V_ip6stat.ip6s_sources_rule[(r)]++; \ 17798943Sluigi goto out; /* XXX: we can't use 'break' here */ \ 17898943Sluigi} while(0) 17998943Sluigi 18098943Sluigiint 18198943Sluigiin6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, 18298943Sluigi struct inpcb *inp, struct route_in6 *ro, struct ucred *cred, 18398943Sluigi struct ifnet **ifpp, struct in6_addr *srcp) 18498943Sluigi{ 18598943Sluigi struct in6_addr dst, tmp; 18698943Sluigi struct ifnet *ifp = NULL, *oifp = NULL; 18798943Sluigi struct in6_ifaddr *ia = NULL, *ia_best = NULL; 18898943Sluigi struct in6_pktinfo *pi = NULL; 18998943Sluigi int dst_scope = -1, best_scope = -1, best_matchlen = -1; 19098943Sluigi struct in6_addrpolicy *dst_policy = NULL, *best_policy = NULL; 19198943Sluigi u_int32_t odstzone; 19298943Sluigi int prefer_tempaddr; 19398943Sluigi int error; 194120141Ssam struct ip6_moptions *mopts; 195120141Ssam 196120141Ssam KASSERT(srcp != NULL, ("%s: srcp is NULL", __func__)); 197120141Ssam 198120141Ssam dst = dstsock->sin6_addr; /* make a copy for local operation */ 199120141Ssam if (ifpp) { 200120141Ssam /* 201120141Ssam * Save a possibly passed in ifp for in6_selectsrc. Only 20298943Sluigi * neighbor discovery code should use this feature, where 20398943Sluigi * we may know the interface but not the FIB number holding 20498943Sluigi * the connected subnet in case someone deleted it from the 20598943Sluigi * default FIB and we need to check the interface. 20698943Sluigi */ 20798943Sluigi if (*ifpp != NULL) 20898943Sluigi oifp = *ifpp; 20998943Sluigi *ifpp = NULL; 21098943Sluigi } 21198943Sluigi 212101978Sluigi if (inp != NULL) { 213101978Sluigi INP_LOCK_ASSERT(inp); 214101978Sluigi mopts = inp->in6p_moptions; 215101978Sluigi } else { 216101978Sluigi mopts = NULL; 217101978Sluigi } 218101978Sluigi 219105775Smaxim /* 220101978Sluigi * If the source address is explicitly specified by the caller, 221101978Sluigi * check if the requested source address is indeed a unicast address 222100004Sluigi * assigned to the node, and can be used as the packet's source 22398943Sluigi * address. If everything is okay, use the address as source. 22499622Sluigi */ 22599622Sluigi if (opts && (pi = opts->ip6po_pktinfo) && 22699622Sluigi !IN6_IS_ADDR_UNSPECIFIED(&pi->ipi6_addr)) { 227101978Sluigi struct sockaddr_in6 srcsock; 22898943Sluigi struct in6_ifaddr *ia6; 22998943Sluigi 23098943Sluigi /* get the outgoing interface */ 23198943Sluigi if ((error = in6_selectif(dstsock, opts, mopts, ro, &ifp, oifp, 23298943Sluigi (inp != NULL) ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB)) 23398943Sluigi != 0) 23498943Sluigi return (error); 23598943Sluigi 23698943Sluigi /* 23798943Sluigi * determine the appropriate zone id of the source based on 23898943Sluigi * the zone of the destination and the outgoing interface. 23998943Sluigi * If the specified address is ambiguous wrt the scope zone, 24098943Sluigi * the interface must be specified; otherwise, ifa_ifwithaddr() 24198943Sluigi * will fail matching the address. 24298943Sluigi */ 24398943Sluigi bzero(&srcsock, sizeof(srcsock)); 24498943Sluigi srcsock.sin6_family = AF_INET6; 24598943Sluigi srcsock.sin6_len = sizeof(srcsock); 24698943Sluigi srcsock.sin6_addr = pi->ipi6_addr; 24798943Sluigi if (ifp) { 24898943Sluigi error = in6_setscope(&srcsock.sin6_addr, ifp, NULL); 24998943Sluigi if (error) 25098943Sluigi return (error); 251100004Sluigi } 252100004Sluigi if (cred != NULL && (error = prison_local_ip6(cred, 25398943Sluigi &srcsock.sin6_addr, (inp != NULL && 25498943Sluigi (inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0) 25598943Sluigi return (error); 25698943Sluigi 25798943Sluigi ia6 = (struct in6_ifaddr *)ifa_ifwithaddr( 25898943Sluigi (struct sockaddr *)&srcsock); 25998943Sluigi if (ia6 == NULL || 26098943Sluigi (ia6->ia6_flags & (IN6_IFF_ANYCAST | IN6_IFF_NOTREADY))) { 26198943Sluigi if (ia6 != NULL) 26298943Sluigi ifa_free(&ia6->ia_ifa); 26398943Sluigi return (EADDRNOTAVAIL); 26498943Sluigi } 26598943Sluigi pi->ipi6_addr = srcsock.sin6_addr; /* XXX: this overrides pi */ 26699622Sluigi if (ifpp) 26798943Sluigi *ifpp = ifp; 26898943Sluigi bcopy(&ia6->ia_addr.sin6_addr, srcp, sizeof(*srcp)); 26998943Sluigi ifa_free(&ia6->ia_ifa); 27098943Sluigi return (0); 27198943Sluigi } 27298943Sluigi 27398943Sluigi /* 27498943Sluigi * Otherwise, if the socket has already bound the source, just use it. 27598943Sluigi */ 27698943Sluigi if (inp != NULL && !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) { 27798943Sluigi if (cred != NULL && 27898943Sluigi (error = prison_local_ip6(cred, &inp->in6p_laddr, 27998943Sluigi ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0) 28098943Sluigi return (error); 28198943Sluigi bcopy(&inp->in6p_laddr, srcp, sizeof(*srcp)); 28298943Sluigi return (0); 28398943Sluigi } 28498943Sluigi 28598943Sluigi /* 28698943Sluigi * Bypass source address selection and use the primary jail IP 28798943Sluigi * if requested. 28898943Sluigi */ 28998943Sluigi if (cred != NULL && !prison_saddrsel_ip6(cred, srcp)) 29098943Sluigi return (0); 29198943Sluigi 29298943Sluigi /* 29398943Sluigi * If the address is not specified, choose the best one based on 29498943Sluigi * the outgoing interface and the destination address. 29598943Sluigi */ 29698943Sluigi /* get the outgoing interface */ 29798943Sluigi if ((error = in6_selectif(dstsock, opts, mopts, ro, &ifp, oifp, 29898943Sluigi (inp != NULL) ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB)) != 0) 29998943Sluigi return (error); 30098943Sluigi 30198943Sluigi#ifdef DIAGNOSTIC 30298943Sluigi if (ifp == NULL) /* this should not happen */ 30398943Sluigi panic("in6_selectsrc: NULL ifp"); 30498943Sluigi#endif 30598943Sluigi error = in6_setscope(&dst, ifp, &odstzone); 30698943Sluigi if (error) 30798943Sluigi return (error); 30898943Sluigi 30998943Sluigi IN6_IFADDR_RLOCK(); 31098943Sluigi TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) { 31198943Sluigi int new_scope = -1, new_matchlen = -1; 31298943Sluigi struct in6_addrpolicy *new_policy = NULL; 31398943Sluigi u_int32_t srczone, osrczone, dstzone; 31498943Sluigi struct in6_addr src; 31598943Sluigi struct ifnet *ifp1 = ia->ia_ifp; 31698943Sluigi 31798943Sluigi /* 31898943Sluigi * We'll never take an address that breaks the scope zone 31998943Sluigi * of the destination. We also skip an address if its zone 32098943Sluigi * does not contain the outgoing interface. 32198943Sluigi * XXX: we should probably use sin6_scope_id here. 32298943Sluigi */ 32398943Sluigi if (in6_setscope(&dst, ifp1, &dstzone) || 32498943Sluigi odstzone != dstzone) { 32598943Sluigi continue; 32698943Sluigi } 32798943Sluigi src = ia->ia_addr.sin6_addr; 32898943Sluigi if (in6_setscope(&src, ifp, &osrczone) || 32998943Sluigi in6_setscope(&src, ifp1, &srczone) || 33098943Sluigi osrczone != srczone) { 33198943Sluigi continue; 33298943Sluigi } 33398943Sluigi 33498943Sluigi /* avoid unusable addresses */ 33598943Sluigi if ((ia->ia6_flags & 33698943Sluigi (IN6_IFF_NOTREADY | IN6_IFF_ANYCAST | IN6_IFF_DETACHED))) { 33798943Sluigi continue; 33898943Sluigi } 33998943Sluigi if (!V_ip6_use_deprecated && IFA6_IS_DEPRECATED(ia)) 34098943Sluigi continue; 34198943Sluigi 34298943Sluigi /* If jailed only take addresses of the jail into account. */ 34398943Sluigi if (cred != NULL && 34498943Sluigi prison_check_ip6(cred, &ia->ia_addr.sin6_addr) != 0) 34598943Sluigi continue; 34698943Sluigi 34798943Sluigi /* Rule 1: Prefer same address */ 34898943Sluigi if (IN6_ARE_ADDR_EQUAL(&dst, &ia->ia_addr.sin6_addr)) { 34998943Sluigi ia_best = ia; 35098943Sluigi BREAK(1); /* there should be no better candidate */ 35198943Sluigi } 35298943Sluigi 35398943Sluigi if (ia_best == NULL) 35498943Sluigi REPLACE(0); 35598943Sluigi 35698943Sluigi /* Rule 2: Prefer appropriate scope */ 35798943Sluigi if (dst_scope < 0) 35898943Sluigi dst_scope = in6_addrscope(&dst); 35998943Sluigi new_scope = in6_addrscope(&ia->ia_addr.sin6_addr); 36098943Sluigi if (IN6_ARE_SCOPE_CMP(best_scope, new_scope) < 0) { 36198943Sluigi if (IN6_ARE_SCOPE_CMP(best_scope, dst_scope) < 0) 36298943Sluigi REPLACE(2); 36398943Sluigi NEXT(2); 36498943Sluigi } else if (IN6_ARE_SCOPE_CMP(new_scope, best_scope) < 0) { 36598943Sluigi if (IN6_ARE_SCOPE_CMP(new_scope, dst_scope) < 0) 36698943Sluigi NEXT(2); 36798943Sluigi REPLACE(2); 36898943Sluigi } 36998943Sluigi 37098943Sluigi /* 37198943Sluigi * Rule 3: Avoid deprecated addresses. Note that the case of 37298943Sluigi * !ip6_use_deprecated is already rejected above. 37398943Sluigi */ 37498943Sluigi if (!IFA6_IS_DEPRECATED(ia_best) && IFA6_IS_DEPRECATED(ia)) 37598943Sluigi NEXT(3); 37698943Sluigi if (IFA6_IS_DEPRECATED(ia_best) && !IFA6_IS_DEPRECATED(ia)) 37798943Sluigi REPLACE(3); 37898943Sluigi 37998943Sluigi /* Rule 4: Prefer home addresses */ 38098943Sluigi /* 38198943Sluigi * XXX: This is a TODO. We should probably merge the MIP6 38298943Sluigi * case above. 38398943Sluigi */ 38498943Sluigi 38598943Sluigi /* Rule 5: Prefer outgoing interface */ 38698943Sluigi if (ia_best->ia_ifp == ifp && ia->ia_ifp != ifp) 38798943Sluigi NEXT(5); 38898943Sluigi if (ia_best->ia_ifp != ifp && ia->ia_ifp == ifp) 38998943Sluigi REPLACE(5); 39098943Sluigi 39198943Sluigi /* 39298943Sluigi * Rule 6: Prefer matching label 39398943Sluigi * Note that best_policy should be non-NULL here. 39498943Sluigi */ 39598943Sluigi if (dst_policy == NULL) 39698943Sluigi dst_policy = lookup_addrsel_policy(dstsock); 39798943Sluigi if (dst_policy->label != ADDR_LABEL_NOTAPP) { 39898943Sluigi new_policy = lookup_addrsel_policy(&ia->ia_addr); 39998943Sluigi if (dst_policy->label == best_policy->label && 40098943Sluigi dst_policy->label != new_policy->label) 40198943Sluigi NEXT(6); 40298943Sluigi if (dst_policy->label != best_policy->label && 40398943Sluigi dst_policy->label == new_policy->label) 40498943Sluigi REPLACE(6); 40598943Sluigi } 40698943Sluigi 40798943Sluigi /* 40898943Sluigi * Rule 7: Prefer public addresses. 40998943Sluigi * We allow users to reverse the logic by configuring 41098943Sluigi * a sysctl variable, so that privacy conscious users can 41198943Sluigi * always prefer temporary addresses. 41298943Sluigi */ 41399475Sluigi if (opts == NULL || 41498943Sluigi opts->ip6po_prefer_tempaddr == IP6PO_TEMPADDR_SYSTEM) { 415121816Sbrooks prefer_tempaddr = V_ip6_prefer_tempaddr; 416121816Sbrooks } else if (opts->ip6po_prefer_tempaddr == 417121816Sbrooks IP6PO_TEMPADDR_NOTPREFER) { 418121816Sbrooks prefer_tempaddr = 0; 419121816Sbrooks } else 420121816Sbrooks prefer_tempaddr = 1; 421121816Sbrooks if (!(ia_best->ia6_flags & IN6_IFF_TEMPORARY) && 42298943Sluigi (ia->ia6_flags & IN6_IFF_TEMPORARY)) { 42398943Sluigi if (prefer_tempaddr) 42498943Sluigi REPLACE(7); 425120141Ssam else 42698943Sluigi NEXT(7); 42798943Sluigi } 42898943Sluigi if ((ia_best->ia6_flags & IN6_IFF_TEMPORARY) && 42998943Sluigi !(ia->ia6_flags & IN6_IFF_TEMPORARY)) { 43098943Sluigi if (prefer_tempaddr) 43198943Sluigi NEXT(7); 43298943Sluigi else 43398943Sluigi REPLACE(7); 43498943Sluigi } 43598943Sluigi 43698943Sluigi /* 43798943Sluigi * Rule 8: prefer addresses on alive interfaces. 43898943Sluigi * This is a KAME specific rule. 439112250Scjc */ 440112250Scjc if ((ia_best->ia_ifp->if_flags & IFF_UP) && 441116763Sluigi !(ia->ia_ifp->if_flags & IFF_UP)) 442112250Scjc NEXT(8); 443112250Scjc if (!(ia_best->ia_ifp->if_flags & IFF_UP) && 444112250Scjc (ia->ia_ifp->if_flags & IFF_UP)) 445112250Scjc REPLACE(8); 446112250Scjc 447112250Scjc /* 448112250Scjc * Rule 14: Use longest matching prefix. 449112250Scjc * Note: in the address selection draft, this rule is 450112250Scjc * documented as "Rule 8". However, since it is also 451112250Scjc * documented that this rule can be overridden, we assign 452112250Scjc * a large number so that it is easy to assign smaller numbers 453112250Scjc * to more preferred rules. 454112250Scjc */ 455112250Scjc new_matchlen = in6_matchlen(&ia->ia_addr.sin6_addr, &dst); 456123000Sandre if (best_matchlen < new_matchlen) 457112250Scjc REPLACE(14); 458112250Scjc if (new_matchlen < best_matchlen) 459123000Sandre NEXT(14); 460123000Sandre 461112250Scjc /* Rule 15 is reserved. */ 462123000Sandre 463123000Sandre /* 464123000Sandre * Last resort: just keep the current candidate. 465123000Sandre * Or, do we need more rules? 466112250Scjc */ 467122922Sandre continue; 468112250Scjc 469122922Sandre replace: 470122922Sandre ia_best = ia; 471122922Sandre best_scope = (new_scope >= 0 ? new_scope : 472122922Sandre in6_addrscope(&ia_best->ia_addr.sin6_addr)); 473122922Sandre best_policy = (new_policy ? new_policy : 474116981Sluigi lookup_addrsel_policy(&ia_best->ia_addr)); 475112250Scjc best_matchlen = (new_matchlen >= 0 ? new_matchlen : 476112250Scjc in6_matchlen(&ia_best->ia_addr.sin6_addr, 477112250Scjc &dst)); 47898943Sluigi 47998943Sluigi next: 48098943Sluigi continue; 48199622Sluigi 482100004Sluigi out: 48398943Sluigi break; 48498943Sluigi } 48599622Sluigi 48698943Sluigi if ((ia = ia_best) == NULL) { 48798943Sluigi IN6_IFADDR_RUNLOCK(); 48898943Sluigi return (EADDRNOTAVAIL); 48998943Sluigi } 49098943Sluigi 49198943Sluigi /* 49298943Sluigi * At this point at least one of the addresses belonged to the jail 49399622Sluigi * but it could still be, that we want to further restrict it, e.g. 49498943Sluigi * theoratically IN6_IS_ADDR_LOOPBACK. 49598943Sluigi * It must not be IN6_IS_ADDR_UNSPECIFIED anymore. 49698943Sluigi * prison_local_ip6() will fix an IN6_IS_ADDR_LOOPBACK but should 49798943Sluigi * let all others previously selected pass. 49898943Sluigi * Use tmp to not change ::1 on lo0 to the primary jail address. 49998943Sluigi */ 50098943Sluigi tmp = ia->ia_addr.sin6_addr; 50198943Sluigi if (cred != NULL && prison_local_ip6(cred, &tmp, (inp != NULL && 50298943Sluigi (inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0) { 50398943Sluigi IN6_IFADDR_RUNLOCK(); 50498943Sluigi return (EADDRNOTAVAIL); 50598943Sluigi } 50698943Sluigi 50798943Sluigi if (ifpp) 50898943Sluigi *ifpp = ifp; 50998943Sluigi 51098943Sluigi bcopy(&tmp, srcp, sizeof(*srcp)); 51198943Sluigi IN6_IFADDR_RUNLOCK(); 51298943Sluigi return (0); 51398943Sluigi} 51498943Sluigi 51598943Sluigi/* 51698943Sluigi * clone - meaningful only for bsdi and freebsd 51798943Sluigi */ 51898943Sluigistatic int 51998943Sluigiselectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, 52098943Sluigi struct ip6_moptions *mopts, struct route_in6 *ro, 52198943Sluigi struct ifnet **retifp, struct rtentry **retrt, int norouteok, u_int fibnum) 52298943Sluigi{ 52399475Sluigi int error = 0; 52498943Sluigi struct ifnet *ifp = NULL; 52599475Sluigi struct rtentry *rt = NULL; 52699475Sluigi struct sockaddr_in6 *sin6_next; 52799475Sluigi struct in6_pktinfo *pi = NULL; 52899475Sluigi struct in6_addr *dst = &dstsock->sin6_addr; 52999475Sluigi#if 0 53099475Sluigi char ip6buf[INET6_ADDRSTRLEN]; 53199475Sluigi 53298943Sluigi if (dstsock->sin6_addr.s6_addr32[0] == 0 && 53399475Sluigi dstsock->sin6_addr.s6_addr32[1] == 0 && 53498943Sluigi !IN6_IS_ADDR_LOOPBACK(&dstsock->sin6_addr)) { 53598943Sluigi printf("in6_selectroute: strange destination %s\n", 53698943Sluigi ip6_sprintf(ip6buf, &dstsock->sin6_addr)); 53798943Sluigi } else { 53898943Sluigi printf("in6_selectroute: destination = %s%%%d\n", 53998943Sluigi ip6_sprintf(ip6buf, &dstsock->sin6_addr), 54098943Sluigi dstsock->sin6_scope_id); /* for debug */ 54198943Sluigi } 54298943Sluigi#endif 54398943Sluigi 54498943Sluigi /* If the caller specify the outgoing interface explicitly, use it. */ 54598943Sluigi if (opts && (pi = opts->ip6po_pktinfo) != NULL && pi->ipi6_ifindex) { 54698943Sluigi /* XXX boundary check is assumed to be already done. */ 54798943Sluigi ifp = ifnet_byindex(pi->ipi6_ifindex); 54898943Sluigi if (ifp != NULL && 54998943Sluigi (norouteok || retrt == NULL || 55098943Sluigi IN6_IS_ADDR_MULTICAST(dst))) { 55198943Sluigi /* 55298943Sluigi * we do not have to check or get the route for 55398943Sluigi * multicast. 55498943Sluigi */ 55598943Sluigi goto done; 55698943Sluigi } else 55798943Sluigi goto getroute; 55898943Sluigi } 55998943Sluigi 56098943Sluigi /* 56198943Sluigi * If the destination address is a multicast address and the outgoing 562100004Sluigi * interface for the address is specified by the caller, use it. 56398943Sluigi */ 564100004Sluigi if (IN6_IS_ADDR_MULTICAST(dst) && 565100004Sluigi mopts != NULL && (ifp = mopts->im6o_multicast_ifp) != NULL) { 56698943Sluigi goto done; /* we do not need a route for multicast. */ 567100004Sluigi } 568107897Smaxim 56998943Sluigi getroute: 57098943Sluigi /* 571105775Smaxim * If the next hop address for the packet is specified by the caller, 57298943Sluigi * use it as the gateway. 57398943Sluigi */ 57498943Sluigi if (opts && opts->ip6po_nexthop) { 57598943Sluigi struct route_in6 *ron; 57698943Sluigi struct llentry *la; 57798943Sluigi 57898943Sluigi sin6_next = satosin6(opts->ip6po_nexthop); 57998943Sluigi 58098943Sluigi /* at this moment, we only support AF_INET6 next hops */ 58198943Sluigi if (sin6_next->sin6_family != AF_INET6) { 58298943Sluigi error = EAFNOSUPPORT; /* or should we proceed? */ 58398943Sluigi goto done; 58498943Sluigi } 58598943Sluigi 58698943Sluigi /* 58798943Sluigi * If the next hop is an IPv6 address, then the node identified 58898943Sluigi * by that address must be a neighbor of the sending host. 58998943Sluigi */ 59098943Sluigi ron = &opts->ip6po_nextroute; 59198943Sluigi /* 59298943Sluigi * XXX what do we do here? 59398943Sluigi * PLZ to be fixing 59498943Sluigi */ 59598943Sluigi 59698943Sluigi 59798943Sluigi if (ron->ro_rt == NULL) { 59898943Sluigi in6_rtalloc(ron, fibnum); /* multi path case? */ 59998943Sluigi if (ron->ro_rt == NULL) { 60098943Sluigi /* XXX-BZ WT.? */ 60198943Sluigi if (ron->ro_rt) { 60298943Sluigi RTFREE(ron->ro_rt); 603100004Sluigi ron->ro_rt = NULL; 604100004Sluigi } 605100004Sluigi error = EHOSTUNREACH; 606100004Sluigi goto done; 60798943Sluigi } 608100004Sluigi } 609100004Sluigi 61098943Sluigi rt = ron->ro_rt; 61198943Sluigi ifp = rt->rt_ifp; 61298943Sluigi IF_AFDATA_RLOCK(ifp); 61398943Sluigi la = lla_lookup(LLTABLE6(ifp), 0, (struct sockaddr *)&sin6_next->sin6_addr); 61498943Sluigi IF_AFDATA_RUNLOCK(ifp); 61598943Sluigi if (la != NULL) 616100004Sluigi LLE_RUNLOCK(la); 617100004Sluigi else { 618100004Sluigi error = EHOSTUNREACH; 619100004Sluigi goto done; 62098943Sluigi } 621100004Sluigi#if 0 622100004Sluigi if ((ron->ro_rt && 62398943Sluigi (ron->ro_rt->rt_flags & (RTF_UP | RTF_LLINFO)) != 62498943Sluigi (RTF_UP | RTF_LLINFO)) || 62598943Sluigi !IN6_ARE_ADDR_EQUAL(&satosin6(&ron->ro_dst)->sin6_addr, 62698943Sluigi &sin6_next->sin6_addr)) { 62798943Sluigi if (ron->ro_rt) { 62898943Sluigi RTFREE(ron->ro_rt); 62998943Sluigi ron->ro_rt = NULL; 63098943Sluigi } 63198943Sluigi *satosin6(&ron->ro_dst) = *sin6_next; 63298943Sluigi } 63398943Sluigi if (ron->ro_rt == NULL) { 63498943Sluigi in6_rtalloc(ron, fibnum); /* multi path case? */ 63598943Sluigi if (ron->ro_rt == NULL || 63698943Sluigi !(ron->ro_rt->rt_flags & RTF_LLINFO)) { 63798943Sluigi if (ron->ro_rt) { 63898943Sluigi RTFREE(ron->ro_rt); 63998943Sluigi ron->ro_rt = NULL; 64098943Sluigi } 64198943Sluigi error = EHOSTUNREACH; 64298943Sluigi goto done; 64398943Sluigi } 64498943Sluigi } 64598943Sluigi#endif 64698943Sluigi 64798943Sluigi /* 64898943Sluigi * When cloning is required, try to allocate a route to the 64998943Sluigi * destination so that the caller can store path MTU 65098943Sluigi * information. 65198943Sluigi */ 65298943Sluigi goto done; 65398943Sluigi } 654121816Sbrooks 65598943Sluigi /* 65698943Sluigi * Use a cached route if it exists and is valid, else try to allocate 657121816Sbrooks * a new one. Note that we should check the address family of the 65898943Sluigi * cached destination, in case of sharing the cache with IPv4. 65998943Sluigi */ 66098943Sluigi if (ro) { 66198943Sluigi if (ro->ro_rt && 66298943Sluigi (!(ro->ro_rt->rt_flags & RTF_UP) || 66398943Sluigi ((struct sockaddr *)(&ro->ro_dst))->sa_family != AF_INET6 || 66498943Sluigi !IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr, 66598943Sluigi dst))) { 66698943Sluigi RTFREE(ro->ro_rt); 66798943Sluigi ro->ro_rt = (struct rtentry *)NULL; 66898943Sluigi } 66998943Sluigi if (ro->ro_rt == (struct rtentry *)NULL) { 67098943Sluigi struct sockaddr_in6 *sa6; 67198943Sluigi 67299475Sluigi /* No route yet, so try to acquire one */ 67398943Sluigi bzero(&ro->ro_dst, sizeof(struct sockaddr_in6)); 67498943Sluigi sa6 = (struct sockaddr_in6 *)&ro->ro_dst; 67598943Sluigi *sa6 = *dstsock; 67698943Sluigi sa6->sin6_scope_id = 0; 67798943Sluigi 67898943Sluigi#ifdef RADIX_MPATH 67998943Sluigi rtalloc_mpath_fib((struct route *)ro, 68098943Sluigi ntohl(sa6->sin6_addr.s6_addr32[3]), fibnum); 68198943Sluigi#else 68298943Sluigi ro->ro_rt = in6_rtalloc1((struct sockaddr *) 68398943Sluigi &ro->ro_dst, 0, 0UL, fibnum); 68498943Sluigi if (ro->ro_rt) 68598943Sluigi RT_UNLOCK(ro->ro_rt); 68698943Sluigi#endif 68798943Sluigi } 68898943Sluigi 68998943Sluigi /* 69098943Sluigi * do not care about the result if we have the nexthop 69198943Sluigi * explicitly specified. 69298943Sluigi */ 69398943Sluigi if (opts && opts->ip6po_nexthop) 69498943Sluigi goto done; 69598943Sluigi 69698943Sluigi if (ro->ro_rt) { 697108258Smaxim ifp = ro->ro_rt->rt_ifp; 69898943Sluigi 69998943Sluigi if (ifp == NULL) { /* can this really happen? */ 70098943Sluigi RTFREE(ro->ro_rt); 70198943Sluigi ro->ro_rt = NULL; 70298943Sluigi } 70398943Sluigi } 70498943Sluigi if (ro->ro_rt == NULL) 70598943Sluigi error = EHOSTUNREACH; 70698943Sluigi rt = ro->ro_rt; 70798943Sluigi 70898943Sluigi /* 70998943Sluigi * Check if the outgoing interface conflicts with 71098943Sluigi * the interface specified by ipi6_ifindex (if specified). 71198943Sluigi * Note that loopback interface is always okay. 71298943Sluigi * (this may happen when we are sending a packet to one of 71398943Sluigi * our own addresses.) 71498943Sluigi */ 71598943Sluigi if (ifp && opts && opts->ip6po_pktinfo && 71698943Sluigi opts->ip6po_pktinfo->ipi6_ifindex) { 71798943Sluigi if (!(ifp->if_flags & IFF_LOOPBACK) && 71898943Sluigi ifp->if_index != 71998943Sluigi opts->ip6po_pktinfo->ipi6_ifindex) { 72098943Sluigi error = EHOSTUNREACH; 72198943Sluigi goto done; 72298943Sluigi } 72398943Sluigi } 72498943Sluigi } 72598943Sluigi 72698943Sluigi done: 72798943Sluigi if (ifp == NULL && rt == NULL) { 72898943Sluigi /* 72998943Sluigi * This can happen if the caller did not pass a cached route 73098943Sluigi * nor any other hints. We treat this case an error. 731120141Ssam */ 732120141Ssam error = EHOSTUNREACH; 73398943Sluigi } 73498943Sluigi if (error == EHOSTUNREACH) 73598943Sluigi V_ip6stat.ip6s_noroute++; 73698943Sluigi 73798943Sluigi if (retifp != NULL) { 73898943Sluigi *retifp = ifp; 73998943Sluigi 74098943Sluigi /* 74198943Sluigi * Adjust the "outgoing" interface. If we're going to loop 74298943Sluigi * the packet back to ourselves, the ifp would be the loopback 74398943Sluigi * interface. However, we'd rather know the interface associated 74498943Sluigi * to the destination address (which should probably be one of 74598943Sluigi * our own addresses.) 74698943Sluigi */ 74798943Sluigi if (rt) { 74898943Sluigi if ((rt->rt_ifp->if_flags & IFF_LOOPBACK) && 74998943Sluigi (rt->rt_gateway->sa_family == AF_LINK)) 75098943Sluigi *retifp = 75198943Sluigi ifnet_byindex(((struct sockaddr_dl *) 75298943Sluigi rt->rt_gateway)->sdl_index); 75398943Sluigi } 75498943Sluigi } 75598943Sluigi 75698943Sluigi if (retrt != NULL) 75798943Sluigi *retrt = rt; /* rt may be NULL */ 75898943Sluigi 75998943Sluigi return (error); 76098943Sluigi} 76198943Sluigi 76298943Sluigistatic int 76398943Sluigiin6_selectif(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, 76498943Sluigi struct ip6_moptions *mopts, struct route_in6 *ro, struct ifnet **retifp, 765108258Smaxim struct ifnet *oifp, u_int fibnum) 76698943Sluigi{ 76798943Sluigi int error; 76898943Sluigi struct route_in6 sro; 76998943Sluigi struct rtentry *rt = NULL; 77098943Sluigi 77198943Sluigi KASSERT(retifp != NULL, ("%s: retifp is NULL", __func__)); 77298943Sluigi 773121123Smckusick if (ro == NULL) { 774121123Smckusick bzero(&sro, sizeof(sro)); 775121123Smckusick ro = &sro; 776121123Smckusick } 77798943Sluigi 77898943Sluigi if ((error = selectroute(dstsock, opts, mopts, ro, retifp, 77998943Sluigi &rt, 1, fibnum)) != 0) { 78098943Sluigi if (ro == &sro && rt && rt == sro.ro_rt) 78198943Sluigi RTFREE(rt); 78298943Sluigi /* Help ND. See oifp comment in in6_selectsrc(). */ 78398943Sluigi if (oifp != NULL && fibnum == RT_DEFAULT_FIB) { 78498943Sluigi *retifp = oifp; 78598943Sluigi error = 0; 78698943Sluigi } 78798943Sluigi return (error); 78898943Sluigi } 78998943Sluigi 79098943Sluigi /* 791120141Ssam * do not use a rejected or black hole route. 792100004Sluigi * XXX: this check should be done in the L2 output routine. 79398943Sluigi * However, if we skipped this check here, we'd see the following 79498943Sluigi * scenario: 79598943Sluigi * - install a rejected route for a scoped address prefix 79698943Sluigi * (like fe80::/10) 79798943Sluigi * - send a packet to a destination that matches the scoped prefix, 79898943Sluigi * with ambiguity about the scope zone. 79998943Sluigi * - pick the outgoing interface from the route, and disambiguate the 80098943Sluigi * scope zone with the interface. 80198943Sluigi * - ip6_output() would try to get another route with the "new" 80298943Sluigi * destination, which may be valid. 80398943Sluigi * - we'd see no error on output. 80498943Sluigi * Although this may not be very harmful, it should still be confusing. 805120141Ssam * We thus reject the case here. 806120141Ssam */ 80798943Sluigi if (rt && (rt->rt_flags & (RTF_REJECT | RTF_BLACKHOLE))) { 80898943Sluigi int flags = (rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); 80998943Sluigi 81098943Sluigi if (ro == &sro && rt && rt == sro.ro_rt) 811121123Smckusick RTFREE(rt); 81298943Sluigi return (flags); 81398943Sluigi } 81498943Sluigi 81598943Sluigi if (ro == &sro && rt && rt == sro.ro_rt) 81698943Sluigi RTFREE(rt); 817121123Smckusick return (0); 818121123Smckusick} 81998943Sluigi 82098943Sluigi/* 82198943Sluigi * Public wrapper function to selectroute(). 82298943Sluigi * 82398943Sluigi * XXX-BZ in6_selectroute() should and will grow the FIB argument. The 82498943Sluigi * in6_selectroute_fib() function is only there for backward compat on stable. 82598943Sluigi */ 82698943Sluigiint 82798943Sluigiin6_selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, 82898943Sluigi struct ip6_moptions *mopts, struct route_in6 *ro, 82998943Sluigi struct ifnet **retifp, struct rtentry **retrt) 83098943Sluigi{ 83198943Sluigi 83298943Sluigi return (selectroute(dstsock, opts, mopts, ro, retifp, 83398943Sluigi retrt, 0, RT_DEFAULT_FIB)); 83498943Sluigi} 83598943Sluigi 83698943Sluigi#ifndef BURN_BRIDGES 83798943Sluigiint 83898943Sluigiin6_selectroute_fib(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, 83998943Sluigi struct ip6_moptions *mopts, struct route_in6 *ro, 84098943Sluigi struct ifnet **retifp, struct rtentry **retrt, u_int fibnum) 84198943Sluigi{ 84298943Sluigi 84398943Sluigi return (selectroute(dstsock, opts, mopts, ro, retifp, 84498943Sluigi retrt, 0, fibnum)); 84598943Sluigi} 84698943Sluigi#endif 84798943Sluigi 84898943Sluigi/* 84998943Sluigi * Default hop limit selection. The precedence is as follows: 85098943Sluigi * 1. Hoplimit value specified via ioctl. 85198943Sluigi * 2. (If the outgoing interface is detected) the current 85298943Sluigi * hop limit of the interface specified by router advertisement. 85398943Sluigi * 3. The system default hoplimit. 85498943Sluigi */ 85598943Sluigiint 856101978Sluigiin6_selecthlim(struct inpcb *in6p, struct ifnet *ifp) 85798943Sluigi{ 85898943Sluigi 85998943Sluigi if (in6p && in6p->in6p_hops >= 0) 860100004Sluigi return (in6p->in6p_hops); 861100004Sluigi else if (ifp) 862100004Sluigi return (ND_IFINFO(ifp)->chlim); 863100004Sluigi else if (in6p && !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) { 864100004Sluigi struct route_in6 ro6; 865100004Sluigi struct ifnet *lifp; 866100004Sluigi 867100004Sluigi bzero(&ro6, sizeof(ro6)); 868100004Sluigi ro6.ro_dst.sin6_family = AF_INET6; 869100004Sluigi ro6.ro_dst.sin6_len = sizeof(struct sockaddr_in6); 870100004Sluigi ro6.ro_dst.sin6_addr = in6p->in6p_faddr; 871100004Sluigi in6_rtalloc(&ro6, in6p->inp_inc.inc_fibnum); 872100004Sluigi if (ro6.ro_rt) { 873100004Sluigi lifp = ro6.ro_rt->rt_ifp; 874100004Sluigi RTFREE(ro6.ro_rt); 875100004Sluigi if (lifp) 876100004Sluigi return (ND_IFINFO(lifp)->chlim); 87798943Sluigi } 87898943Sluigi } 879101978Sluigi return (V_ip6_defhlim); 88098943Sluigi} 881101978Sluigi 882101978Sluigi/* 88398943Sluigi * XXX: this is borrowed from in6_pcbbind(). If possible, we should 88498943Sluigi * share this function by all *bsd*... 885101978Sluigi */ 88698943Sluigiint 88798943Sluigiin6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred) 88898943Sluigi{ 88998943Sluigi struct socket *so = inp->inp_socket; 89098943Sluigi u_int16_t lport = 0; 89198943Sluigi int error, lookupflags = 0; 89298943Sluigi#ifdef INVARIANTS 89398943Sluigi struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; 89498943Sluigi#endif 895101978Sluigi 896101978Sluigi INP_WLOCK_ASSERT(inp); 89798943Sluigi INP_HASH_WLOCK_ASSERT(pcbinfo); 89898943Sluigi 89998943Sluigi error = prison_local_ip6(cred, laddr, 90098943Sluigi ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)); 90198943Sluigi if (error) 90298943Sluigi return(error); 90398943Sluigi 90498943Sluigi /* XXX: this is redundant when called from in6_pcbbind */ 90598943Sluigi if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0) 90698943Sluigi lookupflags = INPLOOKUP_WILDCARD; 90798943Sluigi 90898943Sluigi inp->inp_flags |= INP_ANONPORT; 90998943Sluigi 91098943Sluigi error = in_pcb_lport(inp, NULL, &lport, cred, lookupflags); 91198943Sluigi if (error != 0) 912120141Ssam return (error); 913120141Ssam 914120141Ssam inp->inp_lport = lport; 915120141Ssam if (in_pcbinshash(inp) != 0) { 916120141Ssam inp->in6p_laddr = in6addr_any; 917120141Ssam inp->inp_lport = 0; 918120141Ssam return (EAGAIN); 919120141Ssam } 920120141Ssam 921120141Ssam return (0); 922120141Ssam} 923120141Ssam 924120141Ssamvoid 925120141Ssamaddrsel_policy_init(void) 92698943Sluigi{ 92798943Sluigi 92898943Sluigi init_policy_queue(); 929120141Ssam 930120141Ssam /* initialize the "last resort" policy */ 931101978Sluigi bzero(&V_defaultaddrpolicy, sizeof(V_defaultaddrpolicy)); 932101978Sluigi V_defaultaddrpolicy.label = ADDR_LABEL_NOTAPP; 933101978Sluigi 934101978Sluigi if (!IS_DEFAULT_VNET(curvnet)) 935101978Sluigi return; 93698943Sluigi 937101978Sluigi ADDRSEL_LOCK_INIT(); 938101978Sluigi ADDRSEL_SXLOCK_INIT(); 93998943Sluigi} 94098943Sluigi 94198943Sluigistatic struct in6_addrpolicy * 94298943Sluigilookup_addrsel_policy(struct sockaddr_in6 *key) 94398943Sluigi{ 94498943Sluigi struct in6_addrpolicy *match = NULL; 94598943Sluigi 946101978Sluigi ADDRSEL_LOCK(); 947101978Sluigi match = match_addrsel_policy(key); 948105440Smux 949101978Sluigi if (match == NULL) 950101978Sluigi match = &V_defaultaddrpolicy; 951101978Sluigi else 952101978Sluigi match->use++; 95398943Sluigi ADDRSEL_UNLOCK(); 95498943Sluigi 95598943Sluigi return (match); 95698943Sluigi} 95798943Sluigi 95898943Sluigi/* 95998943Sluigi * Subroutines to manage the address selection policy table via sysctl. 96098943Sluigi */ 96198943Sluigistruct walkarg { 96298943Sluigi struct sysctl_req *w_req; 96398943Sluigi}; 96498943Sluigi 96598943Sluigistatic int in6_src_sysctl(SYSCTL_HANDLER_ARGS); 96698943SluigiSYSCTL_DECL(_net_inet6_ip6); 96798943Sluigistatic SYSCTL_NODE(_net_inet6_ip6, IPV6CTL_ADDRCTLPOLICY, addrctlpolicy, 96898943Sluigi CTLFLAG_RD, in6_src_sysctl, ""); 96998943Sluigi 97098943Sluigistatic int 971120141Ssamin6_src_sysctl(SYSCTL_HANDLER_ARGS) 972120141Ssam{ 97398943Sluigi struct walkarg w; 97498943Sluigi 97598943Sluigi if (req->newptr) 97698943Sluigi return EPERM; 97798943Sluigi 97898943Sluigi bzero(&w, sizeof(w)); 97998943Sluigi w.w_req = req; 98098943Sluigi 981105440Smux return (walk_addrsel_policy(dump_addrsel_policyent, &w)); 98298943Sluigi} 983108258Smaxim 98498943Sluigiint 98598943Sluigiin6_src_ioctl(u_long cmd, caddr_t data) 98698943Sluigi{ 98798943Sluigi int i; 98898943Sluigi struct in6_addrpolicy ent0; 98998943Sluigi 99098943Sluigi if (cmd != SIOCAADDRCTL_POLICY && cmd != SIOCDADDRCTL_POLICY) 99198943Sluigi return (EOPNOTSUPP); /* check for safety */ 99298943Sluigi 99398943Sluigi ent0 = *(struct in6_addrpolicy *)data; 99498943Sluigi 99598943Sluigi if (ent0.label == ADDR_LABEL_NOTAPP) 99698943Sluigi return (EINVAL); 99798943Sluigi /* check if the prefix mask is consecutive. */ 99898943Sluigi if (in6_mask2len(&ent0.addrmask.sin6_addr, NULL) < 0) 99998943Sluigi return (EINVAL); 100098943Sluigi /* clear trailing garbages (if any) of the prefix address. */ 100198943Sluigi for (i = 0; i < 4; i++) { 100298943Sluigi ent0.addr.sin6_addr.s6_addr32[i] &= 100398943Sluigi ent0.addrmask.sin6_addr.s6_addr32[i]; 100498943Sluigi } 100598943Sluigi ent0.use = 0; 100698943Sluigi 100798943Sluigi switch (cmd) { 1008108258Smaxim case SIOCAADDRCTL_POLICY: 100998943Sluigi return (add_addrsel_policyent(&ent0)); 101098943Sluigi case SIOCDADDRCTL_POLICY: 101198943Sluigi return (delete_addrsel_policyent(&ent0)); 101298943Sluigi } 101398943Sluigi 101498943Sluigi return (0); /* XXX: compromise compilers */ 101598943Sluigi} 101698943Sluigi 101798943Sluigi/* 101898943Sluigi * The followings are implementation of the policy table using a 101998943Sluigi * simple tail queue. 102098943Sluigi * XXX such details should be hidden. 102198943Sluigi * XXX implementation using binary tree should be more efficient. 102298943Sluigi */ 102398943Sluigistruct addrsel_policyent { 102498943Sluigi TAILQ_ENTRY(addrsel_policyent) ape_entry; 102598943Sluigi struct in6_addrpolicy ape_policy; 1026120141Ssam}; 1027120141Ssam 102898943SluigiTAILQ_HEAD(addrsel_policyhead, addrsel_policyent); 102998943Sluigi 103098943Sluigistatic VNET_DEFINE(struct addrsel_policyhead, addrsel_policytab); 103198943Sluigi#define V_addrsel_policytab VNET(addrsel_policytab) 103298943Sluigi 103398943Sluigistatic void 103498943Sluigiinit_policy_queue(void) 103598943Sluigi{ 103698943Sluigi 103798943Sluigi TAILQ_INIT(&V_addrsel_policytab); 103898943Sluigi} 1039108258Smaxim 104098943Sluigistatic int 104198943Sluigiadd_addrsel_policyent(struct in6_addrpolicy *newpolicy) 104298943Sluigi{ 104398943Sluigi struct addrsel_policyent *new, *pol; 104498943Sluigi 104598943Sluigi new = malloc(sizeof(*new), M_IFADDR, 104698943Sluigi M_WAITOK); 104798943Sluigi ADDRSEL_XLOCK(); 104898943Sluigi ADDRSEL_LOCK(); 104998943Sluigi 105098943Sluigi /* duplication check */ 105198943Sluigi TAILQ_FOREACH(pol, &V_addrsel_policytab, ape_entry) { 105298943Sluigi if (IN6_ARE_ADDR_EQUAL(&newpolicy->addr.sin6_addr, 105398943Sluigi &pol->ape_policy.addr.sin6_addr) && 105498943Sluigi IN6_ARE_ADDR_EQUAL(&newpolicy->addrmask.sin6_addr, 105598943Sluigi &pol->ape_policy.addrmask.sin6_addr)) { 105698943Sluigi ADDRSEL_UNLOCK(); 105798943Sluigi ADDRSEL_XUNLOCK(); 105898943Sluigi free(new, M_IFADDR); 105998943Sluigi return (EEXIST); /* or override it? */ 1060108258Smaxim } 106198943Sluigi } 106298943Sluigi 106398943Sluigi bzero(new, sizeof(*new)); 106498943Sluigi 1065120141Ssam /* XXX: should validate entry */ 106698943Sluigi new->ape_policy = *newpolicy; 1067120141Ssam 1068120141Ssam TAILQ_INSERT_TAIL(&V_addrsel_policytab, new, ape_entry); 106998943Sluigi ADDRSEL_UNLOCK(); 107098943Sluigi ADDRSEL_XUNLOCK(); 107198943Sluigi 1072108258Smaxim return (0); 107398943Sluigi} 1074120141Ssam 107598943Sluigistatic int 107698943Sluigidelete_addrsel_policyent(struct in6_addrpolicy *key) 107798943Sluigi{ 107898943Sluigi struct addrsel_policyent *pol; 107998943Sluigi 108098943Sluigi ADDRSEL_XLOCK(); 108198943Sluigi ADDRSEL_LOCK(); 108298943Sluigi 108398943Sluigi /* search for the entry in the table */ 108498943Sluigi TAILQ_FOREACH(pol, &V_addrsel_policytab, ape_entry) { 108598943Sluigi if (IN6_ARE_ADDR_EQUAL(&key->addr.sin6_addr, 108698943Sluigi &pol->ape_policy.addr.sin6_addr) && 1087108258Smaxim IN6_ARE_ADDR_EQUAL(&key->addrmask.sin6_addr, 108898943Sluigi &pol->ape_policy.addrmask.sin6_addr)) { 1089120141Ssam break; 109098943Sluigi } 109198943Sluigi } 109298943Sluigi if (pol == NULL) { 109398943Sluigi ADDRSEL_UNLOCK(); 109498943Sluigi ADDRSEL_XUNLOCK(); 109598943Sluigi return (ESRCH); 109698943Sluigi } 109798943Sluigi 109898943Sluigi TAILQ_REMOVE(&V_addrsel_policytab, pol, ape_entry); 109998943Sluigi ADDRSEL_UNLOCK(); 110098943Sluigi ADDRSEL_XUNLOCK(); 110198943Sluigi 110298943Sluigi return (0); 110398943Sluigi} 1104108258Smaxim 1105108258Smaximstatic int 110698943Sluigiwalk_addrsel_policy(int (*callback)(struct in6_addrpolicy *, void *), void *w) 110798943Sluigi{ 110898943Sluigi struct addrsel_policyent *pol; 110998943Sluigi int error = 0; 111098943Sluigi 111198943Sluigi ADDRSEL_SLOCK(); 111298943Sluigi TAILQ_FOREACH(pol, &V_addrsel_policytab, ape_entry) { 111398943Sluigi if ((error = (*callback)(&pol->ape_policy, w)) != 0) { 111498943Sluigi ADDRSEL_SUNLOCK(); 111598943Sluigi return (error); 111698943Sluigi } 111798943Sluigi } 111898943Sluigi ADDRSEL_SUNLOCK(); 111998943Sluigi return (error); 112098943Sluigi} 1121108258Smaxim 112298943Sluigistatic int 112398943Sluigidump_addrsel_policyent(struct in6_addrpolicy *pol, void *arg) 112498943Sluigi{ 112598943Sluigi int error = 0; 112698943Sluigi struct walkarg *w = arg; 112798943Sluigi 112898943Sluigi error = SYSCTL_OUT(w->w_req, pol, sizeof(*pol)); 112998943Sluigi 113098943Sluigi return (error); 113198943Sluigi} 1132106118Smaxim 113398943Sluigistatic struct in6_addrpolicy * 113498943Sluigimatch_addrsel_policy(struct sockaddr_in6 *key) 1135120141Ssam{ 113698943Sluigi struct addrsel_policyent *pent; 113798943Sluigi struct in6_addrpolicy *bestpol = NULL, *pol; 113898943Sluigi int matchlen, bestmatchlen = -1; 113998943Sluigi u_char *mp, *ep, *k, *p, m; 114098943Sluigi 114198943Sluigi TAILQ_FOREACH(pent, &V_addrsel_policytab, ape_entry) { 114298943Sluigi matchlen = 0; 1143108258Smaxim 1144120141Ssam pol = &pent->ape_policy; 114598943Sluigi mp = (u_char *)&pol->addrmask.sin6_addr; 114698943Sluigi ep = mp + 16; /* XXX: scope field? */ 1147120141Ssam k = (u_char *)&key->sin6_addr; 1148120141Ssam p = (u_char *)&pol->addr.sin6_addr; 114998943Sluigi for (; mp < ep && *mp; mp++, k++, p++) { 115098943Sluigi m = *mp; 115198943Sluigi if ((*k & m) != *p) 1152100004Sluigi goto next; /* not match */ 1153100004Sluigi if (m == 0xff) /* short cut for a typical case */ 1154100004Sluigi matchlen += 8; 1155100004Sluigi else { 1156100004Sluigi while (m >= 0x80) { 1157100004Sluigi matchlen++; 115899475Sluigi m <<= 1; 1159100004Sluigi } 116099475Sluigi } 116199475Sluigi } 1162100004Sluigi 116399475Sluigi /* matched. check if this is better than the current best. */ 116499475Sluigi if (bestpol == NULL || 1165111119Simp matchlen > bestmatchlen) { 1166105775Smaxim bestpol = pol; 116799475Sluigi bestmatchlen = matchlen; 116899475Sluigi } 116999475Sluigi 117099475Sluigi next: 117199475Sluigi continue; 1172100004Sluigi } 1173100004Sluigi 1174100004Sluigi return (bestpol); 117599475Sluigi} 1176100004Sluigi