]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: refactor zserv names, consolidate events
authorQuentin Young <qlyoung@cumulusnetworks.com>
Mon, 23 Apr 2018 22:35:35 +0000 (18:35 -0400)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Tue, 29 May 2018 19:06:16 +0000 (19:06 +0000)
* Add centralized thread scheduling dispatchers for client threads and
  the main thread

* Rename everything in zserv.c to stop using a combination of:
  - zebra_server_*
  - zebra_*
  - zserv_*

  Everything in zserv.c now begins with zserv_*.

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
13 files changed:
zebra/label_manager.c
zebra/main.c
zebra/table_manager.c
zebra/zapi_msg.c
zebra/zebra_mpls.c
zebra/zebra_mroute.c
zebra/zebra_ptm.c
zebra/zebra_ptm_redistribute.c
zebra/zebra_pw.c
zebra/zebra_rnh.c
zebra/zebra_vxlan.c
zebra/zserv.c
zebra/zserv.h

index f3fa3ba94efd618e9730c46527f8c2f64f14390f..9bfc4001b66aa7a557ec458750194971a7858384 100644 (file)
@@ -350,7 +350,7 @@ void label_manager_init(char *lm_zserv_path)
 
        obuf = stream_new(ZEBRA_MAX_PACKET_SIZ);
 
-       hook_register(zapi_client_close, release_daemon_label_chunks);
+       hook_register(zserv_client_close, release_daemon_label_chunks);
 }
 
 /**
index 9bcbaa3c20bee79fb7a946ac5b6b7dad881a5b1f..c5246999fa47ebe5dcd457f44b724716259e7459 100644 (file)
@@ -379,10 +379,11 @@ int main(int argc, char **argv)
        /* Needed for BSD routing socket. */
        pid = getpid();
 
+       /* Intialize pthread library */
        frr_pthread_init();
 
-       /* This must be done only after locking pidfile (bug #403). */
-       zebra_zserv_socket_init(zserv_path);
+       /* Start Zebra API server */
+       zserv_start(zserv_path);
 
        /* Init label manager */
        label_manager_init(lblmgr_path);
index cb8c384436977bb44228e598f2d5c710f0973ad2..5bcc2c40d6d085a6f5568d89fe565d2ee56f604d 100644 (file)
@@ -78,7 +78,7 @@ void table_manager_enable(ns_id_t ns_id)
                return;
        tbl_mgr.lc_list = list_new();
        tbl_mgr.lc_list->del = delete_table_chunk;
