Author: melifaro
Date: Tue Apr 14 23:06:25 2020
New Revision: 359942
URL: https://svnweb.freebsd.org/changeset/base/359942

Log:
  Convert IP/IPv6 forwarding, ICMP processing and IP PCB laddr selection to
   the new routing KPI.
  
  Reviewed by:  ae
  Differential Revision:        https://reviews.freebsd.org/D24245

Modified:
  head/sys/netinet/icmp6.h
  head/sys/netinet/in_pcb.c
  head/sys/netinet/ip_fastfwd.c
  head/sys/netinet/ip_icmp.c
  head/sys/netinet6/icmp6.c
  head/sys/netinet6/ip6_fastfwd.c
  head/sys/netinet6/ip6_forward.c

Modified: head/sys/netinet/icmp6.h
==============================================================================
--- head/sys/netinet/icmp6.h    Tue Apr 14 22:57:21 2020        (r359941)
+++ head/sys/netinet/icmp6.h    Tue Apr 14 23:06:25 2020        (r359942)
@@ -693,7 +693,7 @@ void        kmod_icmp6stat_inc(int statnum);
 
 #ifdef _KERNEL
 # ifdef __STDC__
-struct rtentry;
+struct nhop_object;
 struct rttimer;
 struct in6_multi;
 # endif
@@ -705,7 +705,7 @@ void        icmp6_fasttimo(void);
 void   icmp6_slowtimo(void);
 void   icmp6_prepare(struct mbuf *);
 void   icmp6_redirect_input(struct mbuf *, int);
-void   icmp6_redirect_output(struct mbuf *, struct rtentry *);
+void   icmp6_redirect_output(struct mbuf *, struct nhop_object *);
 
 struct ip6ctlparam;
 void   icmp6_mtudisc_update(struct ip6ctlparam *, int);

Modified: head/sys/netinet/in_pcb.c
==============================================================================
--- head/sys/netinet/in_pcb.c   Tue Apr 14 22:57:21 2020        (r359941)
+++ head/sys/netinet/in_pcb.c   Tue Apr 14 23:06:25 2020        (r359942)
@@ -88,6 +88,7 @@ __FBSDID("$FreeBSD$");
 #include <netinet/in_pcb.h>
 #ifdef INET
 #include <netinet/in_var.h>
+#include <netinet/in_fib.h>
 #endif
 #include <netinet/ip_var.h>
 #include <netinet/tcp_var.h>
@@ -102,6 +103,7 @@ __FBSDID("$FreeBSD$");
 #include <netinet6/in6_var.h>
 #include <netinet6/ip6_var.h>
 #endif /* INET6 */
+#include <net/route/nhop.h>
 #endif
 
 #include <netipsec/ipsec_support.h>
@@ -1033,8 +1035,8 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, 
 {
        struct ifaddr *ifa;
        struct sockaddr *sa;
-       struct sockaddr_in *sin;
-       struct route sro;
+       struct sockaddr_in *sin, dst;
+       struct nhop_object *nh;
        int error;
 
        NET_EPOCH_ASSERT();
@@ -1047,9 +1049,10 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, 
                return (0);
 
        error = 0;
-       bzero(&sro, sizeof(sro));
 
-       sin = (struct sockaddr_in *)&sro.ro_dst;
+       nh = NULL;
+       bzero(&dst, sizeof(dst));
+       sin = &dst;
        sin->sin_family = AF_INET;
        sin->sin_len = sizeof(struct sockaddr_in);
        sin->sin_addr.s_addr = faddr->s_addr;
@@ -1061,7 +1064,8 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, 
         * Find out route to destination.
         */
        if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0)
-               in_rtalloc_ign(&sro, 0, inp->inp_inc.inc_fibnum);
+               nh = fib4_lookup(inp->inp_inc.inc_fibnum, *faddr,
+                   0, NHR_NONE, 0);
 
        /*
         * If we found a route, use the address corresponding to
@@ -1071,7 +1075,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, 
         * network and try to find a corresponding interface to take
         * the source address from.
         */
