]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_join.c
zebra: Allow ns delete to happen after under/over flow checks
[mirror_frr.git] / pimd / pim_join.c
index 9bc5c2d9cce1f2645685f65eda122879d3e9577c..ae5032be73f7d41088a7e19f54babc2f8351d8ef 100644 (file)
@@ -38,6 +38,7 @@
 #include "pim_rpf.h"
 #include "pim_rp.h"
 #include "pim_jp_agg.h"
+#include "pim_util.h"
 
 static void on_trace(const char *label, struct interface *ifp,
                     struct in_addr src)
@@ -64,9 +65,9 @@ static void recv_join(struct interface *ifp, struct pim_neighbor *neigh,
                zlog_warn(
                        "%s: join (S,G)=%s rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s",
                        __PRETTY_FUNCTION__, pim_str_sg_dump(sg),
-                       source_flags & PIM_RPT_BIT_MASK,
-                       source_flags & PIM_WILDCARD_BIT_MASK, up_str, holdtime,
-                       neigh_str, ifp->name);
+                       !!(source_flags & PIM_RPT_BIT_MASK),
+                       !!(source_flags & PIM_WILDCARD_BIT_MASK), up_str,
+                       holdtime, neigh_str, ifp->name);
        }
 
        pim_ifp = ifp->info;
@@ -80,14 +81,26 @@ static void recv_join(struct interface *ifp, struct pim_neighbor *neigh,
         */
        if ((source_flags & PIM_RPT_BIT_MASK)
            && (source_flags & PIM_WILDCARD_BIT_MASK)) {
-               struct pim_rpf *rp = RP(sg->grp);
+               struct pim_rpf *rp = RP(pim_ifp->pim, sg->grp);
 
                /*
                 * If the RP sent in the message is not
                 * our RP for the group, drop the message
                 */
-               if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr)
+               if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr) {
+                       char received_rp[INET_ADDRSTRLEN];
+                       char local_rp[INET_ADDRSTRLEN];
+                       pim_inet4_dump("<received?>", sg->src, received_rp,
+                                      sizeof(received_rp));
+                       pim_inet4_dump("<local?>", rp->rpf_addr.u.prefix4,
+                                      local_rp, sizeof(local_rp));
+                       if (PIM_DEBUG_PIM_TRACE)
+                               zlog_warn(
+                                       "%s: Specified RP(%s) in join is different than our configured RP(%s)",
+                                       __PRETTY_FUNCTION__, received_rp,
+                                       local_rp);
                        return;
+               }
 
                sg->src.s_addr = INADDR_ANY;
        }
@@ -124,7 +137,7 @@ static void recv_prune(struct interface *ifp, struct pim_neighbor *neigh,
 
        if ((source_flags & PIM_RPT_BIT_MASK)
            && (source_flags & PIM_WILDCARD_BIT_MASK)) {
-               struct pim_rpf *rp = RP(sg->grp);
+               struct pim_rpf *rp = RP(pim_ifp->pim, sg->grp);
 
                // Ignoring Prune *,G's at the moment.
                if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr)
@@ -141,6 +154,7 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
                       int tlv_buf_size)
 {
        struct prefix msg_upstream_addr;
+       struct pim_interface *pim_ifp;
        uint8_t msg_num_groups;
        uint16_t msg_holdtime;
        int addr_offset;
@@ -151,6 +165,7 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
 
        buf = tlv_buf;
        pastend = tlv_buf + tlv_buf_size;
+       pim_ifp = ifp->info;
 
        /*
          Parse ucast addr
@@ -219,7 +234,7 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
                uint16_t msg_num_pruned_sources;
                int source;
                struct pim_ifchannel *starg_ch = NULL, *sg_ch = NULL;
-               uint8_t starg_alone = 0;
+               bool filtered = false;
 
                memset(&sg, 0, sizeof(struct prefix_sg));
                addr_offset = pim_parse_addr_group(&sg, buf, pastend - buf);
@@ -262,6 +277,9 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
                                src_str, ifp->name);
                }
 
+               /* boundary check */
+               filtered = pim_is_group_filtered(pim_ifp, &sg.grp);
+
                /* Scan joined sources */
                for (source = 0; source < msg_num_joined_sources; ++source) {
                        addr_offset = pim_parse_addr_source(
@@ -272,17 +290,19 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
 
                        buf += addr_offset;
 
+                       /* if we are filtering this group, skip the join */
+                       if (filtered)
+                               continue;
+
                        recv_join(ifp, neigh, msg_holdtime,
                                  msg_upstream_addr.u.prefix4, &sg,
                                  msg_source_flags);
 
                        if (sg.src.s_addr == INADDR_ANY) {
-                               starg_alone = 1;
                                starg_ch = pim_ifchannel_find(ifp, &sg);
                                if (starg_ch)
                                        pim_ifchannel_set_star_g_join_state(
-                                               starg_ch, 0, msg_source_flags,
-                                               1, starg_alone);
+                                               starg_ch, 0, 1);
                        }
                }
 
@@ -294,14 +314,24 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
                                return -8;
                        }
 
-                       sg_ch = pim_ifchannel_find(ifp, &sg);
-
                        buf += addr_offset;
-                       starg_alone = 0;
+
+                       /* if we are filtering this group, skip the prune */
+                       if (filtered)
+                               continue;
+
                        recv_prune(ifp, neigh, msg_holdtime,
                                   msg_upstream_addr.u.prefix4, &sg,
                                   msg_source_flags);
 
+                       /*
+                        * So if we are receiving a S,G,RPT prune
+                        * before we have any data for that S,G
+                        * We need to retrieve the sg_ch after
+                        * we parse the prune.
+                        */
+                       sg_ch = pim_ifchannel_find(ifp, &sg);
+
                        /* Received SG-RPT Prune delete oif from specific S,G */
                        if (starg_ch && sg_ch
                            && (msg_source_flags & PIM_RPT_BIT_MASK)
@@ -321,9 +351,8 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
                                }
                        }
                }
-               if (starg_ch)
-                       pim_ifchannel_set_star_g_join_state(
-                               starg_ch, 1, msg_source_flags, 0, starg_alone);
+               if (starg_ch && !filtered)
+                       pim_ifchannel_set_star_g_join_state(starg_ch, 1, 0);
                starg_ch = NULL;
        } /* scan groups */
 
@@ -401,7 +430,7 @@ int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups)
        struct pim_jp_agg_group *group;
        struct pim_interface *pim_ifp = NULL;
        struct pim_jp_groups *grp = NULL;
-       struct pim_jp *msg;
+       struct pim_jp *msg = NULL;
        struct listnode *node, *nnode;
        uint8_t pim_msg[10000];
        uint8_t *curr_ptr = pim_msg;