-       hook_register(zapi_client_close, release_daemon_table_chunks);
+       hook_register(zserv_client_close, release_daemon_table_chunks);
 }
 
 /**
index 943329b1962bc0d3b6121d07f36394e94dff0ffd..2c19f31c763f7aad2fb6a9683cdd030e0e30ac7e 100644 (file)
@@ -162,7 +162,7 @@ int zsend_interface_add(struct zserv *client, struct interface *ifp)
        zserv_encode_interface(s, ifp);
 
        client->ifadd_cnt++;
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /* Interface deletion from zebra daemon. */
@@ -174,7 +174,7 @@ int zsend_interface_delete(struct zserv *client, struct interface *ifp)
        zserv_encode_interface(s, ifp);
 
        client->ifdel_cnt++;
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 int zsend_vrf_add(struct zserv *client, struct zebra_vrf *zvrf)
@@ -185,7 +185,7 @@ int zsend_vrf_add(struct zserv *client, struct zebra_vrf *zvrf)
        zserv_encode_vrf(s, zvrf);
 
        client->vrfadd_cnt++;
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /* VRF deletion from zebra daemon. */
@@ -198,7 +198,7 @@ int zsend_vrf_delete(struct zserv *client, struct zebra_vrf *zvrf)
        zserv_encode_vrf(s, zvrf);
 
        client->vrfdel_cnt++;
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 int zsend_interface_link_params(struct zserv *client, struct interface *ifp)
@@ -230,7 +230,7 @@ int zsend_interface_link_params(struct zserv *client, struct interface *ifp)
        /* Write packet size. */
        stream_putw_at(s, 0, stream_get_endp(s));
 
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
@@ -309,7 +309,7 @@ int zsend_interface_address(int cmd, struct zserv *client,
        stream_putw_at(s, 0, stream_get_endp(s));
 
        client->connected_rt_add_cnt++;
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 static int zsend_interface_nbr_address(int cmd, struct zserv *client,
@@ -340,7 +340,7 @@ static int zsend_interface_nbr_address(int cmd, struct zserv *client,
        /* Write packet size. */
        stream_putw_at(s, 0, stream_get_endp(s));
 
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /* Interface address addition. */
@@ -438,7 +438,7 @@ int zsend_interface_vrf_update(struct zserv *client, struct interface *ifp,
        stream_putw_at(s, 0, stream_get_endp(s));
 
        client->if_vrfchg_cnt++;
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /* Add new nbr connected IPv6 address */
@@ -511,7 +511,7 @@ int zsend_interface_update(int cmd, struct zserv *client, struct interface *ifp)
        else
                client->ifdown_cnt++;
 
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p,
@@ -602,7 +602,7 @@ int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p,
                           zebra_route_string(api.type), api.vrf_id,
                           buf_prefix);
        }
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /*
@@ -655,7 +655,7 @@ static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client,
 
        stream_putw_at(s, 0, stream_get_endp(s));
 
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 int zsend_route_notify_owner(struct route_entry *re, struct prefix *p,
@@ -665,7 +665,7 @@ int zsend_route_notify_owner(struct route_entry *re, struct prefix *p,
        struct stream *s;
        uint8_t blen;
 
-       client = zebra_find_client(re->type, re->instance);
+       client = zserv_find_client(re->type, re->instance);
        if (!client || !client->notify_owner) {
                if (IS_ZEBRA_DEBUG_PACKET) {
                        char buff[PREFIX_STRLEN];
@@ -703,7 +703,7 @@ int zsend_route_notify_owner(struct route_entry *re, struct prefix *p,
 
        stream_putw_at(s, 0, stream_get_endp(s));
 
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 void zsend_rule_notify_owner(struct zebra_pbr_rule *rule,
@@ -739,7 +739,7 @@ void zsend_rule_notify_owner(struct zebra_pbr_rule *rule,
 
        stream_putw_at(s, 0, stream_get_endp(s));
 
-       zebra_server_send_message(client, s);
+       zserv_send_message(client, s);
 }
 
 void zsend_ipset_notify_owner(struct zebra_pbr_ipset *ipset,
@@ -769,7 +769,7 @@ void zsend_ipset_notify_owner(struct zebra_pbr_ipset *ipset,
        stream_put(s, ipset->ipset_name, ZEBRA_IPSET_NAME_SIZE);
        stream_putw_at(s, 0, stream_get_endp(s));
 
-       zebra_server_send_message(client, s);
+       zserv_send_message(client, s);
 }
 
 void zsend_ipset_entry_notify_owner(struct zebra_pbr_ipset_entry *ipset,
@@ -799,7 +799,7 @@ void zsend_ipset_entry_notify_owner(struct zebra_pbr_ipset_entry *ipset,
        stream_put(s, ipset->backpointer->ipset_name, ZEBRA_IPSET_NAME_SIZE);
        stream_putw_at(s, 0, stream_get_endp(s));
 
-       zebra_server_send_message(client, s);
+       zserv_send_message(client, s);
 }
 
 void zsend_iptable_notify_owner(struct zebra_pbr_iptable *iptable,
@@ -828,7 +828,7 @@ void zsend_iptable_notify_owner(struct zebra_pbr_iptable *iptable,
        stream_putl(s, iptable->unique);
        stream_putw_at(s, 0, stream_get_endp(s));
 
-       zebra_server_send_message(client, s);
+       zserv_send_message(client, s);
 }
 
 /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
@@ -855,7 +855,7 @@ int zsend_router_id_update(struct zserv *client, struct prefix *p,
        /* Write packet size. */
        stream_putw_at(s, 0, stream_get_endp(s));
 
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /*
@@ -873,7 +873,7 @@ int zsend_pw_update(struct zserv *client, struct zebra_pw *pw)
        /* Put length at the first point of the stream. */
        stream_putw_at(s, 0, stream_get_endp(s));
 
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /* Send response to a get label chunk request to client */
@@ -952,7 +952,7 @@ static int zsend_assign_table_chunk_response(struct zserv *client,
        /* Write packet size. */
        stream_putw_at(s, 0, stream_get_endp(s));
 
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 static int zsend_table_manager_connect_response(struct zserv *client,
@@ -968,7 +968,7 @@ static int zsend_table_manager_connect_response(struct zserv *client,
 
        stream_putw_at(s, 0, stream_get_endp(s));
 
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /* Inbound message handling ------------------------------------------------ */
@@ -2194,7 +2194,7 @@ static void zsend_capabilities(struct zserv *client, struct zebra_vrf *zvrf)
        stream_putl(s, multipath_num);
 
        stream_putw_at(s, 0, stream_get_endp(s));
-       zebra_server_send_message(client, s);
+       zserv_send_message(client, s);
 }
 
 /* Tie up route-type and client->sock */
index 3ad640653f92a972568ebbc69d98707c22b71895..e040808e010acf5816bd963f0e22353425d86f70 100644 (file)
@@ -463,7 +463,7 @@ static int fec_send(zebra_fec_t *fec, struct zserv *client)
        stream_put_prefix(s, &rn->p);
        stream_putl(s, fec->label);
        stream_putw_at(s, 0, stream_get_endp(s));
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /*
@@ -2916,5 +2916,5 @@ void zebra_mpls_init(void)
        if (!mpls_processq_init(&zebrad))
                mpls_enabled = 1;
 
-       hook_register(zapi_client_close, zebra_mpls_cleanup_fecs_for_client);
+       hook_register(zserv_client_close, zebra_mpls_cleanup_fecs_for_client);
 }
index 042bd3769e774c1fcaea995aeb46ddf764bd9325..3af3cd5bb2fc72ef91efd76cc52c76ed34a9cb05 100644 (file)
@@ -67,5 +67,5 @@ stream_failure:
        stream_putl(s, suc);
 
        stream_putw_at(s, 0, stream_get_endp(s));
-       zebra_server_send_message(client, s);
+       zserv_send_message(client, s);
 }
index d20f93f521a8bdf65513b6058aa64c013dea8dbc..8c23bf34cf1670c080003fafe9dc4ece86d73fb9 100644 (file)
@@ -126,7 +126,7 @@ void zebra_ptm_init(void)
 
        ptm_cb.ptm_sock = -1;
 
-       hook_register(zapi_client_close, zebra_ptm_bfd_client_deregister);
+       hook_register(zserv_client_close, zebra_ptm_bfd_client_deregister);
 }
 
 void zebra_ptm_finish(void)
index 74771476987f4b9418a2d6ca0f36bb33eef25804..815f61d157a083b4dd42789ea1e35053d6125aaf 100644 (file)
@@ -66,7 +66,7 @@ static int zsend_interface_bfd_update(int cmd, struct zserv *client,
        stream_putw_at(s, 0, stream_get_endp(s));
 
        client->if_bfd_cnt++;
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 void zebra_interface_bfd_update(struct interface *ifp, struct prefix *dp,
@@ -101,7 +101,7 @@ static int zsend_bfd_peer_replay(int cmd, struct zserv *client)
        stream_putw_at(s, 0, stream_get_endp(s));
 
        client->bfd_peer_replay_cnt++;
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 void zebra_bfd_peer_replay_req(void)
index 28e09fe1934470826c2898bf76c2c5df4bb5cb08..bf76f7e86b7d32758764e8110fc17e2e230f79ad 100644 (file)
@@ -292,7 +292,7 @@ void zebra_pw_init(struct zebra_vrf *zvrf)
        RB_INIT(zebra_pw_head, &zvrf->pseudowires);
        RB_INIT(zebra_static_pw_head, &zvrf->static_pseudowires);
 
-       hook_register(zapi_client_close, zebra_pw_client_close);
+       hook_register(zserv_client_close, zebra_pw_client_close);
 }
 
 void zebra_pw_exit(struct zebra_vrf *zvrf)
index 90c39bcc6f01e319f79da7b6121f8fdcf043587a..d482e0ab3da3ec1d796c304e3eaddf9eb031022d 100644 (file)
@@ -73,7 +73,7 @@ int zebra_rnh_ipv6_default_route = 0;
 
 void zebra_rnh_init(void)
 {
-       hook_register(zapi_client_close, zebra_client_cleanup_rnh);
+       hook_register(zserv_client_close, zebra_client_cleanup_rnh);
 }
 
 static inline struct route_table *get_rnh_table(vrf_id_t vrfid, int family,
@@ -1106,7 +1106,7 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
 
        client->nh_last_upd_time = monotime(NULL);
        client->last_write_cmd = cmd;
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 static void print_nh(struct nexthop *nexthop, struct vty *vty)
index 90604215e75dcd9899edba2a44f11efdcb0d1fd6..c6adc89e55e723b24bd782a63c61d49aade2228d 100644 (file)
@@ -1195,7 +1195,7 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
        struct zserv *client = NULL;
        struct stream *s = NULL;
 
-       client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
+       client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
        /* BGP may not be running. */
        if (!client)
                return 0;
@@ -1237,7 +1237,7 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
        else
                client->macipdel_cnt++;
 
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /*
@@ -2779,7 +2779,7 @@ static int zvni_send_add_to_client(zebra_vni_t *zvni)
        struct zserv *client;
        struct stream *s;
 
-       client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
+       client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
        /* BGP may not be running. */
        if (!client)
                return 0;
@@ -2801,7 +2801,7 @@ static int zvni_send_add_to_client(zebra_vni_t *zvni)
                           zebra_route_string(client->proto));
 
        client->vniadd_cnt++;
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /*
@@ -2812,7 +2812,7 @@ static int zvni_send_del_to_client(vni_t vni)
        struct zserv *client;
        struct stream *s;
 
-       client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
+       client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
        /* BGP may not be running. */
        if (!client)
                return 0;
@@ -2831,7 +2831,7 @@ static int zvni_send_del_to_client(vni_t vni)
                           zebra_route_string(client->proto));
 
        client->vnidel_cnt++;
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /*
@@ -3745,7 +3745,7 @@ static int zl3vni_send_add_to_client(zebra_l3vni_t *zl3vni)
        struct ethaddr rmac;
        char buf[ETHER_ADDR_STRLEN];
 
-       client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
+       client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
        /* BGP may not be running. */
        if (!client)
                return 0;
@@ -3777,7 +3777,7 @@ static int zl3vni_send_add_to_client(zebra_l3vni_t *zl3vni)
                        zebra_route_string(client->proto));
 
        client->l3vniadd_cnt++;
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /*
@@ -3788,7 +3788,7 @@ static int zl3vni_send_del_to_client(zebra_l3vni_t *zl3vni)
        struct stream *s = NULL;
        struct zserv *client = NULL;
 
-       client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
+       client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
        /* BGP may not be running. */
        if (!client)
                return 0;
@@ -3807,7 +3807,7 @@ static int zl3vni_send_del_to_client(zebra_l3vni_t *zl3vni)
                           zebra_route_string(client->proto));
 
        client->l3vnidel_cnt++;
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni)
@@ -3920,7 +3920,7 @@ static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
        struct stream *s = NULL;
        char buf[PREFIX_STRLEN];
 
