lib, bgp/vnc: add .auxiliary zclient option

Avoids calling VRF/interface/... handlers in library code more than
once.  It's kinda surprising that this hasn't been blowing up already
for the VNC code, luckily these handlers are (mostly?) idempotent.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
David Lamparter 2023-11-23 15:40:38 +01:00
parent cc90c54b36
commit 5a40f2b0e7
3 changed files with 23 additions and 2 deletions

View file

@ -872,7 +872,7 @@ static zclient_handler *const vnc_handlers[] = {
void vnc_zebra_init(struct event_loop *master)
{
/* Set default values. */
zclient_vnc = zclient_new(master, &zclient_options_default,
zclient_vnc = zclient_new(master, &zclient_options_auxiliary,
vnc_handlers, array_size(vnc_handlers));
zclient_init(zclient_vnc, ZEBRA_ROUTE_VNC, 0, &bgpd_privs);
}

View file

@ -43,10 +43,17 @@ static void zebra_interface_if_set_value(struct stream *s,
const struct zclient_options zclient_options_default = {
.synchronous = false,
.auxiliary = false,
};
const struct zclient_options zclient_options_sync = {
.synchronous = true,
.auxiliary = true,
};
const struct zclient_options zclient_options_auxiliary = {
.synchronous = false,
.auxiliary = true,
};
struct sockaddr_storage zclient_addr;
@ -75,6 +82,7 @@ struct zclient *zclient_new(struct event_loop *master,
zclient->n_handlers = n_handlers;
zclient->synchronous = opt->synchronous;
zclient->auxiliary = opt->auxiliary;
return zclient;
}
@ -4444,7 +4452,8 @@ static void zclient_read(struct event *thread)
zlog_debug("zclient %p command %s VRF %u", zclient,
zserv_command_string(command), vrf_id);
if (command < array_size(lib_handlers) && lib_handlers[command])
if (!zclient->auxiliary && command < array_size(lib_handlers) &&
lib_handlers[command])
lib_handlers[command](command, zclient, length, vrf_id);
if (command < zclient->n_handlers && zclient->handlers[command])
zclient->handlers[command](command, zclient, length, vrf_id);

View file

@ -306,6 +306,11 @@ struct zclient {
/* Is this a synchronous client? */
bool synchronous;
/* Auxiliary clients don't execute standard library handlers
* (which otherwise would duplicate VRF/interface add/delete/etc.
*/
bool auxiliary;
/* BFD enabled with bfd_protocol_integration_init() */
bool bfd_integration;
@ -832,10 +837,17 @@ enum zebra_neigh_state { ZEBRA_NEIGH_INACTIVE = 0, ZEBRA_NEIGH_ACTIVE = 1 };
struct zclient_options {
bool synchronous;
/* auxiliary = don't call common lib/ handlers that manage bits.
* Those should only run once, on the "main" zclient, which this is
* not. (This is also set for synchronous clients.)
*/
bool auxiliary;
};
extern const struct zclient_options zclient_options_default;
extern const struct zclient_options zclient_options_sync;
extern const struct zclient_options zclient_options_auxiliary;
/* link layer representation for GRE like interfaces
* ip_in is the underlay IP, ip_out is the tunnel dest