From f5ca329b2d5a2f19b583b7732950256c788db34c Mon Sep 17 00:00:00 2001 From: Hiroki Shirokura Date: Sun, 5 Sep 2021 10:05:53 +0000 Subject: [PATCH] zebra: implement srv6 locator add/delete notification via ZAPI Signed-off-by: Hiroki Shirokura --- zebra/zapi_msg.c | 25 +++++++++++++++++++++++++ zebra/zebra_srv6.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 6666b3525e..07d171b58f 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1137,6 +1137,31 @@ static int zsend_table_manager_connect_response(struct zserv *client, return zserv_send_message(client, s); } +/* SRv6 locator add notification from zebra daemon. */ +int zsend_zebra_srv6_locator_add(struct zserv *client, struct srv6_locator *loc) +{ + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); + + zclient_create_header(s, ZEBRA_SRV6_LOCATOR_ADD, VRF_DEFAULT); + zapi_srv6_locator_encode(s, loc); + stream_putw_at(s, 0, stream_get_endp(s)); + + return zserv_send_message(client, s); +} + +/* SRv6 locator delete notification from zebra daemon. */ +int zsend_zebra_srv6_locator_delete(struct zserv *client, + struct srv6_locator *loc) +{ + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); + + zclient_create_header(s, ZEBRA_SRV6_LOCATOR_DELETE, VRF_DEFAULT); + zapi_srv6_locator_encode(s, loc); + stream_putw_at(s, 0, stream_get_endp(s)); + + return zserv_send_message(client, s); +} + /* Inbound message handling ------------------------------------------------ */ const int cmd2type[] = { diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index b11331a180..ad99ae1786 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -106,15 +106,60 @@ void zebra_srv6_locator_add(struct srv6_locator *locator) { struct zebra_srv6 *srv6 = zebra_srv6_get_default(); struct srv6_locator *tmp; + struct listnode *node; + struct zserv *client; tmp = zebra_srv6_locator_lookup(locator->name); if (!tmp) listnode_add(srv6->locators, locator); + + /* + * Notify new locator info to zclients. + * + * The srv6 locators and their prefixes are managed by zserv(zebra). + * And an actual configuration the srv6 sid in the srv6 locator is done + * by zclient(bgpd, isisd, etc). The configuration of each locator + * allocation and specify it by zserv and zclient should be + * asynchronous. For that, zclient should be received the event via + * ZAPI when a srv6 locator is added on zebra. + * Basically, in SRv6, adding/removing SRv6 locators is performed less + * frequently than adding rib entries, so a broad to all zclients will + * not degrade the overall performance of FRRouting. + */ + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) + zsend_zebra_srv6_locator_add(client, locator); } void zebra_srv6_locator_delete(struct srv6_locator *locator) { + struct listnode *n; + struct srv6_locator_chunk *c; struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct zserv *client; + + /* + * Notify deleted locator info to zclients if needed. + * + * zclient(bgpd,isisd,etc) allocates a sid from srv6 locator chunk and + * uses it for its own purpose. For example, in the case of BGP L3VPN, + * the SID assigned to vpn unicast rib will be given. + * And when the locator is deleted by zserv(zebra), those SIDs need to + * be withdrawn. The zclient must initiate the withdrawal of the SIDs + * by ZEBRA_SRV6_LOCATOR_DELETE, and this notification is sent to the + * owner of each chunk. + */ + for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, n, c)) { + if (c->proto == ZEBRA_ROUTE_SYSTEM) + continue; + client = zserv_find_client(c->proto, c->instance); + if (!client) { + zlog_warn( + "%s: Not found zclient(proto=%u, instance=%u).", + __func__, c->proto, c->instance); + continue; + } + zsend_zebra_srv6_locator_delete(client, locator); + } listnode_delete(srv6->locators, locator); }