summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2012-10-31 15:50:48 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2012-10-31 15:50:48 +0000
commit61e214650ded5bea555057e64d12f914979673ef (patch)
treea3db9ffe5cecd82cd68619fa99d64299949b630b /sbin
parent57ae29bdd91de0e836aa6f560c21e75d53a92153 (diff)
Forcibly delete all existing ipv4 addresses from an interface when
binding a lease to that interface. This fixes issues sthen@ found with unexpectedly persistant addresses and failures of dhclient when switching an interface repeatedly between different networks. This crude but predictable behaviour may be toned down once it is figured out what we want to do with mixed static/dynamic configurations on an interface. ok sthen@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/dhclient/dhclient.c8
-rw-r--r--sbin/dhclient/dhcpd.h13
-rw-r--r--sbin/dhclient/kroute.c38
3 files changed, 46 insertions, 13 deletions
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c
index b80b7a2e091..b8df58dc440 100644
--- a/sbin/dhclient/dhclient.c
+++ b/sbin/dhclient/dhclient.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhclient.c,v 1.159 2012/10/30 18:39:44 krw Exp $ */
+/* $OpenBSD: dhclient.c,v 1.160 2012/10/31 15:50:47 krw Exp $ */
/*
* Copyright 2004 Henning Brauer <henning@openbsd.org>
@@ -665,11 +665,7 @@ bind_lease(void)
in_addr_t *mask = NULL;
char *domainname, *nameservers;
- if (client->active) {
- delete_old_address(ifi->name, ifi->rdomain,
- client->active->address);
- }
-
+ delete_old_addresses(ifi->name, ifi->rdomain);
flush_routes_and_arp_cache(ifi->name, ifi->rdomain);
lease = apply_defaults(client->new);
diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h
index 3f92d71582f..af95ddb37f9 100644
--- a/sbin/dhclient/dhcpd.h
+++ b/sbin/dhclient/dhcpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhcpd.h,v 1.83 2012/10/30 18:39:44 krw Exp $ */
+/* $OpenBSD: dhcpd.h,v 1.84 2012/10/31 15:50:47 krw Exp $ */
/*
* Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
@@ -334,12 +334,13 @@ int parse_option_decl(FILE *, struct option_data *);
void parse_string_list(FILE *, struct string_list **, int);
void parse_reject_statement(FILE *);
-/* route.c */
-void delete_old_address (char *, int, struct iaddr);
-void priv_delete_old_address (char *, int, struct iaddr);
+/* kroute.c */
+void delete_old_addresses(char *, int);
+void delete_old_address(char *, int, struct iaddr);
+void priv_delete_old_address(char *, int, struct iaddr);
-void add_new_address (char *, int, struct iaddr, in_addr_t *);
-void priv_add_new_address (char *, int, struct iaddr, in_addr_t);
+void add_new_address(char *, int, struct iaddr, in_addr_t *);
+void priv_add_new_address(char *, int, struct iaddr, in_addr_t);
void flush_routes_and_arp_cache(char *, int);
void priv_flush_routes_and_arp_cache(char *, int);
diff --git a/sbin/dhclient/kroute.c b/sbin/dhclient/kroute.c
index 47b7d75a9eb..5c290f42523 100644
--- a/sbin/dhclient/kroute.c
+++ b/sbin/dhclient/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.1 2012/10/30 16:41:28 krw Exp $ */
+/* $OpenBSD: kroute.c,v 1.2 2012/10/31 15:50:47 krw Exp $ */
/*
* Copyright 2012 Kenneth R Westerback <krw@openbsd.org>
@@ -26,6 +26,8 @@
#include <net/if_types.h>
#include <net/if.h>
+#include <ifaddrs.h>
+
#include "dhcpd.h"
#include "privsep.h"
@@ -338,6 +340,40 @@ priv_add_default_route(char *ifname, int rdomain, struct iaddr addr,
}
/*
+ * Delete all existing inet addresses on interface.
+ */
+void
+delete_old_addresses(char *ifname, int rdomain)
+{
+ struct iaddr addr;
+ struct ifaddrs *ifap, *ifa;
+
+ if (getifaddrs(&ifap) != 0)
+ error("delete_old_addresses getifaddrs: %m");
+
+ if (sizeof(struct in_addr) > sizeof(addr.iabuf))
+ error("king bula sez: len mismatch in delete_old_addresses");
+
+ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ if ((ifa->ifa_flags & IFF_LOOPBACK) ||
+ (ifa->ifa_flags & IFF_POINTOPOINT) ||
+ (!(ifa->ifa_flags & IFF_UP)) ||
+ (ifa->ifa_addr->sa_family != AF_INET) ||
+ (strcmp(ifi->name, ifa->ifa_name)))
+ continue;
+
+ bzero(&addr, sizeof(addr));
+ addr.len = sizeof(struct in_addr);
+ memcpy(addr.iabuf,
+ &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, addr.len);
+
+ delete_old_address(ifi->name, ifi->rdomain, addr);
+ }
+
+ freeifaddrs(ifap);
+}
+
+/*
* [priv_]delete_old_address is the equivalent of
*
* ifconfig <ifname> inet <addr> delete