Mercurial > hg > dhcpcd
changeset 2518:28182250f3a0 draft
Add an IPv6 link-local address before upping the interface if needed.
Bring an interface up when we start it and not during discovery.
As such, stop waiting on carrier for a second if we did.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Wed, 04 Jun 2014 23:54:15 +0000 |
| parents | 1d4beca0771f |
| children | 80278d0c53c3 |
| files | dhcpcd.c if-options.h if.c if.h ipv6.c |
| diffstat | 5 files changed, 34 insertions(+), 45 deletions(-) [+] |
line wrap: on
line diff
--- a/dhcpcd.c Wed Jun 04 23:34:39 2014 +0000 +++ b/dhcpcd.c Wed Jun 04 23:54:15 2014 +0000 @@ -569,6 +569,19 @@ size_t i; char buf[DUID_LEN * 3]; + /* Add our link-local address before upping the interface + * so our RFC7217 address beats the hwaddr based one */ + if (ifo->options & DHCPCD_IPV6 && ipv6_start(ifp) == -1) { + syslog(LOG_ERR, "%s: ipv6_start: %m", ifp->name); + ifo->options &= DHCPCD_IPV6; + } + + if (!(ifp->flags & IFF_UP) && if_carrier(ifp) != LINK_UNKNOWN) { + if (if_up(ifp) == -1) + syslog(LOG_ERR, "%s: if_up: %m", + ifp->name); + } + if (ifp->carrier == LINK_UNKNOWN) dhcpcd_handlecarrier(ifp->ctx, LINK_UNKNOWN, 0, ifp->name); if (ifp->carrier == LINK_DOWN) { @@ -604,10 +617,6 @@ } } - if (ifo->options & DHCPCD_IPV6 && ipv6_start(ifp) == -1) { - syslog(LOG_ERR, "%s: ipv6_start: %m", ifp->name); - ifo->options &= DHCPCD_IPV6; - } if (ifo->options & DHCPCD_IPV6) { if (ifo->options & DHCPCD_IPV6RS && !(ifo->options & DHCPCD_INFORM)) @@ -1536,25 +1545,6 @@ } if (!(ctx.options & DHCPCD_BACKGROUND)) { - /* If we don't have a carrier, we may have to wait for a second - * before one becomes available if we brought an interface up */ - if (opt == 0 && - ctx.options & DHCPCD_LINK && - ctx.options & DHCPCD_WAITUP && - !(ctx.options & DHCPCD_WAITIP)) - { - ts.tv_sec = 1; - ts.tv_nsec = 0; - nanosleep(&ts, NULL); - TAILQ_FOREACH(ifp, ctx.ifaces, next) { - dhcpcd_handlecarrier(&ctx, LINK_UNKNOWN, 0, - ifp->name); - if (ifp->carrier != LINK_DOWN) { - opt = 1; - break; - } - } - } if (ctx.options & DHCPCD_MASTER) t = ifo->timeout; else if ((ifp = TAILQ_FIRST(ctx.ifaces)))
--- a/if-options.h Wed Jun 04 23:34:39 2014 +0000 +++ b/if-options.h Wed Jun 04 23:54:15 2014 +0000 @@ -77,7 +77,7 @@ #define DHCPCD_VENDORRAW (1ULL << 23) #define DHCPCD_TIMEOUT_IPV4LL (1ULL << 24) #define DHCPCD_WAITIP (1ULL << 25) -#define DHCPCD_WAITUP (1ULL << 26) +#define DHCPCD_SLAACPRIVATE (1ULL << 26) #define DHCPCD_CSR_WARNED (1ULL << 27) #define DHCPCD_XID_HWADDR (1ULL << 28) #define DHCPCD_BROADCAST (1ULL << 29) @@ -102,7 +102,6 @@ #define DHCPCD_IAID (1ULL << 48) #define DHCPCD_DHCP (1ULL << 49) #define DHCPCD_DHCP6 (1ULL << 50) -#define DHCPCD_SLAACPRIVATE (1ULL << 51) extern const struct option cf_options[];
--- a/if.c Wed Jun 04 23:34:39 2014 +0000 +++ b/if.c Wed Jun 04 23:54:15 2014 +0000 @@ -132,8 +132,8 @@ return r; } -static int -up_interface(struct interface *iface) +int +if_up(struct interface *ifp) { struct ifreq ifr; int s, r; @@ -144,7 +144,7 @@ if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) return -1; memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); #ifdef __linux__ /* We can only bring the real interface up */ if ((p = strchr(ifr.ifr_name, ':'))) @@ -159,7 +159,7 @@ if (ioctl(s, SIOCSIFFLAGS, &ifr) == 0) r = 0; } - iface->flags = (unsigned int)ifr.ifr_flags; + ifp->flags = (unsigned int)ifr.ifr_flags; } close(s); return r; @@ -296,20 +296,6 @@ strlcpy(ifp->name, p, sizeof(ifp->name)); ifp->flags = ifa->ifa_flags; - /* Bring the interface up if not already */ - if (!(ifp->flags & IFF_UP) -#ifdef SIOCGIFMEDIA - && if_carrier(ifp) != LINK_UNKNOWN -#endif - ) - { - if (up_interface(ifp) == 0) - ctx->options |= DHCPCD_WAITUP; - else - syslog(LOG_ERR, "%s: up_interface: %m", - ifp->name); - } - sdl_type = 0; /* Don't allow loopback unless explicit */ if (ifp->flags & IFF_LOOPBACK) {
--- a/if.h Wed Jun 04 23:34:39 2014 +0000 +++ b/if.h Wed Jun 04 23:54:15 2014 +0000 @@ -90,6 +90,7 @@ #define RAW_EOF 1 << 0 #define RAW_PARTIALCSUM 2 << 0 +int if_up(struct interface *ifp); 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 *);
--- a/ipv6.c Wed Jun 04 23:34:39 2014 +0000 +++ b/ipv6.c Wed Jun 04 23:54:15 2014 +0000 @@ -31,6 +31,7 @@ #include <sys/stat.h> #include <net/route.h> +#include <netinet/if_ether.h> #include <netinet/in.h> #ifdef __linux__ @@ -917,7 +918,7 @@ switch (ifp->family) { case ARPHRD_ETHER: /* Check for a valid hardware address */ - if (ifp->hwlen != 6 & ifp->hwlen != 8) { + if (ifp->hwlen != 6 && ifp->hwlen != 8) { errno = ENOTSUP; return -1; } @@ -988,8 +989,20 @@ int ipv6_start(struct interface *ifp) { + const struct ipv6_state *state; + const struct ipv6_addr *ap; - if (ipv6_linklocal(ifp) == NULL && ipv6_addlinklocal(ifp) == -1) + state = IPV6_CSTATE(ifp); + if (state) { + TAILQ_FOREACH(ap, &state->addrs, next) { + if (IN6_IS_ADDR_LINKLOCAL(&ap->addr) && + !(ap->addr_flags & IN6_IFF_DUPLICATED)) + break; + } + } else + ap = NULL; + + if (ap == NULL && ipv6_addlinklocal(ifp) == -1) return -1; return 0; }
