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