-       client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
+       client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
        /* BGP may not be running. */
        if (!client)
                return 0;
@@ -3944,7 +3944,7 @@ static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
        else
                client->prefixdel_cnt++;
 
-       return zebra_server_send_message(client, s);
+       return zserv_send_message(client, s);
 }
 
 /* re-add remote rmac if needed */
index f2a2bdcb89f5c8e60466380ca7a881845d66abb5..9e2c443765cf5435b3c48cd70c9345f1fee7eedf 100644 (file)
@@ -69,14 +69,65 @@ extern struct zebra_privs_t zserv_privs;
  *
  * These are used almost exclusively by client threads to drive their own event
  * loops. The only exception is in zebra_client_create(), which pushes an
- * initial ZEBRA_READ event to start the API handler loop.
+ * initial ZSERV_CLIENT_READ event to start the API handler loop.
  */
-enum event { ZEBRA_READ, ZEBRA_WRITE };
+enum zserv_client_event {
+       /* Schedule a socket read */
+       ZSERV_CLIENT_READ,
+       /* Schedule a buffer write */
+       ZSERV_CLIENT_WRITE,
+       /* Schedule a buffer flush */
+       ZSERV_CLIENT_FLUSH_DATA,
+};
 
-/* Forward declarations for functions used from both threads. */
-static void zebra_event(struct zserv *client, enum event event);
-static int zebra_client_handle_close(struct thread *thread);
-static int zserv_process_messages(struct thread *thread);
+/*
+ * Main thread events.
+ *
+ * These are used by client threads to notify the main thread about various
+ * events and to make processing requests.
+ */
+enum zserv_event {
+       /* Schedule listen job on Zebra API socket */
+       ZSERV_ACCEPT,
+       /* The calling client has packets on its input buffer */
+       ZSERV_PROCESS_MESSAGES,
+       /* The calling client wishes to be killed */
+       ZSERV_HANDLE_CLOSE,
+};
+
+/*
+ * Zebra server event driver for all client threads.
+ *
+ * This is essentially a wrapper around thread_add_event() that centralizes
+ * those scheduling calls into one place.
+ *
+ * All calls to this function schedule an event on the pthread running the
+ * provided client.
+ *
+ * client
+ *    the client in question, and thread target
+ *
+ * event
+ *    the event to notify them about
+ */
+static void zserv_client_event(struct zserv *client,
+                              enum zserv_client_event event);
+
+/*
+ * Zebra server event driver for the main thread.
+ *
+ * This is essentially a wrapper around thread_add_event() that centralizes
+ * those scheduling calls into one place.
+ *
+ * All calls to this function schedule an event on Zebra's main pthread.
+ *
+ * client
+ *    the client in question
+ *
+ * event
+ *    the event to notify the main thread about
+ */
+static void zserv_event(struct zserv *client, enum zserv_event event);
 
 
 /* Client thread lifecycle -------------------------------------------------- */