-       if (sro.ro_rt == NULL || sro.ro_rt->rt_ifp == NULL) {
+       if (nh == NULL || nh->nh_ifp == NULL) {
                struct in_ifaddr *ia;
                struct ifnet *ifp;
 
@@ -1124,22 +1128,22 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, 
         *    belonging to this jail. If so use it.
         * 3. as a last resort return the 'default' jail address.
         */
-       if ((sro.ro_rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) {
+       if ((nh->nh_ifp->if_flags & IFF_LOOPBACK) == 0) {
                struct in_ifaddr *ia;
                struct ifnet *ifp;
 
                /* If not jailed, use the default returned. */
                if (cred == NULL || !prison_flag(cred, PR_IP4)) {
-                       ia = (struct in_ifaddr *)sro.ro_rt->rt_ifa;
+                       ia = (struct in_ifaddr *)nh->nh_ifa;
                        laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
                        goto done;
                }
 
                /* Jailed. */
                /* 1. Check if the iface address belongs to the jail. */
-               sin = (struct sockaddr_in *)sro.ro_rt->rt_ifa->ifa_addr;
+               sin = (struct sockaddr_in *)nh->nh_ifa->ifa_addr;
                if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
-                       ia = (struct in_ifaddr *)sro.ro_rt->rt_ifa;
+                       ia = (struct in_ifaddr *)nh->nh_ifa;
                        laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
                        goto done;
                }
@@ -1149,7 +1153,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, 
                 *    belonging to this jail.
                 */
                ia = NULL;
-               ifp = sro.ro_rt->rt_ifp;
+               ifp = nh->nh_ifp;
                CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
                        sa = ifa->ifa_addr;
                        if (sa->sa_family != AF_INET)
@@ -1179,22 +1183,16 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, 
         * In case of jails, check that it is an address of the jail
         * and if we cannot find, fall back to the 'default' jail address.
         */
-       if ((sro.ro_rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) {
-               struct sockaddr_in sain;
+       if ((nh->nh_ifp->if_flags & IFF_LOOPBACK) != 0) {
                struct in_ifaddr *ia;
 
-               bzero(&sain, sizeof(struct sockaddr_in));
-               sain.sin_family = AF_INET;
-               sain.sin_len = sizeof(struct sockaddr_in);
-               sain.sin_addr.s_addr = faddr->s_addr;
-
-               ia = ifatoia(ifa_ifwithdstaddr(sintosa(&sain),
+               ia = ifatoia(ifa_ifwithdstaddr(sintosa(&dst),
                                        inp->inp_socket->so_fibnum));
                if (ia == NULL)
-                       ia = ifatoia(ifa_ifwithnet(sintosa(&sain), 0,
+                       ia = ifatoia(ifa_ifwithnet(sintosa(&dst), 0,
                                                inp->inp_socket->so_fibnum));
                if (ia == NULL)
-                       ia = ifatoia(ifa_ifwithaddr(sintosa(&sain)));
+                       ia = ifatoia(ifa_ifwithaddr(sintosa(&dst)));
 
                if (cred == NULL || !prison_flag(cred, PR_IP4)) {
                        if (ia == NULL) {
@@ -1234,8 +1232,6 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, 
        }
 
 done:
-       if (sro.ro_rt != NULL)
-               RTFREE(sro.ro_rt);
        return (error);
 }
 

Modified: head/sys/netinet/ip_fastfwd.c
==============================================================================
--- head/sys/netinet/ip_fastfwd.c       Tue Apr 14 22:57:21 2020        
(r359941)
+++ head/sys/netinet/ip_fastfwd.c       Tue Apr 14 23:06:25 2020        
(r359942)
@@ -96,6 +96,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if_dl.h>
 #include <net/pfil.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 #include <net/vnet.h>
 
 #include <netinet/in.h>
@@ -111,11 +112,13 @@ __FBSDID("$FreeBSD$");
 #include <machine/in_cksum.h>
 
 static int
-ip_findroute(struct nhop4_basic *pnh, struct in_addr dest, struct mbuf *m)
+ip_findroute(struct nhop_object **pnh, struct in_addr dest, struct mbuf *m)
 {
+       struct nhop_object *nh;
 
-       bzero(pnh, sizeof(*pnh));
-       if (fib4_lookup_nh_basic(M_GETFIB(m), dest, 0, 0, pnh) != 0) {
+       nh = fib4_lookup(M_GETFIB(m), dest, 0, NHR_NONE,
+           m->m_pkthdr.flowid);
+       if (nh == NULL) {
                IPSTAT_INC(ips_noroute);
                IPSTAT_INC(ips_cantforward);
                icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
@@ -124,18 +127,20 @@ ip_findroute(struct nhop4_basic *pnh, struct in_addr d
        /*
         * Drop blackholed traffic and directed broadcasts.
         */
-       if ((pnh->nh_flags & (NHF_BLACKHOLE | NHF_BROADCAST)) != 0) {
+       if ((nh->nh_flags & (NHF_BLACKHOLE | NHF_BROADCAST)) != 0) {
                IPSTAT_INC(ips_cantforward);
                m_freem(m);
                return (EHOSTUNREACH);
        }
 
-       if (pnh->nh_flags & NHF_REJECT) {
+       if (nh->nh_flags & NHF_REJECT) {
                IPSTAT_INC(ips_cantforward);
                icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
                return (EHOSTUNREACH);
        }
 
+       *pnh = nh;
+
        return (0);
 }
 
@@ -151,7 +156,7 @@ ip_tryforward(struct mbuf *m)
 {
        struct ip *ip;
        struct mbuf *m0 = NULL;
-       struct nhop4_basic nh;
+       struct nhop_object *nh;
        struct sockaddr_in dst;
        struct in_addr dest, odest, rtdest;
        uint16_t ip_len, ip_off;
@@ -323,7 +328,7 @@ passin:
        if (!PFIL_HOOKED_OUT(V_inet_pfil_head))
                goto passout;
 
-       if (pfil_run_hooks(V_inet_pfil_head, &m, nh.nh_ifp,
+       if (pfil_run_hooks(V_inet_pfil_head, &m, nh->nh_ifp,
            PFIL_OUT | PFIL_FWD, NULL) != PFIL_PASS)
                goto drop;
 
@@ -376,12 +381,15 @@ passout:
        bzero(&dst, sizeof(dst));
        dst.sin_family = AF_INET;
        dst.sin_len = sizeof(dst);
-       dst.sin_addr = nh.nh_addr;
+       if (nh->nh_flags & NHF_GATEWAY)
+               dst.sin_addr = nh->gw4_sa.sin_addr;
+       else
+               dst.sin_addr = dest;
 
        /*
         * Check if packet fits MTU or if hardware will fragment for us
         */
-       if (ip_len <= nh.nh_mtu) {
+       if (ip_len <= nh->nh_mtu) {
                /*
                 * Avoid confusing lower layers.
                 */
@@ -389,8 +397,8 @@ passout:
                /*
                 * Send off the packet via outgoing interface
                 */
-               IP_PROBE(send, NULL, NULL, ip, nh.nh_ifp, ip, NULL);
-               error = (*nh.nh_ifp->if_output)(nh.nh_ifp, m,
+               IP_PROBE(send, NULL, NULL, ip, nh->nh_ifp, ip, NULL);
+               error = (*nh->nh_ifp->if_output)(nh->nh_ifp, m,
                    (struct sockaddr *)&dst, NULL);
        } else {
                /*
@@ -399,15 +407,15 @@ passout:
                if (ip_off & IP_DF) {
                        IPSTAT_INC(ips_cantfrag);
                        icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG,
-                               0, nh.nh_mtu);
+                               0, nh->nh_mtu);
                        goto consumed;
                } else {
                        /*
                         * We have to fragment the packet
                         */
                        m->m_pkthdr.csum_flags |= CSUM_IP;
-                       if (ip_fragment(ip, &m, nh.nh_mtu,
-                           nh.nh_ifp->if_hwassist) != 0)
+                       if (ip_fragment(ip, &m, nh->nh_mtu,
+                           nh->nh_ifp->if_hwassist) != 0)
                                goto drop;
                        KASSERT(m != NULL, ("null mbuf and no error"));
                        /*
@@ -423,10 +431,9 @@ passout:
                                m_clrprotoflags(m);
 
                                IP_PROBE(send, NULL, NULL,
-                                   mtod(m, struct ip *), nh.nh_ifp,
+                                   mtod(m, struct ip *), nh->nh_ifp,
                                    mtod(m, struct ip *), NULL);
-                               /* XXX: we can use cached route here */
-                               error = (*nh.nh_ifp->if_output)(nh.nh_ifp, m,
+                               error = (*nh->nh_ifp->if_output)(nh->nh_ifp, m,
                                    (struct sockaddr *)&dst, NULL);
                                if (error)
                                        break;

Modified: head/sys/netinet/ip_icmp.c
==============================================================================
--- head/sys/netinet/ip_icmp.c  Tue Apr 14 22:57:21 2020        (r359941)
+++ head/sys/netinet/ip_icmp.c  Tue Apr 14 23:06:25 2020        (r359942)
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if_var.h>
 #include <net/if_types.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 #include <net/vnet.h>
 
 #include <netinet/in.h>
@@ -945,7 +946,7 @@ static int
 icmp_verify_redirect_gateway(struct sockaddr_in *src, struct sockaddr_in *dst,
     struct sockaddr_in *gateway, u_int fibnum)
 {
-       struct rtentry *rt;
+       struct nhop_object *nh;
        struct ifaddr *ifa;
 
        NET_EPOCH_ASSERT();
@@ -958,8 +959,8 @@ icmp_verify_redirect_gateway(struct sockaddr_in *src, 
        if (ifa_ifwithaddr_check((struct sockaddr *)gateway))
                return (EHOSTUNREACH);
 
-       rt = rtalloc1_fib((struct sockaddr *)dst, 0, 0UL, fibnum); /* NB: rt is 
locked */
-       if (rt == NULL)
+       nh = fib4_lookup(fibnum, dst->sin_addr, 0, NHR_NONE, 0);
+       if (nh == NULL)
                return (EINVAL);
 
        /*
@@ -968,28 +969,19 @@ icmp_verify_redirect_gateway(struct sockaddr_in *src, 
         * we have a routing loop, perhaps as a result of an interface
         * going down recently.
         */
-       if (!sa_equal((struct sockaddr *)src, rt->rt_gateway)) {
-               RTFREE_LOCKED(rt);
+       if (!sa_equal((struct sockaddr *)src, &nh->gw_sa))
                return (EINVAL);
-       }
-       if (rt->rt_ifa != ifa && ifa->ifa_addr->sa_family != AF_LINK) {
-               RTFREE_LOCKED(rt);
+       if (nh->nh_ifa != ifa && ifa->ifa_addr->sa_family != AF_LINK)
                return (EINVAL);
-       }
 
        /* If host route already exists, ignore redirect. */
-       if (rt->rt_flags & RTF_HOST) {
-               RTFREE_LOCKED(rt);
+       if (nh->nh_flags & NHF_HOST)
                return (EEXIST);
-       }
 
        /* If the prefix is directly reachable, ignore redirect. */
-       if (!(rt->rt_flags & RTF_GATEWAY)) {
-               RTFREE_LOCKED(rt);
+       if (!(nh->nh_flags & NHF_GATEWAY))
                return (EEXIST);
-       }
 
-       RTFREE_LOCKED(rt);
        return (0);
 }
 

Modified: head/sys/netinet6/icmp6.c
==============================================================================
--- head/sys/netinet6/icmp6.c   Tue Apr 14 22:57:21 2020        (r359941)
+++ head/sys/netinet6/icmp6.c   Tue Apr 14 23:06:25 2020        (r359942)
@@ -93,6 +93,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if_llatbl.h>
 #include <net/if_types.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 #include <net/vnet.h>
 
 #include <netinet/in.h>
@@ -2412,7 +2413,7 @@ icmp6_redirect_input(struct mbuf *m, int off)
 }
 
 void
-icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt)
+icmp6_redirect_output(struct mbuf *m0, struct nhop_object *nh)
 {
        struct ifnet *ifp;      /* my outgoing interface */
        struct in6_addr *ifp_ll6;
@@ -2435,7 +2436,7 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry 
                goto fail;
 
        /* sanity check */
-       if (!m0 || !rt || !(rt->rt_flags & RTF_UP) || !(ifp = rt->rt_ifp))
+       if (!m0 || !nh || !(NH_IS_VALID(nh)) || !(ifp = nh->nh_ifp))
                goto fail;
 
        /*
@@ -2469,7 +2470,7 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry 
        m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
        if (m == NULL)
                goto fail;
-       M_SETFIB(m, rt->rt_fibnum);
+       M_SETFIB(m, M_GETFIB(m0));
        maxlen = M_TRAILINGSPACE(m);
        maxlen = min(IPV6_MMTU, maxlen);
        /* just for safety */
@@ -2491,9 +2492,9 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry 
        }
 
        /* get ip6 linklocal address for the router. */
-       if (rt->rt_gateway && (rt->rt_flags & RTF_GATEWAY)) {
+       if (nh->nh_flags & NHF_GATEWAY) {
                struct sockaddr_in6 *sin6;
-               sin6 = (struct sockaddr_in6 *)rt->rt_gateway;
+               sin6 = &nh->gw6_sa;
                router_ll6 = &sin6->sin6_addr;
                if (!IN6_IS_ADDR_LINKLOCAL(router_ll6))
                        router_ll6 = (struct in6_addr *)NULL;
@@ -2517,7 +2518,7 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry 
        nd_rd->nd_rd_type = ND_REDIRECT;
        nd_rd->nd_rd_code = 0;
        nd_rd->nd_rd_reserved = 0;
-       if (rt->rt_flags & RTF_GATEWAY) {
+       if (nh->nh_flags & NHF_GATEWAY) {
                /*
                 * nd_rd->nd_rd_target must be a link-local address in
                 * better router cases.

Modified: head/sys/netinet6/ip6_fastfwd.c
==============================================================================
--- head/sys/netinet6/ip6_fastfwd.c     Tue Apr 14 22:57:21 2020        
(r359941)
+++ head/sys/netinet6/ip6_fastfwd.c     Tue Apr 14 23:06:25 2020        
(r359942)
@@ -40,6 +40,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>
 
@@ -55,30 +56,35 @@ __FBSDID("$FreeBSD$");
 #include <netinet6/nd6.h>
 
 static int
-ip6_findroute(struct nhop6_basic *pnh, const struct sockaddr_in6 *dst,
+ip6_findroute(struct nhop_object **pnh, const struct sockaddr_in6 *dst,
     struct mbuf *m)
 {
+       struct nhop_object *nh;
 
-       if (fib6_lookup_nh_basic(M_GETFIB(m), &dst->sin6_addr,
-           dst->sin6_scope_id, 0, dst->sin6_flowinfo, pnh) != 0) {
+       nh = fib6_lookup(M_GETFIB(m), &dst->sin6_addr,
+           dst->sin6_scope_id, NHR_NONE, m->m_pkthdr.flowid);
+       if (nh == NULL) {
                IP6STAT_INC(ip6s_noroute);
                IP6STAT_INC(ip6s_cantforward);
                icmp6_error(m, ICMP6_DST_UNREACH,
                    ICMP6_DST_UNREACH_NOROUTE, 0);
                return (EHOSTUNREACH);
        }
-       if (pnh->nh_flags & NHF_BLACKHOLE) {
+       if (nh->nh_flags & NHF_BLACKHOLE) {
                IP6STAT_INC(ip6s_cantforward);
                m_freem(m);
                return (EHOSTUNREACH);
        }
 
-       if (pnh->nh_flags & NHF_REJECT) {
+       if (nh->nh_flags & NHF_REJECT) {
                IP6STAT_INC(ip6s_cantforward);
                icmp6_error(m, ICMP6_DST_UNREACH,
                    ICMP6_DST_UNREACH_REJECT, 0);
                return (EHOSTUNREACH);
        }
+
+       *pnh = nh;
+
        return (0);
 }
 
@@ -86,7 +92,7 @@ struct mbuf*
 ip6_tryforward(struct mbuf *m)
 {
        struct sockaddr_in6 dst;
-       struct nhop6_basic nh;
+       struct nhop_object *nh;
        struct m_tag *fwd_tag;
        struct ip6_hdr *ip6;
        struct ifnet *rcvif;
@@ -196,9 +202,9 @@ passin:
                goto dropin;
        }
        if (!PFIL_HOOKED_OUT(V_inet6_pfil_head)) {
-               if (m->m_pkthdr.len > nh.nh_mtu) {
-                       in6_ifstat_inc(nh.nh_ifp, ifs6_in_toobig);
-                       icmp6_error(m, ICMP6_PACKET_TOO_BIG, 0, nh.nh_mtu);
+               if (m->m_pkthdr.len > nh->nh_mtu) {
+                       in6_ifstat_inc(nh->nh_ifp, ifs6_in_toobig);
+                       icmp6_error(m, ICMP6_PACKET_TOO_BIG, 0, nh->nh_mtu);
                        m = NULL;
                        goto dropout;
                }
@@ -208,7 +214,7 @@ passin:
        /*
         * Outgoing packet firewall processing.
         */
-       if (pfil_run_hooks(V_inet6_pfil_head, &m, nh.nh_ifp, PFIL_OUT |
+       if (pfil_run_hooks(V_inet6_pfil_head, &m, nh->nh_ifp, PFIL_OUT |
            PFIL_FWD, NULL) != PFIL_PASS)
                goto dropout;
 
@@ -216,9 +222,9 @@ passin:
         * We used slow path processing for packets with scoped addresses.
         * So, scope checks aren't needed here.
         */
-       if (m->m_pkthdr.len > nh.nh_mtu) {
-               in6_ifstat_inc(nh.nh_ifp, ifs6_in_toobig);
-               icmp6_error(m, ICMP6_PACKET_TOO_BIG, 0, nh.nh_mtu);
+       if (m->m_pkthdr.len > nh->nh_mtu) {
+               in6_ifstat_inc(nh->nh_ifp, ifs6_in_toobig);
+               icmp6_error(m, ICMP6_PACKET_TOO_BIG, 0, nh->nh_mtu);
                m = NULL;
                goto dropout;
        }
@@ -272,16 +278,17 @@ passout:
        }
 
        m_clrprotoflags(m);     /* Avoid confusing lower layers. */
-       IP_PROBE(send, NULL, NULL, ip6, nh.nh_ifp, NULL, ip6);
+       IP_PROBE(send, NULL, NULL, ip6, nh->nh_ifp, NULL, ip6);
 
-       dst.sin6_addr = nh.nh_addr;
-       error = (*nh.nh_ifp->if_output)(nh.nh_ifp, m,
+       if (nh->nh_flags & NHF_GATEWAY)
+               dst.sin6_addr = nh->gw6_sa.sin6_addr;
+       error = (*nh->nh_ifp->if_output)(nh->nh_ifp, m,
            (struct sockaddr *)&dst, NULL);
        if (error != 0) {
-               in6_ifstat_inc(nh.nh_ifp, ifs6_out_discard);
+               in6_ifstat_inc(nh->nh_ifp, ifs6_out_discard);
                IP6STAT_INC(ip6s_cantforward);
        } else {
-               in6_ifstat_inc(nh.nh_ifp, ifs6_out_forward);
+               in6_ifstat_inc(nh->nh_ifp, ifs6_out_forward);
                IP6STAT_INC(ip6s_forward);
        }
        return (NULL);
@@ -289,7 +296,7 @@ dropin:
        in6_ifstat_inc(rcvif, ifs6_in_discard);
        goto drop;
 dropout:
-       in6_ifstat_inc(nh.nh_ifp, ifs6_out_discard);
+       in6_ifstat_inc(nh->nh_ifp, ifs6_out_discard);
 drop:
        if (m != NULL)
                m_freem(m);

Modified: head/sys/netinet6/ip6_forward.c
==============================================================================
--- head/sys/netinet6/ip6_forward.c     Tue Apr 14 22:57:21 2020        
(r359941)
+++ head/sys/netinet6/ip6_forward.c     Tue Apr 14 23:06:25 2020        
(r359942)
@@ -401,7 +401,7 @@ pass:
        switch (error) {
        case 0:
                if (type == ND_REDIRECT) {
-                       icmp6_redirect_output(mcopy, rt);
+                       icmp6_redirect_output(mcopy, rt->rt_nhop);
                        goto out;
                }
                goto freecopy;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to