Now that packet headers include the interface index of their receiving interface, pass it directly to in6_addr2scopeid().
This does not change anything with regards to the scopeid hack but it reduces the number of if_get(). Ok? Index: netinet/udp_usrreq.c =================================================================== RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v retrieving revision 1.202 diff -u -p -r1.202 udp_usrreq.c --- netinet/udp_usrreq.c 30 Jun 2015 15:30:17 -0000 1.202 +++ netinet/udp_usrreq.c 7 Jul 2015 13:52:42 -0000 @@ -757,8 +757,8 @@ udp6_ctlinput(int cmd, struct sockaddr * sa6.sin6_len = sizeof(sa6); sa6.sin6_addr = *ip6cp->ip6c_finaldst; /* XXX: assuming M is valid in this case */ - sa6.sin6_scope_id = in6_addr2scopeid( - if_get(m->m_pkthdr.ph_ifidx), ip6cp->ip6c_finaldst); + sa6.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.ph_ifidx, + ip6cp->ip6c_finaldst); if (in6_embedscope(ip6cp->ip6c_finaldst, &sa6, NULL, NULL)) { /* should be impossible */ return; @@ -790,8 +790,8 @@ udp6_ctlinput(int cmd, struct sockaddr * sa6_src.sin6_family = AF_INET6; sa6_src.sin6_len = sizeof(sa6_src); sa6_src.sin6_addr = ip6->ip6_src; - sa6_src.sin6_scope_id = in6_addr2scopeid( - if_get(m->m_pkthdr.ph_ifidx), &ip6->ip6_src); + sa6_src.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.ph_ifidx, + &ip6->ip6_src); if (in6_embedscope(&sa6_src.sin6_addr, &sa6_src, NULL, NULL)) { /* should be impossible */ return; Index: netinet6/icmp6.c =================================================================== RCS file: /cvs/src/sys/netinet6/icmp6.c,v retrieving revision 1.160 diff -u -p -r1.160 icmp6.c --- netinet6/icmp6.c 30 Jun 2015 15:30:17 -0000 1.160 +++ netinet6/icmp6.c 7 Jul 2015 13:52:42 -0000 @@ -928,8 +928,8 @@ icmp6_notify_error(struct mbuf *m, int o icmp6dst.sin6_addr = eip6->ip6_dst; else icmp6dst.sin6_addr = *finaldst; - icmp6dst.sin6_scope_id = in6_addr2scopeid( - if_get(m->m_pkthdr.ph_ifidx), &icmp6dst.sin6_addr); + icmp6dst.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.ph_ifidx, + &icmp6dst.sin6_addr); if (in6_embedscope(&icmp6dst.sin6_addr, &icmp6dst, NULL, NULL)) { /* should be impossbile */ @@ -946,8 +946,8 @@ icmp6_notify_error(struct mbuf *m, int o icmp6src.sin6_len = sizeof(struct sockaddr_in6); icmp6src.sin6_family = AF_INET6; icmp6src.sin6_addr = eip6->ip6_src; - icmp6src.sin6_scope_id = in6_addr2scopeid( - if_get(m->m_pkthdr.ph_ifidx), &icmp6src.sin6_addr); + icmp6src.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.ph_ifidx, + &icmp6src.sin6_addr); if (in6_embedscope(&icmp6src.sin6_addr, &icmp6src, NULL, NULL)) { /* should be impossbile */ @@ -1034,7 +1034,7 @@ icmp6_mtudisc_update(struct ip6ctlparam if (IN6_IS_ADDR_LINKLOCAL(dst)) { sin6.sin6_addr.s6_addr16[1] = htons(m->m_pkthdr.ph_ifidx); } - sin6.sin6_scope_id = in6_addr2scopeid(if_get(m->m_pkthdr.ph_ifidx), + sin6.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.ph_ifidx, &sin6.sin6_addr); rt = icmp6_mtudisc_clone(sin6tosa(&sin6), m->m_pkthdr.ph_rtableid); @@ -1610,7 +1610,7 @@ icmp6_redirect_output(struct mbuf *m0, s src_sa.sin6_len = sizeof(src_sa); src_sa.sin6_addr = sip6->ip6_src; /* we don't currently use sin6_scope_id, but eventually use it */ - src_sa.sin6_scope_id = in6_addr2scopeid(ifp, &sip6->ip6_src); + src_sa.sin6_scope_id = in6_addr2scopeid(ifp->if_index, &sip6->ip6_src); if (nd6_is_addr_neighbor(&src_sa, ifp) == 0) goto fail; if (IN6_IS_ADDR_MULTICAST(&sip6->ip6_dst)) Index: netinet6/in6.c =================================================================== RCS file: /cvs/src/sys/netinet6/in6.c,v retrieving revision 1.159 diff -u -p -r1.159 in6.c --- netinet6/in6.c 8 Jun 2015 22:19:27 -0000 1.159 +++ netinet6/in6.c 7 Jul 2015 13:52:42 -0000 @@ -1671,7 +1671,7 @@ in6_addrscope(struct in6_addr *addr) */ int -in6_addr2scopeid(struct ifnet *ifp, struct in6_addr *addr) +in6_addr2scopeid(unsigned int ifidx, struct in6_addr *addr) { int scope = in6_addrscope(addr); @@ -1679,7 +1679,7 @@ in6_addr2scopeid(struct ifnet *ifp, stru case __IPV6_ADDR_SCOPE_INTFACELOCAL: case __IPV6_ADDR_SCOPE_LINKLOCAL: /* XXX: we do not distinguish between a link and an I/F. */ - return (ifp->if_index); + return (ifidx); case __IPV6_ADDR_SCOPE_SITELOCAL: return (0); /* XXX: invalid. */ @@ -1803,7 +1803,8 @@ in6_ifawithscope(struct ifnet *oifp, str * We can never take an address that breaks the scope zone * of the destination. */ - if (in6_addr2scopeid(ifp, dst) != in6_addr2scopeid(oifp, dst)) + if (in6_addr2scopeid(ifp->if_index, dst) != + in6_addr2scopeid(oifp->if_index, dst)) continue; TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { Index: netinet6/in6_var.h =================================================================== RCS file: /cvs/src/sys/netinet6/in6_var.h,v retrieving revision 1.51 diff -u -p -r1.51 in6_var.h --- netinet6/in6_var.h 20 Nov 2014 09:55:57 -0000 1.51 +++ netinet6/in6_var.h 7 Jul 2015 13:52:42 -0000 @@ -519,7 +519,7 @@ void in6_domifdetach(struct ifnet *, voi struct in6_ifaddr *in6ifa_ifpforlinklocal(struct ifnet *, int); struct in6_ifaddr *in6ifa_ifpwithaddr(struct ifnet *, struct in6_addr *); int in6_ifpprefix(const struct ifnet *, const struct in6_addr *); -int in6_addr2scopeid(struct ifnet *, struct in6_addr *); +int in6_addr2scopeid(unsigned int, struct in6_addr *); int in6_matchlen(struct in6_addr *, struct in6_addr *); int in6_are_prefix_equal(struct in6_addr *, struct in6_addr *, int); void in6_prefixlen2mask(struct in6_addr *, int); Index: netinet6/ip6_forward.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_forward.c,v retrieving revision 1.77 diff -u -p -r1.77 ip6_forward.c --- netinet6/ip6_forward.c 30 Jun 2015 15:30:17 -0000 1.77 +++ netinet6/ip6_forward.c 7 Jul 2015 13:52:42 -0000 @@ -288,8 +288,8 @@ reroute: * unreachable error with Code 2 (beyond scope of source address). * [draft-ietf-ipngwg-icmp-v3-00.txt, Section 3.1] */ - if (in6_addr2scopeid(if_get(m->m_pkthdr.ph_ifidx), &ip6->ip6_src) != - in6_addr2scopeid(rt->rt_ifp, &ip6->ip6_src)) { + if (in6_addr2scopeid(m->m_pkthdr.ph_ifidx, &ip6->ip6_src) != + in6_addr2scopeid(rt->rt_ifp->if_index, &ip6->ip6_src)) { ip6stat.ip6s_cantforward++; ip6stat.ip6s_badscope++; in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard); Index: netinet6/ip6_mroute.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_mroute.c,v retrieving revision 1.84 diff -u -p -r1.84 ip6_mroute.c --- netinet6/ip6_mroute.c 30 Jun 2015 15:30:17 -0000 1.84 +++ netinet6/ip6_mroute.c 7 Jul 2015 13:52:42 -0000 @@ -1475,11 +1475,11 @@ ip6_mdq(struct mbuf *m, struct ifnet *if if ((mif6table[rt->mf6c_parent].m6_flags & MIFF_REGISTER) == 0 && (mif6table[mifi].m6_flags & MIFF_REGISTER) == 0 && - (in6_addr2scopeid(ifp, &ip6->ip6_dst) != - in6_addr2scopeid(mif6table[mifi].m6_ifp, + (in6_addr2scopeid(ifp->if_index, &ip6->ip6_dst) != + in6_addr2scopeid(mif6table[mifi].m6_ifp->if_index, &ip6->ip6_dst) || - in6_addr2scopeid(ifp, &ip6->ip6_src) != - in6_addr2scopeid(mif6table[mifi].m6_ifp, + in6_addr2scopeid(ifp->if_index, &ip6->ip6_src) != + in6_addr2scopeid(mif6table[mifi].m6_ifp->if_index, &ip6->ip6_src))) { ip6stat.ip6s_badscope++; continue;