From a5a2d802d7f4b44423dedf3f7876bdb28aebe844 Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Wed, 22 May 2019 15:34:07 -0400 Subject: [PATCH] lib,zebra,bgpd,pbrd: Compare nexthops without labels 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 --- lib/nexthop.c | 69 +++++++++++++++++++++++++++++++++-------------- lib/nexthop.h | 2 ++ zebra/zebra_rib.c | 6 ++++- 3 files changed, 56 insertions(+), 21 deletions(-) diff --git a/lib/nexthop.c b/lib/nexthop.c index 28a1170444..57a2f1daaa 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -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) diff --git a/lib/nexthop.h b/lib/nexthop.h index 48efc762c5..5b6c12d4ef 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -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); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 297fc7e7e7..b44ed3543f 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -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; } -- 2.39.5