Skip to content

Instantly share code, notes, and snippets.

@eliphaslevy
Created July 7, 2021 21:44
Show Gist options
  • Save eliphaslevy/857c0a07aaa5c5319548b4cc882b4606 to your computer and use it in GitHub Desktop.
Save eliphaslevy/857c0a07aaa5c5319548b4cc882b4606 to your computer and use it in GitHub Desktop.
ripd multicast leave even when interface is down - for FRR6 - fixes igmp membership leak
Fix for:
RIP: can't setsockopt IP_ADD_MEMBERSHIP No buffer space available
RIP: multicast join failed, interface FOO not running
Based on the patch for quagga from Michal Ruzicka
https://lists.quagga.net/pipermail/quagga-dev/2006-August/020891.html
Which was based on the one for zebra from Sergey Vlasov
https://bugzilla.altlinux.org/show_bug.cgi?id=3915
--- frr-6.0.3.orig/ripd/ripd.h 2021-07-07 14:02:30.054026597 -0300
+++ frr-6.0.3/ripd/ripd.h 2021-07-07 14:09:50.546026022 -0300
@@ -249,6 +249,9 @@
/* RIP is running on this interface. */
int running;
+ /* Joined to multicast group for this interface. */
+ int joined_multicast;
+
/* RIP version control. */
int ri_send;
int ri_receive;
--- frr-6.0.3/ripd/rip_interface.c 2021-07-07 14:02:19.994026536 -0300
+++ frr-6.0.3.orig/ripd/rip_interface.c 2021-07-07 14:09:02.322026026 -0300
@@ -95,7 +95,8 @@
group.s_addr, ifindex);
if (ret < 0)
- zlog_info("can't setsockopt IP_DROP_MEMBERSHIP");
+ zlog_info("can't setsockopt IP_DROP_MEMBERSHIP %s",
+ safe_strerror(errno));
return ret;
}
@@ -256,12 +257,15 @@
/* Multicast packet receive socket. */
static int rip_multicast_join(struct interface *ifp, int sock)
{
+ struct rip_interface *ri;
struct listnode *cnode;
struct connected *ifc;
+ ri = ifp->info;
+
if (if_is_operative(ifp) && if_is_multicast(ifp)) {
if (IS_RIP_DEBUG_EVENT)
- zlog_debug("multicast join at %s", ifp->name);
+ zlog_debug("multicast join at %s ifindex %d", ifp->name, ifp->ifindex);
for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) {
struct prefix_ipv4 *p;
@@ -277,8 +281,9 @@
ifp->ifindex)
< 0)
return -1;
- else
- return 0;
+
+ ri->joined_multicast = 1;
+ return 0;
}
}
return 0;
@@ -290,9 +295,12 @@
struct listnode *cnode;
struct connected *connected;
- if (if_is_up(ifp) && if_is_multicast(ifp)) {
+ ri = ifp->info;
+
+ if (if_is_multicast(ifp)) {
if (IS_RIP_DEBUG_EVENT)
- zlog_debug("multicast leave from %s", ifp->name);
+ zlog_debug("multicast leave from %s ifindex %d",
+ ifp->name, ifp->ifindex);
for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
struct prefix_ipv4 *p;
@@ -306,8 +314,10 @@
group.s_addr = htonl(INADDR_RIP_GROUP);
if (ipv4_multicast_leave(sock, group, p->prefix,
ifp->ifindex)
- == 0)
- return;
+ < 0)
+ continue;
+ ri->joined_multicast = 0;
+ return;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment