summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-05 09:56:24 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-05 09:56:24 +0000
commit54de8bbe36d7d968c6367939277942518bd4e11f (patch)
tree924f8c16d9c8831679f355b88c620b9b356c9d5a /zebra
parentAdding debian version 10.0.1-0.1. (diff)
downloadfrr-54de8bbe36d7d968c6367939277942518bd4e11f.tar.xz
frr-54de8bbe36d7d968c6367939277942518bd4e11f.zip
Merging upstream version 10.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--zebra/.gitignore1
-rw-r--r--zebra/debug_nl.c6
-rw-r--r--zebra/dpdk/zebra_dplane_dpdk.c82
-rw-r--r--zebra/dpdk/zebra_dplane_dpdk.h2
-rw-r--r--zebra/dplane_fpm_nl.c96
-rw-r--r--zebra/fpm_listener.c814
-rw-r--r--zebra/if_netlink.c1
-rw-r--r--zebra/interface.c115
-rw-r--r--zebra/interface.h5
-rw-r--r--zebra/kernel_netlink.c20
-rw-r--r--zebra/main.c3
-rw-r--r--zebra/redistribute.c4
-rw-r--r--zebra/rt_netlink.c163
-rw-r--r--zebra/rtadv.c10
-rw-r--r--zebra/subdir.am7
-rw-r--r--zebra/zapi_msg.c7
-rw-r--r--zebra/zebra_dplane.c20
-rw-r--r--zebra/zebra_dplane.h7
-rw-r--r--zebra/zebra_evpn.c146
-rw-r--r--zebra/zebra_evpn_mac.c528
-rw-r--r--zebra/zebra_evpn_mh.c45
-rw-r--r--zebra/zebra_evpn_mh.h3
-rw-r--r--zebra/zebra_fpm_netlink.c8
-rw-r--r--zebra/zebra_gr.c10
-rw-r--r--zebra/zebra_l2.c33
-rw-r--r--zebra/zebra_mpls.c28
-rw-r--r--zebra/zebra_mpls.h5
-rw-r--r--zebra/zebra_mpls_openbsd.c28
-rw-r--r--zebra/zebra_mpls_vty.c2
-rw-r--r--zebra/zebra_nb.c6
-rw-r--r--zebra/zebra_nb.h1
-rw-r--r--zebra/zebra_nb_config.c4
-rw-r--r--zebra/zebra_nb_rpcs.c63
-rw-r--r--zebra/zebra_nb_state.c70
-rw-r--r--zebra/zebra_neigh.c12
-rw-r--r--zebra/zebra_netns_id.c4
-rw-r--r--zebra/zebra_netns_notify.c19
-rw-r--r--zebra/zebra_nhg.c116
-rw-r--r--zebra/zebra_nhg.h10
-rw-r--r--zebra/zebra_rnh.c332
-rw-r--r--zebra/zebra_rnh.h4
-rw-r--r--zebra/zebra_routemap_nb_config.c2
-rw-r--r--zebra/zebra_srv6_vty.c12
-rw-r--r--zebra/zebra_trace.c2
-rw-r--r--zebra/zebra_vty.c324
-rw-r--r--zebra/zebra_vxlan.c85
-rw-r--r--zebra/zebra_vxlan_if.c35
-rw-r--r--zebra/zserv.c65
-rw-r--r--zebra/zserv.h1
49 files changed, 2026 insertions, 1340 deletions
diff --git a/zebra/.gitignore b/zebra/.gitignore
index 41a86e7..f10240d 100644
--- a/zebra/.gitignore
+++ b/zebra/.gitignore
@@ -1,3 +1,4 @@
zebra
zebra.conf
client
+fpm_listener
diff --git a/zebra/debug_nl.c b/zebra/debug_nl.c
index a7cccdb..037d0b6 100644
--- a/zebra/debug_nl.c
+++ b/zebra/debug_nl.c
@@ -534,6 +534,12 @@ const char *rtm_rta2str(int type)
return "NH_ID";
case RTA_EXPIRES:
return "EXPIRES";
+ case RTA_VIA:
+ return "VIA";
+ case RTA_ENCAP_TYPE:
+ return "RTA_ENCAP_TYPE";
+ case RTA_ENCAP:
+ return "RTA_ENCAP";
default:
return "UNKNOWN";
}
diff --git a/zebra/dpdk/zebra_dplane_dpdk.c b/zebra/dpdk/zebra_dplane_dpdk.c
index 4c32044..4111551 100644
--- a/zebra/dpdk/zebra_dplane_dpdk.c
+++ b/zebra/dpdk/zebra_dplane_dpdk.c
@@ -52,7 +52,7 @@ void zd_dpdk_stat_show(struct vty *vty)
static void zd_dpdk_flow_stat_show(struct vty *vty, int in_ifindex,
intptr_t dp_flow_ptr)
{
- struct rte_flow_action_count count = {.shared = 0, .id = 0};
+ struct rte_flow_action_count count = { .id = 0 };
const struct rte_flow_action actions[] = {
{
.type = RTE_FLOW_ACTION_TYPE_COUNT,
@@ -105,8 +105,7 @@ static int zd_dpdk_pbr_show_rules_walkcb(struct hash_bucket *bucket, void *arg)
ifp = if_lookup_by_name_vrf(rule->ifname, vrf);
if (ifp)
- zd_dpdk_flow_stat_show(vty, ifp->ifindex,
- zaction->dp_flow_ptr);
+ zd_dpdk_flow_stat_show(vty, ifp->ifindex, zaction->dp_flow_ptr);
}
return HASHWALK_CONTINUE;
}
@@ -153,8 +152,7 @@ static void zd_dpdk_rule_add(struct zebra_dplane_ctx *ctx)
if (IS_ZEBRA_DEBUG_DPLANE_DPDK_DETAIL)
zlog_debug(
"PBR dpdk flow create ifname %s seq %d pri %u unique %d failed; in_port %d missing\n",
- dplane_ctx_rule_get_ifname(ctx), seq, pri,
- unique, in_ifindex);
+ dplane_ctx_rule_get_ifname(ctx), seq, pri, unique, in_ifindex);
return;
}
@@ -163,8 +161,7 @@ static void zd_dpdk_rule_add(struct zebra_dplane_ctx *ctx)
if (IS_ZEBRA_DEBUG_DPLANE_DPDK_DETAIL)
zlog_debug(
"PBR dpdk flow create ifname %s seq %d pri %u unique %d failed; out_port %d missing\n",
- dplane_ctx_rule_get_ifname(ctx), seq, pri,
- unique, out_ifindex);
+ dplane_ctx_rule_get_ifname(ctx), seq, pri, unique, out_ifindex);
return;
}
@@ -180,7 +177,7 @@ static void zd_dpdk_rule_add(struct zebra_dplane_ctx *ctx)
memset(&ip, 0, sizeof(ip));
memset(&ip_mask, 0, sizeof(ip_mask));
- if (filter_bm & PBR_FILTER_SRC_IP) {
+ if (CHECK_FLAG(filter_bm, PBR_FILTER_SRC_IP)) {
const struct prefix *src_ip;
src_ip = dplane_ctx_rule_get_src_ip(ctx);
@@ -188,7 +185,7 @@ static void zd_dpdk_rule_add(struct zebra_dplane_ctx *ctx)
masklen2ip(src_ip->prefixlen, &tmp_mask);
ip_mask.hdr.src_addr = tmp_mask.s_addr;
}
- if (filter_bm & PBR_FILTER_DST_IP) {
+ if (CHECK_FLAG(filter_bm, PBR_FILTER_DST_IP)) {
const struct prefix *dst_ip;
dst_ip = dplane_ctx_rule_get_dst_ip(ctx);
@@ -196,7 +193,7 @@ static void zd_dpdk_rule_add(struct zebra_dplane_ctx *ctx)
masklen2ip(dst_ip->prefixlen, &tmp_mask);
ip_mask.hdr.dst_addr = tmp_mask.s_addr;
}
- if (filter_bm & PBR_FILTER_IP_PROTOCOL) {
+ if (CHECK_FLAG(filter_bm, PBR_FILTER_IP_PROTOCOL)) {
ip.hdr.next_proto_id = dplane_ctx_rule_get_ipproto(ctx);
ip_mask.hdr.next_proto_id = UINT8_MAX;
}
@@ -206,17 +203,15 @@ static void zd_dpdk_rule_add(struct zebra_dplane_ctx *ctx)
items[item_cnt].last = NULL;
++item_cnt;
- if ((filter_bm & (PBR_FILTER_SRC_PORT | PBR_FILTER_DST_PORT))) {
+ if (CHECK_FLAG(filter_bm, (PBR_FILTER_SRC_PORT | PBR_FILTER_DST_PORT))) {
memset(&udp, 0, sizeof(udp));
memset(&udp_mask, 0, sizeof(udp_mask));
- if (filter_bm & PBR_FILTER_SRC_PORT) {
- udp.hdr.src_port =
- RTE_BE16(dplane_ctx_rule_get_src_port(ctx));
+ if (CHECK_FLAG(filter_bm, PBR_FILTER_SRC_PORT)) {
+ udp.hdr.src_port = RTE_BE16(dplane_ctx_rule_get_src_port(ctx));
udp_mask.hdr.src_port = UINT16_MAX;
}
- if (filter_bm & PBR_FILTER_DST_PORT) {
- udp.hdr.dst_port =
- RTE_BE16(dplane_ctx_rule_get_dst_port(ctx));
+ if (CHECK_FLAG(filter_bm, PBR_FILTER_DST_PORT)) {
+ udp.hdr.dst_port = RTE_BE16(dplane_ctx_rule_get_dst_port(ctx));
udp_mask.hdr.dst_port = UINT16_MAX;
}
items[item_cnt].type = RTE_FLOW_ITEM_TYPE_UDP;
@@ -273,8 +268,7 @@ static void zd_dpdk_rule_add(struct zebra_dplane_ctx *ctx)
} else {
zlog_warn(
"PBR dpdk flow create failed ifname %s seq %d pri %u unique %d; rc %d\n",
- dplane_ctx_rule_get_ifname(ctx), seq, pri, unique,
- error.type);
+ dplane_ctx_rule_get_ifname(ctx), seq, pri, unique, error.type);
}
}
@@ -504,9 +498,11 @@ static void zd_dpdk_port_show_entry(struct zd_dpdk_port *dport, struct vty *vty,
if (detail) {
vty_out(vty, "DPDK port: %u\n", dport->port_id);
vty_out(vty, " Device: %s\n",
- dev_info->device ? dev_info->device->name : "-");
+ dev_info->device ? rte_dev_name(dev_info->device) : "-");
vty_out(vty, " Driver: %s\n",
- dev_info->driver_name ? dev_info->driver_name : "-");
+ dev_info->driver_name ? rte_driver_name(rte_dev_driver(
+ dev_info->device))
+ : "-");
vty_out(vty, " Interface: %s (%d)\n",
ifindex2ifname(dev_info->if_index, VRF_DEFAULT),
dev_info->if_index);
@@ -516,9 +512,8 @@ static void zd_dpdk_port_show_entry(struct zd_dpdk_port *dport, struct vty *vty,
dev_info->switch_info.port_id);
vty_out(vty, "\n");
} else {
- vty_out(vty, "%-4u %-16s %-16s %-16d %s,%u,%u\n",
- dport->port_id,
- dev_info->device ? dev_info->device->name : "-",
+ vty_out(vty, "%-4u %-16s %-16s %-16d %s,%u,%u\n", dport->port_id,
+ dev_info->device ? rte_dev_name(dev_info->device) : "-",
ifindex2ifname(dev_info->if_index, VRF_DEFAULT),
dev_info->if_index, dev_info->switch_info.name,
dev_info->switch_info.domain_id,
@@ -562,7 +557,7 @@ void zd_dpdk_port_show(struct vty *vty, uint16_t port_id, bool uj, int detail)
for (count = 0; count < RTE_MAX_ETHPORTS; ++count) {
dport = &dpdk_ctx->dpdk_ports[count];
- if (dport->flags & ZD_DPDK_PORT_FLAG_INITED)
+ if (CHECK_FLAG(dport->flags, ZD_DPDK_PORT_FLAG_INITED))
zd_dpdk_port_show_entry(dport, vty, detail);
}
}
@@ -592,31 +587,31 @@ static void zd_dpdk_port_init(void)
dport = &dpdk_ctx->dpdk_ports[count];
count++;
dport->port_id = port_id;
- dport->flags |= ZD_DPDK_PORT_FLAG_PROBED;
+ SET_FLAG(dport->flags, ZD_DPDK_PORT_FLAG_PROBED);
dev_info = &dport->dev_info;
if (rte_eth_dev_info_get(port_id, dev_info) < 0) {
zlog_warn("failed to get dev info for %u, %s", port_id,
rte_strerror(rte_errno));
continue;
}
- dport->flags |= ZD_DPDK_PORT_FLAG_INITED;
+ SET_FLAG(dport->flags, ZD_DPDK_PORT_FLAG_INITED);
if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
- zlog_debug(
- "port %u, dev %s, ifI %d, sw_name %s, sw_domain %u, sw_port %u",
- port_id,
- dev_info->device ? dev_info->device->name : "-",
- dev_info->if_index, dev_info->switch_info.name,
- dev_info->switch_info.domain_id,
- dev_info->switch_info.port_id);
+ zlog_debug("port %u, dev %s, ifI %d, sw_name %s, sw_domain %u, sw_port %u",
+ port_id,
+ dev_info->device
+ ? rte_dev_name(dev_info->device)
+ : "-",
+ dev_info->if_index,
+ dev_info->switch_info.name,
+ dev_info->switch_info.domain_id,
+ dev_info->switch_info.port_id);
if (rte_flow_isolate(port_id, 1, &error)) {
if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
zlog_debug(
- "Flow isolate on port %u failed %d",
- port_id, error.type);
+ "Flow isolate on port %u failed %d", port_id, error.type);
} else {
if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
- zlog_debug("Flow isolate on port %u",
- port_id);
+ zlog_debug("Flow isolate on port %u", port_id);
}
rc = rte_eth_dev_start(port_id);
if (rc) {
@@ -625,8 +620,7 @@ static void zd_dpdk_port_init(void)
continue;
}
if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
- zlog_debug("DPDK port %d started in promiscuous mode ",
- port_id);
+ zlog_debug("DPDK port %d started in promiscuous mode ", port_id);
}
if (!count) {
@@ -639,13 +633,12 @@ static void zd_dpdk_port_init(void)
static int zd_dpdk_init(void)
{
int rc;
- static const char *argv[] = {(char *)"/usr/lib/frr/zebra",
- (char *)"--"};
+ static const char *argv[] = {(char *)"/usr/lib/frr/zebra", (char *)"--"};
zd_dpdk_vty_init();
frr_with_privs (&zserv_privs) {
- rc = rte_eal_init(array_size(argv), argv);
+ rc = rte_eal_init(array_size(argv), (char **)argv);
}
if (rc < 0) {
zlog_warn("EAL init failed %s", rte_strerror(rte_errno));
@@ -674,8 +667,7 @@ static int zd_dpdk_finish(struct zebra_dplane_provider *prov, bool early)
if (early) {
if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
- zlog_debug("%s early finish",
- dplane_provider_get_name(prov));
+ zlog_debug("%s early finish", dplane_provider_get_name(prov));
return 0;
}
diff --git a/zebra/dpdk/zebra_dplane_dpdk.h b/zebra/dpdk/zebra_dplane_dpdk.h
index e5a3dbe..ece72d9 100644
--- a/zebra/dpdk/zebra_dplane_dpdk.h
+++ b/zebra/dpdk/zebra_dplane_dpdk.h
@@ -20,4 +20,6 @@ extern void zd_dpdk_port_show(struct vty *vty, uint16_t port_id, bool uj,
extern void zd_dpdk_stat_show(struct vty *vty);
extern void zd_dpdk_vty_init(void);
+extern struct zebra_privs_t zserv_privs;
+
#endif
diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c
index 7ae1b2a..9ad92d6 100644
--- a/zebra/dplane_fpm_nl.c
+++ b/zebra/dplane_fpm_nl.c
@@ -30,6 +30,7 @@
#include "lib/network.h"
#include "lib/ns.h"
#include "lib/frr_pthread.h"
+#include "lib/termtable.h"
#include "zebra/debug.h"
#include "zebra/interface.h"
#include "zebra/zebra_dplane.h"
@@ -44,6 +45,8 @@
#include "zebra/debug.h"
#include "fpm/fpm.h"
+#include "zebra/dplane_fpm_nl_clippy.c"
+
#define SOUTHBOUND_DEFAULT_ADDR INADDR_LOOPBACK
/*
@@ -322,6 +325,74 @@ DEFUN(fpm_reset_counters, fpm_reset_counters_cmd,
return CMD_SUCCESS;
}
+DEFPY(fpm_show_status,
+ fpm_show_status_cmd,
+ "show fpm status [json]$json",
+ SHOW_STR FPM_STR "FPM status\n" JSON_STR)
+{
+ struct json_object *j;
+ bool connected;
+ uint16_t port;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+ char buf[BUFSIZ];
+
+ connected = gfnc->socket > 0 ? true : false;
+
+ switch (gfnc->addr.ss_family) {
+ case AF_INET:
+ sin = (struct sockaddr_in *)&gfnc->addr;
+ snprintfrr(buf, sizeof(buf), "%pI4", &sin->sin_addr);
+ port = ntohs(sin->sin_port);
+ break;
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)&gfnc->addr;
+ snprintfrr(buf, sizeof(buf), "%pI6", &sin6->sin6_addr);
+ port = ntohs(sin6->sin6_port);
+ break;
+ default:
+ strlcpy(buf, "Unknown", sizeof(buf));
+ port = FPM_DEFAULT_PORT;
+ break;
+ }
+
+ if (json) {
+ j = json_object_new_object();
+
+ json_object_boolean_add(j, "connected", connected);
+ json_object_boolean_add(j, "useNHG", gfnc->use_nhg);
+ json_object_boolean_add(j, "useRouteReplace",
+ gfnc->use_route_replace);
+ json_object_boolean_add(j, "disabled", gfnc->disabled);
+ json_object_string_add(j, "address", buf);
+ json_object_int_add(j, "port", port);
+
+ vty_json(vty, j);
+ } else {
+ struct ttable *table = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ char *out;
+
+ ttable_rowseps(table, 0, BOTTOM, true, '-');
+ ttable_add_row(table, "Address to connect to|%s", buf);
+ ttable_add_row(table, "Port|%u", port);
+ ttable_add_row(table, "Connected|%s", connected ? "Yes" : "No");
+ ttable_add_row(table, "Use Nexthop Groups|%s",
+ gfnc->use_nhg ? "Yes" : "No");
+ ttable_add_row(table, "Use Route Replace Semantics|%s",
+ gfnc->use_route_replace ? "Yes" : "No");
+ ttable_add_row(table, "Disabled|%s",
+ gfnc->disabled ? "Yes" : "No");
+
+ out = ttable_dump(table, "\n");
+ vty_out(vty, "%s\n", out);
+ XFREE(MTYPE_TMP, out);
+
+ ttable_del(table);
+ }
+
+ return CMD_SUCCESS;
+}
+
DEFUN(fpm_show_counters, fpm_show_counters_cmd,
"show fpm counters",
SHOW_STR
@@ -583,14 +654,6 @@ static void fpm_read(struct event *t)
hdr_available_bytes = fpm.msg_len - FPM_MSG_HDR_LEN;
available_bytes -= hdr_available_bytes;
- /* Sanity check: must be at least header size. */
- if (hdr->nlmsg_len < sizeof(*hdr)) {
- zlog_warn(
- "%s: [seq=%u] invalid message length %u (< %zu)",
- __func__, hdr->nlmsg_seq, hdr->nlmsg_len,
- sizeof(*hdr));
- continue;
- }
if (hdr->nlmsg_len > fpm.msg_len) {
zlog_warn(
"%s: Received a inner header length of %u that is greater than the fpm total length of %u",
@@ -620,6 +683,14 @@ static void fpm_read(struct event *t)
switch (hdr->nlmsg_type) {
case RTM_NEWROUTE:
+ /* Sanity check: need at least route msg header size. */
+ if (hdr->nlmsg_len < sizeof(struct rtmsg)) {
+ zlog_warn("%s: [seq=%u] invalid message length %u (< %zu)",
+ __func__, hdr->nlmsg_seq,
+ hdr->nlmsg_len, sizeof(struct rtmsg));
+ break;
+ }
+
ctx = dplane_ctx_alloc();
dplane_ctx_route_init(ctx, DPLANE_OP_ROUTE_NOTIFY, NULL,
NULL);
@@ -1394,8 +1465,14 @@ static void fpm_process_queue(struct event *t)
uint64_t processed_contexts = 0;
while (true) {
+ size_t writeable_amount;
+
+ frr_with_mutex (&fnc->obuf_mutex) {
+ writeable_amount = STREAM_WRITEABLE(fnc->obuf);
+ }
+
/* No space available yet. */
- if (STREAM_WRITEABLE(fnc->obuf) < NL_PKT_BUF_SIZE) {
+ if (writeable_amount < NL_PKT_BUF_SIZE) {
no_bufs = true;
break;
}
@@ -1665,6 +1742,7 @@ static int fpm_nl_new(struct event_loop *tm)
zlog_debug("%s register status: %d", prov_name, rv);
install_node(&fpm_node);
+ install_element(ENABLE_NODE, &fpm_show_status_cmd);
install_element(ENABLE_NODE, &fpm_show_counters_cmd);
install_element(ENABLE_NODE, &fpm_show_counters_json_cmd);
install_element(ENABLE_NODE, &fpm_reset_counters_cmd);
diff --git a/zebra/fpm_listener.c b/zebra/fpm_listener.c
new file mode 100644
index 0000000..7d84c70
--- /dev/null
+++ b/zebra/fpm_listener.c
@@ -0,0 +1,814 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef GNU_LINUX
+#include <stdint.h>
+#include <memory.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <assert.h>
+#include <err.h>
+#include <sys/types.h>
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/if_link.h>
+
+#include "rt_netlink.h"
+#include "fpm/fpm.h"
+#include "lib/libfrr.h"
+
+XREF_SETUP();
+
+struct glob {
+ int server_sock;
+ int sock;
+ bool reflect;
+ bool dump_hex;
+};
+
+struct glob glob_space;
+struct glob *glob = &glob_space;
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+/*
+ * get_print_buf
+ */
+static char *
+get_print_buf(size_t *buf_len)
+{
+ static char print_bufs[16][128];
+ static int counter;
+
+ counter++;
+ if (counter >= 16)
+ counter = 0;
+
+ *buf_len = 128;
+ return &print_bufs[counter][0];
+}
+
+/*
+ * create_listen_sock
+ */
+static int create_listen_sock(int port, int *sock_p)
+{
+ int sock;
+ struct sockaddr_in addr;
+ int reuse;
+
+ sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (sock < 0) {
+ fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));
+ return 0;
+ }
+
+ reuse = 1;
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) <
+ 0) {
+ fprintf(stderr, "Failed to set reuse addr option: %s\n",
+ strerror(errno));
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr.sin_port = htons(port);
+
+ if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ fprintf(stderr, "Failed to bind to port %d: %s\n", port, strerror(errno));
+ close(sock);
+ return 0;
+ }
+
+ if (listen(sock, 5)) {
+ fprintf(stderr, "Failed to listen on socket: %s\n", strerror(errno));
+ close(sock);
+ return 0;
+ }
+
+ *sock_p = sock;
+ return 1;
+}
+
+/*
+ * accept_conn
+ */
+static int accept_conn(int listen_sock)
+{
+ int sock;
+ struct sockaddr_in client_addr = { 0 };
+ unsigned int client_len;
+
+ while (1) {
+ char buf[120];
+
+ fprintf(stdout, "Waiting for client connection...\n");
+ client_len = sizeof(client_addr);
+ sock = accept(listen_sock, (struct sockaddr *)&client_addr,
+ &client_len);
+
+ if (sock >= 0) {
+ fprintf(stdout, "Accepted client %s\n",
+ inet_ntop(AF_INET, &client_addr.sin_addr, buf, sizeof(buf)));
+ return sock;
+ }
+ fprintf(stderr, "Failed to accept socket: %s\n", strerror(errno));
+ }
+}
+
+/*
+ * read_fpm_msg
+ */
+static fpm_msg_hdr_t *
+read_fpm_msg(char *buf, size_t buf_len)
+{
+ char *cur, *end;
+ long need_len, bytes_read, have_len;
+ fpm_msg_hdr_t *hdr;
+ int reading_full_msg;
+
+ end = buf + buf_len;
+ cur = buf;
+ hdr = (fpm_msg_hdr_t *)buf;
+
+ while (1) {
+ reading_full_msg = 0;
+
+ have_len = cur - buf;
+
+ if (have_len < (long)FPM_MSG_HDR_LEN) {
+ need_len = FPM_MSG_HDR_LEN - have_len;
+ } else {
+ need_len = fpm_msg_len(hdr) - have_len;
+ assert(need_len >= 0 && need_len <= (end - cur));
+
+ if (!need_len)
+ return hdr;
+
+ reading_full_msg = 1;
+ }
+
+ bytes_read = read(glob->sock, cur, need_len);
+
+ if (bytes_read == 0) {
+ fprintf(stdout,
+ "Socket closed as that read returned 0\n");
+ return NULL;
+ }
+
+ if (bytes_read < 0) {
+ fprintf(stderr, "Error reading from socket: %s\n",
+ strerror(errno));
+ return NULL;
+ }
+
+ cur += bytes_read;
+
+ if (bytes_read < need_len) {
+ fprintf(stderr,
+ "Read %lu bytes but expected to read %lu bytes instead\n",
+ bytes_read, need_len);
+ return NULL;
+ }
+
+ if (reading_full_msg)
+ return hdr;
+
+ if (!fpm_msg_ok(hdr, buf_len)) {
+ assert(0);
+ fprintf(stderr, "Malformed fpm message\n");
+ return NULL;
+ }
+ }
+}
+
+/*
+ * netlink_msg_type_to_s
+ */
+static const char *
+netlink_msg_type_to_s(uint16_t type)
+{
+ switch (type) {
+
+ case RTM_NEWROUTE:
+ return "New route";
+
+ case RTM_DELROUTE:
+ return "Del route";
+
+ case RTM_NEWNEXTHOP:
+ return "New Nexthop Group";
+
+ case RTM_DELNEXTHOP:
+ return "Del Nexthop Group";
+
+ default:
+ return "Unknown";
+ }
+}
+
+/*
+ * netlink_prot_to_s
+ */
+static const char *
+netlink_prot_to_s(unsigned char prot)
+{
+ switch (prot) {
+
+ case RTPROT_KERNEL:
+ return "Kernel";
+
+ case RTPROT_BOOT:
+ return "Boot";
+
+ case RTPROT_STATIC:
+ return "Static";
+
+ case RTPROT_ZEBRA:
+ return "Zebra";
+
+ case RTPROT_DHCP:
+ return "Dhcp";
+
+ case RTPROT_BGP:
+ return "BGP";
+
+ case RTPROT_ISIS:
+ return "ISIS";
+
+ case RTPROT_OSPF:
+ return "OSPF";
+
+ case RTPROT_RIP:
+ return "RIP";
+
+ case RTPROT_RIPNG:
+ return "RIPNG";
+
+ case RTPROT_BABEL:
+ return "BABEL";
+
+ case RTPROT_NHRP:
+ return "NHRP";
+
+ case RTPROT_EIGRP:
+ return "EIGRP";
+
+ case RTPROT_SHARP:
+ return "SHARP";
+
+ case RTPROT_PBR:
+ return "PBR";
+
+ case RTPROT_ZSTATIC:
+ return "Static";
+
+ default:
+ return "Unknown";
+ }
+}
+
+#define MAX_NHS 16
+
+struct netlink_nh {
+ struct rtattr *gateway;
+ int if_index;
+ uint16_t encap_type;
+ uint32_t vxlan_vni;
+};
+
+struct netlink_msg_ctx {
+ struct nlmsghdr *hdr;
+
+ /*
+ * Stuff pertaining to route messages.
+ */
+ struct rtmsg *rtmsg;
+ struct rtattr *rtattrs[RTA_MAX + 1];
+
+ /*
+ * Nexthops.
+ */
+ struct netlink_nh nhs[MAX_NHS];
+ unsigned long num_nhs;
+
+ struct rtattr *dest;
+ struct rtattr *src;
+ int *metric;
+ unsigned int *nhgid;
+
+ const char *err_msg;
+};
+
+/*
+ * netlink_msg_ctx_init
+ */
+static inline void netlink_msg_ctx_init(struct netlink_msg_ctx *ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+/*
+ * netlink_msg_ctx_set_err
+ */
+static inline void netlink_msg_ctx_set_err(struct netlink_msg_ctx *ctx,
+ const char *err_msg)
+{
+ if (ctx->err_msg)
+ return;
+
+ ctx->err_msg = err_msg;
+}
+
+/*
+ * parse_rtattrs_
+ */
+static int parse_rtattrs_(struct rtattr *rta, size_t len, struct rtattr **rtas,
+ uint16_t num_rtas, const char **err_msg)
+{
+ memset(rtas, 0, num_rtas * sizeof(rtas[0]));
+
+ for (; len > 0; rta = RTA_NEXT(rta, len)) {
+ uint16_t type = rta->rta_type & NLA_TYPE_MASK;
+
+ if (!RTA_OK(rta, len)) {
+ *err_msg = "Malformed rta";
+ return 0;
+ }
+
+ if (type >= num_rtas) {
+ warn("Unknown rtattr type %d", rta->rta_type);
+ continue;
+ }
+
+ rtas[type] = rta;
+ }
+
+ return 1;
+}
+
+/*
+ * parse_rtattrs
+ */
+static int parse_rtattrs(struct netlink_msg_ctx *ctx, struct rtattr *rta,
+ size_t len)
+{
+ const char *err_msg;
+
+ err_msg = NULL;
+
+ if (!parse_rtattrs_(rta, len, ctx->rtattrs, ARRAY_SIZE(ctx->rtattrs),
+ &err_msg)) {
+ netlink_msg_ctx_set_err(ctx, err_msg);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * netlink_msg_ctx_add_nh
+ */
+static int netlink_msg_ctx_add_nh(struct netlink_msg_ctx *ctx, int if_index,
+ struct rtattr *gateway, uint16_t encap_type,
+ uint32_t vxlan_vni)
+{
+ struct netlink_nh *nh;
+
+ if (ctx->num_nhs + 1 >= ARRAY_SIZE(ctx->nhs)) {
+ warn("Too many next hops");
+ return 0;
+ }
+ nh = &ctx->nhs[ctx->num_nhs];
+ ctx->num_nhs++;
+
+ nh->gateway = gateway;
+ nh->if_index = if_index;
+
+ nh->encap_type = encap_type;
+ nh->vxlan_vni = vxlan_vni;
+ return 1;
+}
+
+/*
+ * parse_multipath_attr
+ */
+static int parse_multipath_attr(struct netlink_msg_ctx *ctx,
+ struct rtattr *mpath_rtattr)
+{
+ int len;
+ struct rtnexthop *rtnh;
+ struct rtattr *rtattrs[RTA_MAX + 1];
+ struct rtattr *tb[RTA_MAX + 1];
+ struct rtattr *gateway;
+ const char *err_msg;
+
+ rtnh = RTA_DATA(mpath_rtattr);
+ len = RTA_PAYLOAD(mpath_rtattr);
+
+ for (; len > 0;
+ len -= NLMSG_ALIGN(rtnh->rtnh_len), rtnh = RTNH_NEXT(rtnh)) {
+ uint32_t vxlan_vni;
+ uint16_t encap_type;
+
+ if (!RTNH_OK(rtnh, len)) {
+ netlink_msg_ctx_set_err(ctx, "Malformed nh");
+ return 0;
+ }
+
+ if (rtnh->rtnh_len <= sizeof(*rtnh)) {
+ netlink_msg_ctx_set_err(ctx, "NH len too small");
+ return 0;
+ }
+
+ /*
+ * Parse attributes included in the nexthop.
+ */
+ err_msg = NULL;
+ if (!parse_rtattrs_(RTNH_DATA(rtnh),
+ rtnh->rtnh_len - sizeof(*rtnh), rtattrs,
+ ARRAY_SIZE(rtattrs), &err_msg)) {
+ netlink_msg_ctx_set_err(ctx, err_msg);
+ return 0;
+ }
+
+ gateway = rtattrs[RTA_GATEWAY];
+ memset(tb, 0, sizeof(tb));
+ if (rtattrs[RTA_ENCAP]) {
+ parse_rtattrs_(RTA_DATA(rtattrs[RTA_ENCAP]),
+ rtattrs[RTA_ENCAP]->rta_len -
+ sizeof(struct rtattr),
+ tb, ARRAY_SIZE(tb), &err_msg);
+ }
+
+ if (rtattrs[RTA_ENCAP_TYPE])
+ encap_type =
+ *(uint16_t *)RTA_DATA(rtattrs[RTA_ENCAP_TYPE]);
+ else
+ encap_type = 0;
+
+ if (tb[0])
+ vxlan_vni = *(uint32_t *)RTA_DATA(tb[0]);
+ else
+ vxlan_vni = 0;
+
+ netlink_msg_ctx_add_nh(ctx, rtnh->rtnh_ifindex, gateway,
+ encap_type, vxlan_vni);
+ }
+
+ return 1;
+}
+
+/*
+ * parse_route_msg
+ */
+static int parse_route_msg(struct netlink_msg_ctx *ctx)
+{
+ int len;
+ struct rtattr **rtattrs, *rtattr, *gateway, *oif;
+ int if_index;
+
+ ctx->rtmsg = NLMSG_DATA(ctx->hdr);
+
+ len = ctx->hdr->nlmsg_len - NLMSG_LENGTH(sizeof(struct rtmsg));
+ if (len < 0) {
+ netlink_msg_ctx_set_err(ctx, "Bad message length");
+ return 0;
+ }
+
+ if (!parse_rtattrs(ctx, RTM_RTA(ctx->rtmsg), len))
+ return 0;
+
+ rtattrs = ctx->rtattrs;
+
+ ctx->dest = rtattrs[RTA_DST];
+ ctx->src = rtattrs[RTA_PREFSRC];
+
+ rtattr = rtattrs[RTA_PRIORITY];
+ if (rtattr)
+ ctx->metric = (int *)RTA_DATA(rtattr);
+
+ rtattr = rtattrs[RTA_NH_ID];
+ if (rtattr)
+ ctx->nhgid = (unsigned int *)RTA_DATA(rtattr);
+
+ gateway = rtattrs[RTA_GATEWAY];
+ oif = rtattrs[RTA_OIF];
+ if (gateway || oif) {
+ struct rtattr *tb[RTA_MAX + 1] = { 0 };
+ uint16_t encap_type = 0;
+ uint32_t vxlan_vni = 0;
+
+ if_index = 0;
+ if (oif)
+ if_index = *((int *)RTA_DATA(oif));
+
+
+ if (rtattrs[RTA_ENCAP]) {
+ const char *err_msg;
+
+ parse_rtattrs_(RTA_DATA(rtattrs[RTA_ENCAP]),
+ rtattrs[RTA_ENCAP]->rta_len -
+ sizeof(struct rtattr),
+ tb, ARRAY_SIZE(tb), &err_msg);
+ }
+
+ if (rtattrs[RTA_ENCAP_TYPE])
+ encap_type =
+ *(uint16_t *)RTA_DATA(rtattrs[RTA_ENCAP_TYPE]);
+
+ if (tb[0])
+ vxlan_vni = *(uint32_t *)RTA_DATA(tb[0]);
+
+ netlink_msg_ctx_add_nh(ctx, if_index, gateway, encap_type,
+ vxlan_vni);
+ }
+
+ rtattr = rtattrs[RTA_MULTIPATH];
+ if (rtattr)
+ parse_multipath_attr(ctx, rtattr);
+
+ return 1;
+}
+
+/*
+ * addr_to_s
+ */
+static const char *
+addr_to_s(unsigned char family, void *addr)
+{
+ size_t buf_len;
+ char *buf;
+
+ buf = get_print_buf(&buf_len);
+
+ return inet_ntop(family, addr, buf, buf_len);
+}
+
+/*
+ * netlink_msg_ctx_print
+ */
+static int netlink_msg_ctx_snprint(struct netlink_msg_ctx *ctx, char *buf,
+ size_t buf_len)
+{
+ struct nlmsghdr *hdr;
+ struct rtmsg *rtmsg;
+ struct netlink_nh *nh;
+ char *cur, *end;
+ unsigned long i;
+
+ hdr = ctx->hdr;
+ rtmsg = ctx->rtmsg;
+
+ cur = buf;
+ end = buf + buf_len;
+
+ cur += snprintf(cur, end - cur, "%s %s/%d, Prot: %s(%u)",
+ netlink_msg_type_to_s(hdr->nlmsg_type),
+ addr_to_s(rtmsg->rtm_family, RTA_DATA(ctx->dest)),
+ rtmsg->rtm_dst_len,
+ netlink_prot_to_s(rtmsg->rtm_protocol),
+ rtmsg->rtm_protocol);
+
+ if (ctx->metric)
+ cur += snprintf(cur, end - cur, ", Metric: %d", *ctx->metric);
+
+ if (ctx->nhgid)
+ cur += snprintf(cur, end - cur, ", nhgid: %u", *ctx->nhgid);
+ for (i = 0; i < ctx->num_nhs; i++) {
+ cur += snprintf(cur, end - cur, "\n ");
+ nh = &ctx->nhs[i];
+
+ if (nh->gateway) {
+ cur += snprintf(cur, end - cur, " %s",
+ addr_to_s(rtmsg->rtm_family,
+ RTA_DATA(nh->gateway)));
+ }
+
+ if (nh->if_index) {
+ cur += snprintf(cur, end - cur, " via interface %d",
+ nh->if_index);
+ }
+
+ if (nh->encap_type)
+ cur += snprintf(cur, end - cur,
+ ", Encap Type: %u Vxlan vni %u",
+ nh->encap_type, nh->vxlan_vni);
+ }
+
+ return cur - buf;
+}
+
+/*
+ * print_netlink_msg_ctx
+ */
+static void print_netlink_msg_ctx(struct netlink_msg_ctx *ctx)
+{
+ char buf[1024];
+
+ netlink_msg_ctx_snprint(ctx, buf, sizeof(buf));
+ printf("%s\n", buf);
+}
+
+static void fpm_listener_hexdump(const void *mem, size_t len)
+{
+ char line[64];
+ const uint8_t *src = mem;
+ const uint8_t *end = src + len;
+
+ if (!glob->dump_hex)
+ return;
+
+ if (len == 0) {
+ printf("%016lx: (zero length / no data)\n", (long)src);
+ return;
+ }
+
+ while (src < end) {
+ struct fbuf fb = {
+ .buf = line,
+ .pos = line,
+ .len = sizeof(line),
+ };
+ const uint8_t *lineend = src + 8;
+ uint32_t line_bytes = 0;
+
+ printf("%016lx: ", (long)src);
+
+ while (src < lineend && src < end) {
+ printf("%02x ", *src++);
+ line_bytes++;
+ }
+ if (line_bytes < 8)
+ printf("%*s", (8 - line_bytes) * 3, "");
+
+ src -= line_bytes;
+ while (src < lineend && src < end && fb.pos < fb.buf + fb.len) {
+ uint8_t byte = *src++;
+
+ if (isprint(byte))
+ *fb.pos++ = byte;
+ else
+ *fb.pos++ = '.';
+ }
+ printf("\n");
+ }
+}
+
+/*
+ * parse_netlink_msg
+ */
+static void parse_netlink_msg(char *buf, size_t buf_len, fpm_msg_hdr_t *fpm)
+{
+ struct netlink_msg_ctx ctx_space, *ctx;
+ struct nlmsghdr *hdr;
+ unsigned int len;
+
+ fpm_listener_hexdump(buf, buf_len);
+ ctx = &ctx_space;
+
+ hdr = (struct nlmsghdr *)buf;
+ len = buf_len;
+ for (; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) {
+
+ netlink_msg_ctx_init(ctx);
+ ctx->hdr = hdr;
+
+ switch (hdr->nlmsg_type) {
+
+ case RTM_DELROUTE:
+ case RTM_NEWROUTE:
+
+ parse_route_msg(ctx);
+ if (ctx->err_msg) {
+ fprintf(stderr,
+ "Error parsing route message: %s\n",
+ ctx->err_msg);
+ }
+
+ print_netlink_msg_ctx(ctx);
+
+ if (glob->reflect && hdr->nlmsg_type == RTM_NEWROUTE &&
+ ctx->rtmsg->rtm_protocol > RTPROT_STATIC) {
+ printf(" Route %s(%u) reflecting back\n",
+ netlink_prot_to_s(
+ ctx->rtmsg->rtm_protocol),
+ ctx->rtmsg->rtm_protocol);
+ ctx->rtmsg->rtm_flags |= RTM_F_OFFLOAD;
+ write(glob->sock, fpm, fpm_msg_len(fpm));
+ }
+ break;
+
+ default:
+ fprintf(stdout,
+ "Ignoring netlink message - Type: %s(%d)\n",
+ netlink_msg_type_to_s(hdr->nlmsg_type),
+ hdr->nlmsg_type);
+ }
+ }
+}
+
+/*
+ * process_fpm_msg
+ */
+static void process_fpm_msg(fpm_msg_hdr_t *hdr)
+{
+ fprintf(stdout, "FPM message - Type: %d, Length %d\n", hdr->msg_type,
+ ntohs(hdr->msg_len));
+
+ if (hdr->msg_type != FPM_MSG_TYPE_NETLINK) {
+ fprintf(stderr, "Unknown fpm message type %u\n", hdr->msg_type);
+ return;
+ }
+
+ parse_netlink_msg(fpm_msg_data(hdr), fpm_msg_data_len(hdr), hdr);
+}
+
+/*
+ * fpm_serve
+ */
+static void fpm_serve(void)
+{
+ char buf[FPM_MAX_MSG_LEN * 4];
+ fpm_msg_hdr_t *hdr;
+
+ while (1) {
+
+ hdr = read_fpm_msg(buf, sizeof(buf));
+ if (!hdr)
+ return;
+
+ process_fpm_msg(hdr);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ pid_t daemon;
+ int r;
+ bool fork_daemon = false;
+
+ memset(glob, 0, sizeof(*glob));
+
+ while ((r = getopt(argc, argv, "rdv")) != -1) {
+ switch (r) {
+ case 'r':
+ glob->reflect = true;
+ break;
+ case 'd':
+ fork_daemon = true;
+ break;
+ case 'v':
+ glob->dump_hex = true;
+ break;
+ }
+ }
+
+ if (fork_daemon) {
+ daemon = fork();
+
+ if (daemon)
+ exit(0);
+ }
+
+ if (!create_listen_sock(FPM_DEFAULT_PORT, &glob->server_sock))
+ exit(1);
+
+ /*
+ * Server forever.
+ */
+ while (1) {
+ glob->sock = accept_conn(glob->server_sock);
+ fpm_serve();
+ fprintf(stdout, "Done serving client");
+ }
+}
+#else
+
+int main(int argc, char **argv)
+{
+ fprintf(stderr, "This program only works on linux");
+ exit(-1);
+}
+#endif
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index 5f096e3..3233519 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -1473,7 +1473,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
ifi = NLMSG_DATA(h);
- /* assume if not default zns, then new VRF */
if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK)) {
/* If this is not link add/delete message so print warning. */
zlog_debug("%s: wrong kernel message %s", __func__,
diff --git a/zebra/interface.c b/zebra/interface.c
index 5ce222c..b3adc44 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -108,17 +108,6 @@ static void zebra_if_node_destroy(route_table_delegate_t *delegate,
route_node_destroy(delegate, table, node);
}
-static void zebra_if_nhg_dependents_free(struct zebra_if *zebra_if)
-{
- nhg_connected_tree_free(&zebra_if->nhg_dependents);
-}
-
-static void zebra_if_nhg_dependents_init(struct zebra_if *zebra_if)
-{
- nhg_connected_tree_init(&zebra_if->nhg_dependents);
-}
-
-
route_table_delegate_t zebra_if_table_delegate = {
.create_node = route_node_create,
.destroy_node = zebra_if_node_destroy};
@@ -137,7 +126,7 @@ static int if_zebra_new_hook(struct interface *ifp)
zebra_if->link_nsid = NS_UNKNOWN;
- zebra_if_nhg_dependents_init(zebra_if);
+ nhg_connected_tree_init(&zebra_if->nhg_dependents);
zebra_ptm_if_init(zebra_if);
@@ -187,6 +176,10 @@ static void if_nhg_dependents_release(const struct interface *ifp)
frr_each(nhg_connected_tree, &zif->nhg_dependents, rb_node_dep) {
rb_node_dep->nhe->ifp = NULL; /* Null it out */
zebra_nhg_check_valid(rb_node_dep->nhe);
+ if (CHECK_FLAG(rb_node_dep->nhe->flags,
+ NEXTHOP_GROUP_KEEP_AROUND) &&
+ rb_node_dep->nhe->refcnt == 1)
+ zebra_nhg_decrement_ref(rb_node_dep->nhe);
}
}
@@ -221,7 +214,7 @@ static int if_zebra_delete_hook(struct interface *ifp)
zebra_evpn_mac_ifp_del(ifp);
if_nhg_dependents_release(ifp);
- zebra_if_nhg_dependents_free(zebra_if);
+ nhg_connected_tree_free(&zebra_if->nhg_dependents);
XFREE(MTYPE_ZIF_DESC, zebra_if->desc);
@@ -954,47 +947,6 @@ static void if_down_del_nbr_connected(struct interface *ifp)
}
}
-void if_nhg_dependents_add(struct interface *ifp, struct nhg_hash_entry *nhe)
-{
- if (ifp->info) {
- struct zebra_if *zif = (struct zebra_if *)ifp->info;
-
- nhg_connected_tree_add_nhe(&zif->nhg_dependents, nhe);
- }
-}
-
-void if_nhg_dependents_del(struct interface *ifp, struct nhg_hash_entry *nhe)
-{
- if (ifp->info) {
- struct zebra_if *zif = (struct zebra_if *)ifp->info;
-
- nhg_connected_tree_del_nhe(&zif->nhg_dependents, nhe);
- }
-}
-
-unsigned int if_nhg_dependents_count(const struct interface *ifp)
-{
- if (ifp->info) {
- struct zebra_if *zif = (struct zebra_if *)ifp->info;
-
- return nhg_connected_tree_count(&zif->nhg_dependents);
- }
-
- return 0;
-}
-
-
-bool if_nhg_dependents_is_empty(const struct interface *ifp)
-{
- if (ifp->info) {
- struct zebra_if *zif = (struct zebra_if *)ifp->info;
-
- return nhg_connected_tree_is_empty(&zif->nhg_dependents);
- }
-
- return false;
-}
-
/* Interface is up. */
void if_up(struct interface *ifp, bool install_connected)
{
@@ -1022,6 +974,14 @@ void if_up(struct interface *ifp, bool install_connected)
if (install_connected)
if_install_connected(ifp);
+ /*
+ * Interface associated NHG's have been deleted on
+ * interface down events, now that this interface
+ * is coming back up, let's resync the zebra -> dplane
+ * nhg's so that they can be continued to be used.
+ */
+ zebra_interface_nhg_reinstall(ifp);
+
/* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
* are checked to see if (remote) neighbor entries need to be installed
* on them for ARP suppression.
@@ -1523,23 +1483,27 @@ static void interface_vrf_change(enum dplane_op_e op, ifindex_t ifindex,
"DPLANE_OP_INTF_UPDATE for VRF %s(%u) table %u",
name, ifindex, tableid);
- if (!vrf_lookup_by_id((vrf_id_t)ifindex)) {
- vrf_id_t exist_id;
+ /*
+ * For a given tableid, if there already exists a vrf and it
+ * is different from the current vrf to be operated, then there
+ * is a misconfiguration and zebra will exit.
+ */
+ vrf_id_t exist_id = zebra_vrf_lookup_by_table(tableid, ns_id);
- exist_id = zebra_vrf_lookup_by_table(tableid, ns_id);
- if (exist_id != VRF_DEFAULT) {
- vrf = vrf_lookup_by_id(exist_id);
+ if (exist_id != VRF_DEFAULT) {
+ vrf = vrf_lookup_by_id(exist_id);
- if (vrf)
- flog_err(EC_ZEBRA_VRF_MISCONFIGURED,
- "VRF %s id %u table id overlaps existing vrf %s(%d), misconfiguration exiting",
- name, ifindex, vrf->name,
- vrf->vrf_id);
- else
- flog_err(EC_ZEBRA_VRF_NOT_FOUND,
- "VRF %s id %u does not exist",
- name, ifindex);
+ if (!vrf_lookup_by_id((vrf_id_t)ifindex) && !vrf) {
+ flog_err(EC_ZEBRA_VRF_NOT_FOUND,
+ "VRF %s id %u does not exist", name,
+ ifindex);
+ exit(-1);
+ }
+ if (vrf && strcmp(name, vrf->name)) {
+ flog_err(EC_ZEBRA_VRF_MISCONFIGURED,
+ "VRF %s id %u table id overlaps existing vrf %s(%d), misconfiguration exiting",
+ name, ifindex, vrf->name, vrf->vrf_id);
exit(-1);
}
}
@@ -1696,8 +1660,10 @@ static void interface_if_protodown(struct interface *ifp, bool protodown,
uint32_t rc_bitfield)
{
struct zebra_if *zif = ifp->info;
- bool old_protodown;
+ bool old_protodown, reason_extern;
+ reason_extern = !!CHECK_FLAG(zif->protodown_rc,
+ ZEBRA_PROTODOWN_EXTERNAL);
/*
* Set our reason code to note it wasn't us.
* If the reason we got from the kernel is ONLY frr though, don't
@@ -1713,8 +1679,8 @@ static void interface_if_protodown(struct interface *ifp, bool protodown,
return;
if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_DPLANE)
- zlog_debug("interface %s dplane change, protodown %s",
- ifp->name, protodown ? "on" : "off");
+ zlog_debug("interface %s dplane change, protodown %s curr reason_extern %u",
+ ifp->name, protodown ? "on" : "off", reason_extern);
/* Set protodown, respectively */
COND_FLAG(zif->flags, ZIF_FLAG_PROTODOWN, protodown);
@@ -1739,6 +1705,13 @@ static void interface_if_protodown(struct interface *ifp, bool protodown,
return;
}
+ if (!protodown && reason_extern) {
+ if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("bond member %s has protodown reason external and clear the reason, skip reinstall.",
+ ifp->name);
+ return;
+ }
+
if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
"bond mbr %s reinstate protodown %s in the dplane",
diff --git a/zebra/interface.h b/zebra/interface.h
index 7d633f3..8d19c18 100644
--- a/zebra/interface.h
+++ b/zebra/interface.h
@@ -331,11 +331,6 @@ void link_param_cmd_set_float(struct interface *ifp, float *field,
void link_param_cmd_unset(struct interface *ifp, uint32_t type);
/* Nexthop group connected functions */
-extern void if_nhg_dependents_add(struct interface *ifp,
- struct nhg_hash_entry *nhe);
-extern void if_nhg_dependents_del(struct interface *ifp,
- struct nhg_hash_entry *nhe);
-extern unsigned int if_nhg_dependents_count(const struct interface *ifp);
extern bool if_nhg_dependents_is_empty(const struct interface *ifp);
extern void vrf_add_update(struct vrf *vrfp);
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index 8a64a1e..d2f1db6 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -619,6 +619,11 @@ static void netlink_install_filter(int sock, uint32_t pid, uint32_t dplane_pid)
safe_strerror(errno));
}
+/*
+ * Please note, the assumption with this function is that the
+ * flags passed in that are bit masked with type, we are implicitly
+ * assuming that this is handling the NLA_F_NESTED ilk.
+ */
void netlink_parse_rtattr_flags(struct rtattr **tb, int max, struct rtattr *rta,
int len, unsigned short flags)
{
@@ -638,8 +643,19 @@ void netlink_parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta,
{
memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
while (RTA_OK(rta, len)) {
- if (rta->rta_type <= max)
- tb[rta->rta_type] = rta;
+ /*
+ * The type may be &'ed with NLA_F_NESTED
+ * which puts data in the upper 8 bits of the
+ * rta_type. Mask it off and save the actual
+ * underlying value to be placed into the array.
+ * This way we don't accidently crash in the future
+ * when the kernel sends us new data and we try
+ * to write well beyond the end of the array.
+ */
+ uint16_t type = rta->rta_type & NLA_TYPE_MASK;
+
+ if (type <= max)
+ tb[type] = rta;
rta = RTA_NEXT(rta, len);
}
}
diff --git a/zebra/main.c b/zebra/main.c
index 27e05e7..ea1e1cb 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -26,6 +26,7 @@
#include "routemap.h"
#include "routing_nb.h"
#include "mgmt_be_client.h"
+#include "libagentx.h"
#include "zebra/zebra_router.h"
#include "zebra/zebra_errors.h"
@@ -203,6 +204,7 @@ static void sigint(void)
rib_update_finish();
list_delete(&zrouter.client_list);
+ list_delete(&zrouter.stale_client_list);
/*
* Besides other clean-ups zebra's vrf_disable() also enqueues installed
@@ -434,6 +436,7 @@ int main(int argc, char **argv)
zrouter.master = frr_init();
/* Zebra related initialize. */
+ libagentx_init();
zebra_router_init(asic_offload, notify_on_ack, v6_with_v4_nexthop);
zserv_init();
zebra_rib_init();
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 70ace35..11c1330 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -605,10 +605,6 @@ void zebra_interface_address_add_update(struct interface *ifp,
client, ifp, ifc);
}
}
- /* interface associated NHGs may have been deleted,
- * re-sync zebra -> dplane NHGs
- */
- zebra_interface_nhg_reinstall(ifp);
}
/* Interface address deletion. */
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index f092fc5..01b527e 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -1550,7 +1550,7 @@ static ssize_t fill_seg6ipt_encap(char *buffer, size_t buflen,
srh->first_segment = segs->num_segs - 1;
for (i = 0; i < segs->num_segs; i++) {
- memcpy(&srh->segments[i], &segs->seg[i],
+ memcpy(&srh->segments[segs->num_segs - i - 1], &segs->seg[i],
sizeof(struct in6_addr));
}
@@ -1683,6 +1683,16 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
sizeof(struct in_addr)))
return false;
break;
+ case ZEBRA_SEG6_LOCAL_ACTION_END_DX6:
+ if (!nl_attr_put32(nlmsg, req_size,
+ SEG6_LOCAL_ACTION,
+ SEG6_LOCAL_ACTION_END_DX6))
+ return false;
+ if (!nl_attr_put(nlmsg, req_size,
+ SEG6_LOCAL_NH6, &ctx->nh6,
+ sizeof(struct in_addr)))
+ return false;
+ break;
case ZEBRA_SEG6_LOCAL_ACTION_END_DT6:
if (!nl_attr_put32(nlmsg, req_size,
SEG6_LOCAL_ACTION,
@@ -1714,7 +1724,6 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
return false;
break;
case ZEBRA_SEG6_LOCAL_ACTION_END_DX2:
- case ZEBRA_SEG6_LOCAL_ACTION_END_DX6:
case ZEBRA_SEG6_LOCAL_ACTION_END_B6:
case ZEBRA_SEG6_LOCAL_ACTION_END_B6_ENCAP:
case ZEBRA_SEG6_LOCAL_ACTION_END_BM:
@@ -1882,6 +1891,36 @@ static inline bool _netlink_set_tag(struct nlmsghdr *n, unsigned int maxlen,
return true;
}
+/*
+ * The function returns true if the attribute could be added
+ * to the message, otherwise false is returned.
+ */
+static int netlink_route_nexthop_encap(bool fpm, struct nlmsghdr *n,
+ size_t nlen, const struct nexthop *nh)
+{
+ struct rtattr *nest;
+
+ if (!fpm)
+ return true;
+
+ switch (nh->nh_encap_type) {
+ case NET_VXLAN:
+ if (!nl_attr_put16(n, nlen, RTA_ENCAP_TYPE, nh->nh_encap_type))
+ return false;
+
+ nest = nl_attr_nest(n, nlen, RTA_ENCAP);
+ if (!nest)
+ return false;
+
+ if (!nl_attr_put32(n, nlen, 0 /* VXLAN_VNI */, nh->nh_encap.vni))
+ return false;
+ nl_attr_nest_end(n, nest);
+ break;
+ }
+
+ return true;
+}
+
/* This function takes a nexthop as argument and
* appends to the given netlink msg. If the nexthop
* defines a preferred source, the src parameter
@@ -1900,10 +1939,13 @@ static inline bool _netlink_set_tag(struct nlmsghdr *n, unsigned int maxlen,
* The function returns true if the nexthop could be added
* to the message, otherwise false is returned.
*/
-static bool _netlink_route_build_multipath(
- const struct prefix *p, const char *routedesc, int bytelen,
- const struct nexthop *nexthop, struct nlmsghdr *nlmsg, size_t req_size,
- struct rtmsg *rtmsg, const union g_addr **src, route_tag_t tag)
+static bool _netlink_route_build_multipath(const struct prefix *p,
+ const char *routedesc, int bytelen,
+ const struct nexthop *nexthop,
+ struct nlmsghdr *nlmsg,
+ size_t req_size, struct rtmsg *rtmsg,
+ const union g_addr **src,
+ route_tag_t tag, bool fpm)
{
char label_buf[256];
struct vrf *vrf;
@@ -2011,6 +2053,13 @@ static bool _netlink_route_build_multipath(
if (!_netlink_set_tag(nlmsg, req_size, tag))
return false;
+ /*
+ * Add encapsulation information when installing via
+ * FPM.
+ */
+ if (!netlink_route_nexthop_encap(fpm, nlmsg, req_size, nexthop))
+ return false;
+
nl_attr_rtnh_end(nlmsg, rtnh);
return true;
}
@@ -2045,7 +2094,7 @@ _netlink_mpls_build_multipath(const struct prefix *p, const char *routedesc,
bytelen = (family == AF_INET ? 4 : 16);
return _netlink_route_build_multipath(p, routedesc, bytelen,
nhlfe->nexthop, nlmsg, req_size,
- rtmsg, src, 0);
+ rtmsg, src, 0, false);
}
static void _netlink_mpls_debug(int cmd, uint32_t label, const char *routedesc)
@@ -2141,34 +2190,6 @@ static bool nexthop_set_src(const struct nexthop *nexthop, int family,
}
/*
- * The function returns true if the attribute could be added
- * to the message, otherwise false is returned.
- */
-static int netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen,
- struct nexthop *nh)
-{
- struct rtattr *nest;
-
- switch (nh->nh_encap_type) {
- case NET_VXLAN:
- if (!nl_attr_put16(n, nlen, RTA_ENCAP_TYPE, nh->nh_encap_type))
- return false;
-
- nest = nl_attr_nest(n, nlen, RTA_ENCAP);
- if (!nest)
- return false;
-
- if (!nl_attr_put32(n, nlen, 0 /* VXLAN_VNI */,
- nh->nh_encap.vni))
- return false;
- nl_attr_nest_end(n, nest);
- break;
- }
-
- return true;
-}
-
-/*
* Routing table change via netlink interface, using a dataplane context object
*
* Returns -1 on failure, 0 when the msg doesn't fit entirely in the buffer
@@ -2360,6 +2381,14 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx
break;
setsrc = nexthop_set_src(nexthop, p->family, &src);
+ if (setsrc && IS_ZEBRA_DEBUG_KERNEL) {
+ if (p->family == AF_INET)
+ zlog_debug("%s: %pFX set src %pI4",
+ __func__, p, &src.ipv4);
+ else if (p->family == AF_INET6)
+ zlog_debug("%s: %pFX set src %pI6",
+ __func__, p, &src.ipv6);
+ }
}
if (setsrc) {
@@ -2402,6 +2431,16 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx
setsrc = nexthop_set_src(nexthop, p->family,
&src);
+ if (setsrc && IS_ZEBRA_DEBUG_KERNEL) {
+ if (p->family == AF_INET)
+ zlog_debug("%s: %pFX set src %pI4",
+ __func__, p,
+ &src.ipv4);
+ else if (p->family == AF_INET6)
+ zlog_debug("%s: %pFX set src %pI6",
+ __func__, p,
+ &src.ipv6);
+ }
continue;
}
@@ -2422,12 +2461,10 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx
* Add encapsulation information when
* installing via FPM.
*/
- if (fpm) {
- if (!netlink_route_nexthop_encap(&req->n,
- datalen,
- nexthop))
- return 0;
- }
+ if (!netlink_route_nexthop_encap(fpm, &req->n,
+ datalen,
+ nexthop))
+ return 0;
nexthop_num++;
break;
@@ -2463,6 +2500,16 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx
setsrc = nexthop_set_src(nexthop, p->family,
&src);
+ if (setsrc && IS_ZEBRA_DEBUG_KERNEL) {
+ if (p->family == AF_INET)
+ zlog_debug("%s: %pFX set src %pI4",
+ __func__, p,
+ &src.ipv4);
+ else if (p->family == AF_INET6)
+ zlog_debug("%s: %pFX set src %pI6",
+ __func__, p,
+ &src.ipv6);
+ }
continue;
}
@@ -2472,22 +2519,16 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx
: "multipath";
nexthop_num++;
- if (!_netlink_route_build_multipath(
- p, routedesc, bytelen, nexthop,
- &req->n, datalen, &req->r, &src1,
- tag))
+ if (!_netlink_route_build_multipath(p, routedesc,
+ bytelen,
+ nexthop,
+ &req->n,
+ datalen,
+ &req->r,
+ &src1, tag,
+ fpm))
return 0;
- /*
- * Add encapsulation information when installing via
- * FPM.
- */
- if (fpm) {
- if (!netlink_route_nexthop_encap(
- &req->n, datalen, nexthop))
- return 0;
- }
-
if (!setsrc && src1) {
if (p->family == AF_INET)
src.ipv4 = src1->ipv4;
@@ -2931,6 +2972,18 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
sizeof(struct in_addr)))
return 0;
break;
+ case SEG6_LOCAL_ACTION_END_DX6:
+ if (!nl_attr_put32(&req->n,
+ buflen,
+ SEG6_LOCAL_ACTION,
+ SEG6_LOCAL_ACTION_END_DX6))
+ return 0;
+ if (!nl_attr_put(&req->n, buflen,
+ SEG6_LOCAL_NH6,
+ &ctx->nh6,
+ sizeof(struct in_addr)))
+ return 0;
+ break;
case SEG6_LOCAL_ACTION_END_DT6:
if (!nl_attr_put32(
&req->n, buflen,
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 6aca643..470391d 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -184,13 +184,13 @@ static int rtadv_recv_packet(struct zebra_vrf *zvrf, int sock, uint8_t *buf,
static void rtadv_send_packet(int sock, struct interface *ifp,
enum ipv6_nd_suppress_ra_status stop)
{
- struct msghdr msg;
- struct iovec iov;
+ struct msghdr msg = { 0 };
+ struct iovec iov = { 0 };
struct cmsghdr *cmsgptr;
struct in6_pktinfo *pkt;
- struct sockaddr_in6 addr;
- unsigned char buf[RTADV_MSG_SIZE];
- char adata[RTADV_ADATA_SIZE];
+ struct sockaddr_in6 addr = { 0 };
+ unsigned char buf[RTADV_MSG_SIZE] = { 0 };
+ char adata[RTADV_ADATA_SIZE] = { 0 };
struct nd_router_advert *rtadv;
int ret;
diff --git a/zebra/subdir.am b/zebra/subdir.am
index d9c8d90..f767447 100644
--- a/zebra/subdir.am
+++ b/zebra/subdir.am
@@ -19,6 +19,12 @@ if LINUX
module_LTLIBRARIES += zebra/zebra_cumulus_mlag.la
endif
+#if FPM_LISTENER
+sbin_PROGRAMS += zebra/fpm_listener
+zebra_fpm_listener_SOURCES = zebra/fpm_listener.c
+zebra_fpm_listener_LDADD = lib/libfrr.la
+#endf
+
# Dataplane sample plugin
if DEV_BUILD
module_LTLIBRARIES += zebra/dplane_sample_plugin.la
@@ -116,6 +122,7 @@ zebra_zebra_SOURCES = \
clippy_scan += \
zebra/debug.c \
+ zebra/dplane_fpm_nl.c \
zebra/interface.c \
zebra/rtadv.c \
zebra/zebra_mlag_vty.c \
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 76cabd1..d585ef9 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -1724,7 +1724,7 @@ static bool zapi_read_nexthops(struct zserv *client, struct prefix *p,
* Let's convert the weights to a scaled value
* between 1 and zrouter.nexthop_weight_scale_value
* This is a simple application of a ratio:
- * scaled_weight/zrouter.nexthop_weight_scale_value =
+ * scaled_weight/zrouter.nexthop_weight_scale_value =
* weight/max_weight
* This translates to:
* scaled_weight = weight * zrouter.nexthop_weight_scale_value
@@ -1738,9 +1738,8 @@ static bool zapi_read_nexthops(struct zserv *client, struct prefix *p,
for (i = 0; i < nexthop_num; i++) {
znh = &nhops[i];
- tmp = (uint64_t)znh->weight *
- zrouter.nexthop_weight_scale_value;
- znh->weight = MAX(1, ((uint32_t)(tmp / max_weight)));
+ tmp = znh->weight * zrouter.nexthop_weight_scale_value;
+ znh->weight = MAX(1, (tmp / max_weight));
}
}
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index 99693a5..3944876 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -39,6 +39,13 @@ DEFINE_MTYPE_STATIC(ZEBRA, DP_NS, "DPlane NSes");
# define AOK 0
#endif
+/*
+ * Dataplane API version. This must be updated when any incompatible changes
+ * are made. The minor version (at least) should be updated when new APIs
+ * are introduced.
+ */
+static uint32_t zdplane_version = MAKE_FRRVERSION(2, 0, 0);
+
/* Control for collection of extra interface info with route updates; a plugin
* can enable the extra info via a dplane api.
*/
@@ -664,6 +671,12 @@ neigh_update_internal(enum dplane_op_e op, const struct interface *ifp,
* Public APIs
*/
+/* Access the dplane API version */
+uint32_t zebra_dplane_get_version(void)
+{
+ return zdplane_version;
+}
+
/* Obtain thread_master for dataplane thread */
struct event_loop *dplane_get_thread_master(void)
{
@@ -6351,7 +6364,7 @@ dplane_provider_dequeue_out_ctx(struct zebra_dplane_provider *prov)
*/
bool dplane_provider_is_threaded(const struct zebra_dplane_provider *prov)
{
- return (prov->dp_flags & DPLANE_PROV_FLAG_THREADED);
+ return CHECK_FLAG(prov->dp_flags, DPLANE_PROV_FLAG_THREADED);
}
#ifdef HAVE_NETLINK
@@ -7428,6 +7441,11 @@ static void dplane_thread_loop(struct event *event)
zlog_debug("dplane dequeues %d completed work from provider %s",
counter, dplane_provider_get_name(prov));
+ if (event_should_yield(event)) {
+ reschedule = true;
+ break;
+ }
+
/* Locate next provider */
prov = dplane_prov_list_next(&zdplane_info.dg_providers, prov);
}
diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h
index 2f7d218..060b1c8 100644
--- a/zebra/zebra_dplane.h
+++ b/zebra/zebra_dplane.h
@@ -24,6 +24,13 @@
extern "C" {
#endif
+/* Retrieve the dataplane API version number; see libfrr.h to decode major,
+ * minor, sub version values.
+ * Plugins should pay attention to the major version number, at least, to
+ * be able to detect API changes that may not be backward-compatible.
+ */
+uint32_t zebra_dplane_get_version(void);
+
/* Key netlink info from zebra ns */
struct zebra_dplane_info {
ns_id_t ns_id;
diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c
index 147f5b9..ebb5a42 100644
--- a/zebra/zebra_evpn.c
+++ b/zebra/zebra_evpn.c
@@ -109,21 +109,14 @@ void zebra_evpn_print(struct zebra_evpn *zevpn, void **ctxt)
} else {
json_object_int_add(json, "vni", zevpn->vni);
json_object_string_add(json, "type", "L2");
-#if CONFDATE > 20240210
-CPP_NOTICE("Drop `vrf` from JSON output")
-#endif
- json_object_string_add(json, "vrf",
- vrf_id_to_name(zevpn->vrf_id));
- json_object_string_add(json, "tenantVrf",
- vrf_id_to_name(zevpn->vrf_id));
+ json_object_string_add(json, "tenantVrf", vrf_id_to_name(zevpn->vrf_id));
}
if (!zevpn->vxlan_if) { // unexpected
if (json == NULL)
vty_out(vty, " VxLAN interface: unknown\n");
else
- json_object_string_add(json, "vxlanInterface",
- "unknown");
+ json_object_string_add(json, "vxlanInterface", "unknown");
return;
}
num_macs = num_valid_macs(zevpn);
@@ -135,35 +128,21 @@ CPP_NOTICE("Drop `vrf` from JSON output")
(zevpn->svi_if ? zevpn->svi_if->name : ""));
vty_out(vty, " SVI ifIndex: %u\n",
(zevpn->svi_if ? zevpn->svi_if->ifindex : 0));
- vty_out(vty, " Local VTEP IP: %pI4\n",
- &zevpn->local_vtep_ip);
- vty_out(vty, " Mcast group: %pI4\n",
- &zevpn->mcast_grp);
+ vty_out(vty, " Local VTEP IP: %pI4\n", &zevpn->local_vtep_ip);
+ vty_out(vty, " Mcast group: %pI4\n", &zevpn->mcast_grp);
} else {
- json_object_string_add(json, "vxlanInterface",
- zevpn->vxlan_if->name);
-#if CONFDATE > 20240210
-CPP_NOTICE("Drop `ifindex` from JSON output")
-#endif
- json_object_int_add(json, "ifindex", zevpn->vxlan_if->ifindex);
- json_object_int_add(json, "vxlanIfindex",
- zevpn->vxlan_if->ifindex);
+ json_object_string_add(json, "vxlanInterface", zevpn->vxlan_if->name);
+ json_object_int_add(json, "vxlanIfindex", zevpn->vxlan_if->ifindex);
if (zevpn->svi_if) {
- json_object_string_add(json, "sviInterface",
- zevpn->svi_if->name);
- json_object_int_add(json, "sviIfindex",
- zevpn->svi_if->ifindex);
+ json_object_string_add(json, "sviInterface", zevpn->svi_if->name);
+ json_object_int_add(json, "sviIfindex", zevpn->svi_if->ifindex);
}
- json_object_string_addf(json, "vtepIp", "%pI4",
- &zevpn->local_vtep_ip);
- json_object_string_addf(json, "mcastGroup", "%pI4",
- &zevpn->mcast_grp);
+ json_object_string_addf(json, "vtepIp", "%pI4", &zevpn->local_vtep_ip);
+ json_object_string_addf(json, "mcastGroup", "%pI4", &zevpn->mcast_grp);
json_object_string_add(json, "advertiseGatewayMacip",
- zevpn->advertise_gw_macip ? "Yes"
- : "No");
+ zevpn->advertise_gw_macip ? "Yes" : "No");
json_object_string_add(json, "advertiseSviMacip",
- zevpn->advertise_svi_macip ? "Yes"
- : "No");
+ zevpn->advertise_svi_macip ? "Yes" : "No");
json_object_int_add(json, "numMacs", num_macs);
json_object_int_add(json, "numArpNd", num_neigh);
}
@@ -179,28 +158,21 @@ CPP_NOTICE("Drop `ifindex` from JSON output")
json_vtep_list = json_object_new_array();
for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
const char *flood_str = lookup_msg(
- zvtep_flood_str, zvtep->flood_control,
- VXLAN_FLOOD_STR_DEFAULT);
+ zvtep_flood_str, zvtep->flood_control, VXLAN_FLOOD_STR_DEFAULT);
if (json == NULL) {
- vty_out(vty, " %pI4 flood: %s\n",
- &zvtep->vtep_ip,
- flood_str);
+ vty_out(vty, " %pI4 flood: %s\n", &zvtep->vtep_ip, flood_str);
} else {
json_vtep = json_object_new_object();
- json_object_string_addf(json_vtep, "ip", "%pI4",
- &zvtep->vtep_ip);
- json_object_string_add(json_vtep, "flood",
- flood_str);
- json_object_array_add(json_vtep_list,
- json_vtep);
+ json_object_string_addf(json_vtep, "ip", "%pI4", &zvtep->vtep_ip);
+ json_object_string_add(json_vtep, "flood", flood_str);
+ json_object_array_add(json_vtep_list, json_vtep);
}
num_vteps++;
}
if (json) {
json_object_int_add(json, "numRemoteVteps", num_vteps);
- json_object_object_add(json, "remoteVteps",
- json_vtep_list);
+ json_object_object_add(json, "remoteVteps", json_vtep_list);
}
}
if (json == NULL) {
@@ -261,8 +233,7 @@ void zebra_evpn_print_hash(struct hash_bucket *bucket, void *ctxt[])
json_object_int_add(json_evpn, "vni", zevpn->vni);
json_object_string_add(json_evpn, "type", "L2");
json_object_string_add(json_evpn, "vxlanIf",
- zevpn->vxlan_if ? zevpn->vxlan_if->name
- : "unknown");
+ zevpn->vxlan_if ? zevpn->vxlan_if->name : "unknown");
json_object_int_add(json_evpn, "numMacs", num_macs);
json_object_int_add(json_evpn, "numArpNd", num_neigh);
json_object_int_add(json_evpn, "numRemoteVteps", num_vteps);
@@ -272,13 +243,10 @@ void zebra_evpn_print_hash(struct hash_bucket *bucket, void *ctxt[])
json_vtep_list = json_object_new_array();
for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
json_ip_str = json_object_new_string(
- inet_ntop(AF_INET, &zvtep->vtep_ip, buf,
- sizeof(buf)));
- json_object_array_add(json_vtep_list,
- json_ip_str);
+ inet_ntop(AF_INET, &zvtep->vtep_ip, buf, sizeof(buf)));
+ json_object_array_add(json_vtep_list, json_ip_str);
}
- json_object_object_add(json_evpn, "remoteVteps",
- json_vtep_list);
+ json_object_object_add(json_evpn, "remoteVteps", json_vtep_list);
}
json_object_object_add(json, vni_str, json_evpn);
}
@@ -383,7 +351,7 @@ static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
if (!client)
return 0;
- s = stream_new(ZEBRA_MAX_PACKET_SIZ);
+ s = stream_new(ZEBRA_SMALL_PACKET_SIZE);
zclient_create_header(s, cmd, vrf_id);
stream_put(s, p, sizeof(struct prefix));
@@ -490,8 +458,7 @@ int zebra_evpn_gw_macip_del(struct interface *ifp, struct zebra_evpn *zevpn,
/* Remove neighbor from BGP. */
zebra_evpn_neigh_send_del_to_client(zevpn->vni, &n->ip, &n->emac,
- n->flags, ZEBRA_NEIGH_ACTIVE,
- false /*force*/);
+ n->flags, ZEBRA_NEIGH_ACTIVE, false /*force*/);
/* Delete this neighbor entry. */
zebra_evpn_neigh_del(zevpn, n);
@@ -521,8 +488,7 @@ void zebra_evpn_gw_macip_del_for_evpn_hash(struct hash_bucket *bucket,
*/
if (zevpn->advertise_gw_macip) {
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("VNI: %u GW-MACIP enabled, retain gw-macip",
- zevpn->vni);
+ zlog_debug("VNI: %u GW-MACIP enabled, retain gw-macip", zevpn->vni);
return;
}
@@ -694,8 +660,7 @@ static int zebra_evpn_map_vlan_ns(struct ns *ns,
if (zif->brslave_info.br_if != br_if)
continue;
- vni_id =
- zebra_vxlan_if_access_vlan_vni_find(zif, br_if);
+ vni_id = zebra_vxlan_if_access_vlan_vni_find(zif, br_if);
if (vni_id) {
found = 1;
break;
@@ -732,9 +697,7 @@ struct zebra_evpn *zebra_evpn_map_vlan(struct interface *ifp,
in_param.zif = zif;
p_zevpn = &zevpn;
- ns_walk_func(zebra_evpn_map_vlan_ns,
- (void *)&in_param,
- (void **)p_zevpn);
+ ns_walk_func(zebra_evpn_map_vlan_ns, (void *)&in_param, (void **)p_zevpn);
return zevpn;
}
@@ -854,9 +817,7 @@ struct zebra_evpn *zebra_evpn_from_svi(struct interface *ifp,
return zevpn;
}
-static int zvni_map_to_macvlan_ns(struct ns *ns,
- void *_in_param,
- void **_p_ifp)
+static int zvni_map_to_macvlan_ns(struct ns *ns, void *_in_param, void **_p_ifp)
{
struct zebra_ns *zns = ns->info;
struct zebra_from_svi_param *in_param =
@@ -918,9 +879,7 @@ struct interface *zebra_evpn_map_to_macvlan(struct interface *br_if,
p_ifp = &tmp_if;
/* Identify corresponding VLAN interface. */
- ns_walk_func(zvni_map_to_macvlan_ns,
- (void *)&in_param,
- (void **)p_ifp);
+ ns_walk_func(zvni_map_to_macvlan_ns, (void *)&in_param, (void **)p_ifp);
return tmp_if;
}
@@ -1125,8 +1084,7 @@ struct zebra_evpn *zebra_evpn_add(vni_t vni)
/* Create hash table for MAC */
zevpn->mac_table = zebra_mac_db_create(buffer);
- snprintf(buffer, sizeof(buffer), "Zebra EVPN Neighbor Table vni: %u",
- vni);
+ snprintf(buffer, sizeof(buffer), "Zebra EVPN Neighbor Table vni: %u", vni);
/* Create hash table for neighbors */
zevpn->neigh_table = zebra_neigh_db_create(buffer);
@@ -1182,7 +1140,7 @@ int zebra_evpn_send_add_to_client(struct zebra_evpn *zevpn)
svi_index = zevpn->svi_if ? zevpn->svi_if->ifindex : 0;
- s = stream_new(ZEBRA_MAX_PACKET_SIZ);
+ s = stream_new(ZEBRA_SMALL_PACKET_SIZE);
zclient_create_header(s, ZEBRA_VNI_ADD, zebra_vrf_get_evpn_id());
stream_putl(s, zevpn->vni);
@@ -1205,8 +1163,8 @@ int zebra_evpn_send_add_to_client(struct zebra_evpn *zevpn)
client->vniadd_cnt++;
rc = zserv_send_message(client, s);
- if (!(zevpn->flags & ZEVPN_READY_FOR_BGP)) {
- zevpn->flags |= ZEVPN_READY_FOR_BGP;
+ if (!CHECK_FLAG(zevpn->flags, ZEVPN_READY_FOR_BGP)) {
+ SET_FLAG(zevpn->flags, ZEVPN_READY_FOR_BGP);
/* once the EVPN is sent the ES-EVIs can also be replayed
* to BGP
*/
@@ -1228,13 +1186,13 @@ int zebra_evpn_send_del_to_client(struct zebra_evpn *zevpn)
if (!client)
return 0;
- if (zevpn->flags & ZEVPN_READY_FOR_BGP) {
- zevpn->flags &= ~ZEVPN_READY_FOR_BGP;
+ if (CHECK_FLAG(zevpn->flags, ZEVPN_READY_FOR_BGP)) {
+ UNSET_FLAG(zevpn->flags, ZEVPN_READY_FOR_BGP);
/* the ES-EVIs must be removed from BGP before the EVPN is */
zebra_evpn_update_all_es(zevpn);
}
- s = stream_new(ZEBRA_MAX_PACKET_SIZ);
+ s = stream_new(ZEBRA_SMALL_PACKET_SIZE);
stream_reset(s);
zclient_create_header(s, ZEBRA_VNI_DEL, zebra_vrf_get_evpn_id());
@@ -1350,8 +1308,7 @@ int zebra_evpn_vtep_install(struct zebra_evpn *zevpn, struct zebra_vtep *zvtep)
if (is_vxlan_flooding_head_end() &&
(zvtep->flood_control == VXLAN_FLOOD_HEAD_END_REPL)) {
if (ZEBRA_DPLANE_REQUEST_FAILURE ==
- dplane_vtep_add(zevpn->vxlan_if,
- &zvtep->vtep_ip, zevpn->vni))
+ dplane_vtep_add(zevpn->vxlan_if, &zvtep->vtep_ip, zevpn->vni))
return -1;
}
@@ -1442,9 +1399,7 @@ static void zebra_evpn_process_sync_macip_add(struct zebra_evpn *zevpn,
zevpn->vni,
macaddr,
ipa_len ? " IP " : "",
- ipa_len ? ipaddr2str(ipaddr, ipbuf,
- sizeof(ipbuf))
- : "",
+ ipa_len ? ipaddr2str(ipaddr, ipbuf, sizeof(ipbuf)) : "",
sticky ? " sticky" : "",
remote_gw ? " remote_gw" : "");
return;
@@ -1459,16 +1414,13 @@ static void zebra_evpn_process_sync_macip_add(struct zebra_evpn *zevpn,
mac = zebra_evpn_mac_lookup(zevpn, macaddr);
if (!mac) {
mac = zebra_evpn_proc_sync_mac_update(zevpn, macaddr,
- ipa_len, ipaddr,
- flags, seq, esi);
+ ipa_len, ipaddr, flags, seq, esi);
}
if (!mac)
return;
n = zebra_evpn_neigh_lookup(zevpn, ipaddr);
- if (n
- && !zebra_evpn_neigh_is_bgp_seq_ok(zevpn, n, macaddr, seq,
- true))
+ if (n && !zebra_evpn_neigh_is_bgp_seq_ok(zevpn, n, macaddr, seq, true))
return;
zebra_evpn_proc_sync_neigh_update(zevpn, n, ipa_len, ipaddr,
@@ -1514,22 +1466,19 @@ void zebra_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr,
* SYNC - if ES is local
* REMOTE - if ES is not local
*/
- if (flags & ZEBRA_MACIP_TYPE_SYNC_PATH) {
+ if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SYNC_PATH)) {
struct zebra_evpn_es *es;
es = zebra_evpn_es_find(esi);
- if (es && (es->flags & ZEBRA_EVPNES_READY_FOR_BGP)) {
+ if (es && CHECK_FLAG(es->flags, ZEBRA_EVPNES_READY_FOR_BGP)) {
zebra_evpn_process_sync_macip_add(zevpn, macaddr,
- ipa_len, ipaddr,
- flags, seq, esi);
+ ipa_len, ipaddr, flags, seq, esi);
} else {
if (IS_ZEBRA_DEBUG_EVPN_MH_ES) {
char esi_str[ESI_STR_LEN];
esi_to_str(esi, esi_str, sizeof(esi_str));
- zlog_debug(
- "Ignore sync-macip add; ES %s is not ready",
- esi_str);
+ zlog_debug("Ignore sync-macip add; ES %s is not ready", esi_str);
}
}
@@ -1543,8 +1492,7 @@ void zebra_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr,
if (vtep_ip.s_addr) {
zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
if (!zvtep) {
- zvtep = zebra_evpn_vtep_add(zevpn, &vtep_ip,
- VXLAN_FLOOD_DISABLED);
+ zvtep = zebra_evpn_vtep_add(zevpn, &vtep_ip, VXLAN_FLOOD_DISABLED);
if (!zvtep) {
flog_err(
EC_ZEBRA_VTEP_ADD_FAILED,
@@ -1621,9 +1569,7 @@ void zebra_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr,
vnip = zebra_vxlan_if_vni_find(zif, vni);
if (!vnip) {
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug(
- "VNI %u not in interface upon remote MACIP DEL",
- vni);
+ zlog_debug("VNI %u not in interface upon remote MACIP DEL", vni);
return;
}
diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c
index 6d5cd66..bfc060d 100644
--- a/zebra/zebra_evpn_mac.c
+++ b/zebra/zebra_evpn_mac.c
@@ -103,9 +103,7 @@ static void zebra_evpn_mac_ifp_unlink(struct zebra_mac *zmac)
if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
zlog_debug("VNI %d MAC %pEA unlinked from ifp %s (%u)",
- zmac->zevpn->vni,
- &zmac->macaddr,
- ifp->name, ifp->ifindex);
+ zmac->zevpn->vni, &zmac->macaddr, ifp->name, ifp->ifindex);
zif = ifp->info;
list_delete_node(zif->mac_list, &zmac->ifp_listnode);
@@ -122,7 +120,7 @@ void zebra_evpn_mac_ifp_del(struct interface *ifp)
if (zif->mac_list) {
if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
zlog_debug("MAC list deleted for ifp %s (%u)",
- zif->ifp->name, zif->ifp->ifindex);
+ zif->ifp->name, zif->ifp->ifindex);
for (ALL_LIST_ELEMENTS_RO(zif->mac_list, node, zmac)) {
zebra_evpn_mac_ifp_unlink(zmac);
@@ -161,9 +159,7 @@ static void zebra_evpn_mac_ifp_link(struct zebra_mac *zmac,
if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
zlog_debug("VNI %d MAC %pEA linked to ifp %s (%u)",
- zmac->zevpn->vni,
- &zmac->macaddr,
- ifp->name, ifp->ifindex);
+ zmac->zevpn->vni, &zmac->macaddr, ifp->name, ifp->ifindex);
zmac->ifp = ifp;
listnode_init(&zmac->ifp_listnode, zmac);
@@ -205,7 +201,7 @@ int zebra_evpn_rem_mac_install(struct zebra_evpn *zevpn, struct zebra_mac *mac,
return -1;
sticky = !!CHECK_FLAG(mac->flags,
- (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW));
+ (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW));
/* If nexthop group for the FDB entry is inactive (not programmed in
* the dataplane) the MAC entry cannot be installed
@@ -249,7 +245,7 @@ int zebra_evpn_rem_mac_uninstall(struct zebra_evpn *zevpn,
enum zebra_dplane_result res;
/* If the MAC was not installed there is no need to uninstall it */
- if (!force && mac->es && !(mac->es->flags & ZEBRA_EVPNES_NHG_ACTIVE))
+ if (!force && mac->es && !CHECK_FLAG(mac->es->flags, ZEBRA_EVPNES_NHG_ACTIVE))
return -1;
if (!zevpn->vxlan_if) {
@@ -282,8 +278,7 @@ int zebra_evpn_rem_mac_uninstall(struct zebra_evpn *zevpn,
ifp = zevpn->vxlan_if;
vtep_ip = mac->fwd_info.r_vtep_ip;
- res = dplane_rem_mac_del(ifp, br_ifp, vid, &mac->macaddr, vni->vni,
- vtep_ip);
+ res = dplane_rem_mac_del(ifp, br_ifp, vid, &mac->macaddr, vni->vni, vtep_ip);
if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
return 0;
else
@@ -341,8 +336,7 @@ static void zebra_evpn_mac_get_access_info(struct zebra_mac *mac,
*vid = mac->fwd_info.local.vid;
zns = zebra_ns_lookup(mac->fwd_info.local.ns_id);
- *p_ifp = if_lookup_by_index_per_ns(zns,
- mac->fwd_info.local.ifindex);
+ *p_ifp = if_lookup_by_index_per_ns(zns, mac->fwd_info.local.ifindex);
}
}
@@ -355,26 +349,19 @@ static char *zebra_evpn_zebra_mac_flag_dump(struct zebra_mac *mac, char *buf,
return buf;
}
- snprintfrr(
- buf, len, "%s%s%s%s%s%s%s%s%s%s%s%s",
+ snprintfrr(buf, len, "%s%s%s%s%s%s%s%s%s%s%s%s",
CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) ? "LOC " : "",
CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) ? "REM " : "",
CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO) ? "AUTO " : "",
CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? "STICKY " : "",
- CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_RMAC) ? "REM Router "
- : "",
+ CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_RMAC) ? "REM Router " : "",
CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW) ? "Default GW " : "",
- CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW) ? "REM DEF GW "
- : "",
+ CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW) ? "REM DEF GW " : "",
CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE) ? "DUP " : "",
CHECK_FLAG(mac->flags, ZEBRA_MAC_FPM_SENT) ? "FPM " : "",
- CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_ACTIVE)
- ? "PEER Active "
- : "",
+ CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_ACTIVE) ? "PEER Active " : "",
CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_PROXY) ? "PROXY " : "",
- CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE)
- ? "LOC Inactive "
- : "");
+ CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE) ? "LOC Inactive " : "");
return buf;
}
@@ -407,8 +394,7 @@ static void zebra_evpn_dad_mac_auto_recovery_exp(struct event *t)
zlog_debug(
"%s: duplicate addr mac %pEA flags %slearn count %u host count %u auto recovery expired",
__func__, &mac->macaddr,
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)),
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)),
mac->dad_count, listcount(mac->neigh_list));
}
@@ -418,8 +404,7 @@ static void zebra_evpn_dad_mac_auto_recovery_exp(struct event *t)
if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL))
ZEBRA_NEIGH_SET_INACTIVE(nbr);
else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE))
- zebra_evpn_rem_neigh_install(
- zevpn, nbr, false /*was_static*/);
+ zebra_evpn_rem_neigh_install(zevpn, nbr, false /*was_static*/);
}
UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
@@ -438,13 +423,11 @@ static void zebra_evpn_dad_mac_auto_recovery_exp(struct event *t)
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
/* Inform to BGP */
if (zebra_evpn_mac_send_add_to_client(zevpn->vni, &mac->macaddr,
- mac->flags, mac->loc_seq,
- mac->es))
+ mac->flags, mac->loc_seq, mac->es))
return;
/* Process all neighbors associated with this MAC. */
- zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
- 0 /*es_change*/);
+ zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0, 0 /*es_change*/);
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
zebra_evpn_process_neigh_on_remote_mac_add(zevpn, mac);
@@ -479,8 +462,7 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
zlog_debug(
"%s: duplicate addr MAC %pEA flags %sskip update to client, learn count %u recover time %u",
__func__, &mac->macaddr,
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)),
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)),
mac->dad_count, zvrf->dad_freeze_time);
}
/* For duplicate MAC do not update
@@ -516,8 +498,7 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
zlog_debug(
"%s: duplicate addr MAC %pEA flags %sdetection time passed, reset learn count %u",
__func__, &mac->macaddr,
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)),
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)),
mac->dad_count);
}
@@ -545,10 +526,10 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
if (mac->dad_count >= zvrf->dad_max_moves) {
flog_warn(EC_ZEBRA_DUP_MAC_DETECTED,
- "VNI %u: MAC %pEA detected as duplicate during %s VTEP %pI4",
- mac->zevpn->vni, &mac->macaddr,
- is_local ? "local update, last" :
- "remote update, from", &vtep_ip);
+ "VNI %u: MAC %pEA detected as duplicate during %s VTEP %pI4",
+ mac->zevpn->vni, &mac->macaddr,
+ is_local ? "local update, last" : "remote update, from",
+ &vtep_ip);
SET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
@@ -583,15 +564,13 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
zlog_debug(
"%s: duplicate addr MAC %pEA flags %sauto recovery time %u start",
__func__, &mac->macaddr,
- zebra_evpn_zebra_mac_flag_dump(
- mac, mac_buf, sizeof(mac_buf)),
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)),
zvrf->dad_freeze_time);
}
event_add_timer(zrouter.master,
- zebra_evpn_dad_mac_auto_recovery_exp,
- mac, zvrf->dad_freeze_time,
- &mac->dad_mac_auto_recovery_timer);
+ zebra_evpn_dad_mac_auto_recovery_exp, mac,
+ zvrf->dad_freeze_time, &mac->dad_mac_auto_recovery_timer);
}
/* In case of local update, do not inform to client (BGPd),
@@ -638,22 +617,18 @@ void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json)
zebra_evpn_mac_get_access_info(mac, &ifp, &vid);
json_object_string_add(json_mac, "type", "local");
if (ifp) {
- json_object_string_add(json_mac, "intf",
- ifp->name);
- json_object_int_add(json_mac, "ifindex",
- ifp->ifindex);
+ json_object_string_add(json_mac, "intf", ifp->name);
+ json_object_int_add(json_mac, "ifindex", ifp->ifindex);
}
if (vid)
json_object_int_add(json_mac, "vlan", vid);
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
json_object_string_add(json_mac, "type", "remote");
if (mac->es)
- json_object_string_add(json_mac, "remoteEs",
- mac->es->esi_str);
+ json_object_string_add(json_mac, "remoteEs", mac->es->esi_str);
else
json_object_string_addf(
- json_mac, "remoteVtep", "%pI4",
- &mac->fwd_info.r_vtep_ip);
+ json_mac, "remoteVtep", "%pI4", &mac->fwd_info.r_vtep_ip);
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
json_object_string_add(json_mac, "type", "auto");
@@ -664,12 +639,10 @@ void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json)
json_object_boolean_true_add(json_mac, "sviMac");
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW))
- json_object_boolean_true_add(json_mac,
- "defaultGateway");
+ json_object_boolean_true_add(json_mac, "defaultGateway");
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW))
- json_object_boolean_true_add(json_mac,
- "remoteGatewayMac");
+ json_object_boolean_true_add(json_mac, "remoteGatewayMac");
json_object_string_add(json_mac, "uptime", up_str);
json_object_int_add(json_mac, "localSequence", mac->loc_seq);
@@ -690,46 +663,31 @@ void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json)
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_ACTIVE))
json_object_boolean_true_add(json_mac, "peerActive");
if (mac->hold_timer)
- json_object_string_add(
- json_mac, "peerActiveHold",
- event_timer_to_hhmmss(thread_buf,
- sizeof(thread_buf),
- mac->hold_timer));
+ json_object_string_add(json_mac, "peerActiveHold",
+ event_timer_to_hhmmss(thread_buf, sizeof(thread_buf), mac->hold_timer));
if (mac->es)
- json_object_string_add(json_mac, "esi",
- mac->es->esi_str);
+ json_object_string_add(json_mac, "esi", mac->es->esi_str);
/* print all the associated neigh */
if (!listcount(mac->neigh_list))
json_object_string_add(json_mac, "neighbors", "none");
else {
json_object *json_active_nbrs = json_object_new_array();
- json_object *json_inactive_nbrs =
- json_object_new_array();
+ json_object *json_inactive_nbrs = json_object_new_array();
json_object *json_nbrs = json_object_new_object();
for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
if (IS_ZEBRA_NEIGH_ACTIVE(n))
- json_object_array_add(
- json_active_nbrs,
- json_object_new_string(
- ipaddr2str(
- &n->ip, buf2,
- sizeof(buf2))));
+ json_object_array_add(json_active_nbrs,
+ json_object_new_string(ipaddr2str(&n->ip, buf2, sizeof(buf2))));
else
json_object_array_add(
json_inactive_nbrs,
- json_object_new_string(
- ipaddr2str(
- &n->ip, buf2,
- sizeof(buf2))));
+ json_object_new_string(ipaddr2str(&n->ip, buf2, sizeof(buf2))));
}
- json_object_object_add(json_nbrs, "active",
- json_active_nbrs);
- json_object_object_add(json_nbrs, "inactive",
- json_inactive_nbrs);
- json_object_object_add(json_mac, "neighbors",
- json_nbrs);
+ json_object_object_add(json_nbrs, "active", json_active_nbrs);
+ json_object_object_add(json_nbrs, "inactive", json_inactive_nbrs);
+ json_object_object_add(json_mac, "neighbors", json_nbrs);
}
json_object_object_add(json, buf1, json_mac);
@@ -746,18 +704,15 @@ void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json)
vty_out(vty, " ESI: %s\n", mac->es->esi_str);
if (ifp)
- vty_out(vty, " Intf: %s(%u)", ifp->name,
- ifp->ifindex);
+ vty_out(vty, " Intf: %s(%u)", ifp->name, ifp->ifindex);
else
vty_out(vty, " Intf: -");
vty_out(vty, " VLAN: %u", vid);
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
if (mac->es)
- vty_out(vty, " Remote ES: %s",
- mac->es->esi_str);
+ vty_out(vty, " Remote ES: %s", mac->es->esi_str);
else
- vty_out(vty, " Remote VTEP: %pI4",
- &mac->fwd_info.r_vtep_ip);
+ vty_out(vty, " Remote VTEP: %pI4", &mac->fwd_info.r_vtep_ip);
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
vty_out(vty, " Auto Mac ");
}
@@ -784,24 +739,18 @@ void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json)
vty_out(vty, " peer-active");
if (mac->hold_timer)
vty_out(vty, " (ht: %s)",
- event_timer_to_hhmmss(thread_buf,
- sizeof(thread_buf),
- mac->hold_timer));
+ event_timer_to_hhmmss(thread_buf, sizeof(thread_buf), mac->hold_timer));
vty_out(vty, "\n");
- vty_out(vty, " Local Seq: %u Remote Seq: %u\n", mac->loc_seq,
- mac->rem_seq);
+ vty_out(vty, " Local Seq: %u Remote Seq: %u\n", mac->loc_seq, mac->rem_seq);
vty_out(vty, " Uptime: %s\n", up_str);
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
vty_out(vty, " Duplicate, detected at %s",
- time_to_string(mac->dad_dup_detect_time,
- timebuf));
+ time_to_string(mac->dad_dup_detect_time, timebuf));
} else if (mac->dad_count) {
- monotime_since(&mac->detect_start_time,
- &detect_start_time);
+ monotime_since(&mac->detect_start_time, &detect_start_time);
if (detect_start_time.tv_sec <= zvrf->dad_time) {
- time_to_string(mac->detect_start_time.tv_sec,
- timebuf);
+ time_to_string(mac->detect_start_time.tv_sec, timebuf);
vty_out(vty,
" Duplicate detection started at %s, detection count %u\n",
timebuf, mac->dad_count);
@@ -816,9 +765,7 @@ void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json)
for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
vty_out(vty, " %s %s\n",
ipaddr2str(&n->ip, buf2, sizeof(buf2)),
- (IS_ZEBRA_NEIGH_ACTIVE(n)
- ? "Active"
- : "Inactive"));
+ (IS_ZEBRA_NEIGH_ACTIVE(n) ? "Active" : "Inactive"));
}
}
@@ -831,9 +778,9 @@ static char *zebra_evpn_print_mac_flags(struct zebra_mac *mac, char *flags_buf,
{
snprintf(flags_buf, flags_buf_sz, "%s%s%s%s",
mac->sync_neigh_cnt ? "N" : "",
- (mac->flags & ZEBRA_MAC_ES_PEER_ACTIVE) ? "P" : "",
- (mac->flags & ZEBRA_MAC_ES_PEER_PROXY) ? "X" : "",
- (mac->flags & ZEBRA_MAC_LOCAL_INACTIVE) ? "I" : "");
+ CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_ACTIVE) ? "P" : "",
+ CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_PROXY) ? "X" : "",
+ CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE) ? "I" : "");
return flags_buf;
}
@@ -870,14 +817,12 @@ void zebra_evpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt)
zebra_evpn_mac_get_access_info(mac, &ifp, &vid);
if (json_mac_hdr == NULL) {
vty_out(vty, "%-17s %-6s %-5s %-30s", buf1, "local",
- zebra_evpn_print_mac_flags(mac, flags_buf,
- sizeof(flags_buf)),
+ zebra_evpn_print_mac_flags(mac, flags_buf, sizeof(flags_buf)),
ifp ? ifp->name : "-");
} else {
json_object_string_add(json_mac, "type", "local");
if (ifp)
- json_object_string_add(json_mac, "intf",
- ifp->name);
+ json_object_string_add(json_mac, "intf", ifp->name);
}
if (vid) {
if (json_mac_hdr == NULL)
@@ -891,18 +836,13 @@ void zebra_evpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt)
vty_out(vty, " %u/%u", mac->loc_seq, mac->rem_seq);
vty_out(vty, "\n");
} else {
- json_object_int_add(json_mac, "localSequence",
- mac->loc_seq);
- json_object_int_add(json_mac, "remoteSequence",
- mac->rem_seq);
- json_object_int_add(json_mac, "detectionCount",
- mac->dad_count);
+ json_object_int_add(json_mac, "localSequence", mac->loc_seq);
+ json_object_int_add(json_mac, "remoteSequence", mac->rem_seq);
+ json_object_int_add(json_mac, "detectionCount", mac->dad_count);
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
- json_object_boolean_true_add(json_mac,
- "isDuplicate");
+ json_object_boolean_true_add(json_mac, "isDuplicate");
else
- json_object_boolean_false_add(json_mac,
- "isDuplicate");
+ json_object_boolean_false_add(json_mac, "isDuplicate");
json_object_object_add(json_mac_hdr, buf1, json_mac);
}
@@ -910,19 +850,16 @@ void zebra_evpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt)
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
- if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)
- && !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
- &wctx->r_vtep_ip))
+ if (CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)
+ && !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &wctx->r_vtep_ip))
return;
if (json_mac_hdr == NULL) {
- if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)
+ if (CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)
&& (wctx->count == 0)) {
vty_out(vty, "\nVNI %u\n\n", wctx->zevpn->vni);
vty_out(vty, "%-17s %-6s %-5s%-30s %-5s %s\n",
- "MAC", "Type", "Flags",
- "Intf/Remote ES/VTEP", "VLAN",
- "Seq #'s");
+ "MAC", "Type", "Flags", "Intf/Remote ES/VTEP", "VLAN", "Seq #'s");
}
if (mac->es == NULL)
inet_ntop(AF_INET, &mac->fwd_info.r_vtep_ip,
@@ -930,32 +867,24 @@ void zebra_evpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt)
vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %u/%u\n", buf1,
"remote",
- zebra_evpn_print_mac_flags(mac, flags_buf,
- sizeof(flags_buf)),
+ zebra_evpn_print_mac_flags(mac, flags_buf, sizeof(flags_buf)),
mac->es ? mac->es->esi_str : addr_buf,
"", mac->loc_seq, mac->rem_seq);
} else {
json_object_string_add(json_mac, "type", "remote");
if (mac->es)
- json_object_string_add(json_mac, "remoteEs",
- mac->es->esi_str);
+ json_object_string_add(json_mac, "remoteEs", mac->es->esi_str);
else
json_object_string_addf(
- json_mac, "remoteVtep", "%pI4",
- &mac->fwd_info.r_vtep_ip);
+ json_mac, "remoteVtep", "%pI4", &mac->fwd_info.r_vtep_ip);
json_object_object_add(json_mac_hdr, buf1, json_mac);
- json_object_int_add(json_mac, "localSequence",
- mac->loc_seq);
- json_object_int_add(json_mac, "remoteSequence",
- mac->rem_seq);
- json_object_int_add(json_mac, "detectionCount",
- mac->dad_count);
+ json_object_int_add(json_mac, "localSequence", mac->loc_seq);
+ json_object_int_add(json_mac, "remoteSequence", mac->rem_seq);
+ json_object_int_add(json_mac, "detectionCount", mac->dad_count);
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
- json_object_boolean_true_add(json_mac,
- "isDuplicate");
+ json_object_boolean_true_add(json_mac, "isDuplicate");
else
- json_object_boolean_false_add(json_mac,
- "isDuplicate");
+ json_object_boolean_false_add(json_mac, "isDuplicate");
}
wctx->count++;
@@ -1004,7 +933,7 @@ int zebra_evpn_macip_send_msg_to_client(vni_t vni,
if (!client)
return 0;
- s = stream_new(ZEBRA_MAX_PACKET_SIZ);
+ s = stream_new(ZEBRA_SMALL_PACKET_SIZE);
zclient_create_header(s, cmd, zebra_vrf_get_evpn_id());
stream_putl(s, vni);
@@ -1040,9 +969,9 @@ int zebra_evpn_macip_send_msg_to_client(vni_t vni,
zlog_debug(
"Send MACIP %s f %s state %u MAC %pEA IP %pIA seq %u L2-VNI %u ESI %s to %s",
(cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del",
- zclient_evpn_dump_macip_flags(flags, flag_buf,
- sizeof(flag_buf)),
- state, macaddr, ip, seq, vni, es ? es->esi_str : "-",
+ zclient_evpn_dump_macip_flags(flags, flag_buf, sizeof(flag_buf)),
+ state, macaddr, ip, seq, vni,
+ es ? es->esi_str : "-",
zebra_route_string(client->proto));
}
@@ -1076,8 +1005,7 @@ static bool mac_cmp(const void *p1, const void *p2)
if (pmac1 == NULL || pmac2 == NULL)
return false;
- return (memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet, ETH_ALEN)
- == 0);
+ return (memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet, ETH_ALEN) == 0);
}
/*
@@ -1117,10 +1045,8 @@ struct zebra_mac *zebra_evpn_mac_add(struct zebra_evpn *zevpn,
if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) {
char mac_buf[MAC_BUF_SIZE];
- zlog_debug("%s: MAC %pEA flags %s", __func__,
- &mac->macaddr,
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)));
+ zlog_debug("%s: MAC %pEA flags %s", __func__, &mac->macaddr,
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)));
}
return mac;
}
@@ -1135,10 +1061,8 @@ int zebra_evpn_mac_del(struct zebra_evpn *zevpn, struct zebra_mac *mac)
if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) {
char mac_buf[MAC_BUF_SIZE];
- zlog_debug("%s: MAC %pEA flags %s", __func__,
- &mac->macaddr,
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)));
+ zlog_debug("%s: MAC %pEA flags %s", __func__, &mac->macaddr,
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)));
}
/* force de-ref any ES entry linked to the MAC */
@@ -1165,9 +1089,8 @@ int zebra_evpn_mac_del(struct zebra_evpn *zevpn, struct zebra_mac *mac)
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
"MAC %pEA (flags 0x%x vni %u) has non-empty neigh list "
- "count %u, mark MAC as AUTO",
- &mac->macaddr, mac->flags, zevpn->vni,
- listcount(mac->neigh_list));
+ "count %u, mark MAC as AUTO", &mac->macaddr, mac->flags,
+ zevpn->vni, listcount(mac->neigh_list));
SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
return 0;
@@ -1204,25 +1127,25 @@ struct zebra_mac *zebra_evpn_mac_add_auto(struct zebra_evpn *zevpn,
static bool zebra_evpn_check_mac_del_from_db(struct mac_walk_ctx *wctx,
struct zebra_mac *mac)
{
- if ((wctx->flags & DEL_LOCAL_MAC) && (mac->flags & ZEBRA_MAC_LOCAL))
+ if (CHECK_FLAG(wctx->flags, DEL_LOCAL_MAC)
+ && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
return true;
- else if ((wctx->flags & DEL_REMOTE_MAC)
- && (mac->flags & ZEBRA_MAC_REMOTE))
+ else if (CHECK_FLAG(wctx->flags, DEL_REMOTE_MAC)
+ && CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
return true;
- else if ((wctx->flags & DEL_REMOTE_MAC_FROM_VTEP)
- && (mac->flags & ZEBRA_MAC_REMOTE)
+ else if (CHECK_FLAG(wctx->flags, DEL_REMOTE_MAC_FROM_VTEP)
+ && CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
&& IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &wctx->r_vtep_ip))
return true;
- else if ((wctx->flags & DEL_LOCAL_MAC) && (mac->flags & ZEBRA_MAC_AUTO)
+ else if (CHECK_FLAG(wctx->flags, DEL_LOCAL_MAC)
+ && CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)
&& !listcount(mac->neigh_list)) {
if (IS_ZEBRA_DEBUG_VXLAN) {
char mac_buf[MAC_BUF_SIZE];
zlog_debug(
- "%s: Del MAC %pEA flags %s", __func__,
- &mac->macaddr,
- zebra_evpn_zebra_mac_flag_dump(
- mac, mac_buf, sizeof(mac_buf)));
+ "%s: Del MAC %pEA flags %s", __func__, &mac->macaddr,
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)));
}
wctx->uninstall = 0;
@@ -1241,21 +1164,17 @@ static void zebra_evpn_mac_del_hash_entry(struct hash_bucket *bucket, void *arg)
struct zebra_mac *mac = bucket->data;
if (zebra_evpn_check_mac_del_from_db(wctx, mac)) {
- if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) {
+ if (wctx->upd_client && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
zebra_evpn_mac_send_del_to_client(wctx->zevpn->vni,
- &mac->macaddr,
- mac->flags, false);
+ &mac->macaddr, mac->flags, false);
}
if (wctx->uninstall) {
if (zebra_evpn_mac_is_static(mac))
- zebra_evpn_sync_mac_dp_install(
- mac, false /* set_inactive */,
- true /* force_clear_static */,
- __func__);
+ zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */,
+ true /* force_clear_static */, __func__);
if (mac->flags & ZEBRA_MAC_REMOTE)
- zebra_evpn_rem_mac_uninstall(wctx->zevpn, mac,
- false /*force*/);
+ zebra_evpn_rem_mac_uninstall(wctx->zevpn, mac, false /*force*/);
}
zebra_evpn_mac_del(wctx->zevpn, mac);
@@ -1330,8 +1249,7 @@ int zebra_evpn_mac_send_add_to_client(vni_t vni, const struct ethaddr *macaddr,
SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
return zebra_evpn_macip_send_msg_to_client(vni, macaddr, NULL, flags,
- seq, ZEBRA_NEIGH_ACTIVE, es,
- ZEBRA_MACIP_ADD);
+ seq, ZEBRA_NEIGH_ACTIVE, es, ZEBRA_MACIP_ADD);
}
/*
@@ -1357,9 +1275,8 @@ int zebra_evpn_mac_send_del_to_client(vni_t vni, const struct ethaddr *macaddr,
state = ZEBRA_NEIGH_INACTIVE;
}
- return zebra_evpn_macip_send_msg_to_client(
- vni, macaddr, NULL, 0 /* flags */, 0 /* seq */, state, NULL,
- ZEBRA_MACIP_DEL);
+ return zebra_evpn_macip_send_msg_to_client(vni, macaddr, NULL,
+ 0 /* flags */, 0 /* seq */, state, NULL, ZEBRA_MACIP_DEL);
}
/*
@@ -1412,8 +1329,7 @@ int zebra_evpn_sync_mac_dp_install(struct zebra_mac *mac, bool set_inactive,
"%s: dp-install sync-mac vni %u mac %pEA es %s %s%sskipped, no access-port",
caller, zevpn->vni, &mac->macaddr,
mac->es ? mac->es->esi_str : "-",
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)),
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)),
set_inactive ? "inactive " : "");
}
return -1;
@@ -1429,8 +1345,7 @@ int zebra_evpn_sync_mac_dp_install(struct zebra_mac *mac, bool set_inactive,
"%s: dp-install sync-mac vni %u mac %pEA es %s %s%sskipped, no br",
caller, zevpn->vni, &mac->macaddr,
mac->es ? mac->es->esi_str : "-",
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)),
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)),
set_inactive ? "inactive " : "");
}
return -1;
@@ -1455,19 +1370,16 @@ int zebra_evpn_sync_mac_dp_install(struct zebra_mac *mac, bool set_inactive,
set_static ? "install" : "uninstall",
zevpn->vni, &mac->macaddr,
mac->es ? mac->es->esi_str : "-",
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)),
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)),
set_inactive ? "inactive " : "");
}
if (set_static)
/* XXX - old_static needs to be computed more
* accurately
*/
- zebra_evpn_rem_mac_install(zevpn, mac,
- true /* old_static */);
+ zebra_evpn_rem_mac_install(zevpn, mac, true /* old_static */);
else
- zebra_evpn_rem_mac_uninstall(zevpn, mac,
- false /* force */);
+ zebra_evpn_rem_mac_uninstall(zevpn, mac, false /* force */);
return 0;
}
@@ -1478,14 +1390,13 @@ int zebra_evpn_sync_mac_dp_install(struct zebra_mac *mac, bool set_inactive,
zlog_debug("dp-install sync-mac vni %u mac %pEA es %s %s%s%s",
zevpn->vni, &mac->macaddr,
mac->es ? mac->es->esi_str : "-",
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)),
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)),
set_static ? "static " : "",
set_inactive ? "inactive " : "");
}
dplane_local_mac_add(ifp, br_ifp, vid, &mac->macaddr, sticky,
- set_static, set_inactive);
+ set_static, set_inactive);
return 0;
}
@@ -1495,12 +1406,11 @@ void zebra_evpn_mac_send_add_del_to_client(struct zebra_mac *mac,
{
if (new_bgp_ready)
zebra_evpn_mac_send_add_to_client(mac->zevpn->vni,
- &mac->macaddr, mac->flags,
- mac->loc_seq, mac->es);
+ &mac->macaddr, mac->flags,
+ mac->loc_seq, mac->es);
else if (old_bgp_ready)
zebra_evpn_mac_send_del_to_client(mac->zevpn->vni,
- &mac->macaddr, mac->flags,
- true /* force */);
+ &mac->macaddr, mac->flags, true /* force */);
}
/* MAC hold timer is used to age out peer-active flag.
@@ -1537,8 +1447,7 @@ static void zebra_evpn_mac_hold_exp_cb(struct event *t)
"sync-mac vni %u mac %pEA es %s %shold expired",
mac->zevpn->vni, &mac->macaddr,
mac->es ? mac->es->esi_str : "-",
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)));
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)));
}
/* re-program the local mac in the dataplane if the mac is no
@@ -1546,13 +1455,11 @@ static void zebra_evpn_mac_hold_exp_cb(struct event *t)
*/
if (old_static != new_static)
zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */,
- false /* force_clear_static */,
- __func__);
+ false /* force_clear_static */, __func__);
/* inform bgp if needed */
if (old_bgp_ready != new_bgp_ready)
- zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready,
- new_bgp_ready);
+ zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, new_bgp_ready);
}
static inline void zebra_evpn_mac_start_hold_timer(struct zebra_mac *mac)
@@ -1567,8 +1474,7 @@ static inline void zebra_evpn_mac_start_hold_timer(struct zebra_mac *mac)
"sync-mac vni %u mac %pEA es %s %shold started",
mac->zevpn->vni, &mac->macaddr,
mac->es ? mac->es->esi_str : "-",
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)));
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)));
}
event_add_timer(zrouter.master, zebra_evpn_mac_hold_exp_cb, mac,
zmh_info->mac_hold_time, &mac->hold_timer);
@@ -1586,8 +1492,7 @@ void zebra_evpn_mac_stop_hold_timer(struct zebra_mac *mac)
"sync-mac vni %u mac %pEA es %s %shold stopped",
mac->zevpn->vni, &mac->macaddr,
mac->es ? mac->es->esi_str : "-",
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)));
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)));
}
EVENT_OFF(mac->hold_timer);
@@ -1605,8 +1510,7 @@ void zebra_evpn_sync_mac_del(struct zebra_mac *mac)
"sync-mac del vni %u mac %pEA es %s seq %d f %s",
mac->zevpn->vni, &mac->macaddr,
mac->es ? mac->es->esi_str : "-", mac->loc_seq,
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)));
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)));
}
old_static = zebra_evpn_mac_is_static(mac);
@@ -1618,8 +1522,7 @@ void zebra_evpn_sync_mac_del(struct zebra_mac *mac)
if (old_static != new_static)
/* program the local mac in the kernel */
zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */,
- false /* force_clear_static */,
- __func__);
+ false /* force_clear_static */, __func__);
}
static inline bool zebra_evpn_mac_is_bgp_seq_ok(struct zebra_evpn *zevpn,
@@ -1647,8 +1550,7 @@ static inline bool zebra_evpn_mac_is_bgp_seq_ok(struct zebra_evpn *zevpn,
zlog_debug(
"%s-macip not ready vni %u %s-mac %pEA lower seq %u f 0x%x",
sync ? "sync" : "rem", zevpn->vni,
- n_type, &mac->macaddr, tmp_seq,
- mac->flags);
+ n_type, &mac->macaddr, tmp_seq, mac->flags);
return true;
}
@@ -1660,10 +1562,9 @@ static inline bool zebra_evpn_mac_is_bgp_seq_ok(struct zebra_evpn *zevpn,
IS_ZEBRA_DEBUG_VXLAN) {
zlog_debug(
"%s-macip accept vni %u %s-mac %pEA lower seq %u f %s",
- sync ? "sync" : "rem", zevpn->vni,
- n_type, &mac->macaddr, tmp_seq,
- zebra_evpn_zebra_mac_flag_dump(
- mac, mac_buf, sizeof(mac_buf)));
+ (sync ? "sync" : "rem"),
+ zevpn->vni, n_type, &mac->macaddr, tmp_seq,
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)));
}
return true;
@@ -1672,10 +1573,8 @@ static inline bool zebra_evpn_mac_is_bgp_seq_ok(struct zebra_evpn *zevpn,
if (IS_ZEBRA_DEBUG_EVPN_MH_MAC || IS_ZEBRA_DEBUG_VXLAN) {
zlog_debug(
"%s-macip ignore vni %u %s-mac %pEA as existing has higher seq %u f %s",
- sync ? "sync" : "rem", zevpn->vni, n_type,
- &mac->macaddr, tmp_seq,
- zebra_evpn_zebra_mac_flag_dump(
- mac, mac_buf, sizeof(mac_buf)));
+ (sync ? "sync" : "rem"), zevpn->vni, n_type, &mac->macaddr, tmp_seq,
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)));
}
return false;
@@ -1749,9 +1648,7 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn,
"Ignore sync-macip vni %u mac %pEA%s%s%s%s",
zevpn->vni, macaddr,
ipa_len ? " IP " : "",
- ipa_len ? ipaddr2str(ipaddr, ipbuf,
- sizeof(ipbuf))
- : "",
+ ipa_len ? ipaddr2str(ipaddr, ipbuf, sizeof(ipbuf)) : "",
sticky ? " sticky" : "",
remote_gw ? " remote_gw" : "");
return NULL;
@@ -1766,16 +1663,16 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn,
new_flags = 0;
SET_FLAG(new_flags, ZEBRA_MAC_LOCAL);
/* retain old local activity flag */
- if (old_flags & ZEBRA_MAC_LOCAL)
- new_flags |= (old_flags & ZEBRA_MAC_LOCAL_INACTIVE);
+ if (CHECK_FLAG(old_flags, ZEBRA_MAC_LOCAL))
+ SET_FLAG (new_flags, CHECK_FLAG(old_flags, ZEBRA_MAC_LOCAL_INACTIVE));
else
- new_flags |= ZEBRA_MAC_LOCAL_INACTIVE;
+ SET_FLAG(new_flags, ZEBRA_MAC_LOCAL_INACTIVE);
if (ipa_len) {
/* if mac-ip route do NOT update the peer flags
* i.e. retain only flags as is
*/
- new_flags |= (old_flags & ZEBRA_MAC_ALL_PEER_FLAGS);
+ SET_FLAG(new_flags, CHECK_FLAG(old_flags, ZEBRA_MAC_ALL_PEER_FLAGS));
} else {
/* if mac-only route update peer flags */
if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT)) {
@@ -1785,10 +1682,8 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn,
* holdtimer on it. the peer-active flag is
* cleared on holdtimer expiry.
*/
- if (CHECK_FLAG(old_flags,
- ZEBRA_MAC_ES_PEER_ACTIVE)) {
- SET_FLAG(new_flags,
- ZEBRA_MAC_ES_PEER_ACTIVE);
+ if (CHECK_FLAG(old_flags, ZEBRA_MAC_ES_PEER_ACTIVE)) {
+ SET_FLAG(new_flags, ZEBRA_MAC_ES_PEER_ACTIVE);
zebra_evpn_mac_start_hold_timer(mac);
}
} else {
@@ -1811,10 +1706,8 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn,
zlog_debug(
"sync-mac vni %u mac %pEA old_f %snew_f %s",
zevpn->vni, macaddr,
- zebra_evpn_zebra_mac_flag_dump(
- &omac, omac_buf, sizeof(omac_buf)),
- zebra_evpn_zebra_mac_flag_dump(
- mac, mac_buf, sizeof(mac_buf)));
+ zebra_evpn_zebra_mac_flag_dump(&omac, omac_buf, sizeof(omac_buf)),
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)));
}
/* update es */
@@ -1854,24 +1747,24 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn,
char mac_buf[MAC_BUF_SIZE];
zlog_debug("sync-mac %s vni %u mac %pEA es %s seq %d f %s%s%s",
- created ? "created" : "updated", zevpn->vni, macaddr,
- mac->es ? mac->es->esi_str : "-", mac->loc_seq,
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)),
- inform_bgp ? "inform_bgp" : "",
- inform_dataplane ? " inform_dp" : "");
+ created ? "created" : "updated",
+ zevpn->vni, macaddr,
+ mac->es ? mac->es->esi_str : "-",
+ mac->loc_seq,
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)),
+ inform_bgp ? "inform_bgp" : "",
+ inform_dataplane ? " inform_dp" : "");
}
if (inform_bgp)
- zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready,
- new_bgp_ready);
+ zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, new_bgp_ready);
/* neighs using the mac may need to be re-sent to
* bgp with updated info
*/
if (seq_change || es_change || !old_local)
zebra_evpn_process_neigh_on_local_mac_change(
- zevpn, mac, seq_change, es_change);
+ zevpn, mac, seq_change, es_change);
if (inform_dataplane && !ipa_len) {
/* program the local mac in the kernel. when the ES
@@ -1879,9 +1772,8 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn,
* the activity as we are yet to establish activity
* locally
*/
- zebra_evpn_sync_mac_dp_install(
- mac, mac_inactive /* set_inactive */,
- false /* force_clear_static */, __func__);
+ zebra_evpn_sync_mac_dp_install(mac, mac_inactive /* set_inactive */,
+ false /* force_clear_static */, __func__);
}
return mac;
@@ -1891,8 +1783,7 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn,
* is detected
*/
static bool zebra_evpn_local_mac_update_fwd_info(struct zebra_mac *mac,
- struct interface *ifp,
- vlanid_t vid)
+ struct interface *ifp, vlanid_t vid)
{
struct zebra_if *zif = ifp->info;
bool es_change;
@@ -1934,8 +1825,8 @@ static void zebra_evpn_send_mac_hash_entry_to_client(struct hash_bucket *bucket,
if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL))
zebra_evpn_mac_send_add_to_client(wctx->zevpn->vni,
- &zmac->macaddr, zmac->flags,
- zmac->loc_seq, zmac->es);
+ &zmac->macaddr, zmac->flags,
+ zmac->loc_seq, zmac->es);
}
/* Iterator to Notify Local MACs of a EVPN */
@@ -1949,8 +1840,7 @@ void zebra_evpn_send_mac_list_to_client(struct zebra_evpn *zevpn)
memset(&wctx, 0, sizeof(wctx));
wctx.zevpn = zevpn;
- hash_iterate(zevpn->mac_table, zebra_evpn_send_mac_hash_entry_to_client,
- &wctx);
+ hash_iterate(zevpn->mac_table, zebra_evpn_send_mac_hash_entry_to_client, &wctx);
}
void zebra_evpn_rem_mac_del(struct zebra_evpn *zevpn, struct zebra_mac *mac)
@@ -1992,8 +1882,7 @@ void zebra_evpn_print_dad_mac_hash(struct hash_bucket *bucket, void *ctxt)
}
/* Print Duplicate MAC in detail */
-void zebra_evpn_print_dad_mac_hash_detail(struct hash_bucket *bucket,
- void *ctxt)
+void zebra_evpn_print_dad_mac_hash_detail(struct hash_bucket *bucket, void *ctxt)
{
struct zebra_mac *mac;
@@ -2043,11 +1932,13 @@ int zebra_evpn_mac_remote_macip_add(struct zebra_evpn *zevpn,
* If so, that needs to be updated first. Note that client could
* install MAC and MACIP separately or just install the latter.
*/
- if (!mac || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
- || sticky != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)
- || remote_gw != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW)
- || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip)
- || memcmp(old_esi, esi, sizeof(esi_t)) || seq != mac->rem_seq)
+ if (!mac
+ || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
+ || sticky != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)
+ || remote_gw != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW)
+ || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip)
+ || memcmp(old_esi, esi, sizeof(esi_t))
+ || seq != mac->rem_seq)
update_mac = 1;
if (update_mac) {
@@ -2063,8 +1954,7 @@ int zebra_evpn_mac_remote_macip_add(struct zebra_evpn *zevpn,
* the sequence number and ignore this update
* if appropriate.
*/
- if (!zebra_evpn_mac_is_bgp_seq_ok(zevpn, mac, seq,
- false))
+ if (!zebra_evpn_mac_is_bgp_seq_ok(zevpn, mac, seq, false))
return -1;
old_es_present = !!mac->es;
@@ -2091,8 +1981,7 @@ int zebra_evpn_mac_remote_macip_add(struct zebra_evpn *zevpn,
* MAC is already marked duplicate set dad, then
* is_dup_detect will be set to not install the entry.
*/
- if ((!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
- && mac->dad_count)
+ if ((!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) && mac->dad_count)
|| CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
do_dad = true;
@@ -2108,14 +1997,12 @@ int zebra_evpn_mac_remote_macip_add(struct zebra_evpn *zevpn,
zevpn->vni, macaddr,
mac->es ? mac->es->esi_str : "-",
mac->loc_seq,
- zebra_evpn_zebra_mac_flag_dump(
- mac, mac_buf, sizeof(mac_buf)));
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)));
}
zebra_evpn_mac_clear_sync_info(mac);
- zebra_evpn_mac_send_del_to_client(zevpn->vni, macaddr,
- mac->flags,
- false /* force */);
+ zebra_evpn_mac_send_del_to_client(zevpn->vni, macaddr, mac->flags,
+ false /* force */);
}
/* Set "auto" and "remote" forwarding info. */
@@ -2135,8 +2022,7 @@ int zebra_evpn_mac_remote_macip_add(struct zebra_evpn *zevpn,
UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
zebra_evpn_dup_addr_detect_for_mac(
- zvrf, mac, mac->fwd_info.r_vtep_ip, do_dad,
- &is_dup_detect, false);
+ zvrf, mac, mac->fwd_info.r_vtep_ip, do_dad, &is_dup_detect, false);
if (!is_dup_detect) {
zebra_evpn_process_neigh_on_remote_mac_add(zevpn, mac);
@@ -2180,8 +2066,8 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf,
if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
zlog_debug(
"ADD %sMAC %pEA intf %s(%u) VID %u -> VNI %u%s",
- sticky ? "sticky " : "", macaddr,
- ifp->name, ifp->ifindex, vid, zevpn->vni,
+ sticky ? "sticky " : "",
+ macaddr, ifp->name, ifp->ifindex, vid, zevpn->vni,
local_inactive ? " local-inactive" : "");
mac = zebra_evpn_mac_add(zevpn, macaddr);
@@ -2196,11 +2082,10 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf,
zlog_debug(
"UPD %sMAC %pEA intf %s(%u) VID %u -> VNI %u %scurFlags %s",
- sticky ? "sticky " : "", macaddr,
- ifp->name, ifp->ifindex, vid, zevpn->vni,
+ sticky ? "sticky " : "",
+ macaddr, ifp->name, ifp->ifindex, vid, zevpn->vni,
local_inactive ? "local-inactive " : "",
- zebra_evpn_zebra_mac_flag_dump(
- mac, mac_buf, sizeof(mac_buf)));
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)));
}
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
@@ -2209,42 +2094,34 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf,
bool old_static;
zebra_evpn_mac_get_access_info(mac, &old_ifp, &old_vid);
- old_bgp_ready =
- zebra_evpn_mac_is_ready_for_bgp(mac->flags);
- old_local_inactive =
- !!(mac->flags & ZEBRA_MAC_LOCAL_INACTIVE);
+ old_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags);
+ old_local_inactive = !!(mac->flags & ZEBRA_MAC_LOCAL_INACTIVE);
old_static = zebra_evpn_mac_is_static(mac);
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
mac_sticky = true;
- es_change = zebra_evpn_local_mac_update_fwd_info(
- mac, ifp, vid);
+ es_change = zebra_evpn_local_mac_update_fwd_info(mac, ifp, vid);
/*
* Update any changes and if changes are relevant to
* BGP, note it.
*/
- if (mac_sticky == sticky && old_ifp == ifp
- && old_vid == vid
- && old_local_inactive == local_inactive
- && dp_static == old_static && !es_change) {
+ if (mac_sticky == sticky && old_ifp == ifp && old_vid == vid
+ && old_local_inactive == local_inactive
+ && dp_static == old_static && !es_change) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
" Add/Update %sMAC %pEA intf %s(%u) VID %u -> VNI %u%s, "
"entry exists and has not changed ",
sticky ? "sticky " : "",
- macaddr, ifp->name,
- ifp->ifindex, vid, zevpn->vni,
- local_inactive
- ? " local_inactive"
- : "");
+ macaddr, ifp->name, ifp->ifindex, vid, zevpn->vni,
+ local_inactive ? " local_inactive" : "");
return 0;
}
if (mac_sticky != sticky) {
if (sticky)
SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
else
- UNSET_FLAG(mac->flags,
- ZEBRA_MAC_STICKY);
+ UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
inform_client = true;
}
@@ -2262,11 +2139,9 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf,
/* force drop the peer/sync info as it is
* simply no longer relevant
*/
- if (CHECK_FLAG(mac->flags,
- ZEBRA_MAC_ALL_PEER_FLAGS)) {
+ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_ALL_PEER_FLAGS)) {
zebra_evpn_mac_clear_sync_info(mac);
- new_static =
- zebra_evpn_mac_is_static(mac);
+ new_static = zebra_evpn_mac_is_static(mac);
/* if we clear peer-flags we
* also need to notify the dataplane
* to drop the static flag
@@ -2289,16 +2164,13 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf,
flog_warn(
EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT,
"MAC %pEA already learnt as remote sticky MAC behind VTEP %pI4 VNI %u",
- macaddr,
- &mac->fwd_info.r_vtep_ip,
- zevpn->vni);
+ macaddr, &mac->fwd_info.r_vtep_ip, zevpn->vni);
return 0;
}
/* If an actual move, compute MAC's seq number */
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
- mac->loc_seq =
- MAX(mac->rem_seq + 1, mac->loc_seq);
+ mac->loc_seq = MAX(mac->rem_seq + 1, mac->loc_seq);
vtep_ip = mac->fwd_info.r_vtep_ip;
/* Trigger DAD for remote MAC */
do_dad = true;
@@ -2307,8 +2179,7 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf,
UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
- es_change = zebra_evpn_local_mac_update_fwd_info(
- mac, ifp, vid);
+ es_change = zebra_evpn_local_mac_update_fwd_info(mac, ifp, vid);
if (sticky)
SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
else
@@ -2321,8 +2192,7 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf,
upd_neigh = true;
zebra_evpn_dup_addr_detect_for_mac(
- zvrf, mac, vtep_ip, do_dad, &is_dup_detect,
- true);
+ zvrf, mac, vtep_ip, do_dad, &is_dup_detect, true);
if (is_dup_detect) {
inform_client = false;
upd_neigh = false;
@@ -2357,8 +2227,7 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf,
"local mac vni %u mac %pEA es %s seq %d f %s%s",
zevpn->vni, macaddr,
mac->es ? mac->es->esi_str : "", mac->loc_seq,
- zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
- sizeof(mac_buf)),
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)),
local_inactive ? "local-inactive" : "");
}
@@ -2374,18 +2243,15 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf,
/* Inform dataplane if required. */
if (inform_dataplane)
zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */,
- false /* force_clear_static */,
- __func__);
+ false /* force_clear_static */, __func__);
/* Inform BGP if required. */
if (inform_client)
- zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready,
- new_bgp_ready);
+ zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, new_bgp_ready);
/* Process all neighbors associated with this MAC, if required. */
if (upd_neigh)
- zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
- es_change);
+ zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0, es_change);
return 0;
}
@@ -2415,23 +2281,20 @@ int zebra_evpn_del_local_mac(struct zebra_evpn *zevpn, struct zebra_mac *mac,
"re-add sync-mac vni %u mac %pEA es %s seq %d f %s",
zevpn->vni, &mac->macaddr,
mac->es ? mac->es->esi_str : "-", mac->loc_seq,
- zebra_evpn_zebra_mac_flag_dump(
- mac, mac_buf, sizeof(mac_buf)));
+ zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)));
}
/* inform-bgp about change in local-activity if any */
if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE)) {
SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE);
- new_bgp_ready =
- zebra_evpn_mac_is_ready_for_bgp(mac->flags);
+ new_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags);
zebra_evpn_mac_send_add_del_to_client(
- mac, old_bgp_ready, new_bgp_ready);
+ mac, old_bgp_ready, new_bgp_ready);
}
/* re-install the inactive entry in the kernel */
zebra_evpn_sync_mac_dp_install(mac, true /* set_inactive */,
- false /* force_clear_static */,
- __func__);
+ false /* force_clear_static */, __func__);
return 0;
}
@@ -2519,8 +2382,7 @@ void zebra_evpn_mac_svi_del(struct interface *ifp, struct zebra_evpn *zevpn)
old_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags);
UNSET_FLAG(mac->flags, ZEBRA_MAC_SVI);
- zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready,
- false);
+ zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, false);
zebra_evpn_deref_ip2mac(mac->zevpn, mac);
}
}
@@ -2548,13 +2410,11 @@ void zebra_evpn_mac_svi_add(struct interface *ifp, struct zebra_evpn *zevpn)
if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
zlog_debug("SVI %s mac add", zif->ifp->name);
- old_bgp_ready = (mac && zebra_evpn_mac_is_ready_for_bgp(mac->flags))
- ? true
- : false;
+ old_bgp_ready =
+ (mac && zebra_evpn_mac_is_ready_for_bgp(mac->flags)) ? true : false;
zebra_evpn_mac_gw_macip_add(ifp, zevpn, NULL, &mac, &macaddr, 0, false);
new_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags);
- zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready,
- new_bgp_ready);
+ zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, new_bgp_ready);
}
diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c
index 35d5027..75e7e20 100644
--- a/zebra/zebra_evpn_mh.c
+++ b/zebra/zebra_evpn_mh.c
@@ -563,8 +563,9 @@ zebra_evpn_acc_vl_new(vlanid_t vid, struct interface *br_if)
struct zebra_evpn_access_bd *acc_bd;
struct interface *vlan_if;
- if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
- zlog_debug("access vlan %d bridge %s add", vid, br_if->name);
+ if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("%s access vlan %d bridge %s add", __func__, vid,
+ br_if->name);
acc_bd = XCALLOC(MTYPE_ZACC_BD, sizeof(struct zebra_evpn_access_bd));
@@ -582,8 +583,8 @@ zebra_evpn_acc_vl_new(vlanid_t vid, struct interface *br_if)
vlan_if = zvni_map_to_svi(vid, br_if);
if (vlan_if) {
if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
- zlog_debug("vlan %d bridge %s SVI %s set", vid,
- br_if->name, vlan_if->name);
+ zlog_debug("%s vlan %d bridge %s SVI %s set", __func__,
+ vid, br_if->name, vlan_if->name);
acc_bd->vlan_zif = vlan_if->info;
}
return acc_bd;
@@ -731,6 +732,29 @@ static void zebra_evpn_acc_bd_evpn_set(struct zebra_evpn_access_bd *acc_bd,
}
}
+/* Lookup API for VxLAN_IF's Bridge, VLAN in EVPN cache */
+int zebra_evpn_vl_vxl_bridge_lookup(uint16_t vid, struct zebra_if *vxlan_zif)
+{
+ struct interface *br_if;
+ struct zebra_evpn_access_bd *acc_bd;
+
+ if (!vid)
+ return -1;
+
+ br_if = vxlan_zif->brslave_info.br_if;
+
+ if (!br_if)
+ return -1;
+
+ acc_bd = zebra_evpn_acc_vl_find(vid, br_if);
+
+ if (!acc_bd)
+ return 0;
+
+ return 1;
+}
+
+
/* handle VLAN->VxLAN_IF association */
void zebra_evpn_vl_vxl_ref(uint16_t vid, vni_t vni_id,
struct zebra_if *vxlan_zif)
@@ -768,8 +792,9 @@ void zebra_evpn_vl_vxl_ref(uint16_t vid, vni_t vni_id,
if (acc_bd->zevpn == old_zevpn)
return;
- if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
- zlog_debug("access vlan %d vni %u ref", acc_bd->vid, vni_id);
+ if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("%s bridge %s access vlan %d vni %u ref", __func__,
+ br_if->name, acc_bd->vid, vni_id);
if (old_zevpn)
zebra_evpn_acc_bd_evpn_set(acc_bd, NULL, old_zevpn);
@@ -1935,7 +1960,7 @@ static int zebra_evpn_es_send_add_to_client(struct zebra_evpn_es *es)
if (!client)
return 0;
- s = stream_new(ZEBRA_MAX_PACKET_SIZ);
+ s = stream_new(ZEBRA_SMALL_PACKET_SIZE);
zclient_create_header(s, ZEBRA_LOCAL_ES_ADD, zebra_vrf_get_evpn_id());
stream_put(s, &es->esi, sizeof(esi_t));
@@ -1971,7 +1996,7 @@ static int zebra_evpn_es_send_del_to_client(struct zebra_evpn_es *es)
if (!client)
return 0;
- s = stream_new(ZEBRA_MAX_PACKET_SIZ);
+ s = stream_new(ZEBRA_SMALL_PACKET_SIZE);
stream_reset(s);
zclient_create_header(s, ZEBRA_LOCAL_ES_DEL, zebra_vrf_get_evpn_id());
@@ -2639,7 +2664,7 @@ static int zebra_evpn_es_evi_send_to_client(struct zebra_evpn_es *es,
if (!client)
return 0;
- s = stream_new(ZEBRA_MAX_PACKET_SIZ);
+ s = stream_new(ZEBRA_SMALL_PACKET_SIZE);
zclient_create_header(s,
add ? ZEBRA_LOCAL_ES_EVI_ADD : ZEBRA_LOCAL_ES_EVI_DEL,
@@ -3001,7 +3026,7 @@ void zebra_evpn_es_if_oper_state_change(struct zebra_if *zif, bool up)
}
static char *zebra_evpn_es_vtep_str(char *vtep_str, struct zebra_evpn_es *es,
- uint8_t vtep_str_size)
+ size_t vtep_str_size)
{
struct zebra_evpn_es_vtep *zvtep;
struct listnode *node;
diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h
index 34ef79f..f68e2ea 100644
--- a/zebra/zebra_evpn_mh.h
+++ b/zebra/zebra_evpn_mh.h
@@ -378,7 +378,8 @@ extern void zebra_evpn_es_bypass_update(struct zebra_evpn_es *es,
extern void zebra_evpn_proc_remote_nh(ZAPI_HANDLER_ARGS);
extern struct zebra_evpn_es_evi *
zebra_evpn_es_evi_find(struct zebra_evpn_es *es, struct zebra_evpn *zevpn);
-
+extern int zebra_evpn_vl_vxl_bridge_lookup(uint16_t vid,
+ struct zebra_if *vxlan_zif);
void zebra_build_type3_esi(uint32_t lid, struct ethaddr *mac, esi_t *esi);
void zebra_evpn_es_sys_mac_update(struct zebra_if *zif, struct ethaddr *sysmac);
diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c
index 1dd9634..95207ce 100644
--- a/zebra/zebra_fpm_netlink.c
+++ b/zebra/zebra_fpm_netlink.c
@@ -592,19 +592,19 @@ int zfpm_netlink_encode_mac(struct fpm_mac_info_t *mac, char *in_buf,
RTM_DELNEIGH : RTM_NEWNEIGH;
req->hdr.nlmsg_flags = NLM_F_REQUEST;
if (req->hdr.nlmsg_type == RTM_NEWNEIGH)
- req->hdr.nlmsg_flags |= (NLM_F_CREATE | NLM_F_REPLACE);
+ SET_FLAG(req->hdr.nlmsg_flags, (NLM_F_CREATE | NLM_F_REPLACE));
/* Construct ndmsg */
req->ndm.ndm_family = AF_BRIDGE;
req->ndm.ndm_ifindex = mac->vxlan_if;
req->ndm.ndm_state = NUD_REACHABLE;
- req->ndm.ndm_flags |= NTF_SELF | NTF_MASTER;
+ SET_FLAG(req->ndm.ndm_flags, (NTF_SELF | NTF_MASTER));
if (CHECK_FLAG(mac->zebra_flags,
(ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW)))
- req->ndm.ndm_state |= NUD_NOARP;
+ SET_FLAG(req->ndm.ndm_state, NUD_NOARP);
else
- req->ndm.ndm_flags |= NTF_EXT_LEARNED;
+ SET_FLAG(req->ndm.ndm_flags, NTF_EXT_LEARNED);
/* Add attributes */
nl_attr_put(&req->hdr, in_buf_len, NDA_LLADDR, &mac->macaddr, 6);
diff --git a/zebra/zebra_gr.c b/zebra/zebra_gr.c
index f4241f1..cee66cc 100644
--- a/zebra/zebra_gr.c
+++ b/zebra/zebra_gr.c
@@ -298,6 +298,16 @@ struct zebra_gr_afi_clean {
* Functions to deal with capabilities
*/
+void zebra_gr_client_final_shutdown(struct zserv *client)
+{
+ struct client_gr_info *info;
+
+ while (!TAILQ_EMPTY(&client->gr_info_queue)) {
+ info = TAILQ_FIRST(&client->gr_info_queue);
+ zebra_gr_client_info_delete(client, info);
+ }
+}
+
/*
* Function to decode and call appropriate functions
* to handle client capabilities.
diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c
index 4f7a1cd..240f674 100644
--- a/zebra/zebra_l2.c
+++ b/zebra/zebra_l2.c
@@ -111,13 +111,13 @@ static void zebra_l2_bond_lacp_bypass_eval(struct zebra_if *bond_zif)
{
struct listnode *node;
struct zebra_if *bond_mbr;
- bool old_bypass = !!(bond_zif->flags & ZIF_FLAG_LACP_BYPASS);
+ bool old_bypass = !!CHECK_FLAG(bond_zif->flags, ZIF_FLAG_LACP_BYPASS);
bool new_bypass = false;
if (bond_zif->bond_info.mbr_zifs) {
for (ALL_LIST_ELEMENTS_RO(bond_zif->bond_info.mbr_zifs, node,
bond_mbr)) {
- if (bond_mbr->flags & ZIF_FLAG_LACP_BYPASS) {
+ if (CHECK_FLAG(bond_mbr->flags, ZIF_FLAG_LACP_BYPASS)) {
new_bypass = true;
break;
}
@@ -132,9 +132,9 @@ static void zebra_l2_bond_lacp_bypass_eval(struct zebra_if *bond_zif)
bond_zif->ifp->name, new_bypass ? "on" : "off");
if (new_bypass)
- bond_zif->flags |= ZIF_FLAG_LACP_BYPASS;
+ SET_FLAG(bond_zif->flags, ZIF_FLAG_LACP_BYPASS);
else
- bond_zif->flags &= ~ZIF_FLAG_LACP_BYPASS;
+ UNSET_FLAG(bond_zif->flags, ZIF_FLAG_LACP_BYPASS);
if (bond_zif->es_info.es)
zebra_evpn_es_bypass_update(bond_zif->es_info.es, bond_zif->ifp,
@@ -174,8 +174,7 @@ void zebra_l2_map_slave_to_bond(struct zebra_if *zif, vrf_id_t vrf_id)
}
} else {
if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("bond mbr %s link to bond skipped",
- zif->ifp->name);
+ zlog_debug("bond mbr %s link to bond skipped", zif->ifp->name);
}
}
@@ -186,8 +185,7 @@ void zebra_l2_unmap_slave_from_bond(struct zebra_if *zif)
if (!bond_slave->bond_if) {
if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("bond mbr %s unlink from bond skipped",
- zif->ifp->name);
+ zlog_debug("bond mbr %s unlink from bond skipped", zif->ifp->name);
return;
}
@@ -218,8 +216,7 @@ void zebra_l2if_update_bond(struct interface *ifp, bool add)
if (add) {
if (!bond->mbr_zifs) {
if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("bond %s mbr list create",
- ifp->name);
+ zlog_debug("bond %s mbr list create", ifp->name);
bond->mbr_zifs = list_new();
}
} else {
@@ -347,7 +344,7 @@ void zebra_l2_vxlanif_add_update(struct interface *ifp,
ctx.old_vtep_ip = zif->l2info.vxl.vtep_ip;
if (!IPV4_ADDR_SAME(&ctx.old_vtep_ip, &vxlan_info->vtep_ip)) {
- chgflags |= ZEBRA_VXLIF_LOCAL_IP_CHANGE;
+ SET_FLAG(chgflags, ZEBRA_VXLIF_LOCAL_IP_CHANGE);
zif->l2info.vxl.vtep_ip = vxlan_info->vtep_ip;
}
@@ -355,7 +352,7 @@ void zebra_l2_vxlanif_add_update(struct interface *ifp,
ctx.old_vni = vxlan_info->vni_info.vni;
if (!IPV4_ADDR_SAME(&zif->l2info.vxl.vni_info.vni.mcast_grp,
&vxlan_info->vni_info.vni.mcast_grp)) {
- chgflags |= ZEBRA_VXLIF_MCAST_GRP_CHANGE;
+ SET_FLAG(chgflags, ZEBRA_VXLIF_MCAST_GRP_CHANGE);
zif->l2info.vxl.vni_info.vni.mcast_grp =
vxlan_info->vni_info.vni.mcast_grp;
}
@@ -387,7 +384,7 @@ void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp,
return;
old_access_vlan = zif->l2info.vxl.vni_info.vni.access_vlan;
- ;
+
if (old_access_vlan == access_vlan)
return;
@@ -441,11 +438,11 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp,
if (zif->zif_type == ZEBRA_IF_VXLAN
&& chgflags != ZEBRA_BRIDGE_NO_ACTION) {
- if (chgflags & ZEBRA_BRIDGE_MASTER_MAC_CHANGE) {
+ if (CHECK_FLAG(chgflags, ZEBRA_BRIDGE_MASTER_MAC_CHANGE)) {
ctx.chgflags = ZEBRA_VXLIF_MASTER_MAC_CHANGE;
zebra_vxlan_if_update(ifp, &ctx);
}
- if (chgflags & ZEBRA_BRIDGE_MASTER_UP) {
+ if (CHECK_FLAG(chgflags, ZEBRA_BRIDGE_MASTER_UP)) {
ctx.chgflags = ZEBRA_VXLIF_MASTER_CHANGE;
zebra_vxlan_if_update(ifp, &ctx);
}
@@ -494,16 +491,16 @@ void zebra_l2if_update_bond_slave(struct interface *ifp, ifindex_t bond_ifindex,
zif = ifp->info;
assert(zif);
- old_bypass = !!(zif->flags & ZIF_FLAG_LACP_BYPASS);
+ old_bypass = !!CHECK_FLAG(zif->flags, ZIF_FLAG_LACP_BYPASS);
if (old_bypass != new_bypass) {
if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
zlog_debug("bond-mbr %s lacp bypass changed to %s",
zif->ifp->name, new_bypass ? "on" : "off");
if (new_bypass)
- zif->flags |= ZIF_FLAG_LACP_BYPASS;
+ SET_FLAG(zif->flags, ZIF_FLAG_LACP_BYPASS);
else
- zif->flags &= ~ZIF_FLAG_LACP_BYPASS;
+ UNSET_FLAG(zif->flags, ZIF_FLAG_LACP_BYPASS);
bond_mbr = &zif->bondslave_info;
if (bond_mbr->bond_if) {
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index 39fc678..d1c9cd5 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -329,7 +329,7 @@ static void fec_evaluate(struct zebra_vrf *zvrf)
/* Skip configured FECs and those without a label index.
*/
- if (fec->flags & FEC_FLAG_CONFIGURED
+ if (CHECK_FLAG(fec->flags, FEC_FLAG_CONFIGURED)
|| fec->label_index == MPLS_INVALID_LABEL_INDEX)
continue;
@@ -2291,7 +2291,7 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
new_client = true;
} else {
/* Check if the FEC has been statically defined in the config */
- is_configured_fec = fec->flags & FEC_FLAG_CONFIGURED;
+ is_configured_fec = CHECK_FLAG(fec->flags, FEC_FLAG_CONFIGURED);
/* Client may register same FEC with different label index. */
new_client =
(listnode_lookup(fec->client_list, client) == NULL);
@@ -2382,8 +2382,8 @@ int zebra_mpls_fec_unregister(struct zebra_vrf *zvrf, struct prefix *p,
/* If not a configured entry, delete the FEC if no other clients. Before
* deleting, see if any LSP needs to be uninstalled.
*/
- if (!(fec->flags & FEC_FLAG_CONFIGURED)
- && list_isempty(fec->client_list)) {
+ if (!CHECK_FLAG(fec->flags, FEC_FLAG_CONFIGURED) &&
+ list_isempty(fec->client_list)) {
mpls_label_t old_label = fec->label;
fec->label = MPLS_INVALID_LABEL; /* reset */
fec_change_update_lsp(zvrf, fec, old_label);
@@ -2420,7 +2420,7 @@ static int zebra_mpls_cleanup_fecs_for_client(struct zserv *client)
if (fec_client == client) {
listnode_delete(fec->client_list,
fec_client);
- if (!(fec->flags & FEC_FLAG_CONFIGURED)
+ if (!CHECK_FLAG(fec->flags, FEC_FLAG_CONFIGURED)
&& list_isempty(fec->client_list))
fec_del(fec);
break;
@@ -2476,7 +2476,7 @@ static int zebra_mpls_cleanup_zclient_labels(struct zserv *client)
* hash..
*/
struct zebra_fec *zebra_mpls_fec_for_label(struct zebra_vrf *zvrf,
- mpls_label_t label)
+ struct prefix *p, mpls_label_t label)
{
struct route_node *rn;
struct zebra_fec *fec;
@@ -2491,8 +2491,11 @@ struct zebra_fec *zebra_mpls_fec_for_label(struct zebra_vrf *zvrf,
if (!rn->info)
continue;
fec = rn->info;
- if (fec->label == label)
+ if (fec->label == label) {
+ if (p && prefix_same(p, &rn->p))
+ return NULL;
return fec;
+ }
}
}
@@ -2502,9 +2505,10 @@ struct zebra_fec *zebra_mpls_fec_for_label(struct zebra_vrf *zvrf,
/*
* Inform if specified label is currently bound to a FEC or not.
*/
-int zebra_mpls_label_already_bound(struct zebra_vrf *zvrf, mpls_label_t label)
+int zebra_mpls_label_already_bound(struct zebra_vrf *zvrf, struct prefix *p,
+ mpls_label_t label)
{
- return (zebra_mpls_fec_for_label(zvrf, label) ? 1 : 0);
+ return (zebra_mpls_fec_for_label(zvrf, p, label) ? 1 : 0);
}
/*
@@ -2538,7 +2542,7 @@ int zebra_mpls_static_fec_add(struct zebra_vrf *zvrf, struct prefix *p,
if (IS_ZEBRA_DEBUG_MPLS)
zlog_debug("Add fec %pFX label %u", p, in_label);
} else {
- fec->flags |= FEC_FLAG_CONFIGURED;
+ SET_FLAG(fec->flags, FEC_FLAG_CONFIGURED);
if (fec->label == in_label)
/* Duplicate config */
return 0;
@@ -2587,7 +2591,7 @@ int zebra_mpls_static_fec_del(struct zebra_vrf *zvrf, struct prefix *p)
}
old_label = fec->label;
- fec->flags &= ~FEC_FLAG_CONFIGURED;
+ UNSET_FLAG(fec->flags, FEC_FLAG_CONFIGURED);
fec->label = MPLS_INVALID_LABEL;
/* If no client exists, just delete the FEC. */
@@ -2630,7 +2634,7 @@ int zebra_mpls_write_fec_config(struct vty *vty, struct zebra_vrf *zvrf)
char lstr[BUFSIZ];
fec = rn->info;
- if (!(fec->flags & FEC_FLAG_CONFIGURED))
+ if (!CHECK_FLAG(fec->flags, FEC_FLAG_CONFIGURED))
continue;
write = 1;
diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h
index 1ed2f9b..dd6f960 100644
--- a/zebra/zebra_mpls.h
+++ b/zebra/zebra_mpls.h
@@ -203,12 +203,13 @@ int zebra_mpls_fec_unregister(struct zebra_vrf *zvrf, struct prefix *p,
* hash..
*/
struct zebra_fec *zebra_mpls_fec_for_label(struct zebra_vrf *zvrf,
- mpls_label_t label);
+ struct prefix *p, mpls_label_t label);
/*
* Inform if specified label is currently bound to a FEC or not.
*/
-int zebra_mpls_label_already_bound(struct zebra_vrf *zvrf, mpls_label_t label);
+int zebra_mpls_label_already_bound(struct zebra_vrf *zvrf, struct prefix *p,
+ mpls_label_t label);
/*
* Add static FEC to label binding. If there are clients registered for this
diff --git a/zebra/zebra_mpls_openbsd.c b/zebra/zebra_mpls_openbsd.c
index 9cbe6a2..85a53dd 100644
--- a/zebra/zebra_mpls_openbsd.c
+++ b/zebra/zebra_mpls_openbsd.c
@@ -64,8 +64,8 @@ static int kernel_send_rtmsg_v4(int action, mpls_label_t in_label,
sa_label_in.smpls_family = AF_MPLS;
sa_label_in.smpls_label = htonl(in_label << MPLS_LABEL_OFFSET);
/* adjust header */
- hdr.rtm_flags |= RTF_MPLS | RTF_MPATH;
- hdr.rtm_addrs |= RTA_DST;
+ SET_FLAG(hdr.rtm_flags, (RTF_MPLS | RTF_MPATH));
+ SET_FLAG(hdr.rtm_addrs, RTA_DST);
hdr.rtm_msglen += sizeof(sa_label_in);
/* adjust iovec */
iov[iovcnt].iov_base = &sa_label_in;
@@ -77,8 +77,8 @@ static int kernel_send_rtmsg_v4(int action, mpls_label_t in_label,
nexthop.sin_family = AF_INET;
nexthop.sin_addr = nhlfe->nexthop->gate.ipv4;
/* adjust header */
- hdr.rtm_flags |= RTF_GATEWAY;
- hdr.rtm_addrs |= RTA_GATEWAY;
+ SET_FLAG(hdr.rtm_flags, RTF_GATEWAY);
+ SET_FLAG(hdr.rtm_addrs, RTA_GATEWAY);
hdr.rtm_msglen += sizeof(nexthop);
/* adjust iovec */
iov[iovcnt].iov_base = &nexthop;
@@ -93,8 +93,8 @@ static int kernel_send_rtmsg_v4(int action, mpls_label_t in_label,
htonl(nhlfe->nexthop->nh_label->label[0]
<< MPLS_LABEL_OFFSET);
/* adjust header */
- hdr.rtm_addrs |= RTA_SRC;
- hdr.rtm_flags |= RTF_MPLS;
+ SET_FLAG(hdr.rtm_addrs, RTA_SRC);
+ SET_FLAG(hdr.rtm_flags, RTF_MPLS);
hdr.rtm_msglen += sizeof(sa_label_out);
/* adjust iovec */
iov[iovcnt].iov_base = &sa_label_out;
@@ -159,8 +159,8 @@ static int kernel_send_rtmsg_v6(int action, mpls_label_t in_label,
sa_label_in.smpls_family = AF_MPLS;
sa_label_in.smpls_label = htonl(in_label << MPLS_LABEL_OFFSET);
/* adjust header */
- hdr.rtm_flags |= RTF_MPLS | RTF_MPATH;
- hdr.rtm_addrs |= RTA_DST;
+ SET_FLAG(hdr.rtm_flags, (RTF_MPLS | RTF_MPATH));
+ SET_FLAG(hdr.rtm_addrs, RTA_DST);
hdr.rtm_msglen += sizeof(sa_label_in);
/* adjust iovec */
iov[iovcnt].iov_base = &sa_label_in;
@@ -184,8 +184,8 @@ static int kernel_send_rtmsg_v6(int action, mpls_label_t in_label,
}
/* adjust header */
- hdr.rtm_flags |= RTF_GATEWAY;
- hdr.rtm_addrs |= RTA_GATEWAY;
+ SET_FLAG(hdr.rtm_flags, RTF_GATEWAY);
+ SET_FLAG(hdr.rtm_addrs, RTA_GATEWAY);
hdr.rtm_msglen += ROUNDUP(sizeof(struct sockaddr_in6));
/* adjust iovec */
iov[iovcnt].iov_base = &nexthop;
@@ -200,8 +200,8 @@ static int kernel_send_rtmsg_v6(int action, mpls_label_t in_label,
htonl(nhlfe->nexthop->nh_label->label[0]
<< MPLS_LABEL_OFFSET);
/* adjust header */
- hdr.rtm_addrs |= RTA_SRC;
- hdr.rtm_flags |= RTF_MPLS;
+ SET_FLAG(hdr.rtm_addrs, RTA_SRC);
+ SET_FLAG(hdr.rtm_flags, RTF_MPLS);
hdr.rtm_msglen += sizeof(sa_label_out);
/* adjust iovec */
iov[iovcnt].iov_base = &sa_label_out;
@@ -324,8 +324,8 @@ static enum zebra_dplane_result kmpw_install(struct zebra_dplane_ctx *ctx)
return ZEBRA_DPLANE_REQUEST_FAILURE;
}
- if (dplane_ctx_get_pw_flags(ctx) & F_PSEUDOWIRE_CWORD)
- imr.imr_flags |= IMR_FLAG_CONTROLWORD;
+ if (CHECK_FLAG(dplane_ctx_get_pw_flags(ctx), F_PSEUDOWIRE_CWORD))
+ SET_FLAG(imr.imr_flags, IMR_FLAG_CONTROLWORD);
/* pseudowire nexthop */
memset(&ss, 0, sizeof(ss));
diff --git a/zebra/zebra_mpls_vty.c b/zebra/zebra_mpls_vty.c
index 83a1aad..b31bf44 100644
--- a/zebra/zebra_mpls_vty.c
+++ b/zebra/zebra_mpls_vty.c
@@ -210,7 +210,7 @@ static int zebra_mpls_bind(struct vty *vty, int add_cmd, const char *prefix,
vty_out(vty, "%% Invalid label\n");
return CMD_WARNING_CONFIG_FAILED;
}
- if (zebra_mpls_label_already_bound(zvrf, label)) {
+ if (zebra_mpls_label_already_bound(zvrf, &p, label)) {
vty_out(vty,
"%% Label already bound to a FEC\n");
return CMD_WARNING_CONFIG_FAILED;
diff --git a/zebra/zebra_nb.c b/zebra/zebra_nb.c
index e1ca5ec..eee9323 100644
--- a/zebra/zebra_nb.c
+++ b/zebra/zebra_nb.c
@@ -803,6 +803,12 @@ const struct frr_yang_module_info frr_zebra_info = {
}
},
{
+ .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/state/bond",
+ .cbs = {
+ .get_elem = lib_interface_zebra_state_bond_get_elem,
+ }
+ },
+ {
.xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/router-id",
.cbs = {
.modify = lib_vrf_zebra_router_id_modify,
diff --git a/zebra/zebra_nb.h b/zebra/zebra_nb.h
index d7cf5f4..b40ed68 100644
--- a/zebra/zebra_nb.h
+++ b/zebra/zebra_nb.h
@@ -285,6 +285,7 @@ struct yang_data *lib_interface_zebra_state_remote_vtep_get_elem(
struct nb_cb_get_elem_args *args);
struct yang_data *lib_interface_zebra_state_mcast_group_get_elem(
struct nb_cb_get_elem_args *args);
+struct yang_data *lib_interface_zebra_state_bond_get_elem(struct nb_cb_get_elem_args *args);
int lib_vrf_zebra_router_id_modify(struct nb_cb_modify_args *args);
int lib_vrf_zebra_router_id_destroy(struct nb_cb_destroy_args *args);
int lib_vrf_zebra_ipv6_router_id_modify(struct nb_cb_modify_args *args);
diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c
index ff2529f..ae6232a 100644
--- a/zebra/zebra_nb_config.c
+++ b/zebra/zebra_nb_config.c
@@ -3102,7 +3102,7 @@ int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_create(
struct nb_cb_create_args *args)
{
struct interface *ifp;
- struct rtadv_rdnss rdnss = {0}, *p;
+ struct rtadv_rdnss rdnss = {{{{0}}}}, *p;
if (args->event != NB_EV_APPLY)
return NB_OK;
@@ -3181,7 +3181,7 @@ int lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_create(
struct nb_cb_create_args *args)
{
struct interface *ifp;
- struct rtadv_dnssl dnssl = {0}, *p;
+ struct rtadv_dnssl dnssl = {{0}}, *p;
int ret;
strlcpy(dnssl.name, yang_dnode_get_string(args->dnode, "domain"),
diff --git a/zebra/zebra_nb_rpcs.c b/zebra/zebra_nb_rpcs.c
index 083ab3f..744ba62 100644
--- a/zebra/zebra_nb_rpcs.c
+++ b/zebra/zebra_nb_rpcs.c
@@ -12,6 +12,8 @@
#include "zebra/zebra_router.h"
#include "zebra/zebra_vrf.h"
#include "zebra/zebra_vxlan.h"
+#include "zebra/zebra_vxlan_if.h"
+#include "zebra/zebra_evpn.h"
/*
* XPath: /frr-zebra:clear-evpn-dup-addr
@@ -20,48 +22,41 @@ int clear_evpn_dup_addr_rpc(struct nb_cb_rpc_args *args)
{
struct zebra_vrf *zvrf;
int ret = NB_OK;
- struct yang_data *yang_dup_choice = NULL, *yang_dup_vni = NULL,
- *yang_dup_ip = NULL, *yang_dup_mac = NULL;
-
- yang_dup_choice = yang_data_list_find(args->input, "%s/%s", args->xpath,
- "input/clear-dup-choice");
+ if (!is_evpn_enabled()) {
+ snprintf(args->errmsg, args->errmsg_len,
+ "%% EVPN not enabled\n");
+ return NB_ERR_VALIDATION;
+ }
zvrf = zebra_vrf_get_evpn();
- if (yang_dup_choice
- && strcmp(yang_dup_choice->value, "all-case") == 0) {
+ if (yang_dnode_exists(args->input, "all-vnis")) {
zebra_vxlan_clear_dup_detect_vni_all(zvrf);
} else {
- vni_t vni;
+ vni_t vni = yang_dnode_get_uint32(args->input, "vni-id");
struct ipaddr host_ip = {.ipa_type = IPADDR_NONE};
struct ethaddr mac;
- yang_dup_vni = yang_data_list_find(
- args->input, "%s/%s", args->xpath,
- "input/clear-dup-choice/single-case/vni-id");
- if (yang_dup_vni) {
- vni = yang_str2uint32(yang_dup_vni->value);
-
- yang_dup_mac = yang_data_list_find(
- args->input, "%s/%s", args->xpath,
- "input/clear-dup-choice/single-case/vni-id/mac-addr");
- yang_dup_ip = yang_data_list_find(
- args->input, "%s/%s", args->xpath,
- "input/clear-dup-choice/single-case/vni-id/vni-ipaddr");
-
- if (yang_dup_mac) {
- yang_str2mac(yang_dup_mac->value, &mac);
- ret = zebra_vxlan_clear_dup_detect_vni_mac(
- zvrf, vni, &mac, args->errmsg,
- args->errmsg_len);
- } else if (yang_dup_ip) {
- yang_str2ip(yang_dup_ip->value, &host_ip);
- ret = zebra_vxlan_clear_dup_detect_vni_ip(
- zvrf, vni, &host_ip, args->errmsg,
- args->errmsg_len);
- } else
- ret = zebra_vxlan_clear_dup_detect_vni(zvrf,
- vni);
+ if (!zebra_evpn_lookup(vni)) {
+ snprintf(args->errmsg, args->errmsg_len,
+ "%% VNI %u does not exist\n", vni);
+ return NB_ERR_VALIDATION;
+ }
+
+ if (yang_dnode_exists(args->input, "mac-addr")) {
+ yang_dnode_get_mac(&mac, args->input, "mac-addr");
+ ret = zebra_vxlan_clear_dup_detect_vni_mac(zvrf, vni,
+ &mac,
+ args->errmsg,
+ args->errmsg_len);
+ } else if (yang_dnode_exists(args->input, "vni-ipaddr")) {
+ yang_dnode_get_ip(&host_ip, args->input, "vni-ipaddr");
+ ret = zebra_vxlan_clear_dup_detect_vni_ip(zvrf, vni,
+ &host_ip,
+ args->errmsg,
+ args->errmsg_len);
+ } else {
+ ret = zebra_vxlan_clear_dup_detect_vni(zvrf, vni);
}
}
if (ret < 0)
diff --git a/zebra/zebra_nb_state.c b/zebra/zebra_nb_state.c
index 00df9bf..63ac787 100644
--- a/zebra/zebra_nb_state.c
+++ b/zebra/zebra_nb_state.c
@@ -49,8 +49,50 @@ lib_interface_zebra_state_down_count_get_elem(struct nb_cb_get_elem_args *args)
struct yang_data *
lib_interface_zebra_state_zif_type_get_elem(struct nb_cb_get_elem_args *args)
{
- /* TODO: implement me. */
- return NULL;
+ const struct interface *ifp = args->list_entry;
+ struct zebra_if *zebra_if;
+ const char *type = NULL;
+
+ zebra_if = ifp->info;
+
+ /*
+ * NOTE: when adding a new type to the switch, make sure it is defined
+ * in it's YANG model.
+ */
+ switch (zebra_if->zif_type) {
+ case ZEBRA_IF_OTHER:
+ type = "frr-zebra:zif-other";
+ break;
+ case ZEBRA_IF_VXLAN:
+ type = "frr-zebra:zif-vxlan";
+ break;
+ case ZEBRA_IF_VRF:
+ type = "frr-zebra:zif-vrf";
+ break;
+ case ZEBRA_IF_BRIDGE:
+ type = "frr-zebra:zif-bridge";
+ break;
+ case ZEBRA_IF_VLAN:
+ type = "frr-zebra:zif-vlan";
+ break;
+ case ZEBRA_IF_MACVLAN:
+ type = "frr-zebra:zif-macvlan";
+ break;
+ case ZEBRA_IF_VETH:
+ type = "frr-zebra:zif-veth";
+ break;
+ case ZEBRA_IF_BOND:
+ type = "frr-zebra:zif-bond";
+ break;
+ case ZEBRA_IF_GRE:
+ type = "frr-zebra:zif-gre";
+ break;
+ }
+
+ if (!type)
+ return NULL;
+
+ return yang_data_new_string(args->xpath, type);
}
/*
@@ -145,6 +187,28 @@ lib_interface_zebra_state_mcast_group_get_elem(struct nb_cb_get_elem_args *args)
return yang_data_new_ipv4(args->xpath, &vni->mcast_grp);
}
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/bond
+ */
+struct yang_data *
+lib_interface_zebra_state_bond_get_elem(struct nb_cb_get_elem_args *args)
+{
+ const struct interface *ifp = args->list_entry;
+ struct zebra_if *zebra_if;
+ struct interface *bond;
+
+ if (!IS_ZEBRA_IF_BOND_SLAVE(ifp))
+ return NULL;
+
+ zebra_if = ifp->info;
+ bond = zebra_if->bondslave_info.bond_if;
+
+ if (!bond)
+ return NULL;
+
+ return yang_data_new_string(args->xpath, bond->name);
+}
+
const void *lib_vrf_zebra_ribs_rib_get_next(struct nb_cb_get_next_args *args)
{
struct vrf *vrf = (struct vrf *)args->parent_list_entry;
@@ -548,7 +612,7 @@ struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_uptime_get_elem(
{
struct route_entry *re = (struct route_entry *)args->list_entry;
- return yang_data_new_date_and_time(args->xpath, re->uptime);
+ return yang_data_new_date_and_time(args->xpath, re->uptime, true);
}
/*
diff --git a/zebra/zebra_neigh.c b/zebra/zebra_neigh.c
index 941088a..a222e7f 100644
--- a/zebra/zebra_neigh.c
+++ b/zebra/zebra_neigh.c
@@ -83,7 +83,7 @@ zebra_neigh_new(ifindex_t ifindex, struct ipaddr *ip, struct ethaddr *mac)
n->ifindex = ifindex;
if (mac) {
memcpy(&n->mac, mac, sizeof(*mac));
- n->flags |= ZEBRA_NEIGH_ENT_ACTIVE;
+ SET_FLAG(n->flags, ZEBRA_NEIGH_ENT_ACTIVE);
}
/* Add to rb_tree */
@@ -118,10 +118,8 @@ static void zebra_neigh_free(struct zebra_neigh_ent *n)
/* if rules are still using the neigh mark it as inactive and
* update the dataplane
*/
- if (n->flags & ZEBRA_NEIGH_ENT_ACTIVE) {
- n->flags &= ~ZEBRA_NEIGH_ENT_ACTIVE;
- memset(&n->mac, 0, sizeof(n->mac));
- }
+ UNSET_FLAG(n->flags, ZEBRA_NEIGH_ENT_ACTIVE);
+ memset(&n->mac, 0, sizeof(n->mac));
zebra_neigh_pbr_rules_update(n);
return;
}
@@ -181,7 +179,7 @@ void zebra_neigh_add(struct interface *ifp, struct ipaddr *ip,
return;
memcpy(&n->mac, mac, sizeof(*mac));
- n->flags |= ZEBRA_NEIGH_ENT_ACTIVE;
+ SET_FLAG(n->flags, ZEBRA_NEIGH_ENT_ACTIVE);
/* update rules linked to the neigh */
zebra_neigh_pbr_rules_update(n);
@@ -201,7 +199,7 @@ void zebra_neigh_deref(struct zebra_pbr_rule *rule)
rule->action.neigh = NULL;
/* remove rule from the list and free if it is inactive */
list_delete_node(n->pbr_rule_list, &rule->action.neigh_listnode);
- if (!(n->flags & ZEBRA_NEIGH_ENT_ACTIVE))
+ if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ENT_ACTIVE))
zebra_neigh_free(n);
}
diff --git a/zebra/zebra_netns_id.c b/zebra/zebra_netns_id.c
index 1af3a3e..4cee3b8 100644
--- a/zebra/zebra_netns_id.c
+++ b/zebra/zebra_netns_id.c
@@ -42,7 +42,7 @@
#define NETLINK_SOCKET_BUFFER_SIZE 512
#define NETLINK_ALIGNTO 4
#define NETLINK_ALIGN(len) \
- (((len) + NETLINK_ALIGNTO - 1) & ~(NETLINK_ALIGNTO - 1))
+ CHECK_FLAG(((len) + NETLINK_ALIGNTO - 1), ~(NETLINK_ALIGNTO - 1))
#define NETLINK_NLATTR_LEN(_a, _b) (unsigned int)((char *)_a - (char *)_b)
#endif /* defined(HAVE_NETLINK) */
@@ -66,7 +66,7 @@ static struct nlmsghdr *initiate_nlh(char *buf, unsigned int *seq, int type)
nlh->nlmsg_type = type;
nlh->nlmsg_flags = NLM_F_REQUEST;
if (type == RTM_NEWNSID)
- nlh->nlmsg_flags |= NLM_F_ACK;
+ SET_FLAG(nlh->nlmsg_flags, NLM_F_ACK);
nlh->nlmsg_seq = *seq = frr_sequence32_next();
return nlh;
}
diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c
index 1bb1292..fb326b0 100644
--- a/zebra/zebra_netns_notify.c
+++ b/zebra/zebra_netns_notify.c
@@ -15,6 +15,7 @@
#include <sched.h>
#endif
#include <dirent.h>
+#include <libgen.h>
#include <sys/inotify.h>
#include <sys/stat.h>
@@ -234,6 +235,7 @@ static void zebra_ns_ready_read(struct event *t)
{
struct zebra_netns_info *zns_info = EVENT_ARG(t);
const char *netnspath;
+ const char *netnspath_basename;
int err, stop_retry = 0;
if (!zns_info)
@@ -261,23 +263,24 @@ static void zebra_ns_ready_read(struct event *t)
zebra_ns_continue_read(zns_info, stop_retry);
return;
}
+ netnspath_basename = basename(strdupa(netnspath));
/* check default name is not already set */
- if (strmatch(VRF_DEFAULT_NAME, basename(netnspath))) {
- zlog_warn("NS notify : NS %s is already default VRF.Cancel VRF Creation", basename(netnspath));
+ if (strmatch(VRF_DEFAULT_NAME, netnspath_basename)) {
+ zlog_warn("NS notify : NS %s is already default VRF.Cancel VRF Creation", netnspath_basename);
zebra_ns_continue_read(zns_info, 1);
return;
}
- if (zebra_ns_notify_is_default_netns(basename(netnspath))) {
+ if (zebra_ns_notify_is_default_netns(netnspath_basename)) {
zlog_warn(
"NS notify : NS %s is default VRF. Ignore VRF creation",
- basename(netnspath));
+ netnspath_basename);
zebra_ns_continue_read(zns_info, 1);
return;
}
/* success : close fd and create zns context */
- zebra_ns_notify_create_context_from_entry_name(basename(netnspath));
+ zebra_ns_notify_create_context_from_entry_name(netnspath_basename);
zebra_ns_continue_read(zns_info, 1);
}
@@ -304,7 +307,7 @@ static void zebra_ns_notify_read(struct event *t)
char *netnspath;
struct zebra_netns_info *netnsinfo;
- if (!(event->mask & (IN_CREATE | IN_DELETE)))
+ if (!CHECK_FLAG(event->mask, (IN_CREATE | IN_DELETE)))
continue;
if (offsetof(struct inotify_event, name) + event->len
@@ -350,7 +353,7 @@ static void zebra_ns_notify_read(struct event *t)
memcpy(event_name, event->name, event->len);
event_name[event->len - 1] = 0;
- if (event->mask & IN_DELETE) {
+ if (CHECK_FLAG(event->mask, IN_DELETE)) {
zebra_ns_delete(event_name);
continue;
}
@@ -396,7 +399,7 @@ void zebra_ns_notify_parse(void)
continue;
}
/* check default name is not already set */
- if (strmatch(VRF_DEFAULT_NAME, basename(dent->d_name))) {
+ if (strmatch(VRF_DEFAULT_NAME, basename(strdupa(dent->d_name)))) {
zlog_warn("NS notify : NS %s is already default VRF.Cancel VRF Creation", dent->d_name);
continue;
}
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c
index ed949da..9971b19 100644
--- a/zebra/zebra_nhg.c
+++ b/zebra/zebra_nhg.c
@@ -309,8 +309,10 @@ static int zebra_nhg_insert_id(struct nhg_hash_entry *nhe)
static void zebra_nhg_set_if(struct nhg_hash_entry *nhe, struct interface *ifp)
{
+ struct zebra_if *zif = (struct zebra_if *)ifp->info;
+
nhe->ifp = ifp;
- if_nhg_dependents_add(ifp, nhe);
+ nhg_connected_tree_add_nhe(&zif->nhg_dependents, nhe);
}
static void
@@ -1031,31 +1033,44 @@ static struct nhg_ctx *nhg_ctx_init(uint32_t id, struct nexthop *nh,
return ctx;
}
-static void zebra_nhg_set_valid(struct nhg_hash_entry *nhe)
+static void zebra_nhg_set_valid(struct nhg_hash_entry *nhe, bool valid)
{
struct nhg_connected *rb_node_dep;
- SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
+ if (valid)
+ SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
+ else {
+ UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
- frr_each(nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep)
- zebra_nhg_set_valid(rb_node_dep->nhe);
-}
+ /* If we're in shutdown, this interface event needs to clean
+ * up installed NHGs, so don't clear that flag directly.
+ */
+ if (!zebra_router_in_shutdown())
+ UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
+ }
-static void zebra_nhg_set_invalid(struct nhg_hash_entry *nhe)
-{
- struct nhg_connected *rb_node_dep;
+ /* Update validity of nexthops depending on it */
+ frr_each (nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) {
+ if (!valid) {
+ /*
+ * Grab the first nexthop from the depending nexthop group
+ * then let's find the nexthop in that group that matches
+ * my individual nexthop and mark it as no longer ACTIVE
+ */
+ struct nexthop *nexthop = rb_node_dep->nhe->nhg.nexthop;
- UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
+ while (nexthop) {
+ if (nexthop_same(nexthop, nhe->nhg.nexthop))
+ break;
- /* If we're in shutdown, this interface event needs to clean
- * up installed NHGs, so don't clear that flag directly.
- */
- if (!zebra_router_in_shutdown())
- UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
+ nexthop = nexthop->next;
+ }
- /* Update validity of nexthops depending on it */
- frr_each(nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep)
- zebra_nhg_check_valid(rb_node_dep->nhe);
+ if (nexthop)
+ UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ }
+ zebra_nhg_set_valid(rb_node_dep->nhe, valid);
+ }
}
void zebra_nhg_check_valid(struct nhg_hash_entry *nhe)
@@ -1063,6 +1078,13 @@ void zebra_nhg_check_valid(struct nhg_hash_entry *nhe)
struct nhg_connected *rb_node_dep = NULL;
bool valid = false;
+ /*
+ * If I have other nhe's depending on me, then this is a
+ * singleton nhe so set this nexthops flag as appropriate.
+ */
+ if (nhg_connected_tree_count(&nhe->nhg_depends))
+ UNSET_FLAG(nhe->nhg.nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+
/* If anthing else in the group is valid, the group is valid */
frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) {
if (CHECK_FLAG(rb_node_dep->nhe->flags, NEXTHOP_GROUP_VALID)) {
@@ -1071,10 +1093,7 @@ void zebra_nhg_check_valid(struct nhg_hash_entry *nhe)
}
}
- if (valid)
- zebra_nhg_set_valid(nhe);
- else
- zebra_nhg_set_invalid(nhe);
+ zebra_nhg_set_valid(nhe, valid);
}
static void zebra_nhg_release_all_deps(struct nhg_hash_entry *nhe)
@@ -1082,8 +1101,11 @@ static void zebra_nhg_release_all_deps(struct nhg_hash_entry *nhe)
/* Remove it from any lists it may be on */
zebra_nhg_depends_release(nhe);
zebra_nhg_dependents_release(nhe);
- if (nhe->ifp)
- if_nhg_dependents_del(nhe->ifp, nhe);
+ if (nhe->ifp) {
+ struct zebra_if *zif = nhe->ifp->info;
+
+ nhg_connected_tree_del_nhe(&zif->nhg_dependents, nhe);
+ }
}
static void zebra_nhg_release(struct nhg_hash_entry *nhe)
@@ -1115,7 +1137,7 @@ static void zebra_nhg_handle_install(struct nhg_hash_entry *nhe, bool install)
struct nhg_connected *rb_node_dep;
frr_each_safe (nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) {
- zebra_nhg_set_valid(rb_node_dep->nhe);
+ zebra_nhg_set_valid(rb_node_dep->nhe, true);
/* install dependent NHG into kernel */
if (install) {
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
@@ -1799,8 +1821,8 @@ static struct nexthop *nexthop_set_resolved(afi_t afi,
break;
}
- if (newhop->flags & NEXTHOP_FLAG_ONLINK)
- resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
+ if (CHECK_FLAG(newhop->flags, NEXTHOP_FLAG_ONLINK))
+ SET_FLAG(resolved_hop->flags, NEXTHOP_FLAG_ONLINK);
/* Copy labels of the resolved route and the parent resolving to it */
if (policy) {
@@ -3094,14 +3116,15 @@ void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe)
zebra_nhg_install_kernel(rb_node_dep->nhe);
}
- if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID)
- && !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED)
- && !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_QUEUED)) {
+ if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID) &&
+ (!CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED) ||
+ CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_REINSTALL)) &&
+ !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_QUEUED)) {
/* Change its type to us since we are installing it */
if (!ZEBRA_NHG_CREATED(nhe))
nhe->type = ZEBRA_ROUTE_NHG;
- int ret = dplane_nexthop_add(nhe);
+ enum zebra_dplane_result ret = dplane_nexthop_add(nhe);
switch (ret) {
case ZEBRA_DPLANE_REQUEST_QUEUED:
@@ -3114,8 +3137,9 @@ void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe)
nhe);
break;
case ZEBRA_DPLANE_REQUEST_SUCCESS:
- SET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
- zebra_nhg_handle_install(nhe, false);
+ flog_err(EC_ZEBRA_DP_INVALID_RC,
+ "DPlane returned an invalid result code for attempt of installation of %pNG into the kernel",
+ nhe);
break;
}
}
@@ -3182,8 +3206,9 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx)
}
UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_QUEUED);
- if (status == ZEBRA_DPLANE_REQUEST_SUCCESS) {
- SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
+ UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_REINSTALL);
+ switch (status) {
+ case ZEBRA_DPLANE_REQUEST_SUCCESS:
SET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
zebra_nhg_handle_install(nhe, true);
@@ -3192,7 +3217,9 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx)
zsend_nhg_notify(nhe->type, nhe->zapi_instance,
nhe->zapi_session, nhe->id,
ZAPI_NHG_INSTALLED);
- } else {
+ break;
+ case ZEBRA_DPLANE_REQUEST_FAILURE:
+ UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
/* If daemon nhg, send it an update */
if (PROTO_OWNED(nhe))
zsend_nhg_notify(nhe->type, nhe->zapi_instance,
@@ -3205,6 +3232,12 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx)
EC_ZEBRA_DP_INSTALL_FAIL,
"Failed to install Nexthop (%pNG) into the kernel",
nhe);
+ break;
+ case ZEBRA_DPLANE_REQUEST_QUEUED:
+ flog_err(EC_ZEBRA_DP_INVALID_RC,
+ "Dplane returned an invalid result code for a result from the dplane for %pNG into the kernel",
+ nhe);
+ break;
}
}
}
@@ -3682,12 +3715,11 @@ void zebra_interface_nhg_reinstall(struct interface *ifp)
&rb_node_dep->nhe->nhg_dependents,
rb_node_dependent) {
if (IS_ZEBRA_DEBUG_NHG)
- zlog_debug(
- "%s dependent nhe %pNG unset installed flag",
- __func__,
- rb_node_dependent->nhe);
- UNSET_FLAG(rb_node_dependent->nhe->flags,
- NEXTHOP_GROUP_INSTALLED);
+ zlog_debug("%s dependent nhe %pNG Setting Reinstall flag",
+ __func__,
+ rb_node_dependent->nhe);
+ SET_FLAG(rb_node_dependent->nhe->flags,
+ NEXTHOP_GROUP_REINSTALL);
}
}
}
diff --git a/zebra/zebra_nhg.h b/zebra/zebra_nhg.h
index 4eddecb..3bb697a 100644
--- a/zebra/zebra_nhg.h
+++ b/zebra/zebra_nhg.h
@@ -85,7 +85,7 @@ struct nhg_hash_entry {
* nhg(1)->nhg_dependents is 3 in the tree
*
* nhg(2)->nhg_depends is empty
- * nhg(3)->nhg_dependents is 3 in the tree
+ * nhg(2)->nhg_dependents is 3 in the tree
*/
struct nhg_connected_tree_head nhg_depends, nhg_dependents;
@@ -144,6 +144,14 @@ struct nhg_hash_entry {
* Track FPM installation status..
*/
#define NEXTHOP_GROUP_FPM (1 << 7)
+
+/*
+ * When an interface comes up install the
+ * singleton's and schedule the NHG's that
+ * are using this nhg to be reinstalled
+ * when installation is successful.
+ */
+#define NEXTHOP_GROUP_REINSTALL (1 << 8)
};
/* Upper 4 bits of the NHG are reserved for indicating the NHG type */
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index b387e99..bff8258 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -1266,327 +1266,42 @@ failure:
*/
void show_nexthop_json_helper(json_object *json_nexthop,
const struct nexthop *nexthop,
+ const struct route_node *rn,
const struct route_entry *re)
{
- json_object *json_labels = NULL;
- json_object *json_backups = NULL;
- json_object *json_seg6local = NULL;
- json_object *json_seg6 = NULL;
- json_object *json_segs = NULL;
- int i;
-
- json_object_int_add(json_nexthop, "flags", nexthop->flags);
-
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
- json_object_boolean_true_add(json_nexthop, "duplicate");
-
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
- json_object_boolean_true_add(json_nexthop, "fib");
-
- switch (nexthop->type) {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- json_object_string_addf(json_nexthop, "ip", "%pI4",
- &nexthop->gate.ipv4);
- json_object_string_add(json_nexthop, "afi", "ipv4");
-
- if (nexthop->ifindex) {
- json_object_int_add(json_nexthop, "interfaceIndex",
- nexthop->ifindex);
- json_object_string_add(json_nexthop, "interfaceName",
- ifindex2ifname(nexthop->ifindex,
- nexthop->vrf_id));
- }
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- json_object_string_addf(json_nexthop, "ip", "%pI6",
- &nexthop->gate.ipv6);
- json_object_string_add(json_nexthop, "afi", "ipv6");
-
- if (nexthop->ifindex) {
- json_object_int_add(json_nexthop, "interfaceIndex",
- nexthop->ifindex);
- json_object_string_add(json_nexthop, "interfaceName",
- ifindex2ifname(nexthop->ifindex,
- nexthop->vrf_id));
- }
- break;
-
- case NEXTHOP_TYPE_IFINDEX:
- json_object_boolean_true_add(json_nexthop, "directlyConnected");
- json_object_int_add(json_nexthop, "interfaceIndex",
- nexthop->ifindex);
- json_object_string_add(
- json_nexthop, "interfaceName",
- ifindex2ifname(nexthop->ifindex, nexthop->vrf_id));
- break;
- case NEXTHOP_TYPE_BLACKHOLE:
- json_object_boolean_true_add(json_nexthop, "unreachable");
- switch (nexthop->bh_type) {
- case BLACKHOLE_REJECT:
- json_object_boolean_true_add(json_nexthop, "reject");
- break;
- case BLACKHOLE_ADMINPROHIB:
- json_object_boolean_true_add(json_nexthop,
- "adminProhibited");
- break;
- case BLACKHOLE_NULL:
- json_object_boolean_true_add(json_nexthop, "blackhole");
- break;
- case BLACKHOLE_UNSPEC:
- break;
- }
- break;
- }
-
- /* This nexthop is a resolver for the parent nexthop.
- * Set resolver flag for better clarity and delimiter
- * in flat list of nexthops in json.
- */
- if (nexthop->rparent)
- json_object_boolean_true_add(json_nexthop, "resolver");
-
- if ((re == NULL || (nexthop->vrf_id != re->vrf_id)))
- json_object_string_add(json_nexthop, "vrf",
- vrf_id_to_name(nexthop->vrf_id));
+ bool display_vrfid = false;
+ uint8_t rn_family;
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
- json_object_boolean_true_add(json_nexthop, "duplicate");
+ if (re == NULL || nexthop->vrf_id != re->vrf_id)
+ display_vrfid = true;
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
- json_object_boolean_true_add(json_nexthop, "active");
-
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
- json_object_boolean_true_add(json_nexthop, "onLink");
-
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_LINKDOWN))
- json_object_boolean_true_add(json_nexthop, "linkDown");
-
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
- json_object_boolean_true_add(json_nexthop, "recursive");
-
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
- json_backups = json_object_new_array();
- for (i = 0; i < nexthop->backup_num; i++) {
- json_object_array_add(
- json_backups,
- json_object_new_int(nexthop->backup_idx[i]));
- }
-
- json_object_object_add(json_nexthop, "backupIndex",
- json_backups);
- }
-
- switch (nexthop->type) {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- if (nexthop->src.ipv4.s_addr)
- json_object_string_addf(json_nexthop, "source", "%pI4",
- &nexthop->src.ipv4);
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
- json_object_string_addf(json_nexthop, "source", "%pI6",
- &nexthop->src.ipv6);
- break;
- case NEXTHOP_TYPE_IFINDEX:
- case NEXTHOP_TYPE_BLACKHOLE:
- break;
- }
-
- if (nexthop->nh_label && nexthop->nh_label->num_labels) {
- json_labels = json_object_new_array();
-
- for (int label_index = 0;
- label_index < nexthop->nh_label->num_labels; label_index++)
- json_object_array_add(
- json_labels,
- json_object_new_int((
- (nexthop->nh_label_type ==
- ZEBRA_LSP_EVPN)
- ? label2vni(
- &nexthop->nh_label->label
- [label_index])
- : nexthop->nh_label->label
- [label_index])));
-
- json_object_object_add(json_nexthop, "labels", json_labels);
- }
+ if (rn)
+ rn_family = rn->p.family;
+ else
+ rn_family = AF_UNSPEC;
- if (nexthop->weight)
- json_object_int_add(json_nexthop, "weight", nexthop->weight);
-
- if (nexthop->srte_color)
- json_object_int_add(json_nexthop, "srteColor",
- nexthop->srte_color);
-
- if (nexthop->nh_srv6) {
- json_seg6local = json_object_new_object();
- json_object_string_add(
- json_seg6local, "action",
- seg6local_action2str(
- nexthop->nh_srv6->seg6local_action));
- json_object_object_add(json_nexthop, "seg6local",
- json_seg6local);
- if (nexthop->nh_srv6->seg6_segs &&
- nexthop->nh_srv6->seg6_segs->num_segs == 1) {
- json_seg6 = json_object_new_object();
- json_object_string_addf(json_seg6, "segs", "%pI6",
- &nexthop->nh_srv6->seg6_segs
- ->seg[0]);
- json_object_object_add(json_nexthop, "seg6", json_seg6);
- } else {
- if (nexthop->nh_srv6->seg6_segs) {
- json_segs = json_object_new_array();
- for (int seg_idx = 0;
- seg_idx <
- nexthop->nh_srv6->seg6_segs->num_segs;
- seg_idx++)
- json_object_array_add(
- json_segs,
- json_object_new_stringf(
- "%pI6",
- &nexthop->nh_srv6
- ->seg6_segs
- ->seg[seg_idx]));
- json_object_object_add(json_nexthop, "seg6",
- json_segs);
- }
- }
- }
+ nexthop_json_helper(json_nexthop, nexthop, display_vrfid, rn_family);
}
/*
* Helper for nexthop output, used in the 'show ip route' path
*/
-void show_route_nexthop_helper(struct vty *vty, const struct route_entry *re,
+void show_route_nexthop_helper(struct vty *vty, const struct route_node *rn,
+ const struct route_entry *re,
const struct nexthop *nexthop)
{
- char buf[MPLS_LABEL_STRLEN];
- char seg_buf[SRV6_SEG_STRLEN];
- struct seg6_segs segs;
- uint8_t i;
-
- switch (nexthop->type) {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- vty_out(vty, " via %pI4", &nexthop->gate.ipv4);
- if (nexthop->ifindex)
- vty_out(vty, ", %s",
- ifindex2ifname(nexthop->ifindex,
- nexthop->vrf_id));
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- vty_out(vty, " via %s",
- inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
- sizeof(buf)));
- if (nexthop->ifindex)
- vty_out(vty, ", %s",
- ifindex2ifname(nexthop->ifindex,
- nexthop->vrf_id));
- break;
-
- case NEXTHOP_TYPE_IFINDEX:
- vty_out(vty, " is directly connected, %s",
- ifindex2ifname(nexthop->ifindex, nexthop->vrf_id));
- break;
- case NEXTHOP_TYPE_BLACKHOLE:
- vty_out(vty, " unreachable");
- switch (nexthop->bh_type) {
- case BLACKHOLE_REJECT:
- vty_out(vty, " (ICMP unreachable)");
- break;
- case BLACKHOLE_ADMINPROHIB:
- vty_out(vty, " (ICMP admin-prohibited)");
- break;
- case BLACKHOLE_NULL:
- vty_out(vty, " (blackhole)");
- break;
- case BLACKHOLE_UNSPEC:
- break;
- }
- break;
- }
-
- if ((re == NULL || (nexthop->vrf_id != re->vrf_id)))
- vty_out(vty, " (vrf %s)", vrf_id_to_name(nexthop->vrf_id));
-
- if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
- vty_out(vty, " inactive");
+ bool display_vrfid = false;
+ uint8_t rn_family;
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
- vty_out(vty, " onlink");
+ if (re == NULL || nexthop->vrf_id != re->vrf_id)
+ display_vrfid = true;
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_LINKDOWN))
- vty_out(vty, " linkdown");
-
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
- vty_out(vty, " (recursive)");
-
- switch (nexthop->type) {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- if (nexthop->src.ipv4.s_addr) {
- vty_out(vty, ", src %pI4", &nexthop->src.ipv4);
- /* SR-TE information */
- if (nexthop->srte_color)
- vty_out(vty, ", SR-TE color %u",
- nexthop->srte_color);
- }
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
- vty_out(vty, ", src %pI6", &nexthop->src.ipv6);
- break;
- case NEXTHOP_TYPE_IFINDEX:
- case NEXTHOP_TYPE_BLACKHOLE:
- break;
- }
-
- /* Label information */
- if (nexthop->nh_label && nexthop->nh_label->num_labels) {
- vty_out(vty, ", label %s",
- mpls_label2str(nexthop->nh_label->num_labels,
- nexthop->nh_label->label, buf,
- sizeof(buf), nexthop->nh_label_type, 1));
- }
-
- if (nexthop->nh_srv6) {
- seg6local_context2str(buf, sizeof(buf),
- &nexthop->nh_srv6->seg6local_ctx,
- nexthop->nh_srv6->seg6local_action);
- if (nexthop->nh_srv6->seg6local_action !=
- ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
- vty_out(vty, ", seg6local %s %s",
- seg6local_action2str(
- nexthop->nh_srv6->seg6local_action),
- buf);
- if (nexthop->nh_srv6->seg6_segs &&
- IPV6_ADDR_CMP(&nexthop->nh_srv6->seg6_segs->seg[0],
- &in6addr_any)) {
- segs.num_segs = nexthop->nh_srv6->seg6_segs->num_segs;
- for (i = 0; i < segs.num_segs; i++)
- memcpy(&segs.segs[i],
- &nexthop->nh_srv6->seg6_segs->seg[i],
- sizeof(struct in6_addr));
- snprintf_seg6_segs(seg_buf, SRV6_SEG_STRLEN, &segs);
- vty_out(vty, ", seg6 %s", seg_buf);
- }
- }
-
- if (nexthop->weight)
- vty_out(vty, ", weight %u", nexthop->weight);
-
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
- vty_out(vty, ", backup %d", nexthop->backup_idx[0]);
+ if (rn)
+ rn_family = rn->p.family;
+ else
+ rn_family = AF_UNSPEC;
- for (i = 1; i < nexthop->backup_num; i++)
- vty_out(vty, ",%d", nexthop->backup_idx[i]);
- }
+ nexthop_vty_helper(vty, nexthop, display_vrfid, rn_family);
}
static void print_rnh(struct route_node *rn, struct vty *vty, json_object *json)
@@ -1644,9 +1359,10 @@ static void print_rnh(struct route_node *rn, struct vty *vty, json_object *json)
json_object_array_add(json_nexthop_array,
json_nexthop);
show_nexthop_json_helper(json_nexthop, nexthop,
- NULL);
+ rn, NULL);
} else {
- show_route_nexthop_helper(vty, NULL, nexthop);
+ show_route_nexthop_helper(vty, rn, NULL,
+ nexthop);
vty_out(vty, "\n");
}
}
diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h
index 07db7bb..f0b10d8 100644
--- a/zebra/zebra_rnh.h
+++ b/zebra/zebra_rnh.h
@@ -45,8 +45,10 @@ bool rnh_get_hide_backups(void);
void show_nexthop_json_helper(json_object *json_nexthop,
const struct nexthop *nexthop,
+ const struct route_node *rn,
const struct route_entry *re);
-void show_route_nexthop_helper(struct vty *vty, const struct route_entry *re,
+void show_route_nexthop_helper(struct vty *vty, const struct route_node *rn,
+ const struct route_entry *re,
const struct nexthop *nexthop);
#ifdef __cplusplus
diff --git a/zebra/zebra_routemap_nb_config.c b/zebra/zebra_routemap_nb_config.c
index 5bcfb72..ad012da 100644
--- a/zebra/zebra_routemap_nb_config.c
+++ b/zebra/zebra_routemap_nb_config.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
#include <zebra.h>
#include "lib/command.h"
diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c
index c5b8505..d5cd30e 100644
--- a/zebra/zebra_srv6_vty.c
+++ b/zebra/zebra_srv6_vty.c
@@ -475,16 +475,24 @@ static int zebra_sr_config(struct vty *vty)
struct listnode *node;
struct srv6_locator *locator;
char str[256];
+ bool display_source_srv6 = false;
+
+ if (srv6 && !IPV6_ADDR_SAME(&srv6->encap_src_addr, &in6addr_any))
+ display_source_srv6 = true;
vty_out(vty, "!\n");
- if (zebra_srv6_is_enable()) {
+ if (display_source_srv6 || zebra_srv6_is_enable()) {
vty_out(vty, "segment-routing\n");
vty_out(vty, " srv6\n");
+ }
+ if (display_source_srv6) {
if (!IPV6_ADDR_SAME(&srv6->encap_src_addr, &in6addr_any)) {
vty_out(vty, " encapsulation\n");
vty_out(vty, " source-address %pI6\n",
&srv6->encap_src_addr);
}
+ }
+ if (zebra_srv6_is_enable()) {
vty_out(vty, " locators\n");
for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) {
inet_ntop(AF_INET6, &locator->prefix.prefix,
@@ -514,6 +522,8 @@ static int zebra_sr_config(struct vty *vty)
vty_out(vty, " !\n");
vty_out(vty, " exit\n");
vty_out(vty, " !\n");
+ }
+ if (display_source_srv6 || zebra_srv6_is_enable()) {
vty_out(vty, "exit\n");
vty_out(vty, "!\n");
}
diff --git a/zebra/zebra_trace.c b/zebra/zebra_trace.c
index fef5ad2..7b0fb32 100644
--- a/zebra/zebra_trace.c
+++ b/zebra/zebra_trace.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
#define TRACEPOINT_CREATE_PROBES
#define TRACEPOINT_DEFINE
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 9a68d5a..ae82d20 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -60,28 +60,33 @@ struct route_show_ctx {
};
static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
- safi_t safi, bool use_fib, json_object *vrf_json,
- bool use_json, route_tag_t tag,
+ safi_t safi, bool use_fib, bool use_json,
+ route_tag_t tag,
const struct prefix *longer_prefix_p,
bool supernets_only, int type,
unsigned short ospf_instance_id, uint32_t tableid,
bool show_ng, struct route_show_ctx *ctx);
static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
int mcast, bool use_fib, bool show_ng);
-static void vty_show_ip_route_summary(struct vty *vty,
- struct route_table *table, bool use_json);
+static void vty_show_ip_route_summary(struct vty *vty, struct route_table *table,
+ json_object *vrf_json, bool use_json);
static void vty_show_ip_route_summary_prefix(struct vty *vty,
struct route_table *table,
+ json_object *vrf_json,
bool use_json);
/* Helper api to format a nexthop in the 'detailed' output path. */
static void show_nexthop_detail_helper(struct vty *vty,
+ const struct route_node *rn,
const struct route_entry *re,
const struct nexthop *nexthop,
bool is_backup);
static void show_ip_route_dump_vty(struct vty *vty, struct route_table *table);
-static void show_ip_route_nht_dump(struct vty *vty, struct nexthop *nexthop,
- struct route_entry *re, unsigned int num);
+static void show_ip_route_nht_dump(struct vty *vty,
+ const struct nexthop *nexthop,
+ const struct route_node *rn,
+ const struct route_entry *re,
+ unsigned int num);
DEFUN (ip_multicast_mode,
ip_multicast_mode_cmd,
@@ -148,8 +153,8 @@ DEFPY (show_ip_rpf,
};
return do_show_ip_route(vty, VRF_DEFAULT_NAME, ip ? AFI_IP : AFI_IP6,
- SAFI_MULTICAST, false, NULL, uj, 0, NULL, false,
- 0, 0, 0, false, &ctx);
+ SAFI_MULTICAST, false, uj, 0, NULL, false, 0, 0,
+ 0, false, &ctx);
}
DEFPY (show_ip_rpf_addr,
@@ -210,7 +215,7 @@ static char re_status_output_char(const struct route_entry *re,
if (is_fib) {
star_p = !!CHECK_FLAG(nhop->flags,
NEXTHOP_FLAG_FIB);
- } else
+ } else if (CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_ACTIVE))
star_p = true;
}
@@ -251,7 +256,7 @@ static char re_status_output_char(const struct route_entry *re,
/*
* Show backup nexthop info, in the 'detailed' output path
*/
-static void show_nh_backup_helper(struct vty *vty,
+static void show_nh_backup_helper(struct vty *vty, const struct route_node *rn,
const struct route_entry *re,
const struct nexthop *nexthop)
{
@@ -281,7 +286,7 @@ static void show_nh_backup_helper(struct vty *vty,
temp = backup;
while (backup) {
vty_out(vty, " ");
- show_nexthop_detail_helper(vty, re, backup,
+ show_nexthop_detail_helper(vty, rn, re, backup,
true /*backup*/);
vty_out(vty, "\n");
@@ -302,11 +307,11 @@ static void show_nh_backup_helper(struct vty *vty,
* output path.
*/
static void show_nexthop_detail_helper(struct vty *vty,
+ const struct route_node *rn,
const struct route_entry *re,
const struct nexthop *nexthop,
bool is_backup)
{
- char addrstr[32];
char buf[MPLS_LABEL_STRLEN];
int i;
@@ -390,23 +395,21 @@ static void show_nexthop_detail_helper(struct vty *vty,
switch (nexthop->type) {
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX:
- if (nexthop->src.ipv4.s_addr) {
- if (inet_ntop(AF_INET, &nexthop->src.ipv4,
- addrstr, sizeof(addrstr)))
- vty_out(vty, ", src %s",
- addrstr);
- }
+ if (nexthop->rmap_src.ipv4.s_addr)
+ vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4);
+ else if (nexthop->src.ipv4.s_addr)
+ vty_out(vty, ", src %pI4", &nexthop->src.ipv4);
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
- if (!IPV6_ADDR_SAME(&nexthop->src.ipv6,
- &in6addr_any)) {
- if (inet_ntop(AF_INET6, &nexthop->src.ipv6,
- addrstr, sizeof(addrstr)))
- vty_out(vty, ", src %s",
- addrstr);
- }
+ /* Allow for 5549 ipv4 prefix with ipv6 nexthop */
+ if (rn->p.family == AF_INET && nexthop->rmap_src.ipv4.s_addr)
+ vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4);
+ else if (!IPV6_ADDR_SAME(&nexthop->rmap_src.ipv6, &in6addr_any))
+ vty_out(vty, ", rmapsrc %pI6", &nexthop->rmap_src.ipv6);
+ else if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
+ vty_out(vty, ", src %pI6", &nexthop->src.ipv6);
break;
case NEXTHOP_TYPE_IFINDEX:
@@ -590,13 +593,13 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) {
/* Use helper to format each nexthop */
- show_nexthop_detail_helper(vty, re, nexthop,
+ show_nexthop_detail_helper(vty, rn, re, nexthop,
false /*not backup*/);
vty_out(vty, "\n");
/* Include backup(s), if present */
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP))
- show_nh_backup_helper(vty, re, nexthop);
+ show_nh_backup_helper(vty, rn, re, nexthop);
}
zebra_show_ip_route_opaque(vty, re, NULL);
@@ -703,8 +706,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
json_nexthop = json_object_new_object();
- show_nexthop_json_helper(json_nexthop,
- nexthop, re);
+ show_nexthop_json_helper(json_nexthop, nexthop, rn, re);
json_object_array_add(json_nexthops,
json_nexthop);
@@ -724,8 +726,8 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
json_nexthop = json_object_new_object();
- show_nexthop_json_helper(json_nexthop,
- nexthop, re);
+ show_nexthop_json_helper(json_nexthop, nexthop,
+ rn, re);
json_object_array_add(json_nexthops,
json_nexthop);
}
@@ -790,7 +792,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
len - 3 + (2 * nexthop_level(nexthop)), ' ');
}
- show_route_nexthop_helper(vty, re, nexthop);
+ show_route_nexthop_helper(vty, rn, re, nexthop);
vty_out(vty, ", %s\n", up_str);
}
@@ -821,7 +823,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
vty_out(vty, " b%c %*c",
(star_p ? '*' : ' '),
len - 3 + (2 * nexthop_level(nexthop)), ' ');
- show_route_nexthop_helper(vty, re, nexthop);
+ show_route_nexthop_helper(vty, rn, re, nexthop);
vty_out(vty, "\n");
}
@@ -856,19 +858,20 @@ static void vty_show_ip_route_detail_json(struct vty *vty,
vty_json(vty, json);
}
-static void
-do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
- struct route_table *table, afi_t afi, bool use_fib,
- json_object *vrf_json, route_tag_t tag,
- const struct prefix *longer_prefix_p, bool supernets_only,
- int type, unsigned short ospf_instance_id, bool use_json,
- uint32_t tableid, bool show_ng, struct route_show_ctx *ctx)
+static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
+ struct route_table *table, afi_t afi,
+ bool use_fib, route_tag_t tag,
+ const struct prefix *longer_prefix_p,
+ bool supernets_only, int type,
+ unsigned short ospf_instance_id, bool use_json,
+ uint32_t tableid, bool show_ng,
+ struct route_show_ctx *ctx)
{
struct route_node *rn;
struct route_entry *re;
+ bool first_json = true;
int first = 1;
rib_dest_t *dest;
- json_object *json = NULL;
json_object *json_prefix = NULL;
uint32_t addr;
char buf[BUFSIZ];
@@ -884,9 +887,6 @@ do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
* => display the VRF and table if specific
*/
- if (use_json && !vrf_json)
- json = json_object_new_object();
-
/* Show all routes. */
for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
dest = rib_dest_from_rnode(rn);
@@ -959,28 +959,20 @@ do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
if (json_prefix) {
prefix2str(&rn->p, buf, sizeof(buf));
- if (!vrf_json)
- json_object_object_add(json, buf, json_prefix);
- else
- json_object_object_add(vrf_json, buf,
- json_prefix);
+ vty_json_key(vty, buf, &first_json);
+ vty_json_no_pretty(vty, json_prefix);
+
json_prefix = NULL;
}
}
- /*
- * This is an extremely expensive operation at scale
- * and non-pretty reduces memory footprint significantly.
- */
- if (use_json && !vrf_json) {
- vty_json_no_pretty(vty, json);
- json = NULL;
- }
+ if (use_json)
+ vty_json_close(vty, first_json);
}
static void do_show_ip_route_all(struct vty *vty, struct zebra_vrf *zvrf,
- afi_t afi, bool use_fib, json_object *vrf_json,
- bool use_json, route_tag_t tag,
+ afi_t afi, bool use_fib, bool use_json,
+ route_tag_t tag,
const struct prefix *longer_prefix_p,
bool supernets_only, int type,
unsigned short ospf_instance_id, bool show_ng,
@@ -1000,15 +992,15 @@ static void do_show_ip_route_all(struct vty *vty, struct zebra_vrf *zvrf,
continue;
do_show_ip_route(vty, zvrf_name(zvrf), afi, SAFI_UNICAST,
- use_fib, vrf_json, use_json, tag,
- longer_prefix_p, supernets_only, type,
- ospf_instance_id, zrt->tableid, show_ng, ctx);
+ use_fib, use_json, tag, longer_prefix_p,
+ supernets_only, type, ospf_instance_id,
+ zrt->tableid, show_ng, ctx);
}
}
static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
- safi_t safi, bool use_fib, json_object *vrf_json,
- bool use_json, route_tag_t tag,
+ safi_t safi, bool use_fib, bool use_json,
+ route_tag_t tag,
const struct prefix *longer_prefix_p,
bool supernets_only, int type,
unsigned short ospf_instance_id, uint32_t tableid,
@@ -1043,7 +1035,7 @@ static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
return CMD_SUCCESS;
}
- do_show_route_helper(vty, zvrf, table, afi, use_fib, vrf_json, tag,
+ do_show_route_helper(vty, zvrf, table, afi, use_fib, tag,
longer_prefix_p, supernets_only, type,
ospf_instance_id, use_json, tableid, show_ng, ctx);
@@ -1225,7 +1217,12 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe,
json_object_boolean_true_add(json, "valid");
else
vty_out(vty, " Valid");
-
+ if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_REINSTALL)) {
+ if (json)
+ json_object_boolean_true_add(json, "reInstall");
+ else
+ vty_out(vty, ", Reinstall");
+ }
if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED)) {
if (json)
json_object_boolean_true_add(json, "installed");
@@ -1272,14 +1269,15 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe,
for (ALL_NEXTHOPS(nhe->nhg, nexthop)) {
if (json_nexthop_array) {
json_nexthops = json_object_new_object();
- show_nexthop_json_helper(json_nexthops, nexthop, NULL);
+ show_nexthop_json_helper(json_nexthops, nexthop, NULL,
+ NULL);
} else {
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
vty_out(vty, " ");
else
/* Make recursive nexthops a bit more clear */
vty_out(vty, " ");
- show_route_nexthop_helper(vty, NULL, nexthop);
+ show_route_nexthop_helper(vty, NULL, NULL, nexthop);
}
if (nhe->backup_info == NULL || nhe->backup_info->nhe == NULL) {
@@ -1337,7 +1335,7 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe,
if (json_backup_nexthop_array) {
json_backup_nexthops = json_object_new_object();
show_nexthop_json_helper(json_backup_nexthops,
- nexthop, NULL);
+ nexthop, NULL, NULL);
json_object_array_add(json_backup_nexthop_array,
json_backup_nexthops);
} else {
@@ -1350,7 +1348,8 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe,
* clear
*/
vty_out(vty, " ");
- show_route_nexthop_helper(vty, NULL, nexthop);
+ show_route_nexthop_helper(vty, NULL, NULL,
+ nexthop);
vty_out(vty, "\n");
}
}
@@ -1481,17 +1480,18 @@ static void if_nexthop_group_dump_vty(struct vty *vty, struct interface *ifp)
{
struct zebra_if *zebra_if = NULL;
struct nhg_connected *rb_node_dep = NULL;
+ bool first = true;
zebra_if = ifp->info;
- if (!if_nhg_dependents_is_empty(ifp)) {
- vty_out(vty, "Interface %s:\n", ifp->name);
-
- frr_each(nhg_connected_tree, &zebra_if->nhg_dependents,
- rb_node_dep) {
- vty_out(vty, " ");
- show_nexthop_group_out(vty, rb_node_dep->nhe, NULL);
+ frr_each (nhg_connected_tree, &zebra_if->nhg_dependents, rb_node_dep) {
+ if (first) {
+ vty_out(vty, "Interface %s:\n", ifp->name);
+ first = false;
}
+
+ vty_out(vty, " ");
+ show_nexthop_group_out(vty, rb_node_dep->nhe, NULL);
}
}
@@ -1734,13 +1734,13 @@ DEFPY (show_route,
"Nexthop Group Information\n")
{
afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
+ bool first_vrf_json = true;
struct vrf *vrf;
int type = 0;
struct zebra_vrf *zvrf;
struct route_show_ctx ctx = {
.multi = vrf_all || table_all,
};
- json_object *root_json = NULL;
if (!vrf_is_backend_netns()) {
if ((vrf_all || vrf_name) && (table || table_all)) {
@@ -1762,43 +1762,30 @@ DEFPY (show_route,
}
if (vrf_all) {
- if (!!json)
- root_json = json_object_new_object();
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- json_object *vrf_json = NULL;
-
if ((zvrf = vrf->info) == NULL
|| (zvrf->table[afi][SAFI_UNICAST] == NULL))
continue;
-
- if (!!json)
- vrf_json = json_object_new_object();
-
+ if (json)
+ vty_json_key(vty, zvrf_name(zvrf),
+ &first_vrf_json);
if (table_all)
do_show_ip_route_all(vty, zvrf, afi, !!fib,
- vrf_json, !!json, tag,
+ !!json, tag,
prefix_str ? prefix : NULL,
!!supernets_only, type,
ospf_instance_id, !!ng,
&ctx);
else
do_show_ip_route(vty, zvrf_name(zvrf), afi,
- SAFI_UNICAST, !!fib, vrf_json,
- !!json, tag,
- prefix_str ? prefix : NULL,
+ SAFI_UNICAST, !!fib, !!json,
+ tag, prefix_str ? prefix : NULL,
!!supernets_only, type,
ospf_instance_id, table, !!ng,
&ctx);
-
- if (!!json)
- json_object_object_add(root_json,
- zvrf_name(zvrf),
- vrf_json);
- }
- if (!!json) {
- vty_json_no_pretty(vty, root_json);
- root_json = NULL;
}
+ if (json)
+ vty_json_close(vty, first_vrf_json);
} else {
vrf_id_t vrf_id = VRF_DEFAULT;
@@ -1813,13 +1800,13 @@ DEFPY (show_route,
return CMD_SUCCESS;
if (table_all)
- do_show_ip_route_all(vty, zvrf, afi, !!fib, NULL, !!json,
- tag, prefix_str ? prefix : NULL,
+ do_show_ip_route_all(vty, zvrf, afi, !!fib, !!json, tag,
+ prefix_str ? prefix : NULL,
!!supernets_only, type,
ospf_instance_id, !!ng, &ctx);
else
do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST,
- !!fib, NULL, !!json, tag,
+ !!fib, !!json, tag,
prefix_str ? prefix : NULL,
!!supernets_only, type,
ospf_instance_id, table, !!ng, &ctx);
@@ -1991,11 +1978,15 @@ DEFPY (show_route_summary,
afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
struct route_table *table;
bool uj = use_json(argc, argv);
+ json_object *vrf_json = NULL;
if (vrf_all) {
struct vrf *vrf;
struct zebra_vrf *zvrf;
+ if (uj && !vrf_json)
+ vrf_json = json_object_new_object();
+
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
if ((zvrf = vrf->info) == NULL)
continue;
@@ -2013,10 +2004,14 @@ DEFPY (show_route_summary,
if (prefix)
vty_show_ip_route_summary_prefix(vty, table,
- uj);
+ vrf_json, uj);
else
- vty_show_ip_route_summary(vty, table, uj);
+ vty_show_ip_route_summary(vty, table, vrf_json,
+ uj);
}
+
+ if (uj)
+ vty_json(vty, vrf_json);
} else {
vrf_id_t vrf_id = VRF_DEFAULT;
@@ -2032,9 +2027,9 @@ DEFPY (show_route_summary,
return CMD_SUCCESS;
if (prefix)
- vty_show_ip_route_summary_prefix(vty, table, uj);
+ vty_show_ip_route_summary_prefix(vty, table, NULL, uj);
else
- vty_show_ip_route_summary(vty, table, uj);
+ vty_show_ip_route_summary(vty, table, NULL, uj);
}
return CMD_SUCCESS;
@@ -2089,8 +2084,11 @@ DEFUN_HIDDEN (show_route_zebra_dump,
return CMD_SUCCESS;
}
-static void show_ip_route_nht_dump(struct vty *vty, struct nexthop *nexthop,
- struct route_entry *re, unsigned int num)
+static void show_ip_route_nht_dump(struct vty *vty,
+ const struct nexthop *nexthop,
+ const struct route_node *rn,
+ const struct route_entry *re,
+ unsigned int num)
{
char buf[SRCDEST2STR_BUFFER];
@@ -2114,10 +2112,12 @@ static void show_ip_route_nht_dump(struct vty *vty, struct nexthop *nexthop,
nexthop->vrf_id));
}
- if (nexthop->src.ipv4.s_addr
- && (inet_ntop(AF_INET, &nexthop->src.ipv4, buf,
- sizeof(buf))))
- vty_out(vty, " source: %s\n", buf);
+ if (nexthop->rmap_src.ipv4.s_addr)
+ vty_out(vty, " rmapsrc: %pI4\n",
+ &nexthop->rmap_src.ipv4);
+ else if (nexthop->src.ipv4.s_addr)
+ vty_out(vty, " source: %pI4\n",
+ &nexthop->src.ipv4.s_addr);
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -2134,11 +2134,15 @@ static void show_ip_route_nht_dump(struct vty *vty, struct nexthop *nexthop,
nexthop->vrf_id));
}
- if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) {
- if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf,
- sizeof(buf)))
- vty_out(vty, " source: %s\n", buf);
- }
+ /* Allow for 5549 ipv4 prefix with ipv6 nexthop */
+ if (rn->p.family == AF_INET && nexthop->rmap_src.ipv4.s_addr)
+ vty_out(vty, " rmapsrc: %pI4\n",
+ &nexthop->rmap_src.ipv4);
+ else if (!IPV6_ADDR_SAME(&nexthop->rmap_src.ipv6, &in6addr_any))
+ vty_out(vty, " rmapsrc: %pI6\n",
+ &nexthop->rmap_src.ipv6);
+ else if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
+ vty_out(vty, " source: %pI6\n", &nexthop->src.ipv6);
break;
case NEXTHOP_TYPE_IFINDEX:
vty_out(vty,
@@ -2230,7 +2234,7 @@ static void show_ip_route_dump_vty(struct vty *vty, struct route_table *table)
for (ALL_NEXTHOPS_PTR(&(re->nhe->nhg), nexthop)) {
nexthop_num++;
- show_ip_route_nht_dump(vty, nexthop, re,
+ show_ip_route_nht_dump(vty, nexthop, rn, re,
nexthop_num);
}
@@ -2240,8 +2244,8 @@ static void show_ip_route_dump_vty(struct vty *vty, struct route_table *table)
}
}
-static void vty_show_ip_route_summary(struct vty *vty,
- struct route_table *table, bool use_json)
+static void vty_show_ip_route_summary(struct vty *vty, struct route_table *table,
+ json_object *vrf_json, bool use_json)
{
struct route_node *rn;
struct route_entry *re;
@@ -2255,6 +2259,8 @@ static void vty_show_ip_route_summary(struct vty *vty,
uint32_t is_ibgp;
json_object *json_route_summary = NULL;
json_object *json_route_routes = NULL;
+ const char *vrf_name = zvrf_name(
+ ((struct rib_table_info *)route_table_get_info(table))->zvrf);
memset(&rib_cnt, 0, sizeof(rib_cnt));
memset(&fib_cnt, 0, sizeof(fib_cnt));
@@ -2305,10 +2311,7 @@ static void vty_show_ip_route_summary(struct vty *vty,
if (!use_json)
vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
- "Routes", "FIB",
- zvrf_name(((struct rib_table_info *)
- route_table_get_info(table))
- ->zvrf));
+ "Routes", "FIB", vrf_name);
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
@@ -2400,7 +2403,11 @@ static void vty_show_ip_route_summary(struct vty *vty,
json_object_int_add(json_route_summary, "routesTotalFib",
fib_cnt[ZEBRA_ROUTE_TOTAL]);
- vty_json(vty, json_route_summary);
+ if (!vrf_json)
+ vty_json(vty, json_route_summary);
+ else
+ json_object_object_add(vrf_json, vrf_name,
+ json_route_summary);
} else {
vty_out(vty, "------\n");
vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
@@ -2418,6 +2425,7 @@ static void vty_show_ip_route_summary(struct vty *vty,
*/
static void vty_show_ip_route_summary_prefix(struct vty *vty,
struct route_table *table,
+ json_object *vrf_json,
bool use_json)
{
struct route_node *rn;
@@ -2431,6 +2439,8 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty,
int cnt;
json_object *json_route_summary = NULL;
json_object *json_route_routes = NULL;
+ const char *vrf_name = zvrf_name(
+ ((struct rib_table_info *)route_table_get_info(table))->zvrf);
memset(&rib_cnt, 0, sizeof(rib_cnt));
memset(&fib_cnt, 0, sizeof(fib_cnt));
@@ -2470,10 +2480,7 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty,
if (!use_json)
vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
- "Prefix Routes", "FIB",
- zvrf_name(((struct rib_table_info *)
- route_table_get_info(table))
- ->zvrf));
+ "Prefix Routes", "FIB", vrf_name);
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
if (rib_cnt[i] > 0) {
@@ -2548,7 +2555,11 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty,
json_object_int_add(json_route_summary, "prefixRoutesTotalFib",
fib_cnt[ZEBRA_ROUTE_TOTAL]);
- vty_json(vty, json_route_summary);
+ if (!vrf_json)
+ vty_json(vty, json_route_summary);
+ else
+ json_object_object_add(vrf_json, vrf_name,
+ json_route_summary);
} else {
vty_out(vty, "------\n");
vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
@@ -3531,56 +3542,17 @@ DEFPY (clear_evpn_dup_addr,
"IPv4 address\n"
"IPv6 address\n")
{
- struct ipaddr host_ip = {.ipa_type = IPADDR_NONE };
- int ret = CMD_SUCCESS;
- struct list *input;
- struct yang_data *yang_dup = NULL, *yang_dup_ip = NULL,
- *yang_dup_mac = NULL;
-
- input = list_new();
-
if (!vni_str) {
- yang_dup = yang_data_new(
- "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice",
- "all-case");
+ nb_cli_rpc_enqueue(vty, "all-vnis", NULL);
} else {
- yang_dup = yang_data_new_uint32(
- "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id",
- vni);
- if (!is_zero_mac(&mac->eth_addr)) {
- yang_dup_mac = yang_data_new_mac(
- "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id/mac-addr",
- &mac->eth_addr);
- if (yang_dup_mac)
- listnode_add(input, yang_dup_mac);
- } else if (ip) {
- if (sockunion_family(ip) == AF_INET) {
- host_ip.ipa_type = IPADDR_V4;
- host_ip.ipaddr_v4.s_addr = sockunion2ip(ip);
- } else {
- host_ip.ipa_type = IPADDR_V6;
- memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr,
- sizeof(struct in6_addr));
- }
-
- yang_dup_ip = yang_data_new_ip(
- "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id/vni-ipaddr",
- &host_ip);
-
- if (yang_dup_ip)
- listnode_add(input, yang_dup_ip);
- }
- }
-
- if (yang_dup) {
- listnode_add(input, yang_dup);
- ret = nb_cli_rpc(vty, "/frr-zebra:clear-evpn-dup-addr", input,
- NULL);
+ nb_cli_rpc_enqueue(vty, "vni-id", vni_str);
+ if (mac_str)
+ nb_cli_rpc_enqueue(vty, "mac-addr", mac_str);
+ else if (ip_str)
+ nb_cli_rpc_enqueue(vty, "vni-ipaddr", ip_str);
}
- list_delete(&input);
-
- return ret;
+ return nb_cli_rpc(vty, "/frr-zebra:clear-evpn-dup-addr", NULL);
}
DEFPY_HIDDEN (evpn_accept_bgp_seq,
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 0b75ec2..b8c11e1 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -108,10 +108,11 @@ static void zevpn_build_hash_table(void);
static unsigned int zebra_vxlan_sg_hash_key_make(const void *p);
static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2);
static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf,
- struct in_addr sip, struct in_addr mcast_grp);
-static struct zebra_vxlan_sg *zebra_vxlan_sg_do_ref(struct zebra_vrf *vrf,
- struct in_addr sip,
- struct in_addr mcast_grp);
+ const struct ipaddr *sip,
+ const struct in_addr mcast_grp);
+static struct zebra_vxlan_sg *
+zebra_vxlan_sg_do_ref(struct zebra_vrf *vrf, const struct ipaddr *sip,
+ const struct in_addr mcast_grp);
static void zebra_vxlan_cleanup_sg_table(struct zebra_vrf *zvrf);
bool zebra_evpn_do_dup_addr_detect(struct zebra_vrf *zvrf)
@@ -769,10 +770,6 @@ static void zl3vni_print(struct zebra_l3vni *zl3vni, void **ctx)
json_evpn_list = json_object_new_array();
json_object_int_add(json, "vni", zl3vni->vni);
json_object_string_add(json, "type", "L3");
-#if CONFDATE > 20240210
-CPP_NOTICE("Drop `vrf` from JSON outputs")
-#endif
- json_object_string_add(json, "vrf", zl3vni_vrf_name(zl3vni));
json_object_string_add(json, "tenantVrf",
zl3vni_vrf_name(zl3vni));
json_object_string_addf(json, "localVtepIp", "%pI4",
@@ -5895,7 +5892,10 @@ static int zebra_vxlan_sg_send(struct zebra_vrf *zvrf,
zclient_create_header(s, cmd, VRF_DEFAULT);
stream_putl(s, IPV4_MAX_BYTELEN);
- stream_put(s, &sg->src.s_addr, IPV4_MAX_BYTELEN);
+ /*
+ * There is currently no support for IPv6 VTEPs with PIM.
+ */
+ stream_put(s, &sg->src.ipaddr_v4, IPV4_MAX_BYTELEN);
stream_put(s, &sg->grp.s_addr, IPV4_MAX_BYTELEN);
/* Write packet size. */
@@ -5918,9 +5918,17 @@ static int zebra_vxlan_sg_send(struct zebra_vrf *zvrf,
static unsigned int zebra_vxlan_sg_hash_key_make(const void *p)
{
const struct zebra_vxlan_sg *vxlan_sg = p;
+ uint32_t hash1;
- return (jhash_2words(vxlan_sg->sg.src.s_addr,
- vxlan_sg->sg.grp.s_addr, 0));
+ if (IS_IPADDR_V4(&vxlan_sg->sg.src)) {
+ return (jhash_2words(vxlan_sg->sg.src.ipaddr_v4.s_addr,
+ vxlan_sg->sg.grp.s_addr, 0));
+ } else {
+ hash1 = jhash_1word(vxlan_sg->sg.grp.s_addr, 0);
+ return jhash2(vxlan_sg->sg.src.ipaddr_v6.s6_addr32,
+ array_size(vxlan_sg->sg.src.ipaddr_v6.s6_addr32),
+ hash1);
+ }
}
static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2)
@@ -5928,8 +5936,8 @@ static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2)
const struct zebra_vxlan_sg *sg1 = p1;
const struct zebra_vxlan_sg *sg2 = p2;
- return ((sg1->sg.src.s_addr == sg2->sg.src.s_addr)
- && (sg1->sg.grp.s_addr == sg2->sg.grp.s_addr));
+ return (ipaddr_is_same(&sg1->sg.src, &sg2->sg.src) &&
+ (sg1->sg.grp.s_addr == sg2->sg.grp.s_addr));
}
static struct zebra_vxlan_sg *zebra_vxlan_sg_new(struct zebra_vrf *zvrf,
@@ -5965,7 +5973,7 @@ static struct zebra_vxlan_sg *zebra_vxlan_sg_add(struct zebra_vrf *zvrf,
{
struct zebra_vxlan_sg *vxlan_sg;
struct zebra_vxlan_sg *parent = NULL;
- struct in_addr sip;
+ struct ipaddr sip;
vxlan_sg = zebra_vxlan_sg_find(zvrf, sg);
if (vxlan_sg)
@@ -5976,9 +5984,9 @@ static struct zebra_vxlan_sg *zebra_vxlan_sg_add(struct zebra_vrf *zvrf,
* 2. the XG entry is used by pimd to setup the
* vxlan-termination-mroute
*/
- if (sg->src.s_addr != INADDR_ANY) {
+ if (!ipaddr_is_zero(&sg->src)) {
memset(&sip, 0, sizeof(sip));
- parent = zebra_vxlan_sg_do_ref(zvrf, sip, sg->grp);
+ parent = zebra_vxlan_sg_do_ref(zvrf, &sip, sg->grp);
if (!parent)
return NULL;
}
@@ -5993,7 +6001,7 @@ static struct zebra_vxlan_sg *zebra_vxlan_sg_add(struct zebra_vrf *zvrf,
static void zebra_vxlan_sg_del(struct zebra_vxlan_sg *vxlan_sg)
{
- struct in_addr sip;
+ struct ipaddr sip;
struct zebra_vrf *zvrf;
zvrf = vrf_info_lookup(VRF_DEFAULT);
@@ -6001,13 +6009,13 @@ static void zebra_vxlan_sg_del(struct zebra_vxlan_sg *vxlan_sg)
/* On SG entry deletion remove the reference to its parent XG
* entry
*/
- if (vxlan_sg->sg.src.s_addr != INADDR_ANY) {
+ if (!ipaddr_is_zero(&vxlan_sg->sg.src)) {
memset(&sip, 0, sizeof(sip));
- zebra_vxlan_sg_do_deref(zvrf, sip, vxlan_sg->sg.grp);
+ zebra_vxlan_sg_do_deref(zvrf, &sip, vxlan_sg->sg.grp);
}
- zebra_vxlan_sg_send(zvrf, &vxlan_sg->sg,
- vxlan_sg->sg_str, ZEBRA_VXLAN_SG_DEL);
+ zebra_vxlan_sg_send(zvrf, &vxlan_sg->sg, vxlan_sg->sg_str,
+ ZEBRA_VXLAN_SG_DEL);
hash_release(vxlan_sg->zvrf->vxlan_sg_table, vxlan_sg);
@@ -6018,14 +6026,15 @@ static void zebra_vxlan_sg_del(struct zebra_vxlan_sg *vxlan_sg)
}
static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf,
- struct in_addr sip, struct in_addr mcast_grp)
+ const struct ipaddr *sip,
+ const struct in_addr mcast_grp)
{
struct zebra_vxlan_sg *vxlan_sg;
struct prefix_sg sg;
sg.family = AF_INET;
sg.prefixlen = IPV4_MAX_BYTELEN;
- sg.src = sip;
+ sg.src = *sip;
sg.grp = mcast_grp;
vxlan_sg = zebra_vxlan_sg_find(zvrf, &sg);
if (!vxlan_sg)
@@ -6038,16 +6047,16 @@ static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf,
zebra_vxlan_sg_del(vxlan_sg);
}
-static struct zebra_vxlan_sg *zebra_vxlan_sg_do_ref(struct zebra_vrf *zvrf,
- struct in_addr sip,
- struct in_addr mcast_grp)
+static struct zebra_vxlan_sg *
+zebra_vxlan_sg_do_ref(struct zebra_vrf *zvrf, const struct ipaddr *sip,
+ const struct in_addr mcast_grp)
{
struct zebra_vxlan_sg *vxlan_sg;
struct prefix_sg sg;
sg.family = AF_INET;
sg.prefixlen = IPV4_MAX_BYTELEN;
- sg.src = sip;
+ sg.src = *sip;
sg.grp = mcast_grp;
vxlan_sg = zebra_vxlan_sg_add(zvrf, &sg);
if (vxlan_sg)
@@ -6056,10 +6065,10 @@ static struct zebra_vxlan_sg *zebra_vxlan_sg_do_ref(struct zebra_vrf *zvrf,
return vxlan_sg;
}
-void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip,
- struct in_addr mcast_grp)
+void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip, struct in_addr mcast_grp)
{
struct zebra_vrf *zvrf;
+ struct ipaddr local_vtep_ipaddr;
if (local_vtep_ip.s_addr == INADDR_ANY
|| mcast_grp.s_addr == INADDR_ANY)
@@ -6067,20 +6076,26 @@ void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip,
zvrf = vrf_info_lookup(VRF_DEFAULT);
- zebra_vxlan_sg_do_deref(zvrf, local_vtep_ip, mcast_grp);
+ SET_IPADDR_V4(&local_vtep_ipaddr);
+ local_vtep_ipaddr.ipaddr_v4 = local_vtep_ip;
+
+ zebra_vxlan_sg_do_deref(zvrf, &local_vtep_ipaddr, mcast_grp);
}
void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip, struct in_addr mcast_grp)
{
struct zebra_vrf *zvrf;
+ struct ipaddr local_vtep_ipaddr;
- if (local_vtep_ip.s_addr == INADDR_ANY
- || mcast_grp.s_addr == INADDR_ANY)
+ if (local_vtep_ip.s_addr == INADDR_ANY || mcast_grp.s_addr == INADDR_ANY)
return;
zvrf = vrf_info_lookup(VRF_DEFAULT);
- zebra_vxlan_sg_do_ref(zvrf, local_vtep_ip, mcast_grp);
+ SET_IPADDR_V4(&local_vtep_ipaddr);
+ local_vtep_ipaddr.ipaddr_v4 = local_vtep_ip;
+
+ zebra_vxlan_sg_do_ref(zvrf, &local_vtep_ipaddr, mcast_grp);
}
static void zebra_vxlan_xg_pre_cleanup(struct hash_bucket *bucket, void *arg)
@@ -6090,7 +6105,7 @@ static void zebra_vxlan_xg_pre_cleanup(struct hash_bucket *bucket, void *arg)
/* increment the ref count against (*,G) to prevent them from being
* deleted
*/
- if (vxlan_sg->sg.src.s_addr == INADDR_ANY)
+ if (ipaddr_is_zero(&vxlan_sg->sg.src))
++vxlan_sg->ref_cnt;
}
@@ -6099,7 +6114,7 @@ static void zebra_vxlan_xg_post_cleanup(struct hash_bucket *bucket, void *arg)
struct zebra_vxlan_sg *vxlan_sg = (struct zebra_vxlan_sg *)bucket->data;
/* decrement the dummy ref count against (*,G) to delete them */
- if (vxlan_sg->sg.src.s_addr == INADDR_ANY) {
+ if (ipaddr_is_zero(&vxlan_sg->sg.src)) {
if (vxlan_sg->ref_cnt)
--vxlan_sg->ref_cnt;
if (!vxlan_sg->ref_cnt)
diff --git a/zebra/zebra_vxlan_if.c b/zebra/zebra_vxlan_if.c
index 3cc7e49..f4b859b 100644
--- a/zebra/zebra_vxlan_if.c
+++ b/zebra/zebra_vxlan_if.c
@@ -506,7 +506,7 @@ static int zebra_vxlan_if_add_update_vni(struct zebra_if *zif,
if ((hashcount(ctx->old_vni_table) == 0) ||
!(old_vni = hash_release(ctx->old_vni_table, &vni_tmp))) {
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("vxlan %s adding vni(%d, %d)",
+ zlog_debug("%s vxlan %s adding vni(%d, %d)", __func__,
zif->ifp->name, vni->vni, vni->access_vlan);
zebra_vxlan_if_vni_entry_add(zif, &vni_tmp);
@@ -521,17 +521,39 @@ static int zebra_vxlan_if_add_update_vni(struct zebra_if *zif,
if (old_vni->access_vlan != vni->access_vlan) {
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug(
- "vxlan %s updating vni(%d, %d) -> vni(%d, %d)",
- zif->ifp->name, old_vni->vni,
- old_vni->access_vlan, vni->vni,
- vni->access_vlan);
+ zlog_debug("%s vxlan %s updating vni(%d, %d) -> vni(%d, %d)",
+ __func__, zif->ifp->name, old_vni->vni,
+ old_vni->access_vlan, vni->vni,
+ vni->access_vlan);
zebra_evpn_vl_vxl_deref(old_vni->access_vlan, old_vni->vni,
zif);
zebra_evpn_vl_vxl_ref(vni->access_vlan, vni->vni, zif);
zebra_vxlan_if_update_vni(zif->ifp, vni, ctx);
zebra_vxlan_vni_free(old_vni);
+ } else {
+ int ret;
+
+ ret = zebra_evpn_vl_vxl_bridge_lookup(vni->access_vlan, zif);
+ /* Here ret value 0 implied bridge vlan mapping is not present
+ * repopulated. Ignore ret value 1 as it means vlan mapping is
+ * present in bridge table.
+ */
+ if (ret < 0) {
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug("%s vxlan %s vni %u has error accessing bridge table.",
+ __func__, zif->ifp->name, vni->vni);
+ } else if (ret == 0) {
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug("%s vxlan %s vni (%u, %u) not present in bridge table",
+ __func__, zif->ifp->name, vni->vni,
+ vni->access_vlan);
+ zebra_evpn_vl_vxl_deref(old_vni->access_vlan,
+ old_vni->vni, zif);
+ zebra_evpn_vl_vxl_ref(vni->access_vlan, vni->vni, zif);
+ zebra_vxlan_if_update_vni(zif->ifp, vni, ctx);
+ zebra_vxlan_vni_free(old_vni);
+ }
}
return 0;
@@ -768,6 +790,7 @@ vni_t zebra_vxlan_if_access_vlan_vni_find(struct zebra_if *zif,
return vni->vni;
}
+/* SVD VLAN-VNI mapping update */
int zebra_vxlan_if_vni_table_add_update(struct interface *ifp,
struct hash *vni_table)
{
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 6a64176..2766853 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -306,6 +306,14 @@ zwrite_fail:
* this task reschedules itself.
*
* Any failure in any of these actions is handled by terminating the client.
+ *
+ * The client's input buffer ibuf_fifo can have a maximum items as configured
+ * in the packets_to_process. This way we are not filling up the FIFO more
+ * than the maximum when the zebra main is busy. If the fifo has space, we
+ * reschedule ourselves to read more.
+ *
+ * The main thread processes the items in ibuf_fifo and always signals the
+ * client IO thread.
*/
static void zserv_read(struct event *thread)
{
@@ -313,15 +321,25 @@ static void zserv_read(struct event *thread)
int sock;
size_t already;
struct stream_fifo *cache;
- uint32_t p2p_orig;
-
- uint32_t p2p;
+ uint32_t p2p; /* Temp p2p used to process */
+ uint32_t p2p_orig; /* Configured p2p (Default-1000) */
+ int p2p_avail; /* How much space is available for p2p */
struct zmsghdr hdr;
+ size_t client_ibuf_fifo_cnt = stream_fifo_count_safe(client->ibuf_fifo);
p2p_orig = atomic_load_explicit(&zrouter.packets_to_process,
memory_order_relaxed);
+ p2p_avail = p2p_orig - client_ibuf_fifo_cnt;
+
+ /*
+ * Do nothing if ibuf_fifo count has reached its max limit. Otherwise
+ * proceed and reschedule ourselves if there is space in the ibuf_fifo.
+ */
+ if (p2p_avail <= 0)
+ return;
+
+ p2p = p2p_avail;
cache = stream_fifo_new();
- p2p = p2p_orig;
sock = EVENT_FD(thread);
while (p2p) {
@@ -421,7 +439,7 @@ static void zserv_read(struct event *thread)
p2p--;
}
- if (p2p < p2p_orig) {
+ if (p2p < (uint32_t)p2p_avail) {
uint64_t time_now = monotime(NULL);
/* update session statistics */
@@ -435,19 +453,23 @@ static void zserv_read(struct event *thread)
while (cache->head)
stream_fifo_push(client->ibuf_fifo,
stream_fifo_pop(cache));
+ /* Need to update count as main thread could have processed few */
+ client_ibuf_fifo_cnt =
+ stream_fifo_count_safe(client->ibuf_fifo);
}
/* Schedule job to process those packets */
zserv_event(client, ZSERV_PROCESS_MESSAGES);
-
}
if (IS_ZEBRA_DEBUG_PACKET)
- zlog_debug("Read %d packets from client: %s", p2p_orig - p2p,
- zebra_route_string(client->proto));
+ zlog_debug("Read %d packets from client: %s. Current ibuf fifo count: %zu. Conf P2p %d",
+ p2p_avail - p2p, zebra_route_string(client->proto),
+ client_ibuf_fifo_cnt, p2p_orig);
- /* Reschedule ourselves */
- zserv_client_event(client, ZSERV_CLIENT_READ);
+ /* Reschedule ourselves since we have space in ibuf_fifo */
+ if (client_ibuf_fifo_cnt < p2p_orig)
+ zserv_client_event(client, ZSERV_CLIENT_READ);
stream_fifo_free(cache);
@@ -483,14 +505,20 @@ static void zserv_client_event(struct zserv *client,
* as the task argument.
*
* Each message is popped off the client's input queue and the action associated
- * with the message is executed. This proceeds until there are no more messages,
- * an error occurs, or the processing limit is reached.
+ * with the message is executed. This proceeds until an error occurs, or the
+ * processing limit is reached.
*
* The client's I/O thread can push at most zrouter.packets_to_process messages
* onto the input buffer before notifying us there are packets to read. As long
* as we always process zrouter.packets_to_process messages here, then we can
* rely on the read thread to handle queuing this task enough times to process
* everything on the input queue.
+ *
+ * If the client ibuf always schedules a wakeup to the client IO to read more
+ * items from the socked buffer. This way we ensure
+ * - Client IO thread always tries to read the socket buffer and add more
+ * items to the ibuf_fifo (until max limit)
+ * - the hidden config change (zebra zapi-packets <>) is taken into account.
*/
static void zserv_process_messages(struct event *thread)
{
@@ -524,6 +552,9 @@ static void zserv_process_messages(struct event *thread)
/* Reschedule ourselves if necessary */
if (need_resched)
zserv_event(client, ZSERV_PROCESS_MESSAGES);
+
+ /* Ensure to include the read socket in the select/poll/etc.. */
+ zserv_client_event(client, ZSERV_CLIENT_READ);
}
int zserv_send_message(struct zserv *client, struct stream *msg)
@@ -644,10 +675,14 @@ static void zserv_client_free(struct zserv *client)
* If any instance are graceful restart enabled,
* client is not deleted
*/
- if (DYNAMIC_CLIENT_GR_DISABLED(client)) {
+ if (DYNAMIC_CLIENT_GR_DISABLED(client) || zebra_router_in_shutdown()) {
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("%s: Deleting client %s", __func__,
zebra_route_string(client->proto));
+
+ if (zebra_router_in_shutdown())
+ zebra_gr_client_final_shutdown(client);
+
zserv_client_delete(client);
} else {
/* Handle cases where client has GR instance. */
@@ -1090,12 +1125,10 @@ static void zebra_show_client_detail(struct vty *vty, struct zserv *client)
vty_out(vty, "ES-EVI %-12u%-12u%-12u\n",
client->local_es_evi_add_cnt, 0, client->local_es_evi_del_cnt);
vty_out(vty, "Errors: %u\n", client->error_cnt);
-
-#if defined DEV_BUILD
vty_out(vty, "Input Fifo: %zu:%zu Output Fifo: %zu:%zu\n",
client->ibuf_fifo->count, client->ibuf_fifo->max_count,
client->obuf_fifo->count, client->obuf_fifo->max_count);
-#endif
+
vty_out(vty, "\n");
}
diff --git a/zebra/zserv.h b/zebra/zserv.h
index e1c990f..57d6730 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -378,6 +378,7 @@ __attribute__((__noreturn__)) void zebra_finalize(struct event *event);
/*
* Graceful restart functions.
*/
+extern void zebra_gr_client_final_shutdown(struct zserv *client);
extern int zebra_gr_client_disconnect(struct zserv *client);
extern void zebra_gr_client_reconnect(struct zserv *client);
extern void zebra_gr_stale_client_cleanup(struct list *client_list);