]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: standardize ZAPI message handler args
authorQuentin Young <qlyoung@cumulusnetworks.com>
Tue, 6 Mar 2018 22:57:33 +0000 (17:57 -0500)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Mon, 12 Mar 2018 18:57:05 +0000 (14:57 -0400)
A lot of the handler functions that are called directly from the ZAPI
input processing code take different argument sets where they don't need
to. These functions are called from only one place and all have the same
fundamental information available to them to do their work. There is no
need to specialize what information is passed to them; it is cleaner and
easier to understand when they all accept the same base set of
information and extract what they need inline.

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
12 files changed:
zebra/redistribute.c
zebra/redistribute.h
zebra/rtadv.c
zebra/rtadv.h
zebra/zebra_mroute.c
zebra/zebra_mroute.h
zebra/zebra_ptm.c
zebra/zebra_ptm.h
zebra/zebra_vxlan.c
zebra/zebra_vxlan.h
zebra/zserv.c
zebra/zserv.h

index a7b2361ac68dfd636510bbbf8d8b14189072d5cb..93862cadc90a47203400432288f8589d43676255 100644 (file)
@@ -243,8 +243,7 @@ void redistribute_delete(struct prefix *p, struct prefix *src_p,
        }
 }
 
-void zebra_redistribute_add(int command, struct zserv *client, int length,
-                           struct zebra_vrf *zvrf)
+void zebra_redistribute_add(ZAPI_HANDLER_ARGS)
 {
        afi_t afi = 0;
        int type = 0;
@@ -287,8 +286,7 @@ stream_failure:
        return;
 }
 
-void zebra_redistribute_delete(int command, struct zserv *client, int length,
-                              struct zebra_vrf *zvrf)
+void zebra_redistribute_delete(ZAPI_HANDLER_ARGS)
 {
        afi_t afi = 0;
        int type = 0;
@@ -325,15 +323,13 @@ stream_failure:
        return;
 }
 
-void zebra_redistribute_default_add(int command, struct zserv *client,
-                                   int length, struct zebra_vrf *zvrf)
+void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS)
 {
        vrf_bitmap_set(client->redist_default, zvrf_id(zvrf));
        zebra_redistribute_default(client, zvrf_id(zvrf));
 }
 
-void zebra_redistribute_default_delete(int command, struct zserv *client,
-                                      int length, struct zebra_vrf *zvrf)
+void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS)
 {
        vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf));
 }
index 5edb06c3da7d4e2c5f4d4dbb0d203ed99c3efa7a..6ca3b57d4dce2f3d81e304fe7a755f7da546a482 100644 (file)
 #include "vty.h"
 #include "vrf.h"
 
-extern void zebra_redistribute_add(int, struct zserv *, int,
-                                  struct zebra_vrf *zvrf);
-extern void zebra_redistribute_delete(int, struct zserv *, int,
-                                     struct zebra_vrf *zvrf);
-
-extern void zebra_redistribute_default_add(int, struct zserv *, int,
-                                          struct zebra_vrf *zvrf);
-extern void zebra_redistribute_default_delete(int, struct zserv *, int,
-                                             struct zebra_vrf *zvrf);
+/* zapi handlers */
+extern void zebra_redistribute_add(ZAPI_HANDLER_ARGS);
+extern void zebra_redistribute_delete(ZAPI_HANDLER_ARGS);
+extern void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS);
+extern void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS);
 
 extern void redistribute_update(struct prefix *, struct prefix *,
                                struct route_entry *, struct route_entry *);
index 5eebca163b5c1a275c563b0982570da06f3f65cc..56decdcdbabefd52077c5e7329a5606c7be61955 100644 (file)
@@ -43,6 +43,7 @@
 #include "zebra/zserv.h"
 #include "zebra/zebra_ns.h"
 #include "zebra/zebra_vrf.h"
+#include "zebra/zserv.h"
 
 extern struct zebra_privs_t zserv_privs;
 
@@ -801,8 +802,7 @@ static void ipv6_nd_suppress_ra_set(struct interface *ifp,
  * if the operator has explicitly enabled RA. The enable request can also
  * specify a RA interval (in seconds).
  */
-void zebra_interface_radv_set(struct zserv *client, u_short length,
-                             struct zebra_vrf *zvrf, int enable)
+void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int set)
 {
        struct stream *s;
        ifindex_t ifindex;
@@ -818,27 +818,26 @@ void zebra_interface_radv_set(struct zserv *client, u_short length,
 
        if (IS_ZEBRA_DEBUG_EVENT)
                zlog_debug("%u: IF %u RA %s from client %s, interval %ds",
-                          zvrf_id(zvrf), ifindex,
-                          enable ? "enable" : "disable",
+                          zvrf_id(zvrf), ifindex, set ? "enable" : "disable",
                           zebra_route_string(client->proto), ra_interval);
 
        /* Locate interface and check VRF match. */
        ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), ifindex);
        if (!ifp) {
                zlog_warn("%u: IF %u RA %s client %s - interface unknown",
-                         zvrf_id(zvrf), ifindex, enable ? "enable" : "disable",
+                         zvrf_id(zvrf), ifindex, set ? "enable" : "disable",
                          zebra_route_string(client->proto));
                return;
        }
        if (ifp->vrf_id != zvrf_id(zvrf)) {
                zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u",
-                         zvrf_id(zvrf), ifindex, enable ? "enable" : "disable",
+                         zvrf_id(zvrf), ifindex, set ? "enable" : "disable",
                          zebra_route_string(client->proto), ifp->vrf_id);
                return;
        }
 
        zif = ifp->info;
