From: Roy Marples Date: Fri, 26 Feb 2010 15:06:51 +0000 (+0000) Subject: When trying IPv4LL from a DHCP lease with an IPv4LL address, just X-Git-Tag: v5.2.0~3 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=716f28888275611c14c492f6f4d2aaab24f59a8f;p=thirdparty%2Fdhcpcd.git When trying IPv4LL from a DHCP lease with an IPv4LL address, just use the address and nothing else. --- diff --git a/ipv4ll.c b/ipv4ll.c index 46b169a5..7a8e585d 100644 --- a/ipv4ll.c +++ b/ipv4ll.c @@ -40,8 +40,8 @@ #include "ipv4ll.h" #include "net.h" -static struct dhcp_message* -make_ipv4ll_lease(uint32_t old_addr) +static struct dhcp_message * +make_ipv4ll_lease(uint32_t addr) { uint32_t u32; struct dhcp_message *dhcp; @@ -49,6 +49,7 @@ make_ipv4ll_lease(uint32_t old_addr) dhcp = xzalloc(sizeof(*dhcp)); /* Put some LL options in */ + dhcp->yiaddr = addr; p = dhcp->options; *p++ = DHO_SUBNETMASK; *p++ = sizeof(u32); @@ -62,21 +63,30 @@ make_ipv4ll_lease(uint32_t old_addr) p += sizeof(u32); *p++ = DHO_END; + return dhcp; +} + +static struct dhcp_message * +find_ipv4ll_lease(uint32_t old_addr) +{ + uint32_t addr; + for (;;) { - dhcp->yiaddr = htonl(LINKLOCAL_ADDR | + addr = htonl(LINKLOCAL_ADDR | (((uint32_t)abs((int)arc4random()) % 0xFD00) + 0x0100)); - if (dhcp->yiaddr != old_addr && - IN_LINKLOCAL(ntohl(dhcp->yiaddr))) + if (addr != old_addr && + IN_LINKLOCAL(ntohl(addr))) break; } - return dhcp; + return make_ipv4ll_lease(addr); } void start_ipv4ll(void *arg) { struct interface *iface = arg; + uint32_t addr; delete_timeout(NULL, iface); iface->state->probes = 0; @@ -89,19 +99,23 @@ start_ipv4ll(void *arg) } } + if (iface->state->offer == NULL) + addr = 0; + else { + addr = iface->state->offer->yiaddr; + free(iface->state->offer); + } /* We maybe rebooting an IPv4LL address. */ - if (!iface->state->offer || - !IN_LINKLOCAL(htonl(iface->state->offer->yiaddr))) - { + if (!IN_LINKLOCAL(htonl(addr))) { syslog(LOG_INFO, "%s: probing for an IPv4LL address", iface->name); - delete_timeout(NULL, iface); - free(iface->state->offer); - iface->state->offer = make_ipv4ll_lease(0); - iface->state->lease.frominfo = 0; + addr = 0; } - /* Ensure we don't have a cookie */ - iface->state->offer->cookie = 0; + if (addr == 0) + iface->state->offer = find_ipv4ll_lease(addr); + else + iface->state->offer = make_ipv4ll_lease(addr); + iface->state->lease.frominfo = 0; send_arp_probe(iface); }