diff --git a/zebra/interface.c b/zebra/interface.c index 00c8781248f8..0b7cfc371355 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -5380,6 +5380,23 @@ int ipv6_address_configured(struct interface *ifp) return 0; } +void mpls_interface_update(struct interface *ifp, uint8_t mpls) +{ + struct zebra_if *zif; + + if (!ifp) + return; + zif = ifp->info; + if (zif->mpls_config != IF_ZEBRA_DATA_AUTO) + return; + if (zif->mpls && mpls == IF_ZEBRA_DATA_ON) + return; + if (!zif->mpls && mpls == IF_ZEBRA_DATA_OFF) + return; + zif->mpls_dynamic = mpls; + dplane_intf_mpls_modify_state(ifp, mpls); +} + static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp, const char *addr_str, const char *peer_str, const char *label) diff --git a/zebra/interface.h b/zebra/interface.h index f0a0ac990b2d..deb14667823c 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -117,6 +117,9 @@ struct zebra_if { /* MPLS configuration */ uint8_t mpls_config; + /* MPLS dynamic configuration - when mpls_config is auto */ + uint8_t mpls_dynamic; + /* Linkdown status */ bool linkdown, linkdownv6; @@ -334,6 +337,7 @@ extern void zebra_l2_map_slave_to_bond(struct zebra_if *zif, vrf_id_t vrf); extern void zebra_l2_unmap_slave_from_bond(struct zebra_if *zif); extern const char *zebra_protodown_rc_str(uint32_t protodown_rc, char *pd_buf, uint32_t pd_buf_len); +extern void mpls_interface_update(struct interface *ifp, uint8_t mpls); void zebra_if_dplane_result(struct zebra_dplane_ctx *ctx); extern void if_mpls_set_default(struct zebra_if *zif); diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 761eafeb1375..2383f6aa8cdf 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1755,6 +1755,7 @@ static bool zapi_read_nexthops(struct zserv *client, struct prefix *p, char nhbuf[NEXTHOP_STRLEN]; char labelbuf[MPLS_LABEL_STRLEN]; struct zapi_nexthop *api_nh = &nhops[i]; + struct interface *ifp; /* Convert zapi nexthop */ nexthop = nexthop_from_zapi(api_nh, flags, p, backup_nh_num); @@ -1791,7 +1792,9 @@ static bool zapi_read_nexthops(struct zserv *client, struct prefix *p, && api_nh->type != NEXTHOP_TYPE_IFINDEX && api_nh->type != NEXTHOP_TYPE_BLACKHOLE && api_nh->label_num > 0) { - + ifp = if_lookup_by_index(nexthop->ifindex, + nexthop->vrf_id); + mpls_interface_update(ifp, IF_ZEBRA_DATA_ON); /* If label type was passed, use it */ if (api_nh->label_type) label_type = api_nh->label_type; @@ -3182,16 +3185,19 @@ static void zread_vrf_label(ZAPI_HANDLER_ARGS) } } - if (really_remove) + if (really_remove) { mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label[afi], NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex, false /*backup*/); + mpls_interface_update(ifp, IF_ZEBRA_DATA_OFF); + } } if (nlabel != MPLS_LABEL_NONE) { mpls_label_t out_label = MPLS_LABEL_IMPLICIT_NULL; mpls_lsp_install(def_zvrf, ltype, nlabel, 1, &out_label, NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); + mpls_interface_update(ifp, IF_ZEBRA_DATA_ON); } zvrf->label[afi] = nlabel; diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 15e36acda8c3..a08c0de974a4 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -3111,6 +3111,11 @@ lsp_add_nhlfe(struct zebra_lsp *lsp, enum lsp_types_t type, if (!nhlfe) return NULL; + if (num_out_labels) + mpls_interface_update(if_lookup_by_index(ifindex, + vrf_id), + IF_ZEBRA_DATA_ON); + if (IS_ZEBRA_DEBUG_MPLS) { char buf2[MPLS_LABEL_STRLEN]; diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 93758cca2017..e5ce05b05847 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -2385,6 +2385,14 @@ static int nexthop_active(struct nexthop *nexthop, struct nhg_hash_entry *nhe, * tree. */ + if (match && match->nhe->nhg.nexthop && + match->nhe->nhg.nexthop->ifindex != IFINDEX_INTERNAL && + nexthop->type != NEXTHOP_TYPE_BLACKHOLE && + nexthop->nh_label && nexthop->nh_label->num_labels) { + ifp = if_lookup_by_index(match->nhe->nhg.nexthop->ifindex, + nexthop->vrf_id); + mpls_interface_update(ifp, IF_ZEBRA_DATA_ON); + } /* If the candidate match's type is considered "connected", * we consider it first. */