]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: fuse source_new() and add_source_by_addr() 9489/head
authorDavid Lamparter <equinox@opensourcerouting.org>
Tue, 24 Aug 2021 16:17:05 +0000 (18:17 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Fri, 27 Aug 2021 08:46:53 +0000 (10:46 +0200)
This makes a lot more sense semantically (and matches the way groups are
handled.)  Also allows placing additional restrictions on source
creation (e.g. limit on number of sources or ACLs.)

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
pimd/pim_igmp.h
pimd/pim_igmpv3.c
pimd/pim_zebra.c

index 460c9d9a07f4b5ac992e5b774136ba078eeab10f..dfe986e8f541fb8fdc0912787e1fd0ab8bfabc3c 100644 (file)
@@ -191,6 +191,10 @@ struct igmp_group *find_group_by_addr(struct igmp_sock *igmp,
 struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
                                          struct in_addr group_addr);
 
+struct igmp_source *igmp_get_source_by_addr(struct igmp_group *group,
+                                           struct in_addr src_addr,
+                                           bool *created);
+
 void igmp_group_delete_empty_include(struct igmp_group *group);
 
 void igmp_startup_mode_on(struct igmp_sock *igmp);
@@ -198,9 +202,6 @@ void igmp_startup_mode_on(struct igmp_sock *igmp);
 void igmp_group_timer_on(struct igmp_group *group, long interval_msec,
                         const char *ifname);
 
-struct igmp_source *source_new(struct igmp_group *group,
-                              struct in_addr src_addr);
-
 void igmp_send_query(int igmp_version, struct igmp_group *group, int fd,
                     const char *ifname, char *query_buf, int query_buf_size,
                     int num_sources, struct in_addr dst_addr,
index 1f4d904f77d5f5db7743ae49b9d5bd79b38cdbe1..13db11fa80486b3327a1df0b25bb452e1b60d5ee 100644 (file)
@@ -441,11 +441,18 @@ struct igmp_source *igmp_find_source_by_addr(struct igmp_group *group,
        return 0;
 }
 
-struct igmp_source *source_new(struct igmp_group *group,
-                              struct in_addr src_addr)
+struct igmp_source *igmp_get_source_by_addr(struct igmp_group *group,
+                                           struct in_addr src_addr, bool *new)
 {
        struct igmp_source *src;
 
+       if (new)
+               *new = false;
+
+       src = igmp_find_source_by_addr(group, src_addr);
+       if (src)
+               return src;
+
        if (PIM_DEBUG_IGMP_TRACE) {
                char group_str[INET_ADDRSTRLEN];
                char source_str[INET_ADDRSTRLEN];
@@ -472,23 +479,6 @@ struct igmp_source *source_new(struct igmp_group *group,
 
        /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
        igmp_anysource_forward_stop(group);
-
-       return src;
-}
-
-static struct igmp_source *add_source_by_addr(struct igmp_sock *igmp,
-                                             struct igmp_group *group,
-                                             struct in_addr src_addr)
-{
-       struct igmp_source *src;
-
-       src = igmp_find_source_by_addr(group, src_addr);
-       if (src) {
-               return src;
-       }
-
-       src = source_new(group, src_addr);
-
        return src;
 }
 
@@ -540,10 +530,9 @@ static void allow(struct igmp_sock *igmp, struct in_addr from,
 
                src_addr = sources + i;
 
-               source = add_source_by_addr(igmp, group, *src_addr);
-               if (!source) {
+               source = igmp_get_source_by_addr(group, *src_addr, NULL);
+               if (!source)
                        continue;
-               }
 
                /*
                  RFC 3376: 6.4.1. Reception of Current-State Records
@@ -585,18 +574,21 @@ static void isex_excl(struct igmp_group *group, int num_sources,
        /* scan received sources (A) */
        for (i = 0; i < num_sources; ++i) {
                struct in_addr *src_addr;
+               bool new;
 
                src_addr = sources + i;
 
                /* E.2: lookup reported source from (A) in (X,Y) */
-               source = igmp_find_source_by_addr(group, *src_addr);
-               if (source) {
+               source = igmp_get_source_by_addr(group, *src_addr, &new);
+               if (!source)
+                       continue;
+
+               if (!new) {
                        /* E.3: if found, clear deletion flag: (X*A) or (Y*A) */
                        IGMP_SOURCE_DONT_DELETE(source->source_flags);
                } else {
                        /* E.4: if not found, create source with timer=GMI:
                         * (A-X-Y) */
-                       source = source_new(group, *src_addr);
                        assert(!source->t_source_timer); /* timer == 0 */
                        igmp_source_reset_gmi(group, source);
                        assert(source->t_source_timer); /* (A-X-Y) timer > 0 */
@@ -637,18 +629,21 @@ static void isex_incl(struct igmp_group *group, int num_sources,
        for (i = 0; i < num_sources; ++i) {
                struct igmp_source *source;
                struct in_addr *src_addr;
+               bool new;
 
                src_addr = sources + i;
 
                /* I.2: lookup reported source (B) */
-               source = igmp_find_source_by_addr(group, *src_addr);
-               if (source) {
+               source = igmp_get_source_by_addr(group, *src_addr, &new);
+               if (!source)
+                       continue;
+
+               if (!new) {
                        /* I.3: if found, clear deletion flag (A*B) */
                        IGMP_SOURCE_DONT_DELETE(source->source_flags);
                } else {
                        /* I.4: if not found, create source with timer=0 (B-A)
                         */
-                       source = source_new(group, *src_addr);
                        assert(!source->t_source_timer); /* (B-A) timer=0 */
                }
 
@@ -714,18 +709,19 @@ static void toin_incl(struct igmp_group *group, int num_sources,
        for (i = 0; i < num_sources; ++i) {
                struct igmp_source *source;
                struct in_addr *src_addr;
+               bool new;
 
                src_addr = sources + i;
 
                /* Lookup reported source (B) */
-               source = igmp_find_source_by_addr(group, *src_addr);
-               if (source) {
+               source = igmp_get_source_by_addr(group, *src_addr, &new);
+               if (!source)
+                       continue;
+
+               if (!new) {
                        /* If found, clear SEND flag (A*B) */
                        IGMP_SOURCE_DONT_SEND(source->source_flags);
                        --num_sources_tosend;
-               } else {
-                       /* If not found, create new source */
-                       source = source_new(group, *src_addr);
                }
 
                /* (B)=GMI */
@@ -751,21 +747,20 @@ static void toin_excl(struct igmp_group *group, int num_sources,
        for (i = 0; i < num_sources; ++i) {
                struct igmp_source *source;
                struct in_addr *src_addr;
+               bool new;
 
                src_addr = sources + i;
 
                /* Lookup reported source (A) */
-               source = igmp_find_source_by_addr(group, *src_addr);
-               if (source) {
-                       if (source->t_source_timer) {
-                               /* If found and timer running, clear SEND flag
-                                * (X*A) */
-                               IGMP_SOURCE_DONT_SEND(source->source_flags);
-                               --num_sources_tosend;
-                       }
-               } else {
-                       /* If not found, create new source */
-                       source = source_new(group, *src_addr);
+               source = igmp_get_source_by_addr(group, *src_addr, &new);
+               if (!source)
+                       continue;
+
+               if (source->t_source_timer) {
+                       /* If found and timer running, clear SEND flag
+                        * (X*A) */
+                       IGMP_SOURCE_DONT_SEND(source->source_flags);
+                       --num_sources_tosend;
                }
 
                /* (A)=GMI */
@@ -835,22 +830,18 @@ static void toex_incl(struct igmp_group *group, int num_sources,
        for (i = 0; i < num_sources; ++i) {
                struct igmp_source *source;
                struct in_addr *src_addr;
+               bool new;
 
                src_addr = sources + i;
 
                /* Lookup reported source (B) */
-               source = igmp_find_source_by_addr(group, *src_addr);
-               if (source) {
+               source = igmp_get_source_by_addr(group, *src_addr, &new);
+               if (!new) {
                        /* If found, clear deletion flag: (A*B) */
                        IGMP_SOURCE_DONT_DELETE(source->source_flags);
                        /* and set SEND flag (A*B) */
                        IGMP_SOURCE_DO_SEND(source->source_flags);
                        ++num_sources_tosend;
-               } else {
-                       /* If source not found, create source with timer=0:
-                        * (B-A)=0 */
-                       source = source_new(group, *src_addr);
-                       assert(!source->t_source_timer); /* (B-A) timer=0 */
                }
 
        } /* Scan received sources (B) */
@@ -895,12 +886,16 @@ static void toex_excl(struct igmp_group *group, int num_sources,
        for (i = 0; i < num_sources; ++i) {
                struct igmp_source *source;
                struct in_addr *src_addr;
+               bool new;
 
                src_addr = sources + i;
 
                /* lookup reported source (A) in known sources (X,Y) */
-               source = igmp_find_source_by_addr(group, *src_addr);
-               if (source) {
+               source = igmp_get_source_by_addr(group, *src_addr, &new);
+               if (!source)
+                       continue;
+
+               if (!new) {
                        /* if found, clear off DELETE flag from reported source
                         * (A) */
                        IGMP_SOURCE_DONT_DELETE(source->source_flags);
@@ -908,7 +903,6 @@ static void toex_excl(struct igmp_group *group, int num_sources,
                        /* if not found, create source with Group Timer:
                         * (A-X-Y)=Group Timer */
                        long group_timer_msec;
-                       source = source_new(group, *src_addr);
 
                        assert(!source->t_source_timer); /* timer == 0 */
                        group_timer_msec = igmp_group_timer_remain_msec(group);
@@ -1404,16 +1398,19 @@ static void block_excl(struct igmp_group *group, int num_sources,
        for (i = 0; i < num_sources; ++i) {
                struct igmp_source *source;
                struct in_addr *src_addr;
+               bool new;
 
                src_addr = sources + i;
 
                /* lookup reported source (A) in known sources (X,Y) */
-               source = igmp_find_source_by_addr(group, *src_addr);
-               if (!source) {
+               source = igmp_get_source_by_addr(group, *src_addr, &new);
+               if (!source)
+                       continue;
+
+               if (new) {
                        /* 3: if not found, create source with Group Timer:
                         * (A-X-Y)=Group Timer */
                        long group_timer_msec;
-                       source = source_new(group, *src_addr);
 
                        assert(!source->t_source_timer); /* timer == 0 */
                        group_timer_msec = igmp_group_timer_remain_msec(group);
index 521e4ebc1788442de10e6cddc571193e7b3f710e..aa041df85736ed99e19561837e7ac2f67e103876 100644 (file)
@@ -474,7 +474,7 @@ void igmp_anysource_forward_start(struct pim_instance *pim,
        assert(group->group_filtermode_isexcl);
        assert(listcount(group->group_source_list) < 1);
 
-       source = source_new(group, src_addr);
+       source = igmp_get_source_by_addr(group, src_addr, NULL);
        if (!source) {
                zlog_warn("%s: Failure to create * source", __func__);
                return;