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