@@ -107,7 +158,6 @@ static void zserv_log_message(const char *errmsg, struct stream *msg,
        zlog_hexdump(msg->data, STREAM_READABLE(msg));
 }
 
-
 /*
  * Gracefully shut down a client connection.
  *
@@ -116,12 +166,11 @@ static void zserv_log_message(const char *errmsg, struct stream *msg,
  *
  * Must be called from the client pthread, never the main thread.
  */
-static void zebra_client_close(struct zserv *client)
+static void zserv_client_close(struct zserv *client)
 {
        THREAD_OFF(client->t_read);
        THREAD_OFF(client->t_write);
-       thread_add_event(zebrad.master, zebra_client_handle_close, client, 0,
-                        NULL);
+       zserv_event(client, ZSERV_HANDLE_CLOSE);
 }
 
 static int zserv_flush_data(struct thread *thread)
@@ -134,13 +183,11 @@ static int zserv_flush_data(struct thread *thread)
                zlog_warn(
                        "%s: buffer_flush_available failed on zserv client fd %d, closing",
                        __func__, client->sock);
-               zebra_client_close(client);
+               zserv_client_close(client);
                client = NULL;
                break;
        case BUFFER_PENDING:
-               client->t_write = NULL;
-               thread_add_write(client->pthread->master, zserv_flush_data, client,
-                                client->sock, &client->t_write);
+               zserv_client_event(client, ZSERV_CLIENT_FLUSH_DATA);
                break;
        case BUFFER_EMPTY:
                break;
