From dd24e2a2fdd69ca98abae9b73c1eb62eb31f1cbf Mon Sep 17 00:00:00 2001 From: paul Date: Thu, 15 Jun 2006 18:40:49 +0000 Subject: [ospfd] Fix multicast membership drop bug 2006-06-15 Paul Jakma * Reported by Milan Koci * ospf_interface.h: (struct ospf_if_info) Add reference counts for multicast group memberships. Add various macros to help manipulate/check membership state. * ospf_interface.c: (ospf_if_set_multicast) Maintain the ospf_if_info reference counts, and only actually drop memberships if it hits 0, to avoid losing membership when OSPF is disabled on an interface with multiple active OSPF interfaces. * ospf_packet.c: (ospf_{hello,read}) Use the new macros to check/set multicast membership. * ospf_vty.c: (show_ip_ospf_interface_sub) ditto. --- ospfd/ospf_interface.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'ospfd/ospf_interface.c') diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index b94cfa3a..2c2c0749 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -748,22 +748,25 @@ ospf_if_set_multicast(struct ospf_interface *oi) (OSPF_IF_PARAM(oi, passive_interface) == OSPF_IF_ACTIVE)) { /* The interface should belong to the OSPF-all-routers group. */ - if (!CHECK_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS) && + if (!OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) && (ospf_if_add_allspfrouters(oi->ospf, oi->address, oi->ifp->ifindex) >= 0)) - /* Set the flag only if the system call to join succeeded. */ - SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS); + /* Set the flag only if the system call to join succeeded. */ + OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS); } else { /* The interface should NOT belong to the OSPF-all-routers group. */ - if (CHECK_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS)) + if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) { - ospf_if_drop_allspfrouters (oi->ospf, oi->address, oi->ifp->ifindex); + /* Only actually drop if this is the last reference */ + if (OI_MEMBER_COUNT(oi, MEMBER_ALLROUTERS) == 1) + ospf_if_drop_allspfrouters (oi->ospf, oi->address, + oi->ifp->ifindex); /* Unset the flag regardless of whether the system call to leave the group succeeded, since it's much safer to assume that we are not a member. */ - UNSET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS); + OI_MEMBER_LEFT(oi,MEMBER_ALLROUTERS); } } @@ -773,22 +776,25 @@ ospf_if_set_multicast(struct ospf_interface *oi) (OSPF_IF_PARAM(oi, passive_interface) == OSPF_IF_ACTIVE)) { /* The interface should belong to the OSPF-designated-routers group. */ - if (!CHECK_FLAG(oi->multicast_memberships, MEMBER_DROUTERS) && + if (!OI_MEMBER_CHECK(oi, MEMBER_DROUTERS) && (ospf_if_add_alldrouters(oi->ospf, oi->address, oi->ifp->ifindex) >= 0)) /* Set the flag only if the system call to join succeeded. */ - SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS); + OI_MEMBER_JOINED(oi, MEMBER_DROUTERS); } else { /* The interface should NOT belong to the OSPF-designated-routers group */ - if (CHECK_FLAG(oi->multicast_memberships, MEMBER_DROUTERS)) + if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) { - ospf_if_drop_alldrouters(oi->ospf, oi->address, oi->ifp->ifindex); + /* drop only if last reference */ + if (OI_MEMBER_COUNT(oi, MEMBER_DROUTERS) == 1) + ospf_if_drop_alldrouters(oi->ospf, oi->address, oi->ifp->ifindex); + /* Unset the flag regardless of whether the system call to leave the group succeeded, since it's much safer to assume that we are not a member. */ - UNSET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS); + OI_MEMBER_LEFT(oi, MEMBER_DROUTERS); } } } -- cgit v1.2.3