tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Changing the default subnet route.



On Sun, 2008-12-07 at 18:24 +0000, Roy Marples wrote:
> On Fri, 2008-12-05 at 17:04 +0000, Christos Zoulas wrote:
> > Send-pr please.
> 
> Filed as kern/40133.
> 
> I think the issue is because IFA_ROUTE isn't moved correctly as I've
> looked closely at address addition/deletion but not yet route changing.

Well, I was wrong about the cause :)
The error is that in_addprefix assumes that only it will add subnet
routes. So any manually added routes will cause this error. Attached is
a patch to fix this (in.diff).

Also, I think that for deleted routes, we should scrub the IFA_ROUTE
flag from the ia, and preserve it when when changing routes. This has no
bearing on the issue at hand, but does make sense imo.

Comments?

Thanks

Roy
Index: sys/netinet/in.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/in.c,v
retrieving revision 1.128
diff -u -p -r1.128 in.c
--- sys/netinet/in.c    7 Nov 2008 00:20:18 -0000       1.128
+++ sys/netinet/in.c    13 Dec 2008 23:56:43 -0000
@@ -1006,6 +1006,11 @@ in_addprefix(struct in_ifaddr *target, i
        error = rtinit(&target->ia_ifa, RTM_ADD, flags);
        if (error == 0)
                target->ia_flags |= IFA_ROUTE;
+       else if (error == EEXIST)
+               /* 
+                * the fact the route already exists is not an error.
+                */ 
+               error = 0;
        return error;
 }
 
Index: sys/net/rtsock.c
===================================================================
RCS file: /cvsroot/src/sys/net/rtsock.c,v
retrieving revision 1.116
diff -u -p -r1.116 rtsock.c
--- sys/net/rtsock.c    7 Nov 2008 00:20:13 -0000       1.116
+++ sys/net/rtsock.c    13 Dec 2008 23:56:42 -0000
@@ -212,9 +212,9 @@ route_output(struct mbuf *m, ...)
        struct rtentry *rt = NULL;
        struct rtentry *saved_nrt = NULL;
        struct rt_addrinfo info;
-       int len, error = 0;
+       int len, error = 0, ifa_route = 0;
        struct ifnet *ifp = NULL;
-       struct ifaddr *ifa = NULL;
+       struct ifaddr *ifa = NULL, *oifa;
        struct socket *so;
        va_list ap;
        sa_family_t family;
@@ -291,6 +291,12 @@ route_output(struct mbuf *m, ...)
                error = rtrequest1(rtm->rtm_type, &info, &saved_nrt);
                if (error == 0) {
                        (rt = saved_nrt)->rt_refcnt++;
+                       ifa = rt_get_ifa(rt);
+                       /*
+                        * If deleting an automatic route, scrub the flag.
+                        */
+                       if (ifa->ifa_flags & IFA_ROUTE)
+                               ifa->ifa_flags &= ~IFA_ROUTE;
                        goto report;
                }
                break;
@@ -409,13 +415,28 @@ route_output(struct mbuf *m, ...)
                            rt_getkey(rt), info.rti_info[RTAX_GATEWAY])))) {
                                ifp = ifa->ifa_ifp;
                        }
+                       oifa = rt->rt_ifa;
+                       if (oifa && oifa->ifa_flags & IFA_ROUTE) {
+                               /*
+                                * If changing an automatically added route,
+                                * remove the flag and store the fact.
+                                */
+                               oifa->ifa_flags &= ~IFA_ROUTE;
+                               ifa_route = 1;
+                       }
                        if (ifa) {
-                               struct ifaddr *oifa = rt->rt_ifa;
                                if (oifa != ifa) {
                                        if (oifa && oifa->ifa_rtrequest) {
                                                oifa->ifa_rtrequest(RTM_DELETE,
                                                    rt, &info);
                                        }
+                                       /*
+                                        * If changing an automatically added
+                                        * route, store this if not static.
+                                        */
+                                       if (ifa_route &&
+                                           !(rt->rt_flags & RTF_STATIC))
+                                               ifa->ifa_flags |= IFA_ROUTE;
                                        rt_replace_ifa(rt, ifa);
                                        rt->rt_ifp = ifp;
                                }

Attachment: signature.asc
Description: This is a digitally signed message part



Home | Main Index | Thread Index | Old Index