From: Roy Marples Date: Wed, 7 Oct 2020 13:11:47 +0000 (+0100) Subject: dhcpcd: Simplify the link handling even more X-Git-Tag: v9.3.1~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=76b513c6ebf26ae0dfd320f742b945db76466ac0;p=thirdparty%2Fdhcpcd.git dhcpcd: Simplify the link handling even more Move the IS_LINK_UP macro to if_is_link_up function to reduce binary size. Rather than DHCPCD_LINK option controlling the carrier state, use it in if_is_link_up to determine the outcome. --- diff --git a/src/arp.c b/src/arp.c index cc1f8a89..6f24ebf7 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 || !IS_LINK_UP(ifp)) + if (!ifp->active || !if_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 93809628..cbfb2bc8 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 (!IS_LINK_UP(ifp)) + if (!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 (!IS_LINK_UP(ifp)) + if (!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 && !IS_LINK_UP(ifp)) { + if (ifo->options & DHCPCD_LINK && !if_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 (IS_LINK_UP(ifp) && + if (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 725555f9..eda42e20 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 && !IS_LINK_UP(ifp)) + if (!callback && !if_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 (IS_LINK_UP(ifp)) + if (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 (!IS_LINK_UP(ifp)) + if (!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 (!IS_LINK_UP(ifd)) { + if (!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 (!IS_LINK_UP(ifd)) { + if (!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 (IS_LINK_UP(ifp) && + if (if_is_link_up(ifp) && state->state != DH6S_RELEASED && state->state != DH6S_INFORMED) { diff --git a/src/dhcpcd.c b/src/dhcpcd.c index 45d46746..8f429bc5 100644 --- a/src/dhcpcd.c +++ b/src/dhcpcd.c @@ -701,19 +701,13 @@ dhcpcd_reportssid(struct interface *ifp) void dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags) { - bool nolink = ifp->options == NULL || - !(ifp->options->options & DHCPCD_LINK); + bool was_link_up = if_is_link_up(ifp); + ifp->carrier = carrier; ifp->flags = flags; - /* 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) - return; - ifp->carrier = LINK_DOWN; - if (!ifp->active || nolink) + if (!if_is_link_up(ifp)) { + if (!was_link_up || !ifp->active) return; loginfox("%s: carrier lost", ifp->name); script_runreason(ifp, "NOCARRIER"); @@ -734,13 +728,13 @@ dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags) #endif dhcpcd_drop(ifp, 0); if (ifp->options->options & DHCPCD_ANONYMOUS) { - bool was_up = ifp->flags & IFF_UP; + bool is_up = ifp->flags & IFF_UP; - if (was_up) + if (is_up) if_down(ifp); if (if_randomisemac(ifp) == -1 && errno != ENXIO) logerr(__func__); - if (was_up) + if (is_up) if_up(ifp); } return; @@ -753,9 +747,9 @@ dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags) * The consideration of any other information about carrier should * be handled in the OS specific if_carrier() function. */ - if (ifp->carrier == carrier) + if (was_link_up) return; - ifp->carrier = carrier; + if (ifp->active) { if (carrier == LINK_UNKNOWN) loginfox("%s: carrier unknown, assuming up", ifp->name); @@ -792,7 +786,7 @@ dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags) } } - if (!ifp->active || nolink) + if (!ifp->active) return; dhcpcd_initstate(ifp, 0); @@ -867,7 +861,7 @@ dhcpcd_startinterface(void *arg) struct interface *ifp = arg; struct if_options *ifo = ifp->options; - if (ifo->options & DHCPCD_LINK && !IS_LINK_UP(ifp)) { + if (ifo->options & DHCPCD_LINK && !if_is_link_up(ifp)) { loginfox("%s: waiting for carrier", ifp->name); return; } @@ -989,7 +983,7 @@ run_preinit(struct interface *ifp) return; script_runreason(ifp, "PREINIT"); - if (ifp->wireless && ifp->carrier == LINK_UP) + if (ifp->wireless && if_is_link_up(ifp)) dhcpcd_reportssid(ifp); if (ifp->options->options & DHCPCD_LINK && ifp->carrier != LINK_UNKNOWN) script_runreason(ifp, @@ -1356,7 +1350,7 @@ dhcpcd_ifrenew(struct interface *ifp) if (!ifp->active) return; - if (ifp->options->options & DHCPCD_LINK && !IS_LINK_UP(ifp)) + if (ifp->options->options & DHCPCD_LINK && !if_is_link_up(ifp)) return; #ifdef INET @@ -2461,8 +2455,7 @@ printpidfile: TAILQ_FOREACH(ifp, ctx.ifaces, next) { if (ifp->active) { run_preinit(ifp); - if (!(ifp->options->options & DHCPCD_LINK) || - ifp->carrier != LINK_DOWN) + if (if_is_link_up(ifp)) opt = 1; } } diff --git a/src/dhcpcd.h b/src/dhcpcd.h index bbc125c3..8cdd3c19 100644 --- a/src/dhcpcd.h +++ b/src/dhcpcd.h @@ -55,7 +55,6 @@ #define LINK_UP 1 #define LINK_UNKNOWN 0 #define LINK_DOWN -1 -#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/if-bsd.c b/src/if-bsd.c index 8f10acdc..94f58b31 100644 --- a/src/if-bsd.c +++ b/src/if-bsd.c @@ -385,7 +385,7 @@ static int if_indirect_ioctl(struct dhcpcd_ctx *ctx, } int -if_carrier(__unused struct interface *ifp, const void *ifadata) +if_carrier(struct interface *ifp, const void *ifadata) { const struct if_data *ifi = ifadata; @@ -398,8 +398,15 @@ if_carrier(__unused struct interface *ifp, const void *ifadata) if (ifi->ifi_link_state >= LINK_STATE_UP) return LINK_UP; - if (ifi->ifi_link_state == LINK_STATE_UNKNOWN) + if (ifi->ifi_link_state == LINK_STATE_UNKNOWN) { + /* + * Work around net80211 issues in some BSDs. + * Wireless MUST support link state change. + */ + if (ifp->wireless) + return LINK_DOWN; return LINK_UNKNOWN; + } return LINK_DOWN; } diff --git a/src/if.c b/src/if.c index 67586150..d21625ef 100644 --- a/src/if.c +++ b/src/if.c @@ -193,6 +193,17 @@ if_setflag(struct interface *ifp, short setflag, short unsetflag) return 0; } +bool +if_is_link_up(const struct interface *ifp) +{ + + return ifp->flags & IFF_UP && + (ifp->carrier == LINK_UP || + (ifp->carrier == LINK_UNKNOWN && + !(ifp->options == NULL || + ifp->options->options & DHCPCD_LINK))); +} + int if_randomisemac(struct interface *ifp) { @@ -692,12 +703,6 @@ if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs, ifp->active = active; ifp->carrier = if_carrier(ifp, ifa->ifa_data); - - /* Wireless devices must support carrier change, - * so treat UNKNOWN as down. */ - if (ifp->wireless && ifp->carrier == LINK_UNKNOWN) - ifp->carrier = LINK_DOWN; - TAILQ_INSERT_TAIL(ifs, ifp, next); } diff --git a/src/if.h b/src/if.h index fc046820..8474deb7 100644 --- a/src/if.h +++ b/src/if.h @@ -146,6 +146,7 @@ int if_getflags(struct interface *); int if_setflag(struct interface *, short, short); #define if_up(ifp) if_setflag((ifp), (IFF_UP | IFF_RUNNING), 0) #define if_down(ifp) if_setflag((ifp), 0, IFF_UP); +bool if_is_link_up(const struct interface *); bool if_valid_hwaddr(const uint8_t *, size_t); struct if_head *if_discover(struct dhcpcd_ctx *, struct ifaddrs **, int, char * const *); diff --git a/src/ipv6.c b/src/ipv6.c index 78996314..3f0c1d8c 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) || IS_LINK_UP((ifp))) + (!((ifp)->options->options & DHCPCD_LINK) || if_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 63d311a5..1c082ae4 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 || !IS_LINK_UP(ifp)) + if (state == NULL || !if_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 || !IS_LINK_UP(ifp)) + if (state == NULL || !if_is_link_up(ifp)) continue; TAILQ_FOREACH(iap, &state->addrs, next) {