struct ipv4_addr *iap;
TAILQ_FOREACH(ifp, ctx->ifaces, next) {
- if (!ifp->active || !IS_LINK_UP(ifp))
+ if (!ifp->active || !if_is_link_up(ifp))
continue;
iap = ipv4_iffindaddr(ifp, ia, NULL);
if (iap == NULL)
if (callback == NULL) {
/* No carrier? Don't bother sending the packet. */
- if (!IS_LINK_UP(ifp))
+ if (!if_is_link_up(ifp))
return;
logdebugx("%s: sending %s with xid 0x%x",
ifp->name,
(arc4random_uniform(MSEC_PER_SEC * 2) - MSEC_PER_SEC);
/* No carrier? Don't bother sending the packet.
* However, we do need to advance the timeout. */
- if (!IS_LINK_UP(ifp))
+ if (!if_is_link_up(ifp))
goto fail;
logdebugx("%s: sending %s (xid 0x%x), next in %0.1f seconds",
ifp->name,
state->state = DHS_REBOOT;
state->interval = 0;
- if (ifo->options & DHCPCD_LINK && !IS_LINK_UP(ifp)) {
+ if (ifo->options & DHCPCD_LINK && !if_is_link_up(ifp)) {
loginfox("%s: waiting for carrier", ifp->name);
return;
}
state->state = DHS_RELEASE;
dhcp_unlink(ifp->ctx, state->leasefile);
- if (IS_LINK_UP(ifp) &&
+ if (if_is_link_up(ifp) &&
state->new != NULL &&
state->lease.server.s_addr != INADDR_ANY)
{
};
char uaddr[INET6_ADDRSTRLEN];
- if (!callback && !IS_LINK_UP(ifp))
+ if (!callback && !if_is_link_up(ifp))
return 0;
if (!IN6_IS_ADDR_UNSPECIFIED(&state->unicast)) {
+ (unsigned int)((float)state->RT
* ((float)lr / DHCP6_RAND_DIV));
- if (IS_LINK_UP(ifp))
+ if (if_is_link_up(ifp))
logdebugx("%s: %s %s (xid 0x%02x%02x%02x)%s%s,"
" next in %0.1f seconds",
ifp->name,
}
}
- if (!IS_LINK_UP(ifp))
+ if (!if_is_link_up(ifp))
return 0;
/* Update the elapsed time */
if (ia->sla_len == 0) {
/* no SLA configured, so lets
* automate it */
- if (!IS_LINK_UP(ifd)) {
+ if (!if_is_link_up(ifd)) {
logdebugx(
"%s: has no carrier, cannot"
" delegate addresses",
sla = &ia->sla[j];
if (strcmp(ifd->name, sla->ifname))
continue;
- if (!IS_LINK_UP(ifd)) {
+ if (!if_is_link_up(ifd)) {
logdebugx(
"%s: has no carrier, cannot"
" delegate addresses",
if (drop && options & DHCPCD_RELEASE &&
state->state != DH6S_DELEGATED)
{
- if (IS_LINK_UP(ifp) &&
+ if (if_is_link_up(ifp) &&
state->state != DH6S_RELEASED &&
state->state != DH6S_INFORMED)
{
void
dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags)
{
- bool nolink = ifp->options == NULL ||
- !(ifp->options->options & DHCPCD_LINK);
+ bool was_link_up = if_is_link_up(ifp);
+ ifp->carrier = carrier;
ifp->flags = flags;
- /* Wireless *must* support link state changes. */
- if (carrier == LINK_UNKNOWN && ifp->wireless)
- carrier = LINK_DOWN;
- if (carrier == LINK_DOWN || (ifp->flags & IFF_UP) == 0) {
- if (ifp->carrier == LINK_DOWN)
- return;
- ifp->carrier = LINK_DOWN;
- if (!ifp->active || nolink)
+ if (!if_is_link_up(ifp)) {
+ if (!was_link_up || !ifp->active)
return;
loginfox("%s: carrier lost", ifp->name);
script_runreason(ifp, "NOCARRIER");
#endif
dhcpcd_drop(ifp, 0);
if (ifp->options->options & DHCPCD_ANONYMOUS) {
- bool was_up = ifp->flags & IFF_UP;
+ bool is_up = ifp->flags & IFF_UP;
- if (was_up)
+ if (is_up)
if_down(ifp);
if (if_randomisemac(ifp) == -1 && errno != ENXIO)
logerr(__func__);
- if (was_up)
+ if (is_up)
if_up(ifp);
}
return;
* The consideration of any other information about carrier should
* be handled in the OS specific if_carrier() function.
*/
- if (ifp->carrier == carrier)
+ if (was_link_up)
return;
- ifp->carrier = carrier;
+
if (ifp->active) {
if (carrier == LINK_UNKNOWN)
loginfox("%s: carrier unknown, assuming up", ifp->name);
}
}
- if (!ifp->active || nolink)
+ if (!ifp->active)
return;
dhcpcd_initstate(ifp, 0);
struct interface *ifp = arg;
struct if_options *ifo = ifp->options;
- if (ifo->options & DHCPCD_LINK && !IS_LINK_UP(ifp)) {
+ if (ifo->options & DHCPCD_LINK && !if_is_link_up(ifp)) {
loginfox("%s: waiting for carrier", ifp->name);
return;
}
return;
script_runreason(ifp, "PREINIT");
- if (ifp->wireless && ifp->carrier == LINK_UP)
+ if (ifp->wireless && if_is_link_up(ifp))
dhcpcd_reportssid(ifp);
if (ifp->options->options & DHCPCD_LINK && ifp->carrier != LINK_UNKNOWN)
script_runreason(ifp,
if (!ifp->active)
return;
- if (ifp->options->options & DHCPCD_LINK && !IS_LINK_UP(ifp))
+ if (ifp->options->options & DHCPCD_LINK && !if_is_link_up(ifp))
return;
#ifdef INET
TAILQ_FOREACH(ifp, ctx.ifaces, next) {
if (ifp->active) {
run_preinit(ifp);
- if (!(ifp->options->options & DHCPCD_LINK) ||
- ifp->carrier != LINK_DOWN)
+ if (if_is_link_up(ifp))
opt = 1;
}
}
#define LINK_UP 1
#define LINK_UNKNOWN 0
#define LINK_DOWN -1
-#define IS_LINK_UP(ifp) (((ifp)->flags & IFF_UP) && (ifp)->carrier != LINK_DOWN)
#define IF_DATA_IPV4 0
#define IF_DATA_ARP 1
}
int
-if_carrier(__unused struct interface *ifp, const void *ifadata)
+if_carrier(struct interface *ifp, const void *ifadata)
{
const struct if_data *ifi = ifadata;
if (ifi->ifi_link_state >= LINK_STATE_UP)
return LINK_UP;
- if (ifi->ifi_link_state == LINK_STATE_UNKNOWN)
+ if (ifi->ifi_link_state == LINK_STATE_UNKNOWN) {
+ /*
+ * Work around net80211 issues in some BSDs.
+ * Wireless MUST support link state change.
+ */
+ if (ifp->wireless)
+ return LINK_DOWN;
return LINK_UNKNOWN;
+ }
return LINK_DOWN;
}
return 0;
}
+bool
+if_is_link_up(const struct interface *ifp)
+{
+
+ return ifp->flags & IFF_UP &&
+ (ifp->carrier == LINK_UP ||
+ (ifp->carrier == LINK_UNKNOWN &&
+ !(ifp->options == NULL ||
+ ifp->options->options & DHCPCD_LINK)));
+}
+
int
if_randomisemac(struct interface *ifp)
{
ifp->active = active;
ifp->carrier = if_carrier(ifp, ifa->ifa_data);
-
- /* Wireless devices must support carrier change,
- * so treat UNKNOWN as down. */
- if (ifp->wireless && ifp->carrier == LINK_UNKNOWN)
- ifp->carrier = LINK_DOWN;
-
TAILQ_INSERT_TAIL(ifs, ifp, next);
}
int if_setflag(struct interface *, short, short);
#define if_up(ifp) if_setflag((ifp), (IFF_UP | IFF_RUNNING), 0)
#define if_down(ifp) if_setflag((ifp), 0, IFF_UP);
+bool if_is_link_up(const struct interface *);
bool if_valid_hwaddr(const uint8_t *, size_t);
struct if_head *if_discover(struct dhcpcd_ctx *, struct ifaddrs **,
int, char * const *);
defined(IFF_NOLINKLOCAL)
/* Only add the LL address if we have a carrier, so DaD works. */
#define CAN_ADD_LLADDR(ifp) \
- (!((ifp)->options->options & DHCPCD_LINK) || IS_LINK_UP((ifp)))
+ (!((ifp)->options->options & DHCPCD_LINK) || if_is_link_up((ifp)))
#ifdef __sun
/* Although we can add our own LL address, we cannot drop it
* without unplumbing the if which is a lot of code.
const struct rs_state *state = RS_CSTATE(ifp);
int s;
- if (state == NULL || !IS_LINK_UP(ifp))
+ if (state == NULL || !if_is_link_up(ifp))
goto freeit;
#ifdef SIN6_LEN
iaf = NULL;
TAILQ_FOREACH(ifp, ctx->ifaces, next) {
state = IPV6_STATE(ifp);
- if (state == NULL || !IS_LINK_UP(ifp))
+ if (state == NULL || !if_is_link_up(ifp))
continue;
TAILQ_FOREACH(iap, &state->addrs, next) {