This problem still affects the FreeBSD kernel in 4.0 and 5.0.

A patch file for 4.0-STABLE follows, I've tested this on 4.0-RELEASE and
4.0-STABLE (incl. SMP for what it's worth).

There is no difference between route.c at HEAD(5.0-current) and 
RELENG_4(4.0-stable) so this patch should work effectively in both of
the aforementioned.  And it does still fix my routing troubles.

--- route.c.orig        Sat May 27 14:48:42 2000
+++ route.c     Sat May 27 15:01:43 2000
@@ -400,6 +400,9 @@
        struct sockaddr *dst, *gateway;
 {
        register struct ifaddr *ifa;
+       struct rtentry *rt;
+
+       ifa = 0;
        if ((flags & RTF_GATEWAY) == 0) {
                /*
                 * If we are adding a route to an interface,
@@ -408,7 +411,6 @@
                 * as our clue to the interface.  Otherwise
                 * we can use the local address.
                 */
-               ifa = 0;
                if (flags & RTF_HOST) {
                        ifa = ifa_ifwithdstaddr(dst);
                }
@@ -425,18 +427,33 @@
        if (ifa == 0)
                ifa = ifa_ifwithnet(gateway);
        if (ifa == 0) {
-               struct rtentry *rt = rtalloc1(dst, 0, 0UL);
-               if (rt == 0)
-                       return (0);
-               rt->rt_refcnt--;
-               if ((ifa = rt->rt_ifa) == 0)
-                       return (0);
+               rt = rtalloc1(dst, 0, 0UL);
+               if (rt) {
+                       rt->rt_refcnt--;
+                       if (rt->rt_ifa)
+                               ifa = rt->rt_ifa;
+               }
        }
-       if (ifa->ifa_addr->sa_family != dst->sa_family) {
+       if ((ifa) && (ifa->ifa_addr->sa_family != dst->sa_family)) {
                struct ifaddr *oifa = ifa;
                ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
                if (ifa == 0)
                        ifa = oifa;
+       }
+       /* 
+        * If we are adding a gateway, it is quite
+        * possible that the routing table has a static
+        * entry in place for the gateway, that may
+        * not agree with the info from the interfaces.
+        * The routing table should carry more precedence
+        * than the interfaces in this matter.
+        * Must be careful not to stomp on new entries from 
+        * rtinit, hence (ifa->ifa_addr !=gateway).
+        */
+       if ((ifa == 0 || ifa->ifa_addr != gateway) &&
+                       (rt = rtalloc1(gateway,0,0UL))) {
+               rt->rt_refcnt--;
+               ifa = rt->rt_ifa;
        }
        return (ifa);
 }


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to