]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_igmpv3.c
lib: enforce vrf_name_to_id by returning default_vrf when name is null
[mirror_frr.git] / pimd / pim_igmpv3.c
index 1fc7517e0564fe7e613482e8a10bfc5bc1b9b5a7..430cba76b0c7a284f4b4ec0b27b9703eac72e743 100644 (file)
@@ -21,6 +21,7 @@
 #include "log.h"
 #include "memory.h"
 #include "if.h"
+#include "lib_errors.h"
 
 #include "pimd.h"
 #include "pim_iface.h"
@@ -457,11 +458,6 @@ struct igmp_source *source_new(struct igmp_group *group,
        }
 
        src = XCALLOC(MTYPE_PIM_IGMP_GROUP_SOURCE, sizeof(*src));
-       if (!src) {
-               zlog_warn("%s %s: XCALLOC() failure", __FILE__,
-                         __PRETTY_FUNCTION__);
-               return 0; /* error, not found, could not create */
-       }
 
        src->t_source_timer = NULL;
        src->source_group = group; /* back pointer */
@@ -491,9 +487,6 @@ static struct igmp_source *add_source_by_addr(struct igmp_sock *igmp,
        }
 
        src = source_new(group, src_addr);
-       if (!src) {
-               return 0;
-       }
 
        return src;
 }
@@ -584,10 +577,6 @@ static void isex_excl(struct igmp_group *group, int num_sources,
                        /* E.4: if not found, create source with timer=GMI:
                         * (A-X-Y) */
                        source = source_new(group, *src_addr);
-                       if (!source) {
-                               /* ugh, internal malloc failure, skip source */
-                               continue;
-                       }
                        zassert(!source->t_source_timer); /* timer == 0 */
                        igmp_source_reset_gmi(group->group_igmp_sock, group,
                                              source);
@@ -642,10 +631,6 @@ static void isex_incl(struct igmp_group *group, int num_sources,
                        /* I.4: if not found, create source with timer=0 (B-A)
                         */
                        source = source_new(group, *src_addr);
-                       if (!source) {
-                               /* ugh, internal malloc failure, skip source */
-                               continue;
-                       }
                        zassert(!source->t_source_timer); /* (B-A) timer=0 */
                }
 
@@ -671,6 +656,9 @@ void igmpv3_report_isex(struct igmp_sock *igmp, struct in_addr from,
        on_trace(__PRETTY_FUNCTION__, ifp, from, group_addr, num_sources,
                 sources);
 
+       if (pim_is_group_filtered(ifp->info, &group_addr))
+               return;
+
        /* non-existant group is created as INCLUDE {empty} */
        group = igmp_add_group_by_addr(igmp, group_addr);
        if (!group) {
@@ -722,10 +710,6 @@ static void toin_incl(struct igmp_group *group, int num_sources,
                } else {
                        /* If not found, create new source */
                        source = source_new(group, *src_addr);
-                       if (!source) {
-                               /* ugh, internal malloc failure, skip source */
-                               continue;
-                       }
                }
 
                /* (B)=GMI */
@@ -767,10 +751,6 @@ static void toin_excl(struct igmp_group *group, int num_sources,
                } else {
                        /* If not found, create new source */
                        source = source_new(group, *src_addr);
-                       if (!source) {
-                               /* ugh, internal malloc failure, skip source */
-                               continue;
-                       }
                }
 
                /* (A)=GMI */
@@ -856,10 +836,6 @@ static void toex_incl(struct igmp_group *group, int num_sources,
                        /* If source not found, create source with timer=0:
                         * (B-A)=0 */
                        source = source_new(group, *src_addr);
-                       if (!source) {
-                               /* ugh, internal malloc failure, skip source */
-                               continue;
-                       }
                        zassert(!source->t_source_timer); /* (B-A) timer=0 */
                }
 
@@ -919,10 +895,6 @@ static void toex_excl(struct igmp_group *group, int num_sources,
                         * (A-X-Y)=Group Timer */
                        long group_timer_msec;
                        source = source_new(group, *src_addr);
-                       if (!source) {
-                               /* ugh, internal malloc failure, skip source */
-                               continue;
-                       }
 
                        zassert(!source->t_source_timer); /* timer == 0 */
                        group_timer_msec = igmp_group_timer_remain_msec(group);
@@ -1433,10 +1405,6 @@ static void block_excl(struct igmp_group *group, int num_sources,
                         * (A-X-Y)=Group Timer */
                        long group_timer_msec;
                        source = source_new(group, *src_addr);
-                       if (!source) {
-                               /* ugh, internal malloc failure, skip source */
-                               continue;
-                       }
 
                        zassert(!source->t_source_timer); /* timer == 0 */
                        group_timer_msec = igmp_group_timer_remain_msec(group);
@@ -1616,7 +1584,8 @@ void igmp_v3_send_query(struct igmp_group *group, int fd, const char *ifname,
 
        msg_size = IGMP_V3_SOURCES_OFFSET + (num_sources << 2);
        if (msg_size > query_buf_size) {
-               zlog_err(
+               flog_err(
+                       EC_LIB_DEVELOPMENT,
                        "%s %s: unable to send: msg_size=%zd larger than query_buf_size=%d",
                        __FILE__, __PRETTY_FUNCTION__, msg_size,
                        query_buf_size);
@@ -1869,6 +1838,12 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
        struct interface *ifp = igmp->interface;
        int i;
        int local_ncb = 0;
+       struct pim_interface *pim_ifp;
+
+       if (igmp->mtrace_only)
+               return 0;
+
+       pim_ifp = igmp->interface->info;
 
        if (igmp_msg_len < IGMP_V3_MSG_MIN_SIZE) {
                zlog_warn(
@@ -1891,6 +1866,9 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
                return -1;
        }
 
+       /* Collecting IGMP Rx stats */
+       igmp->rx_stats.report_v3++;
+
        num_groups = ntohs(
                *(uint16_t *)(igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET));
        if (num_groups < 1) {
@@ -1920,6 +1898,7 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
                int j;
                struct prefix lncb;
                struct prefix g;
+               bool filtered = false;
 
                if ((group_record + IGMP_V3_GROUP_RECORD_MIN_SIZE)
                    > report_pastend) {
@@ -1983,6 +1962,16 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
                g.family = AF_INET;
                g.u.prefix4 = rec_group;
                g.prefixlen = 32;
+
+               /* determine filtering status for group */
+               filtered = pim_is_group_filtered(ifp->info, &rec_group);
+
+               if (PIM_DEBUG_IGMP_PACKETS && filtered)
+                       zlog_debug(
+                               "Filtering IGMPv3 group record %s from %s on %s per prefix-list %s",
+                               inet_ntoa(rec_group), from_str, ifp->name,
+                               pim_ifp->boundary_oil_plist);
+
                /*
                 * If we receive a igmp report with the group in 224.0.0.0/24
                 * then we should ignore it
@@ -1990,7 +1979,7 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
                if (prefix_match(&lncb, &g))
                        local_ncb = 1;
 
-               if (!local_ncb)
+               if (!local_ncb && !filtered)
                        switch (rec_type) {
                        case IGMP_GRP_REC_TYPE_MODE_IS_INCLUDE:
                                igmpv3_report_isin(igmp, from, rec_group,