Date: Thu, 2 Jul 2020 21:04:09 +0000 (UTC) From: "Alexander V. Chernikov" <melifaro@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r362900 - in head/sys: net netinet netinet6 netpfil/ipfw netpfil/ipfw/nat64 Message-ID: <202007022104.062L49Oo089298@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: melifaro Date: Thu Jul 2 21:04:08 2020 New Revision: 362900 URL: https://svnweb.freebsd.org/changeset/base/362900 Log: Complete conversions from fib<4|6>_lookup_nh_<basic|ext> to fib<4|6>_lookup(). fib[46]_lookup_nh_ represents pre-epoch generation of fib api, providing less guarantees over pointer validness and requiring on-stack data copying. With no callers remaining, remove fib[46]_lookup_nh_ functions. Submitted by: Neel Chauhan <neel AT neelc DOT org> Differential Revision: https://reviews.freebsd.org/D25445 Modified: head/sys/net/if_stf.c head/sys/netinet/if_ether.c head/sys/netinet/in_fib.c head/sys/netinet/in_fib.h head/sys/netinet/in_mcast.c head/sys/netinet/ip_options.c head/sys/netinet6/icmp6.c head/sys/netinet6/in6.c head/sys/netinet6/in6_fib.c head/sys/netinet6/in6_fib.h head/sys/netinet6/in6_mcast.c head/sys/netinet6/in6_src.c head/sys/netpfil/ipfw/ip_fw2.c head/sys/netpfil/ipfw/ip_fw_table_algo.c head/sys/netpfil/ipfw/nat64/nat64_translate.c Modified: head/sys/net/if_stf.c ============================================================================== --- head/sys/net/if_stf.c Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/net/if_stf.c Thu Jul 2 21:04:08 2020 (r362900) @@ -97,6 +97,7 @@ #include <net/if_var.h> #include <net/if_clone.h> #include <net/route.h> +#include <net/route/nhop.h> #include <net/netisr.h> #include <net/if_types.h> #include <net/vnet.h> @@ -568,12 +569,14 @@ stf_checkaddr4(struct stf_softc *sc, struct in_addr *i * perform ingress filter */ if (sc && (STF2IFP(sc)->if_flags & IFF_LINK2) == 0 && inifp) { - struct nhop4_basic nh4; + struct nhop_object *nh; - if (fib4_lookup_nh_basic(sc->sc_fibnum, *in, 0, 0, &nh4) != 0) + NET_EPOCH_ASSERT(); + nh = fib4_lookup(sc->sc_fibnum, *in, 0, 0, 0); + if (nh == NULL) return (-1); - if (nh4.nh_ifp != inifp) + if (nh->nh_ifp != inifp) return (-1); } Modified: head/sys/netinet/if_ether.c ============================================================================== --- head/sys/netinet/if_ether.c Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/netinet/if_ether.c Thu Jul 2 21:04:08 2020 (r362900) @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include <net/netisr.h> #include <net/ethernet.h> #include <net/route.h> +#include <net/route/nhop.h> #include <net/vnet.h> #include <netinet/in.h> @@ -804,7 +805,7 @@ in_arpinput(struct mbuf *m) int carped; struct sockaddr_in sin; struct sockaddr *dst; - struct nhop4_basic nh4; + struct nhop_object *nh; uint8_t linkhdr[LLE_MAX_LINKHDR]; struct route ro; size_t linkhdrsize; @@ -1065,8 +1066,9 @@ reply: if (!V_arp_proxyall) goto drop; - if (fib4_lookup_nh_basic(ifp->if_fib, itaddr, 0, 0, - &nh4) != 0) + NET_EPOCH_ASSERT(); + nh = fib4_lookup(ifp->if_fib, itaddr, 0, 0, 0); + if (nh == NULL) goto drop; /* @@ -1074,7 +1076,7 @@ reply: * as this one came out of, or we'll get into a fight * over who claims what Ether address. */ - if (nh4.nh_ifp == ifp) + if (nh->nh_ifp == ifp) goto drop; (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln); @@ -1087,10 +1089,10 @@ reply: * wrong network. */ - if (fib4_lookup_nh_basic(ifp->if_fib, isaddr, 0, 0, - &nh4) != 0) + nh = fib4_lookup(ifp->if_fib, isaddr, 0, 0, 0); + if (nh == NULL) goto drop; - if (nh4.nh_ifp != ifp) { + if (nh->nh_ifp != ifp) { ARP_LOG(LOG_INFO, "proxy: ignoring request" " from %s via %s\n", inet_ntoa_r(isaddr, addrbuf), Modified: head/sys/netinet/in_fib.c ============================================================================== --- head/sys/netinet/in_fib.c Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/netinet/in_fib.c Thu Jul 2 21:04:08 2020 (r362900) @@ -66,165 +66,6 @@ __FBSDID("$FreeBSD$"); /* Verify struct route compatiblity */ /* Assert 'struct route_in' is compatible with 'struct route' */ CHK_STRUCT_ROUTE_COMPAT(struct route_in, ro_dst4); -static void fib4_rte_to_nh_basic(struct nhop_object *nh, struct in_addr dst, - uint32_t flags, struct nhop4_basic *pnh4); -static void fib4_rte_to_nh_extended(struct nhop_object *nh, struct in_addr dst, - uint32_t flags, struct nhop4_extended *pnh4); - - -static void -fib4_rte_to_nh_basic(struct nhop_object *nh, struct in_addr dst, - uint32_t flags, struct nhop4_basic *pnh4) -{ - - if ((flags & NHR_IFAIF) != 0) - pnh4->nh_ifp = nh->nh_ifa->ifa_ifp; - else - pnh4->nh_ifp = nh->nh_ifp; - pnh4->nh_mtu = nh->nh_mtu; - if (nh->nh_flags & NHF_GATEWAY) - pnh4->nh_addr = nh->gw4_sa.sin_addr; - else - pnh4->nh_addr = dst; - /* Set flags */ - pnh4->nh_flags = nh->nh_flags; - /* TODO: Handle RTF_BROADCAST here */ -} - -static void -fib4_rte_to_nh_extended(struct nhop_object *nh, struct in_addr dst, - uint32_t flags, struct nhop4_extended *pnh4) -{ - - if ((flags & NHR_IFAIF) != 0) - pnh4->nh_ifp = nh->nh_ifa->ifa_ifp; - else - pnh4->nh_ifp = nh->nh_ifp; - pnh4->nh_mtu = nh->nh_mtu; - if (nh->nh_flags & NHF_GATEWAY) - pnh4->nh_addr = nh->gw4_sa.sin_addr; - else - pnh4->nh_addr = dst; - /* Set flags */ - pnh4->nh_flags = nh->nh_flags; - pnh4->nh_ia = ifatoia(nh->nh_ifa); - pnh4->nh_src = IA_SIN(pnh4->nh_ia)->sin_addr; -} - -/* - * Performs IPv4 route table lookup on @dst. Returns 0 on success. - * Stores nexthop info provided @pnh4 structure. - * Note that - * - nh_ifp cannot be safely dereferenced - * - nh_ifp represents logical transmit interface (rt_ifp) (e.g. if - * looking up address on interface "ix0" pointer to "lo0" interface - * will be returned instead of "ix0") - * - nh_ifp represents "address" interface if NHR_IFAIF flag is passed - * - howewer mtu from "transmit" interface will be returned. - */ -int -fib4_lookup_nh_basic(uint32_t fibnum, struct in_addr dst, uint32_t flags, - uint32_t flowid, struct nhop4_basic *pnh4) -{ - RIB_RLOCK_TRACKER; - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in sin; - struct nhop_object *nh; - - KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_basic: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_addr = dst; - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin, &rh->head); - if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { - nh = RNTORT(rn)->rt_nhop; - /* Ensure route & ifp is UP */ - if (RT_LINK_IS_UP(nh->nh_ifp)) { - fib4_rte_to_nh_basic(nh, dst, flags, pnh4); - RIB_RUNLOCK(rh); - - return (0); - } - } - RIB_RUNLOCK(rh); - - return (ENOENT); -} - -/* - * Performs IPv4 route table lookup on @dst. Returns 0 on success. - * Stores extende nexthop info provided @pnh4 structure. - * Note that - * - nh_ifp cannot be safely dereferenced unless NHR_REF is specified. - * - in that case you need to call fib4_free_nh_ext() - * - nh_ifp represents logical transmit interface (rt_ifp) (e.g. if - * looking up address of interface "ix0" pointer to "lo0" interface - * will be returned instead of "ix0") - * - nh_ifp represents "address" interface if NHR_IFAIF flag is passed - * - howewer mtu from "transmit" interface will be returned. - */ -int -fib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flags, - uint32_t flowid, struct nhop4_extended *pnh4) -{ - RIB_RLOCK_TRACKER; - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in sin; - struct rtentry *rte; - struct nhop_object *nh; - - KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_ext: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_addr = dst; - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin, &rh->head); - if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { - rte = RNTORT(rn); -#ifdef RADIX_MPATH - rte = rt_mpath_select(rte, flowid); - if (rte == NULL) { - RIB_RUNLOCK(rh); - return (ENOENT); - } -#endif - nh = rte->rt_nhop; - /* Ensure route & ifp is UP */ - if (RT_LINK_IS_UP(nh->nh_ifp)) { - fib4_rte_to_nh_extended(nh, dst, flags, pnh4); - if ((flags & NHR_REF) != 0) { - /* TODO: lwref on egress ifp's ? */ - } - RIB_RUNLOCK(rh); - - return (0); - } - } - RIB_RUNLOCK(rh); - - return (ENOENT); -} - -void -fib4_free_nh_ext(uint32_t fibnum, struct nhop4_extended *pnh4) -{ - -} /* * Looks up path in fib @fibnum specified by @dst. Modified: head/sys/netinet/in_fib.h ============================================================================== --- head/sys/netinet/in_fib.h Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/netinet/in_fib.h Thu Jul 2 21:04:08 2020 (r362900) @@ -45,32 +45,6 @@ struct route_in { struct sockaddr_in ro_dst4; }; -/* Basic nexthop info used for uRPF/mtu checks */ -struct nhop4_basic { - struct ifnet *nh_ifp; /* Logical egress interface */ - uint16_t nh_mtu; /* nexthop mtu */ - uint16_t nh_flags; /* nhop flags */ - struct in_addr nh_addr; /* GW/DST IPv4 address */ -}; - -/* Extended nexthop info used for control protocols */ -struct nhop4_extended { - struct ifnet *nh_ifp; /* Logical egress interface */ - struct in_ifaddr *nh_ia; /* Associated address */ - uint16_t nh_mtu; /* nexthop mtu */ - uint16_t nh_flags; /* nhop flags */ - uint8_t spare[4]; - struct in_addr nh_addr; /* GW/DST IPv4 address */ - struct in_addr nh_src; /* default source IPv4 address */ - uint64_t spare2; -}; - -int fib4_lookup_nh_basic(uint32_t fibnum, struct in_addr dst, uint32_t flags, - uint32_t flowid, struct nhop4_basic *pnh4); -int fib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flags, - uint32_t flowid, struct nhop4_extended *pnh4); -void fib4_free_nh_ext(uint32_t fibnum, struct nhop4_extended *pnh4); - struct nhop_object *fib4_lookup(uint32_t fibnum, struct in_addr dst, uint32_t scopeid, uint32_t flags, uint32_t flowid); int fib4_check_urpf(uint32_t fibnum, struct in_addr dst, uint32_t scopeid, Modified: head/sys/netinet/in_mcast.c ============================================================================== --- head/sys/netinet/in_mcast.c Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/netinet/in_mcast.c Thu Jul 2 21:04:08 2020 (r362900) @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$"); #include <net/if_var.h> #include <net/if_dl.h> #include <net/route.h> +#include <net/route/nhop.h> #include <net/vnet.h> #include <net/ethernet.h> @@ -1902,7 +1903,7 @@ inp_lookup_mcast_ifp(const struct inpcb *inp, { struct rm_priotracker in_ifa_tracker; struct ifnet *ifp; - struct nhop4_basic nh4; + struct nhop_object *nh; uint32_t fibnum; KASSERT(gsin->sin_family == AF_INET, ("%s: not AF_INET", __func__)); @@ -1916,8 +1917,9 @@ inp_lookup_mcast_ifp(const struct inpcb *inp, IN_IFADDR_RUNLOCK(&in_ifa_tracker); } else { fibnum = inp ? inp->inp_inc.inc_fibnum : 0; - if (fib4_lookup_nh_basic(fibnum, gsin->sin_addr, 0, 0, &nh4)==0) - ifp = nh4.nh_ifp; + nh = fib4_lookup(fibnum, gsin->sin_addr, 0, 0, 0); + if (nh != NULL) + ifp = nh->nh_ifp; else { struct in_ifaddr *ia; struct ifnet *mifp; @@ -2726,6 +2728,7 @@ inp_setmoptions(struct inpcb *inp, struct sockopt *sop { struct ip_moptions *imo; int error; + struct epoch_tracker et; error = 0; @@ -2832,7 +2835,9 @@ inp_setmoptions(struct inpcb *inp, struct sockopt *sop case IP_ADD_SOURCE_MEMBERSHIP: case MCAST_JOIN_GROUP: case MCAST_JOIN_SOURCE_GROUP: + NET_EPOCH_ENTER(et); error = inp_join_group(inp, sopt); + NET_EPOCH_EXIT(et); break; case IP_DROP_MEMBERSHIP: Modified: head/sys/netinet/ip_options.c ============================================================================== --- head/sys/netinet/ip_options.c Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/netinet/ip_options.c Thu Jul 2 21:04:08 2020 (r362900) @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include <net/if_var.h> #include <net/if_dl.h> #include <net/route.h> +#include <net/route/nhop.h> #include <net/netisr.h> #include <net/vnet.h> @@ -107,7 +108,7 @@ ip_dooptions(struct mbuf *m, int pass) int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0; struct in_addr *sin, dst; uint32_t ntime; - struct nhop4_extended nh_ext; + struct nhop_object *nh; struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET }; NET_EPOCH_ASSERT(); @@ -254,11 +255,12 @@ dropit: sizeof(struct in_addr)); } else { /* XXX MRT 0 for routing */ - if (fib4_lookup_nh_ext(M_GETFIB(m), - ipaddr.sin_addr, 0, 0, &nh_ext) != 0) + nh = fib4_lookup(M_GETFIB(m), ipaddr.sin_addr, + 0, NHR_NONE, 0); + if (nh == NULL) goto bad; - memcpy(cp + off, &nh_ext.nh_src, + memcpy(cp + off, &(IA_SIN(nh->nh_ifa)->sin_addr), sizeof(struct in_addr)); } @@ -299,9 +301,9 @@ dropit: if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) != NULL) { memcpy(cp + off, &(IA_SIN(ia)->sin_addr), sizeof(struct in_addr)); - } else if (fib4_lookup_nh_ext(M_GETFIB(m), - ipaddr.sin_addr, 0, 0, &nh_ext) == 0) { - memcpy(cp + off, &nh_ext.nh_src, + } else if ((nh = fib4_lookup(M_GETFIB(m), + ipaddr.sin_addr, 0, NHR_NONE, 0)) != NULL) { + memcpy(cp + off, &(IA_SIN(nh->nh_ifa)->sin_addr), sizeof(struct in_addr)); } else { type = ICMP_UNREACH; Modified: head/sys/netinet6/icmp6.c ============================================================================== --- head/sys/netinet6/icmp6.c Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/netinet6/icmp6.c Thu Jul 2 21:04:08 2020 (r362900) @@ -2270,13 +2270,17 @@ icmp6_redirect_input(struct mbuf *m, int off) } { /* ip6->ip6_src must be equal to gw for icmp6->icmp6_reddst */ - struct nhop6_basic nh6; + struct nhop_object *nh; struct in6_addr kdst; uint32_t scopeid; in6_splitscope(&reddst6, &kdst, &scopeid); - if (fib6_lookup_nh_basic(ifp->if_fib, &kdst, scopeid, 0, 0,&nh6)==0){ - if ((nh6.nh_flags & NHF_GATEWAY) == 0) { + NET_EPOCH_ASSERT(); + nh = fib6_lookup(ifp->if_fib, &kdst, scopeid, 0, 0); + if (nh == NULL) { + struct in6_addr nh_addr; + nh_addr = ifatoia6(nh->nh_ifa)->ia_addr.sin6_addr; + if ((nh->nh_flags & NHF_GATEWAY) == 0) { nd6log((LOG_ERR, "ICMP6 redirect rejected; no route " "with inet6 gateway found for redirect dst: %s\n", @@ -2285,19 +2289,16 @@ icmp6_redirect_input(struct mbuf *m, int off) } /* - * Embed scope zone id into next hop address, since - * fib6_lookup_nh_basic() returns address without embedded - * scope zone id. + * Embed scope zone id into next hop address. */ - if (in6_setscope(&nh6.nh_addr, m->m_pkthdr.rcvif, NULL)) - goto freeit; + nh_addr = nh->gw6_sa.sin6_addr; - if (IN6_ARE_ADDR_EQUAL(&src6, &nh6.nh_addr) == 0) { + if (IN6_ARE_ADDR_EQUAL(&src6, &nh_addr) == 0) { nd6log((LOG_ERR, "ICMP6 redirect rejected; " "not equal to gw-for-src=%s (must be same): " "%s\n", - ip6_sprintf(ip6buf, &nh6.nh_addr), + ip6_sprintf(ip6buf, &nh_addr), icmp6_redirect_diag(&src6, &reddst6, &redtgt6))); goto bad; } Modified: head/sys/netinet6/in6.c ============================================================================== --- head/sys/netinet6/in6.c Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/netinet6/in6.c Thu Jul 2 21:04:08 2020 (r362900) @@ -91,6 +91,7 @@ __FBSDID("$FreeBSD$"); #include <net/if_var.h> #include <net/if_types.h> #include <net/route.h> +#include <net/route/nhop.h> #include <net/if_dl.h> #include <net/vnet.h> @@ -2141,10 +2142,9 @@ in6_lltable_rtcheck(struct ifnet *ifp, const struct sockaddr *l3addr) { const struct sockaddr_in6 *sin6; - struct nhop6_basic nh6; + struct nhop_object *nh; struct in6_addr dst; uint32_t scopeid; - int error; char ip6buf[INET6_ADDRSTRLEN]; int fibnum; @@ -2155,8 +2155,8 @@ in6_lltable_rtcheck(struct ifnet *ifp, sin6 = (const struct sockaddr_in6 *)l3addr; in6_splitscope(&sin6->sin6_addr, &dst, &scopeid); fibnum = V_rt_add_addr_allfibs ? RT_DEFAULT_FIB : ifp->if_fib; - error = fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6); - if (error != 0 || (nh6.nh_flags & NHF_GATEWAY) || nh6.nh_ifp != ifp) { + nh = fib6_lookup(fibnum, &dst, scopeid, NHR_NONE, 0); + if (nh && ((nh->nh_flags & NHF_GATEWAY) || nh->nh_ifp != ifp)) { struct ifaddr *ifa; /* * Create an ND6 cache for an IPv6 neighbor Modified: head/sys/netinet6/in6_fib.c ============================================================================== --- head/sys/netinet6/in6_fib.c Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/netinet6/in6_fib.c Thu Jul 2 21:04:08 2020 (r362900) @@ -70,186 +70,8 @@ __FBSDID("$FreeBSD$"); #include <net/if_types.h> #ifdef INET6 -static void fib6_rte_to_nh_extended(const struct nhop_object *nh, - const struct in6_addr *dst, uint32_t flags, struct nhop6_extended *pnh6); -static void fib6_rte_to_nh_basic(const struct nhop_object *nh, const struct in6_addr *dst, - uint32_t flags, struct nhop6_basic *pnh6); -#define ifatoia6(ifa) ((struct in6_ifaddr *)(ifa)) - CHK_STRUCT_ROUTE_COMPAT(struct route_in6, ro_dst); - - - -static void -fib6_rte_to_nh_basic(const struct nhop_object *nh, const struct in6_addr *dst, - uint32_t flags, struct nhop6_basic *pnh6) -{ - - /* Do explicit nexthop zero unless we're copying it */ - memset(pnh6, 0, sizeof(*pnh6)); - - if ((flags & NHR_IFAIF) != 0) - pnh6->nh_ifp = nh->nh_aifp; - else - pnh6->nh_ifp = nh->nh_ifp; - - pnh6->nh_mtu = nh->nh_mtu; - if (nh->nh_flags & NHF_GATEWAY) { - /* Return address with embedded scope. */ - pnh6->nh_addr = nh->gw6_sa.sin6_addr; - } else - pnh6->nh_addr = *dst; - /* Set flags */ - pnh6->nh_flags = nh->nh_flags; -} - -static void -fib6_rte_to_nh_extended(const struct nhop_object *nh, const struct in6_addr *dst, - uint32_t flags, struct nhop6_extended *pnh6) -{ - - /* Do explicit nexthop zero unless we're copying it */ - memset(pnh6, 0, sizeof(*pnh6)); - - if ((flags & NHR_IFAIF) != 0) - pnh6->nh_ifp = nh->nh_aifp; - else - pnh6->nh_ifp = nh->nh_ifp; - - pnh6->nh_mtu = nh->nh_mtu; - if (nh->nh_flags & NHF_GATEWAY) { - /* Return address with embedded scope. */ - pnh6->nh_addr = nh->gw6_sa.sin6_addr; - } else - pnh6->nh_addr = *dst; - /* Set flags */ - pnh6->nh_flags = nh->nh_flags; - pnh6->nh_ia = ifatoia6(nh->nh_ifa); -} - -/* - * Performs IPv6 route table lookup on @dst. Returns 0 on success. - * Stores basic nexthop info into provided @pnh6 structure. - * Note that - * - nh_ifp represents logical transmit interface (rt_ifp) by default - * - nh_ifp represents "address" interface if NHR_IFAIF flag is passed - * - mtu from logical transmit interface will be returned. - * - nh_ifp cannot be safely dereferenced - * - nh_ifp represents rt_ifp (e.g. if looking up address on - * interface "ix0" pointer to "ix0" interface will be returned instead - * of "lo0") - * - howewer mtu from "transmit" interface will be returned. - * - scope will be embedded in nh_addr - */ -int -fib6_lookup_nh_basic(uint32_t fibnum, const struct in6_addr *dst, uint32_t scopeid, - uint32_t flags, uint32_t flowid, struct nhop6_basic *pnh6) -{ - RIB_RLOCK_TRACKER; - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in6 sin6; - struct nhop_object *nh; - - KASSERT((fibnum < rt_numfibs), ("fib6_lookup_nh_basic: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET6); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_addr = *dst; - sin6.sin6_len = sizeof(struct sockaddr_in6); - /* Assume scopeid is valid and embed it directly */ - if (IN6_IS_SCOPE_LINKLOCAL(dst)) - sin6.sin6_addr.s6_addr16[1] = htons(scopeid & 0xffff); - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin6, &rh->head); - if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { - nh = RNTORT(rn)->rt_nhop; - /* Ensure route & ifp is UP */ - if (RT_LINK_IS_UP(nh->nh_ifp)) { - fib6_rte_to_nh_basic(nh, &sin6.sin6_addr, flags, pnh6); - RIB_RUNLOCK(rh); - return (0); - } - } - RIB_RUNLOCK(rh); - - return (ENOENT); -} - -/* - * Performs IPv6 route table lookup on @dst. Returns 0 on success. - * Stores extended nexthop info into provided @pnh6 structure. - * Note that - * - nh_ifp cannot be safely dereferenced unless NHR_REF is specified. - * - in that case you need to call fib6_free_nh_ext() - * - nh_ifp represents logical transmit interface (rt_ifp) by default - * - nh_ifp represents "address" interface if NHR_IFAIF flag is passed - * - mtu from logical transmit interface will be returned. - * - scope will be embedded in nh_addr - */ -int -fib6_lookup_nh_ext(uint32_t fibnum, const struct in6_addr *dst,uint32_t scopeid, - uint32_t flags, uint32_t flowid, struct nhop6_extended *pnh6) -{ - RIB_RLOCK_TRACKER; - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in6 sin6; - struct rtentry *rte; - struct nhop_object *nh; - - KASSERT((fibnum < rt_numfibs), ("fib6_lookup_nh_ext: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET6); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_len = sizeof(struct sockaddr_in6); - sin6.sin6_addr = *dst; - /* Assume scopeid is valid and embed it directly */ - if (IN6_IS_SCOPE_LINKLOCAL(dst)) - sin6.sin6_addr.s6_addr16[1] = htons(scopeid & 0xffff); - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin6, &rh->head); - if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { - rte = RNTORT(rn); -#ifdef RADIX_MPATH - rte = rt_mpath_select(rte, flowid); - if (rte == NULL) { - RIB_RUNLOCK(rh); - return (ENOENT); - } -#endif - nh = rte->rt_nhop; - /* Ensure route & ifp is UP */ - if (RT_LINK_IS_UP(nh->nh_ifp)) { - fib6_rte_to_nh_extended(nh, &sin6.sin6_addr, flags, - pnh6); - if ((flags & NHR_REF) != 0) { - /* TODO: Do lwref on egress ifp's */ - } - RIB_RUNLOCK(rh); - - return (0); - } - } - RIB_RUNLOCK(rh); - - return (ENOENT); -} - -void -fib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *pnh6) -{ - -} /* * Looks up path in fib @fibnum specified by @dst. Modified: head/sys/netinet6/in6_fib.h ============================================================================== --- head/sys/netinet6/in6_fib.h Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/netinet6/in6_fib.h Thu Jul 2 21:04:08 2020 (r362900) @@ -32,33 +32,6 @@ #ifndef _NETINET6_IN6_FIB_H_ #define _NETINET6_IN6_FIB_H_ -/* Basic nexthop info used for uRPF/mtu checks */ -struct nhop6_basic { - struct ifnet *nh_ifp; /* Logical egress interface */ - uint16_t nh_mtu; /* nexthop mtu */ - uint16_t nh_flags; /* nhop flags */ - uint8_t spare[4]; - struct in6_addr nh_addr; /* GW/DST IPv4 address */ -}; - -/* Extended nexthop info used for control protocols. */ -struct nhop6_extended { - struct ifnet *nh_ifp; /* Logical egress interface */ - struct in6_ifaddr *nh_ia; /* Associated address. */ - uint16_t nh_mtu; /* nexthop mtu */ - uint16_t nh_flags; /* nhop flags */ - uint8_t spare[4]; - struct in6_addr nh_addr; /* GW/DST IPv6 address */ - uint64_t spare2[1]; -}; - -int fib6_lookup_nh_basic(uint32_t fibnum, const struct in6_addr *dst, - uint32_t scopeid, uint32_t flags, uint32_t flowid,struct nhop6_basic *pnh6); -int fib6_lookup_nh_ext(uint32_t fibnum, const struct in6_addr *dst, - uint32_t scopeid, uint32_t flags, uint32_t flowid, - struct nhop6_extended *pnh6); -void fib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *pnh6); - struct nhop_object *fib6_lookup(uint32_t fibnum, const struct in6_addr *dst6, uint32_t scopeid, uint32_t flags, uint32_t flowid); Modified: head/sys/netinet6/in6_mcast.c ============================================================================== --- head/sys/netinet6/in6_mcast.c Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/netinet6/in6_mcast.c Thu Jul 2 21:04:08 2020 (r362900) @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$"); #include <net/if_var.h> #include <net/if_dl.h> #include <net/route.h> +#include <net/route/nhop.h> #include <net/vnet.h> #include <netinet/in.h> @@ -1829,7 +1830,7 @@ static struct ifnet * in6p_lookup_mcast_ifp(const struct inpcb *inp, const struct sockaddr_in6 *gsin6) { - struct nhop6_basic nh6; + struct nhop_object *nh; struct in6_addr dst; uint32_t scopeid; uint32_t fibnum; @@ -1841,10 +1842,9 @@ in6p_lookup_mcast_ifp(const struct inpcb *inp, in6_splitscope(&gsin6->sin6_addr, &dst, &scopeid); fibnum = inp ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB; - if (fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6) != 0) - return (NULL); + nh = fib6_lookup(fibnum, &dst, scopeid, 0, 0); - return (nh6.nh_ifp); + return (nh ? nh->nh_ifp : NULL); } /* Modified: head/sys/netinet6/in6_src.c ============================================================================== --- head/sys/netinet6/in6_src.c Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/netinet6/in6_src.c Thu Jul 2 21:04:08 2020 (r362900) @@ -916,15 +916,16 @@ in6_selecthlim(struct inpcb *inp, struct ifnet *ifp) else if (ifp) return (ND_IFINFO(ifp)->chlim); else if (inp && !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) { - struct nhop6_basic nh6; + struct nhop_object *nh; struct in6_addr dst; uint32_t fibnum, scopeid; int hlim; fibnum = inp->inp_inc.inc_fibnum; in6_splitscope(&inp->in6p_faddr, &dst, &scopeid); - if (fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6)==0){ - hlim = ND_IFINFO(nh6.nh_ifp)->chlim; + nh = fib6_lookup(fibnum, &dst, scopeid, 0, 0); + if (nh != NULL) { + hlim = ND_IFINFO(nh->nh_ifp)->chlim; return (hlim); } } Modified: head/sys/netpfil/ipfw/ip_fw2.c ============================================================================== --- head/sys/netpfil/ipfw/ip_fw2.c Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/netpfil/ipfw/ip_fw2.c Thu Jul 2 21:04:08 2020 (r362900) @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); #include <net/if.h> #include <net/if_var.h> #include <net/route.h> +#include <net/route/nhop.h> #include <net/pfil.h> #include <net/vnet.h> @@ -466,9 +467,10 @@ verify_path(struct in_addr src, struct ifnet *ifp, u_i #if defined(USERSPACE) || !defined(__FreeBSD__) return 0; #else - struct nhop4_basic nh4; + struct nhop_object *nh; - if (fib4_lookup_nh_basic(fib, src, NHR_IFAIF, 0, &nh4) != 0) + nh = fib4_lookup(fib, src, 0, NHR_NONE, 0); + if (nh == NULL) return (0); /* @@ -478,15 +480,15 @@ verify_path(struct in_addr src, struct ifnet *ifp, u_i * routing entry (via lo0) for our own address * may exist, so we need to handle routing assymetry. */ - if (ifp != NULL && ifp != nh4.nh_ifp) + if (ifp != NULL && ifp != nh->nh_aifp) return (0); /* if no ifp provided, check if rtentry is not default route */ - if (ifp == NULL && (nh4.nh_flags & NHF_DEFAULT) != 0) + if (ifp == NULL && (nh->nh_flags & NHF_DEFAULT) != 0) return (0); /* or if this is a blackhole/reject route */ - if (ifp == NULL && (nh4.nh_flags & (NHF_REJECT|NHF_BLACKHOLE)) != 0) + if (ifp == NULL && (nh->nh_flags & (NHF_REJECT|NHF_BLACKHOLE)) != 0) return (0); /* found valid route */ @@ -805,24 +807,25 @@ ipfw_localip6(struct in6_addr *in6) static int verify_path6(struct in6_addr *src, struct ifnet *ifp, u_int fib) { - struct nhop6_basic nh6; + struct nhop_object *nh; if (IN6_IS_SCOPE_LINKLOCAL(src)) return (1); - if (fib6_lookup_nh_basic(fib, src, 0, NHR_IFAIF, 0, &nh6) != 0) + nh = fib6_lookup(fib, src, 0, NHR_NONE, 0); + if (nh == NULL) return (0); /* If ifp is provided, check for equality with route table. */ - if (ifp != NULL && ifp != nh6.nh_ifp) + if (ifp != NULL && ifp != nh->nh_aifp) return (0); /* if no ifp provided, check if rtentry is not default route */ - if (ifp == NULL && (nh6.nh_flags & NHF_DEFAULT) != 0) + if (ifp == NULL && (nh->nh_flags & NHF_DEFAULT) != 0) return (0); /* or if this is a blackhole/reject route */ - if (ifp == NULL && (nh6.nh_flags & (NHF_REJECT|NHF_BLACKHOLE)) != 0) + if (ifp == NULL && (nh->nh_flags & (NHF_REJECT|NHF_BLACKHOLE)) != 0) return (0); /* found valid route */ Modified: head/sys/netpfil/ipfw/ip_fw_table_algo.c ============================================================================== --- head/sys/netpfil/ipfw/ip_fw_table_algo.c Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/netpfil/ipfw/ip_fw_table_algo.c Thu Jul 2 21:04:08 2020 (r362900) @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include <net/if.h> /* ip_fw.h requires IFNAMSIZ */ #include <net/radix.h> #include <net/route.h> +#include <net/route/nhop.h> #include <net/route/route_var.h> #include <netinet/in.h> @@ -3811,26 +3812,22 @@ ta_lookup_kfib(struct table_info *ti, void *key, uint3 uint32_t *val) { #ifdef INET - struct nhop4_basic nh4; struct in_addr in; #endif -#ifdef INET6 - struct nhop6_basic nh6; -#endif int error; error = ENOENT; #ifdef INET if (keylen == 4) { in.s_addr = *(in_addr_t *)key; - error = fib4_lookup_nh_basic(ti->data, - in, 0, 0, &nh4); + NET_EPOCH_ASSERT(); + error = fib4_lookup(ti->data, in, 0, NHR_NONE, 0) != NULL; } #endif #ifdef INET6 if (keylen == 6) - error = fib6_lookup_nh_basic(ti->data, - (struct in6_addr *)key, 0, 0, 0, &nh6); + error = fib6_lookup(ti->data, (struct in6_addr *)key, + 0, NHR_NONE, 0) != NULL; #endif if (error != 0) Modified: head/sys/netpfil/ipfw/nat64/nat64_translate.c ============================================================================== --- head/sys/netpfil/ipfw/nat64/nat64_translate.c Thu Jul 2 18:42:43 2020 (r362899) +++ head/sys/netpfil/ipfw/nat64/nat64_translate.c Thu Jul 2 21:04:08 2020 (r362900) @@ -50,9 +50,11 @@ __FBSDID("$FreeBSD$"); #include <net/pfil.h> #include <net/netisr.h> #include <net/route.h> +#include <net/route/nhop.h> #include <netinet/in.h> #include <netinet/in_fib.h> +#include <netinet/in_var.h> #include <netinet/ip.h> #include <netinet/ip_var.h> #include <netinet/ip_fw.h> @@ -79,9 +81,9 @@ typedef int (*nat64_output_t)(struct ifnet *, struct m typedef int (*nat64_output_one_t)(struct mbuf *, struct nat64_counters *, void *); -static int nat64_find_route4(struct nhop4_basic *, struct sockaddr_in *, +static struct nhop_object *nat64_find_route4(struct sockaddr_in *, struct mbuf *); -static int nat64_find_route6(struct nhop6_basic *, struct sockaddr_in6 *, +static struct nhop_object *nat64_find_route6(struct sockaddr_in6 *, struct mbuf *); static int nat64_output_one(struct mbuf *, struct nat64_counters *, void *); static int nat64_output(struct ifnet *, struct mbuf *, struct sockaddr *, @@ -172,8 +174,8 @@ static int nat64_direct_output_one(struct mbuf *m, struct nat64_counters *stats, void *logdata) { - struct nhop6_basic nh6; - struct nhop4_basic nh4; + struct nhop_object *nh4 = NULL; + struct nhop_object *nh6 = NULL; struct sockaddr_in6 dst6; struct sockaddr_in dst4; struct sockaddr *dst; @@ -183,25 +185,28 @@ nat64_direct_output_one(struct mbuf *m, struct nat64_c int error; ip4 = mtod(m, struct ip *); + error = 0; switch (ip4->ip_v) { case IPVERSION: dst4.sin_addr = ip4->ip_dst; - error = nat64_find_route4(&nh4, &dst4, m); - if (error != 0) + nh4 = nat64_find_route4(&dst4, m); + if (nh4 == NULL) { NAT64STAT_INC(stats, noroute4); - else { - ifp = nh4.nh_ifp; + error = EHOSTUNREACH; + } else { + ifp = nh4->nh_ifp; dst = (struct sockaddr *)&dst4; } break; case (IPV6_VERSION >> 4): ip6 = mtod(m, struct ip6_hdr *); dst6.sin6_addr = ip6->ip6_dst; - error = nat64_find_route6(&nh6, &dst6, m); - if (error != 0) + nh6 = nat64_find_route6(&dst6, m); + if (nh6 == NULL) { NAT64STAT_INC(stats, noroute6); - else { - ifp = nh6.nh_ifp; + error = EHOSTUNREACH; + } else { + ifp = nh6->nh_ifp; dst = (struct sockaddr *)&dst6; } break; @@ -614,31 +619,31 @@ fail: return (ENOMEM); } -static NAT64NOINLINE int -nat64_find_route6(struct nhop6_basic *pnh, struct sockaddr_in6 *dst, - struct mbuf *m) +static struct nhop_object * +nat64_find_route6(struct sockaddr_in6 *dst, struct mbuf *m) { - - if (fib6_lookup_nh_basic(M_GETFIB(m), &dst->sin6_addr, 0, 0, 0, - pnh) != 0) - return (EHOSTUNREACH); - if (pnh->nh_flags & (NHF_BLACKHOLE | NHF_REJECT)) - return (EHOSTUNREACH); + struct nhop_object *nh; + NET_EPOCH_ASSERT(); + nh = fib6_lookup(M_GETFIB(m), &dst->sin6_addr, 0, 0, 0); + if (nh == NULL) + return NULL; + if (nh->nh_flags & (NHF_BLACKHOLE | NHF_REJECT)) + return NULL; /* * XXX: we need to use destination address with embedded scope * zone id, because LLTABLE uses such form of addresses for lookup. */ dst->sin6_family = AF_INET6; dst->sin6_len = sizeof(*dst); - dst->sin6_addr = pnh->nh_addr; + dst->sin6_addr = ifatoia6(nh->nh_ifa)->ia_addr.sin6_addr; if (IN6_IS_SCOPE_LINKLOCAL(&dst->sin6_addr)) dst->sin6_addr.s6_addr16[1] = - htons(pnh->nh_ifp->if_index & 0xffff); + htons(nh->nh_ifp->if_index & 0xffff); dst->sin6_port = 0; dst->sin6_scope_id = 0; dst->sin6_flowinfo = 0; - return (0); + return nh; } #define NAT64_ICMP6_PLEN 64 @@ -766,21 +771,23 @@ freeit: m_freem(m); } -static NAT64NOINLINE int -nat64_find_route4(struct nhop4_basic *pnh, struct sockaddr_in *dst, - struct mbuf *m) +static struct nhop_object * +nat64_find_route4(struct sockaddr_in *dst, struct mbuf *m) { + struct nhop_object *nh; - if (fib4_lookup_nh_basic(M_GETFIB(m), dst->sin_addr, 0, 0, pnh) != 0) - return (EHOSTUNREACH); - if (pnh->nh_flags & (NHF_BLACKHOLE | NHF_BROADCAST | NHF_REJECT)) - return (EHOSTUNREACH); + NET_EPOCH_ASSERT(); + nh = fib4_lookup(M_GETFIB(m), dst->sin_addr, 0, 0, 0); + if (nh == NULL) + return NULL; + if (nh->nh_flags & (NHF_BLACKHOLE | NHF_BROADCAST | NHF_REJECT)) + return NULL; dst->sin_family = AF_INET; dst->sin_len = sizeof(*dst); - dst->sin_addr = pnh->nh_addr; + dst->sin_addr = IA_SIN(nh->nh_ifa)->sin_addr; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202007022104.062L49Oo089298>