From 6e68a08484bf8f5c79f041ce8c103ce42abc2e7f Mon Sep 17 00:00:00 2001 From: Hiroki Shirokura Date: Wed, 9 Dec 2020 18:52:17 +0900 Subject: zebra: ZAPI add new api to manipulate srv6-locator (step2) This commit is a part of #5853 works that add new ZAPI to configure SRv6 locator which manages chunk prefix for SRv6 SID IPv6 address for each routing protocol daemons. NEW-ZAPIs: * ZEBRA_SRV6_LOCATOR_ADD * ZEBRA_SRV6_LOCATOR_DELETE * ZEBRA_SRV6_MANAGER_CONNECT * ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK * ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK Zclient can connect to zebra's srv6-manager with ZEBRA_SRV6_MANAGER_CONNECT api like a label-manager. Then zclient uses ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK to allocated dedicated locator chunk for it's routing protocol. Zebra works for only prefix reservation and distribute the ownership of the locator chunks for zcliens. Then, zclient installs SRv6 function with ZEBRA_ROUTE_ADD api with nh_seg6local_* fields. This feature is already implemented by another PR(#7680). Signed-off-by: Hiroki Shirokura --- zebra/zebra_srv6.c | 349 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 349 insertions(+) create mode 100644 zebra/zebra_srv6.c (limited to 'zebra/zebra_srv6.c') diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c new file mode 100644 index 0000000000..b4b691e8e0 --- /dev/null +++ b/zebra/zebra_srv6.c @@ -0,0 +1,349 @@ +/* + * Zebra SRv6 definitions + * Copyright (C) 2020 Hiroki Shirokura, LINE Corporation + * Copyright (C) 2020 Masakazu Asama + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "network.h" +#include "prefix.h" +#include "stream.h" +#include "srv6.h" +#include "zebra/debug.h" +#include "zebra/zapi_msg.h" +#include "zebra/zserv.h" +#include "zebra/zebra_router.h" +#include "zebra/zebra_srv6.h" +#include "zebra/zebra_errors.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +DEFINE_MGROUP(SRV6_MGR, "SRv6 Manager"); +DEFINE_MTYPE_STATIC(SRV6_MGR, SRV6M_CHUNK, "SRv6 Manager Chunk"); + +/* define hooks for the basic API, so that it can be specialized or served + * externally + */ + +DEFINE_HOOK(srv6_manager_client_connect, + (struct zserv *client, vrf_id_t vrf_id), + (client, vrf_id)); +DEFINE_HOOK(srv6_manager_client_disconnect, + (struct zserv *client), (client)); +DEFINE_HOOK(srv6_manager_get_chunk, + (struct srv6_locator **loc, + struct zserv *client, + const char *locator_name, + vrf_id_t vrf_id), + (loc, client, locator_name, vrf_id)); +DEFINE_HOOK(srv6_manager_release_chunk, + (struct zserv *client, + const char *locator_name, + vrf_id_t vrf_id), + (client, locator_name, vrf_id)); + +/* define wrappers to be called in zapi_msg.c (as hooks must be called in + * source file where they were defined) + */ + +void srv6_manager_client_connect_call(struct zserv *client, vrf_id_t vrf_id) +{ + hook_call(srv6_manager_client_connect, client, vrf_id); +} + +void srv6_manager_get_locator_chunk_call(struct srv6_locator **loc, + struct zserv *client, + const char *locator_name, + vrf_id_t vrf_id) +{ + hook_call(srv6_manager_get_chunk, loc, client, locator_name, vrf_id); +} + +void srv6_manager_release_locator_chunk_call(struct zserv *client, + const char *locator_name, + vrf_id_t vrf_id) +{ + hook_call(srv6_manager_release_chunk, client, locator_name, vrf_id); +} + +int srv6_manager_client_disconnect_cb(struct zserv *client) +{ + hook_call(srv6_manager_client_disconnect, client); + return 0; +} + +static int zebra_srv6_cleanup(struct zserv *client) +{ + return 0; +} + +void zebra_srv6_locator_add(struct srv6_locator *locator) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct srv6_locator *tmp; + + tmp = zebra_srv6_locator_lookup(locator->name); + if (!tmp) + listnode_add(srv6->locators, locator); +} + +void zebra_srv6_locator_delete(struct srv6_locator *locator) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + listnode_delete(srv6->locators, locator); +} + +struct srv6_locator *zebra_srv6_locator_lookup(const char *name) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct srv6_locator *locator; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) + if (!strncmp(name, locator->name, SRV6_LOCNAME_SIZE)) + return locator; + return NULL; +} + +struct zebra_srv6 *zebra_srv6_get_default(void) +{ + static struct zebra_srv6 srv6; + static bool first_execution = true; + + if (first_execution) { + first_execution = false; + srv6.locators = list_new(); + } + return &srv6; +} + +/** + * Core function, assigns srv6-locator chunks + * + * It first searches through the list to check if there's one available + * (previously released). Otherwise it creates and assigns a new one + * + * @param proto Daemon protocol of client, to identify the owner + * @param instance Instance, to identify the owner + * @param session_id SessionID of client + * @param name Name of SRv6-locator + * @return Pointer to the assigned srv6-locator chunk, + * or NULL if the request could not be satisfied + */ +static struct srv6_locator * +assign_srv6_locator_chunk(uint8_t proto, + uint16_t instance, + uint32_t session_id, + const char *locator_name) +{ + bool chunk_found = false; + struct listnode *node = NULL; + struct srv6_locator *loc = NULL; + struct srv6_locator_chunk *chunk = NULL; + + loc = zebra_srv6_locator_lookup(locator_name); + if (!loc) { + zlog_info("%s: locator %s was not found", + __func__, locator_name); + + loc = srv6_locator_alloc(locator_name); + if (!loc) { + zlog_info("%s: locator %s can't allocated", + __func__, locator_name); + return NULL; + } + + loc->status_up = false; + chunk = srv6_locator_chunk_alloc(); + chunk->proto = 0; + listnode_add(loc->chunks, chunk); + zebra_srv6_locator_add(loc); + } + + for (ALL_LIST_ELEMENTS_RO((struct list *)loc->chunks, node, chunk)) { + if (chunk->proto != 0 && chunk->proto != proto) + continue; + chunk_found = true; + break; + } + + if (!chunk_found) { + zlog_info("%s: locator is already owned", __func__); + return NULL; + } + + chunk->proto = proto; + return loc; +} + +static int zebra_srv6_manager_get_locator_chunk(struct srv6_locator **loc, + struct zserv *client, + const char *locator_name, + vrf_id_t vrf_id) +{ + *loc = assign_srv6_locator_chunk(client->proto, client->instance, + client->session_id, locator_name); + + if (!*loc) + zlog_err("Unable to assign locator chunk to %s instance %u", + zebra_route_string(client->proto), client->instance); + else if (IS_ZEBRA_DEBUG_PACKET) + zlog_info("Assigned locator chunk %s to %s instance %u", + (*loc)->name, zebra_route_string(client->proto), + client->instance); + + int ret = 0; + if ((*loc)->status_up) + ret = zsend_srv6_manager_get_locator_chunk_response(client, + vrf_id, + *loc); + return ret; +} + +/** + * Core function, release no longer used srv6-locator chunks + * + * @param proto Daemon protocol of client, to identify the owner + * @param instance Instance, to identify the owner + * @param session_id Zclient session ID, to identify the zclient session + * @param locator_name SRv6-locator name, to identify the actual locator + * @return 0 on success, -1 otherwise + */ +static int release_srv6_locator_chunk(uint8_t proto, uint16_t instance, + uint32_t session_id, + const char *locator_name) +{ + int ret = -1; + struct listnode *node; + struct srv6_locator_chunk *chunk; + struct srv6_locator *loc = NULL; + + loc = zebra_srv6_locator_lookup(locator_name); + if (!loc) { + return -1; + } + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: Releasing srv6-locator on %s", __func__, + locator_name); + + for (ALL_LIST_ELEMENTS_RO((struct list *)loc->chunks, node, chunk)) { + if (chunk->proto != proto || + chunk->instance != instance || + chunk->session_id != session_id) + continue; + chunk->proto = NO_PROTO; + chunk->instance = 0; + chunk->session_id = 0; + chunk->keep = 0; + ret = 0; + break; + } + + if (ret != 0) + flog_err(EC_ZEBRA_SRV6M_UNRELEASED_LOCATOR_CHUNK, + "%s: SRv6 locator chunk not released", __func__); + + return ret; +} + +static int zebra_srv6_manager_release_locator_chunk(struct zserv *client, + const char *locator_name, + vrf_id_t vrf_id) +{ + if (vrf_id != VRF_DEFAULT) { + zlog_err("SRv6 locator doesn't support vrf"); + return -1; + } + + return release_srv6_locator_chunk(client->proto, client->instance, + client->session_id, locator_name); +} + +/** + * Release srv6-locator chunks from a client. + * + * Called on client disconnection or reconnection. It only releases chunks + * with empty keep value. + * + * @param proto Daemon protocol of client, to identify the owner + * @param instance Instance, to identify the owner + * @return Number of chunks released + */ +int release_daemon_srv6_locator_chunks(struct zserv *client) +{ + int ret; + int count = 0; + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct listnode *loc_node; + struct listnode *chunk_node; + struct srv6_locator *loc; + struct srv6_locator_chunk *chunk; + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: Releasing chunks for client proto %s, instance %d, session %u", + __func__, zebra_route_string(client->proto), + client->instance, client->session_id); + + for (ALL_LIST_ELEMENTS_RO(srv6->locators, loc_node, loc)) { + for (ALL_LIST_ELEMENTS_RO(loc->chunks, chunk_node, chunk)) { + if (chunk->proto == client->proto && + chunk->instance == client->instance && + chunk->session_id == client->session_id && + chunk->keep == 0) { + ret = release_srv6_locator_chunk( + chunk->proto, chunk->instance, + chunk->session_id, loc->name); + if (ret == 0) + count++; + } + } + } + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: Released %d srv6-locator chunks", + __func__, count); + + return count; +} + +void zebra_srv6_init(void) +{ + hook_register(zserv_client_close, zebra_srv6_cleanup); + hook_register(srv6_manager_get_chunk, + zebra_srv6_manager_get_locator_chunk); + hook_register(srv6_manager_release_chunk, + zebra_srv6_manager_release_locator_chunk); +} + +bool zebra_srv6_is_enable(void) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + + return listcount(srv6->locators); +} -- cgit v1.2.3 From 4df9d8592b1631e6cb50e291cab1ff7486467a3d Mon Sep 17 00:00:00 2001 From: Hiroki Shirokura Date: Wed, 24 Feb 2021 10:47:05 +0000 Subject: *: fix code format accourding to checkpatch Signed-off-by: Hiroki Shirokura --- lib/nexthop.h | 2 +- lib/zclient.c | 6 ++++-- sharpd/sharp_vty.c | 4 +++- sharpd/sharp_zebra.c | 19 ++++++++++-------- sharpd/sharp_zebra.h | 6 +++++- zebra/rt_netlink.c | 13 ++++++------ zebra/zapi_msg.h | 3 +-- zebra/zebra_srv6.c | 7 ++++--- zebra/zebra_srv6.h | 3 ++- zebra/zebra_srv6_vty.c | 54 +++++++++++++++++++++++++++++--------------------- 10 files changed, 69 insertions(+), 48 deletions(-) (limited to 'zebra/zebra_srv6.c') diff --git a/lib/nexthop.h b/lib/nexthop.h index 8c52631af1..c9af1ff478 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -168,7 +168,7 @@ void nexthop_del_labels(struct nexthop *); void nexthop_add_seg6local(struct nexthop *nexthop, uint32_t action, const struct seg6local_context *ctx); void nexthop_del_seg6local(struct nexthop *nexthop); -void nexthop_add_seg6(struct nexthop *nexthop, const struct in6_addr* segs); +void nexthop_add_seg6(struct nexthop *nexthop, const struct in6_addr *segs); void nexthop_del_seg6(struct nexthop *nexthop); /* diff --git a/lib/zclient.c b/lib/zclient.c index 8520fd769d..7eb365c305 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -2774,7 +2774,8 @@ int srv6_manager_get_locator_chunk(struct zclient *zclient, /* send request */ s = zclient->obuf; stream_reset(s); - zclient_create_header(s, ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK, VRF_DEFAULT); + zclient_create_header(s, ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK, + VRF_DEFAULT); /* proto */ stream_putc(s, zclient->redist_default); @@ -3580,7 +3581,8 @@ enum zclient_send_status zclient_send_mlag_register(struct zclient *client, enum zclient_send_status zclient_send_mlag_deregister(struct zclient *client) { - return zebra_message_send(client, ZEBRA_MLAG_CLIENT_UNREGISTER, VRF_DEFAULT); + return zebra_message_send(client, ZEBRA_MLAG_CLIENT_UNREGISTER, + VRF_DEFAULT); } enum zclient_send_status zclient_send_mlag_data(struct zclient *client, diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index 5997e5e312..58f6e3fe95 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -318,6 +318,7 @@ DEFPY (install_routes, } else if (seg6l_oif) { struct seg6local_context ctx; enum seg6local_action_t action; + memset(&ctx, 0, sizeof(struct seg6local_context)); if (seg6l_enddx4) { action = ZEBRA_SEG6_LOCAL_ACTION_END_DX4; @@ -1047,7 +1048,8 @@ void sharp_vty_init(void) install_element(ENABLE_NODE, &show_sharp_ted_cmd); install_element(ENABLE_NODE, &sharp_srv6_manager_get_locator_chunk_cmd); - install_element(ENABLE_NODE, &sharp_srv6_manager_release_locator_chunk_cmd); + install_element(ENABLE_NODE, + &sharp_srv6_manager_release_locator_chunk_cmd); install_element(ENABLE_NODE, &show_sharp_segment_routing_srv6_cmd); return; diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index 7c24ae380f..ae4add6a60 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -338,7 +338,8 @@ static void sharp_install_routes_restart(struct prefix *p, uint32_t count, uint32_t nhgid, const struct nexthop_group *nhg, const struct nexthop_group *backup_nhg, - uint32_t routes, uint32_t flags, char *opaque) + uint32_t routes, uint32_t flags, + char *opaque) { uint32_t temp, i; bool v4 = false; @@ -924,7 +925,7 @@ static int nhg_notify_owner(ZAPI_CALLBACK_ARGS) return 0; } -int sharp_zebra_srv6_manager_get_locator_chunk(const char* locator_name) +int sharp_zebra_srv6_manager_get_locator_chunk(const char *locator_name) { return srv6_manager_get_locator_chunk(zclient, locator_name); } @@ -942,6 +943,7 @@ static void sharp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS) uint16_t len; char name[256] = {0}; struct prefix_ipv6 *chunk = NULL; + chunk = prefix_ipv6_new(); s = zclient->ibuf; @@ -965,16 +967,17 @@ static void sharp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS) struct listnode *loc_node; struct sharp_srv6_locator *loc; + for (ALL_LIST_ELEMENTS_RO(sg.srv6_locators, loc_node, loc)) { + struct listnode *chunk_node; + struct prefix_ipv6 *c; + if (strcmp(loc->name, name)) continue; - struct listnode *chunk_node; - struct prefix_ipv6 *c; - for (ALL_LIST_ELEMENTS_RO(loc->chunks, chunk_node, c)) { + for (ALL_LIST_ELEMENTS_RO(loc->chunks, chunk_node, c)) if (!prefix_cmp(c, chunk)) return; - } listnode_add(loc->chunks, chunk); } return; @@ -983,7 +986,6 @@ stream_failure: free(chunk); zlog_err("%s: can't get locator_chunk!!", __func__); - return; } void sharp_zebra_init(void) @@ -1007,5 +1009,6 @@ void sharp_zebra_init(void) zclient->redistribute_route_add = sharp_redistribute_route; zclient->redistribute_route_del = sharp_redistribute_route; zclient->opaque_msg_handler = sharp_opaque_handler; - zclient->process_srv6_locator_chunk = sharp_zebra_process_srv6_locator_chunk; + zclient->process_srv6_locator_chunk = + sharp_zebra_process_srv6_locator_chunk; } diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h index 043a7405c2..45e26a9b3d 100644 --- a/sharpd/sharp_zebra.h +++ b/sharpd/sharp_zebra.h @@ -39,7 +39,8 @@ extern void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id, uint8_t instance, uint32_t nhgid, const struct nexthop_group *nhg, const struct nexthop_group *backup_nhg, - uint32_t routes, uint32_t flags, char *opaque); + uint32_t routes, uint32_t flags, + char *opaque); extern void sharp_remove_routes_helper(struct prefix *p, vrf_id_t vrf_id, uint8_t instance, uint32_t routes); @@ -67,6 +68,9 @@ extern void sharp_redistribute_vrf(struct vrf *vrf, int source); extern int sharp_zebra_srv6_manager_get_locator_chunk(const char* locator_name); extern int sharp_zebra_srv6_manager_release_locator_chunk(const char *locator_name); +extern int sharp_zebra_srv6_manager_get_locator_chunk(const char *locator_name); +extern int sharp_zebra_srv6_manager_release_locator_chunk( + const char *locator_name); extern void sharp_install_seg6local_route_helper(struct prefix *p, uint8_t instance, enum seg6local_action_t act, diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 705a035de5..f5ce4e795b 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -474,7 +474,7 @@ parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb, mpls_label_t labels[MPLS_MAX_LABELS] = {0}; int num_labels = 0; enum seg6local_action_t seg6l_act = SEG6_LOCAL_ACTION_UNSPEC; - struct seg6local_context seg6l_ctx = {{0}}; + struct seg6local_context seg6l_ctx = { {0} }; struct in6_addr seg6_segs = {0}; int num_segs = 0; @@ -556,7 +556,7 @@ static uint8_t parse_multipath_nexthops_unicast(ns_id_t ns_id, mpls_label_t labels[MPLS_MAX_LABELS] = {0}; int num_labels = 0; enum seg6local_action_t seg6l_act = SEG6_LOCAL_ACTION_UNSPEC; - struct seg6local_context seg6l_ctx = {{0}}; + struct seg6local_context seg6l_ctx = { {0} }; struct in6_addr seg6_segs = {0}; int num_segs = 0; struct rtattr *rtnh_tb[RTA_MAX + 1] = {}; @@ -1336,6 +1336,7 @@ static size_t fill_seg6ipt_encap(char *buffer, size_t buflen, struct seg6_iptunnel_encap *ipt; struct ipv6_sr_hdr *srh; const size_t srhlen = 24; + memset(buffer, 0, buflen); ipt = (struct seg6_iptunnel_encap *)buffer; @@ -2479,16 +2480,16 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd, break; case SEG6_LOCAL_ACTION_END_DX4: nl_attr_put32(&req->n, buflen, - SEG6_LOCAL_ACTION, - SEG6_LOCAL_ACTION_END_DX4); + SEG6_LOCAL_ACTION, + SEG6_LOCAL_ACTION_END_DX4); nl_attr_put(&req->n, buflen, SEG6_LOCAL_NH4, &ctx->nh4, sizeof(struct in_addr)); break; case SEG6_LOCAL_ACTION_END_DT6: nl_attr_put32(&req->n, buflen, - SEG6_LOCAL_ACTION, - SEG6_LOCAL_ACTION_END_DT6); + SEG6_LOCAL_ACTION, + SEG6_LOCAL_ACTION_END_DT6); nl_attr_put32(&req->n, buflen, SEG6_LOCAL_TABLE, ctx->table); diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index 35bb554121..e991dca4f3 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -122,8 +122,7 @@ extern int zsend_zebra_srv6_locator_add(struct zserv *client, extern int zsend_zebra_srv6_locator_delete(struct zserv *client, struct srv6_locator *loc); extern int zsend_srv6_manager_get_locator_chunk_response(struct zserv *client, - vrf_id_t vrf_id, - struct srv6_locator *loc); + vrf_id_t vrf_id, struct srv6_locator *loc); #ifdef __cplusplus } diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index b4b691e8e0..1e12117ac4 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -115,6 +115,7 @@ void zebra_srv6_locator_add(struct srv6_locator *locator) void zebra_srv6_locator_delete(struct srv6_locator *locator) { struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + listnode_delete(srv6->locators, locator); } @@ -206,6 +207,8 @@ static int zebra_srv6_manager_get_locator_chunk(struct srv6_locator **loc, const char *locator_name, vrf_id_t vrf_id) { + int ret = 0; + *loc = assign_srv6_locator_chunk(client->proto, client->instance, client->session_id, locator_name); @@ -217,7 +220,6 @@ static int zebra_srv6_manager_get_locator_chunk(struct srv6_locator **loc, (*loc)->name, zebra_route_string(client->proto), client->instance); - int ret = 0; if ((*loc)->status_up) ret = zsend_srv6_manager_get_locator_chunk_response(client, vrf_id, @@ -244,9 +246,8 @@ static int release_srv6_locator_chunk(uint8_t proto, uint16_t instance, struct srv6_locator *loc = NULL; loc = zebra_srv6_locator_lookup(locator_name); - if (!loc) { + if (!loc) return -1; - } if (IS_ZEBRA_DEBUG_PACKET) zlog_debug("%s: Releasing srv6-locator on %s", __func__, diff --git a/zebra/zebra_srv6.h b/zebra/zebra_srv6.h index 751cee6e70..84fcc305bc 100644 --- a/zebra/zebra_srv6.h +++ b/zebra/zebra_srv6.h @@ -65,7 +65,8 @@ extern void zebra_srv6_init(void); extern struct zebra_srv6 *zebra_srv6_get_default(void); extern bool zebra_srv6_is_enable(void); -extern void srv6_manager_client_connect_call(struct zserv *client, vrf_id_t vrf_id); +extern void srv6_manager_client_connect_call(struct zserv *client, + vrf_id_t vrf_id); extern void srv6_manager_get_locator_chunk_call(struct srv6_locator **loc, struct zserv *client, const char *locator_name, diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c index 73038fad73..e2685141bb 100644 --- a/zebra/zebra_srv6_vty.c +++ b/zebra/zebra_srv6_vty.c @@ -147,30 +147,31 @@ DEFUN (show_srv6_locator_detail, if (uj) { vty_out(vty, "JSON format isn't supported\n"); return CMD_WARNING; - } else { - for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) { - if (strcmp(locator->name, locator_name) != 0) { - continue; - } + } - prefix2str(&locator->prefix, str, sizeof(str)); - vty_out(vty, "Name: %s\n", locator->name); - vty_out(vty, "Prefix: %s\n", str); - vty_out(vty, "Function-Bit-Len: %u\n", - locator->function_bits_length); - - vty_out(vty, "Chunks:\n"); - struct listnode *node; - struct srv6_locator_chunk *chunk; - for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, node, chunk)) { - prefix2str(&chunk->prefix, str, sizeof(str)); - vty_out(vty, "- prefix: %s, owner: %s\n", str, - zebra_route_string(chunk->proto)); - } + for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) { + struct listnode *node; + struct srv6_locator_chunk *chunk; + + if (strcmp(locator->name, locator_name) != 0) + continue; + + prefix2str(&locator->prefix, str, sizeof(str)); + vty_out(vty, "Name: %s\n", locator->name); + vty_out(vty, "Prefix: %s\n", str); + vty_out(vty, "Function-Bit-Len: %u\n", + locator->function_bits_length); + + vty_out(vty, "Chunks:\n"); + for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, node, + chunk)) { + prefix2str(&chunk->prefix, str, sizeof(str)); + vty_out(vty, "- prefix: %s, owner: %s\n", str, + zebra_route_string(chunk->proto)); } - } + return CMD_SUCCESS; } @@ -264,16 +265,23 @@ DEFUN (locator_prefix, } else { for (ALL_LIST_ELEMENTS_RO(locator->chunks, node, chunk)) { uint8_t zero[16] = {0}; + if (memcmp(&chunk->prefix.prefix, zero, 16) == 0) { struct zserv *client; struct listnode *client_node; + chunk->prefix = prefix; - for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, client_node, client)) { + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, + client_node, + client)) { + struct srv6_locator *tmp; + if (client->proto != chunk->proto) continue; - struct srv6_locator *tmp; srv6_manager_get_locator_chunk_call( - &tmp, client, locator->name, VRF_DEFAULT); + &tmp, client, + locator->name, + VRF_DEFAULT); } } } -- cgit v1.2.3 From 1d5f59a2353c9537193527ca0ffaf58a2e56d30e Mon Sep 17 00:00:00 2001 From: Hiroki Shirokura Date: Wed, 24 Feb 2021 11:28:59 +0000 Subject: zebra: fix Dereference of null pointer Signed-off-by: Hiroki Shirokura --- zebra/zebra_srv6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'zebra/zebra_srv6.c') diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index 1e12117ac4..5664a29682 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -220,7 +220,7 @@ static int zebra_srv6_manager_get_locator_chunk(struct srv6_locator **loc, (*loc)->name, zebra_route_string(client->proto), client->instance); - if ((*loc)->status_up) + if (*loc && (*loc)->status_up) ret = zsend_srv6_manager_get_locator_chunk_response(client, vrf_id, *loc); -- cgit v1.2.3