From e1a1880de3e9da60f72198924fe3407f7bbc975d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 9 Nov 2017 14:34:42 -0500 Subject: [PATCH] *: Make zapi route install Notifications optional Allow the higher level protocol to specify if it would like to receive notifications about it's routes that it has installed. I've purposely made it part of zclient_new_notify because we need to track the routes on a per daemon basis only. Signed-off-by: Donald Sharp --- babeld/babel_zebra.c | 2 +- bgpd/bgp_zebra.c | 2 +- bgpd/rfapi/vnc_zebra.c | 2 +- eigrpd/eigrp_zebra.c | 2 +- isisd/isis_zebra.c | 2 +- ldpd/lde.c | 2 +- ldpd/ldp_zebra.c | 2 +- lib/zclient.c | 14 ++++++++++++-- lib/zclient.h | 20 ++++++++++++++++++++ nhrpd/nhrp_route.c | 2 +- ospf6d/ospf6_zebra.c | 2 +- ospfd/ospf_zebra.c | 2 +- pimd/pim_zebra.c | 2 +- pimd/pim_zlookup.c | 2 +- ripd/rip_zebra.c | 2 +- ripngd/ripng_zebra.c | 2 +- tests/bgpd/test_mpath.c | 2 +- tests/test_lblmgr.c | 2 +- zebra/client_main.c | 2 +- zebra/label_manager.c | 2 +- zebra/zserv.c | 17 ++++++++++++----- zebra/zserv.h | 2 ++ 22 files changed, 64 insertions(+), 25 deletions(-) diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c index e7c27e8e21..8dea1431e2 100644 --- a/babeld/babel_zebra.c +++ b/babeld/babel_zebra.c @@ -237,7 +237,7 @@ babel_zebra_connected (struct zclient *zclient) void babelz_zebra_init(void) { - zclient = zclient_new(master); + zclient = zclient_new_notify(master, &zclient_options_default); zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0, &babeld_privs); zclient->zebra_connected = babel_zebra_connected; diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index b6bf008bae..1cf04abfce 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1759,7 +1759,7 @@ void bgp_zebra_init(struct thread_master *master) zclient_num_connects = 0; /* Set default values. */ - zclient = zclient_new(master); + zclient = zclient_new_notify(master, &zclient_options_default); zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs); zclient->zebra_connected = bgp_zebra_connected; zclient->router_id_update = bgp_router_id_update; diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index 478d3b5ac7..5c71df238f 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -892,7 +892,7 @@ extern struct zebra_privs_t bgpd_privs; void vnc_zebra_init(struct thread_master *master) { /* Set default values. */ - zclient_vnc = zclient_new(master); + zclient_vnc = zclient_new_notify(master, &zclient_options_default); zclient_init(zclient_vnc, ZEBRA_ROUTE_VNC, 0, &bgpd_privs); zclient_vnc->redistribute_route_add = vnc_zebra_read_route; diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index 9076a50f57..b6e776f68a 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -101,7 +101,7 @@ static void eigrp_zebra_connected(struct zclient *zclient) void eigrp_zebra_init(void) { - zclient = zclient_new(master); + zclient = zclient_new_notify(master, &zclient_options_default); zclient_init(zclient, ZEBRA_ROUTE_EIGRP, 0, &eigrpd_privs); zclient->zebra_connected = eigrp_zebra_connected; diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index c186dd56ad..573b81591c 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -411,7 +411,7 @@ static void isis_zebra_connected(struct zclient *zclient) void isis_zebra_init(struct thread_master *master) { - zclient = zclient_new(master); + zclient = zclient_new_notify(master, &zclient_options_default); zclient_init(zclient, ZEBRA_ROUTE_ISIS, 0, &isisd_privs); zclient->zebra_connected = isis_zebra_connected; zclient->router_id_update = isis_router_id_update_zebra; diff --git a/ldpd/lde.c b/ldpd/lde.c index 8122b88cca..b597d967d7 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -1618,7 +1618,7 @@ static void zclient_sync_init(u_short instance) { /* Initialize special zclient for synchronous message exchanges. */ - zclient_sync = zclient_new(master); + zclient_sync = zclient_new_notify(master, &zclient_options_default); zclient_sync->sock = -1; zclient_sync->redist_default = ZEBRA_ROUTE_LDP; zclient_sync->instance = instance; diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c index 8fe51cb9d1..e703a9ff61 100644 --- a/ldpd/ldp_zebra.c +++ b/ldpd/ldp_zebra.c @@ -513,7 +513,7 @@ void ldp_zebra_init(struct thread_master *master) { /* Set default values. */ - zclient = zclient_new(master); + zclient = zclient_new_notify(master, &zclient_options_default); zclient_init(zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs); /* set callbacks */ diff --git a/lib/zclient.c b/lib/zclient.c index e769906012..655e4e1a80 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -52,8 +52,11 @@ socklen_t zclient_addr_len; /* This file local debug flag. */ int zclient_debug = 0; +struct zclient_options zclient_options_default = { .receive_notify = false }; + /* Allocate zclient structure. */ -struct zclient *zclient_new(struct thread_master *master) +struct zclient *zclient_new_notify(struct thread_master *master, + struct zclient_options *opt) { struct zclient *zclient; zclient = XCALLOC(MTYPE_ZCLIENT, sizeof(struct zclient)); @@ -63,6 +66,8 @@ struct zclient *zclient_new(struct thread_master *master) zclient->wb = buffer_new(0); zclient->master = master; + zclient->receive_notify = opt->receive_notify; + return zclient; } @@ -190,7 +195,7 @@ void zclient_reset(struct zclient *zclient) * @param zclient a pointer to zclient structure * @return socket fd just to make sure that connection established * @see zclient_init - * @see zclient_new + * @see zclient_new_notify */ int zclient_socket_connect(struct zclient *zclient) { @@ -346,6 +351,11 @@ static int zebra_hello_send(struct zclient *zclient) zclient_create_header(s, ZEBRA_HELLO, VRF_DEFAULT); stream_putc(s, zclient->redist_default); stream_putw(s, zclient->instance); + if (zclient->receive_notify) + stream_putc(s, 1); + else + stream_putc(s, 0); + stream_putw_at(s, 0, stream_get_endp(s)); return zclient_send_message(zclient); } diff --git a/lib/zclient.h b/lib/zclient.h index 025a3ac230..de58044671 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -138,6 +138,9 @@ struct zclient { /* Priviledges to change socket values */ struct zebra_privs_t *privs; + /* Do we care about failure events for route install? */ + bool receive_notify; + /* Socket to zebra daemon. */ int sock; @@ -336,8 +339,25 @@ enum zapi_route_notify_owner { #define ZEBRA_MAC_TYPE_STICKY 0x01 /* Sticky MAC*/ #define ZEBRA_MAC_TYPE_GW 0x02 /* gateway (SVI) mac*/ +struct zclient_options { + bool receive_notify; +}; + /* Prototypes of zebra client service functions. */ extern struct zclient *zclient_new(struct thread_master *); + +#if CONFDATE > 20181101 +CPP_NOTICE("zclient_new_notify can take over or zclient_new now"); +#endif + +extern struct zclient_options zclient_options_default; + +extern struct zclient *zclient_new_notify(struct thread_master *m, + struct zclient_options *opt); + +#define zclient_new(A) zclient_new_notify((A), &zclient_options_default); \ + CPP_WARN("Please transition to using zclient_new_notify"); + extern void zclient_init(struct zclient *, int, u_short, struct zebra_privs_t *privs); extern int zclient_start(struct zclient *); extern void zclient_stop(struct zclient *); diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index 7701dcbb88..2612d8e045 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -314,7 +314,7 @@ void nhrp_zebra_init(void) zebra_rib[AFI_IP] = route_table_init(); zebra_rib[AFI_IP6] = route_table_init(); - zclient = zclient_new(master); + zclient = zclient_new_notify(master, &zclient_options_default); zclient->zebra_connected = nhrp_zebra_connected; zclient->interface_add = nhrp_interface_add; zclient->interface_delete = nhrp_interface_delete; diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index a900648236..cc87c499ee 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -583,7 +583,7 @@ static void ospf6_zebra_connected(struct zclient *zclient) void ospf6_zebra_init(struct thread_master *master) { /* Allocate zebra structure. */ - zclient = zclient_new(master); + zclient = zclient_new_notify(master, &zclient_options_default); zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs); zclient->zebra_connected = ospf6_zebra_connected; zclient->router_id_update = ospf6_router_id_update_zebra; diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 34ad6f65b0..66be29dbb4 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -1475,7 +1475,7 @@ static void ospf_zebra_connected(struct zclient *zclient) void ospf_zebra_init(struct thread_master *master, u_short instance) { /* Allocate zebra structure. */ - zclient = zclient_new(master); + zclient = zclient_new_notify(master, &zclient_options_default); zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs); zclient->zebra_connected = ospf_zebra_connected; zclient->router_id_update = ospf_router_id_update_zebra; diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index 04466258bb..689e9a7449 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -748,7 +748,7 @@ void pim_zebra_init(void) int i; /* Socket for receiving updates from Zebra daemon */ - zclient = zclient_new(master); + zclient = zclient_new_notify(master, &zclient_options_default); zclient->zebra_connected = pim_zebra_connected; zclient->router_id_update = pim_router_id_update_zebra; diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c index fd75a699b3..bcaf4a38dd 100644 --- a/pimd/pim_zlookup.c +++ b/pimd/pim_zlookup.c @@ -120,7 +120,7 @@ void zclient_lookup_free(void) void zclient_lookup_new(void) { - zlookup = zclient_new(master); + zlookup = zclient_new_notify(master, &zclient_options_default); if (!zlookup) { zlog_err("%s: zclient_new() failure", __PRETTY_FUNCTION__); return; diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index e479e2474d..041635e153 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -590,7 +590,7 @@ static void rip_zebra_connected(struct zclient *zclient) void rip_zclient_init(struct thread_master *master) { /* Set default value to the zebra client structure. */ - zclient = zclient_new(master); + zclient = zclient_new_notify(master, &zclient_options_default); zclient_init(zclient, ZEBRA_ROUTE_RIP, 0, &ripd_privs); zclient->zebra_connected = rip_zebra_connected; zclient->interface_add = rip_interface_add; diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index 084d58ee53..18a8d14f09 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -413,7 +413,7 @@ static void ripng_zebra_connected(struct zclient *zclient) void zebra_init(struct thread_master *master) { /* Allocate zebra structure. */ - zclient = zclient_new(master); + zclient = zclient_new_notify(master, &zclient_options_default); zclient_init(zclient, ZEBRA_ROUTE_RIPNG, 0, &ripngd_privs); zclient->zebra_connected = ripng_zebra_connected; diff --git a/tests/bgpd/test_mpath.c b/tests/bgpd/test_mpath.c index ccd3b6f4c2..247fcf7da0 100644 --- a/tests/bgpd/test_mpath.c +++ b/tests/bgpd/test_mpath.c @@ -374,7 +374,7 @@ static int global_test_init(void) { qobj_init(); master = thread_master_create(NULL); - zclient = zclient_new(master); + zclient = zclient_new_notify(master, &zclient_options_default); bgp_master_init(master); vrf_init(NULL, NULL, NULL, NULL); bgp_option_set(BGP_OPT_NO_LISTEN); diff --git a/tests/test_lblmgr.c b/tests/test_lblmgr.c index 5e604db61a..b08f63b70f 100644 --- a/tests/test_lblmgr.c +++ b/tests/test_lblmgr.c @@ -115,7 +115,7 @@ void init_zclient(struct thread_master *master, char *lm_zserv_path) { frr_zclient_addr(&zclient_addr, &zclient_addr_len, lm_zserv_path); - zclient = zclient_new(master); + zclient = zclient_new_notify(master, &zclient_options_default); /* zclient_init(zclient, ZEBRA_LABEL_MANAGER, 0); */ zclient->sock = -1; zclient->redist_default = ZEBRA_ROUTE_LDP; diff --git a/zebra/client_main.c b/zebra/client_main.c index 95b9d00dc0..9b82e48261 100644 --- a/zebra/client_main.c +++ b/zebra/client_main.c @@ -184,7 +184,7 @@ int main(int argc, char **argv) master = thread_master_create(NULL); /* Establish connection to zebra. */ - zclient = zclient_new(master); + zclient = zclient_new_notify(master, &zclient_options_default); zclient->enable = 1; zclient_socket_connect(zclient); diff --git a/zebra/label_manager.c b/zebra/label_manager.c index 6fbb751789..bf4522b70f 100644 --- a/zebra/label_manager.c +++ b/zebra/label_manager.c @@ -221,7 +221,7 @@ static void lm_zclient_init(char *lm_zserv_path) lm_zserv_path); /* Set default values. */ - zclient = zclient_new(zebrad.master); + zclient = zclient_new_notify(zebrad.master, &zclient_options_default); zclient->sock = -1; zclient->t_connect = NULL; lm_zclient_connect(NULL); diff --git a/zebra/zserv.c b/zebra/zserv.c index f76490861d..7b1839930e 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -997,11 +997,14 @@ int zsend_route_notify_owner(u_char proto, vrf_id_t vrf_id, uint8_t blen; client = zebra_find_client(proto); - if (!client) { - if (IS_ZEBRA_DEBUG_PACKET) - zlog_debug("Attempting to notify a client for proto: %u but did not find one", - proto); - return -1; + if (!client || !client->notify_owner) { + if (IS_ZEBRA_DEBUG_PACKET) { + char buff[PREFIX_STRLEN]; + + zlog_debug("Not Notifying Owner: %u about prefix %s", + proto, prefix2str(p, buff, sizeof(buff))); + } + return 0; } s = client->obuf; @@ -1918,9 +1921,13 @@ static void zread_hello(struct zserv *client) /* type of protocol (lib/zebra.h) */ u_char proto; u_short instance; + u_char notify; STREAM_GETC(client->ibuf, proto); STREAM_GETW(client->ibuf, instance); + STREAM_GETC(client->ibuf, notify); + if (notify) + client->notify_owner = true; /* accept only dynamic routing protocols */ if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_STATIC)) { diff --git a/zebra/zserv.h b/zebra/zserv.h index 9978c6d896..a62f1c89fc 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -75,6 +75,8 @@ struct zserv { /* Router-id information. */ vrf_bitmap_t ridinfo; + bool notify_owner; + /* client's protocol */ u_char proto; u_short instance;