Here a route lookup is done to find an existing ``ifa'' in order to
attach a new route.

This code runs under KERNEL_LOCK and returns a route entry found in
the table (RT_VALID), so rtfree(9) will not free the route.

Note that it is safe to rtfree() a route entry while keeping a pointer
to a *valid* ``ifa'' because ifa insertion/removal are serialized by
the KERNEL_LOCK.  Yes, route entries increment ifas refcounter but this
only matters for stall ifas, and there's already a check for that here.

Ok?

Index: net/route.c
===================================================================
RCS file: /cvs/src/sys/net/route.c,v
retrieving revision 1.220
diff -u -p -r1.220 route.c
--- net/route.c 17 Aug 2015 09:50:12 -0000      1.220
+++ net/route.c 17 Aug 2015 10:25:24 -0000
@@ -666,14 +666,18 @@ ifa_ifwithroute(int flags, struct sockad
                struct rtentry  *rt = rtalloc(gateway, 0, rtableid);
                if (rt == NULL)
                        return (NULL);
-               rt->rt_refcnt--;
                /* The gateway must be local if the same address family. */
                if ((rt->rt_flags & RTF_GATEWAY) &&
-                   rt_key(rt)->sa_family == dst->sa_family)
+                   rt_key(rt)->sa_family == dst->sa_family) {
+                       rtfree(rt);
                        return (NULL);
+               }
                ifa = rt->rt_ifa;
-               if (ifa == NULL || ifa->ifa_ifp == NULL)
+               if (ifa == NULL || ifa->ifa_ifp == NULL) {
+                       rtfree(rt);
                        return (NULL);
+               }
+               rtfree(rt);
        }
        if (ifa->ifa_addr->sa_family != dst->sa_family) {
                struct ifaddr   *oifa = ifa;

Reply via email to