X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fodhcpd.git;a=blobdiff_plain;f=src%2Fdhcpv6-ia.c;h=0bcb4530d10d41dcd112d1f502f2ff3c693bf4a8;hp=f850b020f5e1648c030b65fc135eb2be1399cc44;hb=f35dce59337a8b0a0acdf362e3f8f092647c9374;hpb=bc14cf3779925eadefbced51b70bc6f90b90a79e diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c index f850b02..0bcb453 100644 --- a/src/dhcpv6-ia.c +++ b/src/dhcpv6-ia.c @@ -60,7 +60,6 @@ void free_dhcpv6_assignment(struct dhcpv6_assignment *c) free(c->managed); free(c->hostname); - free(c->classes); free(c); } @@ -75,7 +74,7 @@ int setup_dhcpv6_ia_interface(struct interface *iface, bool enable) } } - if (iface->dhcpv6 == RELAYD_SERVER) { + if (enable && iface->dhcpv6 == RELAYD_SERVER) { if (!iface->ia_assignments.next) INIT_LIST_HEAD(&iface->ia_assignments); @@ -133,7 +132,6 @@ int setup_dhcpv6_ia_interface(struct interface *iface, bool enable) a->hostname = strdup(lease->hostname); } } else { - free(a->classes); free(a->hostname); free(a); } @@ -219,7 +217,7 @@ void dhcpv6_write_statefile(void) return; lockf(fd, F_LOCK, 0); - ftruncate(fd, 0); + if (ftruncate(fd, 0) < 0) {} FILE *fp = fdopen(fd, "w"); if (!fp) { @@ -264,7 +262,8 @@ void dhcpv6_write_statefile(void) for (size_t i = 0; i < addrlen; ++i) { if (addrs[i].prefix > 96 || c->valid_until <= now || - (iface->managed < RELAYD_MANAGED_NO_AFLAG && i != m)) + (iface->managed < RELAYD_MANAGED_NO_AFLAG && i != m && + addrs[i].prefix == 64)) continue; addr = addrs[i].addr; @@ -582,7 +581,8 @@ static void update(struct interface *iface) int minprefix = -1; for (int i = 0; i < len; ++i) { - if (addr[i].preferred > 0 && addr[i].prefix > minprefix) + if (addr[i].preferred > 0 && addr[i].prefix < 64 && + addr[i].prefix > minprefix) minprefix = addr[i].prefix; addr[i].addr.s6_addr32[3] = 0; @@ -595,7 +595,10 @@ static void update(struct interface *iface) } struct dhcpv6_assignment *border = list_last_entry(&iface->ia_assignments, struct dhcpv6_assignment, head); - border->assigned = 1 << (64 - minprefix); + if (minprefix > 32 && minprefix <= 64) + border->assigned = 1U << (64 - minprefix); + else + border->assigned = 0; bool change = len != (int)iface->ia_addr_len; for (int i = 0; !change && i < len; ++i) @@ -727,13 +730,19 @@ static size_t append_reply(uint8_t *buf, size_t buflen, uint16_t status, m = i; for (size_t i = 0; i < addrlen; ++i) { - uint32_t prefix_pref = addrs[i].preferred - now; - uint32_t prefix_valid = addrs[i].valid - now; + uint32_t prefix_pref = addrs[i].preferred; + uint32_t prefix_valid = addrs[i].valid; if (addrs[i].prefix > 96 || addrs[i].preferred <= (uint32_t)now) continue; + if (prefix_pref != UINT32_MAX) + prefix_pref -= now; + + if (prefix_valid != UINT32_MAX) + prefix_valid -= now; + if (a->length < 128) { struct dhcpv6_ia_prefix p = { .type = htons(DHCPV6_OPT_IA_PREFIX), @@ -748,7 +757,8 @@ static size_t append_reply(uint8_t *buf, size_t buflen, uint16_t status, size_t entrlen = sizeof(p) - 4; if (datalen + entrlen + 4 > buflen || - (a->assigned == 0 && a->managed_size == 0)) + (a->assigned == 0 && a->managed_size == 0) || + (!a->managed_size && a->length <= addrs[i].prefix)) continue; memcpy(buf + datalen, &p, sizeof(p)); @@ -764,7 +774,8 @@ static size_t append_reply(uint8_t *buf, size_t buflen, uint16_t status, n.addr.s6_addr32[3] = htonl(a->assigned); size_t entrlen = sizeof(n) - 4; - if (iface->managed < RELAYD_MANAGED_NO_AFLAG && i != m) + if (iface->managed < RELAYD_MANAGED_NO_AFLAG && i != m && + addrs[i].prefix == 64) continue; if (datalen + entrlen + 4 > buflen || a->assigned == 0)