From 4c390ad39c4da7f10a291844ba49ce8036ba24c4 Mon Sep 17 00:00:00 2001 From: sg Date: Wed, 24 Aug 2016 20:51:05 +0200 Subject: [PATCH] update netif address change triggers to tpc & udp to work with IPv6, too --- src/core/netif.c | 87 ++++++++++++++++++++++++++++---- src/core/tcp.c | 38 +++++++------- src/core/udp.c | 24 ++++----- src/include/lwip/priv/tcp_priv.h | 4 +- src/include/lwip/udp.h | 4 +- 5 files changed, 105 insertions(+), 52 deletions(-) diff --git a/src/core/netif.c b/src/core/netif.c index c2a64d6f..b386354a 100644 --- a/src/core/netif.c +++ b/src/core/netif.c @@ -358,6 +358,10 @@ netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t * void netif_remove(struct netif *netif) { +#if LWIP_IPV6 + int i; +#endif + if (netif == NULL) { return; } @@ -365,9 +369,11 @@ netif_remove(struct netif *netif) #if LWIP_IPV4 if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) { #if LWIP_TCP - tcp_netif_ipv4_addr_changed(netif_ip4_addr(netif), NULL); + tcp_netif_ip_addr_changed(netif_ip_addr4(netif), NULL); #endif /* LWIP_TCP */ - /* cannot do this for UDP, as there is no 'err' callback in udp pcbs */ +#if LWIP_UDP + udp_netif_ip_addr_changed(netif_ip_addr4(netif), NULL); +#endif /* LWIP_UDP */ } #if LWIP_IGMP @@ -378,10 +384,22 @@ netif_remove(struct netif *netif) #endif /* LWIP_IGMP */ #endif /* LWIP_IPV4*/ -#if LWIP_IPV6 && LWIP_IPV6_MLD +#if LWIP_IPV6 + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) { +#if LWIP_TCP + tcp_netif_ip_addr_changed(netif_ip_addr6(netif, i), NULL); +#endif /* LWIP_TCP */ +#if LWIP_UDP + udp_netif_ip_addr_changed(netif_ip_addr6(netif, i), NULL); +#endif /* LWIP_UDP */ + } + } +#if LWIP_IPV6_MLD /* stop MLD processing */ mld6_stop(netif); -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ +#endif /* LWIP_IPV6_MLD */ +#endif /* LWIP_IPV6 */ if (netif_is_up(netif)) { /* set netif down before removing (call callback function) */ netif_set_down(netif); @@ -464,15 +482,18 @@ netif_find(const char *name) void netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr) { - ip4_addr_t new_addr = (ipaddr ? *ipaddr : *IP4_ADDR_ANY); + ip_addr_t new_addr; + *ip_2_ip4(&new_addr) = (ipaddr ? *ipaddr : *IP4_ADDR_ANY); + IP_SET_TYPE_VAL(new_addr, IPADDR_TYPE_V4); + /* address is actually being changed? */ - if (ip4_addr_cmp(&new_addr, netif_ip4_addr(netif)) == 0) { + if (ip4_addr_cmp(ip_2_ip4(&new_addr), netif_ip4_addr(netif)) == 0) { LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); #if LWIP_TCP - tcp_netif_ipv4_addr_changed(netif_ip4_addr(netif), ipaddr); + tcp_netif_ip_addr_changed(netif_ip_addr4(netif), &new_addr); #endif /* LWIP_TCP */ #if LWIP_UDP - udp_netif_ipv4_addr_changed(netif_ip4_addr(netif), ipaddr); + udp_netif_ip_addr_changed(netif_ip_addr4(netif), &new_addr); #endif /* LWIP_UDP */ mib2_remove_ip4(netif); @@ -957,6 +978,16 @@ netif_alloc_client_data_id(void) #endif #if LWIP_IPV6 +/** + * @ingroup netif + * Change an IPv6 address of a network interface + * + * @param netif the network interface to change + * @param addr_idx index of the IPv6 address + * @param addr6 the new IPv6 address + * + * @note call netif_ip6_addr_set_state() to set the address valid/temptative + */ void netif_ip6_addr_set(struct netif *netif, s8_t addr_idx, const ip6_addr_t *addr6) { @@ -965,6 +996,16 @@ netif_ip6_addr_set(struct netif *netif, s8_t addr_idx, const ip6_addr_t *addr6) addr6->addr[2], addr6->addr[3]); } +/* + * Change an IPv6 address of a network interface (internal version taking 4 * u32_t) + * + * @param netif the network interface to change + * @param addr_idx index of the IPv6 address + * @param i0 word0 of the new IPv6 address + * @param i1 word1 of the new IPv6 address + * @param i2 word2 of the new IPv6 address + * @param i3 word3 of the new IPv6 address + */ 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) { @@ -978,7 +1019,18 @@ netif_ip6_addr_set_parts(struct netif *netif, s8_t addr_idx, u32_t i0, u32_t 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() */ + if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) { +#if LWIP_TCP || LWIP_UDP + ip_addr_t new_ipaddr; + IP_ADDR6(&new_ipaddr, i0, i1, i2, i3); +#endif /* LWIP_TCP || LWIP_UDP */ +#if LWIP_TCP + tcp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), &new_ipaddr); +#endif /* LWIP_TCP */ +#if LWIP_UDP + udp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), &new_ipaddr); +#endif /* LWIP_UDP */ + } /* @todo: remove/readd mib2 ip6 entries? */ IP6_ADDR(ip_2_ip6(&(netif->ip6_addr[addr_idx])), i0, i1, i2, i3); @@ -995,6 +1047,16 @@ netif_ip6_addr_set_parts(struct netif *netif, s8_t addr_idx, u32_t i0, u32_t i1, netif_ip6_addr_state(netif, addr_idx))); } +/** + * @ingroup netif + * Change the state of an IPv6 address of a network interface + * (INVALID, TEMPTATIVE, PREFERRED, DEPRECATED, where TEMPTATIVE + * includes the number of checks done, see ip6_addr.h) + * + * @param netif the network interface to change + * @param addr_idx index of the IPv6 address + * @param state the new IPv6 address state + */ void netif_ip6_addr_set_state(struct netif* netif, s8_t addr_idx, u8_t state) { @@ -1011,7 +1073,12 @@ netif_ip6_addr_set_state(struct netif* netif, s8_t addr_idx, u8_t state) if (old_valid && !new_valid) { /* address about to be removed by setting invalid */ - /* @todo: tcp_netif_ipv6_addr_changed()/udp_netif_ipv6_addr_changed() */ +#if LWIP_TCP + tcp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), NULL); +#endif /* LWIP_TCP */ +#if LWIP_UDP + udp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), NULL); +#endif /* LWIP_UDP */ /* @todo: remove mib2 ip6 entries? */ } netif->ip6_addr_state[addr_idx] = state; diff --git a/src/core/tcp.c b/src/core/tcp.c index 115b9145..8049c263 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -1896,19 +1896,18 @@ tcp_eff_send_mss_impl(u16_t sendmss, const ip_addr_t *dest } #endif /* TCP_CALCULATE_EFF_SEND_MSS */ -#if LWIP_IPV4 -/** Helper function for tcp_netif_ipv4_addr_changed() that iterates a pcb list */ +/** Helper function for tcp_netif_ip_addr_changed() that iterates a pcb list */ static void -tcp_netif_ipv4_addr_changed_pcblist(const ip4_addr_t* old_addr, struct tcp_pcb* pcb_list) +tcp_netif_ip_addr_changed_pcblist(const ip_addr_t* old_addr, struct tcp_pcb* pcb_list) { struct tcp_pcb *pcb; pcb = pcb_list; while (pcb != NULL) { /* PCB bound to current local interface address? */ - if (IP_IS_V4_VAL(pcb->local_ip) && ip4_addr_cmp(ip_2_ip4(&pcb->local_ip), old_addr) + if (ip_addr_cmp(&pcb->local_ip, old_addr) #if LWIP_AUTOIP /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */ - && !ip4_addr_islinklocal(ip_2_ip4(&pcb->local_ip)) + && (!IP_IS_V4_VAL(pcb->local_ip) || !ip4_addr_islinklocal(ip_2_ip4(&pcb->local_ip))) #endif /* LWIP_AUTOIP */ ) { /* this connection must be aborted */ @@ -1924,35 +1923,32 @@ tcp_netif_ipv4_addr_changed_pcblist(const ip4_addr_t* old_addr, struct tcp_pcb* /** This function is called from netif.c when address is changed or netif is removed * - * @param old_addr IPv4 address of the netif before change - * @param new_addr IPv4 address of the netif after change or NULL if netif has been removed + * @param old_addr IP address of the netif before change + * @param new_addr IP address of the netif after change or NULL if netif has been removed */ void -tcp_netif_ipv4_addr_changed(const ip4_addr_t* old_addr, const ip4_addr_t* new_addr) +tcp_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr) { struct tcp_pcb_listen *lpcb, *next; - tcp_netif_ipv4_addr_changed_pcblist(old_addr, tcp_active_pcbs); - tcp_netif_ipv4_addr_changed_pcblist(old_addr, tcp_bound_pcbs); + if (!ip_addr_isany(old_addr)) { + tcp_netif_ip_addr_changed_pcblist(old_addr, tcp_active_pcbs); + tcp_netif_ip_addr_changed_pcblist(old_addr, tcp_bound_pcbs); - if (!ip4_addr_isany(new_addr)) { - /* PCB bound to current local interface address? */ - for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = next) { - next = lpcb->next; - /* Is this an IPv4 pcb? */ - if (IP_IS_V4_VAL(lpcb->local_ip)) { + if (!ip_addr_isany(new_addr)) { + /* PCB bound to current local interface address? */ + for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = next) { + next = lpcb->next; /* PCB bound to current local interface address? */ - if ((!(ip4_addr_isany(ip_2_ip4(&lpcb->local_ip)))) && - (ip4_addr_cmp(ip_2_ip4(&lpcb->local_ip), old_addr))) { + if (ip_addr_cmp(&lpcb->local_ip, old_addr)) { /* The PCB is listening to the old ipaddr and - * is set to listen to the new one instead */ - ip_addr_copy_from_ip4(lpcb->local_ip, *new_addr); + * is set to listen to the new one instead */ + ip_addr_copy(lpcb->local_ip, *new_addr); } } } } } -#endif /* LWIP_IPV4 */ const char* tcp_debug_state_str(enum tcp_state s) diff --git a/src/core/udp.c b/src/core/udp.c index bb957faf..04a64537 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -1166,32 +1166,26 @@ udp_new_ip_type(u8_t type) return pcb; } -#if LWIP_IPV4 /** This function is called from netif.c when address is changed * - * @param old_addr IPv4 address of the netif before change - * @param new_addr IPv4 address of the netif after change + * @param old_addr IP address of the netif before change + * @param new_addr IP address of the netif after change */ -void udp_netif_ipv4_addr_changed(const ip4_addr_t* old_addr, const ip4_addr_t* new_addr) +void udp_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr) { struct udp_pcb* upcb; - if (!ip4_addr_isany(new_addr)) { + if (!ip_addr_isany(old_addr) && !ip_addr_isany(new_addr)) { for (upcb = udp_pcbs; upcb != NULL; upcb = upcb->next) { - /* Is this an IPv4 pcb? */ - if (IP_IS_V4_VAL(upcb->local_ip)) { - /* PCB bound to current local interface address? */ - if (!ip4_addr_isany(ip_2_ip4(&upcb->local_ip)) && - ip4_addr_cmp(ip_2_ip4(&upcb->local_ip), old_addr)) { - /* The PCB is bound to the old ipaddr and - * is set to bound to the new one instead */ - ip_addr_copy_from_ip4(upcb->local_ip, *new_addr); - } + /* PCB bound to current local interface address? */ + if (ip_addr_cmp(&upcb->local_ip, old_addr)) { + /* The PCB is bound to the old ipaddr and + * is set to bound to the new one instead */ + ip_addr_copy(upcb->local_ip, *new_addr); } } } } -#endif /* LWIP_IPV4 */ #if UDP_DEBUG /** diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h index c0c9110d..736dc325 100644 --- a/src/include/lwip/priv/tcp_priv.h +++ b/src/include/lwip/priv/tcp_priv.h @@ -493,9 +493,7 @@ s16_t tcp_pcbs_sane(void); * that a timer is needed (i.e. active- or time-wait-pcb found). */ void tcp_timer_needed(void); -#if LWIP_IPV4 -void tcp_netif_ipv4_addr_changed(const ip4_addr_t* old_addr, const ip4_addr_t* new_addr); -#endif /* LWIP_IPV4 */ +void tcp_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr); #ifdef __cplusplus } diff --git a/src/include/lwip/udp.h b/src/include/lwip/udp.h index 3e499b06..b9299073 100644 --- a/src/include/lwip/udp.h +++ b/src/include/lwip/udp.h @@ -171,9 +171,7 @@ void udp_debug_print(struct udp_hdr *udphdr); #define udp_debug_print(udphdr) #endif -#if LWIP_IPV4 -void udp_netif_ipv4_addr_changed(const ip4_addr_t* old_addr, const ip4_addr_t* new_addr); -#endif /* LWIP_IPV4 */ +void udp_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr); #ifdef __cplusplus }