summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--alpine/APKBUILD.in8
-rw-r--r--bgpd/bgp_rd.c7
-rw-r--r--bgpd/bgp_route.c31
-rw-r--r--bgpd/bgp_vty.c22
-rwxr-xr-xconfigure.ac11
-rw-r--r--doc/user/overview.rst2
-rw-r--r--docker/alpine/Dockerfile1
-rwxr-xr-xdocker/centos-8/build.sh2
-rw-r--r--lib/if.c7
-rw-r--r--lib/zclient.c11
-rw-r--r--pimd/pim_cmd.c40
-rw-r--r--pimd/pim_igmp.c6
-rw-r--r--pimd/pim_instance.h8
-rw-r--r--pimd/pim_msdp.c4
-rw-r--r--pimd/pim_nht.c5
-rw-r--r--pimd/pim_oil.c53
-rw-r--r--pimd/pim_oil.h9
-rw-r--r--pimd/pim_rp.c14
-rw-r--r--pimd/pim_upstream.c68
-rw-r--r--pimd/pim_upstream.h8
-rw-r--r--pimd/pim_zebra.c5
-rw-r--r--redhat/frr.spec.in2
-rw-r--r--zebra/if_netlink.c4
-rw-r--r--zebra/kernel_netlink.c8
-rw-r--r--zebra/rt_netlink.c32
-rw-r--r--zebra/zapi_msg.c49
-rw-r--r--zebra/zebra_pbr.c13
27 files changed, 184 insertions, 246 deletions
diff --git a/alpine/APKBUILD.in b/alpine/APKBUILD.in
index 1c579a8e7..f740a3458 100644
--- a/alpine/APKBUILD.in
+++ b/alpine/APKBUILD.in
@@ -17,7 +17,7 @@ makedepends="ncurses-dev net-snmp-dev gawk texinfo perl
linux-headers lzip lzo m4 make mkinitfs mpc1 mpfr4 mtools musl-dev
ncurses-libs ncurses-terminfo ncurses-terminfo-base patch pax-utils pcre
perl pkgconf python2 python2-dev readline readline-dev sqlite-libs
- squashfs-tools sudo tar texinfo xorriso xz-libs py-pip py-sphinx rtrlib
+ squashfs-tools sudo tar texinfo xorriso xz-libs py-pip rtrlib
rtrlib-dev"
checkdepends="pytest py-setuptools"
install="$pkgname.pre-install $pkgname.pre-deinstall $pkgname.post-deinstall"
@@ -34,6 +34,12 @@ _user=frr
build() {
cd "$builddir"
+
+ _localpythondir=$PWD/.python
+ pip2 install --prefix $_localpythondir sphinx
+ export PATH=${_localpythondir}/bin:$PATH
+ export PYTHONPATH=${_localpythondir}/lib/python2.7/site-packages
+
./configure \
--prefix=/usr \
--sbindir=$_sbindir \
diff --git a/bgpd/bgp_rd.c b/bgpd/bgp_rd.c
index 571139a49..be950dfa5 100644
--- a/bgpd/bgp_rd.c
+++ b/bgpd/bgp_rd.c
@@ -174,15 +174,16 @@ char *prefix_rd2str(struct prefix_rd *prd, char *buf, size_t size)
if (type == RD_TYPE_AS) {
decode_rd_as(pnt + 2, &rd_as);
- snprintf(buf, size, "%u:%d", rd_as.as, rd_as.val);
+ snprintf(buf, size, "%u:%" PRIu32, rd_as.as, rd_as.val);
return buf;
} else if (type == RD_TYPE_AS4) {
decode_rd_as4(pnt + 2, &rd_as);
- snprintf(buf, size, "%u:%d", rd_as.as, rd_as.val);
+ snprintf(buf, size, "%u:%" PRIu32, rd_as.as, rd_as.val);
return buf;
} else if (type == RD_TYPE_IP) {
decode_rd_ip(pnt + 2, &rd_ip);
- snprintf(buf, size, "%s:%d", inet_ntoa(rd_ip.ip), rd_ip.val);
+ snprintf(buf, size, "%s:%" PRIu16, inet_ntoa(rd_ip.ip),
+ rd_ip.val);
return buf;
}
#if ENABLE_BGP_VNC
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 64d7ce9e9..21d737fb3 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -9147,7 +9147,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 +9439,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 +10466,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 +10474,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 +10490,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 +10527,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 +10545,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 e875c4111..53d973295 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -2692,7 +2692,7 @@ DEFUN (bgp_listen_limit,
"bgp listen limit (1-5000)",
"BGP specific commands\n"
"BGP Dynamic Neighbors listen commands\n"
- "maximum number of BGP Dynamic Neighbors that can be created\n"
+ "Maximum number of BGP Dynamic Neighbors that can be created\n"
"Configure Dynamic Neighbors listen limit value\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
@@ -2712,8 +2712,7 @@ DEFUN (no_bgp_listen_limit,
NO_STR
"BGP specific commands\n"
"BGP Dynamic Neighbors listen commands\n"
- "unset maximum number of BGP Dynamic Neighbors that can be created\n"
- "Configure Dynamic Neighbors listen limit value to default\n"
+ "Maximum number of BGP Dynamic Neighbors that can be created\n"
"Configure Dynamic Neighbors listen limit value\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
@@ -9712,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 0bfcc833f..0694e3ed2 100755
--- a/configure.ac
+++ b/configure.ac
@@ -331,7 +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="$SAN_FLAGS -fsanitize=undefined"
])
fi
AC_SUBST([SAN_FLAGS])
@@ -576,6 +583,8 @@ AC_ARG_ENABLE([thread-sanitizer],
AS_HELP_STRING([--enable-thread-sanitizer], [enable ThreadSanitizer support for detecting data races]))
AC_ARG_ENABLE([memory-sanitizer],
AS_HELP_STRING([--enable-memory-sanitizer], [enable MemorySanitizer support for detecting uninitialized memory reads]))
+AC_ARG_ENABLE([undefined-sanitizer],
+ AS_HELP_STRING([--undefined-sanitizer], [enable UndefinedBehaviorSanitizer support for detecting undefined behavior]))
AC_ARG_WITH([crypto],
AS_HELP_STRING([--with-crypto=<internal|openssl>], [choose between different implementations of cryptographic functions(default value is --with-crypto=internal)]))
diff --git a/doc/user/overview.rst b/doc/user/overview.rst
index 2b2ffdf0f..262c0117d 100644
--- a/doc/user/overview.rst
+++ b/doc/user/overview.rst
@@ -310,6 +310,8 @@ BGP
:t:`BGP Large Communities Attribute. J. Heitz, Ed., J. Snijders, Ed, K. Patel, I. Bagdonas, N. Hilliard. February 2017`
- :rfc:`8195`
:t:`Use of BGP Large Communities. J. Snijders, J. Heasley, M. Schmidt, June 2017`
+- :rfc:`8212`
+ :t:`Default External BGP (EBGP) Route Propagation Behavior without Policies. J. Mauch, J. Snijders, G. Hankins. July 2017`
- :rfc:`8277`
:t:`Using BGP to Bind MPLS Labels to Address Prefixes. E. Rosen. October 2017`
diff --git a/docker/alpine/Dockerfile b/docker/alpine/Dockerfile
index 88c8f88f8..ed6453e2b 100644
--- a/docker/alpine/Dockerfile
+++ b/docker/alpine/Dockerfile
@@ -42,6 +42,7 @@ USER builder
RUN cd /dist \
&& abuild-keygen -a -n \
&& abuild checksum \
+ && git init \
&& abuild -r -P /pkgs/apk
# This stage installs frr from the apk
diff --git a/docker/centos-8/build.sh b/docker/centos-8/build.sh
index 968d5fe6c..4a9918486 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/lib/if.c b/lib/if.c
index c91407084..7332dceb4 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 6982d287a..fd1b181e5 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/pimd/pim_cmd.c b/pimd/pim_cmd.c
index d165cca08..01bebebd2 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -914,7 +914,6 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
struct in_addr ifaddr;
struct interface *ifp;
struct listnode *neighnode;
- struct listnode *upnode;
struct pim_interface *pim_ifp;
struct pim_neighbor *neigh;
struct pim_upstream *up;
@@ -1052,8 +1051,7 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
pim_ifp->pim_dr_election_changes);
// FHR
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
- up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
if (ifp != up->rpf.source_nexthop.interface)
continue;
@@ -1215,8 +1213,7 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
// FHR
print_header = 1;
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
- up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
if (!up->rpf.source_nexthop.interface)
continue;
@@ -1386,7 +1383,6 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
bool uj)
{
struct interface *ifp;
- struct listnode *upnode;
struct pim_interface *pim_ifp;
struct pim_upstream *up;
int fhr = 0;
@@ -1408,7 +1404,7 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
pim_ifchannels = pim_if_ifchannel_count(pim_ifp);
fhr = 0;
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up))
+ frr_each (rb_pim_upstream, &pim->upstream_head, up)
if (ifp == up->rpf.source_nexthop.interface)
if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
fhr++;
@@ -1975,7 +1971,6 @@ static void pim_show_state(struct pim_instance *pim, struct vty *vty,
const char *src_or_group, const char *group, bool uj)
{
struct channel_oil *c_oil;
- struct listnode *node;
json_object *json = NULL;
json_object *json_group = NULL;
json_object *json_ifp_in = NULL;
@@ -1994,7 +1989,7 @@ static void pim_show_state(struct pim_instance *pim, struct vty *vty,
"\nActive Source Group RPT IIF OIL\n");
}
- for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
+ frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
char grp_str[INET_ADDRSTRLEN];
char src_str[INET_ADDRSTRLEN];
char in_ifname[INTERFACE_NAMSIZ + 1];
@@ -2429,7 +2424,6 @@ static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
struct prefix_sg *sg, bool uj)
{
- struct listnode *upnode;
struct pim_upstream *up;
time_t now;
json_object *json = NULL;
@@ -2444,7 +2438,7 @@ static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
vty_out(vty,
"Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
char src_str[INET_ADDRSTRLEN];
char grp_str[INET_ADDRSTRLEN];
char uptime[10];
@@ -2716,7 +2710,6 @@ static void pim_show_join_desired_helper(struct pim_instance *pim,
static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
bool uj)
{
- struct listnode *upnode;
struct pim_upstream *up;
json_object *json = NULL;
@@ -2727,7 +2720,7 @@ static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
vty_out(vty,
"Source Group EvalJD\n");
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
/* scan all interfaces */
pim_show_join_desired_helper(pim, vty, up,
json, uj);
@@ -2743,7 +2736,6 @@ static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
bool uj)
{
- struct listnode *upnode;
struct pim_upstream *up;
json_object *json = NULL;
json_object *json_group = NULL;
@@ -2755,7 +2747,7 @@ static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
vty_out(vty,
"Source Group RpfIface RibNextHop RpfAddress \n");
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
char src_str[INET_ADDRSTRLEN];
char grp_str[INET_ADDRSTRLEN];
char rpf_nexthop_str[PREFIX_STRLEN];
@@ -2876,7 +2868,6 @@ static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
{
- struct listnode *up_node;
struct pim_upstream *up;
time_t now = pim_time_monotonic_sec();
json_object *json = NULL;
@@ -2893,7 +2884,7 @@ static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
"Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
}
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, up_node, up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
char src_str[INET_ADDRSTRLEN];
char grp_str[INET_ADDRSTRLEN];
char rpf_addr_str[PREFIX_STRLEN];
@@ -3933,11 +3924,8 @@ static void clear_mroute(struct pim_instance *pim)
}
/* clean up all upstreams*/
- if (pim->upstream_list) {
- while (pim->upstream_list->count) {
- up = listnode_head(pim->upstream_list);
- pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
- }
+ while ((up = rb_pim_upstream_first(&pim->upstream_head))) {
+ pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
}
}
@@ -5420,7 +5408,7 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty,
now = pim_time_monotonic_sec();
/* print list of PIM and IGMP routes */
- for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
+ frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
found_oif = 0;
first = 1;
if (!c_oil->installed && !uj)
@@ -5828,7 +5816,7 @@ DEFUN (clear_ip_mroute_count,
return CMD_WARNING;
pim = vrf->info;
- for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
+ frr_each(rb_pim_oil, &pim->channel_oil_head, c_oil) {
if (!c_oil->installed)
continue;
@@ -5863,7 +5851,7 @@ static void show_mroute_count(struct pim_instance *pim, struct vty *vty)
"Source Group LastUsed Packets Bytes WrongIf \n");
/* Print PIM and IGMP route counts */
- for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
+ frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
char group_str[INET_ADDRSTRLEN];
char source_str[INET_ADDRSTRLEN];
@@ -5968,7 +5956,7 @@ static void show_mroute_summary(struct pim_instance *pim, struct vty *vty)
vty_out(vty, "Mroute Type Installed/Total\n");
- for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
+ frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
if (!c_oil->installed) {
if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
starg_sw_mroute_cnt++;
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index 54ad17a99..39ef706f7 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -1113,8 +1113,10 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
}
if (pim_is_group_224_0_0_0_24(group_addr)) {
- zlog_warn("%s: Group specified is part of 224.0.0.0/24",
- __PRETTY_FUNCTION__);
+ if (PIM_DEBUG_IGMP_TRACE)
+ zlog_debug(
+ "%s: Group specified %s is part of 224.0.0.0/24",
+ __PRETTY_FUNCTION__, inet_ntoa(group_addr));
return NULL;
}
/*
diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h
index dd3ac8fcb..da0c75dec 100644
--- a/pimd/pim_instance.h
+++ b/pimd/pim_instance.h
@@ -28,6 +28,8 @@
#include "pim_assert.h"
#include "pim_bsm.h"
#include "pim_vxlan_instance.h"
+#include "pim_oil.h"
+#include "pim_upstream.h"
#if defined(HAVE_LINUX_MROUTE_H)
#include <linux/mroute.h>
@@ -107,8 +109,7 @@ struct pim_instance {
struct list *static_routes;
// Upstream vrf specific information
- struct list *upstream_list;
- struct hash *upstream_hash;
+ struct rb_pim_upstream_head upstream_head;
struct timer_wheel *upstream_sg_wheel;
/*
@@ -119,8 +120,7 @@ struct pim_instance {
int iface_vif_index[MAXVIFS];
- struct list *channel_oil_list;
- struct hash *channel_oil_hash;
+ struct rb_pim_oil_head channel_oil_head;
struct pim_msdp msdp;
struct pim_vxlan_instance vxlan;
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index 8a18594fd..58ebc6ce6 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -565,11 +565,9 @@ void pim_msdp_sa_local_update(struct pim_upstream *up)
static void pim_msdp_sa_local_setup(struct pim_instance *pim)
{
struct pim_upstream *up;
- struct listnode *up_node;
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, up_node, up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up)
pim_msdp_sa_local_update(up);
- }
}
/* whenever the RP changes we need to re-evaluate the "local" SA-cache */
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index bd8424b3e..5cb9492ec 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -177,7 +177,6 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
struct pim_nexthop_cache *pnc = NULL;
struct pim_nexthop_cache lookup;
struct zclient *zclient = NULL;
- struct listnode *upnode = NULL;
struct pim_upstream *upstream = NULL;
zclient = pim_zebra_zclient_get();
@@ -190,8 +189,8 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
/* Release the (*, G)upstream from pnc->upstream_hash,
* whose Group belongs to the RP getting deleted
*/
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
- upstream)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head,
+ upstream) {
struct prefix grp;
struct rp_info *trp_info;
diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c
index 65c6bdd2b..598988f88 100644
--- a/pimd/pim_oil.c
+++ b/pimd/pim_oil.c
@@ -64,8 +64,8 @@ char *pim_channel_oil_dump(struct channel_oil *c_oil, char *buf, size_t size)
return buf;
}
-static int pim_channel_oil_compare(struct channel_oil *c1,
- struct channel_oil *c2)
+int pim_channel_oil_compare(const struct channel_oil *c1,
+ const struct channel_oil *c2)
{
if (ntohl(c1->oil.mfcc_mcastgrp.s_addr)
< ntohl(c2->oil.mfcc_mcastgrp.s_addr))
@@ -86,48 +86,19 @@ static int pim_channel_oil_compare(struct channel_oil *c1,
return 0;
}
-static bool pim_oil_equal(const void *arg1, const void *arg2)
-{
- const struct channel_oil *c1 = (const struct channel_oil *)arg1;
- const struct channel_oil *c2 = (const struct channel_oil *)arg2;
-
- if ((c1->oil.mfcc_mcastgrp.s_addr == c2->oil.mfcc_mcastgrp.s_addr)
- && (c1->oil.mfcc_origin.s_addr == c2->oil.mfcc_origin.s_addr))
- return true;
-
- return false;
-}
-
-static unsigned int pim_oil_hash_key(const void *arg)
-{
- const struct channel_oil *oil = arg;
-
- return jhash_2words(oil->oil.mfcc_mcastgrp.s_addr,
- oil->oil.mfcc_origin.s_addr, 0);
-}
-
void pim_oil_init(struct pim_instance *pim)
{
- char hash_name[64];
-
- snprintf(hash_name, 64, "PIM %s Oil Hash", pim->vrf->name);
- pim->channel_oil_hash = hash_create_size(8192, pim_oil_hash_key,
- pim_oil_equal, hash_name);
-
- pim->channel_oil_list = list_new();
- pim->channel_oil_list->del = (void (*)(void *))pim_channel_oil_free;
- pim->channel_oil_list->cmp =
- (int (*)(void *, void *))pim_channel_oil_compare;
+ rb_pim_oil_init(&pim->channel_oil_head);
}
void pim_oil_terminate(struct pim_instance *pim)
{
- if (pim->channel_oil_list)
- list_delete(&pim->channel_oil_list);
+ struct channel_oil *c_oil;
+
+ while ((c_oil = rb_pim_oil_pop(&pim->channel_oil_head)))
+ pim_channel_oil_free(c_oil);
- if (pim->channel_oil_hash)
- hash_free(pim->channel_oil_hash);
- pim->channel_oil_hash = NULL;
+ rb_pim_oil_fini(&pim->channel_oil_head);
}
void pim_channel_oil_free(struct channel_oil *c_oil)
@@ -144,7 +115,7 @@ struct channel_oil *pim_find_channel_oil(struct pim_instance *pim,
lookup.oil.mfcc_mcastgrp = sg->grp;
lookup.oil.mfcc_origin = sg->src;
- c_oil = hash_lookup(pim->channel_oil_hash, &lookup);
+ c_oil = rb_pim_oil_find(&pim->channel_oil_head, &lookup);
return c_oil;
}
@@ -187,7 +158,6 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
c_oil->oil.mfcc_mcastgrp = sg->grp;
c_oil->oil.mfcc_origin = sg->src;
- c_oil = hash_get(pim->channel_oil_hash, c_oil, hash_alloc_intern);
c_oil->oil.mfcc_parent = MAXVIFS;
c_oil->oil_ref_count = 1;
@@ -195,7 +165,7 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
c_oil->up = pim_upstream_find(pim, sg);
c_oil->pim = pim;
- listnode_add_sort(pim->channel_oil_list, c_oil);
+ rb_pim_oil_add(&pim->channel_oil_head, c_oil);
if (PIM_DEBUG_MROUTE)
zlog_debug("%s(%s): c_oil %s add",
@@ -224,8 +194,7 @@ struct channel_oil *pim_channel_oil_del(struct channel_oil *c_oil,
* called by list_delete_all_node()
*/
c_oil->up = NULL;
- listnode_delete(c_oil->pim->channel_oil_list, c_oil);
- hash_release(c_oil->pim->channel_oil_hash, c_oil);
+ rb_pim_oil_del(&c_oil->pim->channel_oil_head, c_oil);
pim_channel_oil_free(c_oil);
return NULL;
diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h
index de7fde05d..788ddaa16 100644
--- a/pimd/pim_oil.h
+++ b/pimd/pim_oil.h
@@ -90,10 +90,13 @@ struct channel_counts {
installed: indicate if this entry is installed in the kernel.
*/
+PREDECL_RBTREE_UNIQ(rb_pim_oil)
struct channel_oil {
struct pim_instance *pim;
+ struct rb_pim_oil_item oil_rb;
+
struct mfcctl oil;
int installed;
int oil_inherited_rescan;
@@ -106,6 +109,12 @@ struct channel_oil {
time_t mroute_creation;
};
+extern int pim_channel_oil_compare(const struct channel_oil *c1,
+ const struct channel_oil *c2);
+DECLARE_RBTREE_UNIQ(rb_pim_oil, struct channel_oil, oil_rb,
+ pim_channel_oil_compare)
+
+
extern struct list *pim_channel_oil_list;
void pim_oil_init(struct pim_instance *pim);
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index bd295b0fe..2db39bac4 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -446,7 +446,6 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
struct prefix nht_p;
struct route_node *rn;
struct pim_upstream *up;
- struct listnode *upnode;
if (rp_addr.s_addr == INADDR_ANY ||
rp_addr.s_addr == INADDR_NONE)
@@ -554,8 +553,7 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
__PRETTY_FUNCTION__, buf, buf1);
}
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
- up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
/* Find (*, G) upstream whose RP is not
* configured yet
*/
@@ -650,7 +648,7 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
rn->lock);
}
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
if (up->sg.src.s_addr == INADDR_ANY) {
struct prefix grp;
struct rp_info *trp_info;
@@ -723,7 +721,6 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
bool was_plist = false;
struct rp_info *trp_info;
struct pim_upstream *up;
- struct listnode *upnode;
struct bsgrp_node *bsgrp = NULL;
struct bsm_rpinfo *bsrp = NULL;
char grp_str[PREFIX2STR_BUFFER];
@@ -800,7 +797,7 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
rp_all = pim_rp_find_match_group(pim, &g_all);
if (rp_all == rp_info) {
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
/* Find the upstream (*, G) whose upstream address is
* same as the deleted RP
*/
@@ -852,7 +849,7 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
pim_rp_refresh_group_to_rp_mapping(pim);
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
/* Find the upstream (*, G) whose upstream address is same as
* the deleted RP
*/
@@ -893,7 +890,6 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
int result = 0;
struct rp_info *rp_info = NULL;
struct pim_upstream *up;
- struct listnode *upnode;
rn = route_node_lookup(pim->rp_table, &group);
if (!rn) {
@@ -942,7 +938,7 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
listnode_add_sort(pim->rp_list, rp_info);
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
if (up->sg.src.s_addr == INADDR_ANY) {
struct prefix grp;
struct rp_info *trp_info;
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index a0387cdd4..afd10bd3d 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -98,7 +98,6 @@ static void pim_upstream_find_new_children(struct pim_instance *pim,
struct pim_upstream *up)
{
struct pim_upstream *child;
- struct listnode *ch_node;
if ((up->sg.src.s_addr != INADDR_ANY)
&& (up->sg.grp.s_addr != INADDR_ANY))
@@ -108,7 +107,7 @@ static void pim_upstream_find_new_children(struct pim_instance *pim,
&& (up->sg.grp.s_addr == INADDR_ANY))
return;
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, ch_node, child)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, child) {
if ((up->sg.grp.s_addr != INADDR_ANY)
&& (child->sg.grp.s_addr == up->sg.grp.s_addr)
&& (child != up)) {
@@ -191,9 +190,8 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
return up;
if (PIM_DEBUG_TRACE)
- zlog_debug(
- "pim_upstream free vrf:%s %s flags 0x%x",
- pim->vrf->name, up->sg_str, up->flags);
+ zlog_debug("pim_upstream free vrf:%s %s flags 0x%x",
+ pim->vrf->name, up->sg_str, up->flags);
THREAD_OFF(up->t_ka_timer);
THREAD_OFF(up->t_rs_timer);
@@ -235,8 +233,7 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
listnode_delete(up->parent->sources, up);
up->parent = NULL;
- listnode_delete(pim->upstream_list, up);
- hash_release(pim->upstream_hash, up);
+ rb_pim_upstream_del(&pim->upstream_head, up);
if (notify_msdp) {
pim_msdp_up_del(pim, &up->sg);
@@ -533,10 +530,9 @@ static int pim_upstream_could_register(struct pim_upstream *up)
* we re-revaluate register setup for existing upstream entries */
void pim_upstream_register_reevaluate(struct pim_instance *pim)
{
- struct listnode *upnode;
struct pim_upstream *up;
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
/* If FHR is set CouldRegister is True. Also check if the flow
* is actually active; if it is not kat setup will trigger
* source
@@ -639,9 +635,8 @@ void pim_upstream_update_use_rpt(struct pim_upstream *up,
void pim_upstream_reeval_use_rpt(struct pim_instance *pim)
{
struct pim_upstream *up;
- struct listnode *node;
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, node, up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
if (up->sg.src.s_addr == INADDR_ANY)
continue;
@@ -756,11 +751,9 @@ void pim_upstream_switch(struct pim_instance *pim, struct pim_upstream *up,
}
}
-int pim_upstream_compare(void *arg1, void *arg2)
+int pim_upstream_compare(const struct pim_upstream *up1,
+ const struct pim_upstream *up2)
{
- const struct pim_upstream *up1 = (const struct pim_upstream *)arg1;
- const struct pim_upstream *up2 = (const struct pim_upstream *)arg2;
-
if (ntohl(up1->sg.grp.s_addr) < ntohl(up2->sg.grp.s_addr))
return -1;
@@ -811,7 +804,7 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
if (ch)
ch->upstream = up;
- up = hash_get(pim->upstream_hash, up, hash_alloc_intern);
+ rb_pim_upstream_add(&pim->upstream_head, up);
/* Set up->upstream_addr as INADDR_ANY, if RP is not
* configured and retain the upstream data structure
*/
@@ -825,7 +818,8 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
up->parent = pim_upstream_find_parent(pim, up);
if (up->sg.src.s_addr == INADDR_ANY) {
up->sources = list_new();
- up->sources->cmp = pim_upstream_compare;
+ up->sources->cmp =
+ (int (*)(void *, void *))pim_upstream_compare;
} else
up->sources = NULL;
@@ -889,8 +883,6 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
}
}
- listnode_add_sort(pim->upstream_list, up);
-
if (PIM_DEBUG_PIM_TRACE) {
zlog_debug(
"%s: Created Upstream %s upstream_addr %s ref count %d increment",
@@ -908,7 +900,7 @@ struct pim_upstream *pim_upstream_find(struct pim_instance *pim,
struct pim_upstream *up = NULL;
lookup.sg = *sg;
- up = hash_lookup(pim->upstream_hash, &lookup);
+ up = rb_pim_upstream_find(&pim->upstream_head, &lookup);
return up;
}
@@ -1168,15 +1160,12 @@ void pim_upstream_update_join_desired(struct pim_instance *pim,
void pim_upstream_rpf_genid_changed(struct pim_instance *pim,
struct in_addr neigh_addr)
{
- struct listnode *up_node;
- struct listnode *up_nextnode;
struct pim_upstream *up;
/*
* Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
*/
- for (ALL_LIST_ELEMENTS(pim->upstream_list, up_node, up_nextnode, up)) {
-
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
if (PIM_DEBUG_PIM_TRACE) {
char neigh_str[INET_ADDRSTRLEN];
char rpf_addr_str[PREFIX_STRLEN];
@@ -1788,8 +1777,6 @@ int pim_upstream_empty_inherited_olist(struct pim_upstream *up)
*/
void pim_upstream_find_new_rpf(struct pim_instance *pim)
{
- struct listnode *up_node;
- struct listnode *up_nextnode;
struct pim_upstream *up;
struct pim_rpf old;
enum pim_rpf_result rpf_result;
@@ -1797,7 +1784,7 @@ void pim_upstream_find_new_rpf(struct pim_instance *pim)
/*
* Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
*/
- for (ALL_LIST_ELEMENTS(pim->upstream_list, up_node, up_nextnode, up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
if (up->upstream_addr.s_addr == INADDR_ANY) {
if (PIM_DEBUG_PIM_TRACE)
zlog_debug(
@@ -1837,18 +1824,11 @@ void pim_upstream_terminate(struct pim_instance *pim)
{
struct pim_upstream *up;
- if (pim->upstream_list) {
- while (pim->upstream_list->count) {
- up = listnode_head(pim->upstream_list);
- pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
- }
-
- list_delete(&pim->upstream_list);
+ while ((up = rb_pim_upstream_first(&pim->upstream_head))) {
+ pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
}
- if (pim->upstream_hash)
- hash_free(pim->upstream_hash);
- pim->upstream_hash = NULL;
+ rb_pim_upstream_fini(&pim->upstream_head);
if (pim->upstream_sg_wheel)
wheel_delete(pim->upstream_sg_wheel);
@@ -1991,9 +1971,8 @@ static void pim_upstream_sg_running(void *arg)
void pim_upstream_add_lhr_star_pimreg(struct pim_instance *pim)
{
struct pim_upstream *up;
- struct listnode *node;
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, node, up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
if (up->sg.src.s_addr != INADDR_ANY)
continue;
@@ -2031,7 +2010,6 @@ void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim,
const char *nlist)
{
struct pim_upstream *up;
- struct listnode *node;
struct prefix_list *np;
struct prefix g;
enum prefix_list_type apply_new;
@@ -2041,7 +2019,7 @@ void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim,
g.family = AF_INET;
g.prefixlen = IPV4_MAX_PREFIXLEN;
- for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, node, up)) {
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
if (up->sg.src.s_addr != INADDR_ANY)
continue;
@@ -2075,11 +2053,5 @@ void pim_upstream_init(struct pim_instance *pim)
wheel_init(router->master, 31000, 100, pim_upstream_hash_key,
pim_upstream_sg_running, name);
- snprintf(name, 64, "PIM %s Upstream Hash",
- pim->vrf->name);
- pim->upstream_hash = hash_create_size(8192, pim_upstream_hash_key,
- pim_upstream_equal, name);
-
- pim->upstream_list = list_new();
- pim->upstream_list->cmp = pim_upstream_compare;
+ rb_pim_upstream_init(&pim->upstream_head);
}
diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h
index ab5082051..1eb2052bb 100644
--- a/pimd/pim_upstream.h
+++ b/pimd/pim_upstream.h
@@ -169,6 +169,7 @@ enum pim_upstream_sptbit {
PIM_UPSTREAM_SPTBIT_TRUE
};
+PREDECL_RBTREE_UNIQ(rb_pim_upstream);
/*
Upstream (S,G) channel in Joined state
(S,G) in the "Not Joined" state is not represented
@@ -198,6 +199,7 @@ enum pim_upstream_sptbit {
*/
struct pim_upstream {
struct pim_instance *pim;
+ struct rb_pim_upstream_item upstream_rb;
struct pim_upstream *parent;
struct in_addr upstream_addr; /* Who we are talking to */
struct in_addr upstream_register; /*Who we received a register from*/
@@ -326,7 +328,11 @@ void pim_upstream_init(struct pim_instance *pim);
void pim_upstream_terminate(struct pim_instance *pim);
void join_timer_start(struct pim_upstream *up);
-int pim_upstream_compare(void *arg1, void *arg2);
+int pim_upstream_compare(const struct pim_upstream *up1,
+ const struct pim_upstream *up2);
+DECLARE_RBTREE_UNIQ(rb_pim_upstream, struct pim_upstream, upstream_rb,
+ pim_upstream_compare)
+
void pim_upstream_register_reevaluate(struct pim_instance *pim);
void pim_upstream_add_lhr_star_pimreg(struct pim_instance *pim);
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index 0417d0d06..06507b1f4 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -392,16 +392,13 @@ static void pim_zebra_vxlan_replay(void)
void pim_scan_oil(struct pim_instance *pim)
{
- struct listnode *node;
- struct listnode *nextnode;
struct channel_oil *c_oil;
pim->scan_oil_last = pim_time_monotonic_sec();
++pim->scan_oil_events;
- for (ALL_LIST_ELEMENTS(pim->channel_oil_list, node, nextnode, c_oil)) {
+ frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil)
pim_upstream_mroute_iif_update(c_oil, __func__);
- }
}
static int on_rpf_cache_refresh(struct thread *t)
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index be3b83bf8..670bc6f4c 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/zebra/if_netlink.c b/zebra/if_netlink.c
index c09007bcb..eae5d2b85 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)
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index 23f1a3bf8..3bceb5635 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -1086,7 +1086,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 +1107,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 fff569c09..29a341abb 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/zapi_msg.c b/zebra/zapi_msg.c
index 1dbe41f46..bb2e55c87 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);
@@ -2459,37 +2460,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 e24d2e2b4..0c3adcdfa 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",