@@ -188,11 +235,10 @@ static int zserv_write(struct thread *thread)
                          client->sock);
                zlog_warn("%s: closing connection to %s", __func__,
                          zebra_route_string(client->proto));
-               zebra_client_close(client);
+               zserv_client_close(client);
                return -1;
        case BUFFER_PENDING:
-               thread_add_write(client->pthread->master, zserv_flush_data,
-                                client, client->sock, &client->t_write);
+               zserv_client_event(client, ZSERV_CLIENT_FLUSH_DATA);
                break;
        case BUFFER_EMPTY:
                break;
@@ -201,7 +247,7 @@ static int zserv_write(struct thread *thread)
        pthread_mutex_lock(&client->obuf_mtx);
        {
                if (client->obuf_fifo->count)
-                       zebra_event(client, ZEBRA_WRITE);
+                       zserv_client_event(client, ZSERV_CLIENT_WRITE);
        }
        pthread_mutex_unlock(&client->obuf_mtx);
 
@@ -231,7 +277,6 @@ static void zserv_write_incoming(struct stream *orig, uint16_t command)
 }
 #endif
 
-
 /*
  * Read and process data from a client socket.
  *
@@ -381,36 +426,39 @@ static int zserv_read(struct thread *thread)
                           zebrad.packets_to_process - p2p);
 
        /* Schedule job to process those packets */
