Skip to content

Commit

Permalink
lib, bgp/vnc: add .auxiliary zclient option
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
eqvinox committed Nov 23, 2023
1 parent cc90c54 commit 5a40f2b
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
2 changes: 1 addition & 1 deletion bgpd/rfapi/vnc_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
11 changes: 10 additions & 1 deletion lib/zclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down
12 changes: 12 additions & 0 deletions lib/zclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 5a40f2b

Please sign in to comment.