From: Roy Marples Date: Fri, 29 Jan 2016 11:36:05 +0000 (+0000) Subject: Allow the suffix of PD addresses to be configurable. X-Git-Tag: v6.10.2~88 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fda2c66357ac64fa6d3b077084f46dd267beb52e;p=thirdparty%2Fdhcpcd.git Allow the suffix of PD addresses to be configurable. Fixes [0666660018]. --- diff --git a/dhcp6.c b/dhcp6.c index 66781516..88fe4f6f 100644 --- a/dhcp6.c +++ b/dhcp6.c @@ -2336,6 +2336,7 @@ dhcp6_ifdelegateaddr(struct interface *ifp, struct ipv6_addr *prefix, char sabuf[INET6_ADDRSTRLEN]; const char *sa; int pfxlen; + uint64_t vl; /* RFC6603 Section 4.2 */ if (strcmp(ifp->name, ifs->name) == 0) { @@ -2354,6 +2355,12 @@ dhcp6_ifdelegateaddr(struct interface *ifp, struct ipv6_addr *prefix, sla, ia)) == -1) return NULL; + if (ffs64(sla->suffix) > 128 - pfxlen) { + logger(ifp->ctx, LOG_ERR, + "%s: suffix %" PRIu64 " + prefix_len %d > 128", + ifp->name, sla->suffix, pfxlen); + return NULL; + } a = calloc(1, sizeof(*a)); if (a == NULL) { @@ -2371,11 +2378,11 @@ dhcp6_ifdelegateaddr(struct interface *ifp, struct ipv6_addr *prefix, a->prefix = addr; a->prefix_len = (uint8_t)pfxlen; - /* Wang a 1 at the end as the prefix could be >64 - * making SLAAC impossible. */ - a->addr = a->prefix; - a->addr.s6_addr[sizeof(a->addr.s6_addr) - 1] = - (uint8_t)(a->addr.s6_addr[sizeof(a->addr.s6_addr) - 1] + 1); + /* Add our suffix */ + a->addr = addr; + vl = be64dec(addr.s6_addr + 8); + vl |= sla->suffix; + be64enc(a->addr.s6_addr + 8, vl); state = D6_STATE(ifp); /* Remove any exiting address */ diff --git a/dhcpcd.conf.5.in b/dhcpcd.conf.5.in index a7f0acd5..35dd8069 100644 --- a/dhcpcd.conf.5.in +++ b/dhcpcd.conf.5.in @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd October 19, 2015 +.Dd January 29, 2016 .Dt DHCPCD.CONF 5 .Os .Sh NAME @@ -252,7 +252,7 @@ Request a DHCPv6 Temporary Address for You can request more than one ia_ta by specifying a unique .Ar iaid for each one. -.It Ic ia_pd Op Ar iaid Oo / Ar prefix / Ar prefix_len Oc Op Ar interface Op / Ar sla_id Op / Ar prefix_len +.It Ic ia_pd Op Ar iaid Oo / Ar prefix / Ar prefix_len Oc Op Ar interface Op / Ar sla_id Op / Ar prefix_len Op / Ar suffix Request a DHCPv6 Delegated Prefix for .Ar iaid . This option must be used in an @@ -273,7 +273,9 @@ Otherwise addresses are only assigned for each .Ar interface and .Ar sla_id . -Each assigned address will have a suffix of 1. +Each assigned address will have a +.Ar suffix , +defaulting to 1. You cannot assign a prefix to the requesting interface unless the DHCPv6 server supports .Li RFC6603 diff --git a/if-options.c b/if-options.c index 9e4ce06d..0ca9f937 100644 --- a/if-options.c +++ b/if-options.c @@ -1408,18 +1408,19 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, if (strlcpy(sla->ifname, p, sizeof(sla->ifname)) >= sizeof(sla->ifname)) { - logger(ctx, LOG_ERR, "%s: interface name too long", - arg); + logger(ctx, LOG_ERR, + "%s: interface name too long", arg); goto err_sla; } + sla->sla_set = 0; + sla->prefix_len = 0; + sla->suffix = 1; p = np; if (p) { np = strchr(p, '/'); if (np) *np++ = '\0'; - if (*p == '\0') - sla->sla_set = 0; - else { + if (*p != '\0') { sla->sla = (uint32_t)strtou(p, NULL, 0, 0, UINT32_MAX, &e); sla->sla_set = 1; @@ -1430,20 +1431,40 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, goto err_sla; } } - if (np) { + p = np; + } + if (p) { + np = strchr(p, '/'); + if (np) + *np++ = '\0'; + if (*p != '\0') { sla->prefix_len = (uint8_t)strtou(np, - NULL, 0, 0, 120, &e); + NULL, 0, 0, 120, &e); if (e) { - logger(ctx, LOG_ERR, "%s: failed to " + logger(ctx, LOG_ERR, + "%s: failed to " "convert prefix len", ifname); goto err_sla; } - } else - sla->prefix_len = 0; - } else { - sla->sla_set = 0; - sla->prefix_len = 0; + } + p = np; + } + if (p) { + np = strchr(p, '/'); + if (np) + *np = '\0'; + if (*p != '\0') { + sla->suffix = (uint64_t)strtou(p, NULL, + 0, 0, UINT64_MAX, &e); + if (e) { + logger(ctx, LOG_ERR, + "%s: failed to " + "convert suffix", + ifname); + goto err_sla; + } + } } /* Sanity check */ for (sl = 0; sl < ia->sla_len - 1; sl++) { diff --git a/if-options.h b/if-options.h index 66b87d8d..6c7ab153 100644 --- a/if-options.h +++ b/if-options.h @@ -129,6 +129,7 @@ struct if_sla { char ifname[IF_NAMESIZE]; uint32_t sla; uint8_t prefix_len; + uint64_t suffix; int8_t sla_set; };