]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: increase RPF metric via the peerlink_rif by plus-10
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Thu, 6 Feb 2020 17:30:43 +0000 (09:30 -0800)
committerAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Fri, 14 Feb 2020 17:18:30 +0000 (09:18 -0800)
The RPF cost is incremented by 10 if the RPF interface is the peerlink-rif.
This is used to force the MLAG switch with the lowest cost to the RPF
to become the MLAG DF. If a switch has to go via the peerlink-rif to get
to the RP or source it simplly cannot be the designated forwarder.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
pimd/pim_rpf.c
pimd/pim_upstream.c
pimd/pim_upstream.h
pimd/pim_vxlan.c

index 889e0704c4c63922ccf5cf328fe6a2424f3d4223..b27374e302978ba1d8a339ac5fec5840a4f8d389 100644 (file)
@@ -36,6 +36,7 @@
 #include "pim_time.h"
 #include "pim_nht.h"
 #include "pim_oil.h"
+#include "pim_mlag.h"
 
 static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up);
 
index 8f7e1741e730d297fa286a50a8c7d8474558d8f9..6ef0290adf81751e3e33d99e89f031470c230d49 100644 (file)
@@ -921,6 +921,14 @@ uint32_t pim_up_mlag_local_cost(struct pim_upstream *up)
        if (!(pim_up_mlag_is_local(up)))
                return router->infinite_assert_metric.route_metric;
 
+       if ((up->rpf.source_nexthop.interface ==
+                               up->pim->vxlan.peerlink_rif) &&
+                       (up->rpf.source_nexthop.mrib_route_metric <
+                        (router->infinite_assert_metric.route_metric -
+                         PIM_UPSTREAM_MLAG_PEERLINK_PLUS_METRIC)))
+               return up->rpf.source_nexthop.mrib_route_metric +
+                       PIM_UPSTREAM_MLAG_PEERLINK_PLUS_METRIC;
+
        return up->rpf.source_nexthop.mrib_route_metric;
 }
 
index 1c1f18008338b204b714ad63c90098c26c486893..0e718a3c31d49b8b94f0446706bc856dd4e39662 100644 (file)
 #define PIM_UPSTREAM_FLAG_UNSET_SRC_NOCACHE(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE)
 #define PIM_UPSTREAM_FLAG_UNSET_USE_RPT(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_USE_RPT)
 
+/* The RPF cost is incremented by 10 if the RPF interface is the peerlink-rif.
+ * This is used to force the MLAG switch with the lowest cost to the RPF
+ * to become the MLAG DF.
+ */
+#define PIM_UPSTREAM_MLAG_PEERLINK_PLUS_METRIC 10
+
 enum pim_upstream_state {
        PIM_UPSTREAM_NOTJOINED,
        PIM_UPSTREAM_JOINED,
index 58d988e9200731a648207595dc015344356cc13d..abfea538e1efd95478e3cbe7f56e5b1b53069715 100644 (file)
@@ -477,13 +477,14 @@ static void pim_vxlan_orig_mr_del(struct pim_vxlan_sg *vxlan_sg)
 
 static void pim_vxlan_orig_mr_iif_update(struct hash_backet *backet, void *arg)
 {
-       struct interface *ifp = (struct interface *)arg;
+       struct interface *ifp;
        struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)backet->data;
        struct interface *old_iif = vxlan_sg->iif;
 
        if (!pim_vxlan_is_orig_mroute(vxlan_sg))
                return;
 
+       ifp = pim_vxlan_orig_mr_iif_get(vxlan_sg->pim);
        if (PIM_DEBUG_VXLAN)
                zlog_debug("vxlan SG %s iif changed from %s to %s",
                                vxlan_sg->sg_str,
@@ -895,7 +896,63 @@ static void pim_vxlan_set_default_iif(struct pim_instance *pim,
         */
        if (pim->vxlan.sg_hash)
                hash_iterate(pim->vxlan.sg_hash,
-                               pim_vxlan_orig_mr_iif_update, ifp);
+                               pim_vxlan_orig_mr_iif_update, NULL);
+}
+
+static void pim_vxlan_up_cost_update(struct pim_instance *pim,
+               struct pim_upstream *up,
+               struct interface *old_peerlink_rif)
+{
+       if (!PIM_UPSTREAM_FLAG_TEST_MLAG_VXLAN(up->flags))
+               return;
+
+       if (up->rpf.source_nexthop.interface &&
+                       ((up->rpf.source_nexthop.interface ==
+                         pim->vxlan.peerlink_rif) ||
+                        (up->rpf.source_nexthop.interface ==
+                         old_peerlink_rif))) {
+               if (PIM_DEBUG_VXLAN)
+                       zlog_debug("RPF cost adjust for %s on peerlink-rif (old: %s, new: %s) change",
+                                       up->sg_str,
+                                       old_peerlink_rif ?
+                                       old_peerlink_rif->name : "-",
+                                       pim->vxlan.peerlink_rif ?
+                                       pim->vxlan.peerlink_rif->name : "-");
+               pim_mlag_up_local_add(pim, up);
+       }
+}
+
+static void pim_vxlan_term_mr_cost_update(struct hash_backet *backet,
+               void *arg)
+{
+       struct interface *old_peerlink_rif = (struct interface *)arg;
+       struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)backet->data;
+       struct pim_upstream *up;
+       struct listnode *listnode;
+       struct pim_upstream *child;
+
+       if (pim_vxlan_is_orig_mroute(vxlan_sg))
+               return;
+
+       /* Lookup all XG and SG entries with RPF-interface peerlink_rif */
+       up = vxlan_sg->up;
+       if (!up)
+               return;
+
+       pim_vxlan_up_cost_update(vxlan_sg->pim, up,
+                       old_peerlink_rif);
+
+       for (ALL_LIST_ELEMENTS_RO(up->sources, listnode,
+                               child))
+               pim_vxlan_up_cost_update(vxlan_sg->pim, child,
+                               old_peerlink_rif);
+}
+
+static void pim_vxlan_sg_peerlink_rif_update(struct hash_backet *backet,
+               void *arg)
+{
+       pim_vxlan_orig_mr_iif_update(backet, NULL);
+       pim_vxlan_term_mr_cost_update(backet, arg);
 }
 
 static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim,
@@ -928,7 +985,7 @@ static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim,
         */
        if (pim->vxlan.sg_hash)
                hash_iterate(pim->vxlan.sg_hash,
-                               pim_vxlan_orig_mr_iif_update, ifp);
+                               pim_vxlan_sg_peerlink_rif_update, old_iif);
 }
 
 void pim_vxlan_add_vif(struct interface *ifp)