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) != -1) && install) {
if (!pbr)
pbra->install_in_progress = true;
else
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) != -1) && install)
pbrim->install_in_progress = true;
}
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) != -1) && install)
pbrime->install_in_progress = true;
}
stream_putw_at(s, 0, stream_get_endp(s));
ret = zclient_send_message(zclient);
if (install) {
- if (ret)
+ if (ret != -1)
pba->refcnt++;
else
pbm->install_iptable_in_progress = true;
zclient->sock, &zclient->t_write);
break;
case BUFFER_EMPTY:
+ if (zclient->zebra_buffer_write_ready)
+ (*zclient->zebra_buffer_write_ready)();
break;
}
return 0;
}
+/*
+ * -1 is a failure
+ * 0 means we sent
+ * 1 means we are buffering
+ */
int zclient_send_message(struct zclient *zclient)
{
if (zclient->sock < 0)
return zclient_failed(zclient);
case BUFFER_EMPTY:
THREAD_OFF(zclient->t_write);
+ return 0;
break;
case BUFFER_PENDING:
thread_add_write(zclient->master, zclient_flush_data, zclient,
zclient->sock, &zclient->t_write);
+ return 1;
break;
}
+
+ /* should not get here */
return 0;
}
return 0;
}
-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)
+int 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;
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. */
}
/* 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)
+int 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 -1;
/* Form and send message. */
s = zclient->obuf;
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,
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. */
return;
}
-void zclient_send_mlag_register(struct zclient *client, uint32_t bit_map)
+int zclient_send_mlag_register(struct zclient *client, uint32_t bit_map)
{
struct stream *s;
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)
+int 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)
+int zclient_send_mlag_data(struct zclient *client, struct stream *client_s)
{
struct stream *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)
int 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;
/* 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);
}
/*
uint32_t session_id, const uint8_t *data,
size_t datasize)
{
- int ret;
struct stream *s;
uint16_t flags = 0;
/* 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);
}
/*
*/
int zclient_register_opaque(struct zclient *zclient, uint32_t type)
{
- int ret;
struct stream *s;
s = zclient->obuf;
/* 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);
}
/*
*/
int zclient_unregister_opaque(struct zclient *zclient, uint32_t type)
{
- int ret;
struct stream *s;
s = zclient->obuf;
/* 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 */
}
}
-void zclient_interface_set_master(struct zclient *client,
- struct interface *master,
- struct interface *slave)
+int zclient_interface_set_master(struct zclient *client,
+ struct interface *master,
+ struct interface *slave)
{
struct stream *s;
stream_putl(s, slave->ifindex);
stream_putw_at(s, 0, stream_get_endp(s));
- zclient_send_message(client);
+ return zclient_send_message(client);
}
/*
/* 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);
* 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 int 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);
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_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 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. */
+/*
+ * 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 int zclient_send_message(struct zclient *);
/* create header for command, length to be filled in by user later */
*/
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 int 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);
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 int zclient_send_mlag_register(struct zclient *client,
+ uint32_t bit_map);
+extern int zclient_send_mlag_deregister(struct zclient *client);
-extern void zclient_send_mlag_data(struct zclient *client,
- struct stream *client_s);
+extern int zclient_send_mlag_data(struct zclient *client,
+ struct stream *client_s);
/*
* Send an OPAQUE message, contents opaque to zebra - but note that