diff options
| -rw-r--r-- | bgpd/bgp_zebra.c | 8 | ||||
| -rw-r--r-- | lib/zclient.c | 71 | ||||
| -rw-r--r-- | lib/zclient.h | 51 |
3 files changed, 72 insertions, 58 deletions
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 17bb41cb9f..b2fec55eae 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -3050,7 +3050,7 @@ 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) != -1) && install) { if (!pbr) pbra->install_in_progress = true; else @@ -3081,7 +3081,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) != -1) && install) pbrim->install_in_progress = true; } @@ -3109,7 +3109,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) != -1) && install) pbrime->install_in_progress = true; } @@ -3184,7 +3184,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 != -1) pba->refcnt++; else pbm->install_iptable_in_progress = true; diff --git a/lib/zclient.c b/lib/zclient.c index b27e2cef73..980ecc5ed8 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -277,11 +277,18 @@ 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; } +/* + * -1 is a failure + * 0 means we sent + * 1 means we are buffering + */ int zclient_send_message(struct zclient *zclient) { if (zclient->sock < 0) @@ -296,12 +303,16 @@ int zclient_send_message(struct zclient *zclient) 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; } @@ -406,8 +417,8 @@ int zclient_send_hello(struct zclient *zclient) 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; @@ -419,7 +430,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. */ @@ -570,15 +581,15 @@ 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) +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; @@ -594,7 +605,7 @@ 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, @@ -611,9 +622,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. */ @@ -3281,7 +3290,7 @@ stream_failure: 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; @@ -3292,15 +3301,15 @@ 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) +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; @@ -3311,7 +3320,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) @@ -3339,7 +3348,6 @@ static void zclient_mlag_handle_msg(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; @@ -3363,9 +3371,7 @@ 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); } /* @@ -3377,7 +3383,6 @@ int zclient_send_opaque_unicast(struct zclient *zclient, uint32_t type, uint32_t session_id, const uint8_t *data, size_t datasize) { - int ret; struct stream *s; uint16_t flags = 0; @@ -3407,9 +3412,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); } /* @@ -3444,7 +3447,6 @@ stream_failure: */ int zclient_register_opaque(struct zclient *zclient, uint32_t type) { - int ret; struct stream *s; s = zclient->obuf; @@ -3463,9 +3465,7 @@ 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); } /* @@ -3473,7 +3473,6 @@ int zclient_register_opaque(struct zclient *zclient, uint32_t type) */ int zclient_unregister_opaque(struct zclient *zclient, uint32_t type) { - int ret; struct stream *s; s = zclient->obuf; @@ -3492,9 +3491,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 */ @@ -3949,9 +3946,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) +int zclient_interface_set_master(struct zclient *client, + struct interface *master, + struct interface *slave) { struct stream *s; @@ -3966,7 +3963,7 @@ 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); } /* diff --git a/lib/zclient.h b/lib/zclient.h index d9237048bd..e8629acbee 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -321,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); @@ -754,9 +766,9 @@ 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 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); @@ -764,10 +776,10 @@ 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_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); @@ -792,8 +804,13 @@ 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. */ +/* + * 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 */ @@ -851,9 +868,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 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); @@ -970,12 +987,12 @@ 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 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 |
