From: Roy Marples Date: Mon, 22 Jul 2019 09:37:13 +0000 (+0100) Subject: DHCP: Set address vltime and pltime to the length of the lease X-Git-Tag: v8.0.0~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0312f6cd3d35280eb67905f4a80428e285f5274f;p=thirdparty%2Fdhcpcd.git DHCP: Set address vltime and pltime to the length of the lease 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. --- diff --git a/src/dhcp.c b/src/dhcp.c index c66b78cc..9a83dc6a 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -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; diff --git a/src/dhcp.h b/src/dhcp.h index 18c627b9..4b6311a3 100644 --- a/src/dhcp.h +++ b/src/dhcp.h @@ -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, diff --git a/src/if-linux.c b/src/if-linux.c index 44767991..88060c9b 100644 --- a/src/if-linux.c +++ b/src/if-linux.c @@ -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); } diff --git a/src/ipv4.c b/src/ipv4.c index 9f908ede..06a5dabf 100644 --- a/src/ipv4.c +++ b/src/ipv4.c @@ -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; diff --git a/src/ipv4.h b/src/ipv4.h index 26161784..4e04e9b2 100644 --- a/src/ipv4.h +++ b/src/ipv4.h @@ -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 *, diff --git a/src/ipv4ll.c b/src/ipv4ll.c index e46b6d7b..8c68af5c 100644 --- a/src/ipv4ll.c +++ b/src/ipv4ll.c @@ -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;