X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=blobdiff_plain;f=interface-ip.c;h=56f8bd9468f38694e998759d930f57859526f87c;hp=99f654048e2a5cf67c4aa81faadbd751942133ca;hb=a637dba6e4393f0ec8f8bf294fbeb89b8e4ebc66;hpb=94c8619d72e65b36aa2a6f5b8157bc479f252473 diff --git a/interface-ip.c b/interface-ip.c index 99f6540..56f8bd9 100644 --- a/interface-ip.c +++ b/interface-ip.c @@ -456,8 +456,13 @@ interface_set_prefix_address(struct interface *iface, bool add, addr.valid_until = assignment->prefix->valid_until; if (!add) { - if (assignment->enabled) - system_del_address(l3_downlink, &addr); + if (assignment->enabled) { + time_t now = system_get_rtime(); + addr.preferred_until = now; + if (addr.valid_until - now > 7200) + addr.valid_until = now + 7200; + system_add_address(l3_downlink, &addr); + } } else { system_add_address(l3_downlink, &addr); @@ -525,11 +530,10 @@ interface_ip_set_prefix_assignment(struct device_prefix *prefix, struct device_prefix_assignment *assignment; if (!length || length > 64) { - assignment = vlist_find(prefix->assignments, &iface, assignment, node); + assignment = vlist_find(prefix->assignments, iface->name, assignment, node); if (assignment) interface_set_prefix_address(iface, false, assignment); } else { - uint8_t length = iface->proto_ip.assignment_length; uint64_t want = 1ULL << (64 - length); char *name; @@ -576,9 +580,11 @@ interface_update_prefix(struct vlist_tree *tree, // Update all assignments struct device_prefix_assignment *assignment; struct vlist_tree *assignments = prefix_new->assignments; - vlist_for_each_element(assignments, assignment, node) + vlist_for_each_element(assignments, assignment, node) { + assignment->prefix = prefix_new; assignments->update(assignments, &assignment->node, &assignment->node); + } } else if (node_new) { prefix_new->avail = 1ULL << (64 - prefix_new->length); prefix_new->assignments = calloc(1, sizeof(*prefix_new->assignments)); @@ -591,8 +597,6 @@ interface_update_prefix(struct vlist_tree *tree, interface_ip_set_prefix_assignment(prefix_new, iface, iface->proto_ip.assignment_length); - list_add(&prefix_new->head, &prefixes); - // Set null-route to avoid routing loops system_add_route(NULL, &route); } @@ -609,6 +613,9 @@ interface_update_prefix(struct vlist_tree *tree, } free(prefix_old); } + + if (node_new) + list_add(&prefix_new->head, &prefixes); } void @@ -632,12 +639,18 @@ void interface_ip_set_ula_prefix(const char *prefix) { char buf[INET6_ADDRSTRLEN + 4] = {0}, *saveptr; - strncpy(buf, prefix, sizeof(buf) - 1); + if (prefix) + strncpy(buf, prefix, sizeof(buf) - 1); char *prefixaddr = strtok_r(buf, "/", &saveptr); struct in6_addr addr; - if (!prefixaddr || inet_pton(AF_INET6, prefixaddr, &addr) < 1) + if (!prefixaddr || inet_pton(AF_INET6, prefixaddr, &addr) < 1) { + if (ula_prefix) { + interface_update_prefix(NULL, NULL, &ula_prefix->node); + ula_prefix = NULL; + } return; + } int length; char *prefixlen = strtok_r(NULL, ",", &saveptr);