]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd, pim6d: Don't set SRC_STREAM flag on LHR
authorSarita Patra <saritap@vmware.com>
Mon, 31 Jul 2023 11:30:26 +0000 (04:30 -0700)
committerSarita Patra <saritap@vmware.com>
Mon, 31 Jul 2023 12:48:35 +0000 (05:48 -0700)
Setup:
------
R1( LHR) ---------R2( RP) ----------R3( FHR)

Problem:
-------
- Send IGMP/MLD join and traffic.
  LHR: (S,G) mroute is created with reference count = 2
  and set the flag SRC_STREAM.
  (Code flow: pim_mroute_msg_wholepkt -> pim_upstream_add,
              pim_upstream_sg_running_proc -> pim_upstream_ref)
- Send IGMP/MLD prune.
  LHR: removes (*,G) entry and it tries to remove childen (S,G) entries.
       But (S,G) is having reference count = 2. So after prune,
       (S,G) entry reference count becomes 1 and will be present
       until KAT expires.

Fix:
---
Don't set SRC_STREAM flag for LHR.
In LHR, (S,G) should be maintained, until (*,G) is present.
When prune receives delete (*,G) and children (S,G).
When traffic stops, delete (S,G) after KAT expires.

Issue: #13893

Signed-off-by: Sarita Patra <saritap@vmware.com>
pimd/pim_upstream.c

index 406f772ffe083eae95cb56cb54192081026fc8e5..a8d087bf4930c914e75917dcf01bafd274a9edfe 100644 (file)
@@ -1965,6 +1965,7 @@ static bool pim_upstream_kat_start_ok(struct pim_upstream *up)
        struct channel_oil *c_oil = up->channel_oil;
        struct interface *ifp = up->rpf.source_nexthop.interface;
        struct pim_interface *pim_ifp;
+       struct pim_instance *pim = up->channel_oil->pim;
 
        /* "iif == RPF_interface(S)" check is not easy to do as the info
         * we get from the kernel/ASIC is really a "lookup/key hit".
@@ -1984,8 +1985,9 @@ static bool pim_upstream_kat_start_ok(struct pim_upstream *up)
        }
 
        if ((up->join_state == PIM_UPSTREAM_JOINED)
-                       && !pim_upstream_empty_inherited_olist(up)) {
-               return true;
+           && !pim_upstream_empty_inherited_olist(up)) {
+               if (I_am_RP(pim, up->sg.grp))
+                       return true;
        }
 
        return false;