summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_flowspec_util.c4
-rw-r--r--bgpd/bgp_labelpool.c5
-rw-r--r--bgpd/bgp_nht.c2
-rw-r--r--bgpd/bgp_vty.c220
-rw-r--r--bgpd/bgp_zebra.c15
-rw-r--r--isisd/isis_bpf.c2
-rw-r--r--isisd/isis_zebra.c2
-rw-r--r--ldpd/lde.c2
-rw-r--r--ldpd/ldp_zebra.c33
-rw-r--r--lib/bfd.c6
-rw-r--r--lib/ferr.c6
-rw-r--r--lib/prefix.h4
-rw-r--r--lib/zclient.c245
-rw-r--r--lib/zclient.h153
-rw-r--r--ospf6d/ospf6_lsdb.c6
-rw-r--r--ospf6d/ospf6_zebra.c2
-rw-r--r--ospfd/ospf_zebra.c2
-rw-r--r--pbrd/pbr_zebra.c4
-rw-r--r--pimd/pim_nht.c2
-rw-r--r--pimd/pim_zlookup.c2
-rw-r--r--sharpd/sharp_zebra.c287
-rw-r--r--sharpd/sharp_zebra.h4
-rw-r--r--staticd/static_zebra.c3
-rw-r--r--tests/helpers/python/frrtest.py13
-rwxr-xr-xtools/frr-reload.py6
-rw-r--r--vrrpd/vrrp_zebra.c5
-rw-r--r--vrrpd/vrrp_zebra.h4
-rw-r--r--vtysh/subdir.am3
-rw-r--r--zebra/zapi_msg.c6
-rw-r--r--zebra/zebra_rnh.c2
30 files changed, 598 insertions, 452 deletions
diff --git a/bgpd/bgp_flowspec_util.c b/bgpd/bgp_flowspec_util.c
index 55e7973f81..15b891f25a 100644
--- a/bgpd/bgp_flowspec_util.c
+++ b/bgpd/bgp_flowspec_util.c
@@ -229,9 +229,9 @@ int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type,
case BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE:
if (prefix) {
if (prefix_local.family == AF_INET)
- PREFIX_COPY_IPV4(prefix, &prefix_local)
+ PREFIX_COPY_IPV4(prefix, &prefix_local);
else
- PREFIX_COPY_IPV6(prefix, &prefix_local)
+ PREFIX_COPY_IPV6(prefix, &prefix_local);
}
break;
case BGP_FLOWSPEC_VALIDATE_ONLY:
diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c
index feda0328bd..e8d8167c35 100644
--- a/bgpd/bgp_labelpool.c
+++ b/bgpd/bgp_labelpool.c
@@ -392,8 +392,9 @@ void bgp_lp_get(
if (lp_fifo_count(&lp->requests) > lp->pending_count) {
if (!zclient || zclient->sock < 0)
return;
- if (!zclient_send_get_label_chunk(zclient, 0, LP_CHUNK_SIZE,
- MPLS_LABEL_BASE_ANY))
+ if (zclient_send_get_label_chunk(zclient, 0, LP_CHUNK_SIZE,
+ MPLS_LABEL_BASE_ANY)
+ == ZCLIENT_SEND_FAILURE)
lp->pending_count += LP_CHUNK_SIZE;
}
}
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 5d3667af1a..9635fe1224 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -624,7 +624,7 @@ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
ret = zclient_send_rnh(zclient, command, &bnc->prefix, exact_match,
bnc->bgp->vrf_id);
/* TBD: handle the failure */
- if (ret < 0)
+ if (ret == ZCLIENT_SEND_FAILURE)
flog_warn(EC_BGP_ZEBRA_SEND,
"sendmsg_nexthop: zclient_send_message() failed");
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 40e9707866..0bbcf99100 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -3676,12 +3676,12 @@ void cli_show_router_bgp_show_hostname(struct vty *vty, struct lyd_node *dnode,
}
/* Display hostname in certain command outputs */
-DEFUN (bgp_default_show_nexthop_hostname,
- bgp_default_show_nexthop_hostname_cmd,
- "bgp default show-nexthop-hostname",
- "BGP specific commands\n"
- "Configure BGP defaults\n"
- "Show hostname for nexthop in certain command outputs\n")
+DEFUN_YANG(bgp_default_show_nexthop_hostname,
+ bgp_default_show_nexthop_hostname_cmd,
+ "bgp default show-nexthop-hostname",
+ "BGP specific commands\n"
+ "Configure BGP defaults\n"
+ "Show hostname for nexthop in certain command outputs\n")
{
nb_cli_enqueue_change(vty, "./global/show-nexthop-hostname",
NB_OP_MODIFY, "true");
@@ -4344,7 +4344,8 @@ int peer_conf_interface_create(struct bgp *bgp, const char *conf_if, afi_t afi,
return bgp_nb_errmsg_return(errmsg, errmsg_len, ret);
}
-DEFUN_YANG(neighbor_interface_config, neighbor_interface_config_cmd,
+DEFUN_YANG(neighbor_interface_config,
+ neighbor_interface_config_cmd,
"neighbor WORD interface [peer-group PGNAME]",
NEIGHBOR_STR
"Interface name or neighbor tag\n"
@@ -4485,16 +4486,14 @@ DEFUN_YANG(neighbor_peer_group, neighbor_peer_group_cmd,
return nb_cli_apply_changes(vty, base_xpath);
}
-DEFUN (no_neighbor,
- no_neighbor_cmd,
- "no neighbor <WORD|<A.B.C.D|X:X::X:X> [remote-as <(1-4294967295)|internal|external>]>",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Specify a BGP neighbor\n"
- AS_STR
- "Internal BGP peer\n"
- "External BGP peer\n")
+DEFUN_YANG(no_neighbor,
+ no_neighbor_cmd,
+ "no neighbor <WORD|<A.B.C.D|X:X::X:X> [remote-as <(1-4294967295)|internal|external>]>",
+ NO_STR NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Specify a BGP neighbor\n" AS_STR
+ "Internal BGP peer\n"
+ "External BGP peer\n")
{
int idx_peer = 2;
char base_xpath[XPATH_MAXLEN];
@@ -5062,7 +5061,7 @@ DEFUN_YANG(neighbor_shutdown_msg,
return nb_cli_apply_changes(vty, base_xpath);
}
-ALIAS(neighbor_shutdown_msg, neighbor_shutdown_cmd,
+ALIAS_YANG(neighbor_shutdown_msg, neighbor_shutdown_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
NEIGHBOR_STR NEIGHBOR_ADDR_STR2
"Administratively shut down this neighbor\n")
@@ -5090,7 +5089,7 @@ DEFUN_YANG(no_neighbor_shutdown_msg,
return nb_cli_apply_changes(vty, base_xpath);
}
-ALIAS(no_neighbor_shutdown_msg, no_neighbor_shutdown_cmd,
+ALIAS_YANG(no_neighbor_shutdown_msg, no_neighbor_shutdown_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
"Administratively shut down this neighbor\n")
@@ -6921,7 +6920,7 @@ DEFUN_YANG (no_neighbor_description,
return nb_cli_apply_changes(vty, base_xpath);
}
-ALIAS(no_neighbor_description, no_neighbor_description_comment_cmd,
+ALIAS_YANG(no_neighbor_description, no_neighbor_description_comment_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> description LINE...",
NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
"Neighbor specific description\n"
@@ -8030,13 +8029,12 @@ ALIAS_HIDDEN(no_neighbor_unsuppress_map, no_neighbor_unsuppress_map_hidden_cmd,
"Name of route map\n")
/* Maximum number of prefix to be sent to the neighbor. */
-DEFUN(neighbor_maximum_prefix_out,
- neighbor_maximum_prefix_out_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix-out (1-4294967295)",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefixes to be sent to this peer\n"
- "Maximum no. of prefix limit\n")
+DEFUN_YANG(neighbor_maximum_prefix_out,
+ neighbor_maximum_prefix_out_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix-out (1-4294967295)",
+ NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Maximum number of prefixes to be sent to this peer\n"
+ "Maximum no. of prefix limit\n")
{
char base_xpath[XPATH_MAXLEN];
char af_xpath[XPATH_MAXLEN];
@@ -8066,13 +8064,11 @@ DEFUN(neighbor_maximum_prefix_out,
return nb_cli_apply_changes(vty, base_xpath);
}
-DEFUN(no_neighbor_maximum_prefix_out,
- no_neighbor_maximum_prefix_out_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix-out",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefixes to be sent to this peer\n")
+DEFUN_YANG(no_neighbor_maximum_prefix_out,
+ no_neighbor_maximum_prefix_out_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix-out",
+ NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Maximum number of prefixes to be sent to this peer\n")
{
char base_xpath[XPATH_MAXLEN];
char af_xpath[XPATH_MAXLEN];
@@ -8101,14 +8097,13 @@ DEFUN(no_neighbor_maximum_prefix_out,
/* Maximum number of prefix configuration. Prefix count is different
for each peer configuration. So this configuration can be set for
each peer configuration. */
-DEFUN (neighbor_maximum_prefix,
- neighbor_maximum_prefix_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) [force]",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n"
- "maximum no. of prefix limit\n"
- "Force checking all received routes not only accepted\n")
+DEFUN_YANG(neighbor_maximum_prefix,
+ neighbor_maximum_prefix_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) [force]",
+ NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Maximum number of prefix accept from this peer\n"
+ "maximum no. of prefix limit\n"
+ "Force checking all received routes not only accepted\n")
{
int idx_peer = 1;
int idx_number = 3;
@@ -8149,15 +8144,14 @@ ALIAS_HIDDEN(neighbor_maximum_prefix, neighbor_maximum_prefix_hidden_cmd,
"maximum no. of prefix limit\n"
"Force checking all received routes not only accepted\n")
-DEFUN (neighbor_maximum_prefix_threshold,
- neighbor_maximum_prefix_threshold_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) (1-100) [force]",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n"
- "maximum no. of prefix limit\n"
- "Threshold value (%) at which to generate a warning msg\n"
- "Force checking all received routes not only accepted\n")
+DEFUN_YANG(neighbor_maximum_prefix_threshold,
+ neighbor_maximum_prefix_threshold_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) (1-100) [force]",
+ NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Maximum number of prefix accept from this peer\n"
+ "maximum no. of prefix limit\n"
+ "Threshold value (%) at which to generate a warning msg\n"
+ "Force checking all received routes not only accepted\n")
{
int idx_peer = 1;
int idx_number = 3;
@@ -8206,15 +8200,14 @@ ALIAS_HIDDEN(
"Threshold value (%) at which to generate a warning msg\n"
"Force checking all received routes not only accepted\n")
-DEFUN (neighbor_maximum_prefix_warning,
- neighbor_maximum_prefix_warning_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) warning-only [force]",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n"
- "maximum no. of prefix limit\n"
- "Only give warning message when limit is exceeded\n"
- "Force checking all received routes not only accepted\n")
+DEFUN_YANG(neighbor_maximum_prefix_warning,
+ neighbor_maximum_prefix_warning_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) warning-only [force]",
+ NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Maximum number of prefix accept from this peer\n"
+ "maximum no. of prefix limit\n"
+ "Only give warning message when limit is exceeded\n"
+ "Force checking all received routes not only accepted\n")
{
int idx_peer = 1;
int idx_number = 3;
@@ -8261,16 +8254,15 @@ ALIAS_HIDDEN(
"Only give warning message when limit is exceeded\n"
"Force checking all received routes not only accepted\n")
-DEFUN (neighbor_maximum_prefix_threshold_warning,
- neighbor_maximum_prefix_threshold_warning_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) (1-100) warning-only [force]",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n"
- "maximum no. of prefix limit\n"
- "Threshold value (%) at which to generate a warning msg\n"
- "Only give warning message when limit is exceeded\n"
- "Force checking all received routes not only accepted\n")
+DEFUN_YANG(neighbor_maximum_prefix_threshold_warning,
+ neighbor_maximum_prefix_threshold_warning_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) (1-100) warning-only [force]",
+ NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Maximum number of prefix accept from this peer\n"
+ "maximum no. of prefix limit\n"
+ "Threshold value (%) at which to generate a warning msg\n"
+ "Only give warning message when limit is exceeded\n"
+ "Force checking all received routes not only accepted\n")
{
int idx_peer = 1;
int idx_number = 3;
@@ -8320,16 +8312,15 @@ ALIAS_HIDDEN(
"Only give warning message when limit is exceeded\n"
"Force checking all received routes not only accepted\n")
-DEFUN (neighbor_maximum_prefix_restart,
- neighbor_maximum_prefix_restart_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) restart (1-65535) [force]",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n"
- "maximum no. of prefix limit\n"
- "Restart bgp connection after limit is exceeded\n"
- "Restart interval in minutes\n"
- "Force checking all received routes not only accepted\n")
+DEFUN_YANG(neighbor_maximum_prefix_restart,
+ neighbor_maximum_prefix_restart_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) restart (1-65535) [force]",
+ NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Maximum number of prefix accept from this peer\n"
+ "maximum no. of prefix limit\n"
+ "Restart bgp connection after limit is exceeded\n"
+ "Restart interval in minutes\n"
+ "Force checking all received routes not only accepted\n")
{
int idx_peer = 1;
int idx_number = 3;
@@ -8377,17 +8368,16 @@ ALIAS_HIDDEN(
"Restart interval in minutes\n"
"Force checking all received routes not only accepted\n")
-DEFUN (neighbor_maximum_prefix_threshold_restart,
- neighbor_maximum_prefix_threshold_restart_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) (1-100) restart (1-65535) [force]",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefixes to accept from this peer\n"
- "maximum no. of prefix limit\n"
- "Threshold value (%) at which to generate a warning msg\n"
- "Restart bgp connection after limit is exceeded\n"
- "Restart interval in minutes\n"
- "Force checking all received routes not only accepted\n")
+DEFUN_YANG(neighbor_maximum_prefix_threshold_restart,
+ neighbor_maximum_prefix_threshold_restart_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) (1-100) restart (1-65535) [force]",
+ NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Maximum number of prefixes to accept from this peer\n"
+ "maximum no. of prefix limit\n"
+ "Threshold value (%) at which to generate a warning msg\n"
+ "Restart bgp connection after limit is exceeded\n"
+ "Restart interval in minutes\n"
+ "Force checking all received routes not only accepted\n")
{
int idx_peer = 1;
int idx_number = 3;
@@ -8439,19 +8429,17 @@ ALIAS_HIDDEN(
"Restart interval in minutes\n"
"Force checking all received routes not only accepted\n")
-DEFUN (no_neighbor_maximum_prefix,
- no_neighbor_maximum_prefix_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix [(1-4294967295) [(1-100)] [restart (1-65535)] [warning-only] [force]]",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefixes to accept from this peer\n"
- "maximum no. of prefix limit\n"
- "Threshold value (%) at which to generate a warning msg\n"
- "Restart bgp connection after limit is exceeded\n"
- "Restart interval in minutes\n"
- "Only give warning message when limit is exceeded\n"
- "Force checking all received routes not only accepted\n")
+DEFUN_YANG(no_neighbor_maximum_prefix,
+ no_neighbor_maximum_prefix_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix [(1-4294967295) [(1-100)] [restart (1-65535)] [warning-only] [force]]",
+ NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Maximum number of prefixes to accept from this peer\n"
+ "maximum no. of prefix limit\n"
+ "Threshold value (%) at which to generate a warning msg\n"
+ "Restart bgp connection after limit is exceeded\n"
+ "Restart interval in minutes\n"
+ "Only give warning message when limit is exceeded\n"
+ "Force checking all received routes not only accepted\n")
{
int idx_peer = 2;
char base_xpath[XPATH_MAXLEN];
@@ -8590,15 +8578,13 @@ DEFUN_YANG (neighbor_ttl_security,
return nb_cli_apply_changes(vty, base_xpath);
}
-DEFUN (no_neighbor_ttl_security,
- no_neighbor_ttl_security_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> ttl-security hops (1-254)",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP ttl-security parameters\n"
- "Specify the maximum number of hops to the BGP peer\n"
- "Number of hops to BGP peer\n")
+DEFUN_YANG(no_neighbor_ttl_security,
+ no_neighbor_ttl_security_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> ttl-security hops (1-254)",
+ NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "BGP ttl-security parameters\n"
+ "Specify the maximum number of hops to the BGP peer\n"
+ "Number of hops to BGP peer\n")
{
int idx_peer = 2;
char base_xpath[XPATH_MAXLEN];
@@ -10832,6 +10818,14 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
BGP_FLAG_SHUTDOWN))
json_object_string_add(json_peer, "state",
"Idle (Admin)");
+ else if (peer->status == Active
+ && CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE))
+ json_object_string_add(json_peer, "state",
+ "Active (passive)");
+ else if (peer->status == Active
+ && CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT))
+ json_object_string_add(json_peer, "state",
+ "Active (NSF passive)");
else if (peer->afc_recv[afi][safi])
json_object_string_add(
json_peer, "state",
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 73f03f6a9d..5d43645c6e 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -3051,7 +3051,8 @@ void bgp_send_pbr_rule_action(struct bgp_pbr_action *pbra,
bgp_encode_pbr_rule_action(s, pbra, pbr);
stream_putw_at(s, 0, stream_get_endp(s));
- if (!zclient_send_message(zclient) && install) {
+ if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE)
+ && install) {
if (!pbr)
pbra->install_in_progress = true;
else
@@ -3082,7 +3083,7 @@ void bgp_send_pbr_ipset_match(struct bgp_pbr_match *pbrim, bool install)
bgp_encode_pbr_ipset_match(s, pbrim);
stream_putw_at(s, 0, stream_get_endp(s));
- if (!zclient_send_message(zclient) && install)
+ if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE) && install)
pbrim->install_in_progress = true;
}
@@ -3110,7 +3111,7 @@ void bgp_send_pbr_ipset_entry_match(struct bgp_pbr_match_entry *pbrime,
bgp_encode_pbr_ipset_entry_match(s, pbrime);
stream_putw_at(s, 0, stream_get_endp(s));
- if (!zclient_send_message(zclient) && install)
+ if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE) && install)
pbrime->install_in_progress = true;
}
@@ -3185,7 +3186,7 @@ void bgp_send_pbr_iptable(struct bgp_pbr_action *pba,
stream_putw_at(s, 0, stream_get_endp(s));
ret = zclient_send_message(zclient);
if (install) {
- if (ret)
+ if (ret != ZCLIENT_SEND_FAILURE)
pba->refcnt++;
else
pbm->install_iptable_in_progress = true;
@@ -3319,7 +3320,7 @@ int bgp_zebra_send_capabilities(struct bgp *bgp, bool disable)
}
if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
- < 0) {
+ == ZCLIENT_SEND_FAILURE) {
zlog_err("error sending capability");
ret = BGP_GR_FAILURE;
} else {
@@ -3361,7 +3362,7 @@ int bgp_zebra_update(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type)
api.cap = type;
if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
- < 0) {
+ == ZCLIENT_SEND_FAILURE) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("error sending capability");
return BGP_GR_FAILURE;
@@ -3393,7 +3394,7 @@ int bgp_zebra_stale_timer_update(struct bgp *bgp)
api.stale_removal_time = bgp->rib_stale_time;
api.vrf_id = bgp->vrf_id;
if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
- < 0) {
+ == ZCLIENT_SEND_FAILURE) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("error sending capability");
return BGP_GR_FAILURE;
diff --git a/isisd/isis_bpf.c b/isisd/isis_bpf.c
index 9599077771..454da99e09 100644
--- a/isisd/isis_bpf.c
+++ b/isisd/isis_bpf.c
@@ -215,7 +215,7 @@ int isis_sock_init(struct isis_circuit *circuit)
int isis_recv_pdu_bcast(struct isis_circuit *circuit, uint8_t *ssnpa)
{
- int bytesread = 0, bytestoread, offset, one = 1;
+ int bytesread = 0, bytestoread = 0, offset, one = 1;
uint8_t *buff_ptr;
struct bpf_hdr *bpf_hdr;
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index 8bc5633997..b9958a6696 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -618,7 +618,7 @@ int isis_zebra_label_manager_connect(void)
set_nonblocking(zclient_sync->sock);
/* Send hello to notify zebra this is a synchronous client */
- if (zclient_send_hello(zclient_sync) < 0) {
+ if (zclient_send_hello(zclient_sync) == ZCLIENT_SEND_FAILURE) {
zlog_warn("%s: failed sending hello for synchronous zclient!",
__func__);
close(zclient_sync->sock);
diff --git a/ldpd/lde.c b/ldpd/lde.c
index 67b695150e..c2e11a0aee 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -2092,7 +2092,7 @@ static void zclient_sync_init(void)
sock_set_nonblock(zclient_sync->sock);
/* Send hello to notify zebra this is a synchronous client */
- if (zclient_send_hello(zclient_sync) < 0) {
+ if (zclient_send_hello(zclient_sync) == ZCLIENT_SEND_FAILURE) {
log_warnx("Error sending hello for synchronous zclient!");
goto retry;
}
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index 3852d8d23b..df9832a281 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -127,8 +127,12 @@ ldp_zebra_opaque_unregister(void)
int
ldp_sync_zebra_send_state_update(struct ldp_igp_sync_if_state *state)
{
- return zclient_send_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE,
- (const uint8_t *) state, sizeof(*state));
+ if (zclient_send_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE,
+ (const uint8_t *)state, sizeof(*state))
+ == ZCLIENT_SEND_FAILURE)
+ return -1;
+ else
+ return 0;
}
static int
@@ -137,8 +141,12 @@ ldp_sync_zebra_send_announce(void)
struct ldp_igp_sync_announce announce;
announce.proto = ZEBRA_ROUTE_LDP;
- return zclient_send_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE,
- (const uint8_t *) &announce, sizeof(announce));
+ if (zclient_send_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE,
+ (const uint8_t *)&announce, sizeof(announce))
+ == ZCLIENT_SEND_FAILURE)
+ return -1;
+ else
+ return 0;
}
static int
@@ -272,7 +280,10 @@ ldp_zebra_send_mpls_labels(int cmd, struct kroute *kr)
znh->label_num = 1;
znh->labels[0] = kr->remote_label;
- return zebra_send_mpls_labels(zclient, cmd, &zl);
+ if (zebra_send_mpls_labels(zclient, cmd, &zl) == ZCLIENT_SEND_FAILURE)
+ return -1;
+
+ return 0;
}
int
@@ -293,7 +304,8 @@ kmpw_add(struct zapi_pw *zpw)
debug_zebra_out("pseudowire %s nexthop %s (add)",
zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
- return (zebra_send_pw(zclient, ZEBRA_PW_ADD, zpw));
+ return zebra_send_pw(zclient, ZEBRA_PW_ADD, zpw)
+ == ZCLIENT_SEND_FAILURE;
}
int
@@ -302,7 +314,8 @@ kmpw_del(struct zapi_pw *zpw)
debug_zebra_out("pseudowire %s nexthop %s (del)",
zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
- return (zebra_send_pw(zclient, ZEBRA_PW_DELETE, zpw));
+ return zebra_send_pw(zclient, ZEBRA_PW_DELETE, zpw)
+ == ZCLIENT_SEND_FAILURE;
}
int
@@ -312,7 +325,8 @@ kmpw_set(struct zapi_pw *zpw)
zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop),
zpw->local_label, zpw->remote_label);
- return (zebra_send_pw(zclient, ZEBRA_PW_SET, zpw));
+ return zebra_send_pw(zclient, ZEBRA_PW_SET, zpw)
+ == ZCLIENT_SEND_FAILURE;
}
int
@@ -321,7 +335,8 @@ kmpw_unset(struct zapi_pw *zpw)
debug_zebra_out("pseudowire %s nexthop %s (unset)",
zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
- return (zebra_send_pw(zclient, ZEBRA_PW_UNSET, zpw));
+ return zebra_send_pw(zclient, ZEBRA_PW_UNSET, zpw)
+ == ZCLIENT_SEND_FAILURE;
}
void
diff --git a/lib/bfd.c b/lib/bfd.c
index 1a37b348f8..cdf7008601 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -405,7 +405,7 @@ void bfd_client_sendmsg(struct zclient *zclient, int command,
vrf_id_t vrf_id)
{
struct stream *s;
- int ret;
+ enum zclient_send_status ret;
/* Check socket. */
if (!zclient || zclient->sock < 0) {
@@ -426,7 +426,7 @@ void bfd_client_sendmsg(struct zclient *zclient, int command,
ret = zclient_send_message(zclient);
- if (ret < 0) {
+ if (ret == ZCLIENT_SEND_FAILURE) {
if (bfd_debug)
zlog_debug(
"bfd_client_sendmsg %ld: zclient_send_message() failed",
@@ -542,7 +542,7 @@ int zclient_bfd_command(struct zclient *zc, struct bfd_session_arg *args)
stream_putw_at(s, 0, stream_get_endp(s));
/* Send message to zebra. */
- if (zclient_send_message(zc) == -1) {
+ if (zclient_send_message(zc) == ZCLIENT_SEND_FAILURE) {
if (bfd_debug)
zlog_debug("%s: zclient_send_message failed", __func__);
return -1;
diff --git a/lib/ferr.c b/lib/ferr.c
index 7b923da177..691da495cf 100644
--- a/lib/ferr.c
+++ b/lib/ferr.c
@@ -121,8 +121,12 @@ void log_ref_display(struct vty *vty, uint32_t code, bool json)
if (code) {
ref = log_ref_get(code);
- if (!ref)
+ if (!ref) {
+ if (top)
+ json_object_free(top);
+ list_delete(&errlist);
return;
+ }
listnode_add(errlist, ref);
}
diff --git a/lib/prefix.h b/lib/prefix.h
index d2cabf3104..b7fdc26369 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -479,7 +479,7 @@ extern void apply_mask_ipv4(struct prefix_ipv4 *);
#define PREFIX_COPY(DST, SRC) \
*((struct prefix *)(DST)) = *((const struct prefix *)(SRC))
#define PREFIX_COPY_IPV4(DST, SRC) \
- *((struct prefix_ipv4 *)(DST)) = *((const struct prefix_ipv4 *)(SRC));
+ *((struct prefix_ipv4 *)(DST)) = *((const struct prefix_ipv4 *)(SRC))
extern int prefix_ipv4_any(const struct prefix_ipv4 *);
extern void apply_classful_mask_ipv4(struct prefix_ipv4 *);
@@ -499,7 +499,7 @@ extern int str2prefix_ipv6(const char *, struct prefix_ipv6 *);
extern void apply_mask_ipv6(struct prefix_ipv6 *);
#define PREFIX_COPY_IPV6(DST, SRC) \
- *((struct prefix_ipv6 *)(DST)) = *((const struct prefix_ipv6 *)(SRC));
+ *((struct prefix_ipv6 *)(DST)) = *((const struct prefix_ipv6 *)(SRC))
extern int ip6_masklen(struct in6_addr);
extern void masklen2ip6(const int, struct in6_addr *);
diff --git a/lib/zclient.c b/lib/zclient.c
index bab1acf667..053014f86d 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -249,12 +249,12 @@ int zclient_socket_connect(struct zclient *zclient)
return sock;
}
-static int zclient_failed(struct zclient *zclient)
+static enum zclient_send_status zclient_failed(struct zclient *zclient)
{
zclient->fail++;
zclient_stop(zclient);
zclient_event(ZCLIENT_CONNECT, zclient);
- return -1;
+ return ZCLIENT_SEND_FAILURE;
}
static int zclient_flush_data(struct thread *thread)
@@ -277,15 +277,23 @@ static int zclient_flush_data(struct thread *thread)
zclient->sock, &zclient->t_write);
break;
case BUFFER_EMPTY:
+ if (zclient->zebra_buffer_write_ready)
+ (*zclient->zebra_buffer_write_ready)();
break;
}
return 0;
}
-int zclient_send_message(struct zclient *zclient)
+/*
+ * Returns:
+ * ZCLIENT_SEND_FAILED - is a failure
+ * ZCLIENT_SEND_SUCCESS - means we sent data to zebra
+ * ZCLIENT_SEND_BUFFERED - means we are buffering
+ */
+enum zclient_send_status zclient_send_message(struct zclient *zclient)
{
if (zclient->sock < 0)
- return -1;
+ return ZCLIENT_SEND_FAILURE;
switch (buffer_write(zclient->wb, zclient->sock,
STREAM_DATA(zclient->obuf),
stream_get_endp(zclient->obuf))) {
@@ -296,13 +304,15 @@ int zclient_send_message(struct zclient *zclient)
return zclient_failed(zclient);
case BUFFER_EMPTY:
THREAD_OFF(zclient->t_write);
- break;
+ return ZCLIENT_SEND_SUCCESS;
case BUFFER_PENDING:
thread_add_write(zclient->master, zclient_flush_data, zclient,
zclient->sock, &zclient->t_write);
- break;
+ return ZCLIENT_SEND_BUFFERED;
}
- return 0;
+
+ /* should not get here */
+ return ZCLIENT_SEND_SUCCESS;
}
/*
@@ -362,8 +372,8 @@ stream_failure:
}
/* Send simple Zebra message. */
-static int zebra_message_send(struct zclient *zclient, int command,
- vrf_id_t vrf_id)
+static enum zclient_send_status zebra_message_send(struct zclient *zclient,
+ int command, vrf_id_t vrf_id)
{
struct stream *s;
@@ -377,7 +387,7 @@ static int zebra_message_send(struct zclient *zclient, int command,
return zclient_send_message(zclient);
}
-int zclient_send_hello(struct zclient *zclient)
+enum zclient_send_status zclient_send_hello(struct zclient *zclient)
{
struct stream *s;
@@ -403,11 +413,13 @@ int zclient_send_hello(struct zclient *zclient)
return zclient_send_message(zclient);
}
- return 0;
+ return ZCLIENT_SEND_SUCCESS;
}
-void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, afi_t afi,
- mpls_label_t label, enum lsp_types_t ltype)
+enum zclient_send_status zclient_send_vrf_label(struct zclient *zclient,
+ vrf_id_t vrf_id, afi_t afi,
+ mpls_label_t label,
+ enum lsp_types_t ltype)
{
struct stream *s;
@@ -419,7 +431,7 @@ void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, afi_t afi,
stream_putc(s, afi);
stream_putc(s, ltype);
stream_putw_at(s, 0, stream_get_endp(s));
- zclient_send_message(zclient);
+ return zclient_send_message(zclient);
}
/* Send register requests to zebra daemon for the information in a VRF. */
@@ -557,9 +569,10 @@ void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
}
}
-int zclient_send_router_id_update(struct zclient *zclient,
- zebra_message_types_t type, afi_t afi,
- vrf_id_t vrf_id)
+enum zclient_send_status
+zclient_send_router_id_update(struct zclient *zclient,
+ zebra_message_types_t type, afi_t afi,
+ vrf_id_t vrf_id)
{
struct stream *s = zclient->obuf;
stream_reset(s);
@@ -570,15 +583,16 @@ int zclient_send_router_id_update(struct zclient *zclient,
}
/* Send request to zebra daemon to start or stop RA. */
-void zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
- struct interface *ifp, int enable,
- int ra_interval)
+enum zclient_send_status
+zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
+ struct interface *ifp, int enable,
+ int ra_interval)
{
struct stream *s;
/* If not connected to the zebra yet. */
if (zclient->sock < 0)
- return;
+ return ZCLIENT_SEND_FAILURE;
/* Form and send message. */
s = zclient->obuf;
@@ -594,16 +608,17 @@ void zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
stream_putw_at(s, 0, stream_get_endp(s));
- zclient_send_message(zclient);
+ return zclient_send_message(zclient);
}
-int zclient_send_interface_protodown(struct zclient *zclient, vrf_id_t vrf_id,
- struct interface *ifp, bool down)
+enum zclient_send_status
+zclient_send_interface_protodown(struct zclient *zclient, vrf_id_t vrf_id,
+ struct interface *ifp, bool down)
{
struct stream *s;
if (zclient->sock < 0)
- return -1;
+ return ZCLIENT_SEND_FAILURE;
s = zclient->obuf;
stream_reset(s);
@@ -611,9 +626,7 @@ int zclient_send_interface_protodown(struct zclient *zclient, vrf_id_t vrf_id,
stream_putl(s, ifp->ifindex);
stream_putc(s, !!down);
stream_putw_at(s, 0, stream_get_endp(s));
- zclient_send_message(zclient);
-
- return 0;
+ return zclient_send_message(zclient);
}
/* Make connection to zebra daemon. */
@@ -712,9 +725,9 @@ static int zclient_connect(struct thread *t)
return zclient_start(zclient);
}
-int zclient_send_rnh(struct zclient *zclient, int command,
- const struct prefix *p, bool exact_match,
- vrf_id_t vrf_id)
+enum zclient_send_status zclient_send_rnh(struct zclient *zclient, int command,
+ const struct prefix *p,
+ bool exact_match, vrf_id_t vrf_id)
{
struct stream *s;
@@ -750,45 +763,10 @@ int zclient_send_rnh(struct zclient *zclient, int command,
* The corresponding read ("xdr_decode") function on the server
* side is zapi_route_decode().
*
- * 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Length (2) | Command | Route Type |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | ZEBRA Flags | Message Flags | Prefix length |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Destination IPv4 Prefix for route |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Nexthop count |
- * +-+-+-+-+-+-+-+-+
- *
- *
- * A number of IPv4 nexthop(s) or nexthop interface index(es) are then
- * described, as per the Nexthop count. Each nexthop described as:
- *
- * +-+-+-+-+-+-+-+-+
- * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_*
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | IPv4 Nexthop address or Interface Index number |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * Alternatively, if the route is a blackhole route, then Nexthop count
- * is set to 1 and a nexthop of type NEXTHOP_TYPE_BLACKHOLE is the sole
- * nexthop.
- *
- * The original struct zapi_route_*() infrastructure was built around
- * the traditional (32-bit "gate OR ifindex") nexthop data unit.
- * A special encoding can be used to feed onlink (64-bit "gate AND ifindex")
- * nexthops into zapi_route_encode() using the same zapi_route structure.
- * This is done by setting zapi_route fields as follows:
- * - .message |= ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_ONLINK
- * - .nexthop_num == .ifindex_num
- * - .nexthop and .ifindex are filled with gate and ifindex parts of
- * each compound nexthop, both in the same order
- *
* If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
* byte value.
*
- * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
+ * If ZAPI_MESSAGE_METRIC is set, the metric value is written as a 4
* byte value.
*
* If ZAPI_MESSAGE_TAG is set, the tag value is written as a 4 byte value
@@ -797,11 +775,11 @@ int zclient_send_rnh(struct zclient *zclient, int command,
*
* XXX: No attention paid to alignment.
*/
-int zclient_route_send(uint8_t cmd, struct zclient *zclient,
- struct zapi_route *api)
+enum zclient_send_status
+zclient_route_send(uint8_t cmd, struct zclient *zclient, struct zapi_route *api)
{
if (zapi_route_encode(cmd, zclient->obuf, api) < 0)
- return -1;
+ return ZCLIENT_SEND_FAILURE;
return zclient_send_message(zclient);
}
@@ -1058,7 +1036,8 @@ int zapi_nhg_encode(struct stream *s, int cmd, struct zapi_nhg *api_nhg)
return 0;
}
-int zclient_nhg_send(struct zclient *zclient, int cmd, struct zapi_nhg *api_nhg)
+enum zclient_send_status zclient_nhg_send(struct zclient *zclient, int cmd,
+ struct zapi_nhg *api_nhg)
{
api_nhg->proto = zclient->redist_default;
@@ -1791,8 +1770,9 @@ stream_failure:
* then set/unset redist[type] in the client handle (a struct zserv) for the
* sending client
*/
-int zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
- int type, unsigned short instance, vrf_id_t vrf_id)
+enum zclient_send_status
+zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
+ int type, unsigned short instance, vrf_id_t vrf_id)
{
struct stream *s;
@@ -1809,8 +1789,9 @@ int zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
return zclient_send_message(zclient);
}
-int zebra_redistribute_default_send(int command, struct zclient *zclient,
- afi_t afi, vrf_id_t vrf_id)
+enum zclient_send_status
+zebra_redistribute_default_send(int command, struct zclient *zclient, afi_t afi,
+ vrf_id_t vrf_id)
{
struct stream *s;
@@ -2601,8 +2582,10 @@ stream_failure:
* @param base Base for the label chunk. if MPLS_LABEL_BASE_ANY we do not care
* @result 0 on success, -1 otherwise
*/
-int zclient_send_get_label_chunk(struct zclient *zclient, uint8_t keep,
- uint32_t chunk_size, uint32_t base)
+enum zclient_send_status zclient_send_get_label_chunk(struct zclient *zclient,
+ uint8_t keep,
+ uint32_t chunk_size,
+ uint32_t base)
{
struct stream *s;
@@ -2610,7 +2593,7 @@ int zclient_send_get_label_chunk(struct zclient *zclient, uint8_t keep,
zlog_debug("Getting Label Chunk");
if (zclient->sock < 0)
- return -1;
+ return ZCLIENT_SEND_FAILURE;
s = zclient->obuf;
stream_reset(s);
@@ -2826,7 +2809,7 @@ int tm_table_manager_connect(struct zclient *zclient)
zlog_debug("Connecting to Table Manager");
if (zclient->sock < 0)
- return -1;
+ return ZCLIENT_SEND_FAILURE;
/* send request */
s = zclient->obuf;
@@ -2842,7 +2825,7 @@ int tm_table_manager_connect(struct zclient *zclient)
stream_putw_at(s, 0, stream_get_endp(s));
ret = zclient_send_message(zclient);
- if (ret < 0)
+ if (ret == ZCLIENT_SEND_FAILURE)
return -1;
if (zclient_debug)
@@ -2967,14 +2950,17 @@ int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
/* Put length at the first point of the stream. */
stream_putw_at(s, 0, stream_get_endp(s));
- return zclient_send_message(zclient);
+ if (zclient_send_message(zclient) == ZCLIENT_SEND_FAILURE)
+ return -1;
+
+ return 0;
}
-int zebra_send_sr_policy(struct zclient *zclient, int cmd,
- struct zapi_sr_policy *zp)
+enum zclient_send_status zebra_send_sr_policy(struct zclient *zclient, int cmd,
+ struct zapi_sr_policy *zp)
{
if (zapi_sr_policy_encode(zclient->obuf, cmd, zp) < 0)
- return -1;
+ return ZCLIENT_SEND_FAILURE;
return zclient_send_message(zclient);
}
@@ -3056,11 +3042,11 @@ stream_failure:
return -1;
}
-int zebra_send_mpls_labels(struct zclient *zclient, int cmd,
- struct zapi_labels *zl)
+enum zclient_send_status zebra_send_mpls_labels(struct zclient *zclient,
+ int cmd, struct zapi_labels *zl)
{
if (zapi_labels_encode(zclient->obuf, cmd, zl) < 0)
- return -1;
+ return ZCLIENT_SEND_FAILURE;
return zclient_send_message(zclient);
}
@@ -3221,7 +3207,8 @@ stream_failure:
return -1;
}
-int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw)
+enum zclient_send_status zebra_send_pw(struct zclient *zclient, int command,
+ struct zapi_pw *pw)
{
struct stream *s;
@@ -3247,7 +3234,7 @@ int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw)
break;
default:
flog_err(EC_LIB_ZAPI_ENCODE, "%s: unknown af", __func__);
- return -1;
+ return ZCLIENT_SEND_FAILURE;
}
/* Put labels */
@@ -3316,7 +3303,8 @@ stream_failure:
return;
}
-void zclient_send_mlag_register(struct zclient *client, uint32_t bit_map)
+enum zclient_send_status zclient_send_mlag_register(struct zclient *client,
+ uint32_t bit_map)
{
struct stream *s;
@@ -3327,15 +3315,16 @@ void zclient_send_mlag_register(struct zclient *client, uint32_t bit_map)
stream_putl(s, bit_map);
stream_putw_at(s, 0, stream_get_endp(s));
- zclient_send_message(client);
+ return zclient_send_message(client);
}
-void zclient_send_mlag_deregister(struct zclient *client)
+enum zclient_send_status zclient_send_mlag_deregister(struct zclient *client)
{
- zebra_message_send(client, ZEBRA_MLAG_CLIENT_UNREGISTER, VRF_DEFAULT);
+ return zebra_message_send(client, ZEBRA_MLAG_CLIENT_UNREGISTER, VRF_DEFAULT);
}
-void zclient_send_mlag_data(struct zclient *client, struct stream *client_s)
+enum zclient_send_status zclient_send_mlag_data(struct zclient *client,
+ struct stream *client_s)
{
struct stream *s;
@@ -3346,7 +3335,7 @@ void zclient_send_mlag_data(struct zclient *client, struct stream *client_s)
stream_put(s, client_s->data, client_s->endp);
stream_putw_at(s, 0, stream_get_endp(s));
- zclient_send_message(client);
+ return zclient_send_message(client);
}
static void zclient_mlag_process_up(ZAPI_CALLBACK_ARGS)
@@ -3371,17 +3360,17 @@ static void zclient_mlag_handle_msg(ZAPI_CALLBACK_ARGS)
* Send an OPAQUE message, contents opaque to zebra. The message header
* is a message subtype.
*/
-int zclient_send_opaque(struct zclient *zclient, uint32_t type,
- const uint8_t *data, size_t datasize)
+enum zclient_send_status zclient_send_opaque(struct zclient *zclient,
+ uint32_t type, const uint8_t *data,
+ size_t datasize)
{
- int ret;
struct stream *s;
uint16_t flags = 0;
/* Check buffer size */
if (STREAM_SIZE(zclient->obuf) <
(ZEBRA_HEADER_SIZE + sizeof(type) + datasize))
- return -1;
+ return ZCLIENT_SEND_FAILURE;
s = zclient->obuf;
stream_reset(s);
@@ -3398,28 +3387,26 @@ int zclient_send_opaque(struct zclient *zclient, uint32_t type,
/* Put length into the header at the start of the stream. */
stream_putw_at(s, 0, stream_get_endp(s));
- ret = zclient_send_message(zclient);
-
- return ret;
+ return zclient_send_message(zclient);
}
/*
* Send an OPAQUE message to a specific zclient. The contents are opaque
* to zebra.
*/
-int zclient_send_opaque_unicast(struct zclient *zclient, uint32_t type,
- uint8_t proto, uint16_t instance,
- uint32_t session_id, const uint8_t *data,
- size_t datasize)
+enum zclient_send_status
+zclient_send_opaque_unicast(struct zclient *zclient, uint32_t type,
+ uint8_t proto, uint16_t instance,
+ uint32_t session_id, const uint8_t *data,
+ size_t datasize)
{
- int ret;
struct stream *s;
uint16_t flags = 0;
/* Check buffer size */
if (STREAM_SIZE(zclient->obuf) <
(ZEBRA_HEADER_SIZE + sizeof(struct zapi_opaque_msg) + datasize))
- return -1;
+ return ZCLIENT_SEND_FAILURE;
s = zclient->obuf;
stream_reset(s);
@@ -3442,9 +3429,7 @@ int zclient_send_opaque_unicast(struct zclient *zclient, uint32_t type,
/* Put length into the header at the start of the stream. */
stream_putw_at(s, 0, stream_get_endp(s));
- ret = zclient_send_message(zclient);
-
- return ret;
+ return zclient_send_message(zclient);
}
/*
@@ -3477,9 +3462,9 @@ stream_failure:
/*
* Send a registration request for opaque messages with a specified subtype.
*/
-int zclient_register_opaque(struct zclient *zclient, uint32_t type)
+enum zclient_send_status zclient_register_opaque(struct zclient *zclient,
+ uint32_t type)
{
- int ret;
struct stream *s;
s = zclient->obuf;
@@ -3498,17 +3483,15 @@ int zclient_register_opaque(struct zclient *zclient, uint32_t type)
/* Put length at the first point of the stream. */
stream_putw_at(s, 0, stream_get_endp(s));
- ret = zclient_send_message(zclient);
-
- return ret;
+ return zclient_send_message(zclient);
}
/*
* Send an un-registration request for a specified opaque subtype.
*/
-int zclient_unregister_opaque(struct zclient *zclient, uint32_t type)
+enum zclient_send_status zclient_unregister_opaque(struct zclient *zclient,
+ uint32_t type)
{
- int ret;
struct stream *s;
s = zclient->obuf;
@@ -3527,9 +3510,7 @@ int zclient_unregister_opaque(struct zclient *zclient, uint32_t type)
/* Put length at the first point of the stream. */
stream_putw_at(s, 0, stream_get_endp(s));
- ret = zclient_send_message(zclient);
-
- return ret;
+ return zclient_send_message(zclient);
}
/* Utility to decode opaque registration info */
@@ -3984,9 +3965,9 @@ static void zclient_event(enum event event, struct zclient *zclient)
}
}
-void zclient_interface_set_master(struct zclient *client,
- struct interface *master,
- struct interface *slave)
+enum zclient_send_status zclient_interface_set_master(struct zclient *client,
+ struct interface *master,
+ struct interface *slave)
{
struct stream *s;
@@ -4001,20 +3982,21 @@ void zclient_interface_set_master(struct zclient *client,
stream_putl(s, slave->ifindex);
stream_putw_at(s, 0, stream_get_endp(s));
- zclient_send_message(client);
+ return zclient_send_message(client);
}
/*
* Send capabilities message to zebra
*/
-int32_t zclient_capabilities_send(uint32_t cmd, struct zclient *zclient,
- struct zapi_cap *api)
+enum zclient_send_status zclient_capabilities_send(uint32_t cmd,
+ struct zclient *zclient,
+ struct zapi_cap *api)
{
struct stream *s;
if (zclient == NULL)
- return -1;
+ return ZCLIENT_SEND_FAILURE;
s = zclient->obuf;
stream_reset(s);
@@ -4073,9 +4055,10 @@ stream_failure:
return 0;
}
-int zclient_send_neigh_discovery_req(struct zclient *zclient,
- const struct interface *ifp,
- const struct prefix *p)
+enum zclient_send_status
+zclient_send_neigh_discovery_req(struct zclient *zclient,
+ const struct interface *ifp,
+ const struct prefix *p)
{
struct stream *s;
diff --git a/lib/zclient.h b/lib/zclient.h
index 3c80ba7efa..ae94237b76 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -54,6 +54,7 @@ typedef uint16_t zebra_size_t;
/* For input/output buffer to zebra. */
#define ZEBRA_MAX_PACKET_SIZ 16384U
+#define ZEBRA_SMALL_PACKET_SIZE 200U
/* Zebra header size. */
#define ZEBRA_HEADER_SIZE 10
@@ -320,6 +321,18 @@ struct zclient {
/* Pointer to the callback functions. */
void (*zebra_connected)(struct zclient *);
void (*zebra_capabilities)(struct zclient_capabilities *cap);
+
+ /*
+ * When the zclient attempts to write the stream data to
+ * it's named pipe to/from zebra, we may have a situation
+ * where the other daemon has not fully drained the data
+ * from the socket. In this case provide a mechanism
+ * where we will *still* buffer the data to be sent
+ * and also provide a callback mechanism to the appropriate
+ * place where we can signal that we're ready to receive
+ * 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);
@@ -663,6 +676,12 @@ enum zapi_iptable_notify_owner {
ZAPI_IPTABLE_FAIL_REMOVE,
};
+enum zclient_send_status {
+ ZCLIENT_SEND_FAILURE = -1,
+ ZCLIENT_SEND_SUCCESS = 0,
+ ZCLIENT_SEND_BUFFERED = 1
+};
+
static inline const char *
zapi_rule_notify_owner2str(enum zapi_rule_notify_owner note)
{
@@ -760,31 +779,33 @@ extern void redist_del_all_instances(struct redist_proto *red);
* we have installed and play some special games
* to get them both installed.
*/
-extern void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id,
- afi_t afi, mpls_label_t label,
- enum lsp_types_t ltype);
+extern enum zclient_send_status
+zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, afi_t afi,
+ mpls_label_t label, enum lsp_types_t ltype);
extern void zclient_send_reg_requests(struct zclient *, vrf_id_t);
extern void zclient_send_dereg_requests(struct zclient *, vrf_id_t);
-extern int zclient_send_router_id_update(struct zclient *zclient,
- zebra_message_types_t type, afi_t afi,
- vrf_id_t vrf_id);
-
-extern void zclient_send_interface_radv_req(struct zclient *zclient,
- vrf_id_t vrf_id,
- struct interface *ifp, int enable,
- int ra_interval);
-extern int zclient_send_interface_protodown(struct zclient *zclient,
- vrf_id_t vrf_id,
- struct interface *ifp, bool down);
+extern enum zclient_send_status
+zclient_send_router_id_update(struct zclient *zclient,
+ zebra_message_types_t type, afi_t afi,
+ vrf_id_t vrf_id);
+
+extern enum zclient_send_status
+zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
+ struct interface *ifp, int enable,
+ int ra_interval);
+extern enum zclient_send_status
+zclient_send_interface_protodown(struct zclient *zclient, vrf_id_t vrf_id,
+ struct interface *ifp, bool down);
/* Send redistribute command to zebra daemon. Do not update zclient state. */
-extern int zebra_redistribute_send(int command, struct zclient *, afi_t,
- int type, unsigned short instance,
- vrf_id_t vrf_id);
+extern enum zclient_send_status
+zebra_redistribute_send(int command, struct zclient *, afi_t, int type,
+ unsigned short instance, vrf_id_t vrf_id);
-extern int zebra_redistribute_default_send(int command, struct zclient *zclient,
- afi_t afi, vrf_id_t vrf_id);
+extern enum zclient_send_status
+zebra_redistribute_default_send(int command, struct zclient *zclient, afi_t afi,
+ vrf_id_t vrf_id);
/* Send route notify request to zebra */
extern int zebra_route_notify_send(int command, struct zclient *zclient,
@@ -798,9 +819,14 @@ extern void zclient_redistribute(int command, struct zclient *, afi_t, int type,
extern void zclient_redistribute_default(int command, struct zclient *,
afi_t, vrf_id_t vrf_id);
-/* Send the message in zclient->obuf to the zebra daemon (or enqueue it).
- Returns 0 for success or -1 on an I/O error. */
-extern int zclient_send_message(struct zclient *);
+/*
+ * Send the message in zclient->obuf to the zebra daemon (or enqueue it).
+ * Returns:
+ * -1 on a I/O error
+ * 0 data was successfully sent
+ * 1 data was buffered for future usage
+ */
+extern enum zclient_send_status zclient_send_message(struct zclient *);
/* create header for command, length to be filled in by user later */
extern void zclient_create_header(struct stream *, uint16_t, vrf_id_t);
@@ -857,9 +883,9 @@ extern int zclient_read_header(struct stream *s, int sock, uint16_t *size,
*/
extern bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr);
-extern void zclient_interface_set_master(struct zclient *client,
- struct interface *master,
- struct interface *slave);
+extern enum zclient_send_status
+zclient_interface_set_master(struct zclient *client, struct interface *master,
+ struct interface *slave);
extern struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t);
extern struct connected *zebra_interface_address_read(int, struct stream *,
vrf_id_t);
@@ -874,8 +900,9 @@ extern struct interface *zebra_interface_link_params_read(struct stream *s,
vrf_id_t vrf_id);
extern size_t zebra_interface_link_params_write(struct stream *,
struct interface *);
-extern int zclient_send_get_label_chunk(struct zclient *zclient, uint8_t keep,
- uint32_t chunk_size, uint32_t base);
+extern enum zclient_send_status
+zclient_send_get_label_chunk(struct zclient *zclient, uint8_t keep,
+ uint32_t chunk_size, uint32_t base);
extern int lm_label_manager_connect(struct zclient *zclient, int async);
extern int lm_get_label_chunk(struct zclient *zclient, uint8_t keep,
@@ -889,29 +916,32 @@ extern int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size,
extern int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
uint32_t end);
-extern int zebra_send_sr_policy(struct zclient *zclient, int cmd,
- struct zapi_sr_policy *zp);
+extern enum zclient_send_status zebra_send_sr_policy(struct zclient *zclient,
+ int cmd,
+ struct zapi_sr_policy *zp);
extern int zapi_sr_policy_encode(struct stream *s, int cmd,
struct zapi_sr_policy *zp);
extern int zapi_sr_policy_decode(struct stream *s, struct zapi_sr_policy *zp);
extern int zapi_sr_policy_notify_status_decode(struct stream *s,
struct zapi_sr_policy *zp);
-extern int zebra_send_mpls_labels(struct zclient *zclient, int cmd,
- struct zapi_labels *zl);
+extern enum zclient_send_status zebra_send_mpls_labels(struct zclient *zclient,
+ int cmd,
+ struct zapi_labels *zl);
extern int zapi_labels_encode(struct stream *s, int cmd,
struct zapi_labels *zl);
extern int zapi_labels_decode(struct stream *s, struct zapi_labels *zl);
-extern int zebra_send_pw(struct zclient *zclient, int command,
- struct zapi_pw *pw);
+extern enum zclient_send_status zebra_send_pw(struct zclient *zclient,
+ int command, struct zapi_pw *pw);
extern int zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS,
struct zapi_pw_status *pw);
-extern int zclient_route_send(uint8_t, struct zclient *, struct zapi_route *);
-extern int zclient_send_rnh(struct zclient *zclient, int command,
- const struct prefix *p, bool exact_match,
- vrf_id_t vrf_id);
+extern enum zclient_send_status zclient_route_send(uint8_t, struct zclient *,
+ struct zapi_route *);
+extern enum zclient_send_status
+zclient_send_rnh(struct zclient *zclient, int command, const struct prefix *p,
+ bool exact_match, vrf_id_t vrf_id);
int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh,
uint32_t api_flags, uint32_t api_message);
extern int zapi_route_encode(uint8_t, struct stream *, struct zapi_route *);
@@ -934,8 +964,8 @@ bool zapi_ipset_notify_decode(struct stream *s,
extern int zapi_nhg_encode(struct stream *s, int cmd, struct zapi_nhg *api_nhg);
extern int zapi_nhg_decode(struct stream *s, int cmd, struct zapi_nhg *api_nhg);
-extern int zclient_nhg_send(struct zclient *zclient, int cmd,
- struct zapi_nhg *api_nhg);
+extern enum zclient_send_status
+zclient_nhg_send(struct zclient *zclient, int cmd, struct zapi_nhg *api_nhg);
#define ZEBRA_IPSET_NAME_SIZE 32
@@ -962,8 +992,9 @@ const char *zapi_nexthop2str(const struct zapi_nexthop *znh, char *buf,
extern bool zapi_error_decode(struct stream *s, enum zebra_error_types *error);
/* Encode and decode restart capabilities */
-extern int32_t zclient_capabilities_send(uint32_t cmd, struct zclient *zclient,
- struct zapi_cap *api);
+extern enum zclient_send_status
+zclient_capabilities_send(uint32_t cmd, struct zclient *zclient,
+ struct zapi_cap *api);
extern int32_t zapi_capabilities_decode(struct stream *s, struct zapi_cap *api);
static inline void zapi_route_set_blackhole(struct zapi_route *api,
@@ -976,12 +1007,13 @@ static inline void zapi_route_set_blackhole(struct zapi_route *api,
SET_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP);
};
-extern void zclient_send_mlag_register(struct zclient *client,
- uint32_t bit_map);
-extern void zclient_send_mlag_deregister(struct zclient *client);
+extern enum zclient_send_status
+zclient_send_mlag_register(struct zclient *client, uint32_t bit_map);
+extern enum zclient_send_status
+zclient_send_mlag_deregister(struct zclient *client);
-extern void zclient_send_mlag_data(struct zclient *client,
- struct stream *client_s);
+extern enum zclient_send_status zclient_send_mlag_data(struct zclient *client,
+ struct stream *client_s);
/*
* Send an OPAQUE message, contents opaque to zebra - but note that
@@ -991,13 +1023,15 @@ extern void zclient_send_mlag_data(struct zclient *client,
* below to avoid sub-type collisions. Clients use the registration
* apis to manage the specific opaque subtypes they want to receive.
*/
-int zclient_send_opaque(struct zclient *zclient, uint32_t type,
- const uint8_t *data, size_t datasize);
+enum zclient_send_status zclient_send_opaque(struct zclient *zclient,
+ uint32_t type, const uint8_t *data,
+ size_t datasize);
-int zclient_send_opaque_unicast(struct zclient *zclient, uint32_t type,
- uint8_t proto, uint16_t instance,
- uint32_t session_id, const uint8_t *data,
- size_t datasize);
+enum zclient_send_status
+zclient_send_opaque_unicast(struct zclient *zclient, uint32_t type,
+ uint8_t proto, uint16_t instance,
+ uint32_t session_id, const uint8_t *data,
+ size_t datasize);
/* Struct representing the decoded opaque header info */
struct zapi_opaque_msg {
@@ -1027,8 +1061,10 @@ struct zapi_opaque_reg_info {
/* Decode incoming opaque */
int zclient_opaque_decode(struct stream *msg, struct zapi_opaque_msg *info);
-int zclient_register_opaque(struct zclient *zclient, uint32_t type);
-int zclient_unregister_opaque(struct zclient *zclient, uint32_t type);
+enum zclient_send_status zclient_register_opaque(struct zclient *zclient,
+ uint32_t type);
+enum zclient_send_status zclient_unregister_opaque(struct zclient *zclient,
+ uint32_t type);
int zapi_opaque_reg_decode(struct stream *msg,
struct zapi_opaque_reg_info *info);
@@ -1054,11 +1090,12 @@ enum zapi_opaque_registry {
/* Send the hello message.
* Returns 0 for success or -1 on an I/O error.
*/
-extern int zclient_send_hello(struct zclient *client);
+extern enum zclient_send_status zclient_send_hello(struct zclient *client);
-extern int zclient_send_neigh_discovery_req(struct zclient *zclient,
- const struct interface *ifp,
- const struct prefix *p);
+extern enum zclient_send_status
+zclient_send_neigh_discovery_req(struct zclient *zclient,
+ const struct interface *ifp,
+ const struct prefix *p);
#ifdef __cplusplus
}
diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c
index 0892863cf1..c136c558cb 100644
--- a/ospf6d/ospf6_lsdb.c
+++ b/ospf6d/ospf6_lsdb.c
@@ -68,9 +68,9 @@ static void ospf6_lsdb_set_key(struct prefix_ipv6 *key, const void *value,
#ifdef DEBUG
static void _lsdb_count_assert(struct ospf6_lsdb *lsdb)
{
- struct ospf6_lsa *debug;
+ struct ospf6_lsa *debug, *debugnext;
unsigned int num = 0;
- for (ALL_LSDB(lsdb, debug))
+ for (ALL_LSDB(lsdb, debug, debugnext))
num++;
if (num == lsdb->count)
@@ -78,7 +78,7 @@ static void _lsdb_count_assert(struct ospf6_lsdb *lsdb)
zlog_debug("PANIC !! lsdb[%p]->count = %d, real = %d", lsdb,
lsdb->count, num);
- for (ALL_LSDB(lsdb, debug))
+ for (ALL_LSDB(lsdb, debug, debugnext))
zlog_debug("%s lsdb[%p]", debug->name, debug->lsdb);
zlog_debug("DUMP END");
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index 8d3ee1ad02..f21e940a77 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -362,7 +362,7 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request,
else
ret = zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
- if (ret < 0)
+ if (ret == ZCLIENT_SEND_FAILURE)
flog_err(EC_LIB_ZAPI_SOCKET,
"zclient_route_send() %s failed: %s",
(type == REM ? "delete" : "add"),
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index d449f9d2fa..e7dbdbd9af 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -1915,7 +1915,7 @@ int ospf_zebra_label_manager_connect(void)
set_nonblocking(zclient_sync->sock);
/* Send hello to notify zebra this is a synchronous client */
- if (zclient_send_hello(zclient_sync) < 0) {
+ if (zclient_send_hello(zclient_sync) == ZCLIENT_SEND_FAILURE) {
zlog_warn("%s: failed sending hello for synchronous zclient!",
__func__);
close(zclient_sync->sock);
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index 82a2d2feb5..222a10e751 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -476,8 +476,8 @@ void pbr_send_rnh(struct nexthop *nhop, bool reg)
break;
}
- if (zclient_send_rnh(zclient, command, &p,
- false, nhop->vrf_id) < 0) {
+ if (zclient_send_rnh(zclient, command, &p, false, nhop->vrf_id)
+ == ZCLIENT_SEND_FAILURE) {
zlog_warn("%s: Failure to send nexthop to zebra", __func__);
}
}
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index f691e8b755..68e0a45690 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -55,7 +55,7 @@ void pim_sendmsg_zebra_rnh(struct pim_instance *pim, struct zclient *zclient,
p = &(pnc->rpf.rpf_addr);
ret = zclient_send_rnh(zclient, command, p, false, pim->vrf_id);
- if (ret < 0)
+ if (ret == ZCLIENT_SEND_FAILURE)
zlog_warn("sendmsg_nexthop: zclient_send_message() failed");
if (PIM_DEBUG_PIM_NHT)
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index dc4c621e9c..05c9af8734 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -61,7 +61,7 @@ static int zclient_lookup_connect(struct thread *t)
zlookup->fail = 0; /* reset counter on connection */
}
- if (zclient_send_hello(zlookup) < 0) {
+ if (zclient_send_hello(zlookup) == ZCLIENT_SEND_FAILURE) {
if (close(zlookup->sock)) {
zlog_warn("%s: closing fd=%d: errno=%d %s", __func__,
zlookup->sock, errno, safe_strerror(errno));
diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c
index 7a335fca3b..627caea37d 100644
--- a/sharpd/sharp_zebra.c
+++ b/sharpd/sharp_zebra.c
@@ -211,66 +211,217 @@ int sharp_install_lsps_helper(bool install_p, bool update_p,
cmd = ZEBRA_MPLS_LABELS_DELETE;
}
- ret = zebra_send_mpls_labels(zclient, cmd, &zl);
+ if (zebra_send_mpls_labels(zclient, cmd, &zl) == ZCLIENT_SEND_FAILURE)
+ return -1;
- return ret;
+ return 0;
}
-void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id,
- uint8_t instance, uint32_t nhgid,
- const struct nexthop_group *nhg,
- const struct nexthop_group *backup_nhg,
- uint32_t routes)
+enum where_to_restart {
+ SHARP_INSTALL_ROUTES_RESTART,
+ SHARP_DELETE_ROUTES_RESTART,
+};
+
+struct buffer_delay {
+ struct prefix p;
+ uint32_t count;
+ uint32_t routes;
+ vrf_id_t vrf_id;
+ uint8_t instance;
+ uint32_t nhgid;
+ const struct nexthop_group *nhg;
+ const struct nexthop_group *backup_nhg;
+ enum where_to_restart restart;
+} wb;
+
+/*
+ * route_add - Encodes a route to zebra
+ *
+ * This function returns true when the route was buffered
+ * by the underlying stream system
+ */
+static bool route_add(const struct prefix *p, vrf_id_t vrf_id, uint8_t instance,
+ uint32_t nhgid, const struct nexthop_group *nhg,
+ const struct nexthop_group *backup_nhg)
+{
+ struct zapi_route api;
+ struct zapi_nexthop *api_nh;
+ struct nexthop *nh;
+ int i = 0;
+
+ memset(&api, 0, sizeof(api));
+ api.vrf_id = vrf_id;
+ api.type = ZEBRA_ROUTE_SHARP;
+ api.instance = instance;
+ api.safi = SAFI_UNICAST;
+ memcpy(&api.prefix, p, sizeof(*p));
+
+ SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
+ SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
+
+ /* Only send via ID if nhgroup has been successfully installed */
+ if (nhgid && sharp_nhgroup_id_is_installed(nhgid)) {
+ SET_FLAG(api.message, ZAPI_MESSAGE_NHG);
+ api.nhgid = nhgid;
+ } else {
+ for (ALL_NEXTHOPS_PTR(nhg, nh)) {
+ api_nh = &api.nexthops[i];
+
+ zapi_nexthop_from_nexthop(api_nh, nh);
+
+ i++;
+ }
+ api.nexthop_num = i;
+ }
+
+ /* Include backup nexthops, if present */
+ if (backup_nhg && backup_nhg->nexthop) {
+ SET_FLAG(api.message, ZAPI_MESSAGE_BACKUP_NEXTHOPS);
+
+ i = 0;
+ for (ALL_NEXTHOPS_PTR(backup_nhg, nh)) {
+ api_nh = &api.backup_nexthops[i];
+
+ zapi_backup_nexthop_from_nexthop(api_nh, nh);
+
+ i++;
+ }
+
+ api.backup_nexthop_num = i;
+ }
+
+ if (zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api)
+ == ZCLIENT_SEND_BUFFERED)
+ return true;
+ else
+ return false;
+}
+
+/*
+ * route_delete - Encodes a route for deletion to zebra
+ *
+ * This function returns true when the route sent was
+ * buffered by the underlying stream system.
+ */
+static bool route_delete(struct prefix *p, vrf_id_t vrf_id, uint8_t instance)
+{
+ struct zapi_route api;
+
+ memset(&api, 0, sizeof(api));
+ api.vrf_id = vrf_id;
+ api.type = ZEBRA_ROUTE_SHARP;
+ api.safi = SAFI_UNICAST;
+ api.instance = instance;
+ memcpy(&api.prefix, p, sizeof(*p));
+
+ if (zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api)
+ == ZCLIENT_SEND_BUFFERED)
+ return true;
+ else
+ return false;
+}
+
+static void sharp_install_routes_restart(struct prefix *p, uint32_t count,
+ vrf_id_t vrf_id, uint8_t instance,
+ uint32_t nhgid,
+ const struct nexthop_group *nhg,
+ const struct nexthop_group *backup_nhg,
+ uint32_t routes)
{
uint32_t temp, i;
bool v4 = false;
- zlog_debug("Inserting %u routes", routes);
-
if (p->family == AF_INET) {
v4 = true;
temp = ntohl(p->u.prefix4.s_addr);
} else
temp = ntohl(p->u.val32[3]);
- /* Only use backup route/nexthops if present */
- if (backup_nhg && (backup_nhg->nexthop == NULL))
- backup_nhg = NULL;
-
- monotime(&sg.r.t_start);
- for (i = 0; i < routes; i++) {
- route_add(p, vrf_id, (uint8_t)instance, nhgid, nhg, backup_nhg);
+ for (i = count; i < routes; i++) {
+ bool buffered = route_add(p, vrf_id, (uint8_t)instance, nhgid,
+ nhg, backup_nhg);
if (v4)
p->u.prefix4.s_addr = htonl(++temp);
else
p->u.val32[3] = htonl(++temp);
+
+ if (buffered) {
+ wb.p = *p;
+ wb.count = i+1;
+ wb.routes = routes;
+ wb.vrf_id = vrf_id;
+ wb.instance = instance;
+ wb.nhgid = nhgid;
+ wb.nhg = nhg;
+ wb.backup_nhg = backup_nhg;
+ wb.restart = SHARP_INSTALL_ROUTES_RESTART;
+
+ return;
+ }
}
}
-void sharp_remove_routes_helper(struct prefix *p, vrf_id_t vrf_id,
- uint8_t instance, uint32_t routes)
+void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id,
+ uint8_t instance, uint32_t nhgid,
+ const struct nexthop_group *nhg,
+ const struct nexthop_group *backup_nhg,
+ uint32_t routes)
+{
+ zlog_debug("Inserting %u routes", routes);
+
+ /* Only use backup route/nexthops if present */
+ if (backup_nhg && (backup_nhg->nexthop == NULL))
+ backup_nhg = NULL;
+
+ monotime(&sg.r.t_start);
+ sharp_install_routes_restart(p, 0, vrf_id, instance, nhgid, nhg,
+ backup_nhg, routes);
+}
+
+static void sharp_remove_routes_restart(struct prefix *p, uint32_t count,
+ vrf_id_t vrf_id, uint8_t instance,
+ uint32_t routes)
{
uint32_t temp, i;
bool v4 = false;
- zlog_debug("Removing %u routes", routes);
-
if (p->family == AF_INET) {
v4 = true;
temp = ntohl(p->u.prefix4.s_addr);
} else
temp = ntohl(p->u.val32[3]);
- monotime(&sg.r.t_start);
- for (i = 0; i < routes; i++) {
- route_delete(p, vrf_id, (uint8_t)instance);
+ for (i = count; i < routes; i++) {
+ bool buffered = route_delete(p, vrf_id, (uint8_t)instance);
+
if (v4)
p->u.prefix4.s_addr = htonl(++temp);
else
p->u.val32[3] = htonl(++temp);
+
+ if (buffered) {
+ wb.p = *p;
+ wb.count = i + 1;
+ wb.vrf_id = vrf_id;
+ wb.instance = instance;
+ wb.routes = routes;
+ wb.restart = SHARP_DELETE_ROUTES_RESTART;
+
+ return;
+ }
}
}
+void sharp_remove_routes_helper(struct prefix *p, vrf_id_t vrf_id,
+ uint8_t instance, uint32_t routes)
+{
+ zlog_debug("Removing %u routes", routes);
+
+ monotime(&sg.r.t_start);
+
+ sharp_remove_routes_restart(p, 0, vrf_id, instance, routes);
+}
+
static void handle_repeated(bool installed)
{
struct prefix p = sg.r.orig_prefix;
@@ -294,6 +445,21 @@ static void handle_repeated(bool installed)
}
}
+static void sharp_zclient_buffer_ready(void)
+{
+ switch (wb.restart) {
+ case SHARP_INSTALL_ROUTES_RESTART:
+ sharp_install_routes_restart(&wb.p, wb.count, wb.vrf_id,
+ wb.instance, wb.nhgid, wb.nhg,
+ wb.backup_nhg, wb.routes);
+ return;
+ case SHARP_DELETE_ROUTES_RESTART:
+ sharp_remove_routes_restart(&wb.p, wb.count, wb.vrf_id,
+ wb.instance, wb.routes);
+ return;
+ }
+}
+
static int route_notify_owner(ZAPI_CALLBACK_ARGS)
{
struct timeval r;
@@ -408,74 +574,6 @@ void nhg_del(uint32_t id)
zclient_nhg_send(zclient, ZEBRA_NHG_DEL, &api_nhg);
}
-void route_add(const struct prefix *p, vrf_id_t vrf_id, uint8_t instance,
- uint32_t nhgid, const struct nexthop_group *nhg,
- const struct nexthop_group *backup_nhg)
-{
- struct zapi_route api;
- struct zapi_nexthop *api_nh;
- struct nexthop *nh;
- int i = 0;
-
- memset(&api, 0, sizeof(api));
- api.vrf_id = vrf_id;
- api.type = ZEBRA_ROUTE_SHARP;
- api.instance = instance;
- api.safi = SAFI_UNICAST;
- memcpy(&api.prefix, p, sizeof(*p));
-
- SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
- SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
-
- /* Only send via ID if nhgroup has been successfully installed */
- if (nhgid && sharp_nhgroup_id_is_installed(nhgid)) {
- SET_FLAG(api.message, ZAPI_MESSAGE_NHG);
- api.nhgid = nhgid;
- } else {
- for (ALL_NEXTHOPS_PTR(nhg, nh)) {
- api_nh = &api.nexthops[i];
-
- zapi_nexthop_from_nexthop(api_nh, nh);
-
- i++;
- }
- api.nexthop_num = i;
- }
-
- /* Include backup nexthops, if present */
- if (backup_nhg && backup_nhg->nexthop) {
- SET_FLAG(api.message, ZAPI_MESSAGE_BACKUP_NEXTHOPS);
-
- i = 0;
- for (ALL_NEXTHOPS_PTR(backup_nhg, nh)) {
- api_nh = &api.backup_nexthops[i];
-
- zapi_backup_nexthop_from_nexthop(api_nh, nh);
-
- i++;
- }
-
- api.backup_nexthop_num = i;
- }
-
- zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
-}
-
-void route_delete(struct prefix *p, vrf_id_t vrf_id, uint8_t instance)
-{
- struct zapi_route api;
-
- memset(&api, 0, sizeof(api));
- api.vrf_id = vrf_id;
- api.type = ZEBRA_ROUTE_SHARP;
- api.safi = SAFI_UNICAST;
- api.instance = instance;
- memcpy(&api.prefix, p, sizeof(*p));
- zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
-
- return;
-}
-
void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id, bool import,
bool watch, bool connected)
{
@@ -493,7 +591,8 @@ void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id, bool import,
command = ZEBRA_IMPORT_ROUTE_UNREGISTER;
}
- if (zclient_send_rnh(zclient, command, p, connected, vrf_id) < 0)
+ if (zclient_send_rnh(zclient, command, p, connected, vrf_id)
+ == ZCLIENT_SEND_FAILURE)
zlog_warn("%s: Failure to send nexthop to zebra", __func__);
}
@@ -679,7 +778,7 @@ void sharp_opaque_send(uint32_t type, uint32_t proto, uint32_t instance,
ret = zclient_send_opaque_unicast(zclient, type, proto,
instance, session_id,
buf, sizeof(buf));
- if (ret < 0) {
+ if (ret == ZCLIENT_SEND_FAILURE) {
zlog_debug("%s: send_opaque() failed => %d",
__func__, ret);
break;
@@ -768,7 +867,7 @@ void sharp_zebra_init(void)
zclient->nexthop_update = sharp_nexthop_update;
zclient->import_check_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;
diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h
index 4a767ababf..8c5fa5e15e 100644
--- a/sharpd/sharp_zebra.h
+++ b/sharpd/sharp_zebra.h
@@ -32,10 +32,6 @@ extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label);
extern void nhg_add(uint32_t id, const struct nexthop_group *nhg,
const struct nexthop_group *backup_nhg);
extern void nhg_del(uint32_t id);
-extern void route_add(const struct prefix *p, vrf_id_t, uint8_t instance,
- uint32_t nhgid, const struct nexthop_group *nhg,
- const struct nexthop_group *backup_nhg);
-extern void route_delete(struct prefix *p, vrf_id_t vrf_id, uint8_t instance);
extern void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id,
bool import, bool watch, bool connected);
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index 0bccbfbead..19c578c60e 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -331,7 +331,8 @@ void static_zebra_nht_register(struct route_node *rn, struct static_nexthop *nh,
static_nht_hash_free(nhtd);
}
- if (zclient_send_rnh(zclient, cmd, &p, false, nh->nh_vrf_id) < 0)
+ if (zclient_send_rnh(zclient, cmd, &p, false, nh->nh_vrf_id)
+ == ZCLIENT_SEND_FAILURE)
zlog_warn("%s: Failure to send nexthop to zebra", __func__);
}
/*
diff --git a/tests/helpers/python/frrtest.py b/tests/helpers/python/frrtest.py
index 0ac54fd900..584fa90374 100644
--- a/tests/helpers/python/frrtest.py
+++ b/tests/helpers/python/frrtest.py
@@ -168,8 +168,8 @@ class TestMultiOut(_TestMultiOut):
class TestRefMismatch(Exception):
def __init__(self, _test, outtext, reftext):
- self.outtext = outtext.decode("utf8") if type(outtext) is bytes else outtext
- self.reftext = reftext.decode("utf8") if type(reftext) is bytes else reftext
+ self.outtext = outtext
+ self.reftext = reftext
def __str__(self):
rv = "Expected output and actual output differ:\n"
@@ -214,7 +214,12 @@ class TestRefOut(object):
[binpath(program)], stdin=subprocess.PIPE, stdout=subprocess.PIPE
)
outtext, _ = proc.communicate(intext)
- if outtext != reftext:
- raise TestRefMismatch(self, outtext, reftext)
+
+ # Get rid of newline problems (Windows vs Unix Style)
+ outtext_str = outtext.decode("utf8").replace("\r\n", "\n").replace("\r", "\n")
+ reftext_str = reftext.decode("utf8").replace("\r\n", "\n").replace("\r", "\n")
+
+ if outtext_str != reftext_str:
+ raise TestRefMismatch(self, outtext_str, reftext_str)
if proc.wait() != 0:
raise TestExitNonzero(self)
diff --git a/tools/frr-reload.py b/tools/frr-reload.py
index 951383beb2..0de6c1c2e3 100755
--- a/tools/frr-reload.py
+++ b/tools/frr-reload.py
@@ -1301,6 +1301,12 @@ def compare_context_objects(newconf, running):
):
continue
+ # same thing for a pseudowire sub-context inside an l2vpn context
+ elif (len(running_ctx_keys) > 1 and running_ctx_keys[0].startswith('l2vpn') and
+ running_ctx_keys[1].startswith('member pseudowire') and
+ (running_ctx_keys[:1], None) in lines_to_del):
+ continue
+
# Non-global context
elif running_ctx_keys and not any(
"address-family" in key for key in running_ctx_keys
diff --git a/vrrpd/vrrp_zebra.c b/vrrpd/vrrp_zebra.c
index 37a1e4a624..385d443571 100644
--- a/vrrpd/vrrp_zebra.c
+++ b/vrrpd/vrrp_zebra.c
@@ -179,14 +179,13 @@ void vrrp_zebra_radv_set(struct vrrp_router *r, bool enable)
enable, VRRP_RADV_INT);
}
-int vrrp_zclient_send_interface_protodown(struct interface *ifp, bool down)
+void vrrp_zclient_send_interface_protodown(struct interface *ifp, bool down)
{
DEBUGD(&vrrp_dbg_zebra,
VRRP_LOGPFX "Requesting Zebra to set %s protodown %s", ifp->name,
down ? "on" : "off");
- return zclient_send_interface_protodown(zclient, ifp->vrf_id, ifp,
- down);
+ zclient_send_interface_protodown(zclient, ifp->vrf_id, ifp, down);
}
void vrrp_zebra_init(void)
diff --git a/vrrpd/vrrp_zebra.h b/vrrpd/vrrp_zebra.h
index 02d7055b86..c09943dcef 100644
--- a/vrrpd/vrrp_zebra.h
+++ b/vrrpd/vrrp_zebra.h
@@ -26,8 +26,8 @@
extern void vrrp_zebra_init(void);
extern void vrrp_zebra_radv_set(struct vrrp_router *r, bool enable);
-extern int vrrp_zclient_send_interface_protodown(struct interface *ifp,
- bool down);
+extern void vrrp_zclient_send_interface_protodown(struct interface *ifp,
+ bool down);
extern int vrrp_ifp_create(struct interface *ifp);
extern int vrrp_ifp_up(struct interface *ifp);
diff --git a/vtysh/subdir.am b/vtysh/subdir.am
index 1e4439d274..86861b0390 100644
--- a/vtysh/subdir.am
+++ b/vtysh/subdir.am
@@ -33,8 +33,9 @@ BUILT_SOURCES += vtysh/vtysh_daemons.h
# force vtysh_daemons.h
$(vtysh_vtysh_OBJECTS): vtysh/vtysh_daemons.h
+CLEANFILES += vtysh/vtysh_daemons.h
vtysh/vtysh_daemons.h:
- $(PERL) vtysh/daemons.pl $(vtysh_daemons) > vtysh/vtysh_daemons.h
+ $(PERL) $(top_srcdir)/vtysh/daemons.pl $(vtysh_daemons) > vtysh/vtysh_daemons.h
AM_V_EXTRACT = $(am__v_EXTRACT_$(V))
am__v_EXTRACT_ = $(am__v_EXTRACT_$(AM_DEFAULT_VERBOSITY))
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 1d68019909..f7c123231e 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -764,7 +764,11 @@ static int route_notify_internal(const struct prefix *p, int type,
"Notifying Owner: %s about prefix %pFX(%u) %d vrf: %u",
zebra_route_string(type), p, table_id, note, vrf_id);
- s = stream_new(ZEBRA_MAX_PACKET_SIZ);
+ /* We're just allocating a small-ish buffer here, since we only
+ * encode a small amount of data.
+ */
+ s = stream_new(ZEBRA_SMALL_PACKET_SIZE);
+
stream_reset(s);
zclient_create_header(s, ZEBRA_ROUTE_NOTIFY_OWNER, vrf_id);
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index 521f969fcc..3c4dbc5e9c 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -152,7 +152,7 @@ struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, enum rnh_type type,
flog_warn(EC_ZEBRA_RNH_NO_TABLE,
"%s(%u): Add RNH %pFX type %s - table not found",
VRF_LOGNAME(vrf), vrfid, p, rnh_type2str(type));
- exists = false;
+ *exists = false;
return NULL;
}