summaryrefslogtreecommitdiff
path: root/zebra
diff options
context:
space:
mode:
Diffstat (limited to 'zebra')
-rw-r--r--zebra/connected.c4
-rw-r--r--zebra/kernel_netlink.c144
-rw-r--r--zebra/kernel_netlink.h4
-rw-r--r--zebra/kernel_socket.c4
-rw-r--r--zebra/main.c51
-rw-r--r--zebra/redistribute.c18
-rw-r--r--zebra/rib.h2
-rw-r--r--zebra/rt_netlink.c6
-rw-r--r--zebra/rule_netlink.c14
-rw-r--r--zebra/zapi_msg.c85
-rw-r--r--zebra/zebra_dplane.c31
-rw-r--r--zebra/zebra_dplane.h1
-rw-r--r--zebra/zebra_evpn.c4
-rw-r--r--zebra/zebra_evpn_mac.c4
-rw-r--r--zebra/zebra_evpn_mh.c17
-rw-r--r--zebra/zebra_evpn_mh.h4
-rw-r--r--zebra/zebra_evpn_neigh.c7
-rw-r--r--zebra/zebra_pbr.c79
-rw-r--r--zebra/zebra_pbr.h7
-rw-r--r--zebra/zebra_rib.c200
-rw-r--r--zebra/zserv.c11
-rw-r--r--zebra/zserv.h4
22 files changed, 323 insertions, 378 deletions
diff --git a/zebra/connected.c b/zebra/connected.c
index 3b9ebe14a4..8c4ba163bd 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -393,10 +393,10 @@ void connected_down(struct interface *ifp, struct connected *ifc)
* head.
*/
rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
- 0, &p, NULL, &nh, 0, zvrf->table_id, 0, 0, false);
+ 0, &p, NULL, &nh, 0, zvrf->table_id, 0, 0, false, true);
rib_delete(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, &nh, 0, zvrf->table_id, 0, 0, false);
+ 0, 0, &p, NULL, &nh, 0, zvrf->table_id, 0, 0, false, true);
/* Schedule LSP forwarding entries for processing, if appropriate. */
if (zvrf->vrf->vrf_id == VRF_DEFAULT) {
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index d0c1bc812d..ad0d4bf56b 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -20,12 +20,6 @@
#include <zebra.h>
-#if defined(HANDLE_NETLINK_FUZZING)
-#include <stdio.h>
-#include <string.h>
-#include "libfrr.h"
-#endif /* HANDLE_NETLINK_FUZZING */
-
#ifdef HAVE_NETLINK
#include "linklist.h"
@@ -96,14 +90,7 @@
*/
#define NL_DEFAULT_BATCH_SEND_THRESHOLD (15 * NL_PKT_BUF_SIZE)
-/*
- * For every request sent to the kernel that has failed we get an error message,
- * which contains a standard netlink message header and the payload consisting
- * of an error code and the original netlink mesage. So the receiving buffer
- * must be at least as big as the transmitting buffer increased by some space
- * for headers.
- */
-#define NL_BATCH_RX_BUFSIZE (NL_DEFAULT_BATCH_BUFSIZE + NL_PKT_BUF_SIZE)
+#define NL_BATCH_RX_BUFSIZE NL_RCV_PKT_BUF_SIZE
static const struct message nlmsg_str[] = {{RTM_NEWROUTE, "RTM_NEWROUTE"},
{RTM_DELROUTE, "RTM_DELROUTE"},
@@ -404,86 +391,6 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id,
return 0;
}
-#if defined(HANDLE_NETLINK_FUZZING)
-/* Using globals here to avoid adding function parameters */
-
-/* Keep distinct filenames for netlink fuzzy collection */
-static unsigned int netlink_file_counter = 1;
-
-/* File name to read fuzzed netlink from */
-static char netlink_fuzz_file[MAXPATHLEN] = "";
-
-/* Flag for whether to read from file or not */
-bool netlink_read;
-
-/**
- * netlink_read_init() - Starts the message parser
- * @fname: Filename to read.
- */
-void netlink_read_init(const char *fname)
-{
- struct zebra_dplane_info dp_info;
-
- snprintf(netlink_fuzz_file, MAXPATHLEN, "%s", fname);
- /* Creating this fake socket for testing purposes */
- struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT);
-
- /* Capture key info from zns struct */
- zebra_dplane_info_from_zns(&dp_info, zns, false);
-
- netlink_parse_info(netlink_information_fetch, &zns->netlink,
- &dp_info, 1, 0);
-}
-
-/**
- * netlink_write_incoming() - Writes all data received from netlink to a file
- * @buf: Data from netlink.
- * @size: Size of data.
- * @counter: Counter for keeping filenames distinct.
- */
-static void netlink_write_incoming(const char *buf, const unsigned int size,
- unsigned int counter)
-{
- char fname[MAXPATHLEN];
- FILE *f;
-
- snprintf(fname, MAXPATHLEN, "%s/%s_%u", frr_vtydir, "netlink", counter);
- frr_with_privs(&zserv_privs) {
- f = fopen(fname, "w");
- }
- if (f) {
- fwrite(buf, 1, size, f);
- fclose(f);
- }
-}
-
-/**
- * netlink_read_file() - Reads netlink data from file
- * @buf: Netlink buffer being overwritten.
- * @fname: File name to read from.
- *
- * Return: Size of file.
- */
-static long netlink_read_file(char *buf, const char *fname)
-{
- FILE *f;
- long file_bytes = -1;
-
- frr_with_privs(&zserv_privs) {
- f = fopen(fname, "r");
- }
- if (f) {
- fseek(f, 0, SEEK_END);
- file_bytes = ftell(f);
- rewind(f);
- fread(buf, NL_RCV_PKT_BUF_SIZE, 1, f);
- fclose(f);
- }
- return file_bytes;
-}
-
-#endif /* HANDLE_NETLINK_FUZZING */
-
static int kernel_read(struct thread *thread)
{
struct zebra_ns *zns = (struct zebra_ns *)THREAD_ARG(thread);
@@ -834,18 +741,7 @@ static int netlink_recv_msg(const struct nlsock *nl, struct msghdr msg,
msg.msg_iovlen = 1;
do {
-#if defined(HANDLE_NETLINK_FUZZING)
- /* Check if reading and filename is set */
- if (netlink_read && '\0' != netlink_fuzz_file[0]) {
- zlog_debug("Reading netlink fuzz file");
- status = netlink_read_file(buf, netlink_fuzz_file);
- ((struct sockaddr_nl *)msg.msg_name)->nl_pid = 0;
- } else {
- status = recvmsg(nl->sock, &msg, 0);
- }
-#else
status = recvmsg(nl->sock, &msg, 0);
-#endif /* HANDLE_NETLINK_FUZZING */
} while (status == -1 && errno == EINTR);
if (status == -1) {
@@ -877,13 +773,6 @@ static int netlink_recv_msg(const struct nlsock *nl, struct msghdr msg,
zlog_hexdump(buf, status);
}
-#if defined(HANDLE_NETLINK_FUZZING)
- if (!netlink_read) {
- zlog_debug("Writing incoming netlink message");
- netlink_write_incoming(buf, status, netlink_file_counter++);
- }
-#endif /* HANDLE_NETLINK_FUZZING */
-
return status;
}
@@ -1173,14 +1062,17 @@ static int nl_batch_read_resp(struct nl_batch *bth)
msg.msg_name = (void *)&snl;
msg.msg_namelen = sizeof(snl);
- status = netlink_recv_msg(nl, msg, nl_batch_rx_buf,
- sizeof(nl_batch_rx_buf));
- if (status == -1 || status == 0)
- return status;
+ /*
+ * The responses are not batched, so we need to read and process one
+ * message at a time.
+ */
+ while (true) {
+ status = netlink_recv_msg(nl, msg, nl_batch_rx_buf,
+ sizeof(nl_batch_rx_buf));
+ if (status == -1 || status == 0)
+ return status;
- for (h = (struct nlmsghdr *)nl_batch_rx_buf;
- (status >= 0 && NLMSG_OK(h, (unsigned int)status));
- h = NLMSG_NEXT(h, status)) {
+ h = (struct nlmsghdr *)nl_batch_rx_buf;
ignore_msg = false;
seq = h->nlmsg_seq;
/*
@@ -1561,6 +1453,15 @@ void kernel_init(struct zebra_ns *zns)
if (ret < 0)
zlog_notice("Registration for extended dp ACK failed : %d %s",
errno, safe_strerror(errno));
+
+ /*
+ * Trim off the payload of the original netlink message in the
+ * acknowledgment. This option is available since Linux 4.2, so if
+ * setsockopt fails, ignore the error.
+ */
+ one = 1;
+ ret = setsockopt(zns->netlink_dplane.sock, SOL_NETLINK, NETLINK_CAP_ACK,
+ &one, sizeof(one));
#endif
/* Register kernel socket. */
@@ -1577,8 +1478,11 @@ void kernel_init(struct zebra_ns *zns)
zns->netlink_dplane.name, safe_strerror(errno), errno);
/* Set receive buffer size if it's set from command line */
- if (nl_rcvbufsize)
+ if (nl_rcvbufsize) {
netlink_recvbuf(&zns->netlink, nl_rcvbufsize);
+ netlink_recvbuf(&zns->netlink_cmd, nl_rcvbufsize);
+ netlink_recvbuf(&zns->netlink_dplane, nl_rcvbufsize);
+ }
netlink_install_filter(zns->netlink.sock,
zns->netlink_cmd.snl.nl_pid,
diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h
index c02e16480b..696f9be4f6 100644
--- a/zebra/kernel_netlink.h
+++ b/zebra/kernel_netlink.h
@@ -86,10 +86,6 @@ extern const char *nl_rtproto_to_str(uint8_t rtproto);
extern const char *nl_family_to_str(uint8_t family);
extern const char *nl_rttype_to_str(uint8_t rttype);
-#if defined(HANDLE_NETLINK_FUZZING)
-extern bool netlink_read;
-extern void netlink_read_init(const char *fname);
-#endif /* HANDLE_NETLINK_FUZZING */
extern int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
const struct nlsock *nl,
const struct zebra_dplane_info *dp_info,
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 4c29b999f0..02963651a0 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -1136,7 +1136,7 @@ void rtm_read(struct rt_msghdr *rtm)
if (rtm->rtm_type == RTM_CHANGE)
rib_delete(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
0, zebra_flags, &p, NULL, NULL, 0, RT_TABLE_MAIN, 0,
- 0, true);
+ 0, true, false);
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE)
rib_add(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0,
@@ -1145,7 +1145,7 @@ void rtm_read(struct rt_msghdr *rtm)
else
rib_delete(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
0, zebra_flags, &p, NULL, &nh, 0, RT_TABLE_MAIN, 0,
- 0, true);
+ 0, true, false);
}
/* Interface function for the kernel routing table updates. Support
diff --git a/zebra/main.c b/zebra/main.c
index 2b97e915fb..2afef46bb2 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -59,10 +59,6 @@
#include "zebra/zebra_opaque.h"
#include "zebra/zebra_srte.h"
-#if defined(HANDLE_NETLINK_FUZZING)
-#include "zebra/kernel_netlink.h"
-#endif /* HANDLE_NETLINK_FUZZING */
-
#define ZEBRA_PTM_SUPPORT
/* process id. */
@@ -284,12 +280,6 @@ int main(int argc, char **argv)
char *vrf_default_name_configured = NULL;
struct sockaddr_storage dummy;
socklen_t dummylen;
-#if defined(HANDLE_ZAPI_FUZZING)
- char *zapi_fuzzing = NULL;
-#endif /* HANDLE_ZAPI_FUZZING */
-#if defined(HANDLE_NETLINK_FUZZING)
- char *netlink_fuzzing = NULL;
-#endif /* HANDLE_NETLINK_FUZZING */
graceful_restart = 0;
vrf_configure_backend(VRF_BACKEND_VRF_LITE);
@@ -301,12 +291,6 @@ int main(int argc, char **argv)
#ifdef HAVE_NETLINK
"s:n"
#endif
-#if defined(HANDLE_ZAPI_FUZZING)
- "c:"
-#endif /* HANDLE_ZAPI_FUZZING */
-#if defined(HANDLE_NETLINK_FUZZING)
- "w:"
-#endif /* HANDLE_NETLINK_FUZZING */
,
longopts,
" -b, --batch Runs in batch mode\n"
@@ -321,12 +305,6 @@ int main(int argc, char **argv)
" -s, --nl-bufsize Set netlink receive buffer size\n"
" --v6-rr-semantics Use v6 RR semantics\n"
#endif /* HAVE_NETLINK */
-#if defined(HANDLE_ZAPI_FUZZING)
- " -c <file> Bypass normal startup and use this file for testing of zapi\n"
-#endif /* HANDLE_ZAPI_FUZZING */
-#if defined(HANDLE_NETLINK_FUZZING)
- " -w <file> Bypass normal startup and use this file for testing of netlink input\n"
-#endif /* HANDLE_NETLINK_FUZZING */
);
while (1) {
@@ -388,21 +366,6 @@ int main(int argc, char **argv)
v6_rr_semantics = true;
break;
#endif /* HAVE_NETLINK */
-#if defined(HANDLE_ZAPI_FUZZING)
- case 'c':
- zapi_fuzzing = optarg;
- break;
-#endif /* HANDLE_ZAPI_FUZZING */
-#if defined(HANDLE_NETLINK_FUZZING)
- case 'w':
- netlink_fuzzing = optarg;
- /* This ensures we are aren't writing any of the
- * startup netlink messages that happen when we
- * just want to read.
- */
- netlink_read = true;
- break;
-#endif /* HANDLE_NETLINK_FUZZING */
default:
frr_help_exit(1);
break;
@@ -489,20 +452,6 @@ int main(int argc, char **argv)
/* Error init */
zebra_error_init();
-#if defined(HANDLE_ZAPI_FUZZING)
- if (zapi_fuzzing) {
- zserv_read_file(zapi_fuzzing);
- exit(0);
- }
-#endif /* HANDLE_ZAPI_FUZZING */
-#if defined(HANDLE_NETLINK_FUZZING)
- if (netlink_fuzzing) {
- netlink_read_init(netlink_fuzzing);
- exit(0);
- }
-#endif /* HANDLE_NETLINK_FUZZING */
-
-
frr_run(zrouter.master);
/* Not reached... */
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 4d6346151a..c0f89e6afe 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -200,8 +200,8 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p,
if (IS_ZEBRA_DEBUG_RIB) {
zlog_debug(
- "%u:%s: Redist update re %p (%s), old %p (%s)",
- re->vrf_id, prefix2str(p, buf, sizeof(buf)),
+ "(%u:%u):%s: Redist update re %p (%s), old %p (%s)",
+ re->vrf_id, re->table, prefix2str(p, buf, sizeof(buf)),
re, zebra_route_string(re->type), prev_re,
prev_re ? zebra_route_string(prev_re->type) : "None");
}
@@ -224,12 +224,12 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p,
if (zebra_redistribute_check(re, client, p, afi)) {
if (IS_ZEBRA_DEBUG_RIB) {
zlog_debug(
- "%s: client %s %s(%u), type=%d, distance=%d, metric=%d",
- __func__,
- zebra_route_string(client->proto),
- prefix2str(p, buf, sizeof(buf)),
- re->vrf_id, re->type,
- re->distance, re->metric);
+ "%s: client %s %s(%u:%u), type=%d, distance=%d, metric=%d",
+ __func__,
+ zebra_route_string(client->proto),
+ prefix2str(p, buf, sizeof(buf)),
+ re->vrf_id, re->table, re->type,
+ re->distance, re->metric);
}
zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
client, p, src_p, re);
@@ -727,7 +727,7 @@ int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE,
re->table, re->flags, &p, NULL, re->nhe->nhg.nexthop,
re->nhe_id, zvrf->table_id, re->metric, re->distance,
- false);
+ false, false);
return 0;
}
diff --git a/zebra/rib.h b/zebra/rib.h
index b9f4e56905..be680a112f 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -379,7 +379,7 @@ extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
unsigned short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
uint32_t nhe_id, uint32_t table_id, uint32_t metric,
- uint8_t distance, bool fromkernel);
+ uint8_t distance, bool fromkernel, bool connected_down);
extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
union g_addr *addr,
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 4a6839d3b1..50b1a62d86 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -837,7 +837,7 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
if (nhe_id) {
rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
&p, &src_p, NULL, nhe_id, table, metric,
- distance, true);
+ distance, true, false);
} else {
if (!tb[RTA_MULTIPATH]) {
struct nexthop nh;
@@ -847,13 +847,13 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
gate, afi, vrf_id);
rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0,
flags, &p, &src_p, &nh, 0, table,
- metric, distance, true);
+ metric, distance, true, false);
} else {
/* XXX: need to compare the entire list of
* nexthops here for NLM_F_APPEND stupidity */
rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0,
flags, &p, &src_p, NULL, 0, table,
- metric, distance, true);
+ metric, distance, true, false);
}
}
}
diff --git a/zebra/rule_netlink.c b/zebra/rule_netlink.c
index 3a3baab4ca..d6a34327a6 100644
--- a/zebra/rule_netlink.c
+++ b/zebra/rule_netlink.c
@@ -74,7 +74,7 @@ netlink_rule_msg_encode(int cmd, const struct zebra_dplane_ctx *ctx,
char buf[];
} *req = buf;
- const char *ifname = dplane_ctx_get_ifname(ctx);
+ const char *ifname = dplane_ctx_rule_get_ifname(ctx);
char buf1[PREFIX_STRLEN];
char buf2[PREFIX_STRLEN];
@@ -141,9 +141,9 @@ netlink_rule_msg_encode(int cmd, const struct zebra_dplane_ctx *ctx,
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
- "Tx %s family %s IF %s(%u) Pref %u Fwmark %u Src %s Dst %s Table %u",
+ "Tx %s family %s IF %s Pref %u Fwmark %u Src %s Dst %s Table %u",
nl_msg_type_to_str(cmd), nl_family_to_str(family),
- ifname, dplane_ctx_get_ifindex(ctx), priority, fwmark,
+ ifname, priority, fwmark,
prefix2str(src_ip, buf1, sizeof(buf1)),
prefix2str(dst_ip, buf2, sizeof(buf2)), table);
@@ -324,13 +324,13 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
ret = dplane_pbr_rule_delete(&rule);
zlog_debug(
- "%s: %s leftover rule: family %s IF %s(%u) Pref %u Src %s Dst %s Table %u",
+ "%s: %s leftover rule: family %s IF %s Pref %u Src %s Dst %s Table %u",
__func__,
((ret == ZEBRA_DPLANE_REQUEST_FAILURE)
? "Failed to remove"
: "Removed"),
nl_family_to_str(frh->family), rule.ifname,
- rule.rule.ifindex, rule.rule.priority,
+ rule.rule.priority,
prefix2str(&rule.rule.filter.src_ip, buf1,
sizeof(buf1)),
prefix2str(&rule.rule.filter.dst_ip, buf2,
@@ -350,10 +350,10 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
- "Rx %s family %s IF %s(%u) Pref %u Src %s Dst %s Table %u",
+ "Rx %s family %s IF %s Pref %u Src %s Dst %s Table %u",
nl_msg_type_to_str(h->nlmsg_type),
nl_family_to_str(frh->family), rule.ifname,
- rule.rule.ifindex, rule.rule.priority,
+ rule.rule.priority,
prefix2str(&rule.rule.filter.src_ip, buf1,
sizeof(buf1)),
prefix2str(&rule.rule.filter.dst_ip, buf2,
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index fbed99dc59..e436e5a288 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -815,7 +815,7 @@ void zsend_rule_notify_owner(const struct zebra_dplane_ctx *ctx,
stream_putl(s, dplane_ctx_rule_get_seq(ctx));
stream_putl(s, dplane_ctx_rule_get_priority(ctx));
stream_putl(s, dplane_ctx_rule_get_unique(ctx));
- stream_putl(s, dplane_ctx_get_ifindex(ctx));
+ stream_put(s, dplane_ctx_rule_get_ifname(ctx), INTERFACE_NAMSIZ);
stream_putw_at(s, 0, stream_get_endp(s));
@@ -1349,6 +1349,20 @@ static void zread_interface_add(ZAPI_HANDLER_ARGS)
struct vrf *vrf;
struct interface *ifp;
+ vrf_id_t vrf_id = zvrf_id(zvrf);
+ if (vrf_id != VRF_DEFAULT && vrf_id != VRF_UNKNOWN) {
+ FOR_ALL_INTERFACES (zvrf->vrf, ifp) {
+ /* Skip pseudo interface. */
+ if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE))
+ continue;
+
+ zsend_interface_add(client, ifp);
+ zsend_interface_link_params(client, ifp);
+ zsend_interface_addresses(client, ifp);
+ }
+ return;
+ }
+
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
FOR_ALL_INTERFACES (vrf, ifp) {
/* Skip pseudo interface. */
@@ -1588,16 +1602,17 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
return;
}
+ vrf_id = zvrf_id(zvrf);
+
if (IS_ZEBRA_DEBUG_RECV) {
char buf_prefix[PREFIX_STRLEN];
prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
- zlog_debug("%s: p=%s, msg flags=0x%x, flags=0x%x",
- __func__, buf_prefix, (int)api.message, api.flags);
+ zlog_debug("%s: p=(%u:%u)%s, msg flags=0x%x, flags=0x%x",
+ __func__, vrf_id, api.tableid, buf_prefix, (int)api.message, api.flags);
}
/* Allocate new route. */
- vrf_id = zvrf_id(zvrf);
re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
re->type = api.type;
re->instance = api.instance;
@@ -1878,9 +1893,18 @@ static void zread_route_del(ZAPI_HANDLER_ARGS)
else
table_id = zvrf->table_id;
+ if (IS_ZEBRA_DEBUG_RECV) {
+ char buf_prefix[PREFIX_STRLEN];
+
+ prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
+ zlog_debug("%s: p=(%u:%u)%s, msg flags=0x%x, flags=0x%x",
+ __func__, zvrf_id(zvrf), table_id, buf_prefix,
+ (int)api.message, api.flags);
+ }
+
rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
api.flags, &api.prefix, src_p, NULL, 0, table_id, api.metric,
- api.distance, false);
+ api.distance, false, false);
/* Stats */
switch (api.prefix.family) {
@@ -2727,6 +2751,7 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
struct zebra_pbr_rule zpr;
struct stream *s;
uint32_t total, i;
+ char ifname[INTERFACE_NAMSIZ + 1] = {};
s = msg;
STREAM_GETL(s, total);
@@ -2752,21 +2777,10 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
STREAM_GETC(s, zpr.rule.filter.dsfield);
STREAM_GETL(s, zpr.rule.filter.fwmark);
STREAM_GETL(s, zpr.rule.action.table);
- STREAM_GETL(s, zpr.rule.ifindex);
+ STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
- if (zpr.rule.ifindex) {
- struct interface *ifp;
-
- ifp = if_lookup_by_index_per_ns(zvrf->zns,
- zpr.rule.ifindex);
- if (!ifp) {
- zlog_debug("Failed to lookup ifindex: %u",
- zpr.rule.ifindex);
- return;
- }
-
- strlcpy(zpr.ifname, ifp->name, sizeof(zpr.ifname));
- }
+ strlcpy(zpr.ifname, ifname, sizeof(zpr.ifname));
+ strlcpy(zpr.rule.ifname, ifname, sizeof(zpr.rule.ifname));
if (!is_default_prefix(&zpr.rule.filter.src_ip))
zpr.rule.filter.filter_bm |= PBR_FILTER_SRC_IP;
@@ -2831,6 +2845,7 @@ static inline void zread_ipset(ZAPI_HANDLER_ARGS)
zpi.vrf_id = zvrf->vrf->vrf_id;
STREAM_GETL(s, zpi.unique);
STREAM_GETL(s, zpi.type);
+ STREAM_GETC(s, zpi.family);
STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
if (hdr->command == ZEBRA_IPSET_CREATE)
@@ -2941,6 +2956,7 @@ static inline void zread_iptable(ZAPI_HANDLER_ARGS)
STREAM_GETL(s, zpi->action);
STREAM_GETL(s, zpi->fwmark);
STREAM_GET(&zpi->ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
+ STREAM_GETC(s, zpi->family);
STREAM_GETW(s, zpi->pkt_len_min);
STREAM_GETW(s, zpi->pkt_len_max);
STREAM_GETW(s, zpi->tcp_flags);
@@ -2948,6 +2964,7 @@ static inline void zread_iptable(ZAPI_HANDLER_ARGS)
STREAM_GETC(s, zpi->dscp_value);
STREAM_GETC(s, zpi->fragment);
STREAM_GETC(s, zpi->protocol);
+ STREAM_GETW(s, zpi->flow_label);
STREAM_GETL(s, zpi->nb_interface);
zebra_pbr_iptable_update_interfacelist(s, zpi);
@@ -3103,29 +3120,6 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_CLIENT_CAPABILITIES] = zread_client_capabilities,
[ZEBRA_NEIGH_DISCOVER] = zread_neigh_discover};
-#if defined(HANDLE_ZAPI_FUZZING)
-extern struct zebra_privs_t zserv_privs;
-
-static void zserv_write_incoming(struct stream *orig, uint16_t command)
-{
- char fname[MAXPATHLEN];
- struct stream *copy;
- int fd = -1;
-
- copy = stream_dup(orig);
- stream_set_getp(copy, 0);
-
- snprintf(fname, MAXPATHLEN, "%s/%u", frr_vtydir, command);
-
- frr_with_privs(&zserv_privs) {
- fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644);
- }
- stream_flush(copy, fd);
- close(fd);
- stream_free(copy);
-}
-#endif
-
/*
* Process a batch of zapi messages.
*/
@@ -3152,13 +3146,10 @@ void zserv_handle_commands(struct zserv *client, struct stream_fifo *fifo)
zapi_parse_header(msg, &hdr);
- if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
+ if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV
+ && IS_ZEBRA_DEBUG_DETAIL)
zserv_log_message(NULL, msg, &hdr);
-#if defined(HANDLE_ZAPI_FUZZING)
- zserv_write_incoming(msg, hdr.command);
-#endif
-
hdr.length -= ZEBRA_HEADER_SIZE;
/* Before checking for a handler function, check for
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index 6e8d35aa77..abd0adb64e 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -210,6 +210,7 @@ struct dplane_ctx_rule {
uint8_t dsfield;
struct prefix src_ip;
struct prefix dst_ip;
+ char ifname[INTERFACE_NAMSIZ + 1];
};
struct dplane_rule_info {
@@ -1632,6 +1633,13 @@ int dplane_ctx_rule_get_sock(const struct zebra_dplane_ctx *ctx)
return ctx->u.rule.sock;
}
+const char *dplane_ctx_rule_get_ifname(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.rule.new.ifname;
+}
+
int dplane_ctx_rule_get_unique(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
@@ -1911,10 +1919,11 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
* If its a delete we only use the prefix anyway, so this only
* matters for INSTALL/UPDATE.
*/
- if (((op == DPLANE_OP_ROUTE_INSTALL)
- || (op == DPLANE_OP_ROUTE_UPDATE))
- && !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED)
- && !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_QUEUED)) {
+ if (zebra_nhg_kernel_nexthops_enabled()
+ && (((op == DPLANE_OP_ROUTE_INSTALL)
+ || (op == DPLANE_OP_ROUTE_UPDATE))
+ && !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED)
+ && !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_QUEUED))) {
ret = ENOENT;
goto done;
}
@@ -2190,6 +2199,7 @@ static void dplane_ctx_rule_init_single(struct dplane_ctx_rule *dplane_rule,
dplane_rule->dsfield = rule->rule.filter.dsfield;
prefix_copy(&(dplane_rule->dst_ip), &rule->rule.filter.dst_ip);
prefix_copy(&(dplane_rule->src_ip), &rule->rule.filter.src_ip);
+ strlcpy(dplane_rule->ifname, rule->ifname, INTERFACE_NAMSIZ);
}
/**
@@ -2211,10 +2221,9 @@ static int dplane_ctx_rule_init(struct zebra_dplane_ctx *ctx,
char buf2[PREFIX_STRLEN];
zlog_debug(
- "init dplane ctx %s: IF %s(%u) Prio %u Fwmark %u Src %s Dst %s Table %u",
+ "init dplane ctx %s: IF %s Prio %u Fwmark %u Src %s Dst %s Table %u",
dplane_op2str(op), new_rule->ifname,
- new_rule->rule.ifindex, new_rule->rule.priority,
- new_rule->rule.filter.fwmark,
+ new_rule->rule.priority, new_rule->rule.filter.fwmark,
prefix2str(&new_rule->rule.filter.src_ip, buf1,
sizeof(buf1)),
prefix2str(&new_rule->rule.filter.dst_ip, buf2,
@@ -2231,7 +2240,6 @@ static int dplane_ctx_rule_init(struct zebra_dplane_ctx *ctx,
ctx->zd_vrf_id = new_rule->vrf_id;
memcpy(ctx->zd_ifname, new_rule->ifname, sizeof(new_rule->ifname));
- ctx->zd_ifindex = new_rule->rule.ifindex;
ctx->u.rule.sock = new_rule->sock;
ctx->u.rule.unique = new_rule->rule.unique;
@@ -2352,11 +2360,8 @@ dplane_route_update_internal(struct route_node *rn,
if (ret == AOK)
result = ZEBRA_DPLANE_REQUEST_QUEUED;
else {
- if (ret == ENOENT)
- result = ZEBRA_DPLANE_REQUEST_SUCCESS;
- else
- atomic_fetch_add_explicit(&zdplane_info.dg_route_errors,
- 1, memory_order_relaxed);
+ atomic_fetch_add_explicit(&zdplane_info.dg_route_errors, 1,
+ memory_order_relaxed);
if (ctx)
dplane_ctx_free(&ctx);
}
diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h
index 5dd789a851..1d852b1bac 100644
--- a/zebra/zebra_dplane.h
+++ b/zebra/zebra_dplane.h
@@ -423,6 +423,7 @@ uint32_t dplane_ctx_neigh_get_update_flags(const struct zebra_dplane_ctx *ctx);
int dplane_ctx_rule_get_sock(const struct zebra_dplane_ctx *ctx);
int dplane_ctx_rule_get_unique(const struct zebra_dplane_ctx *ctx);
int dplane_ctx_rule_get_seq(const struct zebra_dplane_ctx *ctx);
+const char *dplane_ctx_rule_get_ifname(const struct zebra_dplane_ctx *ctx);
uint32_t dplane_ctx_rule_get_priority(const struct zebra_dplane_ctx *ctx);
uint32_t dplane_ctx_rule_get_old_priority(const struct zebra_dplane_ctx *ctx);
uint32_t dplane_ctx_rule_get_table(const struct zebra_dplane_ctx *ctx);
diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c
index 80124f92b3..56699c4e83 100644
--- a/zebra/zebra_evpn.c
+++ b/zebra/zebra_evpn.c
@@ -1011,7 +1011,7 @@ zebra_evpn_t *zebra_evpn_add(vni_t vni)
zevpn = hash_get(zvrf->evpn_table, &tmp_zevpn, zebra_evpn_alloc);
assert(zevpn);
- zebra_evpn_evpn_es_init(zevpn);
+ zebra_evpn_es_evi_init(zevpn);
/* Create hash table for MAC */
zevpn->mac_table = zebra_mac_db_create("Zebra EVPN MAC Table");
@@ -1041,7 +1041,7 @@ int zebra_evpn_del(zebra_evpn_t *zevpn)
hash_free(zevpn->mac_table);
zevpn->mac_table = NULL;
- zebra_evpn_evpn_es_cleanup(zevpn);
+ zebra_evpn_es_evi_cleanup(zevpn);
/* Free the EVPN hash entry and allocated memory. */
tmp_zevpn = hash_release(zvrf->evpn_table, zevpn);
diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c
index 6fc141efbb..75031ddba6 100644
--- a/zebra/zebra_evpn_mac.c
+++ b/zebra/zebra_evpn_mac.c
@@ -2067,6 +2067,7 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn,
if (is_dup_detect) {
inform_client = false;
upd_neigh = false;
+ es_change = false;
}
}
}
@@ -2099,7 +2100,8 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn,
mac->es ? mac->es->esi_str : "", mac->loc_seq,
mac->flags,
local_inactive ? " local-inactive" : "");
- inform_client = true;
+ if (!is_dup_detect)
+ inform_client = true;
}
if (es_change) {
diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c
index 029480eb4a..2567171c5e 100644
--- a/zebra/zebra_evpn_mh.c
+++ b/zebra/zebra_evpn_mh.c
@@ -363,7 +363,7 @@ void zebra_evpn_es_evi_show_vni(struct vty *vty, bool uj, vni_t vni, int detail)
}
/* Initialize the ES tables maintained per-L2_VNI */
-void zebra_evpn_evpn_es_init(zebra_evpn_t *zevpn)
+void zebra_evpn_es_evi_init(zebra_evpn_t *zevpn)
{
/* Initialize the ES-EVI RB tree */
RB_INIT(zebra_es_evi_rb_head, &zevpn->es_evi_rb_tree);
@@ -376,7 +376,7 @@ void zebra_evpn_evpn_es_init(zebra_evpn_t *zevpn)
}
/* Cleanup the ES info maintained per- EVPN */
-void zebra_evpn_evpn_es_cleanup(zebra_evpn_t *zevpn)
+void zebra_evpn_es_evi_cleanup(zebra_evpn_t *zevpn)
{
struct zebra_evpn_es_evi *es_evi;
struct zebra_evpn_es_evi *es_evi_next;
@@ -1356,7 +1356,8 @@ static void zebra_evpn_es_local_info_clear(struct zebra_evpn_es *es)
if (!(es->flags & ZEBRA_EVPNES_LOCAL))
return;
- es->flags &= ~ZEBRA_EVPNES_LOCAL;
+ es->flags &= ~(ZEBRA_EVPNES_LOCAL | ZEBRA_EVPNES_READY_FOR_BGP);
+
/* if there any local macs referring to the ES as dest we
* need to clear the static reference on them
*/
@@ -1613,9 +1614,13 @@ bool zebra_evpn_es_mac_ref(zebra_mac_t *mac, esi_t *esi)
es = zebra_evpn_es_find(esi);
if (!es) {
- es = zebra_evpn_es_new(esi);
- if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
- zlog_debug("auto es %s add on mac ref", es->esi_str);
+ /* If non-zero esi implicitly create a new ES */
+ if (memcmp(esi, zero_esi, sizeof(esi_t))) {
+ es = zebra_evpn_es_new(esi);
+ if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+ zlog_debug("auto es %s add on mac ref",
+ es->esi_str);
+ }
}
return zebra_evpn_es_mac_ref_entry(mac, es);
diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h
index ed62677e3b..72b7f9b675 100644
--- a/zebra/zebra_evpn_mh.h
+++ b/zebra/zebra_evpn_mh.h
@@ -198,8 +198,8 @@ extern void zebra_evpn_mh_terminate(void);
extern bool zebra_evpn_is_if_es_capable(struct zebra_if *zif);
extern void zebra_evpn_if_init(struct zebra_if *zif);
extern void zebra_evpn_if_cleanup(struct zebra_if *zif);
-extern void zebra_evpn_evpn_es_init(zebra_evpn_t *zevpn);
-extern void zebra_evpn_evpn_es_cleanup(zebra_evpn_t *zevpn);
+extern void zebra_evpn_es_evi_init(zebra_evpn_t *zevpn);
+extern void zebra_evpn_es_evi_cleanup(zebra_evpn_t *zevpn);
extern void zebra_evpn_vxl_evpn_set(struct zebra_if *zif, zebra_evpn_t *zevpn,
bool set);
extern void zebra_evpn_es_set_base_evpn(zebra_evpn_t *zevpn);
diff --git a/zebra/zebra_evpn_neigh.c b/zebra/zebra_evpn_neigh.c
index 492052b1b2..661d1c7f81 100644
--- a/zebra/zebra_evpn_neigh.c
+++ b/zebra/zebra_evpn_neigh.c
@@ -2184,9 +2184,10 @@ void process_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
seq, n->flags);
zebra_evpn_neigh_clear_sync_info(n);
if (IS_ZEBRA_NEIGH_ACTIVE(n))
- zebra_evpn_mac_send_del_to_client(
- zevpn->vni, &mac->macaddr,
- mac->flags, false /*force*/);
+ zebra_evpn_neigh_send_del_to_client(
+ zevpn->vni, &n->ip, &n->emac,
+ n->flags, n->state,
+ false /*force*/);
}
if (memcmp(&n->emac, &mac->macaddr,
sizeof(struct ethaddr))
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index 1bc8d893bc..c244d2a955 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -83,6 +83,27 @@ const struct message icmp_typecode_str[] = {
{0}
};
+const struct message icmpv6_typecode_str[] = {
+ { 128 << 8, "echo-request"},
+ { 129 << 8, "echo-reply"},
+ { 1 << 8, "no-route"},
+ { (1 << 8) + 1, "communication-prohibited"},
+ { (1 << 8) + 3, "address-unreachable"},
+ { (1 << 8) + 4, "port-unreachable"},
+ { (2 << 8), "packet-too-big"},
+ { 3 << 0, "ttl-zero-during-transit"},
+ { (3 << 8) + 1, "ttl-zero-during-reassembly"},
+ { 4 << 0, "bad-header"},
+ { (4 << 0) + 1, "unknown-header-type"},
+ { (4 << 0) + 2, "unknown-option"},
+ { 133 << 8, "router-solicitation"},
+ { 134 << 8, "router-advertisement"},
+ { 135 << 8, "neighbor-solicitation"},
+ { 136 << 8, "neighbor-advertisement"},
+ { 137 << 8, "redirect"},
+ {0}
+};
+
/* definitions */
static const struct message tcp_value_str[] = {
{TCP_HEADER_FIN, "FIN"},
@@ -146,10 +167,11 @@ uint32_t zebra_pbr_rules_hash_key(const void *arg)
prefix_hash_key(&rule->rule.filter.src_ip));
if (rule->rule.filter.fwmark)
- key = jhash_3words(rule->rule.filter.fwmark, rule->vrf_id,
- rule->rule.ifindex, key);
+ key = jhash_2words(rule->rule.filter.fwmark, rule->vrf_id, key);
else
- key = jhash_2words(rule->vrf_id, rule->rule.ifindex, key);
+ key = jhash_1word(rule->vrf_id, key);
+
+ key = jhash(rule->ifname, strlen(rule->ifname), key);
return jhash_3words(rule->rule.filter.src_port,
rule->rule.filter.dst_port,
@@ -191,7 +213,7 @@ bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
if (!prefix_same(&r1->rule.filter.dst_ip, &r2->rule.filter.dst_ip))
return false;
- if (r1->rule.ifindex != r2->rule.ifindex)
+ if (strcmp(r1->rule.ifname, r2->rule.ifname) != 0)
return false;
if (r1->vrf_id != r2->vrf_id)
@@ -203,7 +225,7 @@ bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
struct pbr_rule_unique_lookup {
struct zebra_pbr_rule *rule;
uint32_t unique;
- ifindex_t ifindex;
+ char ifname[INTERFACE_NAMSIZ + 1];
vrf_id_t vrf_id;
};
@@ -213,7 +235,7 @@ static int pbr_rule_lookup_unique_walker(struct hash_bucket *b, void *data)
struct zebra_pbr_rule *rule = b->data;
if (pul->unique == rule->rule.unique
- && pul->ifindex == rule->rule.ifindex
+ && strncmp(pul->ifname, rule->rule.ifname, INTERFACE_NAMSIZ) == 0
&& pul->vrf_id == rule->vrf_id) {
pul->rule = rule;
return HASHWALK_ABORT;
@@ -228,7 +250,7 @@ pbr_rule_lookup_unique(struct zebra_pbr_rule *zrule)
struct pbr_rule_unique_lookup pul;
pul.unique = zrule->rule.unique;
- pul.ifindex = zrule->rule.ifindex;
+ strlcpy(pul.ifname, zrule->rule.ifname, INTERFACE_NAMSIZ);
pul.rule = NULL;
pul.vrf_id = zrule->vrf_id;
hash_walk(zrouter.rules_hash, &pbr_rule_lookup_unique_walker, &pul);
@@ -251,6 +273,8 @@ uint32_t zebra_pbr_ipset_hash_key(const void *arg)
uint32_t *pnt = (uint32_t *)&ipset->ipset_name;
uint32_t key = jhash_1word(ipset->vrf_id, 0x63ab42de);
+ key = jhash_1word(ipset->family, key);
+
return jhash2(pnt, ZEBRA_IPSET_NAME_HASH_SIZE, key);
}
@@ -267,6 +291,8 @@ bool zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2)
return false;
if (r1->vrf_id != r2->vrf_id)
return false;
+ if (r1->family != r2->family)
+ return false;
if (strncmp(r1->ipset_name, r2->ipset_name,
ZEBRA_IPSET_NAME_SIZE))
@@ -376,6 +402,8 @@ uint32_t zebra_pbr_iptable_hash_key(const void *arg)
key = jhash2(pnt, ZEBRA_IPSET_NAME_HASH_SIZE,
0x63ab42de);
key = jhash_1word(iptable->fwmark, key);
+ key = jhash_1word(iptable->family, key);
+ key = jhash_1word(iptable->flow_label, key);
key = jhash_1word(iptable->pkt_len_min, key);
key = jhash_1word(iptable->pkt_len_max, key);
key = jhash_1word(iptable->tcp_flags, key);
@@ -411,6 +439,10 @@ bool zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2)
if (strncmp(r1->ipset_name, r2->ipset_name,
ZEBRA_IPSET_NAME_SIZE))
return false;
+ if (r1->family != r2->family)
+ return false;
+ if (r1->flow_label != r2->flow_label)
+ return false;
if (r1->pkt_len_min != r2->pkt_len_min)
return false;
if (r1->pkt_len_max != r2->pkt_len_max)
@@ -876,7 +908,8 @@ static const char *zebra_pbr_prefix2str(union prefixconstptr pu,
const struct prefix *p = pu.p;
char buf[PREFIX2STR_BUFFER];
- if (p->family == AF_INET && p->prefixlen == IPV4_MAX_PREFIXLEN) {
+ if ((p->family == AF_INET && p->prefixlen == IPV4_MAX_PREFIXLEN) ||
+ (p->family == AF_INET6 && p->prefixlen == IPV6_MAX_PREFIXLEN)) {
snprintf(str, size, "%s", inet_ntop(p->family, &p->u.prefix,
buf, PREFIX2STR_BUFFER));
return str;
@@ -889,6 +922,9 @@ static void zebra_pbr_display_icmp(struct vty *vty,
{
char decoded_str[20];
uint16_t port;
+ struct zebra_pbr_ipset *zpi;
+
+ zpi = zpie->backpointer;
/* range icmp type */
if (zpie->src_port_max || zpie->dst_port_max) {
@@ -901,8 +937,10 @@ static void zebra_pbr_display_icmp(struct vty *vty,
memset(decoded_str, 0, sizeof(decoded_str));
snprintf(decoded_str, sizeof(decoded_str), "%u/%u",
zpie->src_port_min, zpie->dst_port_min);
- vty_out(vty, ":icmp:%s",
- lookup_msg(icmp_typecode_str,
+ vty_out(vty, ":%s:%s",
+ zpi->family == AF_INET6 ? "ipv6-icmp" : "icmp",
+ lookup_msg(zpi->family == AF_INET6 ?
+ icmpv6_typecode_str : icmp_typecode_str,
port, decoded_str));
}
}
@@ -1012,8 +1050,9 @@ static int zebra_pbr_show_ipset_walkcb(struct hash_bucket *bucket, void *arg)
struct vty *vty = uniqueipset->vty;
struct zebra_ns *zns = uniqueipset->zns;
- vty_out(vty, "IPset %s type %s\n", zpi->ipset_name,
- zebra_pbr_ipset_type2str(zpi->type));
+ vty_out(vty, "IPset %s type %s family %s\n", zpi->ipset_name,
+ zebra_pbr_ipset_type2str(zpi->type),
+ family2str(zpi->family));
unique.vty = vty;
unique.zpi = zpi;
unique.zns = zns;
@@ -1058,9 +1097,9 @@ void zebra_pbr_show_ipset_list(struct vty *vty, char *ipsetname)
vty_out(vty, "No IPset %s found\n", ipsetname);
return;
}
- vty_out(vty, "IPset %s type %s\n", ipsetname,
- zebra_pbr_ipset_type2str(zpi->type));
-
+ vty_out(vty, "IPset %s type %s family %s\n", ipsetname,
+ zebra_pbr_ipset_type2str(zpi->type),
+ family2str(zpi->family));
unique.vty = vty;
unique.zpi = zpi;
unique.zns = zns;
@@ -1101,7 +1140,9 @@ static void zebra_pbr_show_iptable_unit(struct zebra_pbr_iptable *iptable,
int ret;
uint64_t pkts = 0, bytes = 0;
- vty_out(vty, "IPtable %s action %s (%u)\n", iptable->ipset_name,
+ vty_out(vty, "IPtable %s family %s action %s (%u)\n",
+ iptable->ipset_name,
+ family2str(iptable->family),
iptable->action == ZEBRA_IPTABLES_DROP ? "drop" : "redirect",
iptable->unique);
if (iptable->type == IPSET_NET_PORT ||
@@ -1140,6 +1181,12 @@ static void zebra_pbr_show_iptable_unit(struct zebra_pbr_iptable *iptable,
iptable->filter_bm & MATCH_DSCP_INVERSE_SET ?
"not" : "", iptable->dscp_value);
}
+ if (iptable->filter_bm & (MATCH_FLOW_LABEL_SET |
+ MATCH_FLOW_LABEL_INVERSE_SET)) {
+ vty_out(vty, "\t flowlabel %s %d\n",
+ iptable->filter_bm & MATCH_FLOW_LABEL_INVERSE_SET ?
+ "not" : "", iptable->flow_label);
+ }
if (iptable->fragment) {
char val_str[10];
diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h
index 888d2fcfa0..e7504a3547 100644
--- a/zebra/zebra_pbr.h
+++ b/zebra/zebra_pbr.h
@@ -79,6 +79,9 @@ struct zebra_pbr_ipset {
* but value is an enum ipset_type
*/
uint32_t type;
+
+ uint8_t family;
+
char ipset_name[ZEBRA_IPSET_NAME_SIZE];
};
@@ -150,6 +153,9 @@ struct zebra_pbr_iptable {
uint8_t protocol;
uint32_t nb_interface;
+ uint16_t flow_label;
+
+ uint8_t family;
struct list *interface_name_list;
@@ -157,6 +163,7 @@ struct zebra_pbr_iptable {
};
extern const struct message icmp_typecode_str[];
+extern const struct message icmpv6_typecode_str[];
const char *zebra_pbr_ipset_type2str(uint32_t type);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index d1d56f2cdb..ff30de18a3 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -120,6 +120,7 @@ _rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn,
char buf[SRCDEST2STR_BUFFER + sizeof(" (MRIB)")];
char msgbuf[512];
va_list ap;
+ uint32_t table = 0;
va_start(ap, msgfmt);
vsnprintf(msgbuf, sizeof(msgbuf), msgfmt, ap);
@@ -127,15 +128,24 @@ _rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn,
if (rn) {
struct rib_table_info *info = srcdest_rnode_table_info(rn);
+ rib_dest_t *dest = NULL;
+ struct route_entry *re = NULL;
+
srcdest_rnode2str(rn, buf, sizeof(buf));
if (info->safi == SAFI_MULTICAST)
strlcat(buf, " (MRIB)", sizeof(buf));
+
+ dest = rib_dest_from_rnode(rn);
+ if (dest)
+ re = re_list_first(&dest->routes);
+ if (re)
+ table = re->table;
} else {
snprintf(buf, sizeof(buf), "{(route_node *) NULL}");
}
- zlog(priority, "%s: %d:%s: %s", _func, vrf_id, buf, msgbuf);
+ zlog(priority, "%s: (%u:%u):%s: %s", _func, vrf_id, table, buf, msgbuf);
}
#define rnode_debug(node, vrf_id, ...) \
@@ -489,8 +499,8 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re,
srcdest_rnode2str(rn, str, sizeof(str));
flog_err(EC_ZEBRA_DP_INSTALL_FAIL,
- "%u:%s: Failed to enqueue dataplane install",
- re->vrf_id, str);
+ "%u:%u:%s: Failed to enqueue dataplane install",
+ re->vrf_id, re->table, str);
break;
}
case ZEBRA_DPLANE_REQUEST_SUCCESS:
@@ -758,9 +768,9 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
if (IS_ZEBRA_DEBUG_RIB) {
char buf[SRCDEST2STR_BUFFER];
srcdest_rnode2str(rn, buf, sizeof(buf));
- zlog_debug("%s(%u):%s: Adding route rn %p, re %p (%s)",
- zvrf_name(zvrf), zvrf_id(zvrf), buf, rn, new,
- zebra_route_string(new->type));
+ zlog_debug("%s(%u:%u):%s: Adding route rn %p, re %p (%s)",
+ zvrf_name(zvrf), zvrf_id(zvrf), new->table, buf, rn,
+ new, zebra_route_string(new->type));
}
/* If labeled-unicast route, install transit LSP. */
@@ -781,9 +791,9 @@ static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
if (IS_ZEBRA_DEBUG_RIB) {
char buf[SRCDEST2STR_BUFFER];
srcdest_rnode2str(rn, buf, sizeof(buf));
- zlog_debug("%s(%u):%s: Deleting route rn %p, re %p (%s)",
- zvrf_name(zvrf), zvrf_id(zvrf), buf, rn, old,
- zebra_route_string(old->type));
+ zlog_debug("%s(%u:%u):%s: Deleting route rn %p, re %p (%s)",
+ zvrf_name(zvrf), zvrf_id(zvrf), old->table, buf, rn,
+ old, zebra_route_string(old->type));
}
/* If labeled-unicast route, uninstall transit LSP. */
@@ -834,17 +844,17 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
srcdest_rnode2str(rn, buf, sizeof(buf));
if (new != old)
zlog_debug(
- "%s(%u):%s: Updating route rn %p, re %p (%s) old %p (%s)",
+ "%s(%u:%u):%s: Updating route rn %p, re %p (%s) old %p (%s)",
zvrf_name(zvrf), zvrf_id(zvrf),
- buf, rn, new,
+ new->table, buf, rn, new,
zebra_route_string(new->type),
old,
zebra_route_string(old->type));
else
zlog_debug(
- "%s(%u):%s: Updating route rn %p, re %p (%s)",
+ "%s(%u:%u):%s: Updating route rn %p, re %p (%s)",
zvrf_name(zvrf), zvrf_id(zvrf),
- buf, rn, new,
+ new->table, buf, rn, new,
zebra_route_string(new->type));
}
@@ -874,17 +884,17 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
srcdest_rnode2str(rn, buf, sizeof(buf));
if (new != old)
zlog_debug(
- "%s(%u):%s: Deleting route rn %p, re %p (%s) old %p (%s) - nexthop inactive",
+ "%s(%u:%u):%s: Deleting route rn %p, re %p (%s) old %p (%s) - nexthop inactive",
zvrf_name(zvrf), zvrf_id(zvrf),
- buf, rn, new,
+ new->table, buf, rn, new,
zebra_route_string(new->type),
old,
zebra_route_string(old->type));
else
zlog_debug(
- "%s(%u):%s: Deleting route rn %p, re %p (%s) - nexthop inactive",
+ "%s(%u:%u):%s: Deleting route rn %p, re %p (%s) - nexthop inactive",
zvrf_name(zvrf), zvrf_id(zvrf),
- buf, rn, new,
+ new->table, buf, rn, new,
zebra_route_string(new->type));
}
@@ -1018,24 +1028,29 @@ static void rib_process(struct route_node *rn)
if (IS_ZEBRA_DEBUG_RIB)
srcdest_rnode2str(rn, buf, sizeof(buf));
- if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug("%s(%u):%s: Processing rn %p", VRF_LOGNAME(vrf),
- vrf_id, buf, rn);
-
/*
* we can have rn's that have a NULL info pointer
* (dest). As such let's not let the deref happen
* additionally we know RNODE_FOREACH_RE_SAFE
* will not iterate so we are ok.
*/
- if (dest)
+ if (dest) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
+ struct route_entry *re = re_list_first(&dest->routes);
+
+ zlog_debug("%s(%u:%u):%s: Processing rn %p",
+ VRF_LOGNAME(vrf), vrf_id, re->table, buf,
+ rn);
+ }
+
old_fib = dest->selected_fib;
+ }
RNODE_FOREACH_RE_SAFE (rn, re, next) {
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug(
- "%s(%u):%s: Examine re %p (%s) status %x flags %x dist %d metric %d",
- VRF_LOGNAME(vrf), vrf_id, buf, re,
+ "%s(%u:%u):%s: Examine re %p (%s) status %x flags %x dist %d metric %d",
+ VRF_LOGNAME(vrf), vrf_id, re->table, buf, re,
zebra_route_string(re->type), re->status,
re->flags, re->distance, re->metric);
@@ -1131,10 +1146,20 @@ static void rib_process(struct route_node *rn)
*/
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
+ struct route_entry *entry;
+
+ entry = old_selected
+ ? old_selected
+ : new_selected
+ ? new_selected
+ : old_fib ? old_fib
+ : new_fib ? new_fib : NULL;
+
zlog_debug(
- "%s(%u):%s: After processing: old_selected %p new_selected %p old_fib %p new_fib %p",
- VRF_LOGNAME(vrf), vrf_id, buf, (void *)old_selected,
- (void *)new_selected, (void *)old_fib, (void *)new_fib);
+ "%s(%u:%u):%s: After processing: old_selected %p new_selected %p old_fib %p new_fib %p",
+ VRF_LOGNAME(vrf), vrf_id, entry ? entry->table : 0, buf,
+ (void *)old_selected, (void *)new_selected,
+ (void *)old_fib, (void *)new_fib);
}
/* Buffer ROUTE_ENTRY_CHANGED here, because it will get cleared if
@@ -1456,8 +1481,8 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
is_selected = (re == dest->selected_fib);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug("update_from_ctx: %s(%u):%s: %sSELECTED, re %p",
- VRF_LOGNAME(vrf), re->vrf_id, dest_str,
+ zlog_debug("update_from_ctx: %s(%u:%u):%s: %sSELECTED, re %p",
+ VRF_LOGNAME(vrf), re->vrf_id, re->table, dest_str,
(is_selected ? "" : "NOT "), re);
/* Update zebra's nexthop FIB flag for each nexthop that was installed.
@@ -1483,8 +1508,9 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
if (matched) {
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug(
- "%s(%u):%s update_from_ctx(): existing fib nhg, no change",
- VRF_LOGNAME(vrf), re->vrf_id, dest_str);
+ "%s(%u:%u):%s update_from_ctx(): existing fib nhg, no change",
+ VRF_LOGNAME(vrf), re->vrf_id, re->table,
+ dest_str);
goto check_backups;
} else if (CHECK_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG)) {
@@ -1493,8 +1519,9 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
*/
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug(
- "%s(%u):%s update_from_ctx(): replacing fib nhg",
- VRF_LOGNAME(vrf), re->vrf_id, dest_str);
+ "%s(%u:%u):%s update_from_ctx(): replacing fib nhg",
+ VRF_LOGNAME(vrf), re->vrf_id, re->table,
+ dest_str);
nexthops_free(re->fib_ng.nexthop);
re->fib_ng.nexthop = NULL;
@@ -1504,8 +1531,9 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
changed_p = true;
} else {
if (IS_ZEBRA_DEBUG_RIB)
- zlog_debug("%s(%u):%s update_from_ctx(): no fib nhg",
- VRF_LOGNAME(vrf), re->vrf_id, dest_str);
+ zlog_debug("%s(%u:%u):%s update_from_ctx(): no fib nhg",
+ VRF_LOGNAME(vrf), re->vrf_id, re->table,
+ dest_str);
}
/*
@@ -1532,9 +1560,9 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
if (matched) {
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug(
- "%s(%u):%s update_from_ctx(): rib nhg matched, changed '%s'",
- VRF_LOGNAME(vrf), re->vrf_id, dest_str,
- (changed_p ? "true" : "false"));
+ "%s(%u:%u):%s update_from_ctx(): rib nhg matched, changed '%s'",
+ VRF_LOGNAME(vrf), re->vrf_id, re->table,
+ dest_str, (changed_p ? "true" : "false"));
goto check_backups;
}
@@ -1545,8 +1573,8 @@ no_nexthops:
*/
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug(
- "%s(%u):%s update_from_ctx(): changed %s, adding new fib nhg%s",
- VRF_LOGNAME(vrf), re->vrf_id, dest_str,
+ "%s(%u:%u):%s update_from_ctx(): changed %s, adding new fib nhg%s",
+ VRF_LOGNAME(vrf), re->vrf_id, re->table, dest_str,
(changed_p ? "true" : "false"),
ctxnhg->nexthop != NULL ? "" : " (empty)");
@@ -1722,9 +1750,10 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
zlog_debug(
- "%s(%u):%s Processing dplane result ctx %p, op %s result %s",
- VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), dest_str,
- ctx, dplane_op2str(op), dplane_res2str(status));
+ "%s(%u:%u):%s Processing dplane result ctx %p, op %s result %s",
+ VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
+ dplane_ctx_get_table(ctx), dest_str, ctx,
+ dplane_op2str(op), dplane_res2str(status));
/*
* Update is a bit of a special case, where we may have both old and new
@@ -1774,10 +1803,10 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
if (old_re->dplane_sequence != dplane_ctx_get_old_seq(ctx)) {
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
zlog_debug(
- "%s(%u):%s Stale dplane result for old_re %p",
+ "%s(%u:%u):%s Stale dplane result for old_re %p",
VRF_LOGNAME(vrf),
- dplane_ctx_get_vrf(ctx), dest_str,
- old_re);
+ dplane_ctx_get_vrf(ctx), old_re->table,
+ dest_str, old_re);
} else
UNSET_FLAG(old_re->status, ROUTE_ENTRY_QUEUED);
}
@@ -1815,9 +1844,11 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
if (!fib_changed) {
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
zlog_debug(
- "%s(%u):%s no fib change for re",
+ "%s(%u:%u):%s no fib change for re",
VRF_LOGNAME(vrf),
dplane_ctx_get_vrf(ctx),
+ dplane_ctx_get_table(
+ ctx),
dest_str);
}
@@ -1854,8 +1885,9 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
zsend_route_notify_owner(re, dest_pfx,
ZAPI_ROUTE_FAIL_INSTALL);
- zlog_warn("%s(%u):%s: Route install failed",
+ zlog_warn("%s(%u:%u):%s: Route install failed",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
+ dplane_ctx_get_table(ctx),
prefix2str(dest_pfx, dest_str,
sizeof(dest_str)));
}
@@ -1883,8 +1915,9 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
zsend_route_notify_owner_ctx(ctx,
ZAPI_ROUTE_REMOVE_FAIL);
- zlog_warn("%s(%u):%s: Route Deletion failure",
+ zlog_warn("%s(%u:%u):%s: Route Deletion failure",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
+ dplane_ctx_get_table(ctx),
prefix2str(dest_pfx, dest_str,
sizeof(dest_str)));
}
@@ -1981,9 +2014,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
if (rn == NULL) {
if (debug_p) {
zlog_debug(
- "Failed to process dplane notification: no routes for %s(%u):%s",
+ "Failed to process dplane notification: no routes for %s(%u:%u):%s",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
- dest_str);
+ dplane_ctx_get_table(ctx), dest_str);
}
goto done;
}
@@ -1992,9 +2025,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
srcdest_rnode_prefixes(rn, &dest_pfx, &src_pfx);
if (debug_p)
- zlog_debug("%s(%u):%s Processing dplane notif ctx %p",
- VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), dest_str,
- ctx);
+ zlog_debug("%s(%u:%u):%s Processing dplane notif ctx %p",
+ VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
+ dplane_ctx_get_table(ctx), dest_str, ctx);
/*
* Take a pass through the routes, look for matches with the context
@@ -2009,9 +2042,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
if (re == NULL) {
if (debug_p)
zlog_debug(
- "%s(%u):%s Unable to process dplane notification: no entry for type %s",
+ "%s(%u:%u):%s Unable to process dplane notification: no entry for type %s",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
- dest_str,
+ dplane_ctx_get_table(ctx), dest_str,
zebra_route_string(dplane_ctx_get_type(ctx)));
goto done;
@@ -2043,18 +2076,20 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
if (debug_p)
zlog_debug(
- "%s(%u):%s dplane notif, uninstalled type %s route",
+ "%s(%u:%u):%s dplane notif, uninstalled type %s route",
VRF_LOGNAME(vrf),
- dplane_ctx_get_vrf(ctx), dest_str,
+ dplane_ctx_get_vrf(ctx),
+ dplane_ctx_get_table(ctx), dest_str,
zebra_route_string(
dplane_ctx_get_type(ctx)));
} else {
/* At least report on the event. */
if (debug_p)
zlog_debug(
- "%s(%u):%s dplane notif, but type %s not selected_fib",
+ "%s(%u:%u):%s dplane notif, but type %s not selected_fib",
VRF_LOGNAME(vrf),
- dplane_ctx_get_vrf(ctx), dest_str,
+ dplane_ctx_get_vrf(ctx),
+ dplane_ctx_get_table(ctx), dest_str,
zebra_route_string(
dplane_ctx_get_type(ctx)));
}
@@ -2078,9 +2113,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
if (!fib_changed) {
if (debug_p)
zlog_debug(
- "%s(%u):%s dplane notification: rib_update returns FALSE",
+ "%s(%u:%u):%s dplane notification: rib_update returns FALSE",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
- dest_str);
+ dplane_ctx_get_table(ctx), dest_str);
}
/*
@@ -2095,9 +2130,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
if (start_count > 0 && end_count > 0) {
if (debug_p)
zlog_debug(
- "%s(%u):%s applied nexthop changes from dplane notification",
+ "%s(%u:%u):%s applied nexthop changes from dplane notification",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
- dest_str);
+ dplane_ctx_get_table(ctx), dest_str);
/* Changed nexthops - update kernel/others */
dplane_route_notif_update(rn, re,
@@ -2106,9 +2141,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
} else if (start_count == 0 && end_count > 0) {
if (debug_p)
zlog_debug(
- "%s(%u):%s installed transition from dplane notification",
+ "%s(%u:%u):%s installed transition from dplane notification",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
- dest_str);
+ dplane_ctx_get_table(ctx), dest_str);
/* We expect this to be the selected route, so we want
* to tell others about this transition.
@@ -2124,9 +2159,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
} else if (start_count > 0 && end_count == 0) {
if (debug_p)
zlog_debug(
- "%s(%u):%s un-installed transition from dplane notification",
+ "%s(%u:%u):%s un-installed transition from dplane notification",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
- dest_str);
+ dplane_ctx_get_table(ctx), dest_str);
/* Transition from _something_ installed to _nothing_
* installed.
@@ -2182,17 +2217,20 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex)
rnode = listgetdata(lnode);
dest = rib_dest_from_rnode(rnode);
- if (dest)
- zvrf = rib_dest_vrf(dest);
+ assert(dest);
+
+ zvrf = rib_dest_vrf(dest);
rib_process(rnode);
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
+ struct route_entry *re = re_list_first(&dest->routes);
char buf[SRCDEST2STR_BUFFER];
srcdest_rnode2str(rnode, buf, sizeof(buf));
- zlog_debug("%s(%u):%s: rn %p dequeued from sub-queue %u",
- zvrf_name(zvrf), zvrf_id(zvrf), buf, rnode, qindex);
+ zlog_debug("%s(%u:%u):%s: rn %p dequeued from sub-queue %u",
+ zvrf_name(zvrf), zvrf_id(zvrf), re ? re->table : 0, buf,
+ rnode, qindex);
}
if (rnode->info)
@@ -3003,7 +3041,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
unsigned short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
uint32_t nhe_id, uint32_t table_id, uint32_t metric,
- uint8_t distance, bool fromkernel)
+ uint8_t distance, bool fromkernel, bool connected_down)
{
struct route_table *table;
struct route_node *rn;
@@ -3125,7 +3163,8 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
rn, fib,
zebra_route_string(fib->type));
}
- if (allow_delete) {
+ if (allow_delete
+ || CHECK_FLAG(dest->flags, RIB_ROUTE_ANY_QUEUED)) {
UNSET_FLAG(fib->status, ROUTE_ENTRY_INSTALLED);
/* Unset flags. */
for (rtnh = fib->nhe->nhg.nexthop; rtnh;
@@ -3210,6 +3249,19 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
rib_delnode(rn, same);
}
+ /*
+ * This is to force an immediate re-eval of this particular
+ * node via nexthop tracking. Why? Because there are scenarios
+ * where the interface is flapping and the normal queuing methodology
+ * will cause down/up events to very very rarely be combined into
+ * a non-event from nexthop tracking perspective. Leading
+ * to some fun timing situations with upper level routing protocol
+ * trying to and failing to install routes during this blip. Especially
+ * when zebra is under load.
+ */
+ if (connected_down)
+ zebra_rib_evaluate_rn_nexthops(rn,
+ zebra_router_get_next_sequence());
route_unlock_node(rn);
return;
}
diff --git a/zebra/zserv.c b/zebra/zserv.c
index cded6ea12b..4c8656af0d 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -1294,17 +1294,6 @@ DEFUN (show_zebra_client_summary,
return CMD_SUCCESS;
}
-#if defined(HANDLE_ZAPI_FUZZING)
-void zserv_read_file(char *input)
-{
- int fd;
-
- fd = open(input, O_RDONLY | O_NONBLOCK);
-
- zserv_client_create(fd);
-}
-#endif
-
void zserv_init(void)
{
/* Client list init. */
diff --git a/zebra/zserv.h b/zebra/zserv.h
index 54e840cd56..c60799b8ba 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -375,10 +375,6 @@ extern void zserv_close_client(struct zserv *client);
void zserv_log_message(const char *errmsg, struct stream *msg,
struct zmsghdr *hdr);
-#if defined(HANDLE_ZAPI_FUZZING)
-extern void zserv_read_file(char *input);
-#endif
-
/* TODO */
__attribute__((__noreturn__)) int zebra_finalize(struct thread *event);