From: Roy Marples Date: Tue, 6 Oct 2020 06:10:41 +0000 (+0100) Subject: dhcpcd: Simplify carrier handling more by using IS_LINK_UP macro X-Git-Tag: v9.3.1~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=053976a565bd812c4ecc155173887cce4e3f15a4;p=thirdparty%2Fdhcpcd.git dhcpcd: Simplify carrier handling more by using IS_LINK_UP macro Removes the need for the LINK_DOWN_IFFUP state. While here, remove the check for IFF_RUNNING when LINK_UNKNOWN because that is OS specific. --- diff --git a/src/arp.c b/src/arp.c index 62602f93..cc1f8a89 100644 --- a/src/arp.c +++ b/src/arp.c @@ -506,7 +506,7 @@ arp_announceaddr(struct dhcpcd_ctx *ctx, const struct in_addr *ia) struct ipv4_addr *iap; TAILQ_FOREACH(ifp, ctx->ifaces, next) { - if (!ifp->active || ifp->carrier <= LINK_DOWN) + if (!ifp->active || !IS_LINK_UP(ifp)) continue; iap = ipv4_iffindaddr(ifp, ia, NULL); if (iap == NULL) diff --git a/src/dhcp.c b/src/dhcp.c index 10671c6c..93809628 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -1712,7 +1712,7 @@ send_message(struct interface *ifp, uint8_t type, if (callback == NULL) { /* No carrier? Don't bother sending the packet. */ - if (ifp->carrier <= LINK_DOWN) + if (!IS_LINK_UP(ifp)) return; logdebugx("%s: sending %s with xid 0x%x", ifp->name, @@ -1731,7 +1731,7 @@ send_message(struct interface *ifp, uint8_t type, (arc4random_uniform(MSEC_PER_SEC * 2) - MSEC_PER_SEC); /* No carrier? Don't bother sending the packet. * However, we do need to advance the timeout. */ - if (ifp->carrier <= LINK_DOWN) + if (!IS_LINK_UP(ifp)) goto fail; logdebugx("%s: sending %s (xid 0x%x), next in %0.1f seconds", ifp->name, @@ -2633,7 +2633,7 @@ dhcp_reboot(struct interface *ifp) state->state = DHS_REBOOT; state->interval = 0; - if (ifo->options & DHCPCD_LINK && ifp->carrier <= LINK_DOWN) { + if (ifo->options & DHCPCD_LINK && !IS_LINK_UP(ifp)) { loginfox("%s: waiting for carrier", ifp->name); return; } @@ -2733,7 +2733,7 @@ dhcp_drop(struct interface *ifp, const char *reason) state->state = DHS_RELEASE; dhcp_unlink(ifp->ctx, state->leasefile); - if (ifp->carrier > LINK_DOWN && + if (IS_LINK_UP(ifp) && state->new != NULL && state->lease.server.s_addr != INADDR_ANY) { diff --git a/src/dhcp6.c b/src/dhcp6.c index 0dbf8333..725555f9 100644 --- a/src/dhcp6.c +++ b/src/dhcp6.c @@ -1237,7 +1237,7 @@ dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *)) }; char uaddr[INET6_ADDRSTRLEN]; - if (!callback && ifp->carrier <= LINK_DOWN) + if (!callback && !IS_LINK_UP(ifp)) return 0; if (!IN6_IS_ADDR_UNSPECIFIED(&state->unicast)) { @@ -1298,7 +1298,7 @@ dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *)) + (unsigned int)((float)state->RT * ((float)lr / DHCP6_RAND_DIV)); - if (ifp->carrier > LINK_DOWN) + if (IS_LINK_UP(ifp)) logdebugx("%s: %s %s (xid 0x%02x%02x%02x)%s%s," " next in %0.1f seconds", ifp->name, @@ -1320,7 +1320,7 @@ dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *)) } } - if (ifp->carrier <= LINK_DOWN) + if (!IS_LINK_UP(ifp)) return 0; /* Update the elapsed time */ @@ -2906,7 +2906,7 @@ dhcp6_delegate_prefix(struct interface *ifp) if (ia->sla_len == 0) { /* no SLA configured, so lets * automate it */ - if (ifd->carrier != LINK_UP) { + if (!IS_LINK_UP(ifd)) { logdebugx( "%s: has no carrier, cannot" " delegate addresses", @@ -2922,7 +2922,7 @@ dhcp6_delegate_prefix(struct interface *ifp) sla = &ia->sla[j]; if (strcmp(ifd->name, sla->ifname)) continue; - if (ifd->carrier != LINK_UP) { + if (!IS_LINK_UP(ifd)) { logdebugx( "%s: has no carrier, cannot" " delegate addresses", @@ -4029,7 +4029,7 @@ dhcp6_freedrop(struct interface *ifp, int drop, const char *reason) if (drop && options & DHCPCD_RELEASE && state->state != DH6S_DELEGATED) { - if (ifp->carrier == LINK_UP && + if (IS_LINK_UP(ifp) && state->state != DH6S_RELEASED && state->state != DH6S_INFORMED) { diff --git a/src/dhcpcd.c b/src/dhcpcd.c index 604a08ca..45d46746 100644 --- a/src/dhcpcd.c +++ b/src/dhcpcd.c @@ -97,9 +97,6 @@ const int dhcpcd_signals_ignore[] = { const size_t dhcpcd_signals_ignore_len = __arraycount(dhcpcd_signals_ignore); #endif -#define IF_UPANDRUNNING(a) \ - (((a)->flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) - const char *dhcpcd_default_script = SCRIPT; static void @@ -708,106 +705,110 @@ dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags) !(ifp->options->options & DHCPCD_LINK); ifp->flags = flags; - if (carrier == LINK_UNKNOWN) { - if (ifp->wireless) - carrier = LINK_DOWN; - else - carrier = IF_UPANDRUNNING(ifp) ? LINK_UP : LINK_DOWN; - } + /* Wireless *must* support link state changes. */ + if (carrier == LINK_UNKNOWN && ifp->wireless) + carrier = LINK_DOWN; if (carrier == LINK_DOWN || (ifp->flags & IFF_UP) == 0) { - if (ifp->carrier != LINK_DOWN) { -#ifdef NOCARRIER_PRESERVE_IP - if (ifp->flags & IFF_UP && - (ifp->options == NULL || - !(ifp->options->options & DHCPCD_ANONYMOUS))) - ifp->carrier = LINK_DOWN_IFFUP; - else -#endif - ifp->carrier = LINK_DOWN; - if (!ifp->active || nolink) - return; - loginfox("%s: carrier lost", ifp->name); - script_runreason(ifp, "NOCARRIER"); + if (ifp->carrier == LINK_DOWN) + return; + ifp->carrier = LINK_DOWN; + if (!ifp->active || nolink) + return; + loginfox("%s: carrier lost", ifp->name); + script_runreason(ifp, "NOCARRIER"); #ifdef NOCARRIER_PRESERVE_IP - if (ifp->flags & IFF_UP && - !(ifp->options->options & DHCPCD_ANONYMOUS)) - { + if (ifp->flags & IFF_UP && + !(ifp->options->options & DHCPCD_ANONYMOUS)) + { #ifdef ARP - arp_drop(ifp); + arp_drop(ifp); #endif #ifdef INET - dhcp_abort(ifp); + dhcp_abort(ifp); #endif #ifdef DHCP6 - dhcp6_abort(ifp); + dhcp6_abort(ifp); #endif - } else + } else #endif - dhcpcd_drop(ifp, 0); - if (ifp->options->options & DHCPCD_ANONYMOUS) { - bool was_up = ifp->flags & IFF_UP; + dhcpcd_drop(ifp, 0); + if (ifp->options->options & DHCPCD_ANONYMOUS) { + bool was_up = ifp->flags & IFF_UP; - if (was_up) - if_down(ifp); - if (if_randomisemac(ifp) == -1 && errno != ENXIO) - logerr(__func__); - if (was_up) - if_up(ifp); - } + if (was_up) + if_down(ifp); + if (if_randomisemac(ifp) == -1 && errno != ENXIO) + logerr(__func__); + if (was_up) + if_up(ifp); } - } else if (carrier == LINK_UP && ifp->flags & IFF_UP) { - if (ifp->carrier != LINK_UP) { - ifp->carrier = LINK_UP; - if (ifp->active) - loginfox("%s: carrier acquired", ifp->name); + return; + } + + /* + * At this point carrier is NOT DOWN and we have IFF_UP. + * We should treat LINK_UNKNOWN as up as the driver may not support + * link state changes. + * The consideration of any other information about carrier should + * be handled in the OS specific if_carrier() function. + */ + if (ifp->carrier == carrier) + return; + ifp->carrier = carrier; + if (ifp->active) { + if (carrier == LINK_UNKNOWN) + loginfox("%s: carrier unknown, assuming up", ifp->name); + else + loginfox("%s: carrier acquired", ifp->name); + } + #if !defined(__linux__) && !defined(__NetBSD__) - /* BSD does not emit RTM_NEWADDR or RTM_CHGADDR when the - * hardware address changes so we have to go - * through the disovery process to work it out. */ - dhcpcd_handleinterface(ifp->ctx, 0, ifp->name); -#endif - if (ifp->wireless) { - uint8_t ossid[IF_SSIDLEN]; - size_t olen; - - olen = ifp->ssid_len; - memcpy(ossid, ifp->ssid, ifp->ssid_len); - if_getssid(ifp); - - /* If we changed SSID network, drop leases */ - if ((ifp->ssid_len != olen || - memcmp(ifp->ssid, ossid, ifp->ssid_len)) && - ifp->active) - { - dhcpcd_reportssid(ifp); + /* BSD does not emit RTM_NEWADDR or RTM_CHGADDR when the + * hardware address changes so we have to go + * through the disovery process to work it out. */ + dhcpcd_handleinterface(ifp->ctx, 0, ifp->name); +#endif + + if (ifp->wireless) { + uint8_t ossid[IF_SSIDLEN]; + size_t olen; + + olen = ifp->ssid_len; + memcpy(ossid, ifp->ssid, ifp->ssid_len); + if_getssid(ifp); + + /* If we changed SSID network, drop leases */ + if ((ifp->ssid_len != olen || + memcmp(ifp->ssid, ossid, ifp->ssid_len)) && ifp->active) + { + dhcpcd_reportssid(ifp); #ifdef NOCARRIER_PRESERVE_IP - dhcpcd_drop(ifp, 0); + dhcpcd_drop(ifp, 0); #endif #ifdef IPV4LL - ipv4ll_reset(ifp); + ipv4ll_reset(ifp); #endif - } - } - if (!ifp->active || nolink) - return; - dhcpcd_initstate(ifp, 0); - script_runreason(ifp, "CARRIER"); + } + } + + if (!ifp->active || nolink) + return; + + dhcpcd_initstate(ifp, 0); + script_runreason(ifp, "CARRIER"); #ifdef INET6 #ifdef NOCARRIER_PRESERVE_IP - /* Set any IPv6 Routers we remembered to expire - * faster than they would normally as we - * maybe on a new network. */ - ipv6nd_startexpire(ifp); + /* Set any IPv6 Routers we remembered to expire faster than they + * would normally as we maybe on a new network. */ + ipv6nd_startexpire(ifp); #endif #ifdef IPV6_MANAGETEMPADDR - /* RFC4941 Section 3.5 */ - ipv6_regentempaddrs(ifp); + /* RFC4941 Section 3.5 */ + ipv6_regentempaddrs(ifp); #endif #endif - dhcpcd_startinterface(ifp); - } - } + dhcpcd_startinterface(ifp); } static void @@ -866,9 +867,7 @@ dhcpcd_startinterface(void *arg) struct interface *ifp = arg; struct if_options *ifo = ifp->options; - if (ifo->options & DHCPCD_LINK && (ifp->carrier == LINK_DOWN || - (ifp->carrier == LINK_UNKNOWN && !IF_UPANDRUNNING(ifp)))) - { + if (ifo->options & DHCPCD_LINK && !IS_LINK_UP(ifp)) { loginfox("%s: waiting for carrier", ifp->name); return; } @@ -959,7 +958,7 @@ dhcpcd_prestartinterface(void *arg) struct dhcpcd_ctx *ctx = ifp->ctx; bool anondown; - if (ifp->carrier == LINK_DOWN && + if (ifp->carrier <= LINK_DOWN && ifp->options->options & DHCPCD_ANONYMOUS && ifp->flags & IFF_UP) { @@ -1357,8 +1356,7 @@ dhcpcd_ifrenew(struct interface *ifp) if (!ifp->active) return; - if (ifp->options->options & DHCPCD_LINK && - ifp->carrier == LINK_DOWN) + if (ifp->options->options & DHCPCD_LINK && !IS_LINK_UP(ifp)) return; #ifdef INET diff --git a/src/dhcpcd.h b/src/dhcpcd.h index d2c90c1c..bbc125c3 100644 --- a/src/dhcpcd.h +++ b/src/dhcpcd.h @@ -55,7 +55,7 @@ #define LINK_UP 1 #define LINK_UNKNOWN 0 #define LINK_DOWN -1 -#define LINK_DOWN_IFFUP -2 +#define IS_LINK_UP(ifp) (((ifp)->flags & IFF_UP) && (ifp)->carrier != LINK_DOWN) #define IF_DATA_IPV4 0 #define IF_DATA_ARP 1 diff --git a/src/ipv6.c b/src/ipv6.c index 5442ebde..78996314 100644 --- a/src/ipv6.c +++ b/src/ipv6.c @@ -105,7 +105,7 @@ defined(IFF_NOLINKLOCAL) /* Only add the LL address if we have a carrier, so DaD works. */ #define CAN_ADD_LLADDR(ifp) \ - (!((ifp)->options->options & DHCPCD_LINK) || (ifp)->carrier != LINK_DOWN) + (!((ifp)->options->options & DHCPCD_LINK) || IS_LINK_UP((ifp))) #ifdef __sun /* Although we can add our own LL address, we cannot drop it * without unplumbing the if which is a lot of code. diff --git a/src/ipv6nd.c b/src/ipv6nd.c index 4afbf1fb..63d311a5 100644 --- a/src/ipv6nd.c +++ b/src/ipv6nd.c @@ -437,7 +437,7 @@ ipv6nd_sendadvertisement(void *arg) const struct rs_state *state = RS_CSTATE(ifp); int s; - if (state == NULL || ifp->carrier <= LINK_DOWN) + if (state == NULL || !IS_LINK_UP(ifp)) goto freeit; #ifdef SIN6_LEN @@ -505,7 +505,7 @@ ipv6nd_advertise(struct ipv6_addr *ia) iaf = NULL; TAILQ_FOREACH(ifp, ctx->ifaces, next) { state = IPV6_STATE(ifp); - if (state == NULL || ifp->carrier <= LINK_DOWN) + if (state == NULL || !IS_LINK_UP(ifp)) continue; TAILQ_FOREACH(iap, &state->addrs, next) { diff --git a/src/script.c b/src/script.c index d611a644..ce48b3ba 100644 --- a/src/script.c +++ b/src/script.c @@ -589,7 +589,6 @@ send_interface(struct fd_list *fd, const struct interface *ifp, int af) reason = "CARRIER"; break; case LINK_DOWN: - case LINK_DOWN_IFFUP: reason = "NOCARRIER"; break; default: