From 776c3e90c161ed085897258754477e3fd183b1d2 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 1 Jun 2018 19:26:53 -0400 Subject: [PATCH 1/9] lib: Add nexthop_cmp Add function to allow us to have a sorted order of nexthops. Signed-off-by: Donald Sharp --- lib/nexthop.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/nexthop.h | 1 + 2 files changed, 58 insertions(+) diff --git a/lib/nexthop.c b/lib/nexthop.c index 8e16e70590..2a65c4d546 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -36,6 +36,63 @@ DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop") DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label") +int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2) +{ + int ret; + uint32_t n1, n2; + + if (next1->vrf_id < next2->vrf_id) + return -1; + + if (next1->vrf_id > next2->vrf_id) + return 1; + + if (next1->type < next2->type) + return -1; + + if (next1->type > next2->type) + return 1; + + switch(next1->type) { + case NEXTHOP_TYPE_IPV4: + n1 = ntohl(next1->gate.ipv4.s_addr); + n2 = ntohl(next2->gate.ipv4.s_addr); + if (n1 < n2) + return -1; + if (n1 > n2) + return 1; + break; + case NEXTHOP_TYPE_IPV6: + ret = memcmp(&next1->gate, &next2->gate, sizeof(union g_addr)); + if (!ret) + return ret; + break; + case NEXTHOP_TYPE_IPV4_IFINDEX: + case NEXTHOP_TYPE_IPV6_IFINDEX: + ret = memcmp(&next1->gate, &next2->gate, sizeof(union g_addr)); + if (!ret) + return ret; + /* Intentional Fall-Through */ + case NEXTHOP_TYPE_IFINDEX: + if (next1->ifindex < next2->ifindex) + return -1; + + if (next1->ifindex > next2->ifindex) + return 1; + break; + case NEXTHOP_TYPE_BLACKHOLE: + if (next1->bh_type < next2->bh_type) + return -1; + + if (next1->bh_type > next2->bh_type) + return 1; + break; + } + + ret = memcmp(&next1->src, &next2->src, sizeof(union g_addr)); + return ret; +} + /* check if nexthops are same, non-recursive */ int nexthop_same_no_recurse(const struct nexthop *next1, const struct nexthop *next2) diff --git a/lib/nexthop.h b/lib/nexthop.h index 663acaeb69..58e8e0ebb6 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -139,6 +139,7 @@ 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 int nexthop_cmp(const struct nexthop *nh1, const struct nexthop *nh2); extern const char *nexthop_type_to_str(enum nexthop_types_t nh_type); extern int nexthop_same_no_recurse(const struct nexthop *next1, From ebc403dda50fda7735526798b13a35900f593b5c Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Tue, 14 May 2019 10:21:19 -0700 Subject: [PATCH 2/9] lib: Add nexthop labels cmp functions Add a function to compare nexthop labels. Signed-off-by: Stephen Worley --- lib/nexthop.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/nexthop.c b/lib/nexthop.c index 2a65c4d546..c616ea857e 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -36,6 +36,34 @@ 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) +{ + const struct mpls_label_stack *nhl1 = NULL; + const struct mpls_label_stack *nhl2 = NULL; + + nhl1 = nh1->nh_label; + nhl2 = nh2->nh_label; + + /* No labels is a match */ + if (!nhl1 && !nhl2) + return 0; + + if (nhl1 && !nhl2) + return 1; + + if (nhl2 && !nhl1) + return -1; + + if (nhl1->num_labels > nhl2->num_labels) + return 1; + + if (nhl1->num_labels < nhl2->num_labels) + return -1; + + return memcmp(nhl1->label, nhl2->label, nhl1->num_labels); +} + int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2) { int ret; From 89dc316029c9167189f258ed9b79fec155da41cb Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Tue, 14 May 2019 10:26:22 -0700 Subject: [PATCH 3/9] lib: Make labels_match function use labels_cmp Update the nexthop_labels_match() function to use nexthop_labels_cmp(). Signed-off-by: Stephen Worley --- lib/nexthop.c | 23 ++++------------------- lib/nexthop.h | 4 ++-- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/lib/nexthop.c b/lib/nexthop.c index c616ea857e..120968f436 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -206,27 +206,12 @@ const char *nexthop_type_to_str(enum nexthop_types_t nh_type) /* * Check if the labels match for the 2 nexthops specified. */ -int nexthop_labels_match(const struct nexthop *nh1, const struct nexthop *nh2) +bool nexthop_labels_match(const struct nexthop *nh1, const struct nexthop *nh2) { - const struct mpls_label_stack *nhl1, *nhl2; + if (nexthop_labels_cmp(nh1, nh2) != 0) + return false; - nhl1 = nh1->nh_label; - nhl2 = nh2->nh_label; - - /* No labels is a match */ - if (!nhl1 && !nhl2) - return 1; - - if (!nhl1 || !nhl2) - return 0; - - if (nhl1->num_labels != nhl2->num_labels) - return 0; - - if (memcmp(nhl1->label, nhl2->label, nhl1->num_labels)) - return 0; - - return 1; + return true; } struct nexthop *nexthop_new(void) diff --git a/lib/nexthop.h b/lib/nexthop.h index 58e8e0ebb6..1bc3055835 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -144,8 +144,8 @@ 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); extern int nexthop_same_no_recurse(const struct nexthop *next1, const struct nexthop *next2); -extern int nexthop_labels_match(const struct nexthop *nh1, - const struct nexthop *nh2); +extern bool nexthop_labels_match(const struct nexthop *nh1, + const struct nexthop *nh2); extern int nexthop_same_firsthop(struct nexthop *next1, struct nexthop *next2); extern const char *nexthop2str(const struct nexthop *nexthop, From f932ce865fa1edc91c1f16856682705d82d92d65 Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Tue, 14 May 2019 10:37:45 -0700 Subject: [PATCH 4/9] lib: nexthop-cmp return if gateways don't match Fix the cmp check the so that it returns the result if the gateways don't match. Signed-off-by: Stephen Worley --- lib/nexthop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/nexthop.c b/lib/nexthop.c index 120968f436..2f7ba7e3d0 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -92,13 +92,13 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2) break; case NEXTHOP_TYPE_IPV6: ret = memcmp(&next1->gate, &next2->gate, sizeof(union g_addr)); - if (!ret) + if (ret) return ret; break; case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV6_IFINDEX: ret = memcmp(&next1->gate, &next2->gate, sizeof(union g_addr)); - if (!ret) + if (ret) return ret; /* Intentional Fall-Through */ case NEXTHOP_TYPE_IFINDEX: From ff0e16daf981c4351db29a3b599b32cd4523b205 Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Tue, 14 May 2019 10:39:49 -0700 Subject: [PATCH 5/9] lib: Add labels_cmp to nexthop_cmp Add labels comparison to nexthop_cmp() as well. Signed-off-by: Stephen Worley --- lib/nexthop.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/nexthop.c b/lib/nexthop.c index 2f7ba7e3d0..0153fef3f7 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -66,8 +66,9 @@ static int nexthop_labels_cmp(const struct nexthop *nh1, int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2) { - int ret; - uint32_t n1, n2; + int ret = 0; + uint32_t n1 = 0; + uint32_2 n2 = 0; if (next1->vrf_id < next2->vrf_id) return -1; @@ -81,7 +82,7 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2) if (next1->type > next2->type) return 1; - switch(next1->type) { + switch (next1->type) { case NEXTHOP_TYPE_IPV4: n1 = ntohl(next1->gate.ipv4.s_addr); n2 = ntohl(next2->gate.ipv4.s_addr); @@ -118,6 +119,10 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2) } ret = memcmp(&next1->src, &next2->src, sizeof(union g_addr)); + if (ret) + return ret; + + ret = nexthop_labels_cmp(next1, next2); return ret; } From 2ed74b933dbf980422cc5d4da76b168297e133e6 Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Tue, 14 May 2019 10:41:40 -0700 Subject: [PATCH 6/9] lib: Update nexthop_same to use nexthop_cmp Simplify the code a bit by making nexthop_same() just use nexthop_cmp() internally. Signed-off-by: Stephen Worley --- lib/nexthop.c | 41 +++-------------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/lib/nexthop.c b/lib/nexthop.c index 0153fef3f7..7cc77a7674 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -68,7 +68,7 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2) { int ret = 0; uint32_t n1 = 0; - uint32_2 n2 = 0; + uint32_t n2 = 0; if (next1->vrf_id < next2->vrf_id) return -1; @@ -255,45 +255,10 @@ bool nexthop_same(const struct nexthop *nh1, const struct nexthop *nh2) if (nh1 == nh2) return true; - if (nh1->vrf_id != nh2->vrf_id) + if (nexthop_cmp(nh1, nh2) != 0) return false; - if (nh1->type != nh2->type) - return false; - - switch (nh1->type) { - case NEXTHOP_TYPE_IFINDEX: - if (nh1->ifindex != nh2->ifindex) - return false; - break; - case NEXTHOP_TYPE_IPV4: - if (nh1->gate.ipv4.s_addr != nh2->gate.ipv4.s_addr) - return false; - break; - case NEXTHOP_TYPE_IPV4_IFINDEX: - if (nh1->gate.ipv4.s_addr != nh2->gate.ipv4.s_addr) - return false; - if (nh1->ifindex != nh2->ifindex) - return false; - break; - case NEXTHOP_TYPE_IPV6: - if (memcmp(&nh1->gate.ipv6, &nh2->gate.ipv6, 16)) - return false; - break; - case NEXTHOP_TYPE_IPV6_IFINDEX: - if (memcmp(&nh1->gate.ipv6, &nh2->gate.ipv6, 16)) - return false; - if (nh1->ifindex != nh2->ifindex) - return false; - break; - case NEXTHOP_TYPE_BLACKHOLE: - if (nh1->bh_type != nh2->bh_type) - return false; - break; - } - - /* Compare labels too (if present) */ - return (!!nexthop_labels_match(nh1, nh2)); + return true; } /* Update nexthop with label information. */ From 78fba41bd810ce6e8976077c37644e9d23b9f69d Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Tue, 14 May 2019 10:48:26 -0700 Subject: [PATCH 7/9] lib,zebra,bgpd: Remove nexthop_same_no_recurse() The functions nexthop_same() does not check the resolved nexthops so I don't think this function is even needed anymore. Signed-off-by: Stephen Worley --- bgpd/bgp_nht.c | 3 +-- lib/nexthop.c | 36 ------------------------------------ lib/nexthop.h | 2 -- zebra/zebra_rib.c | 2 +- 4 files changed, 2 insertions(+), 41 deletions(-) diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 7e721db49d..fdfa15b445 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -474,8 +474,7 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id) continue; for (oldnh = bnc->nexthop; oldnh; oldnh = oldnh->next) - if (nexthop_same_no_recurse(oldnh, nexthop) && - nexthop_labels_match(oldnh, nexthop)) + if (nexthop_same(oldnh, nexthop)) break; if (!oldnh) diff --git a/lib/nexthop.c b/lib/nexthop.c index 7cc77a7674..123684b512 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -126,42 +126,6 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2) return ret; } -/* check if nexthops are same, non-recursive */ -int nexthop_same_no_recurse(const struct nexthop *next1, - const struct nexthop *next2) -{ - if (next1->type != next2->type) - return 0; - - switch (next1->type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - if (!IPV4_ADDR_SAME(&next1->gate.ipv4, &next2->gate.ipv4)) - return 0; - if (next1->ifindex && (next1->ifindex != next2->ifindex)) - return 0; - break; - case NEXTHOP_TYPE_IFINDEX: - if (next1->ifindex != next2->ifindex) - return 0; - break; - case NEXTHOP_TYPE_IPV6: - if (!IPV6_ADDR_SAME(&next1->gate.ipv6, &next2->gate.ipv6)) - return 0; - break; - case NEXTHOP_TYPE_IPV6_IFINDEX: - if (!IPV6_ADDR_SAME(&next1->gate.ipv6, &next2->gate.ipv6)) - return 0; - if (next1->ifindex != next2->ifindex) - return 0; - break; - default: - /* do nothing */ - break; - } - return 1; -} - int nexthop_same_firsthop(struct nexthop *next1, struct nexthop *next2) { int type1 = NEXTHOP_FIRSTHOPTYPE(next1->type); diff --git a/lib/nexthop.h b/lib/nexthop.h index 1bc3055835..48efc762c5 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -142,8 +142,6 @@ extern bool nexthop_same(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); -extern int nexthop_same_no_recurse(const struct nexthop *next1, - const struct nexthop *next2); extern bool nexthop_labels_match(const struct nexthop *nh1, const struct nexthop *nh2); extern int nexthop_same_firsthop(struct nexthop *next1, struct nexthop *next2); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 8f27316669..297fc7e7e7 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2855,7 +2855,7 @@ 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_no_recurse(rtnh, nh)) { + if (nexthop_same(rtnh, nh)) { same = re; break; } From 24cfec84188bc8f69eef873302824dc6f49b5339 Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Wed, 22 May 2019 15:17:21 -0400 Subject: [PATCH 8/9] lib: Explicitly cmp gateway and source based on AF Refactor the gatway and source nexthop comparision into a common code path that compares them explicitly based on their address family. Signed-off-by: Stephen Worley --- lib/nexthop.c | 51 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/lib/nexthop.c b/lib/nexthop.c index 123684b512..28a1170444 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -64,11 +64,45 @@ 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) +{ + int ret = 0; + + switch (type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + ret = IPV4_ADDR_CMP(&addr1->ipv4, &addr2->ipv4); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + ret = IPV6_ADDR_CMP(&addr1->ipv6, &addr2->ipv6); + break; + case NEXTHOP_TYPE_IFINDEX: + case NEXTHOP_TYPE_BLACKHOLE: + /* No addr here */ + break; + } + + return ret; +} + +static int nexthop_gateway_cmp(const struct nexthop *nh1, + const struct nexthop *nh2) +{ + return nexthop_g_addr_cmp(nh1->type, &nh1->gate, &nh2->gate); +} + +static int nexthop_source_cmp(const struct nexthop *nh1, + const struct nexthop *nh2) +{ + return nexthop_g_addr_cmp(nh1->type, &nh1->src, &nh2->src); +} + int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2) { int ret = 0; - uint32_t n1 = 0; - uint32_t n2 = 0; if (next1->vrf_id < next2->vrf_id) return -1; @@ -84,21 +118,14 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2) switch (next1->type) { case NEXTHOP_TYPE_IPV4: - n1 = ntohl(next1->gate.ipv4.s_addr); - n2 = ntohl(next2->gate.ipv4.s_addr); - if (n1 < n2) - return -1; - if (n1 > n2) - return 1; - break; case NEXTHOP_TYPE_IPV6: - ret = memcmp(&next1->gate, &next2->gate, sizeof(union g_addr)); + ret = nexthop_gateway_cmp(next1, next2); if (ret) return ret; break; case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV6_IFINDEX: - ret = memcmp(&next1->gate, &next2->gate, sizeof(union g_addr)); + ret = nexthop_gateway_cmp(next1, next2); if (ret) return ret; /* Intentional Fall-Through */ @@ -118,7 +145,7 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2) break; } - ret = memcmp(&next1->src, &next2->src, sizeof(union g_addr)); + ret = nexthop_source_cmp(next1, next2); if (ret) return ret; From a5a2d802d7f4b44423dedf3f7876bdb28aebe844 Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Wed, 22 May 2019 15:34:07 -0400 Subject: [PATCH 9/9] 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 | 73 +++++++++++++++++++++++++++++++++-------------- lib/nexthop.h | 2 ++ zebra/zebra_rib.c | 6 +++- 3 files changed, 58 insertions(+), 23 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, +static int _nexthop_gateway_cmp(const struct nexthop *nh1, + const struct nexthop *nh2) +{ + return _nexthop_g_addr_cmp(nh1->type, &nh1->gate, &nh2->gate); +} + +static int _nexthop_source_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->src, &nh2->src); } -static int nexthop_source_cmp(const struct nexthop *nh1, - const struct nexthop *nh2) -{ - 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; }