mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 09:06:46 +00:00
ospf6d: fix freebsd mcast group issues
There's a delay in FreeBSD between issuing a command to leave a multicast group and an actual leave. If we execute "no router ospf6" and "router ospf6" fast enough, we can end up in a situation when OS performs the leave later than it performs the join and the interface remains without a multicast group. Instead of counting on a one second delay, we must wait until the interface actually leaves the group. Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
This commit is contained in:
parent
507559a089
commit
93828a9923
@ -680,6 +680,43 @@ static uint8_t dr_election(struct ospf6_interface *oi)
|
|||||||
return next_state;
|
return next_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
|
||||||
|
static bool ifmaddr_check(ifindex_t ifindex, struct in6_addr *addr)
|
||||||
|
{
|
||||||
|
struct ifmaddrs *ifmap, *ifma;
|
||||||
|
struct sockaddr_dl *sdl;
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
if (getifmaddrs(&ifmap) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (ifma = ifmap; ifma; ifma = ifma->ifma_next) {
|
||||||
|
if (ifma->ifma_name == NULL || ifma->ifma_addr == NULL)
|
||||||
|
continue;
|
||||||
|
if (ifma->ifma_name->sa_family != AF_LINK)
|
||||||
|
continue;
|
||||||
|
if (ifma->ifma_addr->sa_family != AF_INET6)
|
||||||
|
continue;
|
||||||
|
sdl = (struct sockaddr_dl *)ifma->ifma_name;
|
||||||
|
sin6 = (struct sockaddr_in6 *)ifma->ifma_addr;
|
||||||
|
if (sdl->sdl_index == ifindex
|
||||||
|
&& memcmp(&sin6->sin6_addr, addr, IPV6_MAX_BYTELEN) == 0) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ifmap)
|
||||||
|
freeifmaddrs(ifmap);
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __FreeBSD__ */
|
||||||
|
|
||||||
/* Interface State Machine */
|
/* Interface State Machine */
|
||||||
int interface_up(struct thread *thread)
|
int interface_up(struct thread *thread)
|
||||||
@ -693,11 +730,7 @@ int interface_up(struct thread *thread)
|
|||||||
if (!oi->type_cfg)
|
if (!oi->type_cfg)
|
||||||
oi->type = ospf6_default_iftype(oi->interface);
|
oi->type = ospf6_default_iftype(oi->interface);
|
||||||
|
|
||||||
/*
|
thread_cancel(&oi->thread_sso);
|
||||||
* Remove old pointer. If this thread wasn't a timer this
|
|
||||||
* operation won't make a difference, because it is already NULL.
|
|
||||||
*/
|
|
||||||
oi->thread_sso = NULL;
|
|
||||||
|
|
||||||
if (IS_OSPF6_DEBUG_INTERFACE)
|
if (IS_OSPF6_DEBUG_INTERFACE)
|
||||||
zlog_debug("Interface Event %s: [InterfaceUp]",
|
zlog_debug("Interface Event %s: [InterfaceUp]",
|
||||||
@ -740,13 +773,17 @@ int interface_up(struct thread *thread)
|
|||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
/*
|
/*
|
||||||
* XXX: Schedule IPv6 group join for later, otherwise we might
|
* There's a delay in FreeBSD between issuing a command to leave a
|
||||||
* lose the multicast group registration caused by IPv6 group
|
* multicast group and an actual leave. If we execute "no router ospf6"
|
||||||
* leave race.
|
* and "router ospf6" fast enough, we can end up in a situation when OS
|
||||||
|
* performs the leave later than it performs the join and the interface
|
||||||
|
* remains without a multicast group. We have to do the join only after
|
||||||
|
* the interface actually left the group.
|
||||||
*/
|
*/
|
||||||
if (oi->sso_try_cnt == 0) {
|
if (ifmaddr_check(oi->interface->ifindex, &allspfrouters6)) {
|
||||||
oi->sso_try_cnt++;
|
zlog_info(
|
||||||
zlog_info("Scheduling %s for sso", oi->interface->name);
|
"Interface %s is still in all routers group, rescheduling for SSO",
|
||||||
|
oi->interface->name);
|
||||||
thread_add_timer(master, interface_up, oi,
|
thread_add_timer(master, interface_up, oi,
|
||||||
OSPF6_INTERFACE_SSO_RETRY_INT,
|
OSPF6_INTERFACE_SSO_RETRY_INT,
|
||||||
&oi->thread_sso);
|
&oi->thread_sso);
|
||||||
|
Loading…
Reference in New Issue
Block a user