Mercurial > hg > dhcpcd
changeset 2555:642134e8d77c draft
Fix link handling where kernel reported flags in LINK_UP may not be valid
when we actually process them.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Tue, 01 Jul 2014 21:06:07 +0000 |
| parents | 3823ba691bbb |
| children | 32b8516c20fc |
| files | dhcpcd.c if.c if.h |
| diffstat | 3 files changed, 22 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/dhcpcd.c Tue Jul 01 20:34:19 2014 +0000 +++ b/dhcpcd.c Tue Jul 01 21:06:07 2014 +0000 @@ -502,10 +502,23 @@ if (ifp == NULL || !(ifp->options->options & DHCPCD_LINK)) return; - if (carrier == LINK_UNKNOWN) + switch(carrier) { + case LINK_UNKNOWN: carrier = if_carrier(ifp); /* will set ifp->flags */ - else + break; + case LINK_UP: + /* we have a carrier! however, we need to ignore the flags + * set in the kernel message as sometimes this message is + * reported before IFF_UP is set by the kernel even though + * dhcpcd has already set it. + * + * So we check the flags now. If IFF_UP is still not set + * then we should expect an accompanying link_down message */ + if_setflag(ifp, 0); /* will set ifp->flags */ + break; + default: ifp->flags = flags; + } if (carrier == LINK_UNKNOWN) syslog(LOG_ERR, "%s: carrier_status: %m", ifname); @@ -582,12 +595,8 @@ syslog(LOG_ERR, "%s: ipv6_start: %m", ifp->name); ifp->options->options &= DHCPCD_IPV6; } - - if (!(ifp->flags & IFF_UP) && if_up(ifp) == -1) - syslog(LOG_ERR, "%s: if_up: %m", ifp->name); } - void dhcpcd_startinterface(void *arg) { @@ -597,6 +606,8 @@ char buf[DUID_LEN * 3]; pre_start(ifp); + if (!if_up(ifp) == -1) + syslog(LOG_ERR, "%s: if_up: %m", ifp->name); if (ifp->carrier == LINK_DOWN && ifo->options & DHCPCD_LINK) { syslog(LOG_INFO, "%s: waiting for carrier", ifp->name);
--- a/if.c Tue Jul 01 20:34:19 2014 +0000 +++ b/if.c Tue Jul 01 21:06:07 2014 +0000 @@ -133,7 +133,7 @@ } int -if_up(struct interface *ifp) +if_setflag(struct interface *ifp, short flag) { struct ifreq ifr; int s, r; @@ -152,10 +152,10 @@ #endif r = -1; if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) { - if ((ifr.ifr_flags & IFF_UP)) + if (flag == 0 || ifr.ifr_flags & flag) r = 0; else { - ifr.ifr_flags |= IFF_UP; + ifr.ifr_flags |= flag; if (ioctl(s, SIOCSIFFLAGS, &ifr) == 0) r = 0; }
--- a/if.h Tue Jul 01 20:34:19 2014 +0000 +++ b/if.h Tue Jul 01 21:06:07 2014 +0000 @@ -90,7 +90,8 @@ #define RAW_EOF 1 << 0 #define RAW_PARTIALCSUM 2 << 0 -int if_up(struct interface *ifp); +int if_setflag(struct interface *ifp, short flag); +#define if_up(ifp) if_setflag((ifp), IFF_UP) struct if_head *if_discover(struct dhcpcd_ctx *, int, char * const *); struct interface *if_find(struct dhcpcd_ctx *, const char *); void if_free(struct interface *);
