summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zebra/zapi_msg.c2
-rw-r--r--zebra/zebra_mpls.c34
-rw-r--r--zebra/zebra_mpls.h6
-rw-r--r--zebra/zebra_vrf.h1
-rw-r--r--zebra/zserv.c2
5 files changed, 45 insertions, 0 deletions
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index a53e388062..5b2b1cc26f 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -3107,6 +3107,8 @@ static void zread_vrf_label(ZAPI_HANDLER_ARGS)
}
zvrf->label[afi] = nlabel;
+ zvrf->label_proto[afi] = client->proto;
+
stream_failure:
return;
}
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index a2d1513ce4..66d2d6b4ba 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -3932,6 +3932,40 @@ void zebra_mpls_cleanup_tables(struct zebra_vrf *zvrf)
}
/*
+ * When a vrf label is assigned and the client goes away
+ * we should cleanup the vrf labels associated with
+ * that zclient.
+ */
+void zebra_mpls_client_cleanup_vrf_label(uint8_t proto)
+{
+ struct vrf *vrf;
+ struct zebra_vrf *def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
+
+ if (def_zvrf == NULL)
+ return;
+
+ RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
+ struct zebra_vrf *zvrf = vrf->info;
+ afi_t afi;
+
+ if (!zvrf)
+ continue;
+
+ for (afi = AFI_IP; afi < AFI_MAX; afi++) {
+ if (zvrf->label_proto[afi] == proto
+ && zvrf->label[afi] != MPLS_LABEL_NONE)
+ lsp_uninstall(def_zvrf, zvrf->label[afi]);
+
+ /*
+ * Cleanup data structures by fiat
+ */
+ zvrf->label_proto[afi] = 0;
+ zvrf->label[afi] = MPLS_LABEL_NONE;
+ }
+ }
+}
+
+/*
* Called upon process exiting, need to delete LSP forwarding
* entries from the kernel.
* NOTE: Currently supported only for default VRF.
diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h
index 7059d393ed..5195b2f14f 100644
--- a/zebra/zebra_mpls.h
+++ b/zebra/zebra_mpls.h
@@ -416,6 +416,12 @@ void zebra_mpls_init(void);
*/
void zebra_mpls_vty_init(void);
+/*
+ * When cleaning up a client connection ensure that there are no
+ * vrf labels that need cleaning up too
+ */
+void zebra_mpls_client_cleanup_vrf_label(uint8_t proto);
+
/* Inline functions. */
/*
diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h
index 57dd0c20ad..f32f09850b 100644
--- a/zebra/zebra_vrf.h
+++ b/zebra/zebra_vrf.h
@@ -105,6 +105,7 @@ struct zebra_vrf {
/* MPLS Label to handle L3VPN <-> vrf popping */
mpls_label_t label[AFI_MAX];
+ uint8_t label_proto[AFI_MAX];
/* MPLS static LSP config table */
struct hash *slsp_table;
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 1d94fcae6b..e4a48093f7 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -595,6 +595,8 @@ static void zserv_client_free(struct zserv *client)
close(client->sock);
if (DYNAMIC_CLIENT_GR_DISABLED(client)) {
+ zebra_mpls_client_cleanup_vrf_label(client->proto);
+
nroutes = rib_score_proto(client->proto,
client->instance);
zlog_notice(