-       if (enable) {
+       if (set) {
                SET_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED);
                ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
                if (ra_interval
@@ -859,6 +858,16 @@ stream_failure:
        return;
 }
 
+void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS)
+{
+       zebra_interface_radv_set(client, hdr, zvrf, 0);
+}
+
+void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS)
+{
+       zebra_interface_radv_set(client, hdr, zvrf, 1);
+}
+
 DEFUN (ipv6_nd_suppress_ra,
        ipv6_nd_suppress_ra_cmd,
        "ipv6 nd suppress-ra",
index 2cae6d06f9bb1dfaef79ae4d3edabd7bfba1f3a5..28019a32378a4bff214f04b213b548c811b84e5d 100644 (file)
@@ -103,7 +103,8 @@ typedef enum {
 extern void rtadv_init(struct zebra_ns *);
 extern void rtadv_terminate(struct zebra_ns *);
 extern void rtadv_cmd_init(void);
-extern void zebra_interface_radv_set(struct zserv *client, u_short length,
-                                    struct zebra_vrf *zvrf, int enable);
+extern void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int enable);
+extern void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS);
+extern void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS);
 
 #endif /* _ZEBRA_RTADV_H */
index 1143451d620d7178a1160078f41cfeceb87f281c..e70b963cfd1b72ff72a4446c8d19af339b4f0cca 100644 (file)
@@ -31,9 +31,9 @@
 #include "zebra/zebra_mroute.h"
 #include "zebra/rt.h"
 #include "zebra/debug.h"
+#include "zebra/zserv.h"
 
-void zebra_ipmr_route_stats(struct zserv *client, u_short length,
-                           struct zebra_vrf *zvrf)
+void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS)
 {
        struct mcast_route_data mroute;
        struct stream *s;
index 5bee7b03d62db7f3a3640db246ee6aa579ebd651..33851536005faa3dc64b013ae5dc48840c8b985d 100644 (file)
 #ifndef __ZEBRA_MROUTE_H__
 #define __ZEBRA_MROUTE_H__
 
+#include "zebra/zserv.h"
+
 struct mcast_route_data {
        struct prefix_sg sg;
        unsigned int ifindex;
        unsigned long long lastused;
 };
 
-void zebra_ipmr_route_stats(struct zserv *client, u_short length,
-                           struct zebra_vrf *zvf);
+void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS);
 
 #endif
index b0295d127e0cdde77ebe8af8631c8698e8aa8750..0c48473aad21d3b42ac816958399449dc8e80c2d 100644 (file)
@@ -661,8 +661,7 @@ int zebra_ptm_sock_read(struct thread *thread)
 }
 
 /* BFD peer/dst register/update */
-void zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
-                               int command, struct zebra_vrf *zvrf)
+void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        struct prefix src_p;
@@ -680,14 +679,14 @@ void zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
        int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF;
        unsigned int pid;
 
-       if (command == ZEBRA_BFD_DEST_UPDATE)
+       if (hdr->command == ZEBRA_BFD_DEST_UPDATE)
                client->bfd_peer_upd8_cnt++;
        else
                client->bfd_peer_add_cnt++;
 
        if (IS_ZEBRA_DEBUG_EVENT)
                zlog_debug("bfd_dst_register msg from client %s: length=%d",
-                          zebra_route_string(client->proto), length);
+                          zebra_route_string(client->proto), hdr->length);
 
        if (ptm_cb.ptm_sock == -1) {
                ptm_cb.t_timer = NULL;
@@ -824,8 +823,7 @@ stream_failure:
 }
 
 /* BFD peer/dst deregister */
-void zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
-                                 struct zebra_vrf *zvrf)
+void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        struct prefix src_p;
@@ -843,7 +841,7 @@ void zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
 
        if (IS_ZEBRA_DEBUG_EVENT)
                zlog_debug("bfd_dst_deregister msg from client %s: length=%d",
-                          zebra_route_string(client->proto), length);
+                          zebra_route_string(client->proto), hdr->length);
 
        if (ptm_cb.ptm_sock == -1) {
                ptm_cb.t_timer = NULL;
@@ -956,7 +954,7 @@ stream_failure:
 }
 
 /* BFD client register */
-void zebra_ptm_bfd_client_register(struct zserv *client, u_short length)
+void zebra_ptm_bfd_client_register(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        unsigned int pid;
@@ -968,7 +966,7 @@ void zebra_ptm_bfd_client_register(struct zserv *client, u_short length)
 
        if (IS_ZEBRA_DEBUG_EVENT)
                zlog_debug("bfd_client_register msg from client %s: length=%d",
-                          zebra_route_string(client->proto), length);
+                          zebra_route_string(client->proto), hdr->length);
 
        s = client->ibuf;
        STREAM_GETL(s, pid);
index 2397d5384594157eac8ee5370b023074ca898eef..22cacd6fc0455908cd789333c01055d121d9de70 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef _ZEBRA_PTM_H
 #define _ZEBRA_PTM_H
 
+#include "zebra/zserv.h"
+
 extern const char ZEBRA_PTM_SOCK_NAME[];
 #define ZEBRA_PTM_MAX_SOCKBUF 3200 /* 25B *128 ports */
 #define ZEBRA_PTM_SEND_MAX_SOCKBUF 512
@@ -62,12 +64,11 @@ int zebra_ptm_connect(struct thread *t);
 void zebra_ptm_write(struct vty *vty);
 int zebra_ptm_get_enable_state(void);
 
-void zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
-                               int command, struct zebra_vrf *zvrf);
-void zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
-                                 struct zebra_vrf *zvrf);
+void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS);
+void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS);
+void zebra_ptm_bfd_client_register(ZAPI_HANDLER_ARGS);
+
 void zebra_ptm_show_status(struct vty *vty, struct interface *ifp);
