]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
When trying IPv4LL from a DHCP lease with an IPv4LL address, just
authorRoy Marples <roy@marples.name>
Fri, 26 Feb 2010 15:06:51 +0000 (15:06 +0000)
committerRoy Marples <roy@marples.name>
Fri, 26 Feb 2010 15:06:51 +0000 (15:06 +0000)
use the address and nothing else.

ipv4ll.c

index 46b169a55111489d640bede9a7ffedc1f7e30194..7a8e585d9e4c825959d262550aabccde4fe16a81 100644 (file)
--- 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);
 }