]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: Indicating the rp in the msdp sa message
authorAdriano Marto Reis <adrianomarto@gmail.com>
Sat, 30 Sep 2023 05:49:40 +0000 (15:49 +1000)
committerAdriano Marto Reis <adrianomarto@gmail.com>
Wed, 4 Oct 2023 04:30:44 +0000 (14:30 +1000)
Indicating the configured PIM Rendezvous Point (RP) in the MSDP SA
message

The RFC-3618, section 12.2.1, describes the fields included in the MSDP
SA message. The "RP address" field is "the address of the RP in the
domain the source has become active in".

In the most common case, we will establish an MSDP connection from RP to
RP. However, there are cases where we want to establish a MSDP
connection from an interface/address that is not the RP. Section 3 of
RFC-3618 describes that scenario as "intermediate MSDP peer". Moreover,
the RP could be another router in the PIM domain - not the one
establishing the MSDP connection.

The current implementation could be problematic even with a single
router per PIM domain. Consider the following scenario:
* There are two PIM domains, each one with a single router.
* The two routers are connected via two independent networks. Let's say
that is to provide redundancy.
* The routers are configured to establish two MSDP connections, one on
each network (redundancy again).
* A multicast source becomes active on the router 1. It will be
communicated to router 2 via two independent MSDP SA messages, one per
MSDP connection.
* Without these changes, each MSDP SA message will indicate a different
RP.
* Both RP addresses will pass the RPF check, and both MSDP sources will
be accepted.
* If the router has clients interested in that multicast group, it will
send PIM Join messages to both RPs and start receiving the multicast
traffic from both.

With the changes included in this commit, the multicast source available
in router 1 would still be communicated to router 2 twice. But both MSDP
SA messages would indicate the same RP, and one of them would be
discarded due to failure in the RPF-check failure. Also, the changes
allow us to define the RP that will be included in the MSDP SA message,
and it could be one of the interfaces used to establish the MSDP
connection, some other interface on the router, a loopback interface, or
another router in the PIM domain.

These changes should not create compatibility issues. As I mentioned, we
usually establish MSDP connections from RP to RP. In this case, the
result will be the same. We would still indicate the address used to
establish the MSDP connection if the RP is not set - I wonder if that
should even be a valid configuration.

Signed-off-by: Adriano Marto Reis <adrianomarto@gmail.com>
pimd/pim_msdp.c
pimd/pim_msdp_packet.c

index b1b6958fe16681dd1e7e74abaee259db960dba74..623c14bb03919cd38b168a72ee429c3b75de4a85 100644 (file)
@@ -374,6 +374,8 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp,
                     pim_sgaddr *sg, struct in_addr rp)
 {
        struct pim_msdp_sa *sa;
+       struct rp_info *rp_info;
+       struct prefix grp;
 
        sa = pim_msdp_sa_add(pim, sg, rp);
        if (!sa) {
@@ -406,6 +408,14 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp,
                                           sa->sg_str);
                        }
                        /* send an immediate SA update to peers */
+                       pim_addr_to_prefix(&grp, sa->sg.grp);
+                       rp_info = pim_rp_find_match_group(pim, &grp);
+                       if (rp_info) {
+                           sa->rp = rp_info->rp.rpf_addr;
+                       } else
+                       {
+                           sa->rp = pim->msdp.originator_id;
+                       }
                        sa->rp = pim->msdp.originator_id;
                        pim_msdp_pkt_sa_tx_one(sa);
                }
index a414736cccf1bc552fbb0362e01770d13fdd69be..4324a96bef8962cb0fa818b9f3609f2a276e7985 100644 (file)
@@ -14,7 +14,9 @@
 
 #include "pimd.h"
 #include "pim_instance.h"
+#include "pim_rp.h"
 #include "pim_str.h"
+#include "pim_util.h"
 #include "pim_errors.h"
 
 #include "pim_msdp.h"
@@ -387,6 +389,9 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim,
 {
        struct listnode *sanode;
        struct pim_msdp_sa *sa;
+       struct rp_info *rp_info;
+       struct prefix group_all;
+       struct in_addr rp;
        int sa_count;
        int local_cnt = pim->msdp.local_cnt;
 
@@ -395,8 +400,15 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim,
                zlog_debug("  sa gen  %d", local_cnt);
        }
 
-       local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt,
-                                            pim->msdp.originator_id);
+       rp = pim->msdp.originator_id;
+       if (pim_get_all_mcast_group(&group_all)) {
+           rp_info = pim_rp_find_match_group(pim, &group_all);
+           if (rp_info) {
+               rp = rp_info->rp.rpf_addr;
+           }
+       }
+
+       local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt, rp);
 
        for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
                if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) {
@@ -418,7 +430,7 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim,
                                           local_cnt);
                        }
                        local_cnt = pim_msdp_pkt_sa_fill_hdr(
-                               pim, local_cnt, pim->msdp.originator_id);
+                               pim, local_cnt, rp);
                }
        }