diff options
| -rw-r--r-- | bgpd/bgp_attr.c | 28 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 29 | ||||
| -rw-r--r-- | configure.ac | 6 | ||||
| -rw-r--r-- | doc/user/bgp.rst | 2 | ||||
| -rw-r--r-- | isisd/isis_te.c | 4 | ||||
| -rw-r--r-- | ospfclient/subdir.am | 3 | ||||
| -rwxr-xr-x | tests/topotests/multicast_pim_dr_nondr_test/test_pim_dr_nondr_with_transit_router_topo3.py | 64 | ||||
| -rw-r--r-- | tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py | 65 | ||||
| -rw-r--r-- | tools/subdir.am | 11 | ||||
| -rw-r--r-- | zebra/zebra_nhg.c | 7 |
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) |