-       thread_add_event(zebrad.master, zserv_process_messages, client, 0,
-                        NULL);
+       zserv_event(client, ZSERV_PROCESS_MESSAGES);
 
        /* Reschedule ourselves */
-       zebra_event(client, ZEBRA_READ);
+       zserv_client_event(client, ZSERV_CLIENT_READ);
 
        return 0;
 
 zread_fail:
-       zebra_client_close(client);
+       zserv_client_close(client);
        return -1;
 }
 
-static void zebra_event(struct zserv *client, enum event event)
+static void zserv_client_event(struct zserv *client,
+                              enum zserv_client_event event)
 {
        switch (event) {
-       case ZEBRA_READ:
+       case ZSERV_CLIENT_READ:
                thread_add_read(client->pthread->master, zserv_read, client,
                                client->sock, &client->t_read);
                break;
-       case ZEBRA_WRITE:
+       case ZSERV_CLIENT_WRITE:
                thread_add_write(client->pthread->master, zserv_write, client,
                                 client->sock, &client->t_write);
                break;
+       case ZSERV_CLIENT_FLUSH_DATA:
+               thread_add_write(client->pthread->master, zserv_flush_data,
+                                client, client->sock, &client->t_write);
+               break;
        }
 }
 
 /* Main thread lifecycle ---------------------------------------------------- */
 
-
 /*
  * Read and process messages from a client.
  *
@@ -472,20 +520,19 @@ static int zserv_process_messages(struct thread *thread)
        pthread_mutex_lock(&client->ibuf_mtx);
        {
                if (client->ibuf_fifo->count)
-                       thread_add_event(zebrad.master, zserv_process_messages,
-                                        client, 0, NULL);
+                       zserv_event(client, ZSERV_PROCESS_MESSAGES);
        }
        pthread_mutex_unlock(&client->ibuf_mtx);
 
        return 0;
 }
 
-int zebra_server_send_message(struct zserv *client, struct stream *msg)
+int zserv_send_message(struct zserv *client, struct stream *msg)
 {
        pthread_mutex_lock(&client->obuf_mtx);
        {
                stream_fifo_push(client->obuf_fifo, msg);
-               zebra_event(client, ZEBRA_WRITE);
+               zserv_client_event(client, ZSERV_CLIENT_WRITE);
        }
        pthread_mutex_unlock(&client->obuf_mtx);
        return 0;
@@ -493,8 +540,8 @@ int zebra_server_send_message(struct zserv *client, struct stream *msg)
 
 
 /* Hooks for client connect / disconnect */
-DEFINE_HOOK(zapi_client_connect, (struct zserv *client), (client));
-DEFINE_KOOH(zapi_client_close, (struct zserv *client), (client));
+DEFINE_HOOK(zserv_client_connect, (struct zserv *client), (client));
+DEFINE_KOOH(zserv_client_close, (struct zserv *client), (client));
 
 /*
  * Deinitialize zebra client.
@@ -508,9 +555,9 @@ DEFINE_KOOH(zapi_client_close, (struct zserv *client), (client));
  * managed by the owning pthread and any tasks associated with them must have
  * been stopped prior to invoking this function.
  */
