diff options
| author | Roy Marples <roy@marples.name> | 2020-09-22 13:09:03 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2020-09-22 13:09:03 +0100 |
| commit | 0ede9e5419b798ae5ed183ca7da7986b8d4419bd (patch) | |
| tree | b009feff69e39b125f76f361174635b6e2877b14 /src/if-bsd.c | |
| parent | 96bf083104435f38e06375fbaa094ab50626b5de (diff) | |
| download | dhcpcd-0ede9e5419b798ae5ed183ca7da7986b8d4419bd.tar.xz | |
BSD: Detect initial link state in ifa_data
Not all interfaces report media state to get the link state.
However, link state is available from getifaddrs(3) ifa_data
for AF_LINK addresses.
Testing shows that link state is also sent correctly via
route(4) messages for the same interface.
This makes pppoe(4) interfaces more reliable on FreeBSD and OpenBSD.
Diffstat (limited to 'src/if-bsd.c')
| -rw-r--r-- | src/if-bsd.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/src/if-bsd.c b/src/if-bsd.c index 98bcda63..1dacf20c 100644 --- a/src/if-bsd.c +++ b/src/if-bsd.c @@ -369,13 +369,34 @@ if_carrier(struct interface *ifp) return LINK_UNKNOWN; strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name)); - if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr) == -1 || - !(ifmr.ifm_status & IFM_AVALID)) + if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr) == -1) + return LINK_UNKNOWN; + + if (!(ifmr.ifm_status & IFM_AVALID)) return LINK_UNKNOWN; return (ifmr.ifm_status & IFM_ACTIVE) ? LINK_UP : LINK_DOWN; } +int +if_carrier_ifadata(struct interface *ifp, void *ifadata) +{ + int carrier = if_carrier(ifp); + struct if_data *ifdata; + + if (carrier != LINK_UNKNOWN || ifadata == NULL) + return carrier; + + ifdata = ifadata; + switch (ifdata->ifi_link_state) { + case LINK_STATE_DOWN: + return LINK_DOWN; + case LINK_STATE_UP: + return LINK_UP; + } + return LINK_UNKNOWN; +} + static void if_linkaddr(struct sockaddr_dl *sdl, const struct interface *ifp) { |
