summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-10-07 14:11:47 +0100
committerRoy Marples <roy@marples.name>2020-10-07 14:11:47 +0100
commit76b513c6ebf26ae0dfd320f742b945db76466ac0 (patch)
tree3911abc0ebd1a0757aa7459a3c82e4b5c460266f
parentf2b2cdfb7305245d17fd790db3bf366f34f6d596 (diff)
downloaddhcpcd-76b513c6ebf26ae0dfd320f742b945db76466ac0.tar.xz
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.
-rw-r--r--src/arp.c2
-rw-r--r--src/dhcp.c8
-rw-r--r--src/dhcp6.c12
-rw-r--r--src/dhcpcd.c35
-rw-r--r--src/dhcpcd.h1
-rw-r--r--src/if-bsd.c11
-rw-r--r--src/if.c17
-rw-r--r--src/if.h1
-rw-r--r--src/ipv6.c2
-rw-r--r--src/ipv6nd.c4
10 files changed, 49 insertions, 44 deletions
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) {