update netif address change triggers to tpc & udp to work with IPv6, too

This commit is contained in:
sg 2016-08-24 20:51:05 +02:00
parent a1db05c11e
commit 4c390ad39c
5 changed files with 105 additions and 52 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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
/**

View File

@ -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
}

View File

@ -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
}