]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge branch 'master' into pim-ssm
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 30 Mar 2017 21:20:34 +0000 (16:20 -0500)
committerGitHub <noreply@github.com>
Thu, 30 Mar 2017 21:20:34 +0000 (16:20 -0500)
1  2 
pimd/pim_ifchannel.c
pimd/pim_upstream.c
pimd/pim_upstream.h
pimd/pim_zebra.c

Simple merge
Simple merge
Simple merge
index ccb184fcf2292e7dc4fb0dd1da34dfbcf3f069e3,d02560bfc2d6ed1a4c914506b369c035ad2b13f5..cd7c3db59a098b06e02497b2b477cc7c0aadf176
@@@ -766,215 -760,6 +761,84 @@@ static int fib_lookup_if_vif_index(stru
    return vif_index;
  }
  
- static int del_oif(struct channel_oil *channel_oil,
-                  struct interface *oif,
-                  uint32_t proto_mask)
- {
-   struct pim_interface *pim_ifp;
-   int old_ttl;
-   pim_ifp = oif->info;
-   if (PIM_DEBUG_MROUTE) {
-     char group_str[INET_ADDRSTRLEN]; 
-     char source_str[INET_ADDRSTRLEN];
-     pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
-     pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
-     zlog_debug("%s %s: (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d",
-              __FILE__, __PRETTY_FUNCTION__,
-              source_str, group_str,
-              proto_mask, oif->name, pim_ifp->mroute_vif_index);
-   }
-   /* Prevent single protocol from unsubscribing same interface from
-      channel (S,G) multiple times */
-   if (!(channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask)) {
-     if (PIM_DEBUG_MROUTE)
-       {
-       char group_str[INET_ADDRSTRLEN]; 
-       char source_str[INET_ADDRSTRLEN];
-       pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
-       pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
-       zlog_debug("%s %s: nonexistent protocol mask %u removed OIF %s (vif_index=%d, min_ttl=%d) from channel (S,G)=(%s,%s)",
-                  __FILE__, __PRETTY_FUNCTION__,
-                  proto_mask, oif->name, pim_ifp->mroute_vif_index,
-                  channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
-                  source_str, group_str);
-       }
-     return -2;
-   }
-   /* Mark that protocol is no longer interested in this OIF */
-   channel_oil->oif_flags[pim_ifp->mroute_vif_index] &= ~proto_mask;
-   /* Allow multiple protocols to unsubscribe same interface from
-      channel (S,G) multiple times, by silently ignoring requests while
-      there is at least one protocol interested in the channel */
-   if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & PIM_OIF_FLAG_PROTO_ANY) {
-     /* Check the OIF keeps existing before returning, and only log
-        warning otherwise */
-     if (channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] < 1) {
-       if (PIM_DEBUG_MROUTE)
-       {
-         char group_str[INET_ADDRSTRLEN];
-         char source_str[INET_ADDRSTRLEN];
-         pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
-         pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
-         zlog_debug("%s %s: protocol mask %u removing nonexistent OIF %s (vif_index=%d, min_ttl=%d) from channel (S,G)=(%s,%s)",
-                    __FILE__, __PRETTY_FUNCTION__,
-                    proto_mask, oif->name, pim_ifp->mroute_vif_index,
-                    channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
-                    source_str, group_str);
-       }
-     }
-     return 0;
-   }
-   old_ttl = channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index];
-   if (old_ttl < 1) {
-     if (PIM_DEBUG_MROUTE)
-       {
-       char group_str[INET_ADDRSTRLEN];
-       char source_str[INET_ADDRSTRLEN];
-       pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
-       pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
-       zlog_debug("%s %s: interface %s (vif_index=%d) is not output for channel (S,G)=(%s,%s)",
-                  __FILE__, __PRETTY_FUNCTION__,
-                  oif->name, pim_ifp->mroute_vif_index,
-                  source_str, group_str);
-       }
-     return -3;
-   }
-   channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = 0;
-   if (pim_mroute_add(channel_oil, __PRETTY_FUNCTION__)) {
-     char group_str[INET_ADDRSTRLEN];
-     char source_str[INET_ADDRSTRLEN];
-     pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
-     pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
-     zlog_warn("%s %s: could not remove output interface %s (vif_index=%d) from channel (S,G)=(%s,%s)",
-             __FILE__, __PRETTY_FUNCTION__,
-             oif->name, pim_ifp->mroute_vif_index,
-             source_str, group_str);
-     
-     channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = old_ttl;
-     return -4;
-   }
-   --channel_oil->oil_size;
-   if (channel_oil->oil_size < 1) {
-     if (pim_mroute_del(channel_oil, __PRETTY_FUNCTION__)) {
-       if (PIM_DEBUG_MROUTE)
-       {
-         /* just log a warning in case of failure */
-         char group_str[INET_ADDRSTRLEN];
-         char source_str[INET_ADDRSTRLEN];
-         pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
-         pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
-         zlog_debug("%s %s: failure removing OIL for channel (S,G)=(%s,%s)",
-                    __FILE__, __PRETTY_FUNCTION__,
-                    source_str, group_str);
-       }
-     }
-   }
-   if (PIM_DEBUG_MROUTE) {
-     char group_str[INET_ADDRSTRLEN]; 
-     char source_str[INET_ADDRSTRLEN];
-     pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
-     pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
-     zlog_debug("%s %s: (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d: DONE",
-              __FILE__, __PRETTY_FUNCTION__,
-              source_str, group_str,
-              proto_mask, oif->name, pim_ifp->mroute_vif_index);
-   }
-   return 0;
- }
 +static void
 +igmp_source_forward_reevaluate_one(struct igmp_source *source)
 +{
 +  struct prefix_sg sg;
 +  struct igmp_group *group = source->source_group;
 +  struct pim_ifchannel *ch;
 +
 +  if ((source->source_addr.s_addr != INADDR_ANY) ||
 +      !IGMP_SOURCE_TEST_FORWARDING (source->source_flags))
 +    return;
 +
 +  memset (&sg, 0, sizeof (struct prefix_sg));
 +  sg.src = source->source_addr;
 +  sg.grp = group->group_addr;
 +
 +  ch = pim_ifchannel_find (group->group_igmp_sock->interface, &sg);
 +  if (pim_is_grp_ssm (group->group_addr))
 +    {
 +      /* If SSM group withdraw local membership */
 +      if (ch && (ch->local_ifmembership == PIM_IFMEMBERSHIP_INCLUDE))
 +        {
 +          if (PIM_DEBUG_PIM_EVENTS)
 +            zlog_debug ("local membership del for %s as G is now SSM",
 +                        pim_str_sg_dump (&sg));
 +          pim_ifchannel_local_membership_del (group->group_igmp_sock->interface, &sg);
 +        }
 +    }
 +  else
 +    {
 +      /* If ASM group add local membership */
 +      if (!ch || (ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO))
 +        {
 +          if (PIM_DEBUG_PIM_EVENTS)
 +            zlog_debug ("local membership add for %s as G is now ASM",
 +                        pim_str_sg_dump (&sg));
 +          pim_ifchannel_local_membership_add (group->group_igmp_sock->interface, &sg);
 +        }
 +    }
 +}
 +
 +void
 +igmp_source_forward_reevaluate_all(void)
 +{
 +  struct listnode *ifnode;
 +  struct interface *ifp;
 +
 +  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
 +    {
 +      struct pim_interface *pim_ifp = ifp->info;
 +      struct listnode  *sock_node;
 +      struct igmp_sock *igmp;
 +
 +      if (!pim_ifp)
 +        continue;
 +
 +      /* scan igmp sockets */
 +      for (ALL_LIST_ELEMENTS_RO (pim_ifp->igmp_socket_list, sock_node, igmp))
 +        {
 +          struct listnode *grpnode;
 +          struct igmp_group *grp;
 +
 +          /* scan igmp groups */
 +          for (ALL_LIST_ELEMENTS_RO (igmp->igmp_group_list, grpnode, grp))
 +            {
 +              struct listnode    *srcnode;
 +              struct igmp_source *src;
 +
 +              /* scan group sources */
 +              for (ALL_LIST_ELEMENTS_RO (grp->group_source_list,
 +                                        srcnode, src))
 +                {
 +                  igmp_source_forward_reevaluate_one (src);
 +                } /* scan group sources */
 +            } /* scan igmp groups */
 +        } /* scan igmp sockets */
 +    } /* scan interfaces */
 +}
 +
  void igmp_source_forward_start(struct igmp_source *source)
  {
    struct igmp_group *group;