summaryrefslogtreecommitdiffstats
path: root/src/if-bsd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-09-22 13:09:03 +0100
committerRoy Marples <roy@marples.name>2020-09-22 13:09:03 +0100
commit0ede9e5419b798ae5ed183ca7da7986b8d4419bd (patch)
treeb009feff69e39b125f76f361174635b6e2877b14 /src/if-bsd.c
parent96bf083104435f38e06375fbaa094ab50626b5de (diff)
downloaddhcpcd-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.c25
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)
{