mirror of
https://github.com/rsmarples/dhcpcd.git
synced 2024-11-27 12:03:45 +08:00
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.
This commit is contained in:
parent
96bf083104
commit
0ede9e5419
25
src/if-bsd.c
25
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)
|
||||
{
|
||||
|
@ -517,6 +517,13 @@ if_carrier(struct interface *ifp)
|
||||
return ifp->flags & IFF_RUNNING ? LINK_UP : LINK_DOWN;
|
||||
}
|
||||
|
||||
int
|
||||
if_carrier_ifadata(struct interface *ifp, __unused void *ifadata)
|
||||
{
|
||||
|
||||
return if_carrier(ifp);
|
||||
}
|
||||
|
||||
int
|
||||
if_getnetlink(struct dhcpcd_ctx *ctx, struct iovec *iov, int fd, int flags,
|
||||
int (*cb)(struct dhcpcd_ctx *, void *, struct nlmsghdr *), void *cbarg)
|
||||
|
@ -245,6 +245,13 @@ err:
|
||||
return LINK_UNKNOWN;
|
||||
}
|
||||
|
||||
int
|
||||
if_carrier_ifadata(struct interface *ifp, __unused void *ifadata)
|
||||
{
|
||||
|
||||
return if_carrier(ifp);
|
||||
}
|
||||
|
||||
int
|
||||
if_mtu_os(const struct interface *ifp)
|
||||
{
|
||||
|
2
src/if.c
2
src/if.c
@ -684,7 +684,7 @@ if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs,
|
||||
#endif
|
||||
|
||||
ifp->active = active;
|
||||
ifp->carrier = if_carrier(ifp);
|
||||
ifp->carrier = if_carrier_ifadata(ifp, ifa->ifa_data);
|
||||
TAILQ_INSERT_TAIL(ifs, ifp, next);
|
||||
}
|
||||
|
||||
|
1
src/if.h
1
src/if.h
@ -160,6 +160,7 @@ int if_domtu(const struct interface *, short int);
|
||||
#define if_getmtu(ifp) if_domtu((ifp), 0)
|
||||
#define if_setmtu(ifp, mtu) if_domtu((ifp), (mtu))
|
||||
int if_carrier(struct interface *);
|
||||
int if_carrier_ifadata(struct interface *, void *);
|
||||
int if_pollinit(struct interface *ifp);
|
||||
|
||||
#ifdef ALIAS_ADDR
|
||||
|
Loading…
Reference in New Issue
Block a user