mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-05 22:29:49 +00:00
ipv6: adjust MLD membership on address state changes
If MLD support is enabled, each locally assigned IPv6 address in the appropriate state must be a member of the solicited-node multicast group corresponding to that address. Ensure that this is always the case by (re-)deciding on the membership upon every address state change. By doing so, this patch enforces that user-initiated state changes to addresses (e.g., deletion) never cause a desynchronization with the corresponding solicited-node multicast group membership, thereby making such user-initiated state changes simpler and safer.
This commit is contained in:
parent
d5bc856f45
commit
71810d0415
@ -171,12 +171,6 @@ nd6_input(struct pbuf *p, struct netif *inp)
|
||||
/* We are using a duplicate address. */
|
||||
netif_ip6_addr_set_state(inp, i, IP6_ADDR_INVALID);
|
||||
|
||||
#if LWIP_IPV6_MLD
|
||||
/* Leave solicited node multicast group. */
|
||||
ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(inp, i)->addr[3]);
|
||||
mld6_leavegroup_netif(inp, &multicast_address);
|
||||
#endif /* LWIP_IPV6_MLD */
|
||||
|
||||
#if LWIP_IPV6_AUTOCONFIG
|
||||
/* Check to see if this address was autoconfigured. */
|
||||
if (!ip6_addr_islinklocal(&target_address)) {
|
||||
@ -871,13 +865,6 @@ nd6_tmr(void)
|
||||
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 ((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(netif, &multicast_address);
|
||||
}
|
||||
#endif /* LWIP_IPV6_MLD */
|
||||
/* Send a NS for this address. */
|
||||
nd6_send_ns(netif, netif_ip6_addr(netif, i), ND6_SEND_FLAG_MULTICAST_DEST);
|
||||
/* tentative: set next state by increasing by one */
|
||||
@ -2074,4 +2061,38 @@ nd6_cleanup_netif(struct netif *netif)
|
||||
}
|
||||
}
|
||||
|
||||
#if LWIP_IPV6_MLD
|
||||
/**
|
||||
* The state of a local IPv6 address entry is about to change. If needed, join
|
||||
* or leave the solicited-node multicast group for the address.
|
||||
*
|
||||
* @param netif The netif that owns the address.
|
||||
* @param addr_idx The index of the address.
|
||||
* @param new_state The new (IP6_ADDR_) state for the address.
|
||||
*/
|
||||
void
|
||||
nd6_adjust_mld_membership(struct netif *netif, s8_t addr_idx, u8_t new_state)
|
||||
{
|
||||
u8_t old_state, old_member, new_member;
|
||||
|
||||
old_state = netif_ip6_addr_state(netif, addr_idx);
|
||||
|
||||
/* Determine whether we were, and should be, a member of the solicited-node
|
||||
* multicast group for this address. For tentative addresses, the group is
|
||||
* not joined until the address enters the TENTATIVE_1 (or VALID) state. */
|
||||
old_member = (old_state != IP6_ADDR_INVALID && old_state != IP6_ADDR_TENTATIVE);
|
||||
new_member = (new_state != IP6_ADDR_INVALID && new_state != IP6_ADDR_TENTATIVE);
|
||||
|
||||
if (old_member != new_member) {
|
||||
ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(netif, addr_idx)->addr[3]);
|
||||
|
||||
if (new_member) {
|
||||
mld6_joingroup_netif(netif, &multicast_address);
|
||||
} else {
|
||||
mld6_leavegroup_netif(netif, &multicast_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_IPV6_MLD */
|
||||
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
@ -1096,6 +1096,13 @@ netif_ip6_addr_set_state(struct netif* netif, s8_t addr_idx, u8_t state)
|
||||
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 LWIP_IPV6_MLD
|
||||
/* Reevaluate solicited-node multicast group membership. */
|
||||
if (netif->flags & NETIF_FLAG_MLD6) {
|
||||
nd6_adjust_mld_membership(netif, addr_idx, state);
|
||||
}
|
||||
#endif /* LWIP_IPV6_MLD */
|
||||
|
||||
if (old_valid && !new_valid) {
|
||||
/* address about to be removed by setting invalid */
|
||||
#if LWIP_TCP
|
||||
|
@ -71,6 +71,9 @@ u16_t nd6_get_destination_mtu(const ip6_addr_t *ip6addr, struct netif *netif);
|
||||
void nd6_reachability_hint(const ip6_addr_t *ip6addr);
|
||||
#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */
|
||||
void nd6_cleanup_netif(struct netif *netif);
|
||||
#if LWIP_IPV6_MLD
|
||||
void nd6_adjust_mld_membership(struct netif *netif, s8_t addr_idx, u8_t new_state);
|
||||
#endif /* LWIP_IPV6_MLD */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user