X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=blobdiff_plain;f=interface-ip.c;h=6ccc03ee762029c36db15af0e7a0ad090f080561;hp=1490ca4a7aa3302a22284f3b58413772c1a524cf;hb=1f5a29c3de6e3fec5883796ee772e25d56db6a69;hpb=c92106e3048ae10cb04a7c7303ba5f53bc057953 diff --git a/interface-ip.c b/interface-ip.c index 1490ca4..6ccc03e 100644 --- a/interface-ip.c +++ b/interface-ip.c @@ -262,6 +262,7 @@ interface_ip_add_target_route(union if_addr *addr, bool v6, struct interface *if } } +done: if (!r_next) { free(route); return NULL; @@ -272,8 +273,6 @@ interface_ip_add_target_route(union if_addr *addr, bool v6, struct interface *if route->mtu = r_next->mtu; route->metric = r_next->metric; route->table = r_next->table; - -done: route->iface = iface; if (defaultroute_target) free(route); @@ -712,9 +711,16 @@ random_ifaceid(struct in6_addr *addr) addr->s6_addr32[3] = (uint32_t)mrand48(); } -static void +static bool eui64_ifaceid(struct interface *iface, struct in6_addr *addr) { + struct device_settings st; + + device_merge_settings(iface->l3_dev.dev, &st); + + if (!(st.flags & DEV_OPT_MACADDR)) + return false; + /* get mac address */ uint8_t *macaddr = iface->l3_dev.dev->settings.macaddr; uint8_t *ifaceid = addr->s6_addr + 8; @@ -723,11 +729,15 @@ eui64_ifaceid(struct interface *iface, struct in6_addr *addr) ifaceid[3] = 0xff; ifaceid[4] = 0xfe; ifaceid[0] ^= 0x02; + + return true; } -static void +static bool generate_ifaceid(struct interface *iface, struct in6_addr *addr) { + bool ret = true; + /* generate new iface id */ switch (iface->assignment_iface_id_selection) { case IFID_FIXED: @@ -741,9 +751,13 @@ generate_ifaceid(struct interface *iface, struct in6_addr *addr) break; case IFID_EUI64: /* eui64 */ - eui64_ifaceid(iface, addr); + ret = eui64_ifaceid(iface, addr); + break; + default: + ret = false; break; } + return ret; } static void @@ -761,15 +775,7 @@ interface_set_prefix_address(struct device_prefix_assignment *assignment, memset(&addr, 0, sizeof(addr)); memset(&route, 0, sizeof(route)); - if (IN6_IS_ADDR_UNSPECIFIED(&assignment->addr)) { - addr.addr.in6 = prefix->addr; - addr.addr.in6.s6_addr32[1] |= htonl(assignment->assigned); - generate_ifaceid(iface, &addr.addr.in6); - assignment->addr = addr.addr.in6; - } - else - addr.addr.in6 = assignment->addr; - + addr.addr.in6 = assignment->addr; addr.mask = assignment->length; addr.flags = DEVADDR_INET6 | DEVADDR_OFFLINK; addr.preferred_until = prefix->preferred_until; @@ -778,11 +784,10 @@ interface_set_prefix_address(struct device_prefix_assignment *assignment, route.flags = DEVADDR_INET6; route.mask = addr.mask < 64 ? 64 : addr.mask; route.addr = addr.addr; - clear_if_addr(&route.addr, route.mask); - interface_set_route_info(iface, &route); if (!add && assignment->enabled) { time_t now = system_get_rtime(); + addr.preferred_until = now; if (!addr.valid_until || addr.valid_until - now > 7200) addr.valid_until = now + 7200; @@ -800,12 +805,27 @@ interface_set_prefix_address(struct device_prefix_assignment *assignment, addr.mask, 0, iface, "unreachable", true); } + clear_if_addr(&route.addr, route.mask); + interface_set_route_info(iface, &route); + system_del_route(l3_downlink, &route); system_add_address(l3_downlink, &addr); + assignment->addr = in6addr_any; assignment->enabled = false; - } else if (add && (iface->state == IFS_UP || iface->state == IFS_SETUP) && - !system_add_address(l3_downlink, &addr)) { + } else if (add && (iface->state == IFS_UP || iface->state == IFS_SETUP)) { + if (IN6_IS_ADDR_UNSPECIFIED(&addr.addr.in6)) { + addr.addr.in6 = prefix->addr; + addr.addr.in6.s6_addr32[1] |= htonl(assignment->assigned); + if (!generate_ifaceid(iface, &addr.addr.in6)) + return; + + assignment->addr = addr.addr.in6; + route.addr = addr.addr; + } + + if (system_add_address(l3_downlink, &addr)) + return; if (!assignment->enabled) { if (iface->ip6table) @@ -822,7 +842,9 @@ interface_set_prefix_address(struct device_prefix_assignment *assignment, } } - route.metric = iface->metric; + clear_if_addr(&route.addr, route.mask); + interface_set_route_info(iface, &route); + system_add_route(l3_downlink, &route); if (uplink && uplink->l3_dev.dev && !(l3_downlink->settings.flags & DEV_OPT_MTU6)) {