This single cached route is a nice trick for having higher forwarding
numbers w/ benchmarks.  But as soon as you start forwarding packets to
different end addresses, even using a single next hop, it becomes
useless.

Since this single cached route won't fly with multiple forwarding paths
and it also makes some upcoming refactoring more complicated I'd like to
kill it now.

Note that with PF disable the kernel is currently doing 2 lookups per
forwarded packet.  One to check if the packet needs to be delivered
locally and a second one, probably cached by ``ipforward_rt'', to find
the next hop.

My goal is to change the kernel to just do a single lookup per packet,
so even without ``ipforward_rt'', the performances will be the same.

Once that's done, I'll merge the multicast address lookup with this
single route lookup, for obvious reasons.

Ok?

Index: netinet/ip_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.273
diff -u -p -r1.273 ip_input.c
--- netinet/ip_input.c  19 Apr 2016 08:23:13 -0000      1.273
+++ netinet/ip_input.c  19 Apr 2016 08:55:59 -0000
@@ -197,8 +197,6 @@ ip_init(void)
        mq_init(&ipsend_mq, 64, IPL_SOFTNET);
 }
 
-struct route ipforward_rt;
-
 void
 ipintr(void)
 {
@@ -972,10 +970,6 @@ ip_slowtimo(void)
                        ip_freef(fp);
                }
        }
-       if (ipforward_rt.ro_rt) {
-               rtfree(ipforward_rt.ro_rt);
-               ipforward_rt.ro_rt = NULL;
-       }
        splx(s);
 }
 
@@ -1399,8 +1393,8 @@ ip_forward(struct mbuf *m, struct ifnet 
        struct ip *ip = mtod(m, struct ip *);
        struct sockaddr_in *sin;
        struct rtentry *rt;
+       struct route ro;
        int error, type = 0, code = 0, destmtu = 0, fake = 0, len;
-       u_int rtableid = 0;
        u_int32_t dest;
 
        dest = 0;
@@ -1414,29 +1408,18 @@ ip_forward(struct mbuf *m, struct ifnet 
                return;
        }
 
-       rtableid = m->m_pkthdr.ph_rtableid;
 
-       rt = ipforward_rt.ro_rt;
-       sin = satosin(&ipforward_rt.ro_dst);
-       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) {
-                       rtfree(ipforward_rt.ro_rt);
-                       ipforward_rt.ro_rt = NULL;
-               }
-               sin->sin_family = AF_INET;
-               sin->sin_len = sizeof(*sin);
-               sin->sin_addr = ip->ip_dst;
-               ipforward_rt.ro_tableid = rtableid;
-
-               ipforward_rt.ro_rt = rtalloc_mpath(&ipforward_rt.ro_dst,
-                   &ip->ip_src.s_addr, ipforward_rt.ro_tableid);
-               if (ipforward_rt.ro_rt == 0) {
-                       icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
-                       return;
-               }
-               rt = ipforward_rt.ro_rt;
+       sin = satosin(&ro.ro_dst);
+       memset(sin, 0, sizeof(*sin));
+       sin->sin_family = AF_INET;
+       sin->sin_len = sizeof(*sin);
+       sin->sin_addr = ip->ip_dst;
+
+       rt = rtalloc_mpath(sintosa(sin), &ip->ip_src.s_addr,
+           m->m_pkthdr.ph_rtableid);
+       if (rt == NULL) {
+               icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
+               return;
        }
 
        /*
@@ -1488,7 +1471,8 @@ ip_forward(struct mbuf *m, struct ifnet 
                }
        }
 
-       error = ip_output(m, NULL, &ipforward_rt,
+       ro.ro_rt = rt;
+       error = ip_output(m, NULL, &ro,
            (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)),
            NULL, NULL, 0);
        if (error)
@@ -1501,7 +1485,7 @@ ip_forward(struct mbuf *m, struct ifnet 
                        goto freecopy;
        }
        if (!fake)
-               return;
+               goto freecopy;
 
        switch (error) {
 
@@ -1559,9 +1543,10 @@ ip_forward(struct mbuf *m, struct ifnet 
        if (mcopy)
                icmp_error(mcopy, type, code, dest, destmtu);
 
- freecopy:
+freecopy:
        if (fake)
                m_tag_delete_chain(&mfake);
+       rtfree(rt);
 }
 
 int

Reply via email to