summaryrefslogtreecommitdiff
path: root/lib/zclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/zclient.c')
-rw-r--r--lib/zclient.c273
1 files changed, 141 insertions, 132 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index d0144279e5..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;
@@ -1494,9 +1473,12 @@ stream_failure:
bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
uint32_t *tableid,
- enum zapi_route_notify_owner *note)
+ enum zapi_route_notify_owner *note,
+ afi_t *afi, safi_t *safi)
{
uint32_t t;
+ afi_t afi_val;
+ safi_t safi_val;
STREAM_GET(note, s, sizeof(*note));
@@ -1504,9 +1486,16 @@ bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
STREAM_GETC(s, p->prefixlen);
STREAM_GET(&p->u.prefix, s, prefix_blen(p));
STREAM_GETL(s, t);
+ STREAM_GETC(s, afi_val);
+ STREAM_GETC(s, safi_val);
*tableid = t;
+ if (afi)
+ *afi = afi_val;
+ if (safi)
+ *safi = safi_val;
+
return true;
stream_failure:
@@ -1781,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;
@@ -1799,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;
@@ -1815,6 +1806,22 @@ int zebra_redistribute_default_send(int command, struct zclient *zclient,
return zclient_send_message(zclient);
}
+/* Send route notify request to zebra */
+int zebra_route_notify_send(int command, struct zclient *zclient, bool set)
+{
+ struct stream *s;
+
+ s = zclient->obuf;
+ stream_reset(s);
+
+ zclient_create_header(s, command, 0);
+ stream_putc(s, !!set);
+
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return zclient_send_message(zclient);
+}
+
/* Get prefix in ZServ format; family should be filled in on prefix */
static int zclient_stream_get_prefix(struct stream *s, struct prefix *p)
{
@@ -2575,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;
@@ -2584,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);
@@ -2800,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;
@@ -2816,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)
@@ -2941,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);
}
@@ -3030,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);
}
@@ -3195,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;
@@ -3221,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 */
@@ -3290,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;
@@ -3301,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;
@@ -3320,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)
@@ -3345,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);
@@ -3372,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);
@@ -3416,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);
}
/*
@@ -3451,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;
@@ -3472,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;
@@ -3501,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 */
@@ -3958,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;
@@ -3975,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);
@@ -4047,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;