summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--babeld/babel_zebra.c14
-rw-r--r--bfdd/ptm_adapter.c31
-rw-r--r--bgpd/bgp_open.c129
-rw-r--r--bgpd/bgp_route.c30
-rw-r--r--bgpd/bgp_route.h5
-rw-r--r--bgpd/bgp_vty.c1
-rw-r--r--bgpd/bgp_zebra.c103
-rw-r--r--bgpd/bgpd.c10
-rw-r--r--bgpd/rfapi/vnc_zebra.c11
-rw-r--r--doc/user/bgp.rst9
-rw-r--r--eigrpd/eigrp_zebra.c18
-rw-r--r--include/linux/nexthop.h59
-rw-r--r--isisd/isis_zebra.c28
-rw-r--r--ldpd/lde.c2
-rw-r--r--ldpd/ldp_zebra.c20
-rw-r--r--lib/bfd.c15
-rw-r--r--lib/route_opaque.h6
-rw-r--r--lib/zclient.c357
-rw-r--r--lib/zclient.h82
-rw-r--r--nhrpd/netlink_arp.c9
-rw-r--r--nhrpd/nhrp_route.c30
-rw-r--r--nhrpd/nhrpd.h4
-rw-r--r--ospf6d/ospf6_zebra.c19
-rw-r--r--ospfd/ospf_zebra.c32
-rw-r--r--pathd/path_zebra.c14
-rw-r--r--pbrd/pbr_zebra.c18
-rw-r--r--pimd/pim_mlag.c8
-rw-r--r--pimd/pim_mlag.h7
-rw-r--r--pimd/pim_zebra.c28
-rw-r--r--pimd/pim_zlookup.c2
-rw-r--r--ripd/rip_zebra.c16
-rw-r--r--ripngd/ripng_zebra.c16
-rw-r--r--sharpd/sharp_zebra.c44
-rw-r--r--staticd/static_zebra.c14
-rw-r--r--tests/bgpd/test_mpath.c2
-rw-r--r--tests/topotests/bfd_isis_topo1/test_bfd_isis_topo1.py2
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/scripts/adjacencies.py7
-rw-r--r--vrrpd/vrrp_zebra.c12
-rw-r--r--zebra/debug_nl.c1
-rw-r--r--zebra/kernel_netlink.h4
-rw-r--r--zebra/zapi_msg.c1
-rw-r--r--zebra/zebra_vty.c5
42 files changed, 545 insertions, 680 deletions
diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c
index d10d418572..d0da93e507 100644
--- a/babeld/babel_zebra.c
+++ b/babeld/babel_zebra.c
@@ -234,16 +234,20 @@ babel_zebra_connected (struct zclient *zclient)
zclient_send_reg_requests (zclient, VRF_DEFAULT);
}
+static zclient_handler *const babel_handlers[] = {
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = babel_interface_address_add,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = babel_interface_address_delete,
+ [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = babel_zebra_read_route,
+ [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = babel_zebra_read_route,
+};
+
void babelz_zebra_init(void)
{
- zclient = zclient_new(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default, babel_handlers,
+ array_size(babel_handlers));
zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0, &babeld_privs);
zclient->zebra_connected = babel_zebra_connected;
- zclient->interface_address_add = babel_interface_address_add;
- zclient->interface_address_delete = babel_interface_address_delete;
- zclient->redistribute_route_add = babel_zebra_read_route;
- zclient->redistribute_route_del = babel_zebra_read_route;
install_element(BABEL_NODE, &babel_redistribute_type_cmd);
install_element(ENABLE_NODE, &debug_babel_cmd);
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index 838acf450f..434d79c8f5 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -844,29 +844,32 @@ static int bfd_ifp_create(struct interface *ifp)
return 0;
}
-void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
-{
- if_zapi_callbacks(bfd_ifp_create, NULL, NULL, bfd_ifp_destroy);
- zclient = zclient_new(master, &zclient_options_default);
- assert(zclient != NULL);
- zclient_init(zclient, ZEBRA_ROUTE_BFD, 0, bfdd_priv);
-
+static zclient_handler *const bfd_handlers[] = {
/*
* We'll receive all messages through replay, however it will
* contain a special field with the real command inside so we
* avoid having to create too many handlers.
*/
- zclient->bfd_dest_replay = bfdd_replay;
-
- /* Send replay request on zebra connect. */
- zclient->zebra_connected = bfdd_zebra_connected;
+ [ZEBRA_BFD_DEST_REPLAY] = bfdd_replay,
/* Learn about interface VRF. */
- zclient->interface_vrf_update = bfdd_interface_vrf_update;
+ [ZEBRA_INTERFACE_VRF_UPDATE] = bfdd_interface_vrf_update,
/* Learn about new addresses being registered. */
- zclient->interface_address_add = bfdd_interface_address_update;
- zclient->interface_address_delete = bfdd_interface_address_update;
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = bfdd_interface_address_update,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = bfdd_interface_address_update,
+};
+
+void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
+{
+ if_zapi_callbacks(bfd_ifp_create, NULL, NULL, bfd_ifp_destroy);
+ zclient = zclient_new(master, &zclient_options_default, bfd_handlers,
+ array_size(bfd_handlers));
+ assert(zclient != NULL);
+ zclient_init(zclient, ZEBRA_ROUTE_BFD, 0, bfdd_priv);
+
+ /* Send replay request on zebra connect. */
+ zclient->zebra_connected = bfdd_zebra_connected;
}
void bfdd_zclient_register(vrf_id_t vrf_id)
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index f1dfebdc1b..ca8b1e398b 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -42,6 +42,63 @@
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_memory.h"
+static const struct message capcode_str[] = {
+ {CAPABILITY_CODE_MP, "MultiProtocol Extensions"},
+ {CAPABILITY_CODE_REFRESH, "Route Refresh"},
+ {CAPABILITY_CODE_ORF, "Cooperative Route Filtering"},
+ {CAPABILITY_CODE_RESTART, "Graceful Restart"},
+ {CAPABILITY_CODE_AS4, "4-octet AS number"},
+ {CAPABILITY_CODE_ADDPATH, "AddPath"},
+ {CAPABILITY_CODE_DYNAMIC, "Dynamic"},
+ {CAPABILITY_CODE_ENHE, "Extended Next Hop Encoding"},
+ {CAPABILITY_CODE_DYNAMIC_OLD, "Dynamic (Old)"},
+ {CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)"},
+ {CAPABILITY_CODE_ORF_OLD, "ORF (Old)"},
+ {CAPABILITY_CODE_FQDN, "FQDN"},
+ {CAPABILITY_CODE_ENHANCED_RR, "Enhanced Route Refresh"},
+ {CAPABILITY_CODE_EXT_MESSAGE, "BGP Extended Message"},
+ {0}};
+
+/* Minimum sizes for length field of each cap (so not inc. the header) */
+static const size_t cap_minsizes[] = {
+ [CAPABILITY_CODE_MP] = CAPABILITY_CODE_MP_LEN,
+ [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
+ [CAPABILITY_CODE_ORF] = CAPABILITY_CODE_ORF_LEN,
+ [CAPABILITY_CODE_RESTART] = CAPABILITY_CODE_RESTART_LEN,
+ [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
+ [CAPABILITY_CODE_ADDPATH] = CAPABILITY_CODE_ADDPATH_LEN,
+ [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
+ [CAPABILITY_CODE_DYNAMIC_OLD] = CAPABILITY_CODE_DYNAMIC_LEN,
+ [CAPABILITY_CODE_ENHE] = CAPABILITY_CODE_ENHE_LEN,
+ [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
+ [CAPABILITY_CODE_ORF_OLD] = CAPABILITY_CODE_ORF_LEN,
+ [CAPABILITY_CODE_FQDN] = CAPABILITY_CODE_MIN_FQDN_LEN,
+ [CAPABILITY_CODE_ENHANCED_RR] = CAPABILITY_CODE_ENHANCED_LEN,
+ [CAPABILITY_CODE_EXT_MESSAGE] = CAPABILITY_CODE_EXT_MESSAGE_LEN,
+};
+
+/* value the capability must be a multiple of.
+ * 0-data capabilities won't be checked against this.
+ * Other capabilities whose data doesn't fall on convenient boundaries for this
+ * table should be set to 1.
+ */
+static const size_t cap_modsizes[] = {
+ [CAPABILITY_CODE_MP] = 4,
+ [CAPABILITY_CODE_REFRESH] = 1,
+ [CAPABILITY_CODE_ORF] = 1,
+ [CAPABILITY_CODE_RESTART] = 1,
+ [CAPABILITY_CODE_AS4] = 4,
+ [CAPABILITY_CODE_ADDPATH] = 4,
+ [CAPABILITY_CODE_DYNAMIC] = 1,
+ [CAPABILITY_CODE_DYNAMIC_OLD] = 1,
+ [CAPABILITY_CODE_ENHE] = 6,
+ [CAPABILITY_CODE_REFRESH_OLD] = 1,
+ [CAPABILITY_CODE_ORF_OLD] = 1,
+ [CAPABILITY_CODE_FQDN] = 1,
+ [CAPABILITY_CODE_ENHANCED_RR] = 1,
+ [CAPABILITY_CODE_EXT_MESSAGE] = 1,
+};
+
/* BGP-4 Multiprotocol Extentions lead us to the complex world. We can
negotiate remote peer supports extentions or not. But if
remote-peer doesn't supports negotiation process itself. We would
@@ -264,9 +321,9 @@ static int bgp_capability_mp(struct peer *peer, struct capability_header *hdr)
bgp_capability_mp_data(s, &mpc);
if (bgp_debug_neighbor_events(peer))
- zlog_debug("%s OPEN has MP_EXT CAP for afi/safi: %s/%s",
- peer->host, iana_afi2str(mpc.afi),
- iana_safi2str(mpc.safi));
+ zlog_debug("%s OPEN has %s capability for afi/safi: %s/%s",
+ peer->host, lookup_msg(capcode_str, hdr->code, NULL),
+ iana_afi2str(mpc.afi), iana_safi2str(mpc.safi));
/* Convert AFI, SAFI to internal values, check. */
if (bgp_map_afi_safi_iana2int(mpc.afi, mpc.safi, &afi, &safi))
@@ -466,8 +523,6 @@ static int bgp_capability_restart(struct peer *peer,
peer->v_gr_restart = restart_flag_time;
if (bgp_debug_neighbor_events(peer)) {
- zlog_debug("%s OPEN has Graceful Restart capability",
- peer->host);
zlog_debug("%s Peer has%srestarted. Restart Time : %d",
peer->host,
CHECK_FLAG(peer->cap, PEER_CAP_RESTART_BIT_RCV)
@@ -580,9 +635,10 @@ static int bgp_capability_addpath(struct peer *peer,
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s OPEN has AddPath CAP for afi/safi: %s/%s%s%s",
- peer->host, iana_afi2str(pkt_afi),
- iana_safi2str(pkt_safi),
+ "%s OPEN has %s capability for afi/safi: %s/%s%s%s",
+ peer->host,
+ lookup_msg(capcode_str, hdr->code, NULL),
+ iana_afi2str(pkt_afi), iana_safi2str(pkt_safi),
(send_receive & BGP_ADDPATH_RX) ? ", receive"
: "",
(send_receive & BGP_ADDPATH_TX) ? ", transmit"
@@ -763,63 +819,6 @@ static int bgp_capability_hostname(struct peer *peer,
return 0;
}
-static const struct message capcode_str[] = {
- {CAPABILITY_CODE_MP, "MultiProtocol Extensions"},
- {CAPABILITY_CODE_REFRESH, "Route Refresh"},
- {CAPABILITY_CODE_ORF, "Cooperative Route Filtering"},
- {CAPABILITY_CODE_RESTART, "Graceful Restart"},
- {CAPABILITY_CODE_AS4, "4-octet AS number"},
- {CAPABILITY_CODE_ADDPATH, "AddPath"},
- {CAPABILITY_CODE_DYNAMIC, "Dynamic"},
- {CAPABILITY_CODE_ENHE, "Extended Next Hop Encoding"},
- {CAPABILITY_CODE_DYNAMIC_OLD, "Dynamic (Old)"},
- {CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)"},
- {CAPABILITY_CODE_ORF_OLD, "ORF (Old)"},
- {CAPABILITY_CODE_FQDN, "FQDN"},
- {CAPABILITY_CODE_ENHANCED_RR, "Enhanced Route Refresh"},
- {CAPABILITY_CODE_EXT_MESSAGE, "BGP Extended Message"},
- {0}};
-
-/* Minimum sizes for length field of each cap (so not inc. the header) */
-static const size_t cap_minsizes[] = {
- [CAPABILITY_CODE_MP] = CAPABILITY_CODE_MP_LEN,
- [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
- [CAPABILITY_CODE_ORF] = CAPABILITY_CODE_ORF_LEN,
- [CAPABILITY_CODE_RESTART] = CAPABILITY_CODE_RESTART_LEN,
- [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
- [CAPABILITY_CODE_ADDPATH] = CAPABILITY_CODE_ADDPATH_LEN,
- [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
- [CAPABILITY_CODE_DYNAMIC_OLD] = CAPABILITY_CODE_DYNAMIC_LEN,
- [CAPABILITY_CODE_ENHE] = CAPABILITY_CODE_ENHE_LEN,
- [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
- [CAPABILITY_CODE_ORF_OLD] = CAPABILITY_CODE_ORF_LEN,
- [CAPABILITY_CODE_FQDN] = CAPABILITY_CODE_MIN_FQDN_LEN,
- [CAPABILITY_CODE_ENHANCED_RR] = CAPABILITY_CODE_ENHANCED_LEN,
- [CAPABILITY_CODE_EXT_MESSAGE] = CAPABILITY_CODE_EXT_MESSAGE_LEN,
-};
-
-/* value the capability must be a multiple of.
- * 0-data capabilities won't be checked against this.
- * Other capabilities whose data doesn't fall on convenient boundaries for this
- * table should be set to 1.
- */
-static const size_t cap_modsizes[] = {
- [CAPABILITY_CODE_MP] = 4,
- [CAPABILITY_CODE_REFRESH] = 1,
- [CAPABILITY_CODE_ORF] = 1,
- [CAPABILITY_CODE_RESTART] = 1,
- [CAPABILITY_CODE_AS4] = 4,
- [CAPABILITY_CODE_ADDPATH] = 4,
- [CAPABILITY_CODE_DYNAMIC] = 1,
- [CAPABILITY_CODE_DYNAMIC_OLD] = 1,
- [CAPABILITY_CODE_ENHE] = 6,
- [CAPABILITY_CODE_REFRESH_OLD] = 1,
- [CAPABILITY_CODE_ORF_OLD] = 1,
- [CAPABILITY_CODE_FQDN] = 1,
- [CAPABILITY_CODE_ENHANCED_RR] = 1,
- [CAPABILITY_CODE_EXT_MESSAGE] = 1,
-};
-
/**
* Parse given capability.
* XXX: This is reading into a stream, but not using stream API
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 2a84f548f8..4b798cc264 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -8433,8 +8433,7 @@ enum bgp_display_type {
normal_list,
};
-static const char *
-bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
+const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
{
switch (reason) {
case bgp_path_selection_none:
@@ -13451,16 +13450,6 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
bgp = peer->bgp;
- if (!bgp) {
- if (use_json) {
- json_object_string_add(json, "alert", "no BGP");
- vty_out(vty, "%s\n", json_object_to_json_string(json));
- json_object_free(json);
- } else
- vty_out(vty, "%% No bgp\n");
- return;
- }
-
subgrp = peer_subgroup(peer, afi, safi);
if (type == bgp_show_adj_route_advertised && subgrp
@@ -13701,6 +13690,9 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
"No such neighbor or address family");
vty_out(vty, "%s\n", json_object_to_json_string(json));
json_object_free(json);
+ json_object_free(json_ar);
+ json_object_free(json_scode);
+ json_object_free(json_ocode);
} else
vty_out(vty, "%% No such neighbor or address family\n");
@@ -13717,6 +13709,9 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
"Inbound soft reconfiguration not enabled");
vty_out(vty, "%s\n", json_object_to_json_string(json));
json_object_free(json);
+ json_object_free(json_ar);
+ json_object_free(json_scode);
+ json_object_free(json_ocode);
} else
vty_out(vty,
"%% Inbound soft reconfiguration not enabled\n");
@@ -13785,14 +13780,17 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
- if (!output_count && !filtered_count) {
+ /*
+ * These fields only give up ownership to `json` when `header1`
+ * is used (set to zero). See code in `show_adj_route` and
+ * `show_adj_route_header`.
+ */
+ if (header1 == 1) {
json_object_free(json_scode);
json_object_free(json_ocode);
}
- if (json)
- json_object_free(json);
-
+ json_object_free(json);
} else if (output_count > 0) {
if (filtered_count > 0)
vty_out(vty,
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 37bf675b67..46802d0d14 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -90,6 +90,9 @@ enum bgp_show_adj_route_type {
/* Maximum number of sids we can process or send with a prefix. */
#define BGP_MAX_SIDS 6
+/* Maximum buffer length for storing BGP best path selection reason */
+#define BGP_MAX_SELECTION_REASON_STR_BUF 32
+
/* Error codes for handling NLRI */
#define BGP_NLRI_PARSE_OK 0
#define BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW -1
@@ -803,4 +806,6 @@ extern void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
const struct prefix *p, afi_t afi,
safi_t safi, bool suppress);
extern void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr);
+const char *
+bgp_path_selection_reason2str(enum bgp_path_selection_reason reason);
#endif /* _QUAGGA_BGP_ROUTE_H */
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 158a5f30b7..772e20dc85 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -10241,6 +10241,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
count = 0; /* Reset the value as its used again */
filtered_count = 0;
+ dn_count = 0;
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
continue;
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 6161f56fe6..6c9eb2972c 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;
@@ -1490,6 +1489,8 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
if (is_add && CHECK_FLAG(bm->flags, BM_FLAG_SEND_EXTRA_DATA_TO_ZEBRA)) {
struct bgp_zebra_opaque bzo = {};
+ const char *reason =
+ bgp_path_selection_reason2str(dest->reason);
strlcpy(bzo.aspath, info->attr->aspath->str,
sizeof(bzo.aspath));
@@ -1503,6 +1504,9 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
strlcpy(bzo.lcommunity, info->attr->lcommunity->str,
sizeof(bzo.lcommunity));
+ strlcpy(bzo.selection_reason, reason,
+ sizeof(bzo.selection_reason));
+
SET_FLAG(api.message, ZAPI_MESSAGE_OPAQUE);
api.opaque.length = MIN(sizeof(struct bgp_zebra_opaque),
ZAPI_MESSAGE_OPAQUE_LENGTH);
@@ -3005,7 +3009,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 +3021,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 +3045,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 +3067,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 +3081,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 +3090,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 +3116,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 +3131,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 +3228,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 +3271,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)
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index b191029d2f..c5a5e49a48 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -4775,6 +4775,7 @@ int peer_ebgp_multihop_unset(struct peer *peer)
{
struct peer_group *group;
struct listnode *node, *nnode;
+ int ttl;
if (peer->sort == BGP_PEER_IBGP)
return 0;
@@ -4783,9 +4784,14 @@ int peer_ebgp_multihop_unset(struct peer *peer)
return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
if (peer_group_active(peer))
- peer->ttl = peer->group->conf->ttl;
+ ttl = peer->group->conf->ttl;
else
- peer->ttl = BGP_DEFAULT_TTL;
+ ttl = BGP_DEFAULT_TTL;
+
+ if (ttl == peer->ttl)
+ return 0;
+
+ peer->ttl = ttl;
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c
index ba849e4e0b..672a0e9780 100644
--- a/bgpd/rfapi/vnc_zebra.c
+++ b/bgpd/rfapi/vnc_zebra.c
@@ -895,6 +895,11 @@ int vnc_redistribute_unset(struct bgp *bgp, afi_t afi, int type)
extern struct zebra_privs_t bgpd_privs;
+static zclient_handler *const vnc_handlers[] = {
+ [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = vnc_zebra_read_route,
+ [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = vnc_zebra_read_route,
+};
+
/*
* Modeled after bgp_zebra.c'bgp_zebra_init()
* Charriere asks, "Is it possible to carry two?"
@@ -902,11 +907,9 @@ extern struct zebra_privs_t bgpd_privs;
void vnc_zebra_init(struct thread_master *master)
{
/* Set default values. */
- zclient_vnc = zclient_new(master, &zclient_options_default);
+ zclient_vnc = zclient_new(master, &zclient_options_default,
+ vnc_handlers, array_size(vnc_handlers));
zclient_init(zclient_vnc, ZEBRA_ROUTE_VNC, 0, &bgpd_privs);
-
- zclient_vnc->redistribute_route_add = vnc_zebra_read_route;
- zclient_vnc->redistribute_route_del = vnc_zebra_read_route;
}
void vnc_zebra_destroy(void)
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 5fcddafaaa..1793ae3d27 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -1425,15 +1425,6 @@ Configuring Peers
Set description of the peer.
-.. clicmd:: neighbor PEER version VERSION
-
- Set up the neighbor's BGP version. `version` can be `4`, `4+` or `4-`. BGP
- version `4` is the default value used for BGP peering. BGP version `4+`
- means that the neighbor supports Multiprotocol Extensions for BGP-4. BGP
- version `4-` is similar but the neighbor speaks the old Internet-Draft
- revision 00's Multiprotocol Extensions for BGP-4. Some routing software is
- still using this version.
-
.. clicmd:: neighbor PEER interface IFNAME
When you connect to a BGP peer over an IPv6 link-local address, you have to
diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c
index 7c765248c6..89dd5be272 100644
--- a/eigrpd/eigrp_zebra.c
+++ b/eigrpd/eigrp_zebra.c
@@ -102,20 +102,24 @@ static void eigrp_zebra_connected(struct zclient *zclient)
zclient_send_reg_requests(zclient, VRF_DEFAULT);
}
+static zclient_handler *const eigrp_handlers[] = {
+ [ZEBRA_ROUTER_ID_UPDATE] = eigrp_router_id_update_zebra,
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = eigrp_interface_address_add,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = eigrp_interface_address_delete,
+ [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = eigrp_zebra_read_route,
+ [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = eigrp_zebra_read_route,
+ [ZEBRA_ROUTE_NOTIFY_OWNER] = eigrp_zebra_route_notify_owner,
+};
+
void eigrp_zebra_init(void)
{
struct zclient_options opt = {.receive_notify = false};
- zclient = zclient_new(master, &opt);
+ zclient = zclient_new(master, &opt, eigrp_handlers,
+ array_size(eigrp_handlers));
zclient_init(zclient, ZEBRA_ROUTE_EIGRP, 0, &eigrpd_privs);
zclient->zebra_connected = eigrp_zebra_connected;
- zclient->router_id_update = eigrp_router_id_update_zebra;
- zclient->interface_address_add = eigrp_interface_address_add;
- zclient->interface_address_delete = eigrp_interface_address_delete;
- zclient->redistribute_route_add = eigrp_zebra_read_route;
- zclient->redistribute_route_del = eigrp_zebra_read_route;
- zclient->route_notify_owner = eigrp_zebra_route_notify_owner;
}
diff --git a/include/linux/nexthop.h b/include/linux/nexthop.h
index ee2a15b9c7..d8ffa8c9ca 100644
--- a/include/linux/nexthop.h
+++ b/include/linux/nexthop.h
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _LINUX_NEXTHOP_H
-#define _LINUX_NEXTHOP_H
+#ifndef _UAPI_LINUX_NEXTHOP_H
+#define _UAPI_LINUX_NEXTHOP_H
#include <linux/types.h>
-#define RTM_NHA(h) ((struct rtattr *)(((char *)(h)) + \
- NLMSG_ALIGN(sizeof(struct nhmsg))))
-
struct nhmsg {
unsigned char nh_family;
unsigned char nh_scope; /* return only */
@@ -15,6 +12,7 @@ struct nhmsg {
unsigned int nh_flags; /* RTNH_F flags */
};
+/* entry in a nexthop group */
struct nexthop_grp {
__u32 id; /* nexthop id - must exist */
__u8 weight; /* weight of this nexthop */
@@ -23,7 +21,10 @@ struct nexthop_grp {
};
enum {
- NEXTHOP_GRP_TYPE_MPATH, /* default type if not specified */
+ NEXTHOP_GRP_TYPE_MPATH, /* hash-threshold nexthop group
+ * default type if not specified
+ */
+ NEXTHOP_GRP_TYPE_RES, /* resilient nexthop group */
__NEXTHOP_GRP_TYPE_MAX,
};
@@ -50,10 +51,54 @@ enum {
*/
NHA_GROUPS, /* flag; only return nexthop groups in dump */
NHA_MASTER, /* u32; only return nexthops with given master dev */
- NHA_FDB, /* nexthop belongs to a bridge fdb */
+
+ NHA_FDB, /* flag; nexthop belongs to a bridge fdb */
+ /* if NHA_FDB is added, OIF, BLACKHOLE, ENCAP cannot be set */
+
+ /* nested; resilient nexthop group attributes */
+ NHA_RES_GROUP,
+ /* nested; nexthop bucket attributes */
+ NHA_RES_BUCKET,
__NHA_MAX,
};
#define NHA_MAX (__NHA_MAX - 1)
+
+enum {
+ NHA_RES_GROUP_UNSPEC,
+ /* Pad attribute for 64-bit alignment. */
+ NHA_RES_GROUP_PAD = NHA_RES_GROUP_UNSPEC,
+
+ /* u16; number of nexthop buckets in a resilient nexthop group */
+ NHA_RES_GROUP_BUCKETS,
+ /* clock_t as u32; nexthop bucket idle timer (per-group) */
+ NHA_RES_GROUP_IDLE_TIMER,
+ /* clock_t as u32; nexthop unbalanced timer */
+ NHA_RES_GROUP_UNBALANCED_TIMER,
+ /* clock_t as u64; nexthop unbalanced time */
+ NHA_RES_GROUP_UNBALANCED_TIME,
+
+ __NHA_RES_GROUP_MAX,
+};
+
+#define NHA_RES_GROUP_MAX (__NHA_RES_GROUP_MAX - 1)
+
+enum {
+ NHA_RES_BUCKET_UNSPEC,
+ /* Pad attribute for 64-bit alignment. */
+ NHA_RES_BUCKET_PAD = NHA_RES_BUCKET_UNSPEC,
+
+ /* u16; nexthop bucket index */
+ NHA_RES_BUCKET_INDEX,
+ /* clock_t as u64; nexthop bucket idle time */
+ NHA_RES_BUCKET_IDLE_TIME,
+ /* u32; nexthop id assigned to the nexthop bucket */
+ NHA_RES_BUCKET_NH_ID,
+
+ __NHA_RES_BUCKET_MAX,
+};
+
+#define NHA_RES_BUCKET_MAX (__NHA_RES_BUCKET_MAX - 1)
+
#endif
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index 2c05cb8277..27e80e2501 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -800,23 +800,31 @@ static int isis_zebra_client_close_notify(ZAPI_CALLBACK_ARGS)
return ret;
}
+static zclient_handler *const isis_handlers[] = {
+ [ZEBRA_ROUTER_ID_UPDATE] = isis_router_id_update_zebra,
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = isis_zebra_if_address_add,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = isis_zebra_if_address_del,
+ [ZEBRA_INTERFACE_LINK_PARAMS] = isis_zebra_link_params,
+ [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = isis_zebra_read,
+ [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = isis_zebra_read,
+
+ [ZEBRA_OPAQUE_MESSAGE] = isis_opaque_msg_handler,
+
+ [ZEBRA_CLIENT_CLOSE_NOTIFY] = isis_zebra_client_close_notify,
+};
+
void isis_zebra_init(struct thread_master *master, int instance)
{
/* Initialize asynchronous zclient. */
- zclient = zclient_new(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default, isis_handlers,
+ array_size(isis_handlers));
zclient_init(zclient, PROTO_TYPE, 0, &isisd_privs);
zclient->zebra_connected = isis_zebra_connected;
- zclient->router_id_update = isis_router_id_update_zebra;
- zclient->interface_address_add = isis_zebra_if_address_add;
- zclient->interface_address_delete = isis_zebra_if_address_del;
- zclient->interface_link_params = isis_zebra_link_params;
- zclient->redistribute_route_add = isis_zebra_read;
- zclient->redistribute_route_del = isis_zebra_read;
/* Initialize special zclient for synchronous message exchanges. */
struct zclient_options options = zclient_options_default;
options.synchronous = true;
- zclient_sync = zclient_new(master, &options);
+ zclient_sync = zclient_new(master, &options, NULL, 0);
zclient_sync->sock = -1;
zclient_sync->redist_default = ZEBRA_ROUTE_ISIS;
zclient_sync->instance = instance;
@@ -826,10 +834,6 @@ void isis_zebra_init(struct thread_master *master, int instance)
*/
zclient_sync->session_id = 1;
zclient_sync->privs = &isisd_privs;
-
- zclient->opaque_msg_handler = isis_opaque_msg_handler;
-
- zclient->zebra_client_close_notify = isis_zebra_client_close_notify;
}
void isis_zebra_stop(void)
diff --git a/ldpd/lde.c b/ldpd/lde.c
index babadc461f..0956310367 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -2192,7 +2192,7 @@ static void zclient_sync_init(void)
options.synchronous = true;
/* Initialize special zclient for synchronous message exchanges. */
- zclient_sync = zclient_new(master, &options);
+ zclient_sync = zclient_new(master, &options, NULL, 0);
zclient_sync->sock = -1;
zclient_sync->redist_default = ZEBRA_ROUTE_LDP;
zclient_sync->session_id = 1; /* Distinguish from main session */
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index 2d90412d17..059115915a 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -694,6 +694,16 @@ ldp_zebra_filter_update(struct access_list *access)
extern struct zebra_privs_t ldpd_privs;
+static zclient_handler *const ldp_handlers[] = {
+ [ZEBRA_ROUTER_ID_UPDATE] = ldp_router_id_update,
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = ldp_interface_address_add,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = ldp_interface_address_delete,
+ [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ldp_zebra_read_route,
+ [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ldp_zebra_read_route,
+ [ZEBRA_PW_STATUS_UPDATE] = ldp_zebra_read_pw_status_update,
+ [ZEBRA_OPAQUE_MESSAGE] = ldp_zebra_opaque_msg_handler,
+};
+
void
ldp_zebra_init(struct thread_master *master)
{
@@ -701,18 +711,12 @@ ldp_zebra_init(struct thread_master *master)
ldp_ifp_down, ldp_ifp_destroy);
/* Set default values. */
- zclient = zclient_new(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default, ldp_handlers,
+ array_size(ldp_handlers));
zclient_init(zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs);
/* set callbacks */
zclient->zebra_connected = ldp_zebra_connected;
- zclient->router_id_update = ldp_router_id_update;
- zclient->interface_address_add = ldp_interface_address_add;
- zclient->interface_address_delete = ldp_interface_address_delete;
- zclient->redistribute_route_add = ldp_zebra_read_route;
- zclient->redistribute_route_del = ldp_zebra_read_route;
- zclient->pw_status_update = ldp_zebra_read_pw_status_update;
- zclient->opaque_msg_handler = ldp_zebra_opaque_msg_handler;
/* Access list initialize. */
access_list_add_hook(ldp_zebra_filter_update);
diff --git a/lib/bfd.c b/lib/bfd.c
index 5a8a46b67b..70cbe0f2a6 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -821,10 +821,13 @@ void bfd_sess_show(struct vty *vty, struct json_object *json,
*
* Use this as `zclient` `bfd_dest_replay` callback.
*/
-static int zclient_bfd_session_reply(ZAPI_CALLBACK_ARGS)
+int zclient_bfd_session_reply(ZAPI_CALLBACK_ARGS)
{
struct bfd_session_params *bsp;
+ if (!zclient->bfd_integration)
+ return 0;
+
/* Do nothing when shutting down. */
if (bsglobal.shutting_down)
return 0;
@@ -855,7 +858,7 @@ static int zclient_bfd_session_reply(ZAPI_CALLBACK_ARGS)
return 0;
}
-static int zclient_bfd_session_update(ZAPI_CALLBACK_ARGS)
+int zclient_bfd_session_update(ZAPI_CALLBACK_ARGS)
{
struct bfd_session_params *bsp, *bspn;
size_t sessions_updated = 0;
@@ -868,6 +871,9 @@ static int zclient_bfd_session_update(ZAPI_CALLBACK_ARGS)
struct prefix sp;
char ifstr[128], cbitstr[32];
+ if (!zclient->bfd_integration)
+ return 0;
+
/* Do nothing when shutting down. */
if (bsglobal.shutting_down)
return 0;
@@ -969,9 +975,8 @@ void bfd_protocol_integration_init(struct zclient *zc, struct thread_master *tm)
bsglobal.zc = zc;
bsglobal.tm = tm;
- /* Install our callbacks. */
- zc->interface_bfd_dest_update = zclient_bfd_session_update;
- zc->bfd_dest_replay = zclient_bfd_session_reply;
+ /* Enable BFD callbacks. */
+ zc->bfd_integration = true;
/* Send the client registration */
bfd_client_sendmsg(zc, ZEBRA_BFD_CLIENT_REGISTER, VRF_DEFAULT);
diff --git a/lib/route_opaque.h b/lib/route_opaque.h
index 7c4e9a16e1..c5e7d6a327 100644
--- a/lib/route_opaque.h
+++ b/lib/route_opaque.h
@@ -36,6 +36,12 @@ struct bgp_zebra_opaque {
/* Show at least 10 large-communities AA:BB:CC */
char lcommunity[LCOMMUNITY_SIZE * 30];
+
+ /* 32 bytes seems enough because of
+ * bgp_path_selection_confed_as_path which is
+ * `Confederation based AS Path`.
+ */
+ char selection_reason[BGP_MAX_SELECTION_REASON_STR_BUF];
};
static_assert(sizeof(struct bgp_zebra_opaque) <= ZAPI_MESSAGE_OPAQUE_LENGTH,
diff --git a/lib/zclient.c b/lib/zclient.c
index 90439d5e17..24546f3c45 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -66,7 +66,8 @@ static int zclient_debug;
/* Allocate zclient structure. */
struct zclient *zclient_new(struct thread_master *master,
- struct zclient_options *opt)
+ struct zclient_options *opt,
+ zclient_handler *const *handlers, size_t n_handlers)
{
struct zclient *zclient;
size_t stream_size =
@@ -79,6 +80,9 @@ struct zclient *zclient_new(struct thread_master *master,
zclient->wb = buffer_new(0);
zclient->master = master;
+ zclient->handlers = handlers;
+ zclient->n_handlers = n_handlers;
+
zclient->receive_notify = opt->receive_notify;
zclient->synchronous = opt->synchronous;
@@ -450,7 +454,7 @@ enum zclient_send_status zclient_send_localsid(struct zclient *zclient,
p.prefix = *sid;
api.vrf_id = VRF_DEFAULT;
- api.type = ZEBRA_ROUTE_BGP;
+ api.type = zclient->redist_default;
api.instance = 0;
api.safi = SAFI_UNICAST;
memcpy(&api.prefix, &p, sizeof(p));
@@ -2109,7 +2113,7 @@ stream_failure:
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
-static int zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
+static int zclient_vrf_add(ZAPI_CALLBACK_ARGS)
{
struct vrf *vrf;
char vrfname_tmp[VRF_NAMSIZ + 1] = {};
@@ -2141,7 +2145,7 @@ stream_failure:
return -1;
}
-static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
+static int zclient_vrf_delete(ZAPI_CALLBACK_ARGS)
{
struct vrf *vrf;
@@ -2154,12 +2158,13 @@ static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
* no point in attempting to delete it.
*/
if (!vrf)
- return;
+ return 0;
vrf_delete(vrf);
+ return 0;
}
-static int zclient_interface_add(struct zclient *zclient, vrf_id_t vrf_id)
+static int zclient_interface_add(ZAPI_CALLBACK_ARGS)
{
struct interface *ifp;
char ifname_tmp[INTERFACE_NAMSIZ + 1] = {};
@@ -2219,7 +2224,7 @@ stream_failure:
return NULL;
}
-static void zclient_interface_delete(struct zclient *zclient, vrf_id_t vrf_id)
+static int zclient_interface_delete(ZAPI_CALLBACK_ARGS)
{
struct interface *ifp;
struct stream *s = zclient->ibuf;
@@ -2227,13 +2232,13 @@ static void zclient_interface_delete(struct zclient *zclient, vrf_id_t vrf_id)
ifp = zebra_interface_state_read(s, vrf_id);
if (ifp == NULL)
- return;
+ return 0;
if_destroy_via_zapi(ifp);
- return;
+ return 0;
}
-static void zclient_interface_up(struct zclient *zclient, vrf_id_t vrf_id)
+static int zclient_interface_up(ZAPI_CALLBACK_ARGS)
{
struct interface *ifp;
struct stream *s = zclient->ibuf;
@@ -2241,12 +2246,13 @@ static void zclient_interface_up(struct zclient *zclient, vrf_id_t vrf_id)
ifp = zebra_interface_state_read(s, vrf_id);
if (!ifp)
- return;
+ return 0;
if_up_via_zapi(ifp);
+ return 0;
}
-static void zclient_interface_down(struct zclient *zclient, vrf_id_t vrf_id)
+static int zclient_interface_down(ZAPI_CALLBACK_ARGS)
{
struct interface *ifp;
struct stream *s = zclient->ibuf;
@@ -2254,12 +2260,13 @@ static void zclient_interface_down(struct zclient *zclient, vrf_id_t vrf_id)
ifp = zebra_interface_state_read(s, vrf_id);
if (!ifp)
- return;
+ return 0;
if_down_via_zapi(ifp);
+ return 0;
}
-static void zclient_handle_error(ZAPI_CALLBACK_ARGS)
+static int zclient_handle_error(ZAPI_CALLBACK_ARGS)
{
enum zebra_error_types error;
struct stream *s = zclient->ibuf;
@@ -2268,6 +2275,7 @@ static void zclient_handle_error(ZAPI_CALLBACK_ARGS)
if (zclient->handle_error)
(*zclient->handle_error)(error);
+ return 0;
}
static int link_params_set_value(struct stream *s, struct if_link_params *iflp)
@@ -3585,7 +3593,7 @@ stream_failure:
return -1;
}
-static void zclient_capability_decode(ZAPI_CALLBACK_ARGS)
+static int zclient_capability_decode(ZAPI_CALLBACK_ARGS)
{
struct zclient_capabilities cap;
struct stream *s = zclient->ibuf;
@@ -3612,7 +3620,7 @@ static void zclient_capability_decode(ZAPI_CALLBACK_ARGS)
(*zclient->zebra_capabilities)(&cap);
stream_failure:
- return;
+ return 0;
}
enum zclient_send_status zclient_send_mlag_register(struct zclient *client,
@@ -3651,24 +3659,6 @@ enum zclient_send_status zclient_send_mlag_data(struct zclient *client,
return zclient_send_message(client);
}
-static void zclient_mlag_process_up(ZAPI_CALLBACK_ARGS)
-{
- if (zclient->mlag_process_up)
- (*zclient->mlag_process_up)();
-}
-
-static void zclient_mlag_process_down(ZAPI_CALLBACK_ARGS)
-{
- if (zclient->mlag_process_down)
- (*zclient->mlag_process_down)();
-}
-
-static void zclient_mlag_handle_msg(ZAPI_CALLBACK_ARGS)
-{
- if (zclient->mlag_handle_msg)
- (*zclient->mlag_handle_msg)(zclient->ibuf, length);
-}
-
/*
* Send an OPAQUE message, contents opaque to zebra. The message header
* is a message subtype.
@@ -3858,6 +3848,24 @@ stream_failure:
return -1;
}
+static zclient_handler *const lib_handlers[] = {
+ /* fundamentals */
+ [ZEBRA_CAPABILITIES] = zclient_capability_decode,
+ [ZEBRA_ERROR] = zclient_handle_error,
+
+ /* VRF & interface code is shared in lib */
+ [ZEBRA_VRF_ADD] = zclient_vrf_add,
+ [ZEBRA_VRF_DELETE] = zclient_vrf_delete,
+ [ZEBRA_INTERFACE_ADD] = zclient_interface_add,
+ [ZEBRA_INTERFACE_DELETE] = zclient_interface_delete,
+ [ZEBRA_INTERFACE_UP] = zclient_interface_up,
+ [ZEBRA_INTERFACE_DOWN] = zclient_interface_down,
+
+ /* BFD */
+ [ZEBRA_BFD_DEST_REPLAY] = zclient_bfd_session_reply,
+ [ZEBRA_INTERFACE_BFD_DEST_UPDATE] = zclient_bfd_session_update,
+};
+
/* Zebra client message read function. */
static int zclient_read(struct thread *thread)
{
@@ -3957,283 +3965,10 @@ static int zclient_read(struct thread *thread)
zlog_debug("zclient %p command %s VRF %u", zclient,
zserv_command_string(command), vrf_id);
- switch (command) {
- case ZEBRA_CAPABILITIES:
- zclient_capability_decode(command, zclient, length, vrf_id);
- break;
- case ZEBRA_ROUTER_ID_UPDATE:
- if (zclient->router_id_update)
- (*zclient->router_id_update)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_VRF_ADD:
- zclient_vrf_add(zclient, vrf_id);
- break;
- case ZEBRA_VRF_DELETE:
- zclient_vrf_delete(zclient, vrf_id);
- break;
- case ZEBRA_INTERFACE_ADD:
- zclient_interface_add(zclient, vrf_id);
- break;
- case ZEBRA_INTERFACE_DELETE:
- zclient_interface_delete(zclient, vrf_id);
- break;
- case ZEBRA_INTERFACE_ADDRESS_ADD:
- if (zclient->interface_address_add)
- (*zclient->interface_address_add)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_INTERFACE_ADDRESS_DELETE:
- if (zclient->interface_address_delete)
- (*zclient->interface_address_delete)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
- if (zclient->interface_bfd_dest_update)
- (*zclient->interface_bfd_dest_update)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
- if (zclient->interface_nbr_address_add)
- (*zclient->interface_nbr_address_add)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
- if (zclient->interface_nbr_address_delete)
- (*zclient->interface_nbr_address_delete)(
- command, zclient, length, vrf_id);
- break;
- case ZEBRA_INTERFACE_UP:
- zclient_interface_up(zclient, vrf_id);
- break;
- case ZEBRA_INTERFACE_DOWN:
- zclient_interface_down(zclient, vrf_id);
- break;
- case ZEBRA_INTERFACE_VRF_UPDATE:
- if (zclient->interface_vrf_update)
- (*zclient->interface_vrf_update)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_NEXTHOP_UPDATE:
- if (zclient_debug)
- zlog_debug("zclient rcvd nexthop update");
- if (zclient->nexthop_update)
- (*zclient->nexthop_update)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_BFD_DEST_REPLAY:
- if (zclient->bfd_dest_replay)
- (*zclient->bfd_dest_replay)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_REDISTRIBUTE_ROUTE_ADD:
- if (zclient->redistribute_route_add)
- (*zclient->redistribute_route_add)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_REDISTRIBUTE_ROUTE_DEL:
- if (zclient->redistribute_route_del)
- (*zclient->redistribute_route_del)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_INTERFACE_LINK_PARAMS:
- if (zclient->interface_link_params)
- (*zclient->interface_link_params)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_FEC_UPDATE:
- if (zclient_debug)
- zlog_debug("zclient rcvd fec update");
- if (zclient->fec_update)
- (*zclient->fec_update)(command, zclient, length);
- break;
- case ZEBRA_LOCAL_ES_ADD:
- if (zclient->local_es_add)
- (*zclient->local_es_add)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_LOCAL_ES_DEL:
- if (zclient->local_es_del)
- (*zclient->local_es_del)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_LOCAL_ES_EVI_ADD:
- if (zclient->local_es_evi_add)
- (*zclient->local_es_evi_add)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_LOCAL_ES_EVI_DEL:
- if (zclient->local_es_evi_del)
- (*zclient->local_es_evi_del)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_VNI_ADD:
- if (zclient->local_vni_add)
- (*zclient->local_vni_add)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_VNI_DEL:
- if (zclient->local_vni_del)
- (*zclient->local_vni_del)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_L3VNI_ADD:
- if (zclient->local_l3vni_add)
- (*zclient->local_l3vni_add)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_L3VNI_DEL:
- if (zclient->local_l3vni_del)
- (*zclient->local_l3vni_del)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_MACIP_ADD:
- if (zclient->local_macip_add)
- (*zclient->local_macip_add)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_MACIP_DEL:
- if (zclient->local_macip_del)
- (*zclient->local_macip_del)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_IP_PREFIX_ROUTE_ADD:
- if (zclient->local_ip_prefix_add)
- (*zclient->local_ip_prefix_add)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_IP_PREFIX_ROUTE_DEL:
- if (zclient->local_ip_prefix_del)
- (*zclient->local_ip_prefix_del)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_PW_STATUS_UPDATE:
- if (zclient->pw_status_update)
- (*zclient->pw_status_update)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_ROUTE_NOTIFY_OWNER:
- if (zclient->route_notify_owner)
- (*zclient->route_notify_owner)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_RULE_NOTIFY_OWNER:
- if (zclient->rule_notify_owner)
- (*zclient->rule_notify_owner)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_NHG_NOTIFY_OWNER:
- if (zclient->nhg_notify_owner)
- (*zclient->nhg_notify_owner)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_GET_LABEL_CHUNK:
- if (zclient->label_chunk)
- (*zclient->label_chunk)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_IPSET_NOTIFY_OWNER:
- if (zclient->ipset_notify_owner)
- (*zclient->ipset_notify_owner)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_IPSET_ENTRY_NOTIFY_OWNER:
- if (zclient->ipset_entry_notify_owner)
- (*zclient->ipset_entry_notify_owner)(command,
- zclient, length,
- vrf_id);
- break;
- case ZEBRA_IPTABLE_NOTIFY_OWNER:
- if (zclient->iptable_notify_owner)
- (*zclient->iptable_notify_owner)(command,
- zclient, length,
- vrf_id);
- break;
- case ZEBRA_VXLAN_SG_ADD:
- if (zclient->vxlan_sg_add)
- (*zclient->vxlan_sg_add)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_VXLAN_SG_DEL:
- if (zclient->vxlan_sg_del)
- (*zclient->vxlan_sg_del)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_MLAG_PROCESS_UP:
- zclient_mlag_process_up(command, zclient, length, vrf_id);
- break;
- case ZEBRA_MLAG_PROCESS_DOWN:
- zclient_mlag_process_down(command, zclient, length, vrf_id);
- break;
- case ZEBRA_MLAG_FORWARD_MSG:
- zclient_mlag_handle_msg(command, zclient, length, vrf_id);
- break;
- case ZEBRA_SRV6_LOCATOR_ADD:
- if (zclient->srv6_locator_add)
- (*zclient->srv6_locator_add)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_SRV6_LOCATOR_DELETE:
- if (zclient->srv6_locator_delete)
- (*zclient->srv6_locator_delete)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK:
- if (zclient->process_srv6_locator_chunk)
- (*zclient->process_srv6_locator_chunk)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_ERROR:
- zclient_handle_error(command, zclient, length, vrf_id);
- break;
- case ZEBRA_OPAQUE_MESSAGE:
- if (zclient->opaque_msg_handler)
- (*zclient->opaque_msg_handler)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_OPAQUE_REGISTER:
- if (zclient->opaque_register_handler)
- (*zclient->opaque_register_handler)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_OPAQUE_UNREGISTER:
- if (zclient->opaque_unregister_handler)
- (*zclient->opaque_unregister_handler)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_SR_POLICY_NOTIFY_STATUS:
- if (zclient->sr_policy_notify_status)
- (*zclient->sr_policy_notify_status)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_CLIENT_CLOSE_NOTIFY:
- if (zclient->zebra_client_close_notify)
- (*zclient->zebra_client_close_notify)(command, zclient,
- length, vrf_id);
- break;
- case ZEBRA_NHRP_NEIGH_ADDED:
- if (zclient->neighbor_added)
- (*zclient->neighbor_added)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_NHRP_NEIGH_REMOVED:
- if (zclient->neighbor_removed)
- (*zclient->neighbor_removed)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_NHRP_NEIGH_GET:
- if (zclient->neighbor_get)
- (*zclient->neighbor_get)(command, zclient, length,
- vrf_id);
- break;
- case ZEBRA_GRE_UPDATE:
- if (zclient->gre_update)
- (*zclient->gre_update)(command, zclient,
- length, vrf_id);
- break;
- default:
- break;
- }
+ if (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);
if (zclient->sock < 0)
/* Connection was closed during packet processing. */
diff --git a/lib/zclient.h b/lib/zclient.h
index 3cad9bd4fa..82eaefda42 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -21,6 +21,8 @@
#ifndef _ZEBRA_ZCLIENT_H
#define _ZEBRA_ZCLIENT_H
+struct zclient;
+
/* For struct zapi_route. */
#include "prefix.h"
#include "ipaddr.h"
@@ -284,6 +286,14 @@ struct zapi_cap {
vrf_id_t vrf_id;
};
+/* clang-format off */
+#define ZAPI_CALLBACK_ARGS \
+ int cmd, struct zclient *zclient, uint16_t length, vrf_id_t vrf_id
+
+/* function-type typedef (pointer not included) */
+typedef int (zclient_handler)(ZAPI_CALLBACK_ARGS);
+/* clang-format on */
+
/* Structure for the zebra client. */
struct zclient {
/* The thread master we schedule ourselves on */
@@ -298,6 +308,9 @@ struct zclient {
/* Is this a synchronous client? */
bool synchronous;
+ /* BFD enabled with bfd_protocol_integration_init() */
+ bool bfd_integration;
+
/* Session id (optional) to support clients with multiple sessions */
uint32_t session_id;
@@ -332,13 +345,12 @@ struct zclient {
/* Redistribute default. */
vrf_bitmap_t default_information[AFI_MAX];
-#define ZAPI_CALLBACK_ARGS \
- int cmd, struct zclient *zclient, uint16_t length, vrf_id_t vrf_id
-
/* Pointer to the callback functions. */
void (*zebra_connected)(struct zclient *);
void (*zebra_capabilities)(struct zclient_capabilities *cap);
+ int (*handle_error)(enum zebra_error_types error);
+
/*
* When the zclient attempts to write the stream data to
* it's named pipe to/from zebra, we may have a situation
@@ -350,61 +362,15 @@ struct zclient {
* more data.
*/
void (*zebra_buffer_write_ready)(void);
- int (*router_id_update)(ZAPI_CALLBACK_ARGS);
- int (*interface_address_add)(ZAPI_CALLBACK_ARGS);
- int (*interface_address_delete)(ZAPI_CALLBACK_ARGS);
- int (*interface_link_params)(ZAPI_CALLBACK_ARGS);
- int (*interface_bfd_dest_update)(ZAPI_CALLBACK_ARGS);
- int (*interface_nbr_address_add)(ZAPI_CALLBACK_ARGS);
- int (*interface_nbr_address_delete)(ZAPI_CALLBACK_ARGS);
- int (*interface_vrf_update)(ZAPI_CALLBACK_ARGS);
- int (*nexthop_update)(ZAPI_CALLBACK_ARGS);
- int (*bfd_dest_replay)(ZAPI_CALLBACK_ARGS);
- int (*redistribute_route_add)(ZAPI_CALLBACK_ARGS);
- int (*redistribute_route_del)(ZAPI_CALLBACK_ARGS);
- int (*fec_update)(int, struct zclient *, uint16_t);
- int (*local_es_add)(ZAPI_CALLBACK_ARGS);
- int (*local_es_del)(ZAPI_CALLBACK_ARGS);
- int (*local_es_evi_add)(ZAPI_CALLBACK_ARGS);
- int (*local_es_evi_del)(ZAPI_CALLBACK_ARGS);
- int (*local_vni_add)(ZAPI_CALLBACK_ARGS);
- int (*local_vni_del)(ZAPI_CALLBACK_ARGS);
- int (*local_l3vni_add)(ZAPI_CALLBACK_ARGS);
- int (*local_l3vni_del)(ZAPI_CALLBACK_ARGS);
- void (*local_ip_prefix_add)(ZAPI_CALLBACK_ARGS);
- void (*local_ip_prefix_del)(ZAPI_CALLBACK_ARGS);
- int (*local_macip_add)(ZAPI_CALLBACK_ARGS);
- int (*local_macip_del)(ZAPI_CALLBACK_ARGS);
- int (*pw_status_update)(ZAPI_CALLBACK_ARGS);
- int (*route_notify_owner)(ZAPI_CALLBACK_ARGS);
- int (*rule_notify_owner)(ZAPI_CALLBACK_ARGS);
- void (*label_chunk)(ZAPI_CALLBACK_ARGS);
- int (*ipset_notify_owner)(ZAPI_CALLBACK_ARGS);
- int (*ipset_entry_notify_owner)(ZAPI_CALLBACK_ARGS);
- int (*iptable_notify_owner)(ZAPI_CALLBACK_ARGS);
- int (*vxlan_sg_add)(ZAPI_CALLBACK_ARGS);
- int (*vxlan_sg_del)(ZAPI_CALLBACK_ARGS);
- int (*mlag_process_up)(void);
- int (*mlag_process_down)(void);
- int (*mlag_handle_msg)(struct stream *msg, int len);
- int (*nhg_notify_owner)(ZAPI_CALLBACK_ARGS);
- int (*srv6_locator_add)(ZAPI_CALLBACK_ARGS);
- int (*srv6_locator_delete)(ZAPI_CALLBACK_ARGS);
- int (*srv6_function_add)(ZAPI_CALLBACK_ARGS);
- int (*srv6_function_delete)(ZAPI_CALLBACK_ARGS);
- void (*process_srv6_locator_chunk)(ZAPI_CALLBACK_ARGS);
- int (*handle_error)(enum zebra_error_types error);
- int (*opaque_msg_handler)(ZAPI_CALLBACK_ARGS);
- int (*opaque_register_handler)(ZAPI_CALLBACK_ARGS);
- int (*opaque_unregister_handler)(ZAPI_CALLBACK_ARGS);
- int (*sr_policy_notify_status)(ZAPI_CALLBACK_ARGS);
- int (*zebra_client_close_notify)(ZAPI_CALLBACK_ARGS);
- void (*neighbor_added)(ZAPI_CALLBACK_ARGS);
- void (*neighbor_removed)(ZAPI_CALLBACK_ARGS);
- void (*neighbor_get)(ZAPI_CALLBACK_ARGS);
- void (*gre_update)(ZAPI_CALLBACK_ARGS);
+
+ zclient_handler *const *handlers;
+ size_t n_handlers;
};
+/* lib handlers added in bfd.c */
+extern int zclient_bfd_session_reply(ZAPI_CALLBACK_ARGS);
+extern int zclient_bfd_session_update(ZAPI_CALLBACK_ARGS);
+
/* Zebra API message flag. */
#define ZAPI_MESSAGE_NEXTHOP 0x01
#define ZAPI_MESSAGE_DISTANCE 0x02
@@ -893,7 +859,9 @@ int zclient_neigh_ip_encode(struct stream *s, uint16_t cmd, union sockunion *in,
extern uint32_t zclient_get_nhg_start(uint32_t proto);
extern struct zclient *zclient_new(struct thread_master *m,
- struct zclient_options *opt);
+ struct zclient_options *opt,
+ zclient_handler *const *handlers,
+ size_t n_handlers);
extern void zclient_init(struct zclient *, int, unsigned short,
struct zebra_privs_t *privs);
diff --git a/nhrpd/netlink_arp.c b/nhrpd/netlink_arp.c
index 0a618056d5..3658cb16bb 100644
--- a/nhrpd/netlink_arp.c
+++ b/nhrpd/netlink_arp.c
@@ -147,7 +147,7 @@ void netlink_set_nflog_group(int nlgroup)
}
}
-void nhrp_neighbor_operation(ZAPI_CALLBACK_ARGS)
+int nhrp_neighbor_operation(ZAPI_CALLBACK_ARGS)
{
union sockunion addr = {}, lladdr = {};
struct interface *ifp;
@@ -157,7 +157,7 @@ void nhrp_neighbor_operation(ZAPI_CALLBACK_ARGS)
zclient_neigh_ip_decode(zclient->ibuf, &api);
if (api.ip_in.ipa_type == AF_UNSPEC)
- return;
+ return 0;
sockunion_family(&addr) = api.ip_in.ipa_type;
memcpy((uint8_t *)sockunion_get_addr(&addr), &api.ip_in.ip.addr,
family2addrsize(api.ip_in.ipa_type));
@@ -172,10 +172,10 @@ void nhrp_neighbor_operation(ZAPI_CALLBACK_ARGS)
ndm_state = api.ndm_state;
if (!ifp)
- return;
+ return 0;
c = nhrp_cache_get(ifp, &addr, 0);
if (!c)
- return;
+ return 0;
debugf(NHRP_DEBUG_KERNEL,
"Netlink: %s %pSU dev %s lladdr %pSU nud 0x%x cache used %u type %u",
(cmd == ZEBRA_NHRP_NEIGH_GET)
@@ -200,4 +200,5 @@ void nhrp_neighbor_operation(ZAPI_CALLBACK_ARGS)
: ZEBRA_NEIGH_STATE_FAILED;
nhrp_cache_set_used(c, state == ZEBRA_NEIGH_STATE_REACHABLE);
}
+ return 0;
}
diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c
index 12a2fc2fa0..76e0978cb6 100644
--- a/nhrpd/nhrp_route.c
+++ b/nhrpd/nhrp_route.c
@@ -366,21 +366,25 @@ static void nhrp_zebra_connected(struct zclient *zclient)
nhrp_zebra_register_neigh(VRF_DEFAULT, AFI_IP6, true);
}
+static zclient_handler *const nhrp_handlers[] = {
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = nhrp_interface_address_add,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = nhrp_interface_address_delete,
+ [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = nhrp_route_read,
+ [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = nhrp_route_read,
+ [ZEBRA_NHRP_NEIGH_ADDED] = nhrp_neighbor_operation,
+ [ZEBRA_NHRP_NEIGH_REMOVED] = nhrp_neighbor_operation,
+ [ZEBRA_NHRP_NEIGH_GET] = nhrp_neighbor_operation,
+ [ZEBRA_GRE_UPDATE] = nhrp_gre_update,
+};
+
void nhrp_zebra_init(void)
{
zebra_rib[AFI_IP] = route_table_init();
zebra_rib[AFI_IP6] = route_table_init();
- zclient = zclient_new(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default, nhrp_handlers,
+ array_size(nhrp_handlers));
zclient->zebra_connected = nhrp_zebra_connected;
- zclient->interface_address_add = nhrp_interface_address_add;
- zclient->interface_address_delete = nhrp_interface_address_delete;
- zclient->redistribute_route_add = nhrp_route_read;
- zclient->redistribute_route_del = nhrp_route_read;
- zclient->neighbor_added = nhrp_neighbor_operation;
- zclient->neighbor_removed = nhrp_neighbor_operation;
- zclient->neighbor_get = nhrp_neighbor_operation;
- zclient->gre_update = nhrp_gre_update;
zclient_init(zclient, ZEBRA_ROUTE_NHRP, 0, &nhrpd_privs);
}
@@ -476,7 +480,7 @@ void nhrp_zebra_terminate(void)
route_table_finish(zebra_rib[AFI_IP6]);
}
-void nhrp_gre_update(ZAPI_CALLBACK_ARGS)
+int nhrp_gre_update(ZAPI_CALLBACK_ARGS)
{
struct stream *s;
struct nhrp_gre_info gre_info, *val;
@@ -485,7 +489,7 @@ void nhrp_gre_update(ZAPI_CALLBACK_ARGS)
/* result */
s = zclient->ibuf;
if (vrf_id != VRF_DEFAULT)
- return;
+ return 0;
/* read GRE information */
STREAM_GETL(s, gre_info.ifindex);
@@ -516,7 +520,9 @@ void nhrp_gre_update(ZAPI_CALLBACK_ARGS)
ifp ? ifp->name : "<none>", gre_info.ifindex, vrf_id);
if (ifp)
nhrp_interface_update_nbma(ifp, val);
- return;
+ return 0;
+
stream_failure:
zlog_err("%s(): error reading response ..", __func__);
+ return -1;
}
diff --git a/nhrpd/nhrpd.h b/nhrpd/nhrpd.h
index 63f1cb97ef..753c6e9b22 100644
--- a/nhrpd/nhrpd.h
+++ b/nhrpd/nhrpd.h
@@ -376,8 +376,8 @@ int nhrp_interface_up(ZAPI_CALLBACK_ARGS);
int nhrp_interface_down(ZAPI_CALLBACK_ARGS);
int nhrp_interface_address_add(ZAPI_CALLBACK_ARGS);
int nhrp_interface_address_delete(ZAPI_CALLBACK_ARGS);
-void nhrp_neighbor_operation(ZAPI_CALLBACK_ARGS);
-void nhrp_gre_update(ZAPI_CALLBACK_ARGS);
+int nhrp_neighbor_operation(ZAPI_CALLBACK_ARGS);
+int nhrp_gre_update(ZAPI_CALLBACK_ARGS);
void nhrp_interface_notify_add(struct interface *ifp, struct notifier_block *n,
notifier_fn_t fn);
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index 81573da3a6..5e50a6cc55 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -709,19 +709,22 @@ static void ospf6_zebra_connected(struct zclient *zclient)
zclient_send_reg_requests(zclient, VRF_DEFAULT);
}
+static zclient_handler *const ospf6_handlers[] = {
+ [ZEBRA_ROUTER_ID_UPDATE] = ospf6_router_id_update_zebra,
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = ospf6_zebra_if_address_update_add,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = ospf6_zebra_if_address_update_delete,
+ [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ospf6_zebra_read_route,
+ [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ospf6_zebra_read_route,
+ [ZEBRA_NEXTHOP_UPDATE] = ospf6_zebra_import_check_update,
+};
+
void ospf6_zebra_init(struct thread_master *master)
{
/* Allocate zebra structure. */
- zclient = zclient_new(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default, ospf6_handlers,
+ array_size(ospf6_handlers));
zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs);
zclient->zebra_connected = ospf6_zebra_connected;
- zclient->router_id_update = ospf6_router_id_update_zebra;
- zclient->interface_address_add = ospf6_zebra_if_address_update_add;
- zclient->interface_address_delete =
- ospf6_zebra_if_address_update_delete;
- zclient->redistribute_route_add = ospf6_zebra_read_route;
- zclient->redistribute_route_del = ospf6_zebra_read_route;
- zclient->nexthop_update = ospf6_zebra_import_check_update;
/* Install command element for zebra node. */
install_element(VIEW_NODE, &show_ospf6_zebra_cmd);
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index 2ba976af5a..b0ed66da5f 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -2102,25 +2102,33 @@ static int ospf_zebra_client_close_notify(ZAPI_CALLBACK_ARGS)
return ret;
}
+static zclient_handler *const ospf_handlers[] = {
+ [ZEBRA_ROUTER_ID_UPDATE] = ospf_router_id_update_zebra,
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = ospf_interface_address_add,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = ospf_interface_address_delete,
+ [ZEBRA_INTERFACE_LINK_PARAMS] = ospf_interface_link_params,
+ [ZEBRA_INTERFACE_VRF_UPDATE] = ospf_interface_vrf_update,
+
+ [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ospf_zebra_read_route,
+ [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ospf_zebra_read_route,
+
+ [ZEBRA_OPAQUE_MESSAGE] = ospf_opaque_msg_handler,
+
+ [ZEBRA_CLIENT_CLOSE_NOTIFY] = ospf_zebra_client_close_notify,
+};
+
void ospf_zebra_init(struct thread_master *master, unsigned short instance)
{
/* Allocate zebra structure. */
- zclient = zclient_new(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default, ospf_handlers,
+ array_size(ospf_handlers));
zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs);
zclient->zebra_connected = ospf_zebra_connected;
- zclient->router_id_update = ospf_router_id_update_zebra;
- zclient->interface_address_add = ospf_interface_address_add;
- zclient->interface_address_delete = ospf_interface_address_delete;
- zclient->interface_link_params = ospf_interface_link_params;
- zclient->interface_vrf_update = ospf_interface_vrf_update;
-
- zclient->redistribute_route_add = ospf_zebra_read_route;
- zclient->redistribute_route_del = ospf_zebra_read_route;
/* Initialize special zclient for synchronous message exchanges. */
struct zclient_options options = zclient_options_default;
options.synchronous = true;
- zclient_sync = zclient_new(master, &options);
+ zclient_sync = zclient_new(master, &options, NULL, 0);
zclient_sync->sock = -1;
zclient_sync->redist_default = ZEBRA_ROUTE_OSPF;
zclient_sync->instance = instance;
@@ -2135,10 +2143,6 @@ void ospf_zebra_init(struct thread_master *master, unsigned short instance)
access_list_delete_hook(ospf_filter_update);
prefix_list_add_hook(ospf_prefix_list_update);
prefix_list_delete_hook(ospf_prefix_list_update);
-
- zclient->opaque_msg_handler = ospf_opaque_msg_handler;
-
- zclient->zebra_client_close_notify = ospf_zebra_client_close_notify;
}
void ospf_zebra_send_arp(const struct interface *ifp, const struct prefix *p)
diff --git a/pathd/path_zebra.c b/pathd/path_zebra.c
index 53d834f360..156267a394 100644
--- a/pathd/path_zebra.c
+++ b/pathd/path_zebra.c
@@ -320,6 +320,12 @@ static int path_zebra_opaque_msg_handler(ZAPI_CALLBACK_ARGS)
return ret;
}
+static zclient_handler *const path_handlers[] = {
+ [ZEBRA_SR_POLICY_NOTIFY_STATUS] = path_zebra_sr_policy_notify_status,
+ [ZEBRA_ROUTER_ID_UPDATE] = path_zebra_router_id_update,
+ [ZEBRA_OPAQUE_MESSAGE] = path_zebra_opaque_msg_handler,
+};
+
/**
* Initializes Zebra asynchronous connection.
*
@@ -331,15 +337,13 @@ void path_zebra_init(struct thread_master *master)
options.synchronous = true;
/* Initialize asynchronous zclient. */
- zclient = zclient_new(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default, path_handlers,
+ array_size(path_handlers));
zclient_init(zclient, ZEBRA_ROUTE_SRTE, 0, &pathd_privs);
zclient->zebra_connected = path_zebra_connected;
- zclient->sr_policy_notify_status = path_zebra_sr_policy_notify_status;
- zclient->router_id_update = path_zebra_router_id_update;
- zclient->opaque_msg_handler = path_zebra_opaque_msg_handler;
/* Initialize special zclient for synchronous message exchanges. */
- zclient_sync = zclient_new(master, &options);
+ zclient_sync = zclient_new(master, &options, NULL, 0);
zclient_sync->sock = -1;
zclient_sync->redist_default = ZEBRA_ROUTE_SRTE;
zclient_sync->instance = 1;
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index 44c258cb3d..8a9bb0201e 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -429,20 +429,24 @@ static int pbr_zebra_nexthop_update(ZAPI_CALLBACK_ARGS)
extern struct zebra_privs_t pbr_privs;
+static zclient_handler *const pbr_handlers[] = {
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = interface_address_add,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = interface_address_delete,
+ [ZEBRA_INTERFACE_VRF_UPDATE] = interface_vrf_update,
+ [ZEBRA_ROUTE_NOTIFY_OWNER] = route_notify_owner,
+ [ZEBRA_RULE_NOTIFY_OWNER] = rule_notify_owner,
+ [ZEBRA_NEXTHOP_UPDATE] = pbr_zebra_nexthop_update,
+};
+
void pbr_zebra_init(void)
{
struct zclient_options opt = { .receive_notify = true };
- zclient = zclient_new(master, &opt);
+ zclient = zclient_new(master, &opt, pbr_handlers,
+ array_size(pbr_handlers));
zclient_init(zclient, ZEBRA_ROUTE_PBR, 0, &pbr_privs);
zclient->zebra_connected = zebra_connected;
- zclient->interface_address_add = interface_address_add;
- zclient->interface_address_delete = interface_address_delete;
- zclient->interface_vrf_update = interface_vrf_update;
- zclient->route_notify_owner = route_notify_owner;
- zclient->rule_notify_owner = rule_notify_owner;
- zclient->nexthop_update = pbr_zebra_nexthop_update;
}
void pbr_send_rnh(struct nexthop *nhop, bool reg)
diff --git a/pimd/pim_mlag.c b/pimd/pim_mlag.c
index a06c0a6f4e..55d6e7e0fd 100644
--- a/pimd/pim_mlag.c
+++ b/pimd/pim_mlag.c
@@ -791,8 +791,10 @@ static void pim_mlag_process_mroute_del(struct mlag_mroute_del msg)
pim_mlag_up_peer_del(&msg);
}
-int pim_zebra_mlag_handle_msg(struct stream *s, int len)
+int pim_zebra_mlag_handle_msg(int cmd, struct zclient *zclient,
+ uint16_t zapi_length, vrf_id_t vrf_id)
{
+ struct stream *s = zclient->ibuf;
struct mlag_msg mlag_msg;
char buf[80];
int rc = 0;
@@ -880,7 +882,7 @@ int pim_zebra_mlag_handle_msg(struct stream *s, int len)
/****************End of PIM Mesasge processing handler********************/
-int pim_zebra_mlag_process_up(void)
+int pim_zebra_mlag_process_up(ZAPI_CALLBACK_ARGS)
{
if (PIM_DEBUG_MLAG)
zlog_debug("%s: Received Process-Up from Mlag", __func__);
@@ -908,7 +910,7 @@ static void pim_mlag_param_reset(void)
router->peerlink_rif[0] = '\0';
}
-int pim_zebra_mlag_process_down(void)
+int pim_zebra_mlag_process_down(ZAPI_CALLBACK_ARGS)
{
if (PIM_DEBUG_MLAG)
zlog_debug("%s: Received Process-Down from Mlag", __func__);
diff --git a/pimd/pim_mlag.h b/pimd/pim_mlag.h
index b044c31c44..996e4d473f 100644
--- a/pimd/pim_mlag.h
+++ b/pimd/pim_mlag.h
@@ -24,6 +24,7 @@
#ifndef __PIM_MLAG_H__
#define __PIM_MLAG_H__
+#include "zclient.h"
#include "mlag.h"
#include "pim_iface.h"
@@ -33,9 +34,9 @@ extern void pim_instance_mlag_init(struct pim_instance *pim);
extern void pim_instance_mlag_terminate(struct pim_instance *pim);
extern void pim_if_configure_mlag_dualactive(struct pim_interface *pim_ifp);
extern void pim_if_unconfigure_mlag_dualactive(struct pim_interface *pim_ifp);
-extern int pim_zebra_mlag_process_up(void);
-extern int pim_zebra_mlag_process_down(void);
-extern int pim_zebra_mlag_handle_msg(struct stream *msg, int len);
+extern int pim_zebra_mlag_process_up(ZAPI_CALLBACK_ARGS);
+extern int pim_zebra_mlag_process_down(ZAPI_CALLBACK_ARGS);
+extern int pim_zebra_mlag_handle_msg(ZAPI_CALLBACK_ARGS);
/* pm_zpthread.c */
extern int pim_mlag_signal_zpthread(void);
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index aa041df857..1da33af006 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -439,23 +439,29 @@ static void pim_zebra_capabilities(struct zclient_capabilities *cap)
router->mlag_role = cap->role;
}
+static zclient_handler *const pim_handlers[] = {
+ [ZEBRA_ROUTER_ID_UPDATE] = pim_router_id_update_zebra,
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = pim_zebra_if_address_add,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = pim_zebra_if_address_del,
+ [ZEBRA_INTERFACE_VRF_UPDATE] = pim_zebra_interface_vrf_update,
+ [ZEBRA_NEXTHOP_UPDATE] = pim_parse_nexthop_update,
+
+ [ZEBRA_VXLAN_SG_ADD] = pim_zebra_vxlan_sg_proc,
+ [ZEBRA_VXLAN_SG_DEL] = pim_zebra_vxlan_sg_proc,
+
+ [ZEBRA_MLAG_PROCESS_UP] = pim_zebra_mlag_process_up,
+ [ZEBRA_MLAG_PROCESS_DOWN] = pim_zebra_mlag_process_down,
+ [ZEBRA_MLAG_FORWARD_MSG] = pim_zebra_mlag_handle_msg,
+};
+
void pim_zebra_init(void)
{
/* Socket for receiving updates from Zebra daemon */
- zclient = zclient_new(router->master, &zclient_options_default);
+ zclient = zclient_new(router->master, &zclient_options_default,
+ pim_handlers, array_size(pim_handlers));
zclient->zebra_capabilities = pim_zebra_capabilities;
zclient->zebra_connected = pim_zebra_connected;
- zclient->router_id_update = pim_router_id_update_zebra;
- zclient->interface_address_add = pim_zebra_if_address_add;
- zclient->interface_address_delete = pim_zebra_if_address_del;
- zclient->interface_vrf_update = pim_zebra_interface_vrf_update;
- zclient->nexthop_update = pim_parse_nexthop_update;
- zclient->vxlan_sg_add = pim_zebra_vxlan_sg_proc;
- zclient->vxlan_sg_del = pim_zebra_vxlan_sg_proc;
- zclient->mlag_process_up = pim_zebra_mlag_process_up;
- zclient->mlag_process_down = pim_zebra_mlag_process_down;
- zclient->mlag_handle_msg = pim_zebra_mlag_handle_msg;
zclient_init(zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs);
if (PIM_DEBUG_PIM_TRACE) {
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index abf9577bd5..abf1119ac5 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -137,7 +137,7 @@ void zclient_lookup_new(void)
struct zclient_options options = zclient_options_default;
options.synchronous = true;
- zlookup = zclient_new(router->master, &options);
+ zlookup = zclient_new(router->master, &options, NULL, 0);
if (!zlookup) {
flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_new() failure",
__func__);
diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c
index 074370dc26..1f15668635 100644
--- a/ripd/rip_zebra.c
+++ b/ripd/rip_zebra.c
@@ -230,17 +230,21 @@ static void rip_zebra_connected(struct zclient *zclient)
zclient_send_reg_requests(zclient, VRF_DEFAULT);
}
+zclient_handler *const rip_handlers[] = {
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = rip_interface_address_add,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = rip_interface_address_delete,
+ [ZEBRA_INTERFACE_VRF_UPDATE] = rip_interface_vrf_update,
+ [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = rip_zebra_read_route,
+ [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = rip_zebra_read_route,
+};
+
void rip_zclient_init(struct thread_master *master)
{
/* Set default value to the zebra client structure. */
- zclient = zclient_new(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default, rip_handlers,
+ array_size(rip_handlers));
zclient_init(zclient, ZEBRA_ROUTE_RIP, 0, &ripd_privs);
zclient->zebra_connected = rip_zebra_connected;
- zclient->interface_address_add = rip_interface_address_add;
- zclient->interface_address_delete = rip_interface_address_delete;
- zclient->interface_vrf_update = rip_interface_vrf_update;
- zclient->redistribute_route_add = rip_zebra_read_route;
- zclient->redistribute_route_del = rip_zebra_read_route;
}
void rip_zclient_stop(void)
diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c
index baf7f00961..4108aa506e 100644
--- a/ripngd/ripng_zebra.c
+++ b/ripngd/ripng_zebra.c
@@ -234,19 +234,23 @@ static void ripng_zebra_connected(struct zclient *zclient)
zclient_send_reg_requests(zclient, VRF_DEFAULT);
}
+static zclient_handler *const ripng_handlers[] = {
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = ripng_interface_address_add,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = ripng_interface_address_delete,
+ [ZEBRA_INTERFACE_VRF_UPDATE] = ripng_interface_vrf_update,
+ [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ripng_zebra_read_route,
+ [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ripng_zebra_read_route,
+};
+
/* Initialize zebra structure and it's commands. */
void zebra_init(struct thread_master *master)
{
/* Allocate zebra structure. */
- zclient = zclient_new(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default, ripng_handlers,
+ array_size(ripng_handlers));
zclient_init(zclient, ZEBRA_ROUTE_RIPNG, 0, &ripngd_privs);
zclient->zebra_connected = ripng_zebra_connected;
- zclient->interface_address_add = ripng_interface_address_add;
- zclient->interface_address_delete = ripng_interface_address_delete;
- zclient->interface_vrf_update = ripng_interface_vrf_update;
- zclient->redistribute_route_add = ripng_zebra_read_route;
- zclient->redistribute_route_del = ripng_zebra_read_route;
}
void ripng_zebra_stop(void)
diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c
index 67cff378ee..8c9f0c2784 100644
--- a/sharpd/sharp_zebra.c
+++ b/sharpd/sharp_zebra.c
@@ -720,6 +720,10 @@ void sharp_redistribute_vrf(struct vrf *vrf, int type)
0, vrf->vrf_id);
}
+static zclient_handler *const sharp_opaque_handlers[] = {
+ [ZEBRA_OPAQUE_MESSAGE] = sharp_opaque_handler,
+};
+
/* Add a zclient with a specified session id, for testing. */
int sharp_zclient_create(uint32_t session_id)
{
@@ -732,15 +736,14 @@ int sharp_zclient_create(uint32_t session_id)
return -1;
}
- client = zclient_new(master, &zclient_options_default);
+ client = zclient_new(master, &zclient_options_default,
+ sharp_opaque_handlers,
+ array_size(sharp_opaque_handlers));
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);
@@ -928,7 +931,7 @@ int sharp_zebra_srv6_manager_release_locator_chunk(const char *locator_name)
return srv6_manager_release_locator_chunk(zclient, locator_name);
}
-static void sharp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
+static int sharp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
{
struct stream *s = NULL;
struct srv6_locator_chunk s6c = {};
@@ -951,17 +954,31 @@ static void sharp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
for (ALL_LIST_ELEMENTS_RO(loc->chunks, chunk_node, c))
if (!prefix_cmp(c, &s6c.prefix))
- return;
+ return 0;
chunk = prefix_ipv6_new();
*chunk = s6c.prefix;
listnode_add(loc->chunks, chunk);
- return;
+ return 0;
}
zlog_err("%s: can't get locator_chunk!!", __func__);
+ return 0;
}
+static zclient_handler *const sharp_handlers[] = {
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = interface_address_add,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = interface_address_delete,
+ [ZEBRA_ROUTE_NOTIFY_OWNER] = route_notify_owner,
+ [ZEBRA_NEXTHOP_UPDATE] = sharp_nexthop_update,
+ [ZEBRA_NHG_NOTIFY_OWNER] = nhg_notify_owner,
+ [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = sharp_redistribute_route,
+ [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = sharp_redistribute_route,
+ [ZEBRA_OPAQUE_MESSAGE] = sharp_opaque_handler,
+ [ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK] =
+ sharp_zebra_process_srv6_locator_chunk,
+};
+
void sharp_zebra_init(void)
{
struct zclient_options opt = {.receive_notify = true};
@@ -969,19 +986,10 @@ void sharp_zebra_init(void)
if_zapi_callbacks(sharp_ifp_create, sharp_ifp_up,
sharp_ifp_down, sharp_ifp_destroy);
- zclient = zclient_new(master, &opt);
+ zclient = zclient_new(master, &opt, sharp_handlers,
+ array_size(sharp_handlers));
zclient_init(zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs);
zclient->zebra_connected = zebra_connected;
- zclient->interface_address_add = interface_address_add;
- zclient->interface_address_delete = interface_address_delete;
- zclient->route_notify_owner = route_notify_owner;
- zclient->nexthop_update = sharp_nexthop_update;
- zclient->nhg_notify_owner = nhg_notify_owner;
zclient->zebra_buffer_write_ready = sharp_zclient_buffer_ready;
- zclient->redistribute_route_add = sharp_redistribute_route;
- zclient->redistribute_route_del = sharp_redistribute_route;
- zclient->opaque_msg_handler = sharp_opaque_handler;
- zclient->process_srv6_locator_chunk =
- sharp_zebra_process_srv6_locator_chunk;
}
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index a01ecad815..538fae28aa 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -508,6 +508,13 @@ extern void static_zebra_route_add(struct static_path *pn, bool install)
zclient, &api);
}
+static zclient_handler *const static_handlers[] = {
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = interface_address_add,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = interface_address_delete,
+ [ZEBRA_ROUTE_NOTIFY_OWNER] = route_notify_owner,
+ [ZEBRA_NEXTHOP_UPDATE] = static_zebra_nexthop_update,
+};
+
void static_zebra_init(void)
{
struct zclient_options opt = { .receive_notify = true };
@@ -515,15 +522,12 @@ void static_zebra_init(void)
if_zapi_callbacks(static_ifp_create, static_ifp_up,
static_ifp_down, static_ifp_destroy);
- zclient = zclient_new(master, &opt);
+ zclient = zclient_new(master, &opt, static_handlers,
+ array_size(static_handlers));
zclient_init(zclient, ZEBRA_ROUTE_STATIC, 0, &static_privs);
zclient->zebra_capabilities = static_zebra_capabilities;
zclient->zebra_connected = zebra_connected;
- zclient->interface_address_add = interface_address_add;
- zclient->interface_address_delete = interface_address_delete;
- zclient->route_notify_owner = route_notify_owner;
- zclient->nexthop_update = static_zebra_nexthop_update;
static_nht_hash = hash_create(static_nht_hash_key,
static_nht_hash_cmp,
diff --git a/tests/bgpd/test_mpath.c b/tests/bgpd/test_mpath.c
index 77fd876594..d1ca356b94 100644
--- a/tests/bgpd/test_mpath.c
+++ b/tests/bgpd/test_mpath.c
@@ -392,7 +392,7 @@ static int global_test_init(void)
{
qobj_init();
master = thread_master_create(NULL);
- zclient = zclient_new(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default, NULL, 0);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);
diff --git a/tests/topotests/bfd_isis_topo1/test_bfd_isis_topo1.py b/tests/topotests/bfd_isis_topo1/test_bfd_isis_topo1.py
index 863c296927..27a4419329 100644
--- a/tests/topotests/bfd_isis_topo1/test_bfd_isis_topo1.py
+++ b/tests/topotests/bfd_isis_topo1/test_bfd_isis_topo1.py
@@ -193,7 +193,7 @@ def test_bfd_isis_interface_failure_rt2_step3():
# initial 2 seconds to let the CI not suffer.
# TODO: add check for array size
router_compare_json_output(
- "rt1", "show ip route isis json", "step3/show_ip_route_rt2_down.ref", 20, 10
+ "rt1", "show ip route isis json", "step3/show_ip_route_rt2_down.ref", 20, 1
)
router_compare_json_output(
"rt1", "show ipv6 route isis json", "step3/show_ipv6_route_rt2_down.ref", 20, 1
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/scripts/adjacencies.py b/tests/topotests/bgp_l3vpn_to_bgp_direct/scripts/adjacencies.py
index 789f93b837..6cd92e293d 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_direct/scripts/adjacencies.py
+++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/scripts/adjacencies.py
@@ -7,11 +7,18 @@ luCommand("ce1", 'vtysh -c "show bgp summary"', " 00:0", "wait", "Adjacencies up
luCommand("ce2", 'vtysh -c "show bgp summary"', " 00:0", "wait", "Adjacencies up", 180)
luCommand("ce3", 'vtysh -c "show bgp summary"', " 00:0", "wait", "Adjacencies up", 180)
luCommand(
+ "r1", 'vtysh -c "show ip route ospf"', "2.2.2.2", "wait", "OSPF Route has Arrived", 60)
+luCommand(
"r1", "ping 2.2.2.2 -c 1", " 0. packet loss", "wait", "PE->P2 (loopback) ping", 60
)
luCommand(
+ "r3", 'vtysh -c "show ip route ospf"', "2.2.2.2", "wait", "OSPF Route has Arrived", 60)
+luCommand(
"r3", "ping 2.2.2.2 -c 1", " 0. packet loss", "wait", "PE->P2 (loopback) ping", 60
)
+
+luCommand(
+ "r4", 'vtysh -c "show ip route ospf"', "2.2.2.2", "wait", "OSPF Route has Arrived", 60)
luCommand(
"r4", "ping 2.2.2.2 -c 1", " 0. packet loss", "wait", "PE->P2 (loopback) ping", 60
)
diff --git a/vrrpd/vrrp_zebra.c b/vrrpd/vrrp_zebra.c
index 385d443571..d7d37f1f33 100644
--- a/vrrpd/vrrp_zebra.c
+++ b/vrrpd/vrrp_zebra.c
@@ -188,18 +188,22 @@ void vrrp_zclient_send_interface_protodown(struct interface *ifp, bool down)
zclient_send_interface_protodown(zclient, ifp->vrf_id, ifp, down);
}
+static zclient_handler *const vrrp_handlers[] = {
+ [ZEBRA_ROUTER_ID_UPDATE] = vrrp_router_id_update_zebra,
+ [ZEBRA_INTERFACE_ADDRESS_ADD] = vrrp_zebra_if_address_add,
+ [ZEBRA_INTERFACE_ADDRESS_DELETE] = vrrp_zebra_if_address_del,
+};
+
void vrrp_zebra_init(void)
{
if_zapi_callbacks(vrrp_ifp_create, vrrp_ifp_up,
vrrp_ifp_down, vrrp_ifp_destroy);
/* Socket for receiving updates from Zebra daemon */
- zclient = zclient_new(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default, vrrp_handlers,
+ array_size(vrrp_handlers));
zclient->zebra_connected = vrrp_zebra_connected;
- zclient->router_id_update = vrrp_router_id_update_zebra;
- zclient->interface_address_add = vrrp_zebra_if_address_add;
- zclient->interface_address_delete = vrrp_zebra_if_address_del;
zclient_init(zclient, ZEBRA_ROUTE_VRRP, 0, &vrrp_privs);
diff --git a/zebra/debug_nl.c b/zebra/debug_nl.c
index 842579f89e..2175aaff60 100644
--- a/zebra/debug_nl.c
+++ b/zebra/debug_nl.c
@@ -29,6 +29,7 @@
#include <stdint.h>
#include "zebra/rt_netlink.h"
+#include "zebra/kernel_netlink.h"
const char *nlmsg_type2str(uint16_t type)
{
diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h
index 37c76b9e59..cf8b8c785e 100644
--- a/zebra/kernel_netlink.h
+++ b/zebra/kernel_netlink.h
@@ -27,6 +27,10 @@ extern "C" {
#ifdef HAVE_NETLINK
+#define RTM_NHA(h) \
+ ((struct rtattr *)(((char *)(h)) + NLMSG_ALIGN(sizeof(struct nhmsg))))
+
+
#define NL_RCV_PKT_BUF_SIZE 32768
#define NL_PKT_BUF_SIZE 8192
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 6cb4cf5ca1..61bd1417d1 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -3440,6 +3440,7 @@ static inline void zebra_gre_get(ZAPI_HANDLER_ARGS)
stream_putl(s, IFINDEX_INTERNAL);
stream_putl(s, VRF_UNKNOWN);
stream_putl(s, 0);
+ stream_putl(s, 0);
}
/* Write packet size. */
stream_putw_at(s, 0, stream_get_endp(s));
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 5b79de9697..2cb2b5118b 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -449,6 +449,8 @@ static void zebra_show_ip_route_opaque(struct vty *vty, struct route_entry *re,
bzo.community);
json_object_string_add(json, "largeCommunities",
bzo.lcommunity);
+ json_object_string_add(json, "selectionReason",
+ bzo.selection_reason);
} else {
vty_out(vty, " AS-Path : %s\n", bzo.aspath);
@@ -459,6 +461,9 @@ static void zebra_show_ip_route_opaque(struct vty *vty, struct route_entry *re,
if (bzo.lcommunity[0] != '\0')
vty_out(vty, " Large-Communities: %s\n",
bzo.lcommunity);
+
+ vty_out(vty, " Selection reason : %s\n",
+ bzo.selection_reason);
}
}
default: