From 7104b56ab9a39516fac12fa3ed95d9ae37790aee Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" Date: Sat, 2 Jul 2011 01:51:32 -0400 Subject: [PATCH] Change netlink event handling so that the DHCP client will sleep if the interface carrier is lost or the interface is deconfigured but still exists, eg via ifconfig down. If the hardware is removed, then ndhcp will exit. --- ndhc/netlink.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/ndhc/netlink.c b/ndhc/netlink.c index de3d087..998b152 100644 --- a/ndhc/netlink.c +++ b/ndhc/netlink.c @@ -72,9 +72,9 @@ int nl_open(struct client_state_t *cs) return -1; } -static void takedown_if(struct client_state_t *cs) +static void restart_if(struct client_state_t *cs) { - log_line("nl: taking down interface"); + log_line("nl: %s back, querying for new lease", client_config.interface); // XXX: Same as packet.c - merge somehow? ifchange(NULL, IFCHANGE_DECONFIG); cs->dhcpState = DS_SELECTING; @@ -84,6 +84,14 @@ static void takedown_if(struct client_state_t *cs) set_listen_raw(cs); } +static void sleep_if(struct client_state_t *cs) +{ + arp_close_fd(cs); + set_listen_none(cs); + cs->dhcpState = DS_RELEASED; + cs->timeout = -1; +} + static int data_attr_cb(const struct nlattr *attr, void *data) { const struct nlattr **tb = data; @@ -135,8 +143,6 @@ static void get_if_index_and_mac(const struct nlmsghdr *nlh, } } -// XXX: Rather than exit, go into RELEASE state until a new hardware event -// forces wakeup. static int data_cb(const struct nlmsghdr *nlh, void *data) { struct nlattr *tb[IFLA_MAX+1] = {0}; @@ -149,7 +155,9 @@ static int data_cb(const struct nlmsghdr *nlh, void *data) get_if_index_and_mac(nlh, ifm, (const struct nlattr **)tb); if (ifm->ifi_index != client_config.ifindex) break; + // IFF_UP corresponds to ifconfig down or ifconfig up. if (ifm->ifi_flags & IFF_UP) { + // IFF_RUNNING is the hardware carrier. if (ifm->ifi_flags & IFF_RUNNING) { if (cs->ifsPrevState != IFS_UP) { cs->ifsPrevState = IFS_UP; @@ -162,25 +170,23 @@ static int data_cb(const struct nlmsghdr *nlh, void *data) else log_line("nl: interface back, revalidating lease"); // If we don't have a lease, state -> SELECTING. - } else if (cs->dhcpState != DS_SELECTING) { - log_line("nl: interface back, querying for new lease"); - takedown_if(cs); - } + } else if (cs->dhcpState != DS_SELECTING) + restart_if(cs); } } else { + // No hardware carrier. if (cs->ifsPrevState != IFS_DOWN) { - // Interface was marked up but not running. - // Get a new lease from scratch. + log_line("Interface carrier down. Going to sleep."); cs->ifsPrevState = IFS_DOWN; - takedown_if(cs); + sleep_if(cs); } } } else { - // No hardware carrier. + // User shut down the interface. if (cs->ifsPrevState != IFS_SHUT) { + log_line("Interface shut down. Going to sleep."); cs->ifsPrevState = IFS_SHUT; - log_line("Interface shut down; exiting."); - exit(EXIT_SUCCESS); + sleep_if(cs); } } break;