The problem as I saw it was that a route was being added to the routing
tables in the kernel even in the case where the interface pointer in
the route structure was a null, this was fine until an atempt was made
to remove this route at which point a zero derefernce was "commited" and
the inevitable core was dumped. The easy solution turns out to be to
check for a null interface pointer and not add the route. The only time
I've observed the problem is when adding a route to the local end of a
point to point connection (SLIP or PPP).
rt->rt_flags = RTF_UP | flags;
rt->rt_state = state | RTS_CHANGED;
rt->rt_ifp = if_ifwithdstaddr(&rt->rt_dst);
rt->rt_flags = RTF_UP | flags;
rt->rt_state = state | RTS_CHANGED;
rt->rt_ifp = if_ifwithdstaddr(&rt->rt_dst);
rt->rt_ifp = if_ifwithnet(&rt->rt_router);
rt->rt_ifp = if_ifwithnet(&rt->rt_router);
+ /*
+ * seems like we can't figure out the interface for the
+ * IP address of the local side of a point to point
+ * connection, we just don't add that entry in the
+ * table. (it seems to already be there anyway)
+ */
+ if (rt->rt_ifp == 0) {
+ syslog(LOG_DEBUG,
+ "rtadd: can't get interface for %s",
+ (*afswitch[dst->sa_family].af_format)(dst));
+ return;
+ }
+ }
if ((state & RTS_INTERFACE) == 0)
rt->rt_flags |= RTF_GATEWAY;
rt->rt_metric = metric;
if ((state & RTS_INTERFACE) == 0)
rt->rt_flags |= RTF_GATEWAY;
rt->rt_metric = metric;
if (add) {
rt->rt_router = *gate;
rt->rt_ifp = if_ifwithdstaddr(&rt->rt_router);
if (add) {
rt->rt_router = *gate;
rt->rt_ifp = if_ifwithdstaddr(&rt->rt_router);
rt->rt_ifp = if_ifwithnet(&rt->rt_router);
rt->rt_ifp = if_ifwithnet(&rt->rt_router);
+ /*
+ * seems like we can't figure out the interface for the
+ * IP address of the local side of a point to point
+ * connection, we just don't add that entry in the
+ * table. (it seems to already be there anyway)
+ */
+ if (rt->rt_ifp == 0) {
+ struct sockaddr *dst = &(rt->rt_dst);
+ syslog(LOG_DEBUG,
+ "rtchange: can't get interface for %s",
+ (*afswitch[dst->sa_family].af_format)(dst));
+ return;
+ }
+ }
}
rt->rt_metric = metric;
rt->rt_state |= RTS_CHANGED;
}
rt->rt_metric = metric;
rt->rt_state |= RTS_CHANGED;
rt->rt_flags = RTF_UP | flags;
rt->rt_state = state | RTS_CHANGED;
rt->rt_ifp = if_ifwithdstaddr(&rt->rt_dst);
rt->rt_flags = RTF_UP | flags;
rt->rt_state = state | RTS_CHANGED;
rt->rt_ifp = if_ifwithdstaddr(&rt->rt_dst);
rt->rt_ifp = if_ifwithnet(&rt->rt_router);
rt->rt_ifp = if_ifwithnet(&rt->rt_router);
+ /*
+ * seems like we can't figure out the interface for the
+ * IP address of the local side of a point to point
+ * connection, we just don't add that entry in the
+ * table. (it seems to already be there anyway)
+ */
+ if (rt->rt_ifp == 0) {
+ syslog(LOG_DEBUG,
+ "rtadd: can't get interface for %s",
+ (*afswitch[dst->sa_family].af_format)(dst));
+ return;
+ }
+ }
if ((state & RTS_INTERFACE) == 0)
rt->rt_flags |= RTF_GATEWAY;
rt->rt_metric = metric;
if ((state & RTS_INTERFACE) == 0)
rt->rt_flags |= RTF_GATEWAY;
rt->rt_metric = metric;
if (add) {
rt->rt_router = *gate;
rt->rt_ifp = if_ifwithdstaddr(&rt->rt_router);
if (add) {
rt->rt_router = *gate;
rt->rt_ifp = if_ifwithdstaddr(&rt->rt_router);
rt->rt_ifp = if_ifwithnet(&rt->rt_router);
rt->rt_ifp = if_ifwithnet(&rt->rt_router);
+ /*
+ * seems like we can't figure out the interface for the
+ * IP address of the local side of a point to point
+ * connection, we just don't add that entry in the
+ * table. (it seems to already be there anyway)
+ */
+ if (rt->rt_ifp == 0) {
+ struct sockaddr *dst = &(rt->rt_dst);
+ syslog(LOG_DEBUG,
+ "rtchange: can't get interface for %s",
+ (*afswitch[dst->sa_family].af_format)(dst));
+ return;
+ }
+ }
}
rt->rt_metric = metric;
rt->rt_state |= RTS_CHANGED;
}
rt->rt_metric = metric;
rt->rt_state |= RTS_CHANGED;