]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
DHCP: Set address vltime and pltime to the length of the lease
authorRoy Marples <roy@marples.name>
Mon, 22 Jul 2019 09:37:13 +0000 (10:37 +0100)
committerRoy Marples <roy@marples.name>
Mon, 22 Jul 2019 09:37:13 +0000 (10:37 +0100)
The only OS which supports this is Linux, but more importantly it
will report the address as "dynamic" so that users can distinguish
it from statically added addresses.

src/dhcp.c
src/dhcp.h
src/if-linux.c
src/ipv4.c
src/ipv4.h
src/ipv4ll.c

index c66b78ccb523ee4ba67dec0ab08ff57659efb22f..9a83dc6a4a569faa937e97ee07b7329294b51509 100644 (file)
@@ -1443,7 +1443,7 @@ get_lease(struct interface *ifp,
        }
        if (get_option_uint32(ctx, &lease->leasetime,
            bootp, len, DHO_LEASETIME) != 0)
-               lease->leasetime = ~0U; /* Default to infinite lease */
+               lease->leasetime = DHCP_INFINITE_LIFETIME;
        if (get_option_uint32(ctx, &lease->renewaltime,
            bootp, len, DHO_RENEWALTIME) != 0)
                lease->renewaltime = 0;
@@ -2135,17 +2135,17 @@ dhcp_bind(struct interface *ifp)
                loginfox("%s: using static address %s/%d",
                    ifp->name, inet_ntoa(lease->addr),
                    inet_ntocidr(lease->mask));
