diff options
-rw-r--r-- | sbin/dhclient/dhclient.c | 4 | ||||
-rw-r--r-- | sbin/dhclient/dhcpd.h | 4 | ||||
-rw-r--r-- | sbin/dhclient/kroute.c | 44 | ||||
-rw-r--r-- | sbin/dhclient/privsep.h | 3 |
4 files changed, 41 insertions, 14 deletions
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index f0ac46023fc..48316869437 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhclient.c,v 1.210 2013/01/16 21:35:41 krw Exp $ */ +/* $OpenBSD: dhclient.c,v 1.211 2013/01/17 23:41:07 krw Exp $ */ /* * Copyright 2004 Henning Brauer <henning@openbsd.org> @@ -723,7 +723,7 @@ bind_lease(void) char *domainname, *nameservers; delete_addresses(ifi->name, ifi->rdomain); - flush_routes_and_arp_cache(ifi->rdomain); + flush_routes_and_arp_cache(ifi->name, ifi->rdomain); lease = apply_defaults(client->new); options = lease->options; diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h index 019e93edb42..65be050d33e 100644 --- a/sbin/dhclient/dhcpd.h +++ b/sbin/dhclient/dhcpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcpd.h,v 1.102 2013/01/16 21:35:41 krw Exp $ */ +/* $OpenBSD: dhcpd.h,v 1.103 2013/01/17 23:41:07 krw Exp $ */ /* * Copyright (c) 2004 Henning Brauer <henning@openbsd.org> @@ -327,6 +327,6 @@ void delete_address(char *, int, struct in_addr); void add_address(char *, int, struct in_addr, struct in_addr); -void flush_routes_and_arp_cache(int); +void flush_routes_and_arp_cache(char *, int); void add_default_route(int, struct in_addr, struct in_addr); diff --git a/sbin/dhclient/kroute.c b/sbin/dhclient/kroute.c index b7189da9fd4..7b3348f3b7e 100644 --- a/sbin/dhclient/kroute.c +++ b/sbin/dhclient/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.26 2012/12/29 14:40:00 krw Exp $ */ +/* $OpenBSD: kroute.c,v 1.27 2013/01/17 23:41:07 krw Exp $ */ /* * Copyright 2012 Kenneth R Westerback <krw@openbsd.org> @@ -36,13 +36,14 @@ struct in_addr active_addr; * arp -dan */ void -flush_routes_and_arp_cache(int rdomain) +flush_routes_and_arp_cache(char *ifname, int rdomain) { struct imsg_flush_routes imsg; int rslt; memset(&imsg, 0, sizeof(imsg)); + strlcpy(imsg.ifname, ifname, sizeof(imsg.ifname)); imsg.rdomain = rdomain; rslt = imsg_compose(unpriv_ibuf, IMSG_FLUSH_ROUTES, 0, 0, -1, @@ -61,6 +62,7 @@ flush_routes_and_arp_cache(int rdomain) void priv_flush_routes_and_arp_cache(struct imsg_flush_routes *imsg) { + char ifname[IF_NAMESIZE]; struct sockaddr *rti_info[RTAX_MAX]; int mib[7]; size_t needed; @@ -68,6 +70,7 @@ priv_flush_routes_and_arp_cache(struct imsg_flush_routes *imsg) struct rt_msghdr *rtm; struct sockaddr *sa; struct sockaddr_dl *sdl; + struct sockaddr_in *sa_in; struct sockaddr_inarp *sin; struct sockaddr_rtlabel *sa_rl; int s, seqno = 0, rlen, i; @@ -125,11 +128,19 @@ priv_flush_routes_and_arp_cache(struct imsg_flush_routes *imsg) sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); - if (rti_info[RTAX_LABEL]) { - sa_rl = (struct sockaddr_rtlabel *)rti_info[RTAX_LABEL]; - if (strcmp(routelabel, sa_rl->sr_label)) + sa_rl = (struct sockaddr_rtlabel *)rti_info[RTAX_LABEL]; + if (sa_rl) { + /* Always delete routes we labeled. */ + if (strcmp(routelabel, sa_rl->sr_label) == 0) + goto delete; + + /* Never delete routes labelled by another dhclient. */ + if (strlen(sa_rl->sr_label) > 8 && + strncmp("DHCLIENT ", sa_rl->sr_label, 9) == 0) continue; - } else if (rtm->rtm_flags & RTF_LLINFO) { + } + + if (rtm->rtm_flags & RTF_LLINFO) { if (rtm->rtm_flags & RTF_GATEWAY) continue; @@ -149,14 +160,29 @@ priv_flush_routes_and_arp_cache(struct imsg_flush_routes *imsg) case IFT_ISO88025: case IFT_CARP: /* Delete it. */ - break; + goto delete; default: - continue; + break; } } - } else continue; + } + + if (rtm->rtm_flags & RTF_GATEWAY) { + memset(ifname, 0, sizeof(ifname)); + if (if_indextoname(rtm->rtm_index, ifname) == NULL) + continue; + sa_in = (struct sockaddr_in *)rti_info[RTAX_NETMASK]; + if (sa_in && + sa_in->sin_addr.s_addr == INADDR_ANY && + rtm->rtm_tableid == imsg->rdomain && + strcmp(imsg->ifname, ifname) == 0) + goto delete; + } + + continue; +delete: rtm->rtm_type = RTM_DELETE; rtm->rtm_seq = seqno; rtm->rtm_tableid = imsg->rdomain; diff --git a/sbin/dhclient/privsep.h b/sbin/dhclient/privsep.h index 8e4e09c481a..25839726771 100644 --- a/sbin/dhclient/privsep.h +++ b/sbin/dhclient/privsep.h @@ -1,4 +1,4 @@ -/* $OpenBSD: privsep.h,v 1.11 2013/01/15 21:44:28 krw Exp $ */ +/* $OpenBSD: privsep.h,v 1.12 2013/01/17 23:41:07 krw Exp $ */ /* * Copyright (c) 2004 Henning Brauer <henning@openbsd.org> @@ -47,6 +47,7 @@ struct imsg_add_address { }; struct imsg_flush_routes { + char ifname[IFNAMSIZ]; int rdomain; }; |