diff options
author | David Lamparter <equinox@opensourcerouting.org> | 2021-10-20 13:07:47 +0200 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2021-10-20 13:28:46 +0200 |
commit | a243d1db93aaa123413a754fe69fbad36d810ae7 (patch) | |
tree | 3d2e74c2b3f4d4862f7a7029c2ff5d18d71999ae /bgpd/bgp_zebra.c | |
parent | Merge pull request #9848 from ton31337/feature/as-path_autocomplete (diff) | |
download | frr-a243d1db93aaa123413a754fe69fbad36d810ae7.tar.xz frr-a243d1db93aaa123413a754fe69fbad36d810ae7.zip |
*: convert zclient callbacks to table
This removes a giant `switch { }` block from lib/zclient.c and
harmonizes all zclient callback function types to be the same (some had
a subset of the args, some had a void return, now they all have
ZAPI_CALLBACK_ARGS and int return.)
Apart from getting rid of the giant switch, this is a minor security
benefit since the function pointers are now in a `const` array, so they
can't be overwritten by e.g. heap overflows for code execution anymore.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'bgpd/bgp_zebra.c')
-rw-r--r-- | bgpd/bgp_zebra.c | 98 |
1 files changed, 52 insertions, 46 deletions
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 6161f56fe..4f0501f4b 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -136,8 +136,7 @@ static void bgp_update_interface_nbrs(struct bgp *bgp, struct interface *ifp, } } -static int bgp_read_fec_update(int command, struct zclient *zclient, - zebra_size_t length) +static int bgp_read_fec_update(ZAPI_CALLBACK_ARGS) { bgp_parse_fec_update(); return 0; @@ -3005,7 +3004,7 @@ static int bgp_zebra_process_local_macip(ZAPI_CALLBACK_ARGS) } } -static void bgp_zebra_process_local_ip_prefix(ZAPI_CALLBACK_ARGS) +static int bgp_zebra_process_local_ip_prefix(ZAPI_CALLBACK_ARGS) { struct stream *s = NULL; struct bgp *bgp_vrf = NULL; @@ -3017,7 +3016,7 @@ static void bgp_zebra_process_local_ip_prefix(ZAPI_CALLBACK_ARGS) bgp_vrf = bgp_lookup_by_vrf_id(vrf_id); if (!bgp_vrf) - return; + return 0; if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Recv prefix %pFX %s on vrf %s", &p, @@ -3041,9 +3040,10 @@ static void bgp_zebra_process_local_ip_prefix(ZAPI_CALLBACK_ARGS) bgp_evpn_withdraw_type5_route(bgp_vrf, &p, AFI_IP6, SAFI_UNICAST); } + return 0; } -static void bgp_zebra_process_label_chunk(ZAPI_CALLBACK_ARGS) +static int bgp_zebra_process_label_chunk(ZAPI_CALLBACK_ARGS) { struct stream *s = NULL; uint8_t response_keep; @@ -3062,12 +3062,12 @@ static void bgp_zebra_process_label_chunk(ZAPI_CALLBACK_ARGS) if (zclient->redist_default != proto) { flog_err(EC_BGP_LM_ERROR, "Got LM msg with wrong proto %u", proto); - return; + return 0; } if (zclient->instance != instance) { flog_err(EC_BGP_LM_ERROR, "Got LM msg with wrong instance %u", proto); - return; + return 0; } if (first > last || @@ -3076,7 +3076,7 @@ static void bgp_zebra_process_label_chunk(ZAPI_CALLBACK_ARGS) flog_err(EC_BGP_LM_ERROR, "%s: Invalid Label chunk: %u - %u", __func__, first, last); - return; + return 0; } if (BGP_DEBUG(zebra, ZEBRA)) { zlog_debug("Label Chunk assign: %u - %u (%u) ", @@ -3085,8 +3085,10 @@ static void bgp_zebra_process_label_chunk(ZAPI_CALLBACK_ARGS) bgp_lp_event_chunk(response_keep, first, last); + return 0; + stream_failure: /* for STREAM_GETX */ - return; + return -1; } extern struct zebra_privs_t bgpd_privs; @@ -3109,7 +3111,7 @@ static int bgp_ifp_create(struct interface *ifp) return 0; } -static void bgp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS) +static int bgp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS) { struct stream *s = NULL; struct bgp *bgp = bgp_get_default(); @@ -3124,18 +3126,19 @@ static void bgp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS) if (strcmp(bgp->srv6_locator_name, s6c.locator_name) != 0) { zlog_err("%s: Locator name unmatch %s:%s", __func__, bgp->srv6_locator_name, s6c.locator_name); - return; + return 0; } for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, c)) { if (!prefix_cmp(c, &s6c.prefix)) - return; + return 0; } chunk = prefix_ipv6_new(); *chunk = s6c.prefix; listnode_add(bgp->srv6_locator_chunks, chunk); vpn_leak_postchange_all(); + return 0; } static int bgp_zebra_process_srv6_locator_add(ZAPI_CALLBACK_ARGS) @@ -3220,6 +3223,41 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS) return 0; } +static zclient_handler *const bgp_handlers[] = { + [ZEBRA_ROUTER_ID_UPDATE] = bgp_router_id_update, + [ZEBRA_INTERFACE_ADDRESS_ADD] = bgp_interface_address_add, + [ZEBRA_INTERFACE_ADDRESS_DELETE] = bgp_interface_address_delete, + [ZEBRA_INTERFACE_NBR_ADDRESS_ADD] = bgp_interface_nbr_address_add, + [ZEBRA_INTERFACE_NBR_ADDRESS_DELETE] = bgp_interface_nbr_address_delete, + [ZEBRA_INTERFACE_VRF_UPDATE] = bgp_interface_vrf_update, + [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = zebra_read_route, + [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = zebra_read_route, + [ZEBRA_NEXTHOP_UPDATE] = bgp_read_nexthop_update, + [ZEBRA_FEC_UPDATE] = bgp_read_fec_update, + [ZEBRA_LOCAL_ES_ADD] = bgp_zebra_process_local_es_add, + [ZEBRA_LOCAL_ES_DEL] = bgp_zebra_process_local_es_del, + [ZEBRA_VNI_ADD] = bgp_zebra_process_local_vni, + [ZEBRA_LOCAL_ES_EVI_ADD] = bgp_zebra_process_local_es_evi, + [ZEBRA_LOCAL_ES_EVI_DEL] = bgp_zebra_process_local_es_evi, + [ZEBRA_VNI_DEL] = bgp_zebra_process_local_vni, + [ZEBRA_MACIP_ADD] = bgp_zebra_process_local_macip, + [ZEBRA_MACIP_DEL] = bgp_zebra_process_local_macip, + [ZEBRA_L3VNI_ADD] = bgp_zebra_process_local_l3vni, + [ZEBRA_L3VNI_DEL] = bgp_zebra_process_local_l3vni, + [ZEBRA_IP_PREFIX_ROUTE_ADD] = bgp_zebra_process_local_ip_prefix, + [ZEBRA_IP_PREFIX_ROUTE_DEL] = bgp_zebra_process_local_ip_prefix, + [ZEBRA_GET_LABEL_CHUNK] = bgp_zebra_process_label_chunk, + [ZEBRA_RULE_NOTIFY_OWNER] = rule_notify_owner, + [ZEBRA_IPSET_NOTIFY_OWNER] = ipset_notify_owner, + [ZEBRA_IPSET_ENTRY_NOTIFY_OWNER] = ipset_entry_notify_owner, + [ZEBRA_IPTABLE_NOTIFY_OWNER] = iptable_notify_owner, + [ZEBRA_ROUTE_NOTIFY_OWNER] = bgp_zebra_route_notify_owner, + [ZEBRA_SRV6_LOCATOR_ADD] = bgp_zebra_process_srv6_locator_add, + [ZEBRA_SRV6_LOCATOR_DELETE] = bgp_zebra_process_srv6_locator_delete, + [ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK] = + bgp_zebra_process_srv6_locator_chunk, +}; + void bgp_zebra_init(struct thread_master *master, unsigned short instance) { zclient_num_connects = 0; @@ -3228,43 +3266,11 @@ void bgp_zebra_init(struct thread_master *master, unsigned short instance) bgp_ifp_down, bgp_ifp_destroy); /* Set default values. */ - zclient = zclient_new(master, &zclient_options_default); + zclient = zclient_new(master, &zclient_options_default, bgp_handlers, + array_size(bgp_handlers)); zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs); zclient->zebra_connected = bgp_zebra_connected; - zclient->router_id_update = bgp_router_id_update; - zclient->interface_address_add = bgp_interface_address_add; - zclient->interface_address_delete = bgp_interface_address_delete; - zclient->interface_nbr_address_add = bgp_interface_nbr_address_add; - zclient->interface_nbr_address_delete = - bgp_interface_nbr_address_delete; - zclient->interface_vrf_update = bgp_interface_vrf_update; - zclient->redistribute_route_add = zebra_read_route; - zclient->redistribute_route_del = zebra_read_route; - zclient->nexthop_update = bgp_read_nexthop_update; - zclient->fec_update = bgp_read_fec_update; - zclient->local_es_add = bgp_zebra_process_local_es_add; - zclient->local_es_del = bgp_zebra_process_local_es_del; - zclient->local_vni_add = bgp_zebra_process_local_vni; - zclient->local_es_evi_add = bgp_zebra_process_local_es_evi; - zclient->local_es_evi_del = bgp_zebra_process_local_es_evi; - zclient->local_vni_del = bgp_zebra_process_local_vni; - zclient->local_macip_add = bgp_zebra_process_local_macip; - zclient->local_macip_del = bgp_zebra_process_local_macip; - zclient->local_l3vni_add = bgp_zebra_process_local_l3vni; - zclient->local_l3vni_del = bgp_zebra_process_local_l3vni; - zclient->local_ip_prefix_add = bgp_zebra_process_local_ip_prefix; - zclient->local_ip_prefix_del = bgp_zebra_process_local_ip_prefix; - zclient->label_chunk = bgp_zebra_process_label_chunk; - zclient->rule_notify_owner = rule_notify_owner; - zclient->ipset_notify_owner = ipset_notify_owner; - zclient->ipset_entry_notify_owner = ipset_entry_notify_owner; - zclient->iptable_notify_owner = iptable_notify_owner; - zclient->route_notify_owner = bgp_zebra_route_notify_owner; zclient->instance = instance; - zclient->srv6_locator_add = bgp_zebra_process_srv6_locator_add; - zclient->srv6_locator_delete = bgp_zebra_process_srv6_locator_delete; - zclient->process_srv6_locator_chunk = - bgp_zebra_process_srv6_locator_chunk; } void bgp_zebra_destroy(void) |