-void zebra_ptm_bfd_client_register(struct zserv *client, u_short length);
 void zebra_ptm_if_init(struct zebra_if *zebra_ifp);
 void zebra_ptm_if_set_ptm_state(struct interface *ifp,
                                struct zebra_if *zebra_ifp);
index bac589a8417b1af8fe9e2e42d4136d9a65f47629..f22d5160fbb9f0676e2826e6b71fc5f33b312999 100644 (file)
@@ -46,6 +46,7 @@
 #include "zebra/zebra_vxlan.h"
 #include "zebra/zebra_memory.h"
 #include "zebra/zebra_l2.h"
+#include "zebra/zserv.h"
 
 DEFINE_MTYPE_STATIC(ZEBRA, HOST_PREFIX, "host prefix");
 DEFINE_MTYPE_STATIC(ZEBRA, ZVNI, "VNI hash");
@@ -4863,8 +4864,7 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
 /*
  * Handle message from client to delete a remote MACIP for a VNI.
  */
-void zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
-                                 struct zebra_vrf *zvrf)
+void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        vni_t vni;
@@ -4886,7 +4886,7 @@ void zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
 
        s = client->ibuf;
 
-       while (l < length) {
+       while (l < hdr->length) {
                /* Obtain each remote MACIP and process. */
                /* Message contains VNI, followed by MAC followed by IP (if any)
                 * followed by remote VTEP IP.
@@ -5016,8 +5016,7 @@ stream_failure:
  * could be just the add of a MAC address or the add of a neighbor
  * (IP+MAC).
  */
-void zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
-                                 struct zebra_vrf *zvrf)
+void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        vni_t vni;
@@ -5050,7 +5049,7 @@ void zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
 
        s = client->ibuf;
 
-       while (l < length) {
+       while (l < hdr->length) {
                /* Obtain each remote MACIP and process. */
                /* Message contains VNI, followed by MAC followed by IP (if any)
                 * followed by remote VTEP IP.
@@ -5543,8 +5542,7 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
 /*
  * Handle message from client to delete a remote VTEP for a VNI.
  */
-void zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
-                                struct zebra_vrf *zvrf)
+void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        u_short l = 0;
@@ -5570,7 +5568,7 @@ void zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
 
        s = client->ibuf;
 
-       while (l < length) {
+       while (l < hdr->length) {
                /* Obtain each remote VTEP and process. */
                STREAM_GETL(s, vni);
                l += 4;
@@ -5629,8 +5627,7 @@ stream_failure:
 /*
  * Handle message from client to add a remote VTEP for a VNI.
  */
-void zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
-                                struct zebra_vrf *zvrf)
+void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        u_short l = 0;
@@ -5655,7 +5652,7 @@ void zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
 
        s = client->ibuf;
 
-       while (l < length) {
+       while (l < hdr->length) {
                /* Obtain each remote VTEP and process. */
                STREAM_GETL(s, vni);
                l += 4;
@@ -6512,8 +6509,7 @@ int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf)
  * Handle message from client to enable/disable advertisement of g/w macip
  * routes
  */
-void zebra_vxlan_advertise_subnet(struct zserv *client, u_short length,
-                                 struct zebra_vrf *zvrf)
+void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        int advertise;
@@ -6578,8 +6574,7 @@ void zebra_vxlan_advertise_subnet(struct zserv *client, u_short length,
  * Handle message from client to enable/disable advertisement of g/w macip
  * routes
  */
-void zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
-                                   struct zebra_vrf *zvrf)
+void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        int advertise;
@@ -6686,8 +6681,8 @@ stream_failure:
  * when disabled, the entries should be deleted and remote VTEPs and MACs
  * uninstalled from the kernel.
  */
-void zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length,
-                                  struct zebra_vrf *zvrf)
+void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
+
 {
        struct stream *s = NULL;
        int advertise = 0;
index af76a41d80d64b3d0b82ac43974fd472c00e815e..62c6519d50b259479296e60215fcea85d97bad55 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "lib/json.h"
 #include "zebra/zebra_vrf.h"
+#include "zebra/zserv.h"
 
 /* Is EVPN enabled? */
 #define EVPN_ENABLED(zvrf)  (zvrf)->advertise_all_vni
@@ -52,20 +53,14 @@ static inline int is_evpn_enabled()
 #define VNI_STR_LEN 32
 
 /* zserv handlers */
-extern void zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
-                                        struct zebra_vrf *zvrf);
-extern void zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
-                                        struct zebra_vrf *zvrf);
-extern void zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
-                                       struct zebra_vrf *zvrf);
-extern void zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
-                                       struct zebra_vrf *zvrf);
-extern void zebra_vxlan_advertise_subnet(struct zserv *client, u_short length,
-                                        struct zebra_vrf *zvrf);
-extern void zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
-                                          struct zebra_vrf *zvrf);
-extern void zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length,
-                                         struct zebra_vrf *zvrf);
+extern void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS);
+extern void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS);
+extern void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS);
+extern void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS);
+extern void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS);
+extern void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS);
+extern void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS);
+
 
 extern int is_l3vni_for_prefix_routes_only(vni_t vni);
 extern ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id);
index 3ecc82be4252cc7a746634b68ce199115aeb9ead..127913a63a63cd27978d805e192c1ce75f64ac31 100644 (file)
@@ -692,27 +692,34 @@ static int zsend_write_nexthop(struct stream *s, struct nexthop *nexthop)
        return 1;
 }
 