-static void zebra_client_free(struct zserv *client)
+static void zserv_client_free(struct zserv *client)
 {
-       hook_call(zapi_client_close, client);
+       hook_call(zserv_client_close, client);
 
        /* Close file descriptor. */
        if (client->sock) {
@@ -562,7 +609,7 @@ static void zebra_client_free(struct zserv *client)
  * terminate the client thread, update relevant internal datastructures and
  * free any resources allocated by the main thread.
  */
-static int zebra_client_handle_close(struct thread *thread)
+static int zserv_handle_client_close(struct thread *thread)
 {
        struct zserv *client = THREAD_ARG(thread);
 
@@ -582,7 +629,7 @@ static int zebra_client_handle_close(struct thread *thread)
        client->pthread = NULL;
 
        listnode_delete(zebrad.client_list, client);
-       zebra_client_free(client);
+       zserv_client_free(client);
        return 0;
 }
 
@@ -596,7 +643,7 @@ static int zebra_client_handle_close(struct thread *thread)
  * sock
  *    client's socket file descriptor
  */
-static void zebra_client_create(int sock)
+static void zserv_client_create(int sock)
 {
        struct zserv *client;
        int i;
@@ -645,17 +692,19 @@ static void zebra_client_create(int sock)
        zebra_vrf_update_all(client);
 
        /* start read loop */
-       zebra_event(client, ZEBRA_READ);
+       zserv_client_event(client, ZSERV_CLIENT_READ);
 
        /* call callbacks */
-       hook_call(zapi_client_connect, client);
+       hook_call(zserv_client_connect, client);
 
        /* start pthread */
        frr_pthread_run(client->pthread, NULL);
 }
 
-/* Accept code of zebra server socket. */
-static int zebra_accept(struct thread *thread)
+/*
+ * Accept socket connection.
+ */
+static int zserv_accept(struct thread *thread)
 {
        int accept_sock;
        int client_sock;
@@ -665,7 +714,7 @@ static int zebra_accept(struct thread *thread)
        accept_sock = THREAD_FD(thread);
 
        /* Reregister myself. */
-       thread_add_read(zebrad.master, zebra_accept, NULL, accept_sock, NULL);
+       zserv_event(NULL, ZSERV_ACCEPT);
 
        len = sizeof(struct sockaddr_in);
        client_sock = accept(accept_sock, (struct sockaddr *)&client, &len);
@@ -680,16 +729,14 @@ static int zebra_accept(struct thread *thread)
        set_nonblocking(client_sock);
 
        /* Create new zebra client. */
-       zebra_client_create(client_sock);
+       zserv_client_create(client_sock);
 
        return 0;
 }
 
-/* Make zebra server socket, wiping any existing one (see bug #403). */
-void zebra_zserv_socket_init(char *path)
+void zserv_start(char *path)
 {
        int ret;
-       int sock;
        mode_t old_mask;
        struct sockaddr_storage sa;
        socklen_t sa_len;
@@ -702,8 +749,8 @@ void zebra_zserv_socket_init(char *path)
        old_mask = umask(0077);
 
        /* Make UNIX domain socket. */
-       sock = socket(sa.ss_family, SOCK_STREAM, 0);
-       if (sock < 0) {
+       zebrad.sock = socket(sa.ss_family, SOCK_STREAM, 0);
+       if (zebrad.sock < 0) {
                zlog_warn("Can't create zserv socket: %s",
                          safe_strerror(errno));
                zlog_warn(
@@ -712,8 +759,8 @@ void zebra_zserv_socket_init(char *path)
        }
 
        if (sa.ss_family != AF_UNIX) {
-               sockopt_reuseaddr(sock);
-               sockopt_reuseport(sock);
+               sockopt_reuseaddr(zebrad.sock);
+               sockopt_reuseport(zebrad.sock);
        } else {
                struct sockaddr_un *suna = (struct sockaddr_un *)&sa;
                if (suna->sun_path[0])
@@ -721,40 +768,60 @@ void zebra_zserv_socket_init(char *path)
        }
 
        zserv_privs.change(ZPRIVS_RAISE);
-       setsockopt_so_recvbuf(sock, 1048576);
-       setsockopt_so_sendbuf(sock, 1048576);
+       setsockopt_so_recvbuf(zebrad.sock, 1048576);
+       setsockopt_so_sendbuf(zebrad.sock, 1048576);
        zserv_privs.change(ZPRIVS_LOWER);
 
        if (sa.ss_family != AF_UNIX && zserv_privs.change(ZPRIVS_RAISE))
                zlog_err("Can't raise privileges");
 
-       ret = bind(sock, (struct sockaddr *)&sa, sa_len);
+       ret = bind(zebrad.sock, (struct sockaddr *)&sa, sa_len);
        if (ret < 0) {
                zlog_warn("Can't bind zserv socket on %s: %s", path,
                          safe_strerror(errno));
                zlog_warn(
                        "zebra can't provide full functionality due to above error");
-               close(sock);
+               close(zebrad.sock);
+               zebrad.sock = -1;
                return;
        }
        if (sa.ss_family != AF_UNIX && zserv_privs.change(ZPRIVS_LOWER))
                zlog_err("Can't lower privileges");
 
-       ret = listen(sock, 5);
+       ret = listen(zebrad.sock, 5);
        if (ret < 0) {
                zlog_warn("Can't listen to zserv socket %s: %s", path,
                          safe_strerror(errno));
                zlog_warn(
                        "zebra can't provide full functionality due to above error");
-               close(sock);
+               close(zebrad.sock);
+               zebrad.sock = -1;
                return;
        }
 
        umask(old_mask);
 
-       thread_add_read(zebrad.master, zebra_accept, NULL, sock, NULL);
+       zserv_event(NULL, ZSERV_ACCEPT);
 }
 
+void zserv_event(struct zserv *client, enum zserv_event event)
+{
+       switch (event) {
+       case ZSERV_ACCEPT:
+               thread_add_read(zebrad.master, zserv_accept, NULL, zebrad.sock,
+                               NULL);
+               break;
+       case ZSERV_PROCESS_MESSAGES:
+               thread_add_event(zebrad.master, zserv_process_messages, client,
+                                0, NULL);
+               break;
+       case ZSERV_HANDLE_CLOSE:
+               thread_add_event(zebrad.master, zserv_handle_client_close,
+                                client, 0, NULL);
+       }
+}
+
+
 /* General purpose ---------------------------------------------------------- */
 
 #define ZEBRA_TIME_BUF 32
@@ -895,7 +962,7 @@ static void zebra_show_client_brief(struct vty *vty, struct zserv *client)
                client->v6_route_del_cnt);
 }
 
-struct zserv *zebra_find_client(uint8_t proto, unsigned short instance)
+struct zserv *zserv_find_client(uint8_t proto, unsigned short instance)
 {
        struct listnode *node, *nnode;
        struct zserv *client;
@@ -973,7 +1040,10 @@ void zserv_init(void)
 {
        /* Client list init. */
        zebrad.client_list = list_new();
-       zebrad.client_list->del = (void (*)(void *))zebra_client_free;
+       zebrad.client_list->del = (void (*)(void *)) zserv_client_free;
+
+       /* Misc init. */
+       zebrad.sock = -1;
 
        install_element(ENABLE_NODE, &show_zebra_client_cmd);
        install_element(ENABLE_NODE, &show_zebra_client_summary_cmd);
index 77c5d9a89b37d47a1a90eabbde9e92cbbc9dc0cc..6cd8b8c2921b9101164733b2db19dc14b31aa0cc 100644 (file)
@@ -160,8 +160,8 @@ struct zserv {
                struct zebra_vrf *zvrf
 
 /* Hooks for client connect / disconnect */
-DECLARE_HOOK(zapi_client_connect, (struct zserv *client), (client));
-DECLARE_KOOH(zapi_client_close, (struct zserv *client), (client));
+DECLARE_HOOK(zserv_client_connect, (struct zserv *client), (client));
+DECLARE_KOOH(zserv_client_close, (struct zserv *client), (client));
 
 /* Zebra instance */
 struct zebra_t {
@@ -169,6 +169,9 @@ struct zebra_t {
        struct thread_master *master;
        struct list *client_list;
 
+       /* Socket */
+       int sock;
+
        /* default table */
        uint32_t rtm_table_default;
 
@@ -186,12 +189,48 @@ struct zebra_t {
 extern struct zebra_t zebrad;
 extern unsigned int multipath_num;
 
-/* Prototypes. */
+/*
+ * Initialize Zebra API server.
+ *
+ * Installs CLI commands and creates the client list.
+ */
 extern void zserv_init(void);
-extern void zebra_zserv_socket_init(char *path);
-extern int zebra_server_send_message(struct zserv *client, struct stream *msg);
 
-extern struct zserv *zebra_find_client(uint8_t proto, unsigned short instance);
+/*
+ * Start Zebra API server.
+ *
+ * Allocates resources, creates the server socket and begins listening on the
+ * socket.
+ *
+ * path
+ *    where to place the Unix domain socket
+ */
+extern void zserv_start(char *path);
+
+/*
+ * Send a message to a connected Zebra API client.
+ *
+ * client
+ *    the client to send to
+ *
+ * msg
+ *    the message to send
+ */
+extern int zserv_send_message(struct zserv *client, struct stream *msg);
+
+/*
+ * Retrieve a client by its protocol and instance number.
+ *
+ * proto
+ *    protocol number
+ *
+ * instance
+ *    instance number
+ *
+ * Returns:
+ *    The Zebra API client.
+ */
+extern struct zserv *zserv_find_client(uint8_t proto, unsigned short instance);
 
 #if defined(HANDLE_ZAPI_FUZZING)
 extern void zserv_read_file(char *input);