]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Match on longest prefix when searching for RP
authorDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 29 Aug 2017 13:46:12 +0000 (09:46 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 31 Aug 2017 14:30:19 +0000 (10:30 -0400)
When we are searching for a RP to use, amongst
many RP's and separate prefix-lists, Match on
the longest prefix specified to choose the
correct RP.

Example:
ip pim rp 4.3.2.1 prefix-list A
ip pim rp 4.3.2.2 prefix-list B
ip pim rp 4.3.2.3 prefix-list C

ip prefix-list A seq 5 permit 225.0.0.0/8
ip prefix-list B seq 5 permit 225.1.0.0/16
ip prefix-list C seq 5 permit 225.1.1.0/24

Old behavior:  Group 225.1.1.14 comes in and
we need to find the RP to use, we would match
on the first prefix-list A( since we are searching
based on a sorted link list of RP address ) and
select 4.3.2.1 as our RP

New behavior:  Group 225.1.1.14 comes in and
we need to find theRP to use, we now will
match on C( longest prefix match ) and select
4.3.2.3 as our RP.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pimd/pim_rp.c

index ff89a1bdd271a0da68ca1d6535bff7a189b5cced..423d49a1b9e347db69023347885ca4518701b059 100644 (file)
@@ -198,23 +198,35 @@ static struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
                                               struct prefix *group)
 {
        struct listnode *node;
+       struct rp_info *best = NULL;
        struct rp_info *rp_info;
        struct prefix_list *plist;
+       struct prefix *p, *bp;
 
        for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) {
                if (rp_info->plist) {
                        plist = prefix_list_lookup(AFI_IP, rp_info->plist);
 
-                       if (plist
-                           && prefix_list_apply(plist, group) == PREFIX_PERMIT)
-                               return rp_info;
+                       if (prefix_list_apply_which_prefix(plist, &p, group) == PREFIX_DENY)
+                               continue;
+
+                       if (!best) {
+                               best = rp_info;
+                               bp = p;
+                               continue;
+                       }
+
+                       if (bp->prefixlen < p->prefixlen) {
+                               best = rp_info;
+                               bp = p;
+                       }
                } else {
                        if (prefix_match(&rp_info->group, group))
                                return rp_info;
                }
        }
 
-       return NULL;
+       return best;
 }
 
 /*