From: Roy Marples Date: Wed, 14 Oct 2009 15:16:07 +0000 (+0000) Subject: Remove the -w option and make it the default action if at least one X-Git-Tag: v5.1.2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=355889a91c833240d7e57a2bb1e07ccf713fd3d3;p=thirdparty%2Fdhcpcd.git Remove the -w option and make it the default action if at least one interface reports a carrier. --- diff --git a/dhcpcd.8.in b/dhcpcd.8.in index 9653044a..bd2019e8 100644 --- a/dhcpcd.8.in +++ b/dhcpcd.8.in @@ -30,7 +30,7 @@ .Nd an RFC 2131 compliant DHCP client .Sh SYNOPSIS .Nm -.Op Fl bdgknpqwABDEGKLTV +.Op Fl bdgknpqABDEGKLTV .Op Fl c , -script Ar script .Op Fl e , -env Ar value .Op Fl f , -config Ar file @@ -339,8 +339,6 @@ Set the vendor option 03 with an IP address as a string. .D1 dhcpcd \-v 03,\e"192.168.0.2\e" eth0 Set un-encapulated vendor option to hello world. .D1 dhcpcd \-v ,"hello world" eth0 -.It Fl w , -waitip -Wait for an address to be assigned before forking to the background. .It Fl x , -exit This will signal an existing .Nm diff --git a/dhcpcd.c b/dhcpcd.c index 437bfd23..46ed8138 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -736,7 +736,7 @@ configure_interface1(struct interface *iface) if (iface->flags & IFF_NOARP || ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)) ifo->options &= ~(DHCPCD_ARP | DHCPCD_IPV4LL); - if (ifo->options & DHCPCD_LINK && carrier_status(iface->name) == -1) + if (ifo->options & DHCPCD_LINK && carrier_status(iface) == -1) ifo->options &= ~DHCPCD_LINK; if (ifo->metric != -1) @@ -832,6 +832,7 @@ static void handle_carrier(const char *ifname) { struct interface *iface; + int carrier; if (!(options & DHCPCD_LINK)) return; @@ -840,11 +841,10 @@ handle_carrier(const char *ifname) break; if (!iface || !(iface->state->options->options & DHCPCD_LINK)) return; - switch (carrier_status(iface->name)) { - case -1: - syslog(LOG_ERR, "carrier_status: %m"); - break; - case 0: + carrier = carrier_status(iface); + if (carrier == -1) + syslog(LOG_ERR, "%s: carrier_status: %m", ifname); + else if (carrier == 0 || !(iface->flags & IFF_RUNNING)) { if (iface->carrier != LINK_DOWN) { iface->carrier = LINK_DOWN; syslog(LOG_INFO, "%s: carrier lost", iface->name); @@ -852,8 +852,7 @@ handle_carrier(const char *ifname) delete_timeouts(iface, start_expire, NULL); drop_config(iface, "NOCARRIER"); } - break; - default: + } else if (carrier == 1 && (iface->flags & IFF_RUNNING)) { if (iface->carrier != LINK_UP) { iface->carrier = LINK_UP; syslog(LOG_INFO, "%s: carrier acquired", iface->name); @@ -865,7 +864,6 @@ handle_carrier(const char *ifname) run_script(iface); start_interface(iface); } - break; } } @@ -1176,7 +1174,7 @@ init_state(struct interface *iface, int argc, char **argv) run_script(iface); if (ifs->options->options & DHCPCD_LINK) { - switch (carrier_status(iface->name)) { + switch (carrier_status(iface)) { case 0: iface->carrier = LINK_DOWN; ifs->reason = "NOCARRIER"; @@ -1676,6 +1674,10 @@ main(int argc, char **argv) if (pid == 0 || kill(pid, sig) != 0) { if (sig != SIGALRM) syslog(LOG_ERR, ""PACKAGE" not running"); + if (pid != 0 && errno != ESRCH) { + syslog(LOG_ERR, "kill: %m"); + exit(EXIT_FAILURE); + } unlink(pidfile); if (sig != SIGALRM) exit(EXIT_FAILURE); @@ -1761,19 +1763,6 @@ main(int argc, char **argv) ifc = argc - optind; ifv = argv + optind; - if (options & DHCPCD_BACKGROUND || - (ifc == 0 && - options & DHCPCD_LINK && - options & DHCPCD_DAEMONISE && - !(options & DHCPCD_WAITIP))) - { - daemonise(); - } else if (options & DHCPCD_DAEMONISE && ifo->timeout > 0) { - if (options & DHCPCD_IPV4LL) - options |= DHCPCD_TIMEOUT_IPV4LL; - add_timeout_sec(ifo->timeout, handle_exit_timeout, NULL); - } - free_options(ifo); ifaces = discover_interfaces(ifc, ifv); for (i = 0; i < ifc; i++) { @@ -1790,14 +1779,31 @@ main(int argc, char **argv) else exit(EXIT_FAILURE); if (!(options & DHCPCD_LINK)) { - syslog(LOG_ERR, "aborting as we're not backgrounding" - " with link detection"); + syslog(LOG_ERR, + "aborting as link detection is disabled"); exit(EXIT_FAILURE); } } - for (iface = ifaces; iface; iface = iface->next) + if (options & DHCPCD_BACKGROUND) + daemonise(); + + opt = 0; + for (iface = ifaces; iface; iface = iface->next) { init_state(iface, argc, argv); + if (iface->carrier != LINK_DOWN) + opt = 1; + } + if (options & DHCPCD_LINK && opt == 0) { + syslog(LOG_WARNING, "no interfaces have a carrier"); + daemonise(); + } else if (options & DHCPCD_DAEMONISE && ifo->timeout > 0) { + if (options & DHCPCD_IPV4LL) + options |= DHCPCD_TIMEOUT_IPV4LL; + add_timeout_sec(ifo->timeout, handle_exit_timeout, NULL); + } + free_options(ifo); + sort_interfaces(); for (iface = ifaces; iface; iface = iface->next) add_timeout_sec(0, start_interface, iface); diff --git a/dhcpcd.conf.5.in b/dhcpcd.conf.5.in index 3a41dbc4..7fcc58cc 100644 --- a/dhcpcd.conf.5.in +++ b/dhcpcd.conf.5.in @@ -272,8 +272,6 @@ Set un-encapulated vendor option to hello world. .It Ic vendorclassid Ar string Change the default vendorclassid sent from dhcpcd-version. If not set then none is sent. -.It Ic waitip -Wait for an address to be assigned before forking to the background. .El .Sh SEE ALSO .Xr dhcpcd-run-hooks 8 , diff --git a/if-options.c b/if-options.c index c4d8d096..53bb1a18 100644 --- a/if-options.c +++ b/if-options.c @@ -72,7 +72,6 @@ const struct option cf_options[] = { {"timeout", required_argument, NULL, 't'}, {"userclass", required_argument, NULL, 'u'}, {"vendor", required_argument, NULL, 'v'}, - {"waitip", no_argument, NULL, 'w'}, {"exit", no_argument, NULL, 'x'}, {"allowinterfaces", required_argument, NULL, 'z'}, {"reboot", required_argument, NULL, 'y'}, @@ -508,9 +507,6 @@ parse_option(struct if_options *ifo, int opt, const char *arg) ifo->vendor[0] += s + 2; } break; - case 'w': - ifo->options |= DHCPCD_WAITIP; - break; case 'y': ifo->reboot = atoint(arg); if (ifo->reboot < 0) { diff --git a/if-options.h b/if-options.h index 209a9df3..532bcd48 100644 --- a/if-options.h +++ b/if-options.h @@ -37,7 +37,7 @@ /* Don't set any optional arguments here so we retain POSIX * compatibility with getopt */ -#define IF_OPTS "bc:de:f:gh:i:kl:m:no:pqr:s:t:u:v:wxy:z:ABC:DEF:GI:KLN:O:Q:TVW:X:Z:" +#define IF_OPTS "bc:de:f:gh:i:kl:m:no:pqr:s:t:u:v:xy:z:ABC:DEF:GI:KLN:O:Q:TVW:X:Z:" #define DEFAULT_TIMEOUT 30 #define DEFAULT_REBOOT 10 @@ -70,8 +70,7 @@ #define DHCPCD_QUIET (1 << 21) #define DHCPCD_BACKGROUND (1 << 22) #define DHCPCD_VENDORRAW (1 << 23) -#define DHCPCD_WAITIP (1 << 24) -#define DHCPCD_TIMEOUT_IPV4LL (1 << 25) +#define DHCPCD_TIMEOUT_IPV4LL (1 << 24) extern const struct option cf_options[]; diff --git a/net.c b/net.c index b9b75681..bb464142 100644 --- a/net.c +++ b/net.c @@ -250,6 +250,81 @@ free_interface(struct interface *iface) free(iface); } +int +carrier_status(struct interface *iface) +{ + int s, ret; + struct ifreq ifr; +#ifdef SIOCGIFMEDIA + struct ifmediareq ifmr; +#endif +#ifdef __linux__ + char *p; +#endif + + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + return -1; + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name)); +#ifdef __linux__ + /* We can only test the real interface up */ + if ((p = strchr(ifr.ifr_name, ':'))) + *p = '\0'; +#endif + + if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) { + close(s); + return -1; + } + iface->flags = ifr.ifr_flags; + + ret = -1; +#ifdef SIOCGIFMEDIA + memset(&ifmr, 0, sizeof(ifmr)); + strlcpy(ifmr.ifm_name, iface->name, sizeof(ifmr.ifm_name)); + if (ioctl(s, SIOCGIFMEDIA, &ifmr) != -1 && + ifmr.ifm_status & IFM_AVALID) + ret = (ifmr.ifm_status & IFM_ACTIVE) ? 1 : 0; +#endif + close(s); + if (ret == -1) + ret = (ifr.ifr_flags & IFF_RUNNING) ? 1 : 0; + return ret; +} + +int +up_interface(struct interface *iface) +{ + int s; + struct ifreq ifr; + int retval = -1; +#ifdef __linux__ + char *p; +#endif + + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + return -1; + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name)); +#ifdef __linux__ + /* We can only bring the real interface up */ + if ((p = strchr(ifr.ifr_name, ':'))) + *p = '\0'; +#endif + if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) { + if ((ifr.ifr_flags & IFF_UP)) + retval = 0; + else { + ifr.ifr_flags |= IFF_UP; + if (ioctl(s, SIOCSIFFLAGS, &ifr) == 0) + retval = 0; + } + iface->flags = ifr.ifr_flags; + } + close(s); + return retval; +} + struct interface * discover_interfaces(int argc, char * const *argv) { @@ -327,13 +402,13 @@ discover_interfaces(int argc, char * const *argv) if ((ifp = init_interface(p)) == NULL) continue; - /* Bring the interface up */ - if (!(ifp->flags & IFF_UP) && up_interface(p) != 0) - /* Some drivers return ENODEV here when they are disabled by a switch. - * We just blunder on as the carrier will be down anyway. - * When the switch is enabled, it should bring the interface up. - * Then we'll spot the carrier and start working. */ - syslog(LOG_ERR, "%s: up_interface: %m", p); + /* Bring the interface up if not already */ + if (!(ifp->flags & IFF_UP) && +#ifdef SIOCGIFMEDIA + carrier_status(ifp) != -1 && +#endif + up_interface(ifp) != 0) + syslog(LOG_ERR, "%s: up_interface: %m", ifp->name); /* Don't allow loopback unless explicit */ if (ifp->flags & IFF_LOOPBACK) { @@ -433,82 +508,6 @@ do_address(const char *ifname, freeifaddrs(ifaddrs); return retval; } - -int -up_interface(const char *ifname) -{ - int s; - struct ifreq ifr; - int retval = -1; -#ifdef __linux__ - char *p; -#endif - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) - return -1; - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); -#ifdef __linux__ - /* We can only bring the real interface up */ - if ((p = strchr(ifr.ifr_name, ':'))) - *p = '\0'; -#endif - if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) { - if ((ifr.ifr_flags & IFF_UP)) - retval = 0; - else { - ifr.ifr_flags |= IFF_UP; - if (ioctl(s, SIOCSIFFLAGS, &ifr) == 0) - retval = 0; - } - } - close(s); - return retval; -} - -int -carrier_status(const char *ifname) -{ - int s; - struct ifreq ifr; - int retval = -1; -#ifdef SIOCGIFMEDIA - struct ifmediareq ifmr; -#endif -#ifdef __linux__ - char *p; -#endif - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) - return -1; - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); -#ifdef __linux__ - /* We can only test the real interface up */ - if ((p = strchr(ifr.ifr_name, ':'))) - *p = '\0'; -#endif - if ((retval = ioctl(s, SIOCGIFFLAGS, &ifr)) == 0) { - if (ifr.ifr_flags & IFF_UP && ifr.ifr_flags & IFF_RUNNING) - retval = 1; - else - retval = 0; - } - -#ifdef SIOCGIFMEDIA - if (retval == 1) { - memset(&ifmr, 0, sizeof(ifmr)); - strlcpy(ifmr.ifm_name, ifr.ifr_name, sizeof(ifmr.ifm_name)); - retval = -1; - if (ioctl(s, SIOCGIFMEDIA, &ifmr) != -1 && - ifmr.ifm_status & IFM_AVALID) - retval = (ifmr.ifm_status & IFM_ACTIVE) ? 1 : 0; - } -#endif - close(s); - return retval; -} - int do_mtu(const char *ifname, short int mtu) diff --git a/net.h b/net.h index ba5d6d13..ade4ca17 100644 --- a/net.h +++ b/net.h @@ -102,7 +102,7 @@ int do_mtu(const char *, short int); int inet_ntocidr(struct in_addr); int inet_cidrtoaddr(int, struct in_addr *); -int up_interface(const char *); +int up_interface(struct interface *); int do_address(const char *, struct in_addr *, struct in_addr *, struct in_addr *, int); int if_address(const struct interface *, @@ -146,5 +146,5 @@ ssize_t get_raw_packet(struct interface *, int, void *, ssize_t); int init_socket(void); int open_link_socket(void); int manage_link(int); -int carrier_status(const char *); +int carrier_status(struct interface *); #endif