sharpd: add zclient session create and delete

Add a couple of clis and some simple support that allows sharpd to
create extra zapi client sessions.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
This commit is contained in:
Mark Stapp 2020-06-09 16:36:45 -04:00
parent cba183561b
commit 2be4d61a86
5 changed files with 138 additions and 11 deletions

View File

@ -125,3 +125,15 @@ keyword. At present, no sharp commands will be preserved in the config.
single subtype. The messages must specify a protocol daemon by
name, and can include optional zapi ``instance`` and ``session``
values.
.. index:: sharp create session
.. clicmd:: sharp create session (1-1024)
Create an additional zapi client session for testing, using the
specified session id.
.. index:: sharp remove session
.. clicmd:: sharp remove session (1-1024)
Remove a test zapi client session that was created with the
specified session id.

View File

@ -164,7 +164,7 @@ void zclient_stop(struct zclient *zclient)
int i;
if (zclient_debug)
zlog_debug("zclient stopped");
zlog_debug("zclient %p stopped", zclient);
/* Stop threads. */
THREAD_OFF(zclient->t_read);

View File

@ -547,6 +547,34 @@ DEFPY (logpump,
return CMD_SUCCESS;
}
DEFPY (create_session,
create_session_cmd,
"sharp create session (1-1024)",
"Sharp Routing Protocol\n"
"Create data\n"
"Create a test session\n"
"Session ID\n")
{
if (sharp_zclient_create(session) != 0) {
vty_out(vty, "%% Client session error\n");
return CMD_WARNING;
}
return CMD_SUCCESS;
}
DEFPY (remove_session,
remove_session_cmd,
"sharp remove session (1-1024)",
"Sharp Routing Protocol\n"
"Remove data\n"
"Remove a test session\n"
"Session ID\n")
{
sharp_zclient_delete(session);
return CMD_SUCCESS;
}
DEFPY (send_opaque,
send_opaque_cmd,
"sharp send opaque type (1-255) (1-1000)$count",
@ -626,6 +654,8 @@ void sharp_vty_init(void)
install_element(ENABLE_NODE, &sharp_lsp_prefix_v4_cmd);
install_element(ENABLE_NODE, &sharp_remove_lsp_prefix_v4_cmd);
install_element(ENABLE_NODE, &logpump_cmd);
install_element(ENABLE_NODE, &create_session_cmd);
install_element(ENABLE_NODE, &remove_session_cmd);
install_element(ENABLE_NODE, &send_opaque_cmd);
install_element(ENABLE_NODE, &send_opaque_unicast_cmd);
install_element(ENABLE_NODE, &send_opaque_reg_cmd);

View File

@ -25,14 +25,9 @@
#include "command.h"
#include "network.h"
#include "prefix.h"
#include "routemap.h"
#include "table.h"
#include "stream.h"
#include "memory.h"
#include "zclient.h"
#include "filter.h"
#include "plist.h"
#include "log.h"
#include "nexthop.h"
#include "nexthop_group.h"
@ -44,9 +39,41 @@
struct zclient *zclient = NULL;
/* For registering threads. */
extern struct thread_master *master;
struct thread_master *master;
/* Inteface addition message from zebra. */
/* Privs info */
struct zebra_privs_t sharp_privs;
DEFINE_MTYPE_STATIC(SHARPD, ZC, "Test zclients");
/* Struct to hold list of test zclients */
struct sharp_zclient {
struct sharp_zclient *prev;
struct sharp_zclient *next;
struct zclient *client;
};
/* Head of test zclient list */
static struct sharp_zclient *sharp_clients_head;
static int sharp_opaque_handler(ZAPI_CALLBACK_ARGS);
/* Utility to add a test zclient struct to the list */
static void add_zclient(struct zclient *client)
{
struct sharp_zclient *node;
node = XCALLOC(MTYPE_ZC, sizeof(struct sharp_zclient));
node->client = client;
node->next = sharp_clients_head;
if (sharp_clients_head)
sharp_clients_head->prev = node;
sharp_clients_head = node;
}
/* Interface addition message from zebra. */
static int sharp_ifp_create(struct interface *ifp)
{
return 0;
@ -480,6 +507,62 @@ static int sharp_redistribute_route(ZAPI_CALLBACK_ARGS)
return 0;
}
/* Add a zclient with a specified session id, for testing. */
int sharp_zclient_create(uint32_t session_id)
{
struct zclient *client;
struct sharp_zclient *node;
/* Check for duplicates */
for (node = sharp_clients_head; node != NULL; node = node->next) {
if (node->client->session_id == session_id)
return -1;
}
client = zclient_new(master, &zclient_options_default);
client->sock = -1;
client->session_id = session_id;
zclient_init(client, ZEBRA_ROUTE_SHARP, 0, &sharp_privs);
/* Register handlers for messages we expect this session to see */
client->opaque_msg_handler = sharp_opaque_handler;
/* Enqueue on the list of test clients */
add_zclient(client);
return 0;
}
/* Delete one of the extra test zclients */
int sharp_zclient_delete(uint32_t session_id)
{
struct sharp_zclient *node;
/* Search for session */
for (node = sharp_clients_head; node != NULL; node = node->next) {
if (node->client->session_id == session_id) {
/* Dequeue from list */
if (node->next)
node->next->prev = node->prev;
if (node->prev)
node->prev->next = node->next;
if (node == sharp_clients_head)
sharp_clients_head = node->next;
/* Clean up zclient */
zclient_stop(node->client);
zclient_free(node->client);
/* Free memory */
XFREE(MTYPE_ZC, node);
break;
}
}
return 0;
}
/* Handler for opaque messages */
static int sharp_opaque_handler(ZAPI_CALLBACK_ARGS)
{
@ -491,7 +574,7 @@ static int sharp_opaque_handler(ZAPI_CALLBACK_ARGS)
if (zclient_opaque_decode(s, &info) != 0)
return -1;
zlog_debug("%s: [%d] received opaque type %u", __func__,
zlog_debug("%s: [%u] received opaque type %u", __func__,
zclient->session_id, info.type);
return 0;
@ -564,8 +647,6 @@ void sharp_opaque_reg_send(bool is_reg, uint32_t proto, uint32_t instance,
}
extern struct zebra_privs_t sharp_privs;
void sharp_zebra_init(void)
{
struct zclient_options opt = {.receive_notify = true};

View File

@ -24,6 +24,10 @@
extern void sharp_zebra_init(void);
/* Add and delete extra zapi client sessions, for testing */
int sharp_zclient_create(uint32_t session_id);
int sharp_zclient_delete(uint32_t session_id);
extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label);
extern void route_add(const struct prefix *p, vrf_id_t, uint8_t instance,
const struct nexthop_group *nhg,