summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2022-12-28 15:49:53 +0100
committerDmytro Shytyi <dmytro.shytyi@6wind.com>2024-06-07 12:33:47 +0200
commitcc25d7bd92bdf80cf149b45158fb14d3b57aea28 (patch)
tree9ee629c990eb8e82e5dd40d5b48687d69a1cc72b
parent449e80ab743fa51ee60f8f7c535fa952f965fc5b (diff)
zebra, lib: upon lsp install, iterate nexthop accordingly
There are two ways of iterating over nexthops of a given route entry. - Either only the main nexthop are taken into account (which is the case today when attempting to install an LSP entry on a BGP connected labeled route. - Or by taking into account nexthops that are resolved and linked in nexthop->resolved of the previous nexthop which has RECURSIVE flag set. This second case has to be taken into account in the case where recursive routes may be used to install an LSP entry. Introduce a new API in nexthop that will parse over the appropriate nexthop, if the nexthop-resolution flag is turned on or not on the given VRF. Use that API in the lsp_install() function so as to walk over the appropriate nexthops. Co-developed-by: Dmytro Shytyi <dmytro.shytyi@6wind.com> Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com> Signed-off-by: Dmytro Shytyi <dmytro.shytyi@6wind.com>
-rw-r--r--lib/nexthop.c9
-rw-r--r--lib/nexthop.h2
-rw-r--r--zebra/zebra_mpls.c27
3 files changed, 32 insertions, 6 deletions
diff --git a/lib/nexthop.c b/lib/nexthop.c
index 26c338256f..d6c654a692 100644
--- a/lib/nexthop.c
+++ b/lib/nexthop.c
@@ -699,6 +699,15 @@ struct nexthop *nexthop_next(const struct nexthop *nexthop)
return NULL;
}
+struct nexthop *nexthop_next_resolution(const struct nexthop *nexthop,
+ bool nexthop_resolution)
+{
+ if (nexthop_resolution)
+ return nexthop_next(nexthop);
+ /* no resolution attempt */
+ return nexthop->next;
+}
+
/* Return the next nexthop in the tree that is resolved and active */
struct nexthop *nexthop_next_active_resolved(const struct nexthop *nexthop)
{
diff --git a/lib/nexthop.h b/lib/nexthop.h
index 27073b948d..457c81972e 100644
--- a/lib/nexthop.h
+++ b/lib/nexthop.h
@@ -223,6 +223,8 @@ extern bool nexthop_labels_match(const struct nexthop *nh1,
extern const char *nexthop2str(const struct nexthop *nexthop,
char *str, int size);
extern struct nexthop *nexthop_next(const struct nexthop *nexthop);
+extern struct nexthop *nexthop_next_resolution(const struct nexthop *nexthop,
+ bool nexthop_resolution);
extern struct nexthop *
nexthop_next_active_resolved(const struct nexthop *nexthop);
extern unsigned int nexthop_level(const struct nexthop *nexthop);
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index ca93ce8fbd..17fe455741 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -161,12 +161,14 @@ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
enum lsp_types_t lsp_type;
char buf[BUFSIZ];
int added, changed;
+ bool zvrf_nexthop_resolution;
/* Lookup table. */
lsp_table = zvrf->lsp_table;
if (!lsp_table)
return -1;
+ zvrf_nexthop_resolution = zvrf->zebra_mpls_fec_nexthop_resolution;
lsp_type = lsp_type_from_re_type(re->type);
added = changed = 0;
@@ -180,13 +182,20 @@ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
* the label advertised by the recursive nexthop (plus we don't have the
* logic yet to push multiple labels).
*/
- for (nexthop = re->nhe->nhg.nexthop;
- nexthop; nexthop = nexthop->next) {
- /* Skip inactive and recursive entries. */
- if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+ nexthop = re->nhe->nhg.nexthop;
+ while (nexthop) {
+ if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) {
+ nexthop =
+ nexthop_next_resolution(nexthop,
+ zvrf_nexthop_resolution);
continue;
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+ }
+ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) {
+ nexthop =
+ nexthop_next_resolution(nexthop,
+ zvrf_nexthop_resolution);
continue;
+ }
nhlfe = nhlfe_find(&lsp->nhlfe_list, lsp_type,
nexthop->type, &nexthop->gate,
@@ -194,9 +203,13 @@ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
if (nhlfe) {
/* Clear deleted flag (in case it was set) */
UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED);
- if (nexthop_labels_match(nhlfe->nexthop, nexthop))
+ if (nexthop_labels_match(nhlfe->nexthop, nexthop)) {
/* No change */
+ nexthop =
+ nexthop_next_resolution(nexthop,
+ zvrf_nexthop_resolution);
continue;
+ }
if (IS_ZEBRA_DEBUG_MPLS) {
@@ -234,6 +247,8 @@ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
SET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED);
added++;
}
+ nexthop = nexthop_next_resolution(nexthop,
+ zvrf_nexthop_resolution);
}
/* Queue LSP for processing if necessary. If no NHLFE got added (special