summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_attr.c5
-rw-r--r--bgpd/bgp_evpn_vty.c21
-rw-r--r--bgpd/bgp_route.c34
-rw-r--r--bgpd/bgp_vty.c17
-rwxr-xr-xconfigure.ac4
-rw-r--r--debian/README.Debian2
-rw-r--r--doc/user/pim.rst7
-rwxr-xr-xdocker/centos-8/build.sh2
-rw-r--r--isisd/isisd.c7
-rw-r--r--lib/if.c7
-rw-r--r--lib/zclient.c11
-rw-r--r--redhat/frr.spec.in2
-rw-r--r--yang/frr-isisd.yang6
-rw-r--r--zebra/debug.c30
-rw-r--r--zebra/debug.h9
-rw-r--r--zebra/if_netlink.c6
-rw-r--r--zebra/kernel_netlink.c20
-rw-r--r--zebra/rt_netlink.c32
-rw-r--r--zebra/rtadv.c17
-rw-r--r--zebra/zapi_msg.c64
-rw-r--r--zebra/zebra_pbr.c13
-rw-r--r--zebra/zebra_ptm.c2
-rw-r--r--zebra/zebra_rib.c14
23 files changed, 200 insertions, 132 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index fe7a80ccf2..bdac2a8dcc 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -152,8 +152,9 @@ static bool cluster_hash_cmp(const void *p1, const void *p2)
const struct cluster_list *cluster2 = p2;
return (cluster1->length == cluster2->length
- && memcmp(cluster1->list, cluster2->list, cluster1->length)
- == 0);
+ && (cluster1->list == cluster2->list
+ || memcmp(cluster1->list, cluster2->list, cluster1->length)
+ == 0));
}
static void cluster_free(struct cluster_list *cluster)
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index d316a28dcb..3049a00ce3 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -5620,19 +5620,24 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
if (!bgp->evpn_info->advertise_pip)
vty_out(vty, " no advertise-pip\n");
if (bgp->evpn_info->advertise_pip) {
- if (bgp->evpn_info->pip_ip_static.s_addr != INADDR_ANY)
+ if (bgp->evpn_info->pip_ip_static.s_addr
+ != INADDR_ANY) {
vty_out(vty, " advertise-pip ip %s",
inet_ntop(AF_INET,
&bgp->evpn_info->pip_ip_static,
buf2, INET_ADDRSTRLEN));
- if (!is_zero_mac(&(bgp->evpn_info->pip_rmac_static))) {
- char buf[ETHER_ADDR_STRLEN];
-
- vty_out(vty, " mac %s",
- prefix_mac2str(&bgp->evpn_info->pip_rmac,
- buf, sizeof(buf)));
+ if (!is_zero_mac(&(
+ bgp->evpn_info->pip_rmac_static))) {
+ char buf[ETHER_ADDR_STRLEN];
+
+ vty_out(vty, " mac %s",
+ prefix_mac2str(
+ &bgp->evpn_info
+ ->pip_rmac,
+ buf, sizeof(buf)));
+ }
+ vty_out(vty, "\n");
}
- vty_out(vty, "\n");
}
}
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_RD_CFGD))
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 64d7ce9e9f..b216f85c40 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -4515,7 +4515,8 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
if (pnt + BGP_ADDPATH_ID_LEN >= lim)
return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
- addpath_id = ntohl(*((uint32_t *)pnt));
+ memcpy(&addpath_id, pnt, 4);
+ addpath_id = ntohl(addpath_id);
pnt += BGP_ADDPATH_ID_LEN;
}
@@ -9147,7 +9148,8 @@ static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
const char *prefix, afi_t afi, safi_t safi,
enum bgp_show_type type);
static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
- afi_t afi, safi_t safi, enum bgp_show_type type);
+ afi_t afi, safi_t safi, enum bgp_show_type type,
+ bool use_json);
static int bgp_show_community(struct vty *vty, struct bgp *bgp,
const char *comstr, int exact, afi_t afi,
safi_t safi, bool use_json);
@@ -9438,7 +9440,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
vty_out(vty, ",\"%s\": ", buf2);
}
vty_out(vty, "%s",
- json_object_to_json_string(json_paths));
+ json_object_to_json_string_ext(
+ json_paths, JSON_C_TO_STRING_PRETTY));
json_object_free(json_paths);
json_paths = NULL;
first = 0;
@@ -10464,7 +10467,7 @@ DEFUN (show_ip_bgp_route,
DEFUN (show_ip_bgp_regexp,
show_ip_bgp_regexp_cmd,
- "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX...",
+ "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
SHOW_STR
IP_STR
BGP_STR
@@ -10472,11 +10475,14 @@ DEFUN (show_ip_bgp_regexp,
BGP_AFI_HELP_STR
BGP_SAFI_WITH_LABEL_HELP_STR
"Display routes matching the AS path regular expression\n"
- "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n")
+ "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
+ JSON_STR)
{
afi_t afi = AFI_IP6;
safi_t safi = SAFI_UNICAST;
struct bgp *bgp = NULL;
+ bool uj = use_json(argc, argv);
+ char *regstr = NULL;
int idx = 0;
bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
@@ -10485,14 +10491,11 @@ DEFUN (show_ip_bgp_regexp,
return CMD_WARNING;
// get index of regex
- argv_find(argv, argc, "regexp", &idx);
- idx++;
+ if (argv_find(argv, argc, "REGEX", &idx))
+ regstr = argv[idx]->arg;
- char *regstr = argv_concat(argv, argc, idx);
- int rc = bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
- bgp_show_type_regexp);
- XFREE(MTYPE_TMP, regstr);
- return rc;
+ return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
+ bgp_show_type_regexp, uj);
}
DEFUN (show_ip_bgp_instance_all,
@@ -10525,13 +10528,14 @@ DEFUN (show_ip_bgp_instance_all,
}
static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
- afi_t afi, safi_t safi, enum bgp_show_type type)
+ afi_t afi, safi_t safi, enum bgp_show_type type,
+ bool use_json)
{
regex_t *regex;
int rc;
if (!config_bgp_aspath_validate(regstr)) {
- vty_out(vty, "Invalid character in as-path access-list %s\n",
+ vty_out(vty, "Invalid character in REGEX %s\n",
regstr);
return CMD_WARNING_CONFIG_FAILED;
}
@@ -10542,7 +10546,7 @@ static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
return CMD_WARNING;
}
- rc = bgp_show(vty, bgp, afi, safi, type, regex, 0);
+ rc = bgp_show(vty, bgp, afi, safi, type, regex, use_json);
bgp_regex_free(regex);
return rc;
}
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 04e01411a5..53d9732956 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -9711,23 +9711,6 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
uptime -= p->uptime;
epoch_tbuf = time(NULL) - uptime;
-#if CONFDATE > 20200101
- CPP_NOTICE(
- "bgpTimerUp should be deprecated and can be removed now");
-#endif
- /*
- * bgpTimerUp was miliseconds that was accurate
- * up to 1 day, then the value returned
- * became garbage. So in order to provide
- * some level of backwards compatability,
- * we still provde the data, but now
- * we are returning the correct value
- * and also adding a new bgpTimerUpMsec
- * which will allow us to deprecate
- * this eventually
- */
- json_object_int_add(json_neigh, "bgpTimerUp",
- uptime * 1000);
json_object_int_add(json_neigh, "bgpTimerUpMsec",
uptime * 1000);
json_object_string_add(json_neigh, "bgpTimerUpString",
diff --git a/configure.ac b/configure.ac
index a9784842e4..0694e3ed2c 100755
--- a/configure.ac
+++ b/configure.ac
@@ -331,14 +331,14 @@ if test "$enable_memory_sanitizer" = "yes"; then
AC_C_FLAG([-fsanitize=memory -fPIE -pie], [
AC_MSG_ERROR([$CC does not support Memory Sanitizer.])
], [
- SAN_FLAGS="-fsanitize=memory -fPIE -pie"
+ SAN_FLAGS="$SAN_FLAGS -fsanitize=memory -fPIE -pie"
])
fi
if test "$enable_undefined_sanitizer" = "yes"; then
AC_C_FLAG([-fsanitize=undefined], [
AC_MSG_ERROR([$CC does not support UndefinedBehaviorSanitizer.])
], [
- SAN_FLAGS="-fsanitize=undefined"
+ SAN_FLAGS="$SAN_FLAGS -fsanitize=undefined"
])
fi
AC_SUBST([SAN_FLAGS])
diff --git a/debian/README.Debian b/debian/README.Debian
index 47a353310d..cbd70f82f6 100644
--- a/debian/README.Debian
+++ b/debian/README.Debian
@@ -61,7 +61,7 @@ OpenSSL now is not compatible with the GNU GENERAL PUBLIC LICENSE (GPL)
licence that FRR is distributed under. For more explanation read:
http://www.gnome.org/~markmc/openssl-and-the-gpl.html
http://www.gnu.org/licenses/gpl-faq.html#GPLIncompatibleLibs
-Updating the licence to explecitly allow linking against OpenSSL
+Updating the licence to explicitly allow linking against OpenSSL
would requite the affirmation of all people that ever contributed
a significant part to Zebra / Quagga or FRR and thus are the collective
"copyright holder". That's too much work. Using a shrinked down
diff --git a/doc/user/pim.rst b/doc/user/pim.rst
index 9267095b3e..6bda692607 100644
--- a/doc/user/pim.rst
+++ b/doc/user/pim.rst
@@ -11,6 +11,13 @@ vrf aware and can work within the context of vrf's in order to
do S,G mrouting. Additionally PIM can be used in the EVPN underlay
network for optimizing forwarding of overlay BUM traffic.
+.. note::
+
+ On Linux for PIM-SM operation you *must* have kernel version 4.18 or greater.
+ To use PIM for EVPN BUM forwarding, kernels 5.0 or greater are required.
+ OpenBSD has no multicast support and FreeBSD, NetBSD and Solaris only
+ have support for SSM.
+
.. _starting-and-stopping-pimd:
Starting and Stopping pimd
diff --git a/docker/centos-8/build.sh b/docker/centos-8/build.sh
index 968d5fe6c4..4a9918486c 100755
--- a/docker/centos-8/build.sh
+++ b/docker/centos-8/build.sh
@@ -17,7 +17,7 @@ docker build \
.
# Copy RPM package from container to host
-CONTAINER_ID="$(docker create "frr:centos-builder-8-$GITREV")"
+CONTAINER_ID="$(docker create "frr:centos-8-builder-$GITREV")"
docker cp "${CONTAINER_ID}:/rpmbuild/RPMS/x86_64/" docker/centos-8/pkgs
docker rm "${CONTAINER_ID}"
diff --git a/isisd/isisd.c b/isisd/isisd.c
index f15d7a9c7e..47d2e9faab 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -107,13 +107,10 @@ struct isis_area *isis_area_create(const char *area_tag)
/*
* Fabricd runs only as level-2.
- * For IS-IS, the first instance is level-1-2 rest are level-1,
- * unless otherwise configured
+ * For IS-IS, the default is level-1-2
*/
- if (fabricd) {
+ if (fabricd)
area->is_type = IS_LEVEL_2;
- } else if (listcount(isis->area_list) == 0)
- area->is_type = IS_LEVEL_1_AND_2;
else
area->is_type = yang_get_default_enum(
"/frr-isisd:isis/instance/is-type");
diff --git a/lib/if.c b/lib/if.c
index c91407084e..7332dceb45 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -137,7 +137,12 @@ static int if_cmp_func(const struct interface *ifp1,
static int if_cmp_index_func(const struct interface *ifp1,
const struct interface *ifp2)
{
- return ifp1->ifindex - ifp2->ifindex;
+ if (ifp1->ifindex == ifp2->ifindex)
+ return 0;
+ else if (ifp1->ifindex > ifp2->ifindex)
+ return 1;
+ else
+ return -1;
}
static void ifp_connected_free(void *arg)
diff --git a/lib/zclient.c b/lib/zclient.c
index 6982d287a2..fd1b181e58 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -2679,6 +2679,17 @@ int zapi_labels_decode(struct stream *s, struct zapi_labels *zl)
}
STREAM_GETW(s, zl->nexthop_num);
+
+ if (zl->nexthop_num > MULTIPATH_NUM) {
+ flog_warn(
+ EC_LIB_ZAPI_ENCODE,
+ "%s: Prefix %pFX has %d nexthops, but we can only use the first %d",
+ __func__, &zl->route.prefix, zl->nexthop_num,
+ MULTIPATH_NUM);
+ }
+
+ zl->nexthop_num = MIN(MULTIPATH_NUM, zl->nexthop_num);
+
for (int i = 0; i < zl->nexthop_num; i++) {
znh = &zl->nexthops[i];
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index be3b83bf80..670bc6f4c9 100644
--- a/redhat/frr.spec.in
+++ b/redhat/frr.spec.in
@@ -444,7 +444,7 @@ zebra_spec_add_service ()
{
# Add port /etc/services entry if it isn't already there
if [ -f %{_sysconfdir}/services ] && \
- ! %__sed -e 's/#.*$//' %{_sysconfdir}/services | %__grep -wq $1 ; then
+ ! %__sed -e 's/#.*$//' %{_sysconfdir}/services 2>/dev/null | %__grep -wq $1 ; then
echo "$1 $2 # $3" >> %{_sysconfdir}/services
fi
}
diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang
index faa880eff4..faab1e55b2 100644
--- a/yang/frr-isisd.yang
+++ b/yang/frr-isisd.yang
@@ -27,6 +27,10 @@ module frr-isisd {
description
"This module defines a model for managing FRR isisd daemon.";
+ revision 2019-12-17 {
+ description
+ "Changed default area is-type to level-1-2";
+ }
revision 2019-09-09 {
description
"Changed interface references to use
@@ -748,7 +752,7 @@ module frr-isisd {
leaf is-type {
type level;
- default "level-1";
+ default "level-1-2";
description
"Level of the IS-IS routing instance (OSI only).";
}
diff --git a/zebra/debug.c b/zebra/debug.c
index 8e5fb0ea10..681dfb8753 100644
--- a/zebra/debug.c
+++ b/zebra/debug.c
@@ -39,6 +39,7 @@ unsigned long zebra_debug_vxlan;
unsigned long zebra_debug_pw;
unsigned long zebra_debug_dplane;
unsigned long zebra_debug_mlag;
+unsigned long zebra_debug_nexthop;
DEFINE_HOOK(zebra_debug_show_debugging, (struct vty *vty), (vty));
@@ -103,6 +104,10 @@ DEFUN_NOSH (show_debugging_zebra,
vty_out(vty, " Zebra dataplane debugging is on\n");
if (IS_ZEBRA_DEBUG_MLAG)
vty_out(vty, " Zebra mlag debugging is on\n");
+ if (IS_ZEBRA_DEBUG_NHG_DETAIL)
+ vty_out(vty, "Zebra detailed nexthop debugging is on\n");
+ else if (IS_ZEBRA_DEBUG_NHG)
+ vty_out(vty, "Zebra nexthop debugging is on\n");
hook_call(zebra_debug_show_debugging, vty);
return CMD_SUCCESS;
@@ -443,6 +448,28 @@ DEFUN (no_debug_zebra_dplane,
return CMD_SUCCESS;
}
+DEFPY (debug_zebra_nexthop,
+ debug_zebra_nexthop_cmd,
+ "[no$no] debug zebra nexthop [detail$detail]",
+ NO_STR
+ DEBUG_STR
+ "Zebra configuration\n"
+ "Debug zebra nexthop events\n"
+ "Detailed information\n")
+{
+ if (no)
+ zebra_debug_nexthop = 0;
+ else {
+ SET_FLAG(zebra_debug_nexthop, ZEBRA_DEBUG_NHG);
+
+ if (detail)
+ SET_FLAG(zebra_debug_nexthop,
+ ZEBRA_DEBUG_NHG_DETAILED);
+ }
+
+ return CMD_SUCCESS;
+}
+
/* Debug node. */
struct cmd_node debug_node = {DEBUG_NODE, "", /* Debug node has no interface. */
1};
@@ -546,6 +573,7 @@ void zebra_debug_init(void)
zebra_debug_dplane = 0;
zebra_debug_mlag = 0;
zebra_debug_nht = 0;
+ zebra_debug_nexthop = 0;
install_node(&debug_node, config_write_debug);
@@ -563,6 +591,7 @@ void zebra_debug_init(void)
install_element(ENABLE_NODE, &debug_zebra_fpm_cmd);
install_element(ENABLE_NODE, &debug_zebra_dplane_cmd);
install_element(ENABLE_NODE, &debug_zebra_mlag_cmd);
+ install_element(ENABLE_NODE, &debug_zebra_nexthop_cmd);
install_element(ENABLE_NODE, &no_debug_zebra_events_cmd);
install_element(ENABLE_NODE, &no_debug_zebra_nht_cmd);
install_element(ENABLE_NODE, &no_debug_zebra_mpls_cmd);
@@ -585,6 +614,7 @@ void zebra_debug_init(void)
install_element(CONFIG_NODE, &debug_zebra_rib_cmd);
install_element(CONFIG_NODE, &debug_zebra_fpm_cmd);
install_element(CONFIG_NODE, &debug_zebra_dplane_cmd);
+ install_element(CONFIG_NODE, &debug_zebra_nexthop_cmd);
install_element(CONFIG_NODE, &no_debug_zebra_events_cmd);
install_element(CONFIG_NODE, &no_debug_zebra_nht_cmd);
install_element(CONFIG_NODE, &no_debug_zebra_mpls_cmd);
diff --git a/zebra/debug.h b/zebra/debug.h
index 176226f7ae..e513f8865d 100644
--- a/zebra/debug.h
+++ b/zebra/debug.h
@@ -59,6 +59,9 @@ extern "C" {
#define ZEBRA_DEBUG_MLAG 0x01
+#define ZEBRA_DEBUG_NHG 0x01
+#define ZEBRA_DEBUG_NHG_DETAILED 0x02
+
/* Debug related macro. */
#define IS_ZEBRA_DEBUG_EVENT (zebra_debug_event & ZEBRA_DEBUG_EVENT)
@@ -92,6 +95,11 @@ extern "C" {
#define IS_ZEBRA_DEBUG_MLAG (zebra_debug_mlag & ZEBRA_DEBUG_MLAG)
+#define IS_ZEBRA_DEBUG_NHG (zebra_debug_nexthop & ZEBRA_DEBUG_NHG)
+
+#define IS_ZEBRA_DEBUG_NHG_DETAIL \
+ (zebra_debug_nexthop & ZEBRA_DEBUG_NHG_DETAILED)
+
extern unsigned long zebra_debug_event;
extern unsigned long zebra_debug_packet;
extern unsigned long zebra_debug_kernel;
@@ -103,6 +111,7 @@ extern unsigned long zebra_debug_vxlan;
extern unsigned long zebra_debug_pw;
extern unsigned long zebra_debug_dplane;
extern unsigned long zebra_debug_mlag;
+extern unsigned long zebra_debug_nexthop;
extern void zebra_debug_init(void);
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index c09007bcb1..4731d1ed15 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -366,7 +366,7 @@ static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb,
}
}
-static int get_iflink_speed(struct interface *interface, int *error)
+static uint32_t get_iflink_speed(struct interface *interface, int *error)
{
struct ifreq ifdata;
struct ethtool_cmd ecmd;
@@ -419,7 +419,7 @@ static int get_iflink_speed(struct interface *interface, int *error)
close(sd);
- return (ecmd.speed_hi << 16) | ecmd.speed;
+ return ((uint32_t)ecmd.speed_hi << 16) | ecmd.speed;
}
uint32_t kernel_get_speed(struct interface *ifp, int *error)
@@ -1467,7 +1467,7 @@ int netlink_protodown(struct interface *ifp, bool down)
req.ifa.ifi_index = ifp->ifindex;
- addattr_l(&req.n, sizeof(req), IFLA_PROTO_DOWN, &down, 4);
+ addattr_l(&req.n, sizeof(req), IFLA_PROTO_DOWN, &down, sizeof(down));
addattr_l(&req.n, sizeof(req), IFLA_LINK, &ifp->ifindex, 4);
return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns,
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index 23f1a3bf86..c3d5bf8428 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -290,6 +290,18 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id,
return netlink_neigh_change(h, ns_id);
case RTM_DELNEIGH:
return netlink_neigh_change(h, ns_id);
+ case RTM_GETNEIGH:
+ /*
+ * Kernel in some situations when it expects
+ * user space to resolve arp entries, we will
+ * receive this notification. As we don't
+ * need this notification and as that
+ * we don't want to spam the log file with
+ * below messages, just ignore.
+ */
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("Received RTM_GETNEIGH, ignoring");
+ break;
case RTM_NEWRULE:
return netlink_rule_change(h, ns_id, startup);
case RTM_DELRULE:
@@ -1086,7 +1098,7 @@ int netlink_request(struct nlsock *nl, struct nlmsghdr *n)
netlink_socket (). */
void kernel_init(struct zebra_ns *zns)
{
- unsigned long groups;
+ uint32_t groups;
#if defined SOL_NETLINK
int one, ret;
#endif
@@ -1107,9 +1119,9 @@ void kernel_init(struct zebra_ns *zns)
RTMGRP_IPV6_IFADDR |
RTMGRP_IPV4_MROUTE |
RTMGRP_NEIGH |
- (1 << (RTNLGRP_IPV4_RULE - 1)) |
- (1 << (RTNLGRP_IPV6_RULE - 1)) |
- (1 << (RTNLGRP_NEXTHOP - 1));
+ ((uint32_t) 1 << (RTNLGRP_IPV4_RULE - 1)) |
+ ((uint32_t) 1 << (RTNLGRP_IPV6_RULE - 1)) |
+ ((uint32_t) 1 << (RTNLGRP_NEXTHOP - 1));
snprintf(zns->netlink.name, sizeof(zns->netlink.name),
"netlink-listen (NS %u)", zns->ns_id);
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index fff569c092..29a341abbd 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -787,34 +787,10 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
} else {
if (!tb[RTA_MULTIPATH]) {
struct nexthop nh;
- size_t sz = (afi == AFI_IP) ? 4 : 16;
-
- memset(&nh, 0, sizeof(nh));
- if (bh_type == BLACKHOLE_UNSPEC) {
- if (index && !gate)
- nh.type = NEXTHOP_TYPE_IFINDEX;
- else if (index && gate)
- nh.type =
- (afi == AFI_IP)
- ? NEXTHOP_TYPE_IPV4_IFINDEX
- : NEXTHOP_TYPE_IPV6_IFINDEX;
- else if (!index && gate)
- nh.type =
- (afi == AFI_IP)
- ? NEXTHOP_TYPE_IPV4
- : NEXTHOP_TYPE_IPV6;
- else {
- nh.type =
- NEXTHOP_TYPE_BLACKHOLE;
- nh.bh_type = BLACKHOLE_UNSPEC;
- }
- } else {
- nh.type = NEXTHOP_TYPE_BLACKHOLE;
- nh.bh_type = bh_type;
- }
- nh.ifindex = index;
- if (gate)
- memcpy(&nh.gate, gate, sz);
+
+ nh = parse_nexthop_unicast(
+ ns_id, rtm, tb, bh_type, index, prefsrc,
+ gate, afi, vrf_id);
rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0,
flags, &p, &src_p, &nh, 0, table,
metric, distance, true);
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 5dd6012f62..e9a97d4b15 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -965,16 +965,25 @@ static void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int enable)
ifindex_t ifindex;
struct interface *ifp;
struct zebra_if *zif;
- int ra_interval;
+ int ra_interval_rxd;
s = msg;
/* Get interface index and RA interval. */
STREAM_GETL(s, ifindex);
- STREAM_GETL(s, ra_interval);
+ STREAM_GETL(s, ra_interval_rxd);
+
+ if (ra_interval_rxd < 0) {
+ zlog_warn(
+ "Requested RA interval %d is garbage; ignoring request",
+ ra_interval_rxd);
+ return;
+ }
+
+ unsigned int ra_interval = ra_interval_rxd;
if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("%u: IF %u RA %s from client %s, interval %ds",
+ zlog_debug("%u: IF %u RA %s from client %s, interval %ums",
zvrf_id(zvrf), ifindex,
enable ? "enable" : "disable",
zebra_route_string(client->proto), ra_interval);
@@ -1001,7 +1010,7 @@ static void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int enable)
SET_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED);
ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
if (ra_interval
- && (ra_interval * 1000) < zif->rtadv.MaxRtrAdvInterval
+ && (ra_interval * 1000) < (unsigned int) zif->rtadv.MaxRtrAdvInterval
&& !CHECK_FLAG(zif->rtadv.ra_configured,
VTY_RA_INTERVAL_CONFIGURED))
zif->rtadv.MaxRtrAdvInterval = ra_interval * 1000;
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 095d918b0a..7866ac58f4 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -2136,6 +2136,7 @@ static void zread_pseudowire(ZAPI_HANDLER_ARGS)
/* Get data. */
STREAM_GET(ifname, s, IF_NAMESIZE);
+ ifname[IF_NAMESIZE - 1] = '\0';
STREAM_GETL(s, ifindex);
STREAM_GETL(s, type);
STREAM_GETL(s, af);
@@ -2360,6 +2361,20 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
if (zpr.rule.filter.fwmark)
zpr.rule.filter.filter_bm |= PBR_FILTER_FWMARK;
+ if (!(zpr.rule.filter.src_ip.family == AF_INET
+ || zpr.rule.filter.src_ip.family == AF_INET6)) {
+ zlog_warn("Unsupported PBR source IP family: %s\n",
+ family2str(zpr.rule.filter.src_ip.family));
+ return;
+ }
+ if (!(zpr.rule.filter.dst_ip.family == AF_INET
+ || zpr.rule.filter.dst_ip.family == AF_INET6)) {
+ zlog_warn("Unsupported PBR dest IP family: %s\n",
+ family2str(zpr.rule.filter.dst_ip.family));
+ return;
+ }
+
+
zpr.vrf_id = zvrf->vrf->vrf_id;
if (hdr->command == ZEBRA_RULE_ADD)
zebra_pbr_add_rule(&zpr);
@@ -2416,6 +2431,7 @@ static inline void zread_ipset_entry(ZAPI_HANDLER_ARGS)
zpi.sock = client->sock;
STREAM_GETL(s, zpi.unique);
STREAM_GET(&ipset.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
+ ipset.ipset_name[ZEBRA_IPSET_NAME_SIZE - 1] = '\0';
STREAM_GETC(s, zpi.src.family);
STREAM_GETC(s, zpi.src.prefixlen);
STREAM_GET(&zpi.src.u.prefix, s, prefix_blen(&zpi.src));
@@ -2466,37 +2482,39 @@ stream_failure:
static inline void zread_iptable(ZAPI_HANDLER_ARGS)
{
- struct zebra_pbr_iptable zpi;
+ struct zebra_pbr_iptable *zpi =
+ XCALLOC(MTYPE_TMP, sizeof(struct zebra_pbr_iptable));
struct stream *s;
s = msg;
- memset(&zpi, 0, sizeof(zpi));
-
- zpi.interface_name_list = list_new();
- zpi.sock = client->sock;
- zpi.vrf_id = zvrf->vrf->vrf_id;
- STREAM_GETL(s, zpi.unique);
- STREAM_GETL(s, zpi.type);
- STREAM_GETL(s, zpi.filter_bm);
- STREAM_GETL(s, zpi.action);
- STREAM_GETL(s, zpi.fwmark);
- STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
- STREAM_GETW(s, zpi.pkt_len_min);
- STREAM_GETW(s, zpi.pkt_len_max);
- STREAM_GETW(s, zpi.tcp_flags);
- STREAM_GETW(s, zpi.tcp_mask_flags);
- STREAM_GETC(s, zpi.dscp_value);
- STREAM_GETC(s, zpi.fragment);
- STREAM_GETC(s, zpi.protocol);
- STREAM_GETL(s, zpi.nb_interface);
- zebra_pbr_iptable_update_interfacelist(s, &zpi);
+ zpi->interface_name_list = list_new();
+ zpi->sock = client->sock;
+ zpi->vrf_id = zvrf->vrf->vrf_id;
+ STREAM_GETL(s, zpi->unique);
+ STREAM_GETL(s, zpi->type);
+ STREAM_GETL(s, zpi->filter_bm);
+ STREAM_GETL(s, zpi->action);
+ STREAM_GETL(s, zpi->fwmark);
+ STREAM_GET(&zpi->ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
+ STREAM_GETW(s, zpi->pkt_len_min);
+ STREAM_GETW(s, zpi->pkt_len_max);
+ STREAM_GETW(s, zpi->tcp_flags);
+ STREAM_GETW(s, zpi->tcp_mask_flags);
+ STREAM_GETC(s, zpi->dscp_value);
+ STREAM_GETC(s, zpi->fragment);
+ STREAM_GETC(s, zpi->protocol);
+ STREAM_GETL(s, zpi->nb_interface);
+ zebra_pbr_iptable_update_interfacelist(s, zpi);
if (hdr->command == ZEBRA_IPTABLE_ADD)
- zebra_pbr_add_iptable(&zpi);
+ zebra_pbr_add_iptable(zpi);
else
- zebra_pbr_del_iptable(&zpi);
+ zebra_pbr_del_iptable(zpi);
+
stream_failure:
+ zebra_pbr_iptable_free(zpi);
+ zpi = NULL;
return;
}
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index e24d2e2b42..0c3adcdfa1 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -345,11 +345,13 @@ void zebra_pbr_iptable_free(void *arg)
iptable = (struct zebra_pbr_iptable *)arg;
hook_call(zebra_pbr_iptable_update, 0, iptable);
- for (ALL_LIST_ELEMENTS(iptable->interface_name_list,
- node, nnode, name)) {
- XFREE(MTYPE_PBR_IPTABLE_IFNAME, name);
- list_delete_node(iptable->interface_name_list,
- node);
+ if (iptable->interface_name_list) {
+ for (ALL_LIST_ELEMENTS(iptable->interface_name_list, node,
+ nnode, name)) {
+ XFREE(MTYPE_PBR_IPTABLE_IFNAME, name);
+ list_delete_node(iptable->interface_name_list, node);
+ }
+ list_delete(&iptable->interface_name_list);
}
XFREE(MTYPE_TMP, iptable);
}
@@ -688,6 +690,7 @@ void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable)
list_delete_node(iptable->interface_name_list,
node);
}
+ list_delete(&iptable->interface_name_list);
XFREE(MTYPE_TMP, lookup);
} else
zlog_debug("%s: IPTable being deleted we know nothing about",
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index 46f1385520..8640a4a720 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -1295,7 +1295,6 @@ static void zebra_ptm_send_bfdd(struct stream *msg)
}
stream_free(msgc);
- stream_free(msg);
}
static void zebra_ptm_send_clients(struct stream *msg)
@@ -1327,7 +1326,6 @@ static void zebra_ptm_send_clients(struct stream *msg)
}
stream_free(msgc);
- stream_free(msg);
}
static int _zebra_ptm_bfd_client_deregister(struct zserv *zs)
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 309b0f4301..051d7f5231 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -1898,11 +1898,6 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
/* Redistribute, lsp, and nht update */
redistribute_update(dest_pfx, src_pfx, re, NULL);
- zebra_rib_evaluate_rn_nexthops(
- rn, zebra_router_get_next_sequence());
-
- zebra_rib_evaluate_mpls(rn);
-
} else if (start_count > 0 && end_count == 0) {
if (debug_p)
zlog_debug("%u:%s un-installed transition from dplane notification",
@@ -1921,12 +1916,13 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
/* Redistribute, lsp, and nht update */
redistribute_delete(dest_pfx, src_pfx, re, NULL);
+ }
- zebra_rib_evaluate_rn_nexthops(
- rn, zebra_router_get_next_sequence());
+ /* Make any changes visible for lsp and nexthop-tracking processing */
+ zebra_rib_evaluate_rn_nexthops(
+ rn, zebra_router_get_next_sequence());
- zebra_rib_evaluate_mpls(rn);
- }
+ zebra_rib_evaluate_mpls(rn);
done:
if (rn)