-               lease->leasetime = ~0U;
+               lease->leasetime = DHCP_INFINITE_LIFETIME;
                state->reason = "STATIC";
        } else if (ifo->options & DHCPCD_INFORM) {
                loginfox("%s: received approval for %s",
                    ifp->name, inet_ntoa(lease->addr));
-               lease->leasetime = ~0U;
+               lease->leasetime = DHCP_INFINITE_LIFETIME;
                state->reason = "INFORM";
        } else {
                if (lease->frominfo)
                        state->reason = "TIMEOUT";
-               if (lease->leasetime == ~0U) {
+               if (lease->leasetime == DHCP_INFINITE_LIFETIME) {
                        lease->renewaltime =
                            lease->rebindtime =
                            lease->leasetime;
@@ -2208,7 +2208,7 @@ dhcp_bind(struct interface *ifp)
                else
                        state->reason = "BOUND";
        }
-       if (lease->leasetime == ~0U)
+       if (lease->leasetime == DHCP_INFINITE_LIFETIME)
                lease->renewaltime = lease->rebindtime = lease->leasetime;
        else {
                eloop_timeout_add_sec(ctx->eloop,
@@ -2346,7 +2346,8 @@ dhcp_arp_address(struct interface *ifp)
 
                        get_lease(ifp, &l, state->offer, state->offer_len);
                        /* Add the address now, let the kernel handle DAD. */
-                       ipv4_addaddr(ifp, &l.addr, &l.mask, &l.brd);
+                       ipv4_addaddr(ifp, &l.addr, &l.mask, &l.brd,
+                           l.leasetime, l.leastime);
                } else
                        loginfox("%s: waiting for DAD on %s",
                            ifp->name, inet_ntoa(addr));
@@ -3759,7 +3760,7 @@ dhcp_start1(void *arg)
                        state->offer = NULL;
                        state->offer_len = 0;
                } else if (!(ifo->options & DHCPCD_LASTLEASE_EXTEND) &&
-                   state->lease.leasetime != ~0U &&
+                   state->lease.leasetime != DHCP_INFINITE_LIFETIME &&
                    stat(state->leasefile, &st) == 0)
                {
                        time_t now;
index 18c627b94918cb8c44b61eb99fb5a68958b58a37..4b6311a38bb536544f95dd6392e3acb0f0c5e779 100644 (file)
@@ -183,6 +183,10 @@ struct dhcp_lease {
        uint32_t cookie;
 };
 
+#ifndef DHCP_INFINITE_LIFETIME
+#  define DHCP_INFINITE_LIFETIME       (~0U)
+#endif
+
 enum DHS {
        DHS_NONE,
        DHS_INIT,
index 447679919d1aab7635c44a611aa07fdb624b2caa..88060c9ba74da866f4c5d0ece53aa53a8f8d7d87 100644 (file)
@@ -1466,13 +1466,12 @@ bpf_attach(int s, void *filter, unsigned int filter_len)
 }
 
 int
-if_address(unsigned char cmd, const struct ipv4_addr *addr)
+if_address(unsigned char cmd, const struct ipv4_addr *ia)
 {
        struct nlma nlm;
+       struct ifa_cacheinfo cinfo;
        int retval = 0;
-#if defined(IFA_F_NOPREFIXROUTE)
        uint32_t flags = 0;
-#endif
 
        memset(&nlm, 0, sizeof(nlm));
        nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
@@ -1480,29 +1479,39 @@ if_address(unsigned char cmd, const struct ipv4_addr *addr)
        nlm.hdr.nlmsg_type = cmd;
        if (cmd == RTM_NEWADDR)
                nlm.hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
-       nlm.ifa.ifa_index = addr->iface->index;
+       nlm.ifa.ifa_index = ia->iface->index;
        nlm.ifa.ifa_family = AF_INET;
-       nlm.ifa.ifa_prefixlen = inet_ntocidr(addr->mask);
+
+       nlm.ifa.ifa_prefixlen = inet_ntocidr(ia->mask);
+
 #if 0
        /* This creates the aliased interface */
        add_attr_l(&nlm.hdr, sizeof(nlm), IFA_LABEL,
-           addr->iface->alias,
-           (unsigned short)(strlen(addr->iface->alias) + 1));
+           ia->iface->alias,
+           (unsigned short)(strlen(ia->iface->alias) + 1));
 #endif
+
        add_attr_l(&nlm.hdr, sizeof(nlm), IFA_LOCAL,
-           &addr->addr.s_addr, sizeof(addr->addr.s_addr));
-       if (cmd == RTM_NEWADDR)
-               add_attr_l(&nlm.hdr, sizeof(nlm), IFA_BROADCAST,
-                   &addr->brd.s_addr, sizeof(addr->brd.s_addr));
+           &ia->addr.s_addr, sizeof(ia->addr.s_addr));
 
+       if (cmd == RTM_NEWADDR) {
 #ifdef IFA_F_NOPREFIXROUTE
-       if (nlm.ifa.ifa_prefixlen < 32)
-               flags |= IFA_F_NOPREFIXROUTE;
-       if (flags)
-               add_attr_32(&nlm.hdr, sizeof(nlm), IFA_FLAGS, flags);
+               if (nlm.ifa.ifa_prefixlen < 32)
+                       flags |= IFA_F_NOPREFIXROUTE;
 #endif
+               add_attr_32(&nlm.hdr, sizeof(nlm), IFA_FLAGS, flags);
 
-       if (send_netlink(addr->iface->ctx, NULL,
+               add_attr_l(&nlm.hdr, sizeof(nlm), IFA_BROADCAST,
+                   &ia->brd.s_addr, sizeof(ia->brd.s_addr));
+
+               memset(&cinfo, 0, sizeof(cinfo));
+               cinfo.ifa_prefered = ia->pltime;
+               cinfo.ifa_valid = ia->vltime;
+               add_attr_l(&nlm.hdr, sizeof(nlm), IFA_CACHEINFO,
+                   &cinfo, sizeof(cinfo));
+       }
+
+       if (send_netlink(ia->iface->ctx, NULL,
            NETLINK_ROUTE, &nlm.hdr, NULL) == -1)
                retval = -1;
        return retval;
@@ -1524,11 +1533,7 @@ if_address6(unsigned char cmd, const struct ipv6_addr *ia)
 {
        struct nlma nlm;
        struct ifa_cacheinfo cinfo;
-/* IFA_FLAGS is not a define, but is was added at the same time
- * IFA_F_NOPREFIXROUTE was do use that. */
-#if defined(IFA_F_NOPREFIXROUTE) || defined(IFA_F_MANAGETEMPADDR)
        uint32_t flags = 0;
-#endif
 
        memset(&nlm, 0, sizeof(nlm));
        nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
@@ -1538,22 +1543,10 @@ if_address6(unsigned char cmd, const struct ipv6_addr *ia)
                nlm.hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
        nlm.ifa.ifa_index = ia->iface->index;
        nlm.ifa.ifa_family = AF_INET6;
-#ifdef IPV6_MANAGETEMPADDR
-       if (ia->flags & IPV6_AF_TEMPORARY) {
-               /* Currently the kernel filters out these flags */
-#ifdef IFA_F_NOPREFIXROUTE
-               flags |= IFA_F_TEMPORARY;
-#else
-               nlm.ifa.ifa_flags |= IFA_F_TEMPORARY;
-#endif
-       }
-#elif IFA_F_MANAGETEMPADDR
-       if (ia->flags & IPV6_AF_AUTOCONF)
-               flags |= IFA_F_MANAGETEMPADDR;
-#endif
 
        /* Add as /128 if no IFA_F_NOPREFIXROUTE ? */
        nlm.ifa.ifa_prefixlen = ia->prefix_len;
+
 #if 0
        /* This creates the aliased interface */
        add_attr_l(&nlm.hdr, sizeof(nlm), IFA_LABEL,
@@ -1563,6 +1556,25 @@ if_address6(unsigned char cmd, const struct ipv6_addr *ia)
            &ia->addr.s6_addr, sizeof(ia->addr.s6_addr));
 
        if (cmd == RTM_NEWADDR) {
+#ifdef IPV6_MANAGETEMPADDR
+               if (ia->flags & IPV6_AF_TEMPORARY) {
+                       /* Currently the kernel filters out these flags */
+#ifdef IFA_F_NOPREFIXROUTE
+                       flags |= IFA_F_TEMPORARY;
+#else
+                       nlm.ifa.ifa_flags |= IFA_F_TEMPORARY;
+#endif
+               }
+#elif IFA_F_MANAGETEMPADDR
+               if (ia->flags & IPV6_AF_AUTOCONF)
+                       flags |= IFA_F_MANAGETEMPADDR;
+#endif
+#ifdef IFA_F_NOPREFIXROUTE
+               if (!IN6_IS_ADDR_LINKLOCAL(&ia->addr))
+                       flags |= IFA_F_NOPREFIXROUTE;
+#endif
+               add_attr_32(&nlm.hdr, sizeof(nlm), IFA_FLAGS, flags);
+
                memset(&cinfo, 0, sizeof(cinfo));
                cinfo.ifa_prefered = ia->prefix_pltime;
                cinfo.ifa_valid = ia->prefix_vltime;
@@ -1570,15 +1582,6 @@ if_address6(unsigned char cmd, const struct ipv6_addr *ia)
                    &cinfo, sizeof(cinfo));
        }
 
-#ifdef IFA_F_NOPREFIXROUTE
-       if (!IN6_IS_ADDR_LINKLOCAL(&ia->addr))
-               flags |= IFA_F_NOPREFIXROUTE;
-#endif
-#if defined(IFA_F_NOPREFIXROUTE) || defined(IFA_F_MANAGETEMPADDR)
-       if (flags)
-               add_attr_32(&nlm.hdr, sizeof(nlm), IFA_FLAGS, flags);
-#endif
-
        return send_netlink(ia->iface->ctx, NULL,
            NETLINK_ROUTE, &nlm.hdr, NULL);
 }
index 9f908ede60485828c1debbc5235de6fdb12efb72..06a5dabff7899b4ea89f10ce295ce557db90e6e4 100644 (file)
@@ -599,7 +599,8 @@ find_lun:
 
 struct ipv4_addr *
 ipv4_addaddr(struct interface *ifp, const struct in_addr *addr,
-    const struct in_addr *mask, const struct in_addr *bcast)
+    const struct in_addr *mask, const struct in_addr *bcast,
+    uint32_t vltime, uint32_t pltime)
 {
        struct ipv4_state *state;
        struct ipv4_addr *ia;
@@ -639,6 +640,8 @@ ipv4_addaddr(struct interface *ifp, const struct in_addr *addr,
 
        ia->mask = *mask;
        ia->brd = *bcast;
+       ia->vltime = vltime;
+       ia->pltime = pltime;
        snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
            inet_ntoa(*addr), inet_ntocidr(*mask));
 
@@ -681,7 +684,8 @@ ipv4_daddaddr(struct interface *ifp, const struct dhcp_lease *lease)
        struct dhcp_state *state;
        struct ipv4_addr *ia;
 
-       ia = ipv4_addaddr(ifp, &lease->addr, &lease->mask, &lease->brd);
+       ia = ipv4_addaddr(ifp, &lease->addr, &lease->mask, &lease->brd,
+           lease->leasetime, lease->leasetime);
        if (ia == NULL)
                return -1;
 
index 26161784502003b52a42b73f718bb298cda318bf..4e04e9b22bbdaaca3dec7d5908d6aac7426dbedc 100644 (file)
@@ -83,6 +83,8 @@ struct ipv4_addr {
        struct interface *iface;
        int addr_flags;
        unsigned int flags;
+       uint32_t vltime;
+       uint32_t pltime;
        char saddr[INET_ADDRSTRLEN + 3];
 #ifdef ALIAS_ADDR
        char alias[IF_NAMESIZE];
@@ -126,7 +128,8 @@ bool inet_getroutes(struct dhcpcd_ctx *, rb_tree_t *);
 
 int ipv4_deladdr(struct ipv4_addr *, int);
 struct ipv4_addr *ipv4_addaddr(struct interface *,
-    const struct in_addr *, const struct in_addr *, const struct in_addr *);
+    const struct in_addr *, const struct in_addr *, const struct in_addr *,
+    uint32_t, uint32_t);
 void ipv4_applyaddr(void *);
 
 struct ipv4_addr *ipv4_iffindaddr(struct interface *,
index e46b6d7b391f05a0f503ea8b9fd213e1d4071af6..8c68af5c7950f4e5365c872aec5359da474550e5 100644 (file)
@@ -40,6 +40,7 @@
 #include "config.h"
 #include "arp.h"
 #include "common.h"
+#include "dhcp.h"
 #include "eloop.h"
 #include "if.h"
 #include "if-options.h"
@@ -212,7 +213,8 @@ ipv4ll_not_found(struct interface *ifp)
                if (ifp->ctx->options & DHCPCD_TEST)
                        goto test;
                ia = ipv4_addaddr(ifp, &state->pickedaddr,
-                   &inaddr_llmask, &inaddr_llbcast);
+                   &inaddr_llmask, &inaddr_llbcast,
+                   DHCP_INFINITE_LIFETIME, DHCP_INFINITE_LIFETIME);
        }
        if (ia == NULL)
                return;