summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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