Instead of rtfree(9)ing the cached route after using it, if it is a
multipath one, free it before.

Ok?

Index: netinet/ip_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.269
diff -u -p -r1.269 ip_input.c
--- netinet/ip_input.c  29 Mar 2016 10:34:42 -0000      1.269
+++ netinet/ip_input.c  11 Apr 2016 13:21:44 -0000
@@ -1422,8 +1422,9 @@ ip_forward(struct mbuf *m, struct ifnet 
 
        rtableid = m->m_pkthdr.ph_rtableid;
 
+       rt = ipforward_rt.ro_rt;
        sin = satosin(&ipforward_rt.ro_dst);
-       if ((rt = ipforward_rt.ro_rt) == NULL ||
+       if (rt == NULL || ISSET(rt->rt_flags, RTF_MPATH) ||
            ip->ip_dst.s_addr != sin->sin_addr.s_addr ||
            rtableid != ipforward_rt.ro_tableid) {
                if (ipforward_rt.ro_rt) {
@@ -1506,7 +1507,7 @@ ip_forward(struct mbuf *m, struct ifnet 
                        goto freecopy;
        }
        if (!fake)
-               goto freert;
+               return;
 
        switch (error) {
 
@@ -1528,9 +1529,7 @@ ip_forward(struct mbuf *m, struct ifnet 
                code = ICMP_UNREACH_NEEDFRAG;
 
 #ifdef IPSEC
-               if (ipforward_rt.ro_rt) {
-                       struct rtentry *rt = ipforward_rt.ro_rt;
-
+               if (rt != NULL) {
                        if (rt->rt_rmx.rmx_mtu)
                                destmtu = rt->rt_rmx.rmx_mtu;
                        else {
@@ -1569,15 +1568,6 @@ ip_forward(struct mbuf *m, struct ifnet 
  freecopy:
        if (fake)
                m_tag_delete_chain(&mfake);
- freert:
-#ifndef SMALL_KERNEL
-       if (ipmultipath && ipforward_rt.ro_rt &&
-           (ipforward_rt.ro_rt->rt_flags & RTF_MPATH)) {
-               rtfree(ipforward_rt.ro_rt);
-               ipforward_rt.ro_rt = NULL;
-       }
-#endif
-       return;
 }
 
 int
Index: netinet6/ip6_forward.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_forward.c,v
retrieving revision 1.87
diff -u -p -r1.87 ip6_forward.c
--- netinet6/ip6_forward.c      29 Mar 2016 11:57:51 -0000      1.87
+++ netinet6/ip6_forward.c      11 Apr 2016 13:21:45 -0000
@@ -225,6 +225,7 @@ reroute:
                 * ip6_forward_rt.ro_dst.sin6_addr is equal to ip6->ip6_dst
                 */
                if (!rtisvalid(ip6_forward_rt.ro_rt) ||
+                   ISSET(ip6_forward_rt.ro_rt->rt_flags, RTF_MPATH) ||
                    ip6_forward_rt.ro_tableid != rtableid) {
                        if (ip6_forward_rt.ro_rt) {
                                rtfree(ip6_forward_rt.ro_rt);
@@ -248,6 +249,7 @@ reroute:
                        return;
                }
        } else if (!rtisvalid(ip6_forward_rt.ro_rt) ||
+          ISSET(ip6_forward_rt.ro_rt->rt_flags, RTF_MPATH) ||
           !IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &dst->sin6_addr) ||
           ip6_forward_rt.ro_tableid != rtableid) {
                if (ip6_forward_rt.ro_rt) {
@@ -303,7 +305,7 @@ reroute:
                        icmp6_error(mcopy, ICMP6_DST_UNREACH,
                                    ICMP6_DST_UNREACH_BEYONDSCOPE, 0);
                m_freem(m);
-               goto freert;
+               goto out;
        }
 
 #ifdef IPSEC
@@ -346,7 +348,7 @@ reroute:
                /* Callee frees mbuf */
                error = ipsp_process_packet(m, tdb, AF_INET6, 0);
                m_freem(mcopy);
-               goto freert;
+               goto out;
        }
 #endif /* IPSEC */
 
@@ -387,7 +389,7 @@ reroute:
                                icmp6_error(mcopy, ICMP6_DST_UNREACH,
                                    ICMP6_DST_UNREACH_ADDR, 0);
                        m_freem(m);
-                       goto freert;
+                       goto out;
                }
                type = ND_REDIRECT;
        }
@@ -434,7 +436,7 @@ reroute:
                        icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0,
                            ifp->if_mtu);
                m_freem(m);
-               goto freert;
+               goto out;
        }
 
        error = nd6_output(ifp, m, dst, rt);
@@ -454,12 +456,12 @@ reroute:
 senderr:
 #endif
        if (mcopy == NULL)
-               goto freert;
+               goto out;
        switch (error) {
        case 0:
                if (type == ND_REDIRECT) {
                        icmp6_redirect_output(mcopy, rt);
-                       goto freert;
+                       goto out;
                }
                goto freecopy;
 
@@ -481,17 +483,10 @@ senderr:
                break;
        }
        icmp6_error(mcopy, type, code, 0);
-       goto freert;
+       goto out;
 
- freecopy:
+freecopy:
        m_freem(mcopy);
- freert:
-#ifndef SMALL_KERNEL
-       if (ip6_multipath && ip6_forward_rt.ro_rt &&
-           (ip6_forward_rt.ro_rt->rt_flags & RTF_MPATH)) {
-               rtfree(ip6_forward_rt.ro_rt);
-               ip6_forward_rt.ro_rt = NULL;
-       }
-#endif
+out:
        if_put(ifp);
 }
Index: netinet6/ip6_input.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.157
diff -u -p -r1.157 ip6_input.c
--- netinet6/ip6_input.c        11 Apr 2016 13:02:35 -0000      1.157
+++ netinet6/ip6_input.c        11 Apr 2016 13:21:45 -0000
@@ -422,6 +422,7 @@ ip6_input(struct mbuf *m)
         *  Unicast check
         */
        if (rtisvalid(ip6_forward_rt.ro_rt) &&
+           !ISSET(ip6_forward_rt.ro_rt->rt_flags, RTF_MPATH) &&
            IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
                               &ip6_forward_rt.ro_dst.sin6_addr) &&
            rtableid == ip6_forward_rt.ro_tableid)

Reply via email to