tech-net archive

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

Re: [PATCH] Deletion of route scrubs ifa flag IFA_ROUTE even if it's not the automatic route



On Tue, 2009-03-03 at 22:47 +0000, Roy Marples wrote:
> To make ammends, attached is a patch to fix this. It is intended for
> pullup to netbsd-5.

For reference, here is the new patch, but targeted for code before my
origonal patches were applied. It's been hand crafted to remove any
changes done in the meantime, so it may not apply cleanly.

Thanks

Roy
Index: sys/net/rtsock.c
===================================================================
RCS file: /cvsroot/src/sys/net/rtsock.c,v
retrieving revision 1.118
diff -u -p -r1.118 rtsock.c
--- sys/net/rtsock.c    17 Dec 2008 20:51:37 -0000      1.118
+++ sys/net/rtsock.c    5 Mar 2009 18:13:40 -0000
@@ -213,9 +222,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;
@@ -345,12 +354,12 @@ route_output(struct mbuf *m, ...)
                                if (info.rti_info[RTAX_IFA]->sa_family ==
                                    AF_INET) {
                                        printf("%s: copying out RTAX_IFA %s ",
-                                           __func__, inet_ntoa(
+                                           __func__, inet_ntoa((
                                            (const struct sockaddr_in *)
-                                           info.rti_info[RTAX_IFA])->sin_addr);
+                                           
info.rti_info[RTAX_IFA])->sin_addr));
                                        printf("for info.rti_info[RTAX_DST] %s "
                                            "ifa_getifa %p ifa_seqno %p\n",
-                                           inet_ntoa(
+                                           inet_ntoa((
                                            (const struct sockaddr_in *)
                                            info.rti_info[RTAX_DST])->sin_addr),
                                            (void *)rtifa->ifa_getifa,
@@ -409,16 +418,21 @@ route_output(struct mbuf *m, ...)
                            rt_getkey(rt), info.rti_info[RTAX_GATEWAY])))) {
                                ifp = ifa->ifa_ifp;
                        }
-                       if (ifa) {
-                               struct ifaddr *oifa = rt->rt_ifa;
-                               if (oifa != ifa) {
-                                       if (oifa && oifa->ifa_rtrequest) {
+                       oifa = rt->rt_ifa;
+                       if (ifa && oifa != ifa) {
+                               if (oifa) {
+                                       if (oifa->ifa_flags & IFA_ROUTE) {
+                                               oifa->ifa_flags &= ~IFA_ROUTE;
+                                               ifa_route = 1;
+                                       }
+                                       if (oifa->ifa_rtrequest)
                                                oifa->ifa_rtrequest(RTM_DELETE,
                                                    rt, &info);
-                                       }
-                                       rt_replace_ifa(rt, ifa);
-                                       rt->rt_ifp = ifp;
                                }
+                               if (ifa_route)
+                                       ifa->ifa_flags |= IFA_ROUTE;
+                               rt_replace_ifa(rt, ifa);
+                               rt->rt_ifp = ifp;
                        }
                        rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx,
                            &rt->rt_rmx);
Index: sys/net/route.c
===================================================================
RCS file: /cvsroot/src/sys/net/route.c,v
retrieving revision 1.115
diff -u -p -r1.115 route.c
--- sys/net/route.c     20 Feb 2009 10:57:19 -0000      1.115
+++ sys/net/route.c     5 Mar 2009 18:10:15 -0000
@@ -628,7 +628,7 @@ int
 rtrequest1(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt)
 {
        int s = splsoftnet();
-       int error = 0;
+       int error = 0, scrub_ifa = 0;
        struct rtentry *rt, *crt;
        struct radix_node *rn;
        struct radix_node_head *rnh;
@@ -658,6 +658,20 @@ rtrequest1(int req, struct rt_addrinfo *
                        /* clean up any cloned children */
                        rtflushclone(dst->sa_family, rt);
                }
+               if ((ifa = rt->rt_ifa) != NULL &&
+                   ifa->ifa_netmask != NULL &&
+                   netmask != NULL &&
+                   ifa->ifa_flags & IFA_ROUTE)
+               {
+                       rt_maskedcopy(dst,
+                           (struct sockaddr *)&maskeddst,
+                           ifa->ifa_netmask);
+                       dst = (struct sockaddr *)&maskeddst;
+                       rn = rnh->rnh_lookup(dst, ifa->ifa_netmask,
+                           rnh);
+                       if ((struct rtentry *)rn == rt)
+                               scrub_ifa = 1;
+               }
                if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == NULL)
                        senderr(ESRCH);
                if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))
@@ -672,8 +686,12 @@ rtrequest1(int req, struct rt_addrinfo *
                        rt->rt_parent = NULL;
                }
                rt->rt_flags &= ~RTF_UP;
-               if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)
-                       ifa->ifa_rtrequest(RTM_DELETE, rt, info);
+               if (ifa != NULL) {
+                       if (ifa->ifa_rtrequest)
+                               ifa->ifa_rtrequest(RTM_DELETE, rt, info);
+                       if (scrub_ifa)
+                               ifa->ifa_flags &= ~IFA_ROUTE;
+               }
                rttrash++;
                if (ret_nrt)
                        *ret_nrt = rt;
@@ -690,9 +708,8 @@ rtrequest1(int req, struct rt_addrinfo *
                        senderr(EINVAL);
                ifa = rt->rt_ifa;
                flags = rt->rt_flags & ~(RTF_CLONING | RTF_STATIC);
-               flags |= RTF_CLONED;
+               flags |= RTF_CLONED | RTF_HOST;
                gateway = rt->rt_gateway;
-               flags |= RTF_HOST;
                goto makeroute;
 
        case RTM_ADD:
Index: sys/netinet/in.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/in.c,v
retrieving revision 1.129
diff -u -p -r1.129 in.c
--- sys/netinet/in.c    17 Dec 2008 20:51:37 -0000      1.129
+++ sys/netinet/in.c    5 Mar 2009 18:11:47 -0000
@@ -1000,8 +993,11 @@ in_addprefix(struct in_ifaddr *target, i
 
        /*
         * noone seem to have prefix route.  insert it.
+        * if it already exists, mark ourselves as having it.
         */
        error = rtinit(&target->ia_ifa, RTM_ADD, flags);
+       if (error == EEXIST)
+               error = 0; /* XXX: We should remove and re-add the route */
        if (error == 0)
                target->ia_flags |= IFA_ROUTE;
        return error;

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



Home | Main Index | Thread Index | Old Index