diff options
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/dhclient/dhclient.c | 42 | ||||
-rw-r--r-- | sbin/dhclient/dhcpd.h | 3 | ||||
-rw-r--r-- | sbin/dhclient/dispatch.c | 30 |
3 files changed, 42 insertions, 33 deletions
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index 512a478e7c0..15dfcf1b1e5 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhclient.c,v 1.117 2008/03/12 13:31:22 hugh Exp $ */ +/* $OpenBSD: dhclient.c,v 1.118 2008/05/09 05:19:14 reyk Exp $ */ /* * Copyright 2004 Henning Brauer <henning@openbsd.org> @@ -154,6 +154,7 @@ struct iaddr defaddr = { 4 }; void routehandler(void) { + int linkstat; char msg[2048]; struct rt_msghdr *rtm; struct if_msghdr *ifm; @@ -216,6 +217,19 @@ routehandler(void) break; if ((rtm->rtm_flags & RTF_UP) == 0) goto die; + + linkstat = + LINK_STATE_IS_UP(ifm->ifm_data.ifi_link_state) ? 1 : 0; + if (linkstat != ifi->linkstat) { + debug("link state %s -> %s", + ifi->linkstat ? "up" : "down", + linkstat ? "up" : "down"); + ifi->linkstat = interface_link_status(ifi->name); + if (ifi->linkstat) { + client->state = S_INIT; + state_reboot(); + } + } break; case RTM_IFANNOUNCE: ifan = (struct if_announcemsghdr *)rtm; @@ -305,32 +319,27 @@ main(int argc, char *argv[]) read_client_conf(); - if (!interface_link_status(ifi->name)) { - int linkstat = interface_link_forceup(ifi->name); - + if (!(ifi->linkstat = interface_link_status(ifi->name))) { fprintf(stderr, "%s: no link ...", ifi->name); if (config->link_timeout == 0) { - fprintf(stderr, " giving up\n"); - if (linkstat == 0) - interface_link_forcedown(ifi->name); - exit(1); + fprintf(stderr, " sleeping\n"); + goto dispatch; } fflush(stderr); sleep(1); - while (!interface_link_status(ifi->name)) { + while (!(ifi->linkstat = interface_link_status(ifi->name))) { fprintf(stderr, "."); fflush(stderr); if (++i > config->link_timeout) { - fprintf(stderr, " giving up\n"); - if (linkstat == 0) - interface_link_forcedown(ifi->name); - exit(1); + fprintf(stderr, " sleeping\n"); + goto dispatch; } sleep(1); } fprintf(stderr, " got link\n"); } + dispatch: if ((nullfd = open(_PATH_DEVNULL, O_RDWR, 0)) == -1) error("cannot open %s: %m", _PATH_DEVNULL); @@ -383,8 +392,11 @@ main(int argc, char *argv[]) setproctitle("%s", ifi->name); - client->state = S_INIT; - state_reboot(); + if (ifi->linkstat) { + client->state = S_INIT; + state_reboot(); + } else + go_daemon(); dispatch(); diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h index 3ad7564b1de..b3427c5f16c 100644 --- a/sbin/dhclient/dhcpd.h +++ b/sbin/dhclient/dhcpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcpd.h,v 1.65 2007/02/25 16:27:20 stevesk Exp $ */ +/* $OpenBSD: dhcpd.h,v 1.66 2008/05/09 05:19:14 reyk Exp $ */ /* * Copyright (c) 2004 Henning Brauer <henning@openbsd.org> @@ -189,6 +189,7 @@ struct interface_info { int noifmedia; int errors; u_int16_t index; + int linkstat; }; struct timeout { diff --git a/sbin/dhclient/dispatch.c b/sbin/dhclient/dispatch.c index f02aabead3c..182c08c81b9 100644 --- a/sbin/dhclient/dispatch.c +++ b/sbin/dhclient/dispatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dispatch.c,v 1.40 2007/11/12 10:14:40 dlg Exp $ */ +/* $OpenBSD: dispatch.c,v 1.41 2008/05/09 05:19:14 reyk Exp $ */ /* * Copyright 2004 Henning Brauer <henning@openbsd.org> @@ -133,6 +133,9 @@ dispatch(void) * a timeout registered, time out the select call then. */ another: + if (!ifi->linkstat) + interfaces_invalidated = 0; + if (timeouts) { struct timeout *t; @@ -181,7 +184,8 @@ another: } if ((fds[0].revents & (POLLIN | POLLHUP))) { - if (ifi && ifi->rfdesc != -1) + if (ifi->linkstat && + ifi && ifi->rfdesc != -1) got_one(); } if ((fds[1].revents & (POLLIN | POLLHUP))) { @@ -321,16 +325,10 @@ interface_status(void) goto active; } if (ifmr.ifm_status & IFM_AVALID) { - switch (ifmr.ifm_active & IFM_NMASK) { - case IFM_ETHER: - if (ifmr.ifm_status & IFM_ACTIVE) - goto active; - else - goto inactive; - break; - default: + if (ifmr.ifm_status & IFM_ACTIVE) + goto active; + else goto inactive; - } } inactive: return (0); @@ -442,12 +440,10 @@ interface_link_status(char *ifname) close(sock); if (ifmr.ifm_status & IFM_AVALID) { - if ((ifmr.ifm_active & IFM_NMASK) == IFM_ETHER) { - if (ifmr.ifm_status & IFM_ACTIVE) - return (1); - else - return (0); - } + if (ifmr.ifm_status & IFM_ACTIVE) + return (1); + else + return (0); } return (1); } |