2005-04-11 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
Implement non-blocking zclient I/O with buffering.
* zclient.h (struct zclient): Add two fields to support non-blocking
I/O: struct buffer *wb, and struct thread *t_write.
(zclient_free): Remove function.
(zebra_redistribute_send): Change 2nd arg from socket fd to
struct zclient * (needed to support non-blocking I/O and buffering).
(zclient_send_message): New function to send an arbitrary
message with non-blocking I/O.
* zclient.c (zclient_new): Create write buffer.
(zclient_free): Remove unused function.
(zclient_stop): Must cancel new t_write thread. Also, reset
all buffers: ibuf, obuf, and wb.
(zclient_failed): New helper function for typical error handling.
(zclient_flush_data): New thread to flush queued data.
(zclient_send_message): New function to send the message in
zclient->obuf to zebra using non-blocking I/O and buffering.
(zebra_message_send, zapi_ipv4_route, zapi_ipv6_route): Use
new zclient_send_message function instead of calling writen.
(zclient_start): Set socket non-blocking. Also, change 2nd arg
to zebra_redistribute_send from zclient->sock to zclient.
(zebra_redistribute_send): Change 2nd arg to struct zclient *.
Can now use zclient->obuf to assemble the message instead of
allocating a temporary stream. And call zclient_send_message to
send the message instead of writen.
(zclient_read): Convert to support non-blocking I/O by using
stream_read_try instead of deprecated stream_read.
(zclient_redistribute): Change 2nd arg to zebra_redistribute_send
from zclient->sock to zclient.
* ospf6_zebra.c (ospf6_zebra_redistribute, ospf6_zebra_no_redistribute):
Change 2nd arg to zebra_redistribute_send from zclient->sock
to zclient.
* ospf_zebra.c (ospf_zebra_add): Call zclient_send_message instead
of writen.
* rip_zebra.c (rip_redistribute_set, rip_redistribute_unset,
rip_redistribute_clean): Change 2nd arg to zebra_redistribute_send
from zclient->sock to zclient.
* ripng_zebra.c (ripng_redistribute_unset, ripng_redistribute_clean):
Change 2nd arg to zebra_redistribute_send from zclient->sock
to zclient.
* bgp_zebra.c (bgp_redistribute_set, bgp_redistribute_unset):
The 2nd arg to zebra_redistribute_send is now zclient instead of
zclient->sock.
* isis_zebra.h (isis_zebra_finish): Remove declaration of unused
function.
* isis_zebra.c (isis_zebra_route_add_ipv4): Call zclient_send_message
to send the message to zebra instead of calling writen directly, since
zclient_send_message understands non-blocking I/O and will manage
the buffer queue appropriately.
(isis_zebra_finish): Remove unused function, particularly since
the zclient_free function has been removed.
diff --git a/lib/zclient.h b/lib/zclient.h
index d18cf62..aa9f75c 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -50,10 +50,16 @@
/* Output buffer for zebra message. */
struct stream *obuf;
+ /* Buffer of data waiting to be written to zebra. */
+ struct buffer *wb;
+
/* Read and connect thread. */
struct thread *t_read;
struct thread *t_connect;
+ /* Thread to write buffered data to zebra. */
+ struct thread *t_write;
+
/* Redistribute information. */
u_char redist_default;
u_char redist[ZEBRA_ROUTE_MAX];
@@ -103,19 +109,29 @@
/* Prototypes of zebra client service functions. */
struct zclient *zclient_new (void);
-void zclient_free (struct zclient *);
void zclient_init (struct zclient *, int);
int zclient_start (struct zclient *);
void zclient_stop (struct zclient *);
void zclient_reset (struct zclient *);
-int zclient_socket ();
+
+/* Get TCP socket connection to zebra daemon at loopback address. */
+int zclient_socket (void);
+
+/* Get unix stream socket connection to zebra daemon at given path. */
int zclient_socket_un (const char *);
-void zclient_redistribute (int, struct zclient *, int);
-void zclient_redistribute_default (int, struct zclient *);
+/* Send redistribute command to zebra daemon. Do not update zclient state. */
+int zebra_redistribute_send (int command, struct zclient *, int type);
-/* struct zebra *zebra_new (); */
-int zebra_redistribute_send (int, int, int);
+/* If state has changed, update state and call zebra_redistribute_send. */
+void zclient_redistribute (int command, struct zclient *, int type);
+
+/* If state has changed, update state and send the command to zebra. */
+void zclient_redistribute_default (int command, struct zclient *);
+
+/* 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 *);
struct interface *zebra_interface_add_read (struct stream *);
struct interface *zebra_interface_state_read (struct stream *s);