summaryrefslogtreecommitdiffstats
path: root/src/if-bsd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2019-01-26 00:08:43 +0000
committerRoy Marples <roy@marples.name>2019-01-26 00:08:43 +0000
commit4f903d6ad4adf2de7712d36a921051b4dfd7210a (patch)
tree6c1b535d692ae0c96d5a4cb9a70bdb82ad23e9fa /src/if-bsd.c
parent700fd4e3d3cc65602427816f7446dada757d0538 (diff)
downloaddhcpcd-4f903d6ad4adf2de7712d36a921051b4dfd7210a.tar.xz
BSD: treat LINK_STATE_UNKNOWN as DOWN if media is invalid
On BSD, some interfaces might emit RTM_IFINFO before the link state has initialised. Mainly wireless cards. If the intial carrier call says media state change is valid, we need to treat LINK_STATE_UNKNOWN as LINK_DOWN rather than LINK_UP.
Diffstat (limited to 'src/if-bsd.c')
-rw-r--r--src/if-bsd.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/src/if-bsd.c b/src/if-bsd.c
index a5338624..5ec60eb5 100644
--- a/src/if-bsd.c
+++ b/src/if-bsd.c
@@ -946,16 +946,22 @@ if_ifinfo(struct dhcpcd_ctx *ctx, const struct if_msghdr *ifm)
if ((ifp = if_findindex(ctx->ifaces, ifm->ifm_index)) == NULL)
return;
- /* If we get LINK_STATE_UNKNOWN here, it means the interface
- * doesn't support reporting carrier state.
- * As such, we need to rely on IFF_UP.
- * Even if LINK_STATE_UP is reported, we also need IFF_UP as well
- * so for dhcpcd they are equivalent and we only need to check
- * LINK_STATE_DOWN. */
- if (ifm->ifm_data.ifi_link_state == LINK_STATE_DOWN)
- link_state = LINK_DOWN;
- else
+ switch (ifm->ifm_data.ifi_link_state) {
+ case LINK_STATE_UNKNOWN:
+ if (ifp->media_valid) {
+ link_state = LINK_DOWN;
+ break;
+ }
+ /* Interface does not report media state, so we have
+ * to rely on IFF_UP. */
+ /* FALLTHROUGH */
+ case LINK_STATE_UP:
link_state = ifm->ifm_flags & IFF_UP ? LINK_UP : LINK_DOWN;
+ break;
+ default:
+ link_state = LINK_DOWN;
+ break;
+ }
dhcpcd_handlecarrier(ctx, link_state,
(unsigned int)ifm->ifm_flags, ifp->name);