From 06302ecb8808e1f59bdbd0daf41f48d6c2378adf Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 21 Jul 2021 13:55:52 -0400 Subject: [PATCH] zebra: On client shutdown cleanup any vrf labels associated with it When a vrf label is created by a client and the client disconnects we should clean up any vrf labels associated with that client. eva# show mpls table Inbound Label Type Nexthop Outbound Label ----------------------------------------------- 1000 SHARP RED - eva# exit sharpd@eva ~/f/zebra (label_destruction)> ps -ef | grep frr root 4017793 1 0 13:57 ? 00:00:00 /usr/lib/frr/watchfrr -d -F datacenter --log file:/var/log/frr/watchfrr.log --log-level debug zebra bgpd ospfd isisd pimd eigrpd sharpd staticd frr 4017824 1 0 13:57 ? 00:00:00 /usr/lib/frr/zebra -d -F datacenter --log file:/tmp/zebra.log -r --graceful_restart 60 -A 127.0.0.1 -s 90000000 frr 4017829 1 0 13:57 ? 00:00:00 /usr/lib/frr/bgpd -d -F datacenter -M rpki -A 127.0.0.1 frr 4017836 1 0 13:57 ? 00:00:00 /usr/lib/frr/ospfd -d -F datacenter -A 127.0.0.1 frr 4017839 1 0 13:57 ? 00:00:00 /usr/lib/frr/isisd -d -F datacenter -A 127.0.0.1 frr 4017842 1 0 13:57 ? 00:00:00 /usr/lib/frr/pimd -d -F datacenter -A 127.0.0.1 frr 4017865 1 0 13:57 ? 00:00:00 /usr/lib/frr/eigrpd -d -F datacenter -A 127.0.0.1 frr 4017869 1 0 13:57 ? 00:00:00 /usr/lib/frr/sharpd -d -F datacenter -A 127.0.0.1 frr 4017888 1 0 13:57 ? 00:00:00 /usr/lib/frr/staticd -d -F datacenter -A 127.0.0.1 sharpd 4018624 3938423 0 14:02 pts/10 00:00:00 grep --color=auto frr sharpd@eva ~/f/zebra (label_destruction)> sudo kill -9 4017869 sharpd@eva ~/f/zebra (label_destruction)> sudo vtysh -c "show mpls table" sharpd@eva ~/f/zebra (label_destruction)> Fixes: #1787 Signed-off-by: Donald Sharp --- zebra/zapi_msg.c | 2 ++ zebra/zebra_mpls.c | 34 ++++++++++++++++++++++++++++++++++ zebra/zebra_mpls.h | 6 ++++++ zebra/zebra_vrf.h | 1 + zebra/zserv.c | 2 ++ 5 files changed, 45 insertions(+) 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 @@ -3931,6 +3931,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. 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(