From 2cf63c35614034ef83fe2a561cf79a638366cc5b Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Mon, 12 Mar 2018 14:01:47 -0400 Subject: [PATCH 01/10] lib: fixup zlog_hexdump * Allocate correct amount of memory * Use snprintf() instead of sprintf() Signed-off-by: Quentin Young --- lib/log.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/lib/log.c b/lib/log.c index 9e33ef91021c..5537d8d721fd 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1092,41 +1092,48 @@ void zlog_hexdump(const void *mem, unsigned int len) unsigned long i = 0; unsigned int j = 0; unsigned int columns = 8; - char buf[(len * 4) + ((len / 4) * 20) + 30]; + /* 19 bytes for 0xADDRESS: */ + /* 24 bytes for data; 2 chars plus a space per data byte */ + /* 1 byte for space */ + /* 8 bytes for ASCII representation */ + /* 1 byte for a newline */ + /* ===================== */ + /* 53 bytes per 8 bytes of data */ + /* 1 byte for null term */ + size_t bs = ((len / 8) + 1) * 53 + 1; + char buf[bs]; char *s = buf; for (i = 0; i < len + ((len % columns) ? (columns - len % columns) : 0); i++) { /* print offset */ if (i % columns == 0) - s += sprintf(s, "0x%016lx: ", (unsigned long)mem + i); + s += snprintf(s, bs - (s - buf), + "0x%016lx: ", (unsigned long)mem + i); /* print hex data */ if (i < len) - s += sprintf(s, "%02x ", 0xFF & ((const char *)mem)[i]); + s += snprintf(s, bs - (s - buf), "%02x ", + 0xFF & ((const char *)mem)[i]); /* end of block, just aligning for ASCII dump */ else - s += sprintf(s, " "); + s += snprintf(s, bs - (s - buf), " "); /* print ASCII dump */ if (i % columns == (columns - 1)) { for (j = i - (columns - 1); j <= i; j++) { - if (j >= len) /* end of block, not really - printing */ - s += sprintf(s, " "); - - else if (isprint((int)((const char *)mem) - [j])) /* printable char - */ - s += sprintf( - s, "%c", + /* end of block not really printing */ + if (j >= len) + s += snprintf(s, bs - (s - buf), " "); + else if (isprint((int)((const char *)mem)[j])) + s += snprintf( + s, bs - (s - buf), "%c", 0xFF & ((const char *)mem)[j]); - else /* other char */ - s += sprintf(s, "."); + s += snprintf(s, bs - (s - buf), "."); } - s += sprintf(s, "\n"); + s += snprintf(s, bs - (s - buf), "\n"); } } zlog_debug("\n%s", buf); From 3fc174e18c080416932fff5e8cb3a08f0d9f8660 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Mon, 12 Mar 2018 14:04:56 -0400 Subject: [PATCH 02/10] tests: add unit test for zlog Just tests zlog_hexdump right now Signed-off-by: Quentin Young --- lib/log.c | 18 +++++++------ tests/Makefile.am | 6 ++++- tests/lib/test_zlog.c | 61 ++++++++++++++++++++++++++++++++++++++++++ tests/lib/test_zlog.py | 4 +++ 4 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 tests/lib/test_zlog.c create mode 100644 tests/lib/test_zlog.py diff --git a/lib/log.c b/lib/log.c index 5537d8d721fd..f6dfa1092333 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1092,14 +1092,16 @@ void zlog_hexdump(const void *mem, unsigned int len) unsigned long i = 0; unsigned int j = 0; unsigned int columns = 8; - /* 19 bytes for 0xADDRESS: */ - /* 24 bytes for data; 2 chars plus a space per data byte */ - /* 1 byte for space */ - /* 8 bytes for ASCII representation */ - /* 1 byte for a newline */ - /* ===================== */ - /* 53 bytes per 8 bytes of data */ - /* 1 byte for null term */ + /* + * 19 bytes for 0xADDRESS: + * 24 bytes for data; 2 chars plus a space per data byte + * 1 byte for space + * 8 bytes for ASCII representation + * 1 byte for a newline + * ===================== + * 53 bytes per 8 bytes of data + * 1 byte for null term + */ size_t bs = ((len / 8) + 1) * 53 + 1; char buf[bs]; char *s = buf; diff --git a/tests/Makefile.am b/tests/Makefile.am index f4ab2a126a29..0c9a5684dad2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -73,6 +73,7 @@ check_PROGRAMS = \ lib/test_timer_correctness \ lib/test_timer_performance \ lib/test_ttable \ + lib/test_zlog \ lib/cli/test_cli \ lib/cli/test_commands \ $(TESTS_BGPD) \ @@ -115,9 +116,9 @@ lib_test_heavy_SOURCES = lib/test_heavy.c helpers/c/main.c lib_test_memory_SOURCES = lib/test_memory.c lib_test_nexthop_iter_SOURCES = lib/test_nexthop_iter.c helpers/c/prng.c lib_test_privs_SOURCES = lib/test_privs.c +lib_test_ringbuf_SOURCES = lib/test_ringbuf.c lib_test_srcdest_table_SOURCES = lib/test_srcdest_table.c \ helpers/c/prng.c -lib_test_ringbuf_SOURCES = lib/test_ringbuf.c lib_test_segv_SOURCES = lib/test_segv.c lib_test_sig_SOURCES = lib/test_sig.c lib_test_stream_SOURCES = lib/test_stream.c @@ -127,6 +128,7 @@ lib_test_timer_correctness_SOURCES = lib/test_timer_correctness.c \ lib_test_timer_performance_SOURCES = lib/test_timer_performance.c \ helpers/c/prng.c lib_test_ttable_SOURCES = lib/test_ttable.c +lib_test_zlog_SOURCES = lib/test_zlog.c lib_test_zmq_SOURCES = lib/test_zmq.c lib_test_zmq_CFLAGS = $(AM_CFLAGS) $(ZEROMQ_CFLAGS) lib_cli_test_cli_SOURCES = lib/cli/test_cli.c lib/cli/common_cli.c @@ -167,6 +169,7 @@ lib_test_table_LDADD = $(ALL_TESTS_LDADD) -lm lib_test_timer_correctness_LDADD = $(ALL_TESTS_LDADD) lib_test_timer_performance_LDADD = $(ALL_TESTS_LDADD) lib_test_ttable_LDADD = $(ALL_TESTS_LDADD) +lib_test_zlog_LDADD = $(ALL_TESTS_LDADD) lib_test_zmq_LDADD = ../lib/libfrrzmq.la $(ALL_TESTS_LDADD) $(ZEROMQ_LIBS) lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD) lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD) @@ -207,6 +210,7 @@ EXTRA_DIST = \ lib/test_timer_correctness.py \ lib/test_ttable.py \ lib/test_ttable.refout \ + lib/test_zlog.py \ ospf6d/test_lsdb.py \ ospf6d/test_lsdb.in \ ospf6d/test_lsdb.refout \ diff --git a/tests/lib/test_zlog.c b/tests/lib/test_zlog.c new file mode 100644 index 000000000000..790e65cfe9d3 --- /dev/null +++ b/tests/lib/test_zlog.c @@ -0,0 +1,61 @@ +/* + * Zlog tests. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Quentin Young + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include +#include "log.h" + +/* maximum amount of data to hexdump */ +#define MAXDATA 16384 + +/* + * Test hexdump functionality. + * + * At the moment, not crashing is considered success. + */ +static bool test_zlog_hexdump(void) +{ + unsigned int nl = 1; + + do { + long d[nl]; + + for (unsigned int i = 0; i < nl; i++) + d[i] = random(); + zlog_hexdump(d, nl * sizeof(long)); + } while (++nl * sizeof(long) <= MAXDATA); + + return true; +} + +bool (*tests[])(void) = { + test_zlog_hexdump, +}; + +int main(int argc, char **argv) +{ + openzlog("testzlog", "NONE", 0, LOG_CONS | LOG_NDELAY | LOG_PID, + LOG_ERR); + zlog_set_file("test_zlog.log", LOG_DEBUG); + + for (unsigned int i = 0; i < array_size(tests); i++) + if (!tests[i]()) + return 1; + return 0; +} diff --git a/tests/lib/test_zlog.py b/tests/lib/test_zlog.py new file mode 100644 index 000000000000..2ca25858868a --- /dev/null +++ b/tests/lib/test_zlog.py @@ -0,0 +1,4 @@ +import frrtest + +class TestZlog(frrtest.TestMultiOut): + program = './test_zlog' From 8068a649a79409737dfa5235a84915b544d4fff7 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Tue, 6 Mar 2018 17:01:42 -0500 Subject: [PATCH 03/10] zebra: dont return a status code in zapi handlers All of the ZAPI message handlers return an integer that means different things to each of them, but nobody ever reads these integers, so this is technical debt that we can just eliminate outright. Signed-off-by: Quentin Young --- zebra/zebra_mroute.c | 5 +- zebra/zebra_mroute.h | 4 +- zebra/zebra_ptm.c | 28 +++--- zebra/zebra_ptm.h | 10 +- zebra/zebra_vxlan.c | 88 +++++++++--------- zebra/zebra_vxlan.h | 30 +++--- zebra/zebra_vxlan_null.c | 20 ++-- zebra/zserv.c | 194 +++++++++++++++++++-------------------- 8 files changed, 188 insertions(+), 191 deletions(-) diff --git a/zebra/zebra_mroute.c b/zebra/zebra_mroute.c index e9cd19ebe0cf..1143451d620d 100644 --- a/zebra/zebra_mroute.c +++ b/zebra/zebra_mroute.c @@ -32,8 +32,8 @@ #include "zebra/rt.h" #include "zebra/debug.h" -int zebra_ipmr_route_stats(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +void zebra_ipmr_route_stats(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct mcast_route_data mroute; struct stream *s; @@ -69,5 +69,4 @@ int zebra_ipmr_route_stats(struct zserv *client, u_short length, stream_putw_at(s, 0, stream_get_endp(s)); zebra_server_send_message(client); - return 0; } diff --git a/zebra/zebra_mroute.h b/zebra/zebra_mroute.h index 616c3a83ab54..5bee7b03d62d 100644 --- a/zebra/zebra_mroute.h +++ b/zebra/zebra_mroute.h @@ -28,7 +28,7 @@ struct mcast_route_data { unsigned long long lastused; }; -int zebra_ipmr_route_stats(struct zserv *client, u_short length, - struct zebra_vrf *zvf); +void zebra_ipmr_route_stats(struct zserv *client, u_short length, + struct zebra_vrf *zvf); #endif diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index f6775fa0b121..b0295d127e0c 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -661,8 +661,8 @@ int zebra_ptm_sock_read(struct thread *thread) } /* BFD peer/dst register/update */ -int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length, - int command, struct zebra_vrf *zvrf) +void zebra_ptm_bfd_dst_register(struct zserv *client, u_short length, + int command, struct zebra_vrf *zvrf) { struct stream *s; struct prefix src_p; @@ -693,7 +693,7 @@ int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length, ptm_cb.t_timer = NULL; thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time, &ptm_cb.t_timer); - return -1; + return; } ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); @@ -816,16 +816,16 @@ int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length, ptm_cb.out_data); zebra_ptm_send_message(ptm_cb.out_data, data_len); - return 0; + return; stream_failure: ptm_lib_cleanup_msg(ptm_hdl, out_ctxt); - return 0; + return; } /* BFD peer/dst deregister */ -int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +void zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct stream *s; struct prefix src_p; @@ -849,7 +849,7 @@ int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length, ptm_cb.t_timer = NULL; thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time, &ptm_cb.t_timer); - return -1; + return; } ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); @@ -948,15 +948,15 @@ int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length, zebra_ptm_send_message(ptm_cb.out_data, data_len); - return 0; + return; stream_failure: ptm_lib_cleanup_msg(ptm_hdl, out_ctxt); - return 0; + return; } /* BFD client register */ -int zebra_ptm_bfd_client_register(struct zserv *client, u_short length) +void zebra_ptm_bfd_client_register(struct zserv *client, u_short length) { struct stream *s; unsigned int pid; @@ -977,7 +977,7 @@ int zebra_ptm_bfd_client_register(struct zserv *client, u_short length) ptm_cb.t_timer = NULL; thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time, &ptm_cb.t_timer); - return -1; + return; } ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); @@ -1003,7 +1003,7 @@ int zebra_ptm_bfd_client_register(struct zserv *client, u_short length) SET_FLAG(ptm_cb.client_flags[client->proto], ZEBRA_PTM_BFD_CLIENT_FLAG_REG); - return 0; + return; stream_failure: /* @@ -1013,7 +1013,7 @@ int zebra_ptm_bfd_client_register(struct zserv *client, u_short length) * if (out_ctxt) * ptm_lib_cleanup_msg(ptm_hdl, out_ctxt); */ - return 0; + return; } /* BFD client deregister */ diff --git a/zebra/zebra_ptm.h b/zebra/zebra_ptm.h index 392853b59960..2397d5384594 100644 --- a/zebra/zebra_ptm.h +++ b/zebra/zebra_ptm.h @@ -62,12 +62,12 @@ int zebra_ptm_connect(struct thread *t); void zebra_ptm_write(struct vty *vty); int zebra_ptm_get_enable_state(void); -int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length, - int command, struct zebra_vrf *zvrf); -int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length, - struct zebra_vrf *zvrf); +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_show_status(struct vty *vty, struct interface *ifp); -int zebra_ptm_bfd_client_register(struct zserv *client, u_short length); +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); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index d3ede66fb0ca..bac589a8417b 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -4863,8 +4863,8 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp, /* * Handle message from client to delete a remote MACIP for a VNI. */ -int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +void zebra_vxlan_remote_macip_del(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct stream *s; vni_t vni; @@ -5008,7 +5008,7 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length, } stream_failure: - return 0; + return; } /* @@ -5016,8 +5016,8 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length, * could be just the add of a MAC address or the add of a neighbor * (IP+MAC). */ -int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +void zebra_vxlan_remote_macip_add(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct stream *s; vni_t vni; @@ -5045,7 +5045,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length, zlog_warn( "%s: EVPN Not turned on yet we have received a remote_macip add zapi callback", __PRETTY_FUNCTION__); - return -1; + return; } s = client->ibuf; @@ -5159,7 +5159,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length, prefix_mac2str(&macaddr, buf, sizeof(buf)), vni, inet_ntoa(vtep_ip)); - return -1; + return; } /* Is this MAC created for a MACIP? */ @@ -5212,7 +5212,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length, prefix_mac2str(&macaddr, buf, sizeof(buf)), vni, inet_ntoa(vtep_ip)); - return -1; + return; } } else if (memcmp(&n->emac, &macaddr, sizeof(macaddr)) @@ -5240,7 +5240,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length, } stream_failure: - return 0; + return; } /* @@ -5543,8 +5543,8 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, /* * Handle message from client to delete a remote VTEP for a VNI. */ -int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +void zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct stream *s; u_short l = 0; @@ -5559,13 +5559,13 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length, zlog_warn( "%s: EVPN is not enabled yet we have received a vtep del command", __PRETTY_FUNCTION__); - return -1; + return; } if (zvrf_id(zvrf) != VRF_DEFAULT) { zlog_err("Recv MACIP DEL for non-default VRF %u", zvrf_id(zvrf)); - return -1; + return; } s = client->ibuf; @@ -5623,14 +5623,14 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length, } stream_failure: - return 0; + return; } /* * Handle message from client to add a remote VTEP for a VNI. */ -int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +void zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct stream *s; u_short l = 0; @@ -5644,13 +5644,13 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length, zlog_warn( "%s: EVPN not enabled yet we received a vtep_add zapi call", __PRETTY_FUNCTION__); - return -1; + return; } if (zvrf_id(zvrf) != VRF_DEFAULT) { zlog_err("Recv MACIP ADD for non-default VRF %u", zvrf_id(zvrf)); - return -1; + return; } s = client->ibuf; @@ -5705,7 +5705,7 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length, } stream_failure: - return 0; + return; } /* @@ -6512,8 +6512,8 @@ int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf) * Handle message from client to enable/disable advertisement of g/w macip * routes */ -int zebra_vxlan_advertise_subnet(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +void zebra_vxlan_advertise_subnet(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct stream *s; int advertise; @@ -6527,7 +6527,7 @@ int zebra_vxlan_advertise_subnet(struct zserv *client, u_short length, if (zvrf_id(zvrf) != VRF_DEFAULT) { zlog_err("EVPN GW-MACIP Adv for non-default VRF %u", zvrf_id(zvrf)); - return -1; + return; } s = client->ibuf; @@ -6536,10 +6536,10 @@ int zebra_vxlan_advertise_subnet(struct zserv *client, u_short length, zvni = zvni_lookup(vni); if (!zvni) - return 0; + return; if (zvni->advertise_subnet == advertise) - return 0; + return; if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("EVPN subnet Adv %s on VNI %d , currently %s", @@ -6551,35 +6551,35 @@ int zebra_vxlan_advertise_subnet(struct zserv *client, u_short length, ifp = zvni->vxlan_if; if (!ifp) - return 0; + return; zif = ifp->info; /* If down or not mapped to a bridge, we're done. */ if (!if_is_operative(ifp) || !zif->brslave_info.br_if) - return 0; + return; zl2_info = zif->l2info.vxl; vlan_if = zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if); if (!vlan_if) - return 0; + return; if (zvni->advertise_subnet) zvni_advertise_subnet(zvni, vlan_if, 1); else zvni_advertise_subnet(zvni, vlan_if, 0); - return 0; + return; } /* * Handle message from client to enable/disable advertisement of g/w macip * routes */ -int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +void zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct stream *s; int advertise; @@ -6590,7 +6590,7 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length, if (zvrf_id(zvrf) != VRF_DEFAULT) { zlog_err("EVPN GW-MACIP Adv for non-default VRF %u", zvrf_id(zvrf)); - return -1; + return; } s = client->ibuf; @@ -6606,7 +6606,7 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length, : "disabled"); if (zvrf->advertise_gw_macip == advertise) - return 0; + return; zvrf->advertise_gw_macip = advertise; @@ -6625,7 +6625,7 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length, zvni = zvni_lookup(vni); if (!zvni) - return 0; + return; if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( @@ -6635,26 +6635,26 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length, : "disabled"); if (zvni->advertise_gw_macip == advertise) - return 0; + return; zvni->advertise_gw_macip = advertise; ifp = zvni->vxlan_if; if (!ifp) - return 0; + return; zif = ifp->info; /* If down or not mapped to a bridge, we're done. */ if (!if_is_operative(ifp) || !zif->brslave_info.br_if) - return 0; + return; zl2_info = zif->l2info.vxl; vlan_if = zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if); if (!vlan_if) - return 0; + return; if (advertise_gw_macip_enabled(zvni)) { /* Add primary SVI MAC-IP */ @@ -6676,7 +6676,7 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length, } stream_failure: - return 0; + return; } @@ -6686,8 +6686,8 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length, * when disabled, the entries should be deleted and remote VTEPs and MACs * uninstalled from the kernel. */ -int zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +void zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct stream *s = NULL; int advertise = 0; @@ -6695,7 +6695,7 @@ int zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length, if (zvrf_id(zvrf) != VRF_DEFAULT) { zlog_err("EVPN VNI Adv for non-default VRF %u", zvrf_id(zvrf)); - return -1; + return; } s = client->ibuf; @@ -6707,7 +6707,7 @@ int zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length, is_evpn_enabled() ? "enabled" : "disabled"); if (zvrf->advertise_all_vni == advertise) - return 0; + return; zvrf->advertise_all_vni = advertise; if (is_evpn_enabled()) { @@ -6732,13 +6732,13 @@ int zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length, /* cleanup all l3vnis */ zns = zebra_ns_lookup(NS_DEFAULT); if (!zns) - return -1; + return; hash_iterate(zns->l3vni_table, zl3vni_cleanup_all, NULL); } stream_failure: - return 0; + return; } /* diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index 7abf0050fcfb..af76a41d80d6 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -51,6 +51,22 @@ 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 int is_l3vni_for_prefix_routes_only(vni_t vni); extern ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id); extern int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf); @@ -117,10 +133,6 @@ extern int zebra_vxlan_local_neigh_add_update( extern int zebra_vxlan_local_neigh_del(struct interface *ifp, struct interface *link_if, struct ipaddr *ip); -extern int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length, - struct zebra_vrf *zvrf); -extern int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length, - struct zebra_vrf *zvrf); extern int zebra_vxlan_local_mac_add_update(struct interface *ifp, struct interface *br_if, struct ethaddr *mac, vlanid_t vid, @@ -140,16 +152,6 @@ extern int zebra_vxlan_if_down(struct interface *ifp); extern int zebra_vxlan_if_add(struct interface *ifp); extern int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags); extern int zebra_vxlan_if_del(struct interface *ifp); -extern int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length, - struct zebra_vrf *zvrf); -extern int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length, - struct zebra_vrf *zvrf); -extern int zebra_vxlan_advertise_subnet(struct zserv *client, u_short length, - struct zebra_vrf *zvrf); -extern int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length, - struct zebra_vrf *zvrf); -extern int zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length, - struct zebra_vrf *zvrf); extern int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, char *err, int err_str_sz, int filter, int add); diff --git a/zebra/zebra_vxlan_null.c b/zebra/zebra_vxlan_null.c index 1bac2cafb6b1..e6a3dd674ebe 100644 --- a/zebra/zebra_vxlan_null.c +++ b/zebra/zebra_vxlan_null.c @@ -117,14 +117,14 @@ int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if) return 0; } -int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length, - struct zebra_vrf *zvrf) +void zebra_vxlan_remote_macip_add(struct zserv *client, int sock, + u_short length, struct zebra_vrf *zvrf) { return 0; } -int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length, - struct zebra_vrf *zvrf) +void zebra_vxlan_remote_macip_del(struct zserv *client, int sock, + u_short length, struct zebra_vrf *zvrf) { return 0; } @@ -182,20 +182,20 @@ int zebra_vxlan_if_del(struct interface *ifp) return 0; } -int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length, - struct zebra_vrf *zvrf) +void zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length, + struct zebra_vrf *zvrf) { return 0; } -int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length, - struct zebra_vrf *zvrf) +void zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length, + struct zebra_vrf *zvrf) { return 0; } -int zebra_vxlan_advertise_all_vni(struct zserv *client, int sock, - u_short length, struct zebra_vrf *zvrf) +void zebra_vxlan_advertise_all_vni(struct zserv *client, int sock, + u_short length, struct zebra_vrf *zvrf) { return 0; } diff --git a/zebra/zserv.c b/zebra/zserv.c index 1a2ad7f8b4f5..f3ee38fef121 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -693,8 +693,8 @@ static int zsend_write_nexthop(struct stream *s, struct nexthop *nexthop) } /* Nexthop register */ -static int zserv_rnh_register(struct zserv *client, u_short length, - rnh_type_t type, struct zebra_vrf *zvrf) +static void zserv_rnh_register(struct zserv *client, u_short length, + rnh_type_t type, struct zebra_vrf *zvrf) { struct rnh *rnh; struct stream *s; @@ -722,7 +722,7 @@ static int zserv_rnh_register(struct zserv *client, u_short length, zlog_warn( "%s: Specified prefix length %d is too large for a v4 address", __PRETTY_FUNCTION__, p.prefixlen); - return -1; + return; } STREAM_GET(&p.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN); l += IPV4_MAX_BYTELEN; @@ -731,7 +731,7 @@ static int zserv_rnh_register(struct zserv *client, u_short length, zlog_warn( "%s: Specified prefix length %d is to large for a v6 address", __PRETTY_FUNCTION__, p.prefixlen); - return -1; + return; } STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN); l += IPV6_MAX_BYTELEN; @@ -739,7 +739,7 @@ static int zserv_rnh_register(struct zserv *client, u_short length, zlog_err( "rnh_register: Received unknown family type %d\n", p.family); - return -1; + return; } rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type); if (type == RNH_NEXTHOP_TYPE) { @@ -764,12 +764,12 @@ static int zserv_rnh_register(struct zserv *client, u_short length, } stream_failure: - return 0; + return; } /* Nexthop register */ -static int zserv_rnh_unregister(struct zserv *client, u_short length, - rnh_type_t type, struct zebra_vrf *zvrf) +static void zserv_rnh_unregister(struct zserv *client, u_short length, + rnh_type_t type, struct zebra_vrf *zvrf) { struct rnh *rnh; struct stream *s; @@ -797,7 +797,7 @@ static int zserv_rnh_unregister(struct zserv *client, u_short length, zlog_warn( "%s: Specified prefix length %d is to large for a v4 address", __PRETTY_FUNCTION__, p.prefixlen); - return -1; + return; } STREAM_GET(&p.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN); l += IPV4_MAX_BYTELEN; @@ -806,7 +806,7 @@ static int zserv_rnh_unregister(struct zserv *client, u_short length, zlog_warn( "%s: Specified prefix length %d is to large for a v6 address", __PRETTY_FUNCTION__, p.prefixlen); - return -1; + return; } STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN); l += IPV6_MAX_BYTELEN; @@ -814,7 +814,7 @@ static int zserv_rnh_unregister(struct zserv *client, u_short length, zlog_err( "rnh_register: Received unknown family type %d\n", p.family); - return -1; + return; } rnh = zebra_lookup_rnh(&p, zvrf_id(zvrf), type); if (rnh) { @@ -823,13 +823,13 @@ static int zserv_rnh_unregister(struct zserv *client, u_short length, } } stream_failure: - return 0; + return; } #define ZEBRA_MIN_FEC_LENGTH 5 /* FEC register */ -static int zserv_fec_register(struct zserv *client, u_short length) +static void zserv_fec_register(struct zserv *client, u_short length) { struct stream *s; struct zebra_vrf *zvrf; @@ -841,7 +841,7 @@ static int zserv_fec_register(struct zserv *client, u_short length) s = client->ibuf; zvrf = vrf_info_lookup(VRF_DEFAULT); if (!zvrf) - return 0; // unexpected + return; /* * The minimum amount of data that can be sent for one fec @@ -851,7 +851,7 @@ static int zserv_fec_register(struct zserv *client, u_short length) zlog_err( "fec_register: Received a fec register of length %d, it is of insufficient size to properly decode", length); - return -1; + return; } while (l < length) { @@ -862,7 +862,7 @@ static int zserv_fec_register(struct zserv *client, u_short length) zlog_err( "fec_register: Received unknown family type %d\n", p.family); - return -1; + return; } STREAM_GETC(s, p.prefixlen); if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN) @@ -871,7 +871,7 @@ static int zserv_fec_register(struct zserv *client, u_short length) zlog_warn( "%s: Specified prefix length: %d is to long for %d", __PRETTY_FUNCTION__, p.prefixlen, p.family); - return -1; + return; } l += 5; STREAM_GET(&p.u.prefix, s, PSIZE(p.prefixlen)); @@ -885,11 +885,11 @@ static int zserv_fec_register(struct zserv *client, u_short length) } stream_failure: - return 0; + return; } /* FEC unregister */ -static int zserv_fec_unregister(struct zserv *client, u_short length) +static void zserv_fec_unregister(struct zserv *client, u_short length) { struct stream *s; struct zebra_vrf *zvrf; @@ -900,7 +900,7 @@ static int zserv_fec_unregister(struct zserv *client, u_short length) s = client->ibuf; zvrf = vrf_info_lookup(VRF_DEFAULT); if (!zvrf) - return 0; // unexpected + return; /* * The minimum amount of data that can be sent for one @@ -910,7 +910,7 @@ static int zserv_fec_unregister(struct zserv *client, u_short length) zlog_err( "fec_unregister: Received a fec unregister of length %d, it is of insufficient size to properly decode", length); - return -1; + return; } while (l < length) { @@ -924,7 +924,7 @@ static int zserv_fec_unregister(struct zserv *client, u_short length) zlog_err( "fec_unregister: Received unknown family type %d\n", p.family); - return -1; + return; } STREAM_GETC(s, p.prefixlen); if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN) @@ -933,7 +933,7 @@ static int zserv_fec_unregister(struct zserv *client, u_short length) zlog_warn( "%s: Received prefix length %d which is greater than %d can support", __PRETTY_FUNCTION__, p.prefixlen, p.family); - return -1; + return; } l += 5; STREAM_GET(&p.u.prefix, s, PSIZE(p.prefixlen)); @@ -942,7 +942,7 @@ static int zserv_fec_unregister(struct zserv *client, u_short length) } stream_failure: - return 0; + return; } /* @@ -1133,8 +1133,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 int zread_interface_add(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +static void zread_interface_add(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct vrf *vrf; struct interface *ifp; @@ -1149,21 +1149,20 @@ static int zread_interface_add(struct zserv *client, u_short length, continue; if (zsend_interface_add(client, ifp) < 0) - return -1; + return; if (zsend_interface_addresses(client, ifp) < 0) - return -1; + return; } } - return 0; + return; } /* Unregister zebra server interface information. */ -static int zread_interface_delete(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +static void zread_interface_delete(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { vrf_bitmap_unset(client->ifinfo, zvrf_id(zvrf)); - return 0; } void zserv_nexthop_num_warn(const char *caller, const struct prefix *p, @@ -1178,8 +1177,8 @@ void zserv_nexthop_num_warn(const char *caller, const struct prefix *p, } } -static int zread_route_add(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +static void zread_route_add(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct stream *s; struct zapi_route api; @@ -1193,7 +1192,7 @@ static int zread_route_add(struct zserv *client, u_short length, s = client->ibuf; if (zapi_route_decode(s, &api) < 0) - return -1; + return; /* Allocate new route. */ vrf_id = zvrf_id(zvrf); @@ -1277,7 +1276,7 @@ static int zread_route_add(struct zserv *client, u_short length, __PRETTY_FUNCTION__, api.nexthop_num); nexthops_free(re->ng.nexthop); XFREE(MTYPE_RE, re); - return -1; + return; } /* MPLS labels for BGP-LU or Segment Routing */ if (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL) @@ -1309,7 +1308,7 @@ static int zread_route_add(struct zserv *client, u_short length, __PRETTY_FUNCTION__); nexthops_free(re->ng.nexthop); XFREE(MTYPE_RE, re); - return -1; + return; } if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) src_p = &api.src_prefix; @@ -1331,12 +1330,10 @@ static int zread_route_add(struct zserv *client, u_short length, client->v6_route_upd8_cnt++; break; } - - return 0; } -static int zread_route_del(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +static void zread_route_del(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct stream *s; struct zapi_route api; @@ -1345,13 +1342,13 @@ static int zread_route_del(struct zserv *client, u_short length, s = client->ibuf; if (zapi_route_decode(s, &api) < 0) - return -1; + return; afi = family2afi(api.prefix.family); if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { zlog_warn("%s: Received a src prefix while afi is not v6", __PRETTY_FUNCTION__); - return -1; + return; } if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) src_p = &api.src_prefix; @@ -1370,7 +1367,7 @@ static int zread_route_del(struct zserv *client, u_short length, break; } - return 0; + return; } /* This function support multiple nexthop. */ @@ -1378,8 +1375,8 @@ static int 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 int zread_ipv4_add(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +static void zread_ipv4_add(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { int i; struct route_entry *re; @@ -1409,7 +1406,7 @@ static int zread_ipv4_add(struct zserv *client, u_short length, zlog_warn("%s: Specified route type %d is not a legal value\n", __PRETTY_FUNCTION__, re->type); XFREE(MTYPE_RE, re); - return -1; + return; } STREAM_GETW(s, re->instance); STREAM_GETL(s, re->flags); @@ -1426,7 +1423,7 @@ static int zread_ipv4_add(struct zserv *client, u_short length, "%s: Specified prefix length %d is greater than what v4 can be", __PRETTY_FUNCTION__, p.prefixlen); XFREE(MTYPE_RE, re); - return -1; + return; } STREAM_GET(&p.u.prefix4, s, PSIZE(p.prefixlen)); @@ -1478,7 +1475,7 @@ static int zread_ipv4_add(struct zserv *client, u_short length, __PRETTY_FUNCTION__); nexthops_free(re->ng.nexthop); XFREE(MTYPE_RE, re); - return -1; + return; break; case NEXTHOP_TYPE_BLACKHOLE: route_entry_nexthop_blackhole_add(re, bh_type); @@ -1489,7 +1486,7 @@ static int zread_ipv4_add(struct zserv *client, u_short length, __PRETTY_FUNCTION__, nexthop_type); nexthops_free(re->ng.nexthop); XFREE(MTYPE_RE, re); - return -1; + return; } } } @@ -1524,17 +1521,17 @@ static int zread_ipv4_add(struct zserv *client, u_short length, else if (ret < 0) client->v4_route_upd8_cnt++; - return 0; + return; stream_failure: nexthops_free(re->ng.nexthop); XFREE(MTYPE_RE, re); - return -1; + return; } /* Zebra server IPv4 prefix delete function. */ -static int zread_ipv4_delete(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +static void zread_ipv4_delete(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct stream *s; struct zapi_ipv4 api; @@ -1557,7 +1554,7 @@ static int zread_ipv4_delete(struct zserv *client, u_short length, if (p.prefixlen > IPV4_MAX_BITLEN) { zlog_warn("%s: Passed in prefixlen %d is impossible", __PRETTY_FUNCTION__, p.prefixlen); - return -1; + return; } STREAM_GET(&p.u.prefix4, s, PSIZE(p.prefixlen)); @@ -1568,28 +1565,29 @@ static int zread_ipv4_delete(struct zserv *client, u_short length, client->v4_route_del_cnt++; stream_failure: - return 0; + return; } /* MRIB Nexthop lookup for IPv4. */ -static int zread_ipv4_nexthop_lookup_mrib(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +static void zread_ipv4_nexthop_lookup_mrib(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct in_addr addr; struct route_entry *re; STREAM_GET(&addr.s_addr, client->ibuf, IPV4_MAX_BYTELEN); re = rib_match_ipv4_multicast(zvrf_id(zvrf), addr, NULL); - return zsend_ipv4_nexthop_lookup_mrib(client, addr, re, zvrf); + zsend_ipv4_nexthop_lookup_mrib(client, addr, re, zvrf); + return; stream_failure: - return -1; + return; } /* Zebra server IPv6 prefix add function. */ -static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, - u_short length, - struct zebra_vrf *zvrf) +static void zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, + u_short length, + struct zebra_vrf *zvrf) { unsigned int i; struct stream *s; @@ -1623,7 +1621,8 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, zlog_warn("%s: Specified route type: %d is not a legal value\n", __PRETTY_FUNCTION__, re->type); XFREE(MTYPE_RE, re); - return -1; + + return; } STREAM_GETW(s, re->instance); STREAM_GETL(s, re->flags); @@ -1640,7 +1639,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, "%s: Prefix Length %d is greater than what a v4 address can use", __PRETTY_FUNCTION__, p.prefixlen); XFREE(MTYPE_RE, re); - return -1; + return; } STREAM_GET(&p.u.prefix4, s, PSIZE(p.prefixlen)); @@ -1695,7 +1694,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, __PRETTY_FUNCTION__); nexthops_free(re->ng.nexthop); XFREE(MTYPE_RE, re); - return -1; + return; } } @@ -1753,16 +1752,16 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, else if (ret < 0) client->v4_route_upd8_cnt++; - return 0; + return; stream_failure: nexthops_free(re->ng.nexthop); XFREE(MTYPE_RE, re); - return -1; + return; } -static int zread_ipv6_add(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +static void zread_ipv6_add(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { unsigned int i; struct stream *s; @@ -1798,7 +1797,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length, zlog_warn("%s: Specified route type: %d is not a legal value\n", __PRETTY_FUNCTION__, re->type); XFREE(MTYPE_RE, re); - return -1; + return; } STREAM_GETW(s, re->instance); STREAM_GETL(s, re->flags); @@ -1815,7 +1814,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length, "%s: Specified prefix length %d is to large for v6 prefix", __PRETTY_FUNCTION__, p.prefixlen); XFREE(MTYPE_RE, re); - return -1; + return; } STREAM_GET(&p.u.prefix6, s, PSIZE(p.prefixlen)); @@ -1828,7 +1827,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length, "%s: Specified src prefix length %d is to large for v6 prefix", __PRETTY_FUNCTION__, src_p.prefixlen); XFREE(MTYPE_RE, re); - return -1; + return; } STREAM_GET(&src_p.prefix, s, PSIZE(src_p.prefixlen)); src_pp = &src_p; @@ -1891,7 +1890,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length, __PRETTY_FUNCTION__); nexthops_free(re->ng.nexthop); XFREE(MTYPE_RE, re); - return -1; + return; } } @@ -1947,18 +1946,18 @@ static int zread_ipv6_add(struct zserv *client, u_short length, else if (ret < 0) client->v6_route_upd8_cnt++; - return 0; + return; stream_failure: nexthops_free(re->ng.nexthop); XFREE(MTYPE_RE, re); - return -1; + return; } /* Zebra server IPv6 prefix delete function. */ -static int zread_ipv6_delete(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +static void zread_ipv6_delete(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct stream *s; struct zapi_ipv6 api; @@ -1996,12 +1995,12 @@ static int zread_ipv6_delete(struct zserv *client, u_short length, client->v6_route_del_cnt++; stream_failure: - return 0; + return; } /* Register zebra server router-id information. Send current router-id */ -static int zread_router_id_add(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +static void zread_router_id_add(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct prefix p; @@ -2010,15 +2009,14 @@ static int zread_router_id_add(struct zserv *client, u_short length, router_id_get(&p, zvrf_id(zvrf)); - return zsend_router_id_update(client, &p, zvrf_id(zvrf)); + zsend_router_id_update(client, &p, zvrf_id(zvrf)); } /* Unregister zebra server router-id information. */ -static int zread_router_id_delete(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +static void zread_router_id_delete(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf)); - return 0; } /* Tie up route-type and client->sock */ @@ -2052,8 +2050,8 @@ static void zread_hello(struct zserv *client) } /* Unregister all information in a VRF. */ -static int zread_vrf_unregister(struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +static void zread_vrf_unregister(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { int i; afi_t afi; @@ -2064,8 +2062,6 @@ static int zread_vrf_unregister(struct zserv *client, u_short length, vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf)); vrf_bitmap_unset(client->ifinfo, zvrf_id(zvrf)); vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf)); - - return 0; } static void zread_mpls_labels(int command, struct zserv *client, u_short length, @@ -2313,8 +2309,8 @@ static void zread_label_manager_request(int cmd, struct zserv *client, } } -static int zread_pseudowire(int command, struct zserv *client, u_short length, - struct zebra_vrf *zvrf) +static void zread_pseudowire(int command, struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { struct stream *s; char ifname[IF_NAMESIZE]; @@ -2345,7 +2341,7 @@ static int zread_pseudowire(int command, struct zserv *client, u_short length, STREAM_GET(&nexthop.ipv6, s, 16); break; default: - return -1; + return; } STREAM_GETL(s, local_label); STREAM_GETL(s, remote_label); @@ -2360,7 +2356,7 @@ static int zread_pseudowire(int command, struct zserv *client, u_short length, zlog_warn("%s: pseudowire %s already exists [%s]", __func__, ifname, zserv_command_string(command)); - return -1; + return; } zebra_pw_add(zvrf, ifname, protocol, client); @@ -2369,7 +2365,7 @@ static int zread_pseudowire(int command, struct zserv *client, u_short length, if (!pw) { zlog_warn("%s: pseudowire %s not found [%s]", __func__, ifname, zserv_command_string(command)); - return -1; + return; } zebra_pw_del(zvrf, pw); @@ -2379,7 +2375,7 @@ static int zread_pseudowire(int command, struct zserv *client, u_short length, if (!pw) { zlog_warn("%s: pseudowire %s not found [%s]", __func__, ifname, zserv_command_string(command)); - return -1; + return; } switch (command) { @@ -2397,7 +2393,7 @@ static int zread_pseudowire(int command, struct zserv *client, u_short length, } stream_failure: - return 0; + return; } /* Cleanup registered nexthops (across VRFs) upon client disconnect. */ @@ -2532,7 +2528,7 @@ static void zebra_client_create(int sock) zebra_vrf_update_all(client); } -static int zread_interface_set_master(struct zserv *client, u_short length) +static void zread_interface_set_master(struct zserv *client, u_short length) { struct interface *master; struct interface *slave; @@ -2549,12 +2545,12 @@ static int zread_interface_set_master(struct zserv *client, u_short length) slave = if_lookup_by_index(ifindex, vrf_id); if (!master || !slave) - return 0; + return; kernel_interface_set_master(master, slave); stream_failure: - return 1; + return; } From 9bcbcae2e428bfd2b8d3a95368e459a338c14eed Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Tue, 6 Mar 2018 17:09:36 -0500 Subject: [PATCH 04/10] zebra: add struct zmsghdr Formalize the ZAPI header by documenting it in code and providing it to message handlers free of charge to reduce complexity. Signed-off-by: Quentin Young --- zebra/zserv.c | 21 +++++++++++++++++++++ zebra/zserv.h | 9 +++++++++ 2 files changed, 30 insertions(+) diff --git a/zebra/zserv.c b/zebra/zserv.c index f3ee38fef121..3ecc82be4252 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2681,10 +2681,31 @@ static inline void zread_rule(uint16_t command, struct zserv *client, return; } +/* + * Reads header from zmsg stream. + * + * Note this advances the stream getp by the size of the header. + */ +static bool zserv_read_header(struct stream *msg, struct zmsghdr *hdr) +{ + STREAM_GETW(msg, hdr->length); + STREAM_GETC(msg, hdr->marker); + STREAM_GETC(msg, hdr->version); + STREAM_GETL(msg, hdr->vrf_id); + STREAM_GETW(msg, hdr->command); + return true; +stream_failure: + return false; +} + 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); diff --git a/zebra/zserv.h b/zebra/zserv.h index 8519693726e3..a09baeff7a3e 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -129,6 +129,15 @@ struct zserv { int last_write_cmd; }; +/* ZAPI protocol message header */ +struct zmsghdr { + uint16_t length; + uint8_t marker; + uint8_t version; + uint32_t vrf_id; + uint16_t command; +}; + /* Zebra instance */ struct zebra_t { /* Thread master */ From 89f4e5077bd8162dbda0e10a3bbd594c2c698d77 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Tue, 6 Mar 2018 17:57:33 -0500 Subject: [PATCH 05/10] zebra: standardize ZAPI message handler args 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 --- zebra/redistribute.c | 12 +- zebra/redistribute.h | 14 +- zebra/rtadv.c | 23 ++- zebra/rtadv.h | 5 +- zebra/zebra_mroute.c | 4 +- zebra/zebra_mroute.h | 5 +- zebra/zebra_ptm.c | 16 +- zebra/zebra_ptm.h | 11 +- zebra/zebra_vxlan.c | 31 ++-- zebra/zebra_vxlan.h | 23 ++- zebra/zserv.c | 341 ++++++++++++++++--------------------------- zebra/zserv.h | 3 + 12 files changed, 194 insertions(+), 294 deletions(-) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index a7b2361ac68d..93862cadc90a 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -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 @@ void zebra_redistribute_add(int command, struct zserv *client, int length, 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 @@ void zebra_redistribute_delete(int command, struct zserv *client, int length, 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)); } diff --git a/zebra/redistribute.h b/zebra/redistribute.h index 5edb06c3da7d..6ca3b57d4dce 100644 --- a/zebra/redistribute.h +++ b/zebra/redistribute.h @@ -27,15 +27,11 @@ #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 *); diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 5eebca163b5c..56decdcdbabe 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -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 @@ void zebra_interface_radv_set(struct zserv *client, u_short length, 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", diff --git a/zebra/rtadv.h b/zebra/rtadv.h index 2cae6d06f9bb..28019a32378a 100644 --- a/zebra/rtadv.h +++ b/zebra/rtadv.h @@ -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 */ diff --git a/zebra/zebra_mroute.c b/zebra/zebra_mroute.c index 1143451d620d..e70b963cfd1b 100644 --- a/zebra/zebra_mroute.c +++ b/zebra/zebra_mroute.c @@ -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; diff --git a/zebra/zebra_mroute.h b/zebra/zebra_mroute.h index 5bee7b03d62d..33851536005f 100644 --- a/zebra/zebra_mroute.h +++ b/zebra/zebra_mroute.h @@ -22,13 +22,14 @@ #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 diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index b0295d127e0c..0c48473aad21 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -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 @@ void zebra_ptm_bfd_dst_register(struct zserv *client, u_short length, } /* 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 @@ void zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length, } /* 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); diff --git a/zebra/zebra_ptm.h b/zebra/zebra_ptm.h index 2397d5384594..22cacd6fc045 100644 --- a/zebra/zebra_ptm.h +++ b/zebra/zebra_ptm.h @@ -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); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index bac589a8417b..f22d5160fbb9 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -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 @@ void zebra_vxlan_remote_macip_del(struct zserv *client, u_short length, * 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 @@ void zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length, /* * 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 @@ void zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length, * 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; diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index af76a41d80d6..62c6519d50b2 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -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); diff --git a/zebra/zserv.c b/zebra/zserv.c index 3ecc82be4252..127913a63a63 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -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 @@ static void zserv_rnh_register(struct zserv *client, u_short length, } /* 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 @@ static void zserv_rnh_unregister(struct zserv *client, u_short length, #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 @@ static void zserv_fec_register(struct zserv *client, u_short length) } /* 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 @@ static void zread_ipv4_add(struct zserv *client, u_short length, } /* 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 @@ static void zread_ipv4_delete(struct zserv *client, u_short length, } /* 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 @@ static void zread_ipv4_nexthop_lookup_mrib(struct zserv *client, u_short length, } /* 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 @@ static void zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, 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 @@ static void zread_ipv6_add(struct zserv *client, u_short length, } /* 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 @@ static void zread_ipv6_delete(struct zserv *client, u_short length, } /* 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 @@ static void zread_hello(struct zserv *client) } /* 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 @@ static void zread_interface_set_master(struct zserv *client, u_short length) } -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 @@ static void zread_vrf_label(struct zserv *client, struct zebra_vrf *zvrf) 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 @@ static bool zserv_read_header(struct stream *msg, struct zmsghdr *hdr) 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) diff --git a/zebra/zserv.h b/zebra/zserv.h index a09baeff7a3e..74ff31bcf9b0 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -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 */ From 1002497af5aedffc661cb457c8775634a65c3a19 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Tue, 6 Mar 2018 18:08:37 -0500 Subject: [PATCH 06/10] zebra: reorganize zserv, batch i/o Group send and receive functions together, change handlers to take a message instead of looking at ->ibuf and ->obuf, allow zebra to read multiple packets off the wire at a time. Signed-off-by: Quentin Young --- zebra/label_manager.c | 22 +- zebra/redistribute.c | 12 +- zebra/redistribute.h | 3 +- zebra/rtadv.c | 19 +- zebra/rtadv.h | 2 +- zebra/zebra_mpls.c | 5 +- zebra/zebra_mroute.c | 11 +- zebra/zebra_ptm.c | 8 +- zebra/zebra_ptm.h | 5 +- zebra/zebra_ptm_redistribute.c | 10 +- zebra/zebra_rnh.c | 5 +- zebra/zebra_vxlan.c | 49 +- zebra/zebra_vxlan.h | 3 +- zebra/zebra_vxlan_null.c | 20 +- zebra/zserv.c | 1773 ++++++++++++++++---------------- zebra/zserv.h | 15 +- 16 files changed, 1004 insertions(+), 958 deletions(-) diff --git a/zebra/label_manager.c b/zebra/label_manager.c index 5bf0fce0947d..b58f0c9ff84d 100644 --- a/zebra/label_manager.c +++ b/zebra/label_manager.c @@ -50,6 +50,8 @@ DEFINE_MTYPE_STATIC(LBL_MGR, LM_CHUNK, "Label Manager Chunk"); * it will be a proxy to relay messages to external label manager * This zclient thus is to connect to it */ +static struct stream *ibuf; +static struct stream *obuf; static struct zclient *zclient; bool lm_is_external; @@ -69,7 +71,7 @@ static int relay_response_back(struct zserv *zserv) u_int16_t resp_cmd; src = zclient->ibuf; - dst = zserv->obuf; + dst = obuf; stream_reset(src); @@ -87,7 +89,7 @@ static int relay_response_back(struct zserv *zserv) /* send response back */ stream_copy(dst, src); - ret = writen(zserv->sock, dst->data, stream_get_endp(dst)); + ret = writen(zserv->sock, src->data, stream_get_endp(src)); if (ret <= 0) { zlog_err("%s: Error sending Label Manager response back: %s", __func__, strerror(errno)); @@ -116,10 +118,10 @@ static int lm_zclient_read(struct thread *t) static int reply_error(int cmd, struct zserv *zserv, vrf_id_t vrf_id) { + int ret; struct stream *s; - s = zserv->obuf; - stream_reset(s); + s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, cmd, vrf_id); @@ -129,7 +131,10 @@ static int reply_error(int cmd, struct zserv *zserv, vrf_id_t vrf_id) /* Write packet size. */ stream_putw_at(s, 0, stream_get_endp(s)); - return writen(zserv->sock, s->data, stream_get_endp(s)); + ret = writen(zserv->sock, s->data, stream_get_endp(s)); + + stream_free(s); + return ret; } /** * Receive a request to get or release a label chunk and forward it to external @@ -161,7 +166,7 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv, ret = relay_response_back(zserv); /* Send request to external label manager */ - src = zserv->ibuf; + src = ibuf; dst = zclient->obuf; stream_copy(dst, src); @@ -247,6 +252,9 @@ void label_manager_init(char *lm_zserv_path) lm_is_external = true; lm_zclient_init(lm_zserv_path); } + + ibuf = stream_new(ZEBRA_MAX_PACKET_SIZ); + obuf = stream_new(ZEBRA_MAX_PACKET_SIZ); } /** @@ -379,4 +387,6 @@ int release_daemon_chunks(u_char proto, u_short instance) void label_manager_close() { list_delete_and_null(&lbl_mgr.lc_list); + stream_free(ibuf); + stream_free(obuf); } diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 93862cadc90a..5a239306fbfa 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -249,9 +249,9 @@ void zebra_redistribute_add(ZAPI_HANDLER_ARGS) int type = 0; u_short instance; - STREAM_GETC(client->ibuf, afi); - STREAM_GETC(client->ibuf, type); - STREAM_GETW(client->ibuf, instance); + STREAM_GETC(msg, afi); + STREAM_GETC(msg, type); + STREAM_GETW(msg, instance); if (afi == 0 || afi > AFI_MAX) { zlog_warn("%s: Specified afi %d does not exist", @@ -292,9 +292,9 @@ void zebra_redistribute_delete(ZAPI_HANDLER_ARGS) int type = 0; u_short instance; - STREAM_GETC(client->ibuf, afi); - STREAM_GETC(client->ibuf, type); - STREAM_GETW(client->ibuf, instance); + STREAM_GETC(msg, afi); + STREAM_GETC(msg, type); + STREAM_GETW(msg, instance); if (afi == 0 || afi > AFI_MAX) { zlog_warn("%s: Specified afi %d does not exist", diff --git a/zebra/redistribute.h b/zebra/redistribute.h index 6ca3b57d4dce..e551f820cc18 100644 --- a/zebra/redistribute.h +++ b/zebra/redistribute.h @@ -27,11 +27,12 @@ #include "vty.h" #include "vrf.h" -/* zapi handlers */ +/* ZAPI command 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 *); diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 56decdcdbabe..d0b821bfd21d 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -43,7 +43,6 @@ #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; @@ -802,7 +801,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(ZAPI_HANDLER_ARGS, int set) +static void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int enable) { struct stream *s; ifindex_t ifindex; @@ -810,7 +809,7 @@ void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int set) struct zebra_if *zif; int ra_interval; - s = client->ibuf; + s = msg; /* Get interface index and RA interval. */ STREAM_GETL(s, ifindex); @@ -818,26 +817,27 @@ void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int set) if (IS_ZEBRA_DEBUG_EVENT) zlog_debug("%u: IF %u RA %s from client %s, interval %ds", - zvrf_id(zvrf), ifindex, set ? "enable" : "disable", + zvrf_id(zvrf), ifindex, + enable ? "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, set ? "enable" : "disable", + zvrf_id(zvrf), ifindex, enable ? "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, set ? "enable" : "disable", + zvrf_id(zvrf), ifindex, enable ? "enable" : "disable", zebra_route_string(client->proto), ifp->vrf_id); return; } zif = ifp->info; - if (set) { + if (enable) { SET_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED); ipv6_nd_suppress_ra_set(ifp, RA_ENABLE); if (ra_interval @@ -860,12 +860,11 @@ void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int set) void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS) { - zebra_interface_radv_set(client, hdr, zvrf, 0); + zebra_interface_radv_set(client, hdr, msg, zvrf, 0); } - void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS) { - zebra_interface_radv_set(client, hdr, zvrf, 1); + zebra_interface_radv_set(client, hdr, msg, zvrf, 1); } DEFUN (ipv6_nd_suppress_ra, diff --git a/zebra/rtadv.h b/zebra/rtadv.h index 28019a32378a..8fd67c8a63b3 100644 --- a/zebra/rtadv.h +++ b/zebra/rtadv.h @@ -103,8 +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(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 */ diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 0af06806d348..1868b4676d19 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -455,8 +455,7 @@ static int fec_send(zebra_fec_t *fec, struct zserv *client) rn = fec->rn; /* Get output stream. */ - s = client->obuf; - stream_reset(s); + s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, ZEBRA_FEC_UPDATE, VRF_DEFAULT); @@ -464,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); + return zebra_server_send_message(client, s); } /* diff --git a/zebra/zebra_mroute.c b/zebra/zebra_mroute.c index e70b963cfd1b..042bd3769e77 100644 --- a/zebra/zebra_mroute.c +++ b/zebra/zebra_mroute.c @@ -31,7 +31,6 @@ #include "zebra/zebra_mroute.h" #include "zebra/rt.h" #include "zebra/debug.h" -#include "zebra/zserv.h" void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS) { @@ -40,9 +39,9 @@ void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS) int suc = -1; memset(&mroute, 0, sizeof(mroute)); - STREAM_GET(&mroute.sg.src, client->ibuf, 4); - STREAM_GET(&mroute.sg.grp, client->ibuf, 4); - STREAM_GETL(client->ibuf, mroute.ifindex); + STREAM_GET(&mroute.sg.src, msg, 4); + STREAM_GET(&mroute.sg.grp, msg, 4); + STREAM_GETL(msg, mroute.ifindex); if (IS_ZEBRA_DEBUG_KERNEL) { char sbuf[40]; @@ -57,7 +56,7 @@ void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS) suc = kernel_get_ipmr_sg_stats(zvrf, &mroute); stream_failure: - s = client->obuf; + s = stream_new(ZEBRA_MAX_PACKET_SIZ); stream_reset(s); @@ -68,5 +67,5 @@ void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS) stream_putl(s, suc); stream_putw_at(s, 0, stream_get_endp(s)); - zebra_server_send_message(client); + zebra_server_send_message(client, s); } diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 0c48473aad21..67c7220b6fe7 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -702,7 +702,7 @@ void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS) ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, tmp_buf); - s = client->ibuf; + s = msg; STREAM_GETL(s, pid); sprintf(tmp_buf, "%d", pid); @@ -819,7 +819,6 @@ void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS) stream_failure: ptm_lib_cleanup_msg(ptm_hdl, out_ctxt); - return; } /* BFD peer/dst deregister */ @@ -859,7 +858,7 @@ void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS) ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, tmp_buf); - s = client->ibuf; + s = msg; STREAM_GETL(s, pid); sprintf(tmp_buf, "%d", pid); @@ -950,7 +949,6 @@ void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS) stream_failure: ptm_lib_cleanup_msg(ptm_hdl, out_ctxt); - return; } /* BFD client register */ @@ -968,7 +966,7 @@ void zebra_ptm_bfd_client_register(ZAPI_HANDLER_ARGS) zlog_debug("bfd_client_register msg from client %s: length=%d", zebra_route_string(client->proto), hdr->length); - s = client->ibuf; + s = msg; STREAM_GETL(s, pid); if (ptm_cb.ptm_sock == -1) { diff --git a/zebra/zebra_ptm.h b/zebra/zebra_ptm.h index 22cacd6fc045..0b41410beca6 100644 --- a/zebra/zebra_ptm.h +++ b/zebra/zebra_ptm.h @@ -22,14 +22,14 @@ #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 #define ZEBRA_PTM_BFD_CLIENT_FLAG_REG (1 << 1) /* client registered with BFD */ +#include "zebra/zserv.h" + /* Zebra ptm context block */ struct zebra_ptm_cb { int ptm_sock; /* ptm file descriptor. */ @@ -64,6 +64,7 @@ int zebra_ptm_connect(struct thread *t); void zebra_ptm_write(struct vty *vty); int zebra_ptm_get_enable_state(void); +/* ZAPI message handlers */ 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); diff --git a/zebra/zebra_ptm_redistribute.c b/zebra/zebra_ptm_redistribute.c index 8fddd400cc04..fe788ac4d7b8 100644 --- a/zebra/zebra_ptm_redistribute.c +++ b/zebra/zebra_ptm_redistribute.c @@ -38,8 +38,7 @@ static int zsend_interface_bfd_update(int cmd, struct zserv *client, if (!client->ifinfo) return 0; - s = client->obuf; - stream_reset(s); + s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, cmd, vrf_id); if (ifp) @@ -66,7 +65,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); + return zebra_server_send_message(client, s); } void zebra_interface_bfd_update(struct interface *ifp, struct prefix *dp, @@ -93,8 +92,7 @@ static int zsend_bfd_peer_replay(int cmd, struct zserv *client) { struct stream *s; - s = client->obuf; - stream_reset(s); + s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, cmd, VRF_DEFAULT); @@ -102,7 +100,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); + return zebra_server_send_message(client, s); } void zebra_bfd_peer_replay_req(void) diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index dd3fe17702c0..c9fb782ba615 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -995,8 +995,7 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type, re = rnh->state; /* Get output stream. */ - s = client->obuf; - stream_reset(s); + s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, cmd, vrf_id); @@ -1063,7 +1062,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); + return zebra_server_send_message(client, s); } static void print_nh(struct nexthop *nexthop, struct vty *vty) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index f22d5160fbb9..a8d184872357 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -46,7 +46,6 @@ #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"); @@ -1158,8 +1157,7 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr, if (!client) return 0; - s = client->obuf; - stream_reset(s); + s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, cmd, VRF_DEFAULT); stream_putl(s, vni); @@ -1196,7 +1194,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); + return zebra_server_send_message(client, s); } /* @@ -2566,8 +2564,7 @@ static int zvni_send_add_to_client(zebra_vni_t *zvni) if (!client) return 0; - s = client->obuf; - stream_reset(s); + s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, ZEBRA_VNI_ADD, VRF_DEFAULT); stream_putl(s, zvni->vni); @@ -2584,7 +2581,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); + return zebra_server_send_message(client, s); } /* @@ -2600,7 +2597,7 @@ static int zvni_send_del_to_client(vni_t vni) if (!client) return 0; - s = client->obuf; + s = stream_new(ZEBRA_MAX_PACKET_SIZ); stream_reset(s); zclient_create_header(s, ZEBRA_VNI_DEL, VRF_DEFAULT); @@ -2614,7 +2611,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); + return zebra_server_send_message(client, s); } /* @@ -3551,8 +3548,7 @@ static int zl3vni_send_add_to_client(zebra_l3vni_t *zl3vni) memset(&rmac, 0, sizeof(struct ethaddr)); zl3vni_get_rmac(zl3vni, &rmac); - s = client->obuf; - stream_reset(s); + s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, ZEBRA_L3VNI_ADD, zl3vni_vrf_id(zl3vni)); stream_putl(s, zl3vni->vni); @@ -3575,7 +3571,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); + return zebra_server_send_message(client, s); } /* @@ -3591,8 +3587,7 @@ static int zl3vni_send_del_to_client(zebra_l3vni_t *zl3vni) if (!client) return 0; - s = client->obuf; - stream_reset(s); + s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, ZEBRA_L3VNI_DEL, zl3vni_vrf_id(zl3vni)); stream_putl(s, zl3vni->vni); @@ -3606,7 +3601,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); + return zebra_server_send_message(client, s); } static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni) @@ -3724,8 +3719,7 @@ static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p, if (!client) return 0; - s = client->obuf; - stream_reset(s); + s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, cmd, vrf_id); stream_put(s, p, sizeof(struct prefix)); @@ -3744,7 +3738,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); + return zebra_server_send_message(client, s); } /* re-add remote rmac if needed */ @@ -4884,7 +4878,7 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) memset(&ip, 0, sizeof(struct ipaddr)); memset(&vtep_ip, 0, sizeof(struct in_addr)); - s = client->ibuf; + s = msg; while (l < hdr->length) { /* Obtain each remote MACIP and process. */ @@ -5047,7 +5041,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) return; } - s = client->ibuf; + s = msg; while (l < hdr->length) { /* Obtain each remote MACIP and process. */ @@ -5566,7 +5560,7 @@ void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS) return; } - s = client->ibuf; + s = msg; while (l < hdr->length) { /* Obtain each remote VTEP and process. */ @@ -5650,7 +5644,7 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS) return; } - s = client->ibuf; + s = msg; while (l < hdr->length) { /* Obtain each remote VTEP and process. */ @@ -6526,7 +6520,7 @@ void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS) return; } - s = client->ibuf; + s = msg; advertise = stream_getc(s); vni = stream_get3(s); @@ -6566,8 +6560,6 @@ void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS) zvni_advertise_subnet(zvni, vlan_if, 1); else zvni_advertise_subnet(zvni, vlan_if, 0); - - return; } /* @@ -6588,7 +6580,7 @@ void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS) return; } - s = client->ibuf; + s = msg; STREAM_GETC(s, advertise); STREAM_GET(&vni, s, 3); @@ -6620,7 +6612,7 @@ void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS) zvni = zvni_lookup(vni); if (!zvni) - return; + return 0; if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( @@ -6682,7 +6674,6 @@ void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS) * uninstalled from the kernel. */ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) - { struct stream *s = NULL; int advertise = 0; @@ -6693,7 +6684,7 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) return; } - s = client->ibuf; + s = msg; STREAM_GETC(s, advertise); if (IS_ZEBRA_DEBUG_VXLAN) diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index 62c6519d50b2..6f25ad1e24ae 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -52,7 +52,7 @@ static inline int is_evpn_enabled() #define VNI_STR_LEN 32 -/* zserv handlers */ +/* ZAPI message handlers */ 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); @@ -61,7 +61,6 @@ 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); extern int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf); diff --git a/zebra/zebra_vxlan_null.c b/zebra/zebra_vxlan_null.c index e6a3dd674ebe..1bac2cafb6b1 100644 --- a/zebra/zebra_vxlan_null.c +++ b/zebra/zebra_vxlan_null.c @@ -117,14 +117,14 @@ int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if) return 0; } -void zebra_vxlan_remote_macip_add(struct zserv *client, int sock, - u_short length, struct zebra_vrf *zvrf) +int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length, + struct zebra_vrf *zvrf) { return 0; } -void zebra_vxlan_remote_macip_del(struct zserv *client, int sock, - u_short length, struct zebra_vrf *zvrf) +int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length, + struct zebra_vrf *zvrf) { return 0; } @@ -182,20 +182,20 @@ int zebra_vxlan_if_del(struct interface *ifp) return 0; } -void zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length, - struct zebra_vrf *zvrf) +int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length, + struct zebra_vrf *zvrf) { return 0; } -void zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length, - struct zebra_vrf *zvrf) +int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length, + struct zebra_vrf *zvrf) { return 0; } -void zebra_vxlan_advertise_all_vni(struct zserv *client, int sock, - u_short length, struct zebra_vrf *zvrf) +int zebra_vxlan_advertise_all_vni(struct zserv *client, int sock, + u_short length, struct zebra_vrf *zvrf) { return 0; } diff --git a/zebra/zserv.c b/zebra/zserv.c index 127913a63a63..ac2fe9c0e219 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -63,94 +63,23 @@ #include "zebra/zebra_pbr.h" /* Event list of zebra. */ -enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE }; - -static void zebra_event(enum event event, int sock, struct zserv *client); - +enum event { ZEBRA_READ, ZEBRA_WRITE }; +/* privileges */ extern struct zebra_privs_t zserv_privs; +/* post event into client */ +static void zebra_event(struct zserv *client, enum event event); -static void zebra_client_close(struct zserv *client); - -static int zserv_delayed_close(struct thread *thread) -{ - struct zserv *client = THREAD_ARG(thread); - client->t_suicide = NULL; - zebra_client_close(client); - return 0; -} +/* Public interface ======================================================== */ -static int zserv_flush_data(struct thread *thread) +int zebra_server_send_message(struct zserv *client, struct stream *msg) { - struct zserv *client = THREAD_ARG(thread); - - client->t_write = NULL; - if (client->t_suicide) { - zebra_client_close(client); - return -1; - } - switch (buffer_flush_available(client->wb, client->sock)) { - case BUFFER_ERROR: - zlog_warn( - "%s: buffer_flush_available failed on zserv client fd %d, " - "closing", - __func__, client->sock); - zebra_client_close(client); - client = NULL; - break; - case BUFFER_PENDING: - client->t_write = NULL; - thread_add_write(zebrad.master, zserv_flush_data, client, - client->sock, &client->t_write); - break; - case BUFFER_EMPTY: - break; - } - - if (client) - client->last_write_time = monotime(NULL); + stream_fifo_push(client->obuf_fifo, msg); + zebra_event(client, ZEBRA_WRITE); return 0; } -int zebra_server_send_message(struct zserv *client) -{ - if (client->t_suicide) - return -1; - - if (client->is_synchronous) - return 0; - - stream_set_getp(client->obuf, 0); - client->last_write_cmd = stream_getw_from(client->obuf, 6); - switch (buffer_write(client->wb, client->sock, - STREAM_DATA(client->obuf), - stream_get_endp(client->obuf))) { - case BUFFER_ERROR: - zlog_warn( - "%s: buffer_write failed to zserv client fd %d, closing", - __func__, client->sock); - /* Schedule a delayed close since many of the functions that - call this - one do not check the return code. They do not allow for the - possibility that an I/O error may have caused the client to - be - deleted. */ - client->t_suicide = NULL; - thread_add_event(zebrad.master, zserv_delayed_close, client, 0, - &client->t_suicide); - return -1; - case BUFFER_EMPTY: - THREAD_OFF(client->t_write); - break; - case BUFFER_PENDING: - thread_add_write(zebrad.master, zserv_flush_data, client, - client->sock, &client->t_write); - break; - } - - client->last_write_time = monotime(NULL); - return 0; -} +/* Encoding helpers -------------------------------------------------------- */ static void zserv_encode_interface(struct stream *s, struct interface *ifp) { @@ -202,6 +131,34 @@ static void zserv_encode_vrf(struct stream *s, struct zebra_vrf *zvrf) stream_putw_at(s, 0, stream_get_endp(s)); } +static int zserv_encode_nexthop(struct stream *s, struct nexthop *nexthop) +{ + stream_putc(s, nexthop->type); + switch (nexthop->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + stream_put_in_addr(s, &nexthop->gate.ipv4); + stream_putl(s, nexthop->ifindex); + break; + case NEXTHOP_TYPE_IPV6: + stream_put(s, &nexthop->gate.ipv6, 16); + break; + case NEXTHOP_TYPE_IPV6_IFINDEX: + stream_put(s, &nexthop->gate.ipv6, 16); + stream_putl(s, nexthop->ifindex); + break; + case NEXTHOP_TYPE_IFINDEX: + stream_putl(s, nexthop->ifindex); + break; + default: + /* do nothing */ + break; + } + return 1; +} + +/* Send handlers ----------------------------------------------------------- */ + /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */ /* * This function is called in the following situations: @@ -215,65 +172,54 @@ static void zserv_encode_vrf(struct stream *s, struct zebra_vrf *zvrf) */ int zsend_interface_add(struct zserv *client, struct interface *ifp) { - struct stream *s; - - s = client->obuf; - stream_reset(s); + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, ZEBRA_INTERFACE_ADD, ifp->vrf_id); zserv_encode_interface(s, ifp); client->ifadd_cnt++; - return zebra_server_send_message(client); + return zebra_server_send_message(client, s); } /* Interface deletion from zebra daemon. */ int zsend_interface_delete(struct zserv *client, struct interface *ifp) { - struct stream *s; - - s = client->obuf; - stream_reset(s); + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id); zserv_encode_interface(s, ifp); client->ifdel_cnt++; - return zebra_server_send_message(client); + return zebra_server_send_message(client, s); } int zsend_vrf_add(struct zserv *client, struct zebra_vrf *zvrf) { - struct stream *s; - - s = client->obuf; - stream_reset(s); + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, ZEBRA_VRF_ADD, zvrf_id(zvrf)); zserv_encode_vrf(s, zvrf); client->vrfadd_cnt++; - return zebra_server_send_message(client); + return zebra_server_send_message(client, s); } /* VRF deletion from zebra daemon. */ int zsend_vrf_delete(struct zserv *client, struct zebra_vrf *zvrf) -{ - struct stream *s; - s = client->obuf; - stream_reset(s); +{ + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, ZEBRA_VRF_DELETE, zvrf_id(zvrf)); zserv_encode_vrf(s, zvrf); client->vrfdel_cnt++; - return zebra_server_send_message(client); + return zebra_server_send_message(client, s); } int zsend_interface_link_params(struct zserv *client, struct interface *ifp) { - struct stream *s; + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); /* Check this client need interface information. */ if (!client->ifinfo) @@ -281,8 +227,6 @@ int zsend_interface_link_params(struct zserv *client, struct interface *ifp) if (!ifp->link_params) return 0; - s = client->obuf; - stream_reset(s); zclient_create_header(s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf_id); @@ -296,7 +240,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); + return zebra_server_send_message(client, s); } /* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or @@ -341,11 +285,8 @@ int zsend_interface_address(int cmd, struct zserv *client, struct interface *ifp, struct connected *ifc) { int blen; - struct stream *s; struct prefix *p; - - s = client->obuf; - stream_reset(s); + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, cmd, ifp->vrf_id); stream_putl(s, ifp->ifindex); @@ -378,7 +319,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); + return zebra_server_send_message(client, s); } static int zsend_interface_nbr_address(int cmd, struct zserv *client, @@ -386,12 +327,9 @@ static int zsend_interface_nbr_address(int cmd, struct zserv *client, struct nbr_connected *ifc) { int blen; - struct stream *s; + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); struct prefix *p; - s = client->obuf; - stream_reset(s); - zclient_create_header(s, cmd, ifp->vrf_id); stream_putl(s, ifp->ifindex); @@ -412,7 +350,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); + return zebra_server_send_message(client, s); } /* Interface address addition. */ @@ -498,10 +436,7 @@ int zsend_interface_addresses(struct zserv *client, struct interface *ifp) int zsend_interface_vrf_update(struct zserv *client, struct interface *ifp, vrf_id_t vrf_id) { - struct stream *s; - - s = client->obuf; - stream_reset(s); + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id); @@ -513,7 +448,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); + return zebra_server_send_message(client, s); } /* Add new nbr connected IPv6 address */ @@ -575,10 +510,7 @@ void nbr_connected_delete_ipv6(struct interface *ifp, struct in6_addr *address) */ int zsend_interface_update(int cmd, struct zserv *client, struct interface *ifp) { - struct stream *s; - - s = client->obuf; - stream_reset(s); + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, cmd, ifp->vrf_id); zserv_encode_interface(s, ifp); @@ -588,7 +520,7 @@ int zsend_interface_update(int cmd, struct zserv *client, struct interface *ifp) else client->ifdown_cnt++; - return zebra_server_send_message(client); + return zebra_server_send_message(client, s); } int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p, @@ -660,134 +592,342 @@ int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p, SET_FLAG(api.message, ZAPI_MESSAGE_MTU); api.mtu = re->mtu; + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); + /* Encode route and send. */ - if (zapi_route_encode(cmd, client->obuf, &api) < 0) + if (zapi_route_encode(cmd, s, &api) < 0) return -1; - return zebra_server_send_message(client); -} - -static int zsend_write_nexthop(struct stream *s, struct nexthop *nexthop) -{ - stream_putc(s, nexthop->type); - switch (nexthop->type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - stream_put_in_addr(s, &nexthop->gate.ipv4); - stream_putl(s, nexthop->ifindex); - break; - case NEXTHOP_TYPE_IPV6: - stream_put(s, &nexthop->gate.ipv6, 16); - break; - case NEXTHOP_TYPE_IPV6_IFINDEX: - stream_put(s, &nexthop->gate.ipv6, 16); - stream_putl(s, nexthop->ifindex); - break; - case NEXTHOP_TYPE_IFINDEX: - stream_putl(s, nexthop->ifindex); - break; - default: - /* do nothing */ - break; - } - return 1; + return zebra_server_send_message(client, s); } -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(ZAPI_HANDLER_ARGS) +/* + * Modified version of zsend_ipv4_nexthop_lookup(): Query unicast rib if + * nexthop is not found on mrib. Returns both route metric and protocol + * distance. + */ +static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client, + struct in_addr addr, + struct route_entry *re, + struct zebra_vrf *zvrf) { - 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), hdr->length, - (type == RNH_NEXTHOP_TYPE) ? "nexthop" : "route"); + unsigned long nump; + u_char num; + struct nexthop *nexthop; - s = client->ibuf; + /* Get output stream. */ + s = stream_new(ZEBRA_MAX_PACKET_SIZ); + stream_reset(s); - client->nh_reg_time = monotime(NULL); + /* Fill in result. */ + zclient_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id(zvrf)); + stream_put_in_addr(s, &addr); - while (l < hdr->length) { - STREAM_GETC(s, flags); - STREAM_GETW(s, p.family); - STREAM_GETC(s, p.prefixlen); - l += 4; - if (p.family == AF_INET) { - if (p.prefixlen > IPV4_MAX_BITLEN) { - zlog_warn( - "%s: Specified prefix length %d is too large for a v4 address", - __PRETTY_FUNCTION__, p.prefixlen); - return; - } - STREAM_GET(&p.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN); - l += IPV4_MAX_BYTELEN; - } else if (p.family == AF_INET6) { - if (p.prefixlen > IPV6_MAX_BITLEN) { - zlog_warn( - "%s: Specified prefix length %d is to large for a v6 address", - __PRETTY_FUNCTION__, p.prefixlen); - return; - } - STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN); - l += IPV6_MAX_BYTELEN; - } else { - zlog_err( - "rnh_register: Received unknown family type %d\n", - p.family); - return; - } - rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type); - if (type == RNH_NEXTHOP_TYPE) { - if (flags - && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) - SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED); - else if (!flags - && CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) - UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED); - } else if (type == RNH_IMPORT_CHECK_TYPE) { - if (flags - && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH)) - SET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH); - else if (!flags && CHECK_FLAG(rnh->flags, - ZEBRA_NHT_EXACT_MATCH)) - UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH); - } + if (re) { + stream_putc(s, re->distance); + stream_putl(s, re->metric); + num = 0; + nump = stream_get_endp( + s); /* remember position for nexthop_num */ + stream_putc(s, 0); /* reserve room for nexthop_num */ + /* Only non-recursive routes are elegible to resolve the nexthop + * we + * are looking up. Therefore, we will just iterate over the top + * chain of nexthops. */ + for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next) + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + num += zsend_write_nexthop(s, nexthop); - zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf)); - /* Anything not AF_INET/INET6 has been filtered out above */ - zebra_evaluate_rnh(zvrf_id(zvrf), p.family, 1, type, &p); + stream_putc_at(s, nump, num); /* store nexthop_num */ + } else { + stream_putc(s, 0); /* distance */ + stream_putl(s, 0); /* metric */ + stream_putc(s, 0); /* nexthop_num */ } -stream_failure: - return; + stream_putw_at(s, 0, stream_get_endp(s)); + + return zebra_server_send_message(client, s); } -/* Nexthop register */ -static void zserv_rnh_unregister(ZAPI_HANDLER_ARGS) +int zsend_route_notify_owner(struct route_entry *re, struct prefix *p, + enum zapi_route_notify_owner note) { - struct rnh *rnh; + struct zserv *client; struct stream *s; - struct prefix p; - u_short l = 0; - uint16_t type = cmd2type[hdr->command]; + uint8_t blen; - if (IS_ZEBRA_DEBUG_NHT) - zlog_debug("rnh_unregister msg from client %s: length=%d\n", - zebra_route_string(client->proto), hdr->length); + client = zebra_find_client(re->type, re->instance); + if (!client || !client->notify_owner) { + if (IS_ZEBRA_DEBUG_PACKET) { + char buff[PREFIX_STRLEN]; - s = client->ibuf; + zlog_debug( + "Not Notifying Owner: %u about prefix %s(%u) %d", + re->type, prefix2str(p, buff, sizeof(buff)), + re->table, note); + } + return 0; + } + + if (IS_ZEBRA_DEBUG_PACKET) { + char buff[PREFIX_STRLEN]; + + zlog_debug("Notifying Owner: %u about prefix %s(%u) %d", + re->type, prefix2str(p, buff, sizeof(buff)), + re->table, note); + } + + s = stream_new(ZEBRA_MAX_PACKET_SIZ); + stream_reset(s); + + zclient_create_header(s, ZEBRA_ROUTE_NOTIFY_OWNER, re->vrf_id); + + stream_put(s, ¬e, sizeof(note)); + + stream_putc(s, p->family); + + blen = prefix_blen(p); + stream_putc(s, p->prefixlen); + stream_put(s, &p->u.prefix, blen); + + stream_putl(s, re->table); + + stream_putw_at(s, 0, stream_get_endp(s)); + + return zebra_server_send_message(client, s); +} + +void zsend_rule_notify_owner(struct zebra_pbr_rule *rule, + enum zapi_rule_notify_owner note) +{ + struct listnode *node; + struct zserv *client; + struct stream *s; + + if (IS_ZEBRA_DEBUG_PACKET) { + zlog_debug("%s: Notifying %u", + __PRETTY_FUNCTION__, rule->unique); + } + + for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) { + if (rule->sock == client->sock) + break; + } + + if (!client) + return; + + s = stream_new(ZEBRA_MAX_PACKET_SIZ); + stream_reset(s); + + zclient_create_header(s, ZEBRA_RULE_NOTIFY_OWNER, VRF_DEFAULT); + stream_put(s, ¬e, sizeof(note)); + stream_putl(s, rule->seq); + stream_putl(s, rule->priority); + stream_putl(s, rule->unique); + if (rule->ifp) + stream_putl(s, rule->ifp->ifindex); + else + stream_putl(s, 0); + + stream_putw_at(s, 0, stream_get_endp(s)); + + zebra_server_send_message(client, s); +} + +/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */ +int zsend_router_id_update(struct zserv *client, struct prefix *p, + vrf_id_t vrf_id) +{ + int blen; + + /* Check this client need interface information. */ + if (!vrf_bitmap_check(client->ridinfo, vrf_id)) + return 0; + + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); + + /* Message type. */ + zclient_create_header(s, ZEBRA_ROUTER_ID_UPDATE, vrf_id); + + /* Prefix information. */ + stream_putc(s, p->family); + blen = prefix_blen(p); + stream_put(s, &p->u.prefix, blen); + stream_putc(s, p->prefixlen); + + /* Write packet size. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + return zebra_server_send_message(client, s); +} + +/* + * Function used by Zebra to send a PW status update to LDP daemon + */ +int zsend_pw_update(struct zserv *client, struct zebra_pw *pw) +{ + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); + + zclient_create_header(s, ZEBRA_PW_STATUS_UPDATE, pw->vrf_id); + stream_write(s, pw->ifname, IF_NAMESIZE); + stream_putl(s, pw->ifindex); + stream_putl(s, pw->status); + + /* 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); +} + +/* Send response to a get label chunk request to client */ +static int zsend_assign_label_chunk_response(struct zserv *client, + vrf_id_t vrf_id, + struct label_manager_chunk *lmc) +{ + int ret; + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); + + zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, vrf_id); + + if (lmc) { + /* keep */ + stream_putc(s, lmc->keep); + /* start and end labels */ + stream_putl(s, lmc->start); + stream_putl(s, lmc->end); + } + + /* Write packet size. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + ret = writen(client->sock, s->data, stream_get_endp(s)); + stream_free(s); + return ret; +} + +/* Send response to a label manager connect request to client */ +static int zsend_label_manager_connect_response(struct zserv *client, + vrf_id_t vrf_id, u_short result) +{ + int ret; + struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); + + zclient_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, vrf_id); + + /* result */ + stream_putc(s, result); + + /* Write packet size. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + ret = writen(client->sock, s->data, stream_get_endp(s)); + stream_free(s); + + return ret; +} + +/* Inbound message handling ------------------------------------------------ */ + +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 zread_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: hdr->length=%d, type=%s\n", + zebra_route_string(client->proto), hdr->length, + (type == RNH_NEXTHOP_TYPE) ? "nexthop" : "route"); + + s = msg; + + client->nh_reg_time = monotime(NULL); + + while (l < hdr->length) { + STREAM_GETC(s, flags); + STREAM_GETW(s, p.family); + STREAM_GETC(s, p.prefixlen); + l += 4; + if (p.family == AF_INET) { + if (p.prefixlen > IPV4_MAX_BITLEN) { + zlog_warn( + "%s: Specified prefix hdr->length %d is too large for a v4 address", + __PRETTY_FUNCTION__, p.prefixlen); + return; + } + STREAM_GET(&p.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN); + l += IPV4_MAX_BYTELEN; + } else if (p.family == AF_INET6) { + if (p.prefixlen > IPV6_MAX_BITLEN) { + zlog_warn( + "%s: Specified prefix hdr->length %d is to large for a v6 address", + __PRETTY_FUNCTION__, p.prefixlen); + return; + } + STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN); + l += IPV6_MAX_BYTELEN; + } else { + zlog_err( + "rnh_register: Received unknown family type %d\n", + p.family); + return; + } + rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type); + if (type == RNH_NEXTHOP_TYPE) { + if (flags + && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) + SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED); + else if (!flags + && CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) + UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED); + } else if (type == RNH_IMPORT_CHECK_TYPE) { + if (flags + && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH)) + SET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH); + else if (!flags + && CHECK_FLAG(rnh->flags, + ZEBRA_NHT_EXACT_MATCH)) + UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH); + } + + zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf)); + /* Anything not AF_INET/INET6 has been filtered out above */ + zebra_evaluate_rnh(zvrf_id(zvrf), p.family, 1, type, &p); + } + +stream_failure: + return; +} + +/* Nexthop register */ +static void zread_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: hdr->length=%d\n", + zebra_route_string(client->proto), hdr->length); + + s = msg; while (l < hdr->length) { uint8_t flags; @@ -802,7 +942,7 @@ static void zserv_rnh_unregister(ZAPI_HANDLER_ARGS) if (p.family == AF_INET) { if (p.prefixlen > IPV4_MAX_BITLEN) { zlog_warn( - "%s: Specified prefix length %d is to large for a v4 address", + "%s: Specified prefix hdr->length %d is to large for a v4 address", __PRETTY_FUNCTION__, p.prefixlen); return; } @@ -811,7 +951,7 @@ static void zserv_rnh_unregister(ZAPI_HANDLER_ARGS) } else if (p.family == AF_INET6) { if (p.prefixlen > IPV6_MAX_BITLEN) { zlog_warn( - "%s: Specified prefix length %d is to large for a v6 address", + "%s: Specified prefix hdr->length %d is to large for a v6 address", __PRETTY_FUNCTION__, p.prefixlen); return; } @@ -836,18 +976,18 @@ static void zserv_rnh_unregister(ZAPI_HANDLER_ARGS) #define ZEBRA_MIN_FEC_LENGTH 5 /* FEC register */ -static void zserv_fec_register(ZAPI_HANDLER_ARGS) +static void zread_fec_register(ZAPI_HANDLER_ARGS) { struct stream *s; u_short l = 0; struct prefix p; - u_int16_t flags; - u_int32_t label_index = MPLS_INVALID_LABEL_INDEX; + uint16_t flags; + uint32_t label_index = MPLS_INVALID_LABEL_INDEX; - s = client->ibuf; + s = msg; zvrf = vrf_info_lookup(VRF_DEFAULT); if (!zvrf) - return; + return; // unexpected /* * The minimum amount of data that can be sent for one fec @@ -855,7 +995,7 @@ static void zserv_fec_register(ZAPI_HANDLER_ARGS) */ 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", + "fec_register: Received a fec register of hdr->length %d, it is of insufficient size to properly decode", hdr->length); return; } @@ -875,7 +1015,7 @@ static void zserv_fec_register(ZAPI_HANDLER_ARGS) || (p.family == AF_INET6 && p.prefixlen > IPV6_MAX_BITLEN)) { zlog_warn( - "%s: Specified prefix length: %d is to long for %d", + "%s: Specified prefix hdr->length: %d is to long for %d", __PRETTY_FUNCTION__, p.prefixlen, p.family); return; } @@ -895,17 +1035,17 @@ static void zserv_fec_register(ZAPI_HANDLER_ARGS) } /* FEC unregister */ -static void zserv_fec_unregister(ZAPI_HANDLER_ARGS) +static void zread_fec_unregister(ZAPI_HANDLER_ARGS) { struct stream *s; u_short l = 0; struct prefix p; uint16_t flags; - s = client->ibuf; + s = msg; zvrf = vrf_info_lookup(VRF_DEFAULT); if (!zvrf) - return; + return; // unexpected /* * The minimum amount of data that can be sent for one @@ -913,7 +1053,7 @@ static void zserv_fec_unregister(ZAPI_HANDLER_ARGS) */ 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", + "fec_unregister: Received a fec unregister of hdr->length %d, it is of insufficient size to properly decode", hdr->length); return; } @@ -936,7 +1076,7 @@ static void zserv_fec_unregister(ZAPI_HANDLER_ARGS) || (p.family == AF_INET6 && p.prefixlen > IPV6_MAX_BITLEN)) { zlog_warn( - "%s: Received prefix length %d which is greater than %d can support", + "%s: Received prefix hdr->length %d which is greater than %d can support", __PRETTY_FUNCTION__, p.prefixlen, p.family); return; } @@ -950,199 +1090,16 @@ static void zserv_fec_unregister(ZAPI_HANDLER_ARGS) return; } + + /* - Modified version of zsend_ipv4_nexthop_lookup(): - Query unicast rib if nexthop is not found on mrib. - Returns both route metric and protocol distance. -*/ -static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client, - struct in_addr addr, - struct route_entry *re, - struct zebra_vrf *zvrf) + * Register zebra server interface information. + * Send current all interface and address information. + */ +static void zread_interface_add(ZAPI_HANDLER_ARGS) { - struct stream *s; - unsigned long nump; - u_char num; - struct nexthop *nexthop; - - /* Get output stream. */ - s = client->obuf; - stream_reset(s); - - /* Fill in result. */ - zclient_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id(zvrf)); - stream_put_in_addr(s, &addr); - - if (re) { - stream_putc(s, re->distance); - stream_putl(s, re->metric); - num = 0; - nump = stream_get_endp( - s); /* remember position for nexthop_num */ - stream_putc(s, 0); /* reserve room for nexthop_num */ - /* Only non-recursive routes are elegible to resolve the nexthop - * we - * are looking up. Therefore, we will just iterate over the top - * chain of nexthops. */ - for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next) - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) - num += zsend_write_nexthop(s, nexthop); - - stream_putc_at(s, nump, num); /* store nexthop_num */ - } else { - stream_putc(s, 0); /* distance */ - stream_putl(s, 0); /* metric */ - stream_putc(s, 0); /* nexthop_num */ - } - - stream_putw_at(s, 0, stream_get_endp(s)); - - return zebra_server_send_message(client); -} - -int zsend_route_notify_owner(struct route_entry *re, struct prefix *p, - enum zapi_route_notify_owner note) -{ - struct zserv *client; - struct stream *s; - uint8_t blen; - - client = zebra_find_client(re->type, re->instance); - if (!client || !client->notify_owner) { - if (IS_ZEBRA_DEBUG_PACKET) { - char buff[PREFIX_STRLEN]; - - zlog_debug( - "Not Notifying Owner: %u about prefix %s(%u) %d", - re->type, prefix2str(p, buff, sizeof(buff)), - re->table, note); - } - return 0; - } - - if (IS_ZEBRA_DEBUG_PACKET) { - char buff[PREFIX_STRLEN]; - - zlog_debug("Notifying Owner: %u about prefix %s(%u) %d", - re->type, prefix2str(p, buff, sizeof(buff)), - re->table, note); - } - - s = client->obuf; - stream_reset(s); - - zclient_create_header(s, ZEBRA_ROUTE_NOTIFY_OWNER, re->vrf_id); - - stream_put(s, ¬e, sizeof(note)); - - stream_putc(s, p->family); - - blen = prefix_blen(p); - stream_putc(s, p->prefixlen); - stream_put(s, &p->u.prefix, blen); - - stream_putl(s, re->table); - - stream_putw_at(s, 0, stream_get_endp(s)); - - return zebra_server_send_message(client); -} - -void zsend_rule_notify_owner(struct zebra_pbr_rule *rule, - enum zapi_rule_notify_owner note) -{ - struct listnode *node; - struct zserv *client; - struct stream *s; - - if (IS_ZEBRA_DEBUG_PACKET) { - zlog_debug("%s: Notifying %u", - __PRETTY_FUNCTION__, rule->unique); - } - - for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) { - if (rule->sock == client->sock) - break; - } - - if (!client) - return; - - s = client->obuf; - stream_reset(s); - - zclient_create_header(s, ZEBRA_RULE_NOTIFY_OWNER, VRF_DEFAULT); - stream_put(s, ¬e, sizeof(note)); - stream_putl(s, rule->seq); - stream_putl(s, rule->priority); - stream_putl(s, rule->unique); - if (rule->ifp) - stream_putl(s, rule->ifp->ifindex); - else - stream_putl(s, 0); - - stream_putw_at(s, 0, stream_get_endp(s)); - - zebra_server_send_message(client); -} - -/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */ -int zsend_router_id_update(struct zserv *client, struct prefix *p, - vrf_id_t vrf_id) -{ - struct stream *s; - int blen; - - /* Check this client need interface information. */ - if (!vrf_bitmap_check(client->ridinfo, vrf_id)) - return 0; - - s = client->obuf; - stream_reset(s); - - /* Message type. */ - zclient_create_header(s, ZEBRA_ROUTER_ID_UPDATE, vrf_id); - - /* Prefix information. */ - stream_putc(s, p->family); - blen = prefix_blen(p); - stream_put(s, &p->u.prefix, blen); - stream_putc(s, p->prefixlen); - - /* Write packet size. */ - stream_putw_at(s, 0, stream_get_endp(s)); - - return zebra_server_send_message(client); -} - -/* - * Function used by Zebra to send a PW status update to LDP daemon - */ -int zsend_pw_update(struct zserv *client, struct zebra_pw *pw) -{ - struct stream *s; - - s = client->obuf; - stream_reset(s); - - zclient_create_header(s, ZEBRA_PW_STATUS_UPDATE, pw->vrf_id); - stream_write(s, pw->ifname, IF_NAMESIZE); - stream_putl(s, pw->ifindex); - stream_putl(s, pw->status); - - /* Put length at the first point of the stream. */ - stream_putw_at(s, 0, stream_get_endp(s)); - - return zebra_server_send_message(client); -} - -/* Register zebra server interface information. Send current all - interface and address information. */ -static void zread_interface_add(ZAPI_HANDLER_ARGS) - -{ - struct vrf *vrf; - struct interface *ifp; + struct vrf *vrf; + struct interface *ifp; /* Interface information is needed. */ vrf_bitmap_set(client->ifinfo, zvrf_id(zvrf)); @@ -1153,14 +1110,10 @@ static void zread_interface_add(ZAPI_HANDLER_ARGS) if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) continue; - if (zsend_interface_add(client, ifp) < 0) - return; - - if (zsend_interface_addresses(client, ifp) < 0) - return; + zsend_interface_add(client, ifp); + zsend_interface_addresses(client, ifp); } } - return; } /* Unregister zebra server interface information. */ @@ -1193,9 +1146,8 @@ static void zread_route_add(ZAPI_HANDLER_ARGS) int i, ret; vrf_id_t vrf_id = 0; - s = client->ibuf; - if (zapi_route_decode(s, &api) < 0) - return; + s = msg; + zapi_route_decode(s, &api); /* Allocate new route. */ vrf_id = zvrf_id(zvrf); @@ -1342,7 +1294,7 @@ static void zread_route_del(ZAPI_HANDLER_ARGS) afi_t afi; struct prefix_ipv6 *src_p = NULL; - s = client->ibuf; + s = msg; if (zapi_route_decode(s, &api) < 0) return; @@ -1368,8 +1320,6 @@ static void zread_route_del(ZAPI_HANDLER_ARGS) client->v6_route_del_cnt++; break; } - - return; } /* This function support multiple nexthop. */ @@ -1396,7 +1346,7 @@ static void zread_ipv4_add(ZAPI_HANDLER_ARGS) enum blackhole_type bh_type = BLACKHOLE_NULL; /* Get input stream. */ - s = client->ibuf; + s = msg; /* Allocate new re. */ re = XCALLOC(MTYPE_RE, sizeof(struct route_entry)); @@ -1527,7 +1477,6 @@ static void zread_ipv4_add(ZAPI_HANDLER_ARGS) stream_failure: nexthops_free(re->ng.nexthop); XFREE(MTYPE_RE, re); - return; } /* Zebra server IPv4 prefix delete function. */ @@ -1538,7 +1487,7 @@ static void zread_ipv4_delete(ZAPI_HANDLER_ARGS) struct prefix p; u_int32_t table_id; - s = client->ibuf; + s = msg; /* Type, flags, message. */ STREAM_GETC(s, api.type); @@ -1574,10 +1523,9 @@ static void zread_ipv4_nexthop_lookup_mrib(ZAPI_HANDLER_ARGS) struct in_addr addr; struct route_entry *re; - STREAM_GET(&addr.s_addr, client->ibuf, IPV4_MAX_BYTELEN); + STREAM_GET(&addr.s_addr, msg, IPV4_MAX_BYTELEN); re = rib_match_ipv4_multicast(zvrf_id(zvrf), addr, NULL); zsend_ipv4_nexthop_lookup_mrib(client, addr, re, zvrf); - return; stream_failure: return; @@ -1605,7 +1553,7 @@ static void zread_ipv4_route_ipv6_nexthop_add(ZAPI_HANDLER_ARGS) enum blackhole_type bh_type = BLACKHOLE_NULL; /* Get input stream. */ - s = client->ibuf; + s = msg; memset(&nhop_addr, 0, sizeof(struct in6_addr)); @@ -1618,7 +1566,6 @@ static void zread_ipv4_route_ipv6_nexthop_add(ZAPI_HANDLER_ARGS) zlog_warn("%s: Specified route type: %d is not a legal value\n", __PRETTY_FUNCTION__, re->type); XFREE(MTYPE_RE, re); - return; } STREAM_GETW(s, re->instance); @@ -1754,7 +1701,6 @@ static void zread_ipv4_route_ipv6_nexthop_add(ZAPI_HANDLER_ARGS) stream_failure: nexthops_free(re->ng.nexthop); XFREE(MTYPE_RE, re); - return; } static void zread_ipv6_add(ZAPI_HANDLER_ARGS) @@ -1780,7 +1726,7 @@ static void zread_ipv6_add(ZAPI_HANDLER_ARGS) enum blackhole_type bh_type = BLACKHOLE_NULL; /* Get input stream. */ - s = client->ibuf; + s = msg; memset(&nhop_addr, 0, sizeof(struct in6_addr)); @@ -1947,8 +1893,6 @@ static void zread_ipv6_add(ZAPI_HANDLER_ARGS) stream_failure: nexthops_free(re->ng.nexthop); XFREE(MTYPE_RE, re); - - return; } /* Zebra server IPv6 prefix delete function. */ @@ -1959,7 +1903,7 @@ static void zread_ipv6_delete(ZAPI_HANDLER_ARGS) struct prefix p; struct prefix_ipv6 src_p, *src_pp; - s = client->ibuf; + s = msg; /* Type, flags, message. */ STREAM_GETC(s, api.type); @@ -2020,9 +1964,9 @@ static void zread_hello(ZAPI_HANDLER_ARGS) u_short instance; u_char notify; - STREAM_GETC(client->ibuf, proto); - STREAM_GETW(client->ibuf, instance); - STREAM_GETC(client->ibuf, notify); + STREAM_GETC(msg, proto); + STREAM_GETW(msg, instance); + STREAM_GETC(msg, notify); if (notify) client->notify_owner = true; @@ -2068,7 +2012,7 @@ static void zread_mpls_labels(ZAPI_HANDLER_ARGS) u_int8_t distance; /* Get input stream. */ - s = client->ibuf; + s = msg; /* Get data. */ STREAM_GETC(s, type); @@ -2139,27 +2083,9 @@ static void zread_mpls_labels(ZAPI_HANDLER_ARGS) stream_failure: return; } -/* Send response to a label manager connect request to client */ -static int zsend_label_manager_connect_response(struct zserv *client, - vrf_id_t vrf_id, u_short result) -{ - struct stream *s; - - s = client->obuf; - stream_reset(s); - - zclient_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, vrf_id); - - /* result */ - stream_putc(s, result); - - /* Write packet size. */ - stream_putw_at(s, 0, stream_get_endp(s)); - - return writen(client->sock, s->data, stream_get_endp(s)); -} -static void zread_label_manager_connect(struct zserv *client, vrf_id_t vrf_id) +static void zread_label_manager_connect(struct zserv *client, + struct stream *msg, vrf_id_t vrf_id) { struct stream *s; /* type of protocol (lib/zebra.h) */ @@ -2167,7 +2093,7 @@ static void zread_label_manager_connect(struct zserv *client, vrf_id_t vrf_id) u_short instance; /* Get input stream. */ - s = client->ibuf; + s = msg; /* Get data. */ STREAM_GETC(s, proto); @@ -2200,33 +2126,9 @@ static void zread_label_manager_connect(struct zserv *client, vrf_id_t vrf_id) stream_failure: return; } -/* Send response to a get label chunk request to client */ -static int zsend_assign_label_chunk_response(struct zserv *client, - vrf_id_t vrf_id, - struct label_manager_chunk *lmc) -{ - struct stream *s; - - s = client->obuf; - stream_reset(s); - - zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, vrf_id); - - if (lmc) { - /* keep */ - stream_putc(s, lmc->keep); - /* start and end labels */ - stream_putl(s, lmc->start); - stream_putl(s, lmc->end); - } - - /* Write packet size. */ - stream_putw_at(s, 0, stream_get_endp(s)); - - return writen(client->sock, s->data, stream_get_endp(s)); -} -static void zread_get_label_chunk(struct zserv *client, vrf_id_t vrf_id) +static void zread_get_label_chunk(struct zserv *client, struct stream *msg, + vrf_id_t vrf_id) { struct stream *s; u_char keep; @@ -2234,7 +2136,7 @@ static void zread_get_label_chunk(struct zserv *client, vrf_id_t vrf_id) struct label_manager_chunk *lmc; /* Get input stream. */ - s = client->ibuf; + s = msg; /* Get data. */ STREAM_GETC(s, keep); @@ -2254,13 +2156,13 @@ static void zread_get_label_chunk(struct zserv *client, vrf_id_t vrf_id) return; } -static void zread_release_label_chunk(struct zserv *client) +static void zread_release_label_chunk(struct zserv *client, struct stream *msg) { struct stream *s; uint32_t start, end; /* Get input stream. */ - s = client->ibuf; + s = msg; /* Get data. */ STREAM_GETL(s, start); @@ -2284,7 +2186,7 @@ static void zread_label_manager_request(ZAPI_HANDLER_ARGS) /* this is a label manager */ else { if (hdr->command == ZEBRA_LABEL_MANAGER_CONNECT) - zread_label_manager_connect(client, zvrf_id(zvrf)); + zread_label_manager_connect(client, msg, zvrf_id(zvrf)); else { /* Sanity: don't allow 'unidentified' requests */ if (!client->proto) { @@ -2293,9 +2195,10 @@ static void zread_label_manager_request(ZAPI_HANDLER_ARGS) return; } if (hdr->command == ZEBRA_GET_LABEL_CHUNK) - zread_get_label_chunk(client, zvrf_id(zvrf)); + zread_get_label_chunk(client, msg, + zvrf_id(zvrf)); else if (hdr->command == ZEBRA_RELEASE_LABEL_CHUNK) - zread_release_label_chunk(client); + zread_release_label_chunk(client, msg); } } } @@ -2316,7 +2219,7 @@ static void zread_pseudowire(ZAPI_HANDLER_ARGS) struct zebra_pw *pw; /* Get input stream. */ - s = client->ibuf; + s = msg; /* Get data. */ STREAM_GET(ifname, s, IF_NAMESIZE); @@ -2413,116 +2316,11 @@ static void zebra_client_close_cleanup_rnh(struct zserv *client) } } -/* free zebra client information. */ -static void zebra_client_free(struct zserv *client) -{ - /* Send client de-registration to BFD */ - zebra_ptm_bfd_client_deregister(client->proto); - - /* Cleanup any registered nexthops - across all VRFs. */ - zebra_client_close_cleanup_rnh(client); - - /* Release Label Manager chunks */ - release_daemon_chunks(client->proto, client->instance); - - /* Cleanup any FECs registered by this client. */ - zebra_mpls_cleanup_fecs_for_client(vrf_info_lookup(VRF_DEFAULT), - client); - - /* Remove pseudowires associated with this client */ - zebra_pw_client_close(client); - - /* Close file descriptor. */ - if (client->sock) { - unsigned long nroutes; - - close(client->sock); - nroutes = rib_score_proto(client->proto, client->instance); - zlog_notice( - "client %d disconnected. %lu %s routes removed from the rib", - client->sock, nroutes, - zebra_route_string(client->proto)); - client->sock = -1; - } - - /* Free stream buffers. */ - if (client->ibuf) - stream_free(client->ibuf); - if (client->obuf) - stream_free(client->obuf); - if (client->wb) - buffer_free(client->wb); - - /* Release threads. */ - if (client->t_read) - thread_cancel(client->t_read); - if (client->t_write) - thread_cancel(client->t_write); - if (client->t_suicide) - thread_cancel(client->t_suicide); - - /* Free bitmaps. */ - for (afi_t afi = AFI_IP; afi < AFI_MAX; afi++) - for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) - vrf_bitmap_free(client->redist[afi][i]); - - vrf_bitmap_free(client->redist_default); - vrf_bitmap_free(client->ifinfo); - vrf_bitmap_free(client->ridinfo); - - XFREE(MTYPE_TMP, client); -} - -static void zebra_client_close(struct zserv *client) -{ - listnode_delete(zebrad.client_list, client); - zebra_client_free(client); -} - -/* Make new client. */ -static void zebra_client_create(int sock) -{ - struct zserv *client; - int i; - afi_t afi; - - client = XCALLOC(MTYPE_TMP, sizeof(struct zserv)); - - /* Make client input/output buffer. */ - client->sock = sock; - client->ibuf = stream_new(ZEBRA_MAX_PACKET_SIZ); - client->obuf = stream_new(ZEBRA_MAX_PACKET_SIZ); - client->wb = buffer_new(0); - - /* Set table number. */ - client->rtm_table = zebrad.rtm_table_default; - - client->connect_time = monotime(NULL); - /* Initialize flags */ - for (afi = AFI_IP; afi < AFI_MAX; afi++) - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - client->redist[afi][i] = vrf_bitmap_init(); - client->redist_default = vrf_bitmap_init(); - client->ifinfo = vrf_bitmap_init(); - client->ridinfo = vrf_bitmap_init(); - - /* by default, it's not a synchronous client */ - client->is_synchronous = 0; - - /* Add this client to linked list. */ - listnode_add(zebrad.client_list, client); - - /* Make new read thread. */ - zebra_event(ZEBRA_READ, sock, client); - - zebra_vrf_update_all(client); -} - static void zread_interface_set_master(ZAPI_HANDLER_ARGS) { struct interface *master; struct interface *slave; - struct stream *s = client->ibuf; + struct stream *s = msg; int ifindex; vrf_id_t vrf_id; @@ -2553,7 +2351,7 @@ static void zread_vrf_label(ZAPI_HANDLER_ARGS) struct zebra_vrf *def_zvrf; enum lsp_types_t ltype; - s = client->ibuf; + s = msg; STREAM_GETL(s, nlabel); STREAM_GETC(s, afi); if (nlabel == zvrf->label[afi]) { @@ -2619,146 +2417,365 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS) uint32_t total, i; ifindex_t ifindex; - s = client->ibuf; - STREAM_GETL(s, total); + s = msg; + STREAM_GETL(s, total); + + for (i = 0; i < total; i++) { + memset(&zpr, 0, sizeof(zpr)); + + zpr.sock = client->sock; + STREAM_GETL(s, zpr.seq); + STREAM_GETL(s, zpr.priority); + STREAM_GETL(s, zpr.unique); + STREAM_GETC(s, zpr.filter.src_ip.family); + STREAM_GETC(s, zpr.filter.src_ip.prefixlen); + STREAM_GET(&zpr.filter.src_ip.u.prefix, s, + prefix_blen(&zpr.filter.src_ip)); + STREAM_GETW(s, zpr.filter.src_port); + STREAM_GETC(s, zpr.filter.dst_ip.family); + STREAM_GETC(s, zpr.filter.dst_ip.prefixlen); + STREAM_GET(&zpr.filter.dst_ip.u.prefix, s, + prefix_blen(&zpr.filter.dst_ip)); + STREAM_GETW(s, zpr.filter.dst_port); + STREAM_GETL(s, zpr.action.table); + STREAM_GETL(s, ifindex); + + zpr.ifp = if_lookup_by_index(ifindex, VRF_UNKNOWN); + if (!zpr.ifp) { + zlog_debug("FAiled to lookup ifindex: %u", ifindex); + return; + } + + if (!is_default_prefix(&zpr.filter.src_ip)) + zpr.filter.filter_bm |= PBR_FILTER_SRC_IP; + + if (!is_default_prefix(&zpr.filter.dst_ip)) + zpr.filter.filter_bm |= PBR_FILTER_DST_IP; + + if (zpr.filter.src_port) + zpr.filter.filter_bm |= PBR_FILTER_SRC_PORT; + + if (zpr.filter.dst_port) + zpr.filter.filter_bm |= PBR_FILTER_DST_PORT; + + if (hdr->command == ZEBRA_RULE_ADD) + zebra_pbr_add_rule(zvrf->zns, &zpr); + else + zebra_pbr_del_rule(zvrf->zns, &zpr); + } + +stream_failure: + return; +} + +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] = zread_rnh_register, + [ZEBRA_NEXTHOP_UNREGISTER] = zread_rnh_unregister, + [ZEBRA_IMPORT_ROUTE_REGISTER] = zread_rnh_register, + [ZEBRA_IMPORT_ROUTE_UNREGISTER] = zread_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] = zread_fec_register, + [ZEBRA_FEC_UNREGISTER] = zread_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, + struct zmsghdr *hdr, + struct stream *msg, + struct zebra_vrf *zvrf) +{ + 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, msg, zvrf); + + stream_free(msg); +} + +/* Lifecycle ---------------------------------------------------------------- */ + +/* free zebra client information. */ +static void zebra_client_free(struct zserv *client) +{ + /* Send client de-registration to BFD */ + zebra_ptm_bfd_client_deregister(client->proto); + + /* Cleanup any registered nexthops - across all VRFs. */ + zebra_client_close_cleanup_rnh(client); + + /* Release Label Manager chunks */ + release_daemon_chunks(client->proto, client->instance); + + /* Cleanup any FECs registered by this client. */ + zebra_mpls_cleanup_fecs_for_client(vrf_info_lookup(VRF_DEFAULT), + client); + + /* Remove pseudowires associated with this client */ + zebra_pw_client_close(client); + + /* Close file descriptor. */ + if (client->sock) { + unsigned long nroutes; + + close(client->sock); + nroutes = rib_score_proto(client->proto, client->instance); + zlog_notice( + "client %d disconnected. %lu %s routes removed from the rib", + client->sock, nroutes, + zebra_route_string(client->proto)); + client->sock = -1; + } + + /* Free stream buffers. */ + if (client->ibuf_work) + stream_free(client->ibuf_work); + if (client->obuf_work) + stream_free(client->obuf_work); + if (client->ibuf_fifo) + stream_fifo_free(client->ibuf_fifo); + if (client->obuf_fifo) + stream_fifo_free(client->obuf_fifo); + if (client->wb) + buffer_free(client->wb); + + /* Release threads. */ + if (client->t_read) + thread_cancel(client->t_read); + if (client->t_write) + thread_cancel(client->t_write); + if (client->t_suicide) + thread_cancel(client->t_suicide); + + /* Free bitmaps. */ + for (afi_t afi = AFI_IP; afi < AFI_MAX; afi++) + for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) + vrf_bitmap_free(client->redist[afi][i]); + + vrf_bitmap_free(client->redist_default); + vrf_bitmap_free(client->ifinfo); + vrf_bitmap_free(client->ridinfo); + + XFREE(MTYPE_TMP, client); +} + +/* + * Called from client thread to terminate itself. + */ +static void zebra_client_close(struct zserv *client) +{ + listnode_delete(zebrad.client_list, client); + zebra_client_free(client); +} + +/* Make new client. */ +static void zebra_client_create(int sock) +{ + struct zserv *client; + int i; + afi_t afi; + + client = XCALLOC(MTYPE_TMP, sizeof(struct zserv)); - for (i = 0; i < total; i++) { - memset(&zpr, 0, sizeof(zpr)); + /* Make client input/output buffer. */ + client->sock = sock; + client->ibuf_fifo = stream_fifo_new(); + client->obuf_fifo = stream_fifo_new(); + client->ibuf_work = stream_new(ZEBRA_MAX_PACKET_SIZ); + client->obuf_work = stream_new(ZEBRA_MAX_PACKET_SIZ); + client->wb = buffer_new(0); - zpr.sock = client->sock; - STREAM_GETL(s, zpr.seq); - STREAM_GETL(s, zpr.priority); - STREAM_GETL(s, zpr.unique); - STREAM_GETC(s, zpr.filter.src_ip.family); - STREAM_GETC(s, zpr.filter.src_ip.prefixlen); - STREAM_GET(&zpr.filter.src_ip.u.prefix, s, - prefix_blen(&zpr.filter.src_ip)); - STREAM_GETW(s, zpr.filter.src_port); - STREAM_GETC(s, zpr.filter.dst_ip.family); - STREAM_GETC(s, zpr.filter.dst_ip.prefixlen); - STREAM_GET(&zpr.filter.dst_ip.u.prefix, s, - prefix_blen(&zpr.filter.dst_ip)); - STREAM_GETW(s, zpr.filter.dst_port); - STREAM_GETL(s, zpr.action.table); - STREAM_GETL(s, ifindex); + /* Set table number. */ + client->rtm_table = zebrad.rtm_table_default; - zpr.ifp = if_lookup_by_index(ifindex, VRF_UNKNOWN); - if (!zpr.ifp) { - zlog_debug("FAiled to lookup ifindex: %u", ifindex); - return; - } + client->connect_time = monotime(NULL); + /* Initialize flags */ + for (afi = AFI_IP; afi < AFI_MAX; afi++) + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) + client->redist[afi][i] = vrf_bitmap_init(); + client->redist_default = vrf_bitmap_init(); + client->ifinfo = vrf_bitmap_init(); + client->ridinfo = vrf_bitmap_init(); - if (!is_default_prefix(&zpr.filter.src_ip)) - zpr.filter.filter_bm |= PBR_FILTER_SRC_IP; + /* by default, it's not a synchronous client */ + client->is_synchronous = 0; - if (!is_default_prefix(&zpr.filter.dst_ip)) - zpr.filter.filter_bm |= PBR_FILTER_DST_IP; + /* Add this client to linked list. */ + listnode_add(zebrad.client_list, client); - if (zpr.filter.src_port) - zpr.filter.filter_bm |= PBR_FILTER_SRC_PORT; + zebra_vrf_update_all(client); - if (zpr.filter.dst_port) - zpr.filter.filter_bm |= PBR_FILTER_DST_PORT; + /* start read loop */ + zebra_event(client, ZEBRA_READ); +} - if (hdr->command == ZEBRA_RULE_ADD) - zebra_pbr_add_rule(zvrf->zns, &zpr); - else - zebra_pbr_del_rule(zvrf->zns, &zpr); - } +static int zserv_delayed_close(struct thread *thread) +{ + struct zserv *client = THREAD_ARG(thread); -stream_failure: - return; + client->t_suicide = NULL; + zebra_client_close(client); + return 0; } /* - * Reads header from zmsg stream. + * Log zapi message to zlog. + * + * errmsg (optional) + * Debugging message * - * Note this advances the stream getp by the size of the header. + * msg + * The message + * + * hdr (optional) + * The message header */ -static bool zserv_read_header(struct stream *msg, struct zmsghdr *hdr) -{ - STREAM_GETW(msg, hdr->length); - STREAM_GETC(msg, hdr->marker); - STREAM_GETC(msg, hdr->version); - STREAM_GETL(msg, hdr->vrf_id); - STREAM_GETW(msg, hdr->command); - return true; -stream_failure: - return false; +static void zserv_log_message(const char *errmsg, struct stream *msg, + struct zmsghdr *hdr) +{ + zlog_debug("Rx'd ZAPI message"); + if (errmsg) + zlog_debug("%s", errmsg); + if (hdr) { + zlog_debug(" Length: %d", hdr->length); + zlog_debug("Command: %s", zserv_command_string(hdr->command)); + zlog_debug(" VRF: %u", hdr->vrf_id); + } + zlog_hexdump(msg->data, STREAM_READABLE(msg)); } -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 int zserv_flush_data(struct thread *thread) +{ + struct zserv *client = THREAD_ARG(thread); -static inline void zserv_handle_commands(struct zserv *client, uint16_t command, - uint16_t length, - struct zebra_vrf *zvrf) + client->t_write = NULL; + if (client->t_suicide) { + zebra_client_close(client); + return -1; + } + switch (buffer_flush_available(client->wb, client->sock)) { + case BUFFER_ERROR: + zlog_warn( + "%s: buffer_flush_available failed on zserv client fd %d, closing", + __func__, client->sock); + zebra_client_close(client); + client = NULL; + break; + case BUFFER_PENDING: + client->t_write = NULL; + thread_add_write(zebrad.master, zserv_flush_data, client, + client->sock, &client->t_write); + break; + case BUFFER_EMPTY: + break; + } + + if (client) + client->last_write_time = monotime(NULL); + return 0; +} + +/* + * Write a single packet. + */ +static int zserv_write(struct thread *thread) { - struct zmsghdr hdr; + struct zserv *client = THREAD_ARG(thread); + struct stream *msg; + int writerv; - stream_set_getp(client->ibuf, 0); - zserv_read_header(client->ibuf, &hdr); - 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 (client->t_suicide) + return -1; + + if (client->is_synchronous) + return 0; + + msg = stream_fifo_pop(client->obuf_fifo); + stream_set_getp(msg, 0); + client->last_write_cmd = stream_getw_from(msg, 6); + + writerv = buffer_write(client->wb, client->sock, STREAM_DATA(msg), + stream_get_endp(msg)); + + stream_free(msg); + + switch (writerv) { + case BUFFER_ERROR: + zlog_warn( + "%s: buffer_write failed to zserv client fd %d, closing", + __func__, client->sock); + /* + * Schedule a delayed close since many of the functions that + * call this one do not check the return code. They do not + * allow for the possibility that an I/O error may have caused + * the client to be deleted. + */ + client->t_suicide = NULL; + thread_add_event(zebrad.master, zserv_delayed_close, client, 0, + &client->t_suicide); + return -1; + case BUFFER_EMPTY: + THREAD_OFF(client->t_write); + break; + case BUFFER_PENDING: + thread_add_write(zebrad.master, zserv_flush_data, client, + client->sock, &client->t_write); + break; + } + + if (client->obuf_fifo->count) + zebra_event(client, ZEBRA_WRITE); + + client->last_write_time = monotime(NULL); + return 0; } #if defined(HANDLE_ZAPI_FUZZING) @@ -2781,26 +2798,66 @@ static void zserv_write_incoming(struct stream *orig, uint16_t command) } #endif +static int zserv_process_messages(struct thread *thread) +{ + struct zserv *client = THREAD_ARG(thread); + struct zebra_vrf *zvrf; + struct zmsghdr hdr; + struct stream *msg; + bool hdrvalid; + + do { + msg = stream_fifo_pop(client->ibuf_fifo); + + /* break if out of messages */ + if (!msg) + continue; + + /* read & check header */ + hdrvalid = zapi_parse_header(msg, &hdr); + if (!hdrvalid && IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) { + const char *emsg = "Message has corrupt header"; + zserv_log_message(emsg, msg, NULL); + } + if (!hdrvalid) + continue; + + /* lookup vrf */ + zvrf = zebra_vrf_lookup_by_id(hdr.vrf_id); + if (!zvrf && IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) { + const char *emsg = "Message specifies unknown VRF"; + zserv_log_message(emsg, msg, &hdr); + } + if (!zvrf) + continue; + + /* process commands */ + zserv_handle_commands(client, &hdr, msg, zvrf); + + } while (msg); + + return 0; +} + /* Handler of zebra service request. */ -static int zebra_client_read(struct thread *thread) +static int zserv_read(struct thread *thread) { int sock; struct zserv *client; size_t already; - uint16_t length, command; - uint8_t marker, version; - vrf_id_t vrf_id; - struct zebra_vrf *zvrf; #if defined(HANDLE_ZAPI_FUZZING) int packets = 1; #else int packets = zebrad.packets_to_process; #endif + struct zmsghdr hdr; + ssize_t nb; + bool hdrvalid; + char errmsg[256]; /* Get thread data. Reset reading thread because I'm running. */ sock = THREAD_FD(thread); client = THREAD_ARG(thread); - client->t_read = NULL; if (client->t_suicide) { zebra_client_close(client); @@ -2808,88 +2865,84 @@ static int zebra_client_read(struct thread *thread) } while (packets) { + already = stream_get_endp(client->ibuf_work); + /* Read length and command (if we don't have it already). */ - if ((already = stream_get_endp(client->ibuf)) - < ZEBRA_HEADER_SIZE) { - ssize_t nbyte; - if (((nbyte = stream_read_try(client->ibuf, sock, - ZEBRA_HEADER_SIZE - - already)) - == 0) - || (nbyte == -1)) { - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug( - "connection closed socket [%d]", - sock); - zebra_client_close(client); - return -1; - } - if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) { + if (already < ZEBRA_HEADER_SIZE) { + nb = stream_read_try(client->ibuf_work, sock, + ZEBRA_HEADER_SIZE - already); + if ((nb == 0 || nb == -1) && IS_ZEBRA_DEBUG_EVENT) + zlog_debug("connection closed socket [%d]", + sock); + if ((nb == 0 || nb == -1)) + goto zread_fail; + if (nb != (ssize_t)(ZEBRA_HEADER_SIZE - already)) { /* Try again later. */ - zebra_event(ZEBRA_READ, sock, client); - return 0; + break; } already = ZEBRA_HEADER_SIZE; } /* Reset to read from the beginning of the incoming packet. */ - stream_set_getp(client->ibuf, 0); + stream_set_getp(client->ibuf_work, 0); /* Fetch header values */ - STREAM_GETW(client->ibuf, length); - STREAM_GETC(client->ibuf, marker); - STREAM_GETC(client->ibuf, version); - STREAM_GETL(client->ibuf, vrf_id); - STREAM_GETW(client->ibuf, command); + hdrvalid = zapi_parse_header(client->ibuf_work, &hdr); - if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) { - zlog_err( - "%s: socket %d version mismatch, marker %d, version %d", - __func__, sock, marker, version); - zebra_client_close(client); - return -1; + if (!hdrvalid) { + snprintf(errmsg, sizeof(errmsg), + "%s: Message has corrupt header", __func__); + zserv_log_message(errmsg, client->ibuf_work, NULL); + goto zread_fail; } - if (length < ZEBRA_HEADER_SIZE) { - zlog_warn( - "%s: socket %d message length %u is less than header size %d", - __func__, sock, length, ZEBRA_HEADER_SIZE); - zebra_client_close(client); - return -1; + + /* Validate header */ + if (hdr.marker != ZEBRA_HEADER_MARKER + || hdr.version != ZSERV_VERSION) { + snprintf( + errmsg, sizeof(errmsg), + "Message has corrupt header\n%s: socket %d version mismatch, marker %d, version %d", + __func__, sock, hdr.marker, hdr.version); + zserv_log_message(errmsg, client->ibuf_work, &hdr); + goto zread_fail; } - if (length > STREAM_SIZE(client->ibuf)) { - zlog_warn( - "%s: socket %d message length %u exceeds buffer size %lu", - __func__, sock, length, - (u_long)STREAM_SIZE(client->ibuf)); - zebra_client_close(client); - return -1; + if (hdr.length < ZEBRA_HEADER_SIZE) { + snprintf( + errmsg, sizeof(errmsg), + "Message has corrupt header\n%s: socket %d message length %u is less than header size %d", + __func__, sock, hdr.length, ZEBRA_HEADER_SIZE); + zserv_log_message(errmsg, client->ibuf_work, &hdr); + goto zread_fail; + } + if (hdr.length > STREAM_SIZE(client->ibuf_work)) { + snprintf( + errmsg, sizeof(errmsg), + "Message has corrupt header\n%s: socket %d message length %u exceeds buffer size %lu", + __func__, sock, hdr.length, + (unsigned long)STREAM_SIZE(client->ibuf_work)); + goto zread_fail; } /* Read rest of data. */ - if (already < length) { - ssize_t nbyte; - if (((nbyte = stream_read_try(client->ibuf, sock, - length - already)) - == 0) - || (nbyte == -1)) { - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug( - "connection closed [%d] when reading zebra data", - sock); - zebra_client_close(client); - return -1; - } - if (nbyte != (ssize_t)(length - already)) { + if (already < hdr.length) { + nb = stream_read_try(client->ibuf_work, sock, + hdr.length - already); + if ((nb == 0 || nb == -1) && IS_ZEBRA_DEBUG_EVENT) + zlog_debug( + "connection closed [%d] when reading zebra data", + sock); + if ((nb == 0 || nb == -1)) + goto zread_fail; + if (nb != (ssize_t)(hdr.length - already)) { /* Try again later. */ - zebra_event(ZEBRA_READ, sock, client); - return 0; + break; } } #if defined(HANDLE_ZAPI_FUZZING) - zserv_write_incoming(client->ibuf, command); + zserv_write_incoming(client->ibuf_work, command); #endif - length -= ZEBRA_HEADER_SIZE; + hdr.length -= ZEBRA_HEADER_SIZE; /* Debug packet information. */ if (IS_ZEBRA_DEBUG_EVENT) @@ -2897,41 +2950,54 @@ static int zebra_client_read(struct thread *thread) sock); if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) - zlog_debug("zebra message received [%s] %d in VRF %u", - zserv_command_string(command), length, - vrf_id); + zserv_log_message(NULL, client->ibuf_work, &hdr); client->last_read_time = monotime(NULL); - client->last_read_cmd = command; - - zvrf = zebra_vrf_lookup_by_id(vrf_id); - if (!zvrf) { - if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) - zlog_debug("zebra received unknown VRF[%u]", - vrf_id); - goto zclient_read_out; - } + client->last_read_cmd = hdr.command; - zserv_handle_commands(client, command, length, zvrf); + stream_set_getp(client->ibuf_work, 0); + struct stream *msg = stream_dup(client->ibuf_work); - if (client->t_suicide) { - /* No need to wait for thread callback, just kill - * immediately. - */ - zebra_client_close(client); - return -1; - } - packets -= 1; - stream_reset(client->ibuf); + stream_fifo_push(client->ibuf_fifo, msg); + + if (client->t_suicide) + goto zread_fail; + + --packets; + stream_reset(client->ibuf_work); } -stream_failure: -zclient_read_out: - stream_reset(client->ibuf); - zebra_event(ZEBRA_READ, sock, client); + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("Read %d packets", + zebrad.packets_to_process - packets); + + /* Schedule job to process those packets */ + thread_add_event(zebrad.master, &zserv_process_messages, client, 0, + NULL); + + /* Reschedule ourselves */ + zebra_event(client, ZEBRA_READ); + return 0; + +zread_fail: + zebra_client_close(client); + return -1; } +static void zebra_event(struct zserv *client, enum event event) +{ + switch (event) { + case ZEBRA_READ: + thread_add_read(zebrad.master, zserv_read, client, client->sock, + &client->t_read); + break; + case ZEBRA_WRITE: + thread_add_write(zebrad.master, zserv_write, client, + client->sock, &client->t_write); + break; + } +} /* Accept code of zebra server socket. */ static int zebra_accept(struct thread *thread) @@ -2944,7 +3010,7 @@ static int zebra_accept(struct thread *thread) accept_sock = THREAD_FD(thread); /* Reregister myself. */ - zebra_event(ZEBRA_SERV, accept_sock, NULL); + thread_add_read(zebrad.master, zebra_accept, NULL, accept_sock, NULL); len = sizeof(struct sockaddr_in); client_sock = accept(accept_sock, (struct sockaddr *)&client, &len); @@ -3031,26 +3097,7 @@ void zebra_zserv_socket_init(char *path) umask(old_mask); - zebra_event(ZEBRA_SERV, sock, NULL); -} - - -static void zebra_event(enum event event, int sock, struct zserv *client) -{ - switch (event) { - case ZEBRA_SERV: - thread_add_read(zebrad.master, zebra_accept, client, sock, - NULL); - break; - case ZEBRA_READ: - client->t_read = NULL; - thread_add_read(zebrad.master, zebra_client_read, client, sock, - &client->t_read); - break; - case ZEBRA_WRITE: - /**/ - break; - } + thread_add_read(zebrad.master, zebra_accept, NULL, sock, NULL); } #define ZEBRA_TIME_BUF 32 diff --git a/zebra/zserv.h b/zebra/zserv.h index 74ff31bcf9b0..a055a28c0100 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -47,8 +47,12 @@ struct zserv { int sock; /* Input/output buffer to the client. */ - struct stream *ibuf; - struct stream *obuf; + struct stream_fifo *ibuf_fifo; + struct stream_fifo *obuf_fifo; + + /* Private I/O buffers */ + struct stream *ibuf_work; + struct stream *obuf_work; /* Buffer of data waiting to be written to client. */ struct buffer *wb; @@ -129,7 +133,7 @@ struct zserv { int last_write_cmd; }; -/* ZAPI protocol message header */ +/* ZAPI protocol structs */ struct zmsghdr { uint16_t length; uint8_t marker; @@ -139,7 +143,8 @@ struct zmsghdr { }; #define ZAPI_HANDLER_ARGS \ - struct zserv *client, struct zmsghdr *hdr, struct zebra_vrf *zvrf + struct zserv *client, struct zmsghdr *hdr, struct stream *msg, \ + struct zebra_vrf *zvrf /* Zebra instance */ struct zebra_t { @@ -197,7 +202,7 @@ extern void zsend_rule_notify_owner(struct zebra_pbr_rule *rule, extern void zserv_nexthop_num_warn(const char *, const struct prefix *, const unsigned int); -extern int zebra_server_send_message(struct zserv *client); +extern int zebra_server_send_message(struct zserv *client, struct stream *msg); extern struct zserv *zebra_find_client(u_char proto, u_short instance); From 124ead27dbd7e61e79a334533adc702fdf172ddb Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Wed, 7 Mar 2018 11:23:58 -0500 Subject: [PATCH 07/10] lib, zebra: use existing zapi header struct Nobody uses it, but it's got the same definition. Move the parser function into zclient.c and use it. Signed-off-by: Quentin Young --- lib/zclient.c | 12 +++++++++ lib/zclient.h | 62 ++++++++++++++++++++++++++++++++++++++++----- zebra/zebra_vxlan.c | 2 +- zebra/zserv.h | 9 ------- 4 files changed, 68 insertions(+), 17 deletions(-) diff --git a/lib/zclient.c b/lib/zclient.c index fa3a5f669127..20aaaca161c3 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -322,6 +322,18 @@ int zclient_read_header(struct stream *s, int sock, u_int16_t *size, return 0; } +bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr) +{ + STREAM_GETW(zmsg, hdr->length); + STREAM_GETC(zmsg, hdr->marker); + STREAM_GETC(zmsg, hdr->version); + STREAM_GETC(zmsg, hdr->vrf_id); + STREAM_GETW(zmsg, hdr->command); + return true; +stream_failure: + return false; +} + /* Send simple Zebra message. */ static int zebra_message_send(struct zclient *zclient, int command, vrf_id_t vrf_id) diff --git a/lib/zclient.h b/lib/zclient.h index 1aa94b641c86..c8574946d01f 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -237,14 +237,14 @@ struct zclient { */ #define ZAPI_MESSAGE_TABLEID 0x80 +#define ZSERV_VERSION 5 /* Zserv protocol message header */ -struct zserv_header { +struct zmsghdr { uint16_t length; - uint8_t marker; /* corresponds to command field in old zserv - * always set to 255 in new zserv. - */ + /* corresponds to command field in old zserv + * always set to 255 in new zserv. */ + uint8_t marker; uint8_t version; -#define ZSERV_VERSION 5 vrf_id_t vrf_id; uint16_t command; }; @@ -449,9 +449,58 @@ extern int zclient_send_message(struct zclient *); /* create header for command, length to be filled in by user later */ extern void zclient_create_header(struct stream *, uint16_t, vrf_id_t); +/* + * Read sizeof(struct zmsghdr) bytes from the provided socket and parse the + * received data into the specified fields. If this is successful, read the + * rest of the packet into the provided stream. + * + * s + * The stream to read into + * + * sock + * The socket to read from + * + * size + * Parsed message size will be placed in the pointed-at integer + * + * marker + * Parsed marker will be placed in the pointed-at byte + * + * version + * Parsed version will be placed in the pointed-at byte + * + * vrf_id + * Parsed VRF ID will be placed in the pointed-at vrf_id_t + * + * cmd + * Parsed command number will be placed in the pointed-at integer + * + * Returns: + * -1 if: + * - insufficient data for header was read + * - a version mismatch was detected + * - a marker mismatch was detected + * - header size field specified more data than could be read + */ extern int zclient_read_header(struct stream *s, int sock, u_int16_t *size, u_char *marker, u_char *version, vrf_id_t *vrf_id, u_int16_t *cmd); +/* + * Parse header from ZAPI message stream into struct zmsghdr. + * This function assumes the stream getp points at the first byte of the header. + * If the function is successful then the stream getp will point to the byte + * immediately after the last byte of the header. + * + * zmsg + * The stream containing the header + * + * hdr + * The header struct to parse into. + * + * Returns: + * true if parsing succeeded, false otherwise + */ +extern bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr); extern void zclient_interface_set_master(struct zclient *client, struct interface *master, @@ -469,8 +518,7 @@ extern void zebra_interface_if_set_value(struct stream *, struct interface *); extern void zebra_router_id_update_read(struct stream *s, struct prefix *rid); #if CONFDATE > 20180823 -CPP_NOTICE( - "zapi_ipv4_route, zapi_ipv6_route, zapi_ipv4_route_ipv6_nexthop as well as the zapi_ipv4 and zapi_ipv6 data structures should be removed now"); +CPP_NOTICE("zapi_ipv4_route, zapi_ipv6_route, zapi_ipv4_route_ipv6_nexthop as well as the zapi_ipv4 and zapi_ipv6 data structures should be removed now"); #endif extern int zapi_ipv4_route(u_char, struct zclient *, struct prefix_ipv4 *, diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index a8d184872357..256fa9e4b710 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -6612,7 +6612,7 @@ void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS) zvni = zvni_lookup(vni); if (!zvni) - return 0; + return; if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( diff --git a/zebra/zserv.h b/zebra/zserv.h index a055a28c0100..62707510c2ef 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -133,15 +133,6 @@ struct zserv { int last_write_cmd; }; -/* ZAPI protocol structs */ -struct zmsghdr { - uint16_t length; - uint8_t marker; - uint8_t version; - uint32_t vrf_id; - uint16_t command; -}; - #define ZAPI_HANDLER_ARGS \ struct zserv *client, struct zmsghdr *hdr, struct stream *msg, \ struct zebra_vrf *zvrf From 5530922ef7408fe8275a75675094c7c453186a2b Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Wed, 7 Mar 2018 12:30:51 -0500 Subject: [PATCH 08/10] lib: zclient.h style fixes Signed-off-by: Quentin Young --- lib/zclient.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/zclient.h b/lib/zclient.h index c8574946d01f..dd9c8973fa6b 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -241,8 +241,7 @@ struct zclient { /* Zserv protocol message header */ struct zmsghdr { uint16_t length; - /* corresponds to command field in old zserv - * always set to 255 in new zserv. */ + /* Always set to 255 in new zserv */ uint8_t marker; uint8_t version; vrf_id_t vrf_id; @@ -380,9 +379,11 @@ struct zclient_options { /* Prototypes of zebra client service functions. */ extern struct zclient *zclient_new(struct thread_master *); +/* clang-format off */ #if CONFDATE > 20181101 CPP_NOTICE("zclient_new_notify can take over or zclient_new now"); #endif +/* clang-format on */ extern struct zclient_options zclient_options_default; @@ -517,9 +518,11 @@ extern struct interface *zebra_interface_vrf_update_read(struct stream *s, extern void zebra_interface_if_set_value(struct stream *, struct interface *); extern void zebra_router_id_update_read(struct stream *s, struct prefix *rid); +/* clang-format off */ #if CONFDATE > 20180823 CPP_NOTICE("zapi_ipv4_route, zapi_ipv6_route, zapi_ipv4_route_ipv6_nexthop as well as the zapi_ipv4 and zapi_ipv6 data structures should be removed now"); #endif +/* clang-format on */ extern int zapi_ipv4_route(u_char, struct zclient *, struct prefix_ipv4 *, struct zapi_ipv4 *) __attribute__((deprecated)); From 107afcd10b59be3441e2b1f358942ca5e760daa2 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Fri, 9 Mar 2018 15:59:39 -0500 Subject: [PATCH 09/10] lib, zebra: clean up zapi nits * Get correct data size when parsing VRF ids * Move some vars into smaller scope Signed-off-by: Quentin Young --- lib/zclient.c | 2 +- zebra/zserv.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/zclient.c b/lib/zclient.c index 20aaaca161c3..c720e2519bd2 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -327,7 +327,7 @@ bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr) STREAM_GETW(zmsg, hdr->length); STREAM_GETC(zmsg, hdr->marker); STREAM_GETC(zmsg, hdr->version); - STREAM_GETC(zmsg, hdr->vrf_id); + STREAM_GETL(zmsg, hdr->vrf_id); STREAM_GETW(zmsg, hdr->command); return true; stream_failure: diff --git a/zebra/zserv.c b/zebra/zserv.c index ac2fe9c0e219..4cdb97be42c9 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2850,11 +2850,6 @@ static int zserv_read(struct thread *thread) #else int packets = zebrad.packets_to_process; #endif - struct zmsghdr hdr; - ssize_t nb; - bool hdrvalid; - char errmsg[256]; - /* Get thread data. Reset reading thread because I'm running. */ sock = THREAD_FD(thread); client = THREAD_ARG(thread); @@ -2865,6 +2860,11 @@ static int zserv_read(struct thread *thread) } while (packets) { + struct zmsghdr hdr; + ssize_t nb; + bool hdrvalid; + char errmsg[256]; + already = stream_get_endp(client->ibuf_work); /* Read length and command (if we don't have it already). */ From 41903a407407bcdf73dbd471dea3f53d2d056b0b Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Fri, 9 Mar 2018 17:40:16 -0500 Subject: [PATCH 10/10] lib, zebra: slight cleanup after rebase Rebased zapi-cleanup, needs a bit of poking. Signed-off-by: Quentin Young --- lib/zclient.h | 2 +- zebra/zserv.c | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/zclient.h b/lib/zclient.h index dd9c8973fa6b..80334884440f 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -237,7 +237,7 @@ struct zclient { */ #define ZAPI_MESSAGE_TABLEID 0x80 -#define ZSERV_VERSION 5 +#define ZSERV_VERSION 5 /* Zserv protocol message header */ struct zmsghdr { uint16_t length; diff --git a/zebra/zserv.c b/zebra/zserv.c index 4cdb97be42c9..f53baf65d07d 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -636,7 +636,7 @@ static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client, * chain of nexthops. */ for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next) if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) - num += zsend_write_nexthop(s, nexthop); + num += zserv_encode_nexthop(s, nexthop); stream_putc_at(s, nump, num); /* store nexthop_num */ } else { @@ -706,8 +706,8 @@ void zsend_rule_notify_owner(struct zebra_pbr_rule *rule, struct stream *s; if (IS_ZEBRA_DEBUG_PACKET) { - zlog_debug("%s: Notifying %u", - __PRETTY_FUNCTION__, rule->unique); + zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__, + rule->unique); } for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) { @@ -1091,7 +1091,6 @@ static void zread_fec_unregister(ZAPI_HANDLER_ARGS) } - /* * Register zebra server interface information. * Send current all interface and address information.