]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
BSD: Use SIOCGIFDATA if no media support and no ifa_data
authorRoy Marples <roy@marples.name>
Tue, 22 Sep 2020 20:53:13 +0000 (21:53 +0100)
committerRoy Marples <roy@marples.name>
Tue, 22 Sep 2020 20:53:13 +0000 (21:53 +0100)
Hopefully this nails link state once and for all on BSD.

src/if-bsd.c

index 1dacf20c6f9cd9b93c87812cd15a788dadeac323..c7be22fe1689c986affb994bad517743e64c959d 100644 (file)
@@ -359,8 +359,8 @@ if_ignore(struct dhcpcd_ctx *ctx, const char *ifname)
 #endif
 }
 
-int
-if_carrier(struct interface *ifp)
+static int
+if_carrier0(struct interface *ifp)
 {
        struct ifmediareq ifmr = { .ifm_status = 0 };
 
@@ -378,10 +378,34 @@ if_carrier(struct interface *ifp)
        return (ifmr.ifm_status & IFM_ACTIVE) ? LINK_UP : LINK_DOWN;
 }
 
+int
+if_carrier(struct interface *ifp)
+{
+       int carrier = if_carrier0(ifp);
+       struct ifdatareq ifdr = { .ifdr_data.ifi_link_state = 0 };
+       struct if_data *ifdata;
+
+       if (carrier != LINK_UNKNOWN)
+               return carrier;
+
+       strlcpy(ifdr.ifdr_name, ifp->name, sizeof(ifdr.ifdr_name));
+       if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFDATA, &ifdr) == -1)
+               return LINK_UNKNOWN;
+
+       ifdata = &ifdr.ifdr_data;
+       switch (ifdata->ifi_link_state) {
+       case LINK_STATE_DOWN:
+               return LINK_DOWN;
+       case LINK_STATE_UP:
+               return LINK_UP;
+       }
+       return LINK_UNKNOWN;
+}
+
 int
 if_carrier_ifadata(struct interface *ifp, void *ifadata)
 {
-       int carrier = if_carrier(ifp);
+       int carrier = if_carrier0(ifp);
        struct if_data *ifdata;
 
        if (carrier != LINK_UNKNOWN || ifadata == NULL)