+int cmd2type[] = {
+       [ZEBRA_NEXTHOP_REGISTER] = RNH_NEXTHOP_TYPE,
+       [ZEBRA_NEXTHOP_UNREGISTER] = RNH_NEXTHOP_TYPE,
+       [ZEBRA_IMPORT_ROUTE_REGISTER] = RNH_IMPORT_CHECK_TYPE,
+       [ZEBRA_IMPORT_ROUTE_UNREGISTER] = RNH_IMPORT_CHECK_TYPE,
+};
+
 /* Nexthop register */
-static void zserv_rnh_register(struct zserv *client, u_short length,
-                              rnh_type_t type, struct zebra_vrf *zvrf)
+static void zserv_rnh_register(ZAPI_HANDLER_ARGS)
 {
        struct rnh *rnh;
        struct stream *s;
        struct prefix p;
        u_short l = 0;
        u_char flags = 0;
+       uint16_t type = cmd2type[hdr->command];
 
        if (IS_ZEBRA_DEBUG_NHT)
                zlog_debug(
                        "rnh_register msg from client %s: length=%d, type=%s\n",
-                       zebra_route_string(client->proto), length,
+                       zebra_route_string(client->proto), hdr->length,
                        (type == RNH_NEXTHOP_TYPE) ? "nexthop" : "route");
 
        s = client->ibuf;
 
        client->nh_reg_time = monotime(NULL);
 
-       while (l < length) {
+       while (l < hdr->length) {
                STREAM_GETC(s, flags);
                STREAM_GETW(s, p.family);
                STREAM_GETC(s, p.prefixlen);
@@ -768,21 +775,21 @@ stream_failure:
 }
 
 /* Nexthop register */
-static void zserv_rnh_unregister(struct zserv *client, u_short length,
-                                rnh_type_t type, struct zebra_vrf *zvrf)
+static void zserv_rnh_unregister(ZAPI_HANDLER_ARGS)
 {
        struct rnh *rnh;
        struct stream *s;
        struct prefix p;
        u_short l = 0;
+       uint16_t type = cmd2type[hdr->command];
 
        if (IS_ZEBRA_DEBUG_NHT)
                zlog_debug("rnh_unregister msg from client %s: length=%d\n",
-                          zebra_route_string(client->proto), length);
+                          zebra_route_string(client->proto), hdr->length);
 
        s = client->ibuf;
 
-       while (l < length) {
+       while (l < hdr->length) {
                uint8_t flags;
 
                STREAM_GETC(s, flags);
@@ -829,10 +836,9 @@ stream_failure:
 #define ZEBRA_MIN_FEC_LENGTH 5
 
 /* FEC register */
-static void zserv_fec_register(struct zserv *client, u_short length)
+static void zserv_fec_register(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
-       struct zebra_vrf *zvrf;
        u_short l = 0;
        struct prefix p;
        u_int16_t flags;
@@ -847,14 +853,14 @@ static void zserv_fec_register(struct zserv *client, u_short length)
         * The minimum amount of data that can be sent for one fec
         * registration
         */
-       if (length < ZEBRA_MIN_FEC_LENGTH) {
+       if (hdr->length < ZEBRA_MIN_FEC_LENGTH) {
                zlog_err(
                        "fec_register: Received a fec register of length %d, it is of insufficient size to properly decode",
-                       length);
+                       hdr->length);
                return;
        }
 
-       while (l < length) {
+       while (l < hdr->length) {
                STREAM_GETW(s, flags);
                memset(&p, 0, sizeof(p));
                STREAM_GETW(s, p.family);
@@ -889,10 +895,9 @@ stream_failure:
 }
 
 /* FEC unregister */
-static void zserv_fec_unregister(struct zserv *client, u_short length)
+static void zserv_fec_unregister(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
-       struct zebra_vrf *zvrf;
        u_short l = 0;
        struct prefix p;
        uint16_t flags;
@@ -906,14 +911,14 @@ static void zserv_fec_unregister(struct zserv *client, u_short length)
         * The minimum amount of data that can be sent for one
         * fec unregistration
         */
-       if (length < ZEBRA_MIN_FEC_LENGTH) {
+       if (hdr->length < ZEBRA_MIN_FEC_LENGTH) {
                zlog_err(
                        "fec_unregister: Received a fec unregister of length %d, it is of insufficient size to properly decode",
-                       length);
+                       hdr->length);
                return;
        }
 
-       while (l < length) {
+       while (l < hdr->length) {
                STREAM_GETW(s, flags);
                if (flags != 0)
                        goto stream_failure;
@@ -1133,8 +1138,8 @@ int zsend_pw_update(struct zserv *client, struct zebra_pw *pw)
 
 /* Register zebra server interface information.  Send current all
    interface and address information. */
-static void zread_interface_add(struct zserv *client, u_short length,
-                               struct zebra_vrf *zvrf)
+static void zread_interface_add(ZAPI_HANDLER_ARGS)
+
 {
        struct vrf *vrf;
        struct interface *ifp;
@@ -1159,8 +1164,7 @@ static void zread_interface_add(struct zserv *client, u_short length,
 }
 
 /* Unregister zebra server interface information. */
-static void zread_interface_delete(struct zserv *client, u_short length,
-                                  struct zebra_vrf *zvrf)
+static void zread_interface_delete(ZAPI_HANDLER_ARGS)
 {
        vrf_bitmap_unset(client->ifinfo, zvrf_id(zvrf));
 }
@@ -1177,8 +1181,7 @@ void zserv_nexthop_num_warn(const char *caller, const struct prefix *p,
        }
 }
 
-static void zread_route_add(struct zserv *client, u_short length,
-                           struct zebra_vrf *zvrf)
+static void zread_route_add(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        struct zapi_route api;
@@ -1332,8 +1335,7 @@ static void zread_route_add(struct zserv *client, u_short length,
        }
 }
 
-static void zread_route_del(struct zserv *client, u_short length,
-                           struct zebra_vrf *zvrf)
+static void zread_route_del(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        struct zapi_route api;
@@ -1375,8 +1377,7 @@ static void zread_route_del(struct zserv *client, u_short length,
  * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update re and
  * add kernel route.
  */
-static void zread_ipv4_add(struct zserv *client, u_short length,
-                          struct zebra_vrf *zvrf)
+static void zread_ipv4_add(ZAPI_HANDLER_ARGS)
 {
        int i;
        struct route_entry *re;
@@ -1530,8 +1531,7 @@ stream_failure:
 }
 
 /* Zebra server IPv4 prefix delete function. */
-static void zread_ipv4_delete(struct zserv *client, u_short length,
-                             struct zebra_vrf *zvrf)
+static void zread_ipv4_delete(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        struct zapi_ipv4 api;
@@ -1569,8 +1569,7 @@ stream_failure:
 }
 
 /* MRIB Nexthop lookup for IPv4. */
-static void zread_ipv4_nexthop_lookup_mrib(struct zserv *client, u_short length,
-                                          struct zebra_vrf *zvrf)
+static void zread_ipv4_nexthop_lookup_mrib(ZAPI_HANDLER_ARGS)
 {
        struct in_addr addr;
        struct route_entry *re;
@@ -1585,9 +1584,7 @@ stream_failure:
 }
 
 /* Zebra server IPv6 prefix add function. */
-static void zread_ipv4_route_ipv6_nexthop_add(struct zserv *client,
-                                             u_short length,
-                                             struct zebra_vrf *zvrf)
+static void zread_ipv4_route_ipv6_nexthop_add(ZAPI_HANDLER_ARGS)
 {
        unsigned int i;
        struct stream *s;
@@ -1760,8 +1757,7 @@ stream_failure:
        return;
 }
 
-static void zread_ipv6_add(struct zserv *client, u_short length,
-                          struct zebra_vrf *zvrf)
+static void zread_ipv6_add(ZAPI_HANDLER_ARGS)
 {
        unsigned int i;
        struct stream *s;
@@ -1956,8 +1952,7 @@ stream_failure:
 }
 
 /* Zebra server IPv6 prefix delete function. */
-static void zread_ipv6_delete(struct zserv *client, u_short length,
-                             struct zebra_vrf *zvrf)
+static void zread_ipv6_delete(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        struct zapi_ipv6 api;
@@ -1999,8 +1994,7 @@ stream_failure:
 }
 
 /* Register zebra server router-id information.  Send current router-id */
-static void zread_router_id_add(struct zserv *client, u_short length,
-                               struct zebra_vrf *zvrf)
+static void zread_router_id_add(ZAPI_HANDLER_ARGS)
 {
        struct prefix p;
 
@@ -2013,14 +2007,13 @@ static void zread_router_id_add(struct zserv *client, u_short length,
 }
 
 /* Unregister zebra server router-id information. */
-static void zread_router_id_delete(struct zserv *client, u_short length,
-                                  struct zebra_vrf *zvrf)
+static void zread_router_id_delete(ZAPI_HANDLER_ARGS)
 {
        vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf));
 }
 
 /* Tie up route-type and client->sock */
-static void zread_hello(struct zserv *client)
+static void zread_hello(ZAPI_HANDLER_ARGS)
 {
        /* type of protocol (lib/zebra.h) */
        u_char proto;
@@ -2050,8 +2043,7 @@ stream_failure:
 }
 
 /* Unregister all information in a VRF. */
-static void zread_vrf_unregister(struct zserv *client, u_short length,
-                                struct zebra_vrf *zvrf)
+static void zread_vrf_unregister(ZAPI_HANDLER_ARGS)
 {
        int i;
        afi_t afi;
@@ -2064,8 +2056,7 @@ static void zread_vrf_unregister(struct zserv *client, u_short length,
        vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf));
 }
 
-static void zread_mpls_labels(int command, struct zserv *client, u_short length,
-                             struct zebra_vrf *zvrf)
+static void zread_mpls_labels(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        enum lsp_types_t type;
@@ -2135,12 +2126,12 @@ static void zread_mpls_labels(int command, struct zserv *client, u_short length,
        if (!mpls_enabled)
                return;
 
-       if (command == ZEBRA_MPLS_LABELS_ADD) {
+       if (hdr->command == ZEBRA_MPLS_LABELS_ADD) {
                mpls_lsp_install(zvrf, type, in_label, out_label, gtype, &gate,
                                 ifindex);
                mpls_ftn_update(1, zvrf, type, &prefix, gtype, &gate, ifindex,
                                distance, out_label);
-       } else if (command == ZEBRA_MPLS_LABELS_DELETE) {
+       } else if (hdr->command == ZEBRA_MPLS_LABELS_DELETE) {
                mpls_lsp_uninstall(zvrf, type, in_label, gtype, &gate, ifindex);
                mpls_ftn_update(0, zvrf, type, &prefix, gtype, &gate, ifindex,
                                distance, out_label);
@@ -2280,19 +2271,19 @@ static void zread_release_label_chunk(struct zserv *client)
 stream_failure:
        return;
 }
-static void zread_label_manager_request(int cmd, struct zserv *client,
-                                       struct zebra_vrf *zvrf)
+static void zread_label_manager_request(ZAPI_HANDLER_ARGS)
 {
        /* to avoid sending other messages like ZERBA_INTERFACE_UP */
-       if (cmd == ZEBRA_LABEL_MANAGER_CONNECT)
+       if (hdr->command == ZEBRA_LABEL_MANAGER_CONNECT)
                client->is_synchronous = 1;
 
        /* external label manager */
        if (lm_is_external)
-               zread_relay_label_manager_request(cmd, client, zvrf_id(zvrf));
+               zread_relay_label_manager_request(hdr->command, client,
+                                                 zvrf_id(zvrf));
        /* this is a label manager */
        else {
-               if (cmd == ZEBRA_LABEL_MANAGER_CONNECT)
+               if (hdr->command == ZEBRA_LABEL_MANAGER_CONNECT)
                        zread_label_manager_connect(client, zvrf_id(zvrf));
                else {
                        /* Sanity: don't allow 'unidentified' requests */
@@ -2301,16 +2292,15 @@ static void zread_label_manager_request(int cmd, struct zserv *client,
                                        "Got label request from an unidentified client");
                                return;
                        }
-                       if (cmd == ZEBRA_GET_LABEL_CHUNK)
+                       if (hdr->command == ZEBRA_GET_LABEL_CHUNK)
                                zread_get_label_chunk(client, zvrf_id(zvrf));
-                       else if (cmd == ZEBRA_RELEASE_LABEL_CHUNK)
+                       else if (hdr->command == ZEBRA_RELEASE_LABEL_CHUNK)
                                zread_release_label_chunk(client);
                }
        }
 }
 
-static void zread_pseudowire(int command, struct zserv *client, u_short length,
-                            struct zebra_vrf *zvrf)
+static void zread_pseudowire(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
        char ifname[IF_NAMESIZE];
@@ -2350,12 +2340,12 @@ static void zread_pseudowire(int command, struct zserv *client, u_short length,
        protocol = client->proto;
 
        pw = zebra_pw_find(zvrf, ifname);
-       switch (command) {
+       switch (hdr->command) {
        case ZEBRA_PW_ADD:
                if (pw) {
                        zlog_warn("%s: pseudowire %s already exists [%s]",
                                  __func__, ifname,
-                                 zserv_command_string(command));
+                                 zserv_command_string(hdr->command));
                        return;
                }
 
@@ -2364,7 +2354,7 @@ static void zread_pseudowire(int command, struct zserv *client, u_short length,
        case ZEBRA_PW_DELETE:
                if (!pw) {
                        zlog_warn("%s: pseudowire %s not found [%s]", __func__,
-                                 ifname, zserv_command_string(command));
+                                 ifname, zserv_command_string(hdr->command));
                        return;
                }
 
@@ -2374,11 +2364,11 @@ static void zread_pseudowire(int command, struct zserv *client, u_short length,
        case ZEBRA_PW_UNSET:
                if (!pw) {
                        zlog_warn("%s: pseudowire %s not found [%s]", __func__,
-                                 ifname, zserv_command_string(command));
+                                 ifname, zserv_command_string(hdr->command));
                        return;
                }
 
-               switch (command) {
+               switch (hdr->command) {
                case ZEBRA_PW_SET:
                        pw->enabled = 1;
                        break;
@@ -2528,7 +2518,7 @@ static void zebra_client_create(int sock)
        zebra_vrf_update_all(client);
 }
 
-static void zread_interface_set_master(struct zserv *client, u_short length)
+static void zread_interface_set_master(ZAPI_HANDLER_ARGS)
 {
        struct interface *master;
        struct interface *slave;
@@ -2554,7 +2544,7 @@ stream_failure:
 }
 
 
-static void zread_vrf_label(struct zserv *client, struct zebra_vrf *zvrf)
+static void zread_vrf_label(ZAPI_HANDLER_ARGS)
 {
        struct interface *ifp;
        mpls_label_t nlabel;
@@ -2622,8 +2612,7 @@ stream_failure:
        return;
 }
 
-static inline void zread_rule(uint16_t command, struct zserv *client,
-                             uint16_t length, struct zebra_vrf *zvrf)
+static inline void zread_rule(ZAPI_HANDLER_ARGS)
 {
        struct zebra_pbr_rule zpr;
        struct stream *s;
@@ -2671,7 +2660,7 @@ static inline void zread_rule(uint16_t command, struct zserv *client,
                if (zpr.filter.dst_port)
                        zpr.filter.filter_bm |= PBR_FILTER_DST_PORT;
 
-               if (command == ZEBRA_RULE_ADD)
+               if (hdr->command == ZEBRA_RULE_ADD)
                        zebra_pbr_add_rule(zvrf->zns, &zpr);
                else
                        zebra_pbr_del_rule(zvrf->zns, &zpr);
@@ -2698,162 +2687,78 @@ stream_failure:
        return false;
 }
 
+void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
+       [ZEBRA_ROUTER_ID_ADD] = zread_router_id_add,
+       [ZEBRA_ROUTER_ID_DELETE] = zread_router_id_delete,
+       [ZEBRA_INTERFACE_ADD] = zread_interface_add,
+       [ZEBRA_INTERFACE_DELETE] = zread_interface_delete,
+       [ZEBRA_ROUTE_ADD] = zread_route_add,
+       [ZEBRA_ROUTE_DELETE] = zread_route_del,
+       [ZEBRA_IPV4_ROUTE_ADD] = zread_ipv4_add,
+       [ZEBRA_IPV4_ROUTE_DELETE] = zread_ipv4_delete,
+       [ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD] = zread_ipv4_route_ipv6_nexthop_add,
+       [ZEBRA_IPV6_ROUTE_ADD] = zread_ipv6_add,
+       [ZEBRA_IPV6_ROUTE_DELETE] = zread_ipv6_delete,
+       [ZEBRA_REDISTRIBUTE_ADD] = zebra_redistribute_add,
+       [ZEBRA_REDISTRIBUTE_DELETE] = zebra_redistribute_delete,
+       [ZEBRA_REDISTRIBUTE_DEFAULT_ADD] = zebra_redistribute_default_add,
+       [ZEBRA_REDISTRIBUTE_DEFAULT_DELETE] = zebra_redistribute_default_delete,
+       [ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB] = zread_ipv4_nexthop_lookup_mrib,
+       [ZEBRA_HELLO] = zread_hello,
+       [ZEBRA_NEXTHOP_REGISTER] = zserv_rnh_register,
+       [ZEBRA_NEXTHOP_UNREGISTER] = zserv_rnh_unregister,
+       [ZEBRA_IMPORT_ROUTE_REGISTER] = zserv_rnh_register,
+       [ZEBRA_IMPORT_ROUTE_UNREGISTER] = zserv_rnh_unregister,
+       [ZEBRA_BFD_DEST_UPDATE] = zebra_ptm_bfd_dst_register,
+       [ZEBRA_BFD_DEST_REGISTER] = zebra_ptm_bfd_dst_register,
+       [ZEBRA_BFD_DEST_DEREGISTER] = zebra_ptm_bfd_dst_deregister,
+       [ZEBRA_VRF_UNREGISTER] = zread_vrf_unregister,
+       [ZEBRA_VRF_LABEL] = zread_vrf_label,
+       [ZEBRA_BFD_CLIENT_REGISTER] = zebra_ptm_bfd_client_register,
+#if defined(HAVE_RTADV)
+       [ZEBRA_INTERFACE_ENABLE_RADV] = zebra_interface_radv_enable,
+       [ZEBRA_INTERFACE_DISABLE_RADV] = zebra_interface_radv_disable,
+#else
+       [ZEBRA_INTERFACE_ENABLE_RADV] = NULL,
+       [ZEBRA_INTERFACE_DISABLE_RADV] = NULL,
+#endif
+       [ZEBRA_MPLS_LABELS_ADD] = zread_mpls_labels,
+       [ZEBRA_MPLS_LABELS_DELETE] = zread_mpls_labels,
+       [ZEBRA_IPMR_ROUTE_STATS] = zebra_ipmr_route_stats,
+       [ZEBRA_LABEL_MANAGER_CONNECT] = zread_label_manager_request,
+       [ZEBRA_GET_LABEL_CHUNK] = zread_label_manager_request,
+       [ZEBRA_RELEASE_LABEL_CHUNK] = zread_label_manager_request,
+       [ZEBRA_FEC_REGISTER] = zserv_fec_register,
+       [ZEBRA_FEC_UNREGISTER] = zserv_fec_unregister,
+       [ZEBRA_ADVERTISE_DEFAULT_GW] = zebra_vxlan_advertise_gw_macip,
+       [ZEBRA_ADVERTISE_SUBNET] = zebra_vxlan_advertise_subnet,
+       [ZEBRA_ADVERTISE_ALL_VNI] = zebra_vxlan_advertise_all_vni,
+       [ZEBRA_REMOTE_VTEP_ADD] = zebra_vxlan_remote_vtep_add,
+       [ZEBRA_REMOTE_VTEP_DEL] = zebra_vxlan_remote_vtep_del,
+       [ZEBRA_REMOTE_MACIP_ADD] = zebra_vxlan_remote_macip_add,
+       [ZEBRA_REMOTE_MACIP_DEL] = zebra_vxlan_remote_macip_del,
+       [ZEBRA_INTERFACE_SET_MASTER] = zread_interface_set_master,
+       [ZEBRA_PW_ADD] = zread_pseudowire,
+       [ZEBRA_PW_DELETE] = zread_pseudowire,
+       [ZEBRA_PW_SET] = zread_pseudowire,
+       [ZEBRA_PW_UNSET] = zread_pseudowire,
+       [ZEBRA_RULE_ADD] = zread_rule,
+       [ZEBRA_RULE_DELETE] = zread_rule,
+};
+
 static inline void zserv_handle_commands(struct zserv *client, uint16_t command,
                                         uint16_t length,
                                         struct zebra_vrf *zvrf)
 {
        struct zmsghdr hdr;
+
        stream_set_getp(client->ibuf, 0);
        zserv_read_header(client->ibuf, &hdr);
-
-       switch (command) {
-       case ZEBRA_ROUTER_ID_ADD:
-               zread_router_id_add(client, length, zvrf);
-               break;
-       case ZEBRA_ROUTER_ID_DELETE:
-               zread_router_id_delete(client, length, zvrf);
-               break;
-       case ZEBRA_INTERFACE_ADD:
-               zread_interface_add(client, length, zvrf);
-               break;
-       case ZEBRA_INTERFACE_DELETE:
-               zread_interface_delete(client, length, zvrf);
-               break;
-       case ZEBRA_ROUTE_ADD:
-               zread_route_add(client, length, zvrf);
-               break;
-       case ZEBRA_ROUTE_DELETE:
-               zread_route_del(client, length, zvrf);
-               break;
-       case ZEBRA_IPV4_ROUTE_ADD:
-               zread_ipv4_add(client, length, zvrf);
-               break;
-       case ZEBRA_IPV4_ROUTE_DELETE:
-               zread_ipv4_delete(client, length, zvrf);
-               break;
-       case ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD:
-               zread_ipv4_route_ipv6_nexthop_add(client, length, zvrf);
-               break;
-       case ZEBRA_IPV6_ROUTE_ADD:
-               zread_ipv6_add(client, length, zvrf);
-               break;
-       case ZEBRA_IPV6_ROUTE_DELETE:
-               zread_ipv6_delete(client, length, zvrf);
-               break;
-       case ZEBRA_REDISTRIBUTE_ADD:
-               zebra_redistribute_add(command, client, length, zvrf);
-               break;
-       case ZEBRA_REDISTRIBUTE_DELETE:
-               zebra_redistribute_delete(command, client, length, zvrf);
-               break;
-       case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
-               zebra_redistribute_default_add(command, client, length, zvrf);
-               break;
-       case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
-               zebra_redistribute_default_delete(command, client, length,
-                                                 zvrf);
-               break;
-       case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB:
-               zread_ipv4_nexthop_lookup_mrib(client, length, zvrf);
-               break;
-       case ZEBRA_HELLO:
-               zread_hello(client);
-               break;
-       case ZEBRA_NEXTHOP_REGISTER:
-               zserv_rnh_register(client, length, RNH_NEXTHOP_TYPE, zvrf);
-               break;
-       case ZEBRA_NEXTHOP_UNREGISTER:
-               zserv_rnh_unregister(client, length, RNH_NEXTHOP_TYPE, zvrf);
-               break;
-       case ZEBRA_IMPORT_ROUTE_REGISTER:
-               zserv_rnh_register(client, length, RNH_IMPORT_CHECK_TYPE, zvrf);
-               break;
-       case ZEBRA_IMPORT_ROUTE_UNREGISTER:
-               zserv_rnh_unregister(client, length, RNH_IMPORT_CHECK_TYPE,
-                                    zvrf);
-               break;
-       case ZEBRA_BFD_DEST_UPDATE:
-       case ZEBRA_BFD_DEST_REGISTER:
-               zebra_ptm_bfd_dst_register(client, length, command, zvrf);
-               break;
-       case ZEBRA_BFD_DEST_DEREGISTER:
-               zebra_ptm_bfd_dst_deregister(client, length, zvrf);
-               break;
-       case ZEBRA_VRF_UNREGISTER:
-               zread_vrf_unregister(client, length, zvrf);
-               break;
-       case ZEBRA_VRF_LABEL:
-               zread_vrf_label(client, zvrf);
-               break;
-       case ZEBRA_BFD_CLIENT_REGISTER:
-               zebra_ptm_bfd_client_register(client, length);
-               break;
-       case ZEBRA_INTERFACE_ENABLE_RADV:
-#if defined(HAVE_RTADV)
-               zebra_interface_radv_set(client, length, zvrf, 1);
-#endif
-               break;
-       case ZEBRA_INTERFACE_DISABLE_RADV:
-#if defined(HAVE_RTADV)
-               zebra_interface_radv_set(client, length, zvrf, 0);
-#endif
-               break;
-       case ZEBRA_MPLS_LABELS_ADD:
-       case ZEBRA_MPLS_LABELS_DELETE:
-               zread_mpls_labels(command, client, length, zvrf);
-               break;
-       case ZEBRA_IPMR_ROUTE_STATS:
-               zebra_ipmr_route_stats(client, length, zvrf);
-               break;
-       case ZEBRA_LABEL_MANAGER_CONNECT:
-       case ZEBRA_GET_LABEL_CHUNK:
-       case ZEBRA_RELEASE_LABEL_CHUNK:
-               zread_label_manager_request(command, client, zvrf);
-               break;
-       case ZEBRA_FEC_REGISTER:
-               zserv_fec_register(client, length);
-               break;
-       case ZEBRA_FEC_UNREGISTER:
-               zserv_fec_unregister(client, length);
-               break;
-       case ZEBRA_ADVERTISE_DEFAULT_GW:
-               zebra_vxlan_advertise_gw_macip(client, length, zvrf);
-               break;
-       case ZEBRA_ADVERTISE_SUBNET:
-               zebra_vxlan_advertise_subnet(client, length, zvrf);
-               break;
-       case ZEBRA_ADVERTISE_ALL_VNI:
-               zebra_vxlan_advertise_all_vni(client, length, zvrf);
-               break;
-       case ZEBRA_REMOTE_VTEP_ADD:
-               zebra_vxlan_remote_vtep_add(client, length, zvrf);
-               break;
-       case ZEBRA_REMOTE_VTEP_DEL:
-               zebra_vxlan_remote_vtep_del(client, length, zvrf);
-               break;
-       case ZEBRA_REMOTE_MACIP_ADD:
-               zebra_vxlan_remote_macip_add(client, length, zvrf);
-               break;
-       case ZEBRA_REMOTE_MACIP_DEL:
-               zebra_vxlan_remote_macip_del(client, length, zvrf);
-               break;
-       case ZEBRA_INTERFACE_SET_MASTER:
-               zread_interface_set_master(client, length);
-               break;
-       case ZEBRA_PW_ADD:
-       case ZEBRA_PW_DELETE:
-       case ZEBRA_PW_SET:
-       case ZEBRA_PW_UNSET:
-               zread_pseudowire(command, client, length, zvrf);
-               break;
-       case ZEBRA_RULE_ADD:
-       case ZEBRA_RULE_DELETE:
-               zread_rule(command, client, length, zvrf);
-               break;
-       default:
-               zlog_info("Zebra received unknown command %d", command);
-               break;
-       }
+       if (hdr.command > sizeof(zserv_handlers)
+           || zserv_handlers[hdr.command] == NULL)
+               zlog_info("Zebra received unknown command %d", hdr.command);
+       else
+               zserv_handlers[hdr.command](client, &hdr, zvrf);
 }
 
 #if defined(HANDLE_ZAPI_FUZZING)
index a09baeff7a3e1a75877bb3622b699f57b446e081..74ff31bcf9b0b82d2837e4c9c34c9bd256da5a3c 100644 (file)
@@ -138,6 +138,9 @@ struct zmsghdr {
        uint16_t command;
 };
 
+#define ZAPI_HANDLER_ARGS                                                      \
+       struct zserv *client, struct zmsghdr *hdr, struct zebra_vrf *zvrf
+
 /* Zebra instance */
 struct zebra_t {
        /* Thread master */