diff --git a/src/core/ipv6/nd6.c b/src/core/ipv6/nd6.c index 6c47dbca..8b24180b 100644 --- a/src/core/ipv6/nd6.c +++ b/src/core/ipv6/nd6.c @@ -751,8 +751,7 @@ nd6_tmr(void) #if LWIP_IPV6_AUTOCONFIG /* If any addresses were configured with this prefix, remove them */ - if (prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED) - { + if (prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED) { s8_t j; for (j = 1; j < LWIP_IPV6_NUM_ADDRESSES; j++) { @@ -784,7 +783,7 @@ nd6_tmr(void) for (j = 1; j < LWIP_IPV6_NUM_ADDRESSES; j++) { if (netif_ip6_addr_state(prefix_list[i].netif, j) == IP6_ADDR_INVALID) { /* Generate an address using this prefix and interface ID from link-local address. */ - IP_ADDR6(&prefix_list[i].netif->ip6_addr[j], + netif_ip6_addr_set_parts(prefix_list[i].netif, j, prefix_list[i].prefix.addr[0], prefix_list[i].prefix.addr[1], netif_ip6_addr(prefix_list[i].netif, 0)->addr[2], netif_ip6_addr(prefix_list[i].netif, 0)->addr[3]); @@ -808,14 +807,15 @@ nd6_tmr(void) /* Process our own addresses, if DAD configured. */ for (netif = netif_list; netif != NULL; netif = netif->next) { for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { - if (ip6_addr_istentative(netif->ip6_addr_state[i])) { - if ((netif->ip6_addr_state[i] & IP6_ADDR_TENTATIVE_COUNT_MASK) >= LWIP_IPV6_DUP_DETECT_ATTEMPTS) { + u8_t addr_state = netif_ip6_addr_state(netif, i); + if (ip6_addr_istentative(addr_state)) { + if ((addr_state & IP6_ADDR_TENTATIVE_COUNT_MASK) >= LWIP_IPV6_DUP_DETECT_ATTEMPTS) { /* No NA received in response. Mark address as valid. */ - netif->ip6_addr_state[i] = IP6_ADDR_PREFERRED; + netif_ip6_addr_set_state(netif, i, IP6_ADDR_PREFERRED); /* @todo implement preferred and valid lifetimes. */ } else if (netif->flags & NETIF_FLAG_UP) { #if LWIP_IPV6_MLD - if ((netif->ip6_addr_state[i] & IP6_ADDR_TENTATIVE_COUNT_MASK) == 0) { + if ((addr_state & IP6_ADDR_TENTATIVE_COUNT_MASK) == 0) { /* Join solicited node multicast group. */ ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(netif, i)->addr[3]); mld6_joingroup(netif_ip6_addr(netif, i), &multicast_address); @@ -823,7 +823,8 @@ nd6_tmr(void) #endif /* LWIP_IPV6_MLD */ /* Send a NS for this address. */ nd6_send_ns(netif, netif_ip6_addr(netif, i), ND6_SEND_FLAG_MULTICAST_DEST); - netif->ip6_addr_state[i]++; + /* tentative: set next state by increasing by one */ + netif_ip6_addr_set_state(netif, i, addr_state + 1); /* @todo send max 1 NS per tmr call? enable return*/ /*return;*/ } @@ -943,7 +944,7 @@ nd6_send_na(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags) u16_t lladdr_opt_len; /* Use link-local address as source address. */ - /* src_addr = &(netif->ip6_addr[0]); */ + /* src_addr = netif_ip6_addr(netif, 0); */ /* Use target address as source address. */ src_addr = target_addr; diff --git a/src/core/netif.c b/src/core/netif.c index 5c194588..718b5587 100644 --- a/src/core/netif.c +++ b/src/core/netif.c @@ -227,7 +227,7 @@ netif_add(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input) { #if LWIP_IPV6 - u32_t i; + s8_t i; #endif LWIP_ASSERT("No init function given", init != NULL); @@ -241,7 +241,7 @@ netif_add(struct netif *netif, #if LWIP_IPV6 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { ip_addr_set_zero_ip6(&netif->ip6_addr[i]); - netif_ip6_addr_set_state(netif, i, IP6_ADDR_INVALID); + netif->ip6_addr_state[0] = IP6_ADDR_INVALID; } netif->output_ip6 = netif_null_output_ip6; #endif /* LWIP_IPV6 */ @@ -951,12 +951,88 @@ netif_alloc_client_data_id(void) u8_t result = netif_client_id; netif_client_id++; - LWIP_ASSERT("Increase LWIP_NUM_NETIF_CLIENT_DATA in lwipopts.h", resultaddr[0], addr6->addr[1], + addr6->addr[2], addr6->addr[3]); +} + +void +netif_ip6_addr_set_parts(struct netif *netif, s8_t addr_idx, u32_t i0, u32_t i1, u32_t i2, u32_t i3) +{ + const ip6_addr_t *old_addr; + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("invalid index", addr_idx < LWIP_IPV6_NUM_ADDRESSES); + + old_addr = netif_ip6_addr(netif, addr_idx); + /* address is actually being changed? */ + if ((old_addr->addr[0] != i0) || (old_addr->addr[1] != i1) || + (old_addr->addr[2] != i2) || (old_addr->addr[3] != i3)) { + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_ip6_addr_set: netif address being changed\n")); + + /* @todo: tcp_netif_ipv6_addr_changed()/udp_netif_ipv6_addr_changed() */ + /* @todo: remove/readd mib2 ip6 entries? */ + + IP6_ADDR(ip_2_ip6(&(netif->ip6_addr[addr_idx])), i0, i1, i2, i3); + IP_SET_TYPE_VAL(netif->ip6_addr[addr_idx], IPADDR_TYPE_V6); + + if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) { + netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV6); + NETIF_STATUS_CALLBACK(netif); + } + } + + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IPv6 address %d of interface %c%c set to %s/0x%"X8_F"\n", + addr_idx, netif->name[0], netif->name[1], ip6addr_ntoa(netif_ip6_addr(netif, addr_idx)), + netif_ip6_addr_state(netif, addr_idx))); +} + +void +netif_ip6_addr_set_state(struct netif* netif, s8_t addr_idx, u8_t state) +{ + u8_t old_state; + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("invalid index", addr_idx < LWIP_IPV6_NUM_ADDRESSES); + + old_state = netif_ip6_addr_state(netif, addr_idx); + /* state is actually being changed? */ + if (old_state != state) { + u8_t old_valid = old_state & IP6_ADDR_VALID; + u8_t new_valid = state & IP6_ADDR_VALID; + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_ip6_addr_set_state: netif address state being changed\n")); + + if (old_valid && !new_valid) { + /* address about to be removed by setting invalid */ + /* @todo: tcp_netif_ipv6_addr_changed()/udp_netif_ipv6_addr_changed() */ + /* @todo: remove mib2 ip6 entries? */ + } + netif->ip6_addr_state[addr_idx] = state; + + if (!old_valid && new_valid) { + /* address added by setting valid */ + /* @todo: add mib2 ip6 entries? */ + netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV6); + } + if ((old_state & IP6_ADDR_PREFERRED) != (state & IP6_ADDR_PREFERRED)) { + /* address state has changed (valid flag changed or switched between + preferred and deprecated) -> call the callback function */ + NETIF_STATUS_CALLBACK(netif); + } + } + + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IPv6 address %d of interface %c%c set to %s/0x%"X8_F"\n", + addr_idx, netif->name[0], netif->name[1], ip6addr_ntoa(netif_ip6_addr(netif, addr_idx)), + netif_ip6_addr_state(netif, addr_idx))); +} + /** * Checks if a specific address is assigned to the netif and returns its * index. diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h index 1f11551b..782f7b27 100644 --- a/src/include/lwip/netif.h +++ b/src/include/lwip/netif.h @@ -433,9 +433,10 @@ u8_t netif_alloc_client_data_id(void); #define netif_ip_addr6(netif, i) ((const ip_addr_t*)(&((netif)->ip6_addr[i]))) /** @ingroup netif */ #define netif_ip6_addr(netif, i) ((const ip6_addr_t*)ip_2_ip6(&((netif)->ip6_addr[i]))) -#define netif_ip6_addr_set(netif, i, addr6) do { ip6_addr_set(ip_2_ip6(&((netif)->ip6_addr[i])), addr6); IP_SET_TYPE_VAL((netif)->ip6_addr[i], IPADDR_TYPE_V6); } while(0) +void netif_ip6_addr_set(struct netif *netif, s8_t addr_idx, ip6_addr_t *addr6); +void netif_ip6_addr_set_parts(struct netif *netif, s8_t addr_idx, u32_t i0, u32_t i1, u32_t i2, u32_t i3); #define netif_ip6_addr_state(netif, i) ((netif)->ip6_addr_state[i]) -#define netif_ip6_addr_set_state(netif, i, state) ((netif)->ip6_addr_state[i] = (state)) +void netif_ip6_addr_set_state(struct netif* netif, s8_t addr_idx, u8_t state); s8_t netif_get_ip6_addr_match(struct netif *netif, const ip6_addr_t *ip6addr); void netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit); err_t netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chosen_idx);