]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib,zebra,bgpd,pbrd: Compare nexthops without labels
authorStephen Worley <sworley@cumulusnetworks.com>
Wed, 22 May 2019 19:34:07 +0000 (15:34 -0400)
committerStephen Worley <sworley@cumulusnetworks.com>
Thu, 23 May 2019 16:21:15 +0000 (12:21 -0400)
Allow label ignoring when comparing nexthops. Specifically,
add another functon nexthop_same_no_labels() that shares
a path with nexthop_same() but doesn't check labels.

rib_delete() needs to ignore labels in this case.

Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
lib/nexthop.c
lib/nexthop.h
zebra/zebra_rib.c

index 28a11704447569348d3079556044e56d560b332c..57a2f1daaaec4fe0a222253c2f77472db353a43f 100644 (file)
@@ -36,8 +36,8 @@
 DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop")
 DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label")
 
-static int nexthop_labels_cmp(const struct nexthop *nh1,
-                             const struct nexthop *nh2)
+static int _nexthop_labels_cmp(const struct nexthop *nh1,
+                              const struct nexthop *nh2)
 {
        const struct mpls_label_stack *nhl1 = NULL;
        const struct mpls_label_stack *nhl2 = NULL;
@@ -64,9 +64,9 @@ static int nexthop_labels_cmp(const struct nexthop *nh1,
        return memcmp(nhl1->label, nhl2->label, nhl1->num_labels);
 }
 
-static int nexthop_g_addr_cmp(enum nexthop_types_t type,
-                             const union g_addr *addr1,
-                             const union g_addr *addr2)
+static int _nexthop_g_addr_cmp(enum nexthop_types_t type,
+                              const union g_addr *addr1,
+                              const union g_addr *addr2)
 {
        int ret = 0;
 
@@ -88,19 +88,20 @@ static int nexthop_g_addr_cmp(enum nexthop_types_t type,
        return ret;
 }
 
-static int nexthop_gateway_cmp(const struct nexthop *nh1,
-                              const struct nexthop *nh2)
+static int _nexthop_gateway_cmp(const struct nexthop *nh1,
+                               const struct nexthop *nh2)
 {
-       return nexthop_g_addr_cmp(nh1->type, &nh1->gate, &nh2->gate);
+       return _nexthop_g_addr_cmp(nh1->type, &nh1->gate, &nh2->gate);
 }
 
-static int nexthop_source_cmp(const struct nexthop *nh1,
-                             const struct nexthop *nh2)
+static int _nexthop_source_cmp(const struct nexthop *nh1,
+                              const struct nexthop *nh2)
 {
-       return nexthop_g_addr_cmp(nh1->type, &nh1->src, &nh2->src);
+       return _nexthop_g_addr_cmp(nh1->type, &nh1->src, &nh2->src);
 }
 
-int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2)
+static int _nexthop_cmp_no_labels(const struct nexthop *next1,
+                                 const struct nexthop *next2)
 {
        int ret = 0;
 
@@ -119,14 +120,14 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2)
        switch (next1->type) {
        case NEXTHOP_TYPE_IPV4:
        case NEXTHOP_TYPE_IPV6:
-               ret = nexthop_gateway_cmp(next1, next2);
-               if (ret)
+               ret = _nexthop_gateway_cmp(next1, next2);
+               if (ret != 0)
                        return ret;
                break;
        case NEXTHOP_TYPE_IPV4_IFINDEX:
        case NEXTHOP_TYPE_IPV6_IFINDEX:
-               ret = nexthop_gateway_cmp(next1, next2);
-               if (ret)
+               ret = _nexthop_gateway_cmp(next1, next2);
+               if (ret != 0)
                        return ret;
                /* Intentional Fall-Through */
        case NEXTHOP_TYPE_IFINDEX:
@@ -145,11 +146,21 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2)
                break;
        }
 
-       ret = nexthop_source_cmp(next1, next2);
-       if (ret)
+       ret = _nexthop_source_cmp(next1, next2);
+
+       return ret;
+}
+
+int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2)
+{
+       int ret = 0;
+
+       ret = _nexthop_cmp_no_labels(next1, next2);
+       if (ret != 0)
                return ret;
 
-       ret = nexthop_labels_cmp(next1, next2);
+       ret = _nexthop_labels_cmp(next1, next2);
+
        return ret;
 }
 
@@ -204,7 +215,7 @@ const char *nexthop_type_to_str(enum nexthop_types_t nh_type)
  */
 bool nexthop_labels_match(const struct nexthop *nh1, const struct nexthop *nh2)
 {
-       if (nexthop_labels_cmp(nh1, nh2) != 0)
+       if (_nexthop_labels_cmp(nh1, nh2) != 0)
                return false;
 
        return true;
@@ -252,6 +263,24 @@ bool nexthop_same(const struct nexthop *nh1, const struct nexthop *nh2)
        return true;
 }
 
+bool nexthop_same_no_labels(const struct nexthop *nh1,
+                           const struct nexthop *nh2)
+{
+       if (nh1 && !nh2)
+               return false;
+
+       if (!nh1 && nh2)
+               return false;
+
+       if (nh1 == nh2)
+               return true;
+
+       if (_nexthop_cmp_no_labels(nh1, nh2) != 0)
+               return false;
+
+       return true;
+}
+
 /* Update nexthop with label information. */
 void nexthop_add_labels(struct nexthop *nexthop, enum lsp_types_t type,
                        uint8_t num_labels, mpls_label_t *label)
index 48efc762c55e14b0b320acdc57a03076fb1ca36a..5b6c12d4ef504005341f45c9c886c8c5f2a7f87f 100644 (file)
@@ -139,6 +139,8 @@ void nexthop_del_labels(struct nexthop *);
 uint32_t nexthop_hash(const struct nexthop *nexthop);
 
 extern bool nexthop_same(const struct nexthop *nh1, const struct nexthop *nh2);
+extern bool nexthop_same_no_labels(const struct nexthop *nh1,
+                                  const struct nexthop *nh2);
 extern int nexthop_cmp(const struct nexthop *nh1, const struct nexthop *nh2);
 
 extern const char *nexthop_type_to_str(enum nexthop_types_t nh_type);
index 297fc7e7e775cf819595d8e2d2920be920186c90..b44ed3543f9c5d0a715e414ca583952d044af9b2 100644 (file)
@@ -2855,7 +2855,11 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                                break;
                        }
                        for (ALL_NEXTHOPS(re->ng, rtnh))
-                               if (nexthop_same(rtnh, nh)) {
+                               /*
+                                * No guarantee all kernel send nh with labels
+                                * on delete.
+                                */
+                               if (nexthop_same_no_labels(rtnh, nh)) {
                                        same = re;
                                        break;
                                }