diff options
| author | Roy Marples <roy@marples.name> | 2009-01-26 22:32:42 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2009-01-26 22:32:42 +0000 |
| commit | 16687a3be1f8c1e6d55cdd691e947e5760eef30c (patch) | |
| tree | 81ecc57612e06ddcc51dd29a6473ec5aea736f44 | |
| parent | 495c0a77ac4caba2360004b64a1f563d682ac7ee (diff) | |
| download | dhcpcd-16687a3be1f8c1e6d55cdd691e947e5760eef30c.tar.xz | |
We need to ensure that manual route deletions are deleted from our internal routing table also. Partial fix for #159.
| -rw-r--r-- | configure.c | 28 | ||||
| -rw-r--r-- | configure.h | 3 | ||||
| -rw-r--r-- | if-bsd.c | 32 |
3 files changed, 63 insertions, 0 deletions
diff --git a/configure.c b/configure.c index 3b4b2124..96d8d886 100644 --- a/configure.c +++ b/configure.c @@ -62,6 +62,7 @@ static struct rt *routes; + static int exec_script(char *const *argv, char *const *env) { @@ -388,6 +389,33 @@ desc_route(const char *cmd, const struct rt *rt, const char *ifname) addr, inet_ntocidr(rt->net), inet_ntoa(rt->gate)); } +/* If something other than dhcpcd removes a route, + * we need to remove it from our internal table. */ +int +route_deleted(const struct in_addr *dst, + const struct in_addr *net, + const struct in_addr *gate) +{ + struct rt rt, *f, *l; + + rt.dest.s_addr = dst->s_addr; + rt.net.s_addr = net->s_addr; + rt.gate.s_addr = gate->s_addr; + rt.iface = NULL; + rt.next = NULL; + + f = find_route(routes, &rt, &l, NULL); + if (f == NULL) + return 0; + desc_route("removing", f, f->iface->name); + if (l) + l->next = f->next; + else + routes = f->next; + free(f); + return 1; +} + static int n_route(struct rt *rt, const struct interface *iface) { diff --git a/configure.h b/configure.h index 5ee4ab8a..5d0124de 100644 --- a/configure.h +++ b/configure.h @@ -33,5 +33,8 @@ int send_interface(int, const struct interface *); int run_script(const struct interface *); int configure(struct interface *); +int route_deleted(const struct in_addr *, + const struct in_addr *, + const struct in_addr *); #endif @@ -51,10 +51,14 @@ #include "config.h" #include "common.h" +#include "configure.h" #include "dhcp.h" #include "if-options.h" #include "net.h" +#define ROUNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) + /* Darwin doesn't define this for some very odd reason */ #ifndef SA_SIZE # define SA_SIZE(sa) \ @@ -312,6 +316,9 @@ manage_link(int fd, struct rt_msghdr *rtm; struct if_announcemsghdr *ifa; struct if_msghdr *ifm; + struct in_addr dst, net, gate; + struct sockaddr *sa; + struct sockaddr_in *sin; for (;;) { bytes = read(fd, buffer, BUFFER_LEN); @@ -343,6 +350,31 @@ manage_link(int fd, if (if_indextoname(ifm->ifm_index, ifname)) if_carrier(ifname); break; + case RTM_DELETE: + if (!(rtm->rtm_addrs & RTA_DST) || + !(rtm->rtm_addrs & RTA_GATEWAY) || + !(rtm->rtm_addrs & RTA_NETMASK)) + break; + if (rtm->rtm_pid == getpid()) + break; + sa = (struct sockaddr *)(rtm + 1); + if (sa->sa_family != AF_INET) + break; + sin = (struct sockaddr_in *)sa; + memcpy(&dst.s_addr, &sin->sin_addr.s_addr, + sizeof(dst.s_addr)); + sa = (struct sockaddr *) + (ROUNDUP(sa->sa_len) + (char *)sa); + sin = (struct sockaddr_in *)sa; + memcpy(&gate.s_addr, &sin->sin_addr.s_addr, + sizeof(gate.s_addr)); + sa = (struct sockaddr *) + (ROUNDUP(sa->sa_len) + (char *)sa); + sin = (struct sockaddr_in *)sa; + memcpy(&net.s_addr, &sin->sin_addr.s_addr, + sizeof(net.s_addr)); + route_deleted(&dst, &net, &gate); + break; } } } |
