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.
This commit is contained in:
parent
17570e9a38
commit
7104b56ab9
@ -72,9 +72,9 @@ int nl_open(struct client_state_t *cs)
|
|||||||
return -1;
|
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?
|
// XXX: Same as packet.c - merge somehow?
|
||||||
ifchange(NULL, IFCHANGE_DECONFIG);
|
ifchange(NULL, IFCHANGE_DECONFIG);
|
||||||
cs->dhcpState = DS_SELECTING;
|
cs->dhcpState = DS_SELECTING;
|
||||||
@ -84,6 +84,14 @@ static void takedown_if(struct client_state_t *cs)
|
|||||||
set_listen_raw(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)
|
static int data_attr_cb(const struct nlattr *attr, void *data)
|
||||||
{
|
{
|
||||||
const struct nlattr **tb = 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)
|
static int data_cb(const struct nlmsghdr *nlh, void *data)
|
||||||
{
|
{
|
||||||
struct nlattr *tb[IFLA_MAX+1] = {0};
|
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);
|
get_if_index_and_mac(nlh, ifm, (const struct nlattr **)tb);
|
||||||
if (ifm->ifi_index != client_config.ifindex)
|
if (ifm->ifi_index != client_config.ifindex)
|
||||||
break;
|
break;
|
||||||
|
// IFF_UP corresponds to ifconfig down or ifconfig up.
|
||||||
if (ifm->ifi_flags & IFF_UP) {
|
if (ifm->ifi_flags & IFF_UP) {
|
||||||
|
// IFF_RUNNING is the hardware carrier.
|
||||||
if (ifm->ifi_flags & IFF_RUNNING) {
|
if (ifm->ifi_flags & IFF_RUNNING) {
|
||||||
if (cs->ifsPrevState != IFS_UP) {
|
if (cs->ifsPrevState != IFS_UP) {
|
||||||
cs->ifsPrevState = IFS_UP;
|
cs->ifsPrevState = IFS_UP;
|
||||||
@ -162,25 +170,23 @@ static int data_cb(const struct nlmsghdr *nlh, void *data)
|
|||||||
else
|
else
|
||||||
log_line("nl: interface back, revalidating lease");
|
log_line("nl: interface back, revalidating lease");
|
||||||
// If we don't have a lease, state -> SELECTING.
|
// If we don't have a lease, state -> SELECTING.
|
||||||
} else if (cs->dhcpState != DS_SELECTING) {
|
} else if (cs->dhcpState != DS_SELECTING)
|
||||||
log_line("nl: interface back, querying for new lease");
|
restart_if(cs);
|
||||||
takedown_if(cs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (cs->ifsPrevState != IFS_DOWN) {
|
|
||||||
// Interface was marked up but not running.
|
|
||||||
// Get a new lease from scratch.
|
|
||||||
cs->ifsPrevState = IFS_DOWN;
|
|
||||||
takedown_if(cs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No hardware carrier.
|
// No hardware carrier.
|
||||||
|
if (cs->ifsPrevState != IFS_DOWN) {
|
||||||
|
log_line("Interface carrier down. Going to sleep.");
|
||||||
|
cs->ifsPrevState = IFS_DOWN;
|
||||||
|
sleep_if(cs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// User shut down the interface.
|
||||||
if (cs->ifsPrevState != IFS_SHUT) {
|
if (cs->ifsPrevState != IFS_SHUT) {
|
||||||
|
log_line("Interface shut down. Going to sleep.");
|
||||||
cs->ifsPrevState = IFS_SHUT;
|
cs->ifsPrevState = IFS_SHUT;
|
||||||
log_line("Interface shut down; exiting.");
|
sleep_if(cs);
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user