]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Allow IPv4LL address range to be configured by DHCP.
authorRoy Marples <roy@marples.name>
Wed, 17 Feb 2010 22:23:17 +0000 (22:23 +0000)
committerRoy Marples <roy@marples.name>
Wed, 17 Feb 2010 22:23:17 +0000 (22:23 +0000)
We now check the message for a DHCP cookie instead of the address
assigned to test for local link.

arp.c
bind.c
dhcp.c
dhcp.h
dhcpcd.c
if-pref.c
ipv4ll.c

diff --git a/arp.c b/arp.c
index 15d998253cc4078ad927fbfb58eb8f24dd81616b..e6a2928e5268d98226abfc10446f0e469e17d061 100644 (file)
--- a/arp.c
+++ b/arp.c
@@ -78,7 +78,7 @@ send_arp(const struct interface *iface, int op, in_addr_t sip, in_addr_t tip)
 static void
 handle_arp_failure(struct interface *iface)
 {
-       if (IN_LINKLOCAL(htonl(iface->state->fail.s_addr))) {
+       if (iface->state->offer->cookie != htonl(MAGIC_COOKIE)) {
                handle_ipv4ll_failure(iface);
                return;
        }
@@ -216,7 +216,7 @@ send_arp_announce(void *arg)
                add_timeout_sec(ANNOUNCE_WAIT, send_arp_announce, iface);
                return;
        }
-       if (IN_LINKLOCAL(htonl(state->new->yiaddr))) {
+       if (state->new->cookie != htonl(MAGIC_COOKIE)) {
                /* We should pretend to be at the end
                 * of the DHCP negotation cycle unless we rebooted */
                if (state->interval != 0)
diff --git a/bind.c b/bind.c
index 40fc09e774914a90be793f5e9f7c69e445e9a9cd..9e79ceaa82470ac443ee0fdd0606fa99bbc45401 100644 (file)
--- a/bind.c
+++ b/bind.c
@@ -143,7 +143,7 @@ bind_interface(void *arg)
                lease->leasetime = ~0U;
                lease->net.s_addr = ifo->req_mask.s_addr;
                state->reason = "STATIC";
-       } else if (IN_LINKLOCAL(htonl(state->new->yiaddr))) {
+       } else if (state->new->cookie != htonl(MAGIC_COOKIE)) {
                syslog(LOG_INFO, "%s: using IPv4LL address %s",
                    iface->name, inet_ntoa(lease->addr));
                lease->leasetime = ~0U;
diff --git a/dhcp.c b/dhcp.c
index 2c0c4a138165379136a6509143e4c3a2aacd88a0..c036c00f40472e67ae919c7862dd21d1f66534a3 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -843,19 +843,16 @@ make_message(struct dhcp_message **message,
        m = (uint8_t *)dhcp;
        p = dhcp->options;
 
-       if ((type == DHCP_INFORM ||
-               type == DHCP_RELEASE ||
-               type == DHCP_REQUEST) &&
-           !IN_LINKLOCAL(ntohl(iface->addr.s_addr)))
+       if ((type == DHCP_INFORM || type == DHCP_RELEASE ||
+               (type == DHCP_REQUEST &&
+                   iface->net.s_addr == lease->net.s_addr &&
+                   (iface->state->new == NULL ||
+                       iface->state->new->cookie == htonl(MAGIC_COOKIE)))))
        {
                dhcp->ciaddr = iface->addr.s_addr;
                /* In-case we haven't actually configured the address yet */
                if (type == DHCP_INFORM && iface->addr.s_addr == 0)
                        dhcp->ciaddr = lease->addr.s_addr;
-               /* Zero the address if we're currently on a different subnet */
-               if (type == DHCP_REQUEST &&
-                   iface->net.s_addr != lease->net.s_addr)
-                       dhcp->ciaddr = 0;
        }
 
        dhcp->op = DHCP_BOOTREQUEST;
@@ -893,7 +890,7 @@ make_message(struct dhcp_message **message,
                p += iface->clientid[0] + 1;
        }
 
-       if (lease->addr.s_addr && !IN_LINKLOCAL(htonl(lease->addr.s_addr))) {
+       if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) {
                if (type == DHCP_DECLINE ||
                    type == DHCP_DISCOVER ||
                    (type == DHCP_REQUEST &&
@@ -1374,6 +1371,7 @@ get_lease(struct dhcp_lease *lease, const struct dhcp_message *dhcp)
 {
        struct timeval now;
 
+       lease->cookie = dhcp->cookie;
        /* BOOTP does not set yiaddr for replies when ciaddr is set. */
        if (dhcp->yiaddr)
                lease->addr.s_addr = dhcp->yiaddr;
diff --git a/dhcp.h b/dhcp.h
index 3562a5a02b530fd52a2f5bb4f1f1e36c0b920612..cb42275f52db1f4aced39ef57bbe2ea29c054171 100644 (file)
--- a/dhcp.h
+++ b/dhcp.h
@@ -165,6 +165,7 @@ struct dhcp_lease {
        time_t leasedfrom;
        struct timeval boundtime;
        uint8_t frominfo;
+       uint32_t cookie;
 };
 
 #include "dhcpcd.h"
index f37c801705b73746651c613ea3b9681b0ef44656..bcfb7b007d418baa809bd46374faf5c2cd73cf1b 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -540,6 +540,7 @@ handle_dhcp(struct interface *iface, struct dhcp_message **dhcpp)
        {
                lease->frominfo = 0;
                lease->addr.s_addr = dhcp->yiaddr;
+               lease->cookie = dhcp->cookie;
                if (type == 0 ||
                    get_option_addr(&lease->server, dhcp, DHO_SERVERID) != 0)
                        lease->server.s_addr = INADDR_ANY;
@@ -728,8 +729,8 @@ send_release(struct interface *iface)
 {
        struct timespec ts;
 
-       if (iface->state->lease.addr.s_addr &&
-           !IN_LINKLOCAL(htonl(iface->state->lease.addr.s_addr)))
+       if (iface->state->new != NULL &&
+           iface->state->new->cookie == htonl(MAGIC_COOKIE))
        {
                syslog(LOG_INFO, "%s: releasing lease of %s",
                    iface->name, inet_ntoa(iface->state->lease.addr));
@@ -1064,21 +1065,20 @@ start_reboot(struct interface *iface)
                start_static(iface);
                return;
        }
-       if (ifo->reboot == 0) {
+       if (ifo->reboot == 0 || iface->state->offer == NULL) {
                start_discover(iface);
                return;
        }
-       if (IN_LINKLOCAL(htonl(iface->state->lease.addr.s_addr))) {
+       if (ifo->options & DHCPCD_INFORM) {
+               syslog(LOG_INFO, "%s: informing address of %s",
+                   iface->name, inet_ntoa(iface->state->lease.addr));
+       } else if (iface->state->offer->cookie == 0) {
                if (ifo->options & DHCPCD_IPV4LL) {
                        iface->state->claims = 0;
                        send_arp_announce(iface);
                } else
                        start_discover(iface);
                return;
-       }
-       if (ifo->options & DHCPCD_INFORM) {
-               syslog(LOG_INFO, "%s: informing address of %s",
-                   iface->name, inet_ntoa(iface->state->lease.addr));
        } else {
                syslog(LOG_INFO, "%s: rebinding lease of %s",
                    iface->name, inet_ntoa(iface->state->lease.addr));
@@ -1161,7 +1161,7 @@ start_interface(void *arg)
        if (iface->state->offer) {
                get_lease(&iface->state->lease, iface->state->offer);
                iface->state->lease.frominfo = 1;
-               if (IN_LINKLOCAL(htonl(iface->state->offer->yiaddr))) {
+               if (iface->state->offer->cookie == 0) {
                        if (iface->state->offer->yiaddr ==
                            iface->addr.s_addr)
                        {
@@ -1189,9 +1189,9 @@ start_interface(void *arg)
                        }
                }
        }
-       if (!iface->state->offer)
+       if (iface->state->offer == NULL)
                start_discover(iface);
-       else if (IN_LINKLOCAL(htonl(iface->state->lease.addr.s_addr)) &&
+       else if (iface->state->offer->cookie == 0 &&
            iface->state->options->options & DHCPCD_IPV4LL)
                start_ipv4ll(iface);
        else
index d8741d166c3c3cf7cfef045faabda24d6ddd75e5..d6eee3aea7cb097758102e7b4c87f0801e1884d8 100644 (file)
--- a/if-pref.c
+++ b/if-pref.c
@@ -51,9 +51,9 @@ ifcmp(struct interface *si, struct interface *ti)
                return 1;
        /* If we are either, they neither have a lease, or they both have.
         * We need to check for IPv4LL and make it non-preferred. */
-       if (si->state->new) {
-               sill = IN_LINKLOCAL(htonl(si->state->new->yiaddr));
-               till = IN_LINKLOCAL(htonl(ti->state->new->yiaddr));
+       if (si->state->new && ti->state->new) {
+               sill = (si->state->new->cookie == htonl(MAGIC_COOKIE));
+               till = (ti->state->new->cookie == htonl(MAGIC_COOKIE));
                if (!sill && till)
                        return -1;
                if (sill && !till)
index a91a2f326b422a460957e6eebde55b9c0d4eb587..13f163a90035a2bb1b0dda4bcc2a90d78b2fb679 100644 (file)
--- a/ipv4ll.c
+++ b/ipv4ll.c
@@ -99,6 +99,8 @@ start_ipv4ll(void *arg)
                iface->state->offer = make_ipv4ll_lease(0);
                iface->state->lease.frominfo = 0;
        }
+       /* Ensure we don't have a cookie */
+       iface->state->offer->cookie = 0;
        send_arp_probe(iface);
 }