summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_attr.c28
-rw-r--r--bgpd/bgp_route.c29
-rw-r--r--configure.ac6
-rw-r--r--doc/user/bgp.rst2
-rw-r--r--isisd/isis_te.c4
-rw-r--r--ospfclient/subdir.am3
-rwxr-xr-xtests/topotests/multicast_pim_dr_nondr_test/test_pim_dr_nondr_with_transit_router_topo3.py64
-rw-r--r--tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py65
-rw-r--r--tools/subdir.am11
-rw-r--r--zebra/zebra_nhg.c7
10 files changed, 169 insertions, 50 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 753db24b1b..d79ccf9644 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -2790,6 +2790,9 @@ static int bgp_attr_encap(struct bgp_attr_parser_args *args)
uint8_t type = args->type;
uint8_t flag = args->flags;
+ if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
+ goto encap_ignore;
+
if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
|| !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
zlog_err("Tunnel Encap attribute flag isn't optional and transitive %d",
@@ -2908,7 +2911,14 @@ static int bgp_attr_encap(struct bgp_attr_parser_args *args)
args->total);
}
- return 0;
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ENCAP));
+
+ return BGP_ATTR_PARSE_PROCEED;
+
+encap_ignore:
+ stream_forward_getp(peer->curr, length);
+
+ return bgp_attr_ignore(peer, type);
}
@@ -3300,6 +3310,9 @@ enum bgp_attr_parse_ret bgp_attr_prefix_sid(struct bgp_attr_parser_args *args)
size_t headersz = sizeof(type) + sizeof(length);
size_t psid_parsed_length = 0;
+ if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
+ goto prefix_sid_ignore;
+
while (STREAM_READABLE(peer->curr) > 0
&& psid_parsed_length < args->length) {
@@ -3347,6 +3360,11 @@ enum bgp_attr_parse_ret bgp_attr_prefix_sid(struct bgp_attr_parser_args *args)
SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID));
return BGP_ATTR_PARSE_PROCEED;
+
+prefix_sid_ignore:
+ stream_forward_getp(peer->curr, args->length);
+
+ return bgp_attr_ignore(peer, args->type);
}
/* PMSI tunnel attribute (RFC 6514)
@@ -3361,6 +3379,9 @@ bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args)
uint8_t tnl_type;
int attr_parse_len = 2 + BGP_LABEL_BYTES;
+ if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
+ goto pmsi_tunnel_ignore;
+
/* Verify that the receiver is expecting "ingress replication" as we
* can only support that.
*/
@@ -3397,6 +3418,11 @@ bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args)
stream_forward_getp(peer->curr, length - attr_parse_len);
return BGP_ATTR_PARSE_PROCEED;
+
+pmsi_tunnel_ignore:
+ stream_forward_getp(peer->curr, length);
+
+ return bgp_attr_ignore(peer, args->type);
}
/* AIGP attribute (rfc7311) */
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 49f3c77ada..3ff7dbc070 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -4783,22 +4783,21 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
false);
}
- if (peer->sort == BGP_PEER_EBGP) {
-
- /* rfc7999:
- * A BGP speaker receiving an announcement tagged with the
- * BLACKHOLE community SHOULD add the NO_ADVERTISE or
- * NO_EXPORT community as defined in RFC1997, or a
- * similar community, to prevent propagation of the
- * prefix outside the local AS. The community to prevent
- * propagation SHOULD be chosen according to the operator's
- * routing policy.
- */
- if (bgp_attr_get_community(&new_attr) &&
- community_include(bgp_attr_get_community(&new_attr),
- COMMUNITY_BLACKHOLE))
- bgp_attr_add_no_export_community(&new_attr);
+ /* rfc7999:
+ * A BGP speaker receiving an announcement tagged with the
+ * BLACKHOLE community SHOULD add the NO_ADVERTISE or
+ * NO_EXPORT community as defined in RFC1997, or a
+ * similar community, to prevent propagation of the
+ * prefix outside the local AS. The community to prevent
+ * propagation SHOULD be chosen according to the operator's
+ * routing policy.
+ */
+ if (bgp_attr_get_community(&new_attr) &&
+ community_include(bgp_attr_get_community(&new_attr),
+ COMMUNITY_BLACKHOLE))
+ bgp_attr_add_no_export_community(&new_attr);
+ if (peer->sort == BGP_PEER_EBGP) {
/* If we receive the graceful-shutdown community from an eBGP
* peer we must lower local-preference */
if (bgp_attr_get_community(&new_attr) &&
diff --git a/configure.ac b/configure.ac
index 885d5d1f5e..e1aa05b869 100644
--- a/configure.ac
+++ b/configure.ac
@@ -850,6 +850,9 @@ AC_ARG_WITH([frr-format],
AC_ARG_ENABLE([version_build_config],
AS_HELP_STRING([--disable-version-build-config], [do not include build configs in show version command]))
+AC_ARG_ENABLE([python_runtime],
+ AS_HELP_STRING([--disable-python-runtime], [do not install python scripts or have python runtime dependency]))
+
#if openssl, else use the internal
AS_IF([test "$with_crypto" = "openssl"], [
AC_CHECK_LIB([crypto], [EVP_DigestInit], [LIBS="$LIBS -lcrypto"], [], [])
@@ -2811,6 +2814,9 @@ AM_CONDITIONAL([PATHD], [test "$enable_pathd" != "no"])
AM_CONDITIONAL([PATHD_PCEP], [test "$enable_pathd" != "no"])
AM_CONDITIONAL([DP_DPDK], [test "$enable_dp_dpdk" = "yes"])
+
+AM_CONDITIONAL([PYTHON_RUNTIME_DEPENDENCY], [test "$enable_python_runtime" != "no"])
+
AC_CONFIG_FILES([Makefile],[
test "$enable_dev_build" = "yes" && makefile_devbuild="--dev-build"
${PYTHON} "${ac_abs_top_srcdir}/python/makefile.py" ${makefile_devbuild} || exit 1
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index a569a9af28..aa62d274f0 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -2482,7 +2482,7 @@ is 4 octet long. The following format is used to define the community value.
``blackhole``
``blackhole`` represents well-known communities value ``BLACKHOLE``
``0xFFFF029A`` ``65535:666``. :rfc:`7999` documents sending prefixes to
- EBGP peers and upstream for the purpose of blackholing traffic.
+ peers and upstream for the purpose of blackholing traffic.
Prefixes tagged with the this community should normally not be
re-advertised from neighbors of the originating network. Upon receiving
``BLACKHOLE`` community from a BGP speaker, ``NO_ADVERTISE`` community
diff --git a/isisd/isis_te.c b/isisd/isis_te.c
index b6321dbac3..a550d59387 100644
--- a/isisd/isis_te.c
+++ b/isisd/isis_te.c
@@ -172,6 +172,10 @@ void isis_link_params_update_asla(struct isis_circuit *circuit,
struct isis_ext_subtlvs *ext = circuit->ext;
int i;
+ if (!ext)
+ /* no extended subTLVs - nothing to update */
+ return;
+
if (!HAS_LINK_PARAMS(ifp)) {
list_delete_all_node(ext->aslas);
return;
diff --git a/ospfclient/subdir.am b/ospfclient/subdir.am
index 289ddd009d..2bf32544fd 100644
--- a/ospfclient/subdir.am
+++ b/ospfclient/subdir.am
@@ -7,10 +7,13 @@ lib_LTLIBRARIES += ospfclient/libfrrospfapiclient.la
noinst_PROGRAMS += ospfclient/ospfclient
#man8 += $(MANBUILD)/frr-ospfclient.8
+if PYTHON_RUNTIME_DEPENDENCY
sbin_SCRIPTS += \
ospfclient/ospfclient.py \
# end
endif
+endif
+
ospfclient_libfrrospfapiclient_la_LDFLAGS = $(LIB_LDFLAGS) -version-info 0:0:0
ospfclient_libfrrospfapiclient_la_LIBADD = lib/libfrr.la
diff --git a/tests/topotests/multicast_pim_dr_nondr_test/test_pim_dr_nondr_with_transit_router_topo3.py b/tests/topotests/multicast_pim_dr_nondr_test/test_pim_dr_nondr_with_transit_router_topo3.py
index 1987001002..8d91826022 100755
--- a/tests/topotests/multicast_pim_dr_nondr_test/test_pim_dr_nondr_with_transit_router_topo3.py
+++ b/tests/topotests/multicast_pim_dr_nondr_test/test_pim_dr_nondr_with_transit_router_topo3.py
@@ -25,6 +25,10 @@ import time
import datetime
from time import sleep
import pytest
+from functools import partial
+
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
# Save the Current Working Directory to find configuration files.
CWD = os.path.dirname(os.path.realpath(__file__))
@@ -594,6 +598,66 @@ def pre_config_for_source_dr_tests(
result = create_pim_config(tgen, topo, input_dict)
assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+ expected = {
+ "r2-s1-eth1.2501": {
+ "state": "up",
+ "address": "10.1.1.1",
+ "neighbors": {
+ "10.1.1.2": {
+ "address": "10.1.1.2",
+ }
+ },
+ "drAddress": "10.1.1.2",
+ }
+ }
+
+ step("Ensure that neighbors have come up on the vlan")
+ r2 = tgen.gears["r2"]
+ test_func = partial(
+ topotest.router_json_cmp,
+ r2,
+ "show ip pim interface r2-s1-eth1.2501 json",
+ expected,
+ )
+ result, _ = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assert result, "Neighbors did not come up: {}".format(result)
+
+ expected = {
+ "10.1.1.0/24": [
+ {
+ "prefix": "10.1.1.0/24",
+ "prefixLen": 24,
+ "protocol": "ospf",
+ "vrfName": "default",
+ "distance": 110,
+ "metric": 20,
+ "nexthops": [
+ {
+ "ip": "10.0.3.1",
+ "afi": "ipv4",
+ "interfaceName": "r5-r4-eth1",
+ "weight": 1,
+ },
+ {
+ "ip": "10.0.3.1",
+ "afi": "ipv4",
+ "interfaceName": "r5-r4-eth1",
+ "weight": 1,
+ },
+ ],
+ }
+ ]
+ }
+
+ step("Ensure that the vlan route is available where it is needed")
+ r5 = tgen.gears["r5"]
+ test_func = partial(
+ topotest.router_json_cmp, r5, "show ip route 10.1.1.0/24 json", expected
+ )
+
+ result, _ = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assert result, "vlan routes are not available on r5\n{}".format(result)
+
step("Configure IGMP on R5 port and send IGMP join for groups " "(226.1.1.1-5)")
intf_r5_i2 = topo["routers"]["r5"]["links"]["i2"]["interface"]
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py
index d981a84597..00d4e8ffdb 100644
--- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py
+++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py
@@ -704,11 +704,6 @@ def test_ospfv3_hello_tc10_p0(request):
tc_name, result
)
- step("verify that ospf neighbours are full")
- ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "Testcase {} [22]: Failed \n Error: {}".format(
- tc_name, ospf_covergence
- )
step(" Try configuring timer values outside range for example 65536")
topo1 = {
"r0": {
@@ -790,7 +785,9 @@ def test_ospfv3_dead_tc11_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [01]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step(
"verify that new timer value is configured and applied using "
@@ -799,7 +796,9 @@ def test_ospfv3_dead_tc11_p0(request):
dut = "r1"
input_dict = {"r1": {"links": {"r0": {"ospf6": {"timerIntervalsConfigDead": 48}}}}}
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [02]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("modify dead interval from default value to r1 dead interval timer on r2")
@@ -808,31 +807,35 @@ def test_ospfv3_dead_tc11_p0(request):
"links": {
"r1": {
"interface": topo["routers"]["r0"]["links"]["r1"]["interface"],
- "ospf6": {"dead_interval": 48, "hello_interval": 12},
+ "ospf6": {"hello_interval": 12, "dead_interval": 48},
}
}
}
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [03]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that new timer value is configured.")
input_dict = {"r0": {"links": {"r1": {"ospf6": {"timerIntervalsConfigDead": 48}}}}}
dut = "r0"
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [04]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "Testcase {} : Failed \n Error: {}".format(
+ assert ospf_covergence is True, "Testcase {} [05]: Failed \n Error: {}".format(
tc_name, ospf_covergence
)
step("remove ospf on R0")
ospf_del = {"r0": {"ospf6": {"delete": True}}}
result = create_router_ospf(tgen, topo, ospf_del)
- assert result is True, "Testcase : Failed \n Error: {}".format(result)
+ assert result is True, "Testcase [06]: Failed \n Error: {}".format(result)
# reconfiguring deleted ospf process by resetting the configs.
reset_config_on_routers(tgen)
@@ -850,7 +853,9 @@ def test_ospfv3_dead_tc11_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [07]: Failed \n Error: {}".format(
+ tc_name, result
+ )
topo1 = {
"r1": {
@@ -864,17 +869,21 @@ def test_ospfv3_dead_tc11_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [08]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that new timer value is configured.")
input_dict = {"r0": {"links": {"r1": {"ospf6": {"timerIntervalsConfigDead": 40}}}}}
dut = "r0"
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [09]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "Testcase {} : Failed \n Error: {}".format(
+ assert ospf_covergence is True, "Testcase {} [10]: Failed \n Error: {}".format(
tc_name, ospf_covergence
)
@@ -892,7 +901,9 @@ def test_ospfv3_dead_tc11_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [11]: Failed \n Error: {}".format(
+ tc_name, result
+ )
topo1 = {
"r1": {
@@ -906,7 +917,9 @@ def test_ospfv3_dead_tc11_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [12]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that new timer value is configured.")
input_dict = {
@@ -914,11 +927,13 @@ def test_ospfv3_dead_tc11_p0(request):
}
dut = "r0"
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [13]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "Testcase {} : Failed \n Error: {}".format(
+ assert ospf_covergence is True, "Testcase {} [14]: Failed \n Error: {}".format(
tc_name, ospf_covergence
)
@@ -937,7 +952,7 @@ def test_ospfv3_dead_tc11_p0(request):
result = create_interfaces_cfg(tgen, topo1)
assert (
result is not True
- ), "Testcase {} : Failed \n Create interface config failed. Error: {}".format(
+ ), "Testcase {} [15]: Failed \n Create interface config failed. Error: {}".format(
tc_name, result
)
@@ -956,13 +971,17 @@ def test_ospfv3_dead_tc11_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [16]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("Verify that timer value is deleted from intf & set to default value 40 sec.")
input_dict = {"r1": {"links": {"r0": {"ospf6": {"timerIntervalsConfigDead": 40}}}}}
dut = "r1"
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [17]: Failed \n Error: {}".format(
+ tc_name, result
+ )
write_test_footer(tc_name)
diff --git a/tools/subdir.am b/tools/subdir.am
index 64ca0bd514..f2ed2332b8 100644
--- a/tools/subdir.am
+++ b/tools/subdir.am
@@ -13,15 +13,20 @@ EXTRA_PROGRAMS += \
# end
sbin_PROGRAMS += tools/ssd
+
+if PYTHON_RUNTIME_DEPENDENCY
sbin_SCRIPTS += \
- tools/frr-reload \
tools/frr-reload.py \
+ tools/generate_support_bundle.py \
+ tools/frr_babeltrace.py
+endif
+
+sbin_SCRIPTS += \
+ tools/frr-reload \
tools/frr \
\
tools/frrcommon.sh \
tools/frrinit.sh \
- tools/generate_support_bundle.py \
- tools/frr_babeltrace.py \
tools/watchfrr.sh \
# end
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c
index 96807356d6..27b7f6340b 100644
--- a/zebra/zebra_nhg.c
+++ b/zebra/zebra_nhg.c
@@ -2656,13 +2656,6 @@ static unsigned nexthop_active_check(struct route_node *rn,
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
break;
case NEXTHOP_TYPE_IPV6:
- family = AFI_IP6;
- if (nexthop_active(nexthop, nhe, &rn->p, re->type, re->flags,
- &mtu, vrf_id))
- SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
- else
- UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
- break;
case NEXTHOP_TYPE_IPV6_IFINDEX:
/* RFC 5549, v4 prefix with v6 NH */
if (rn->p.family != AF_INET)