From 006b17a319c540a2fb384b90c65294f5a607787c Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Thu, 9 Dec 2021 23:19:43 +0100 Subject: bgp: T4058: add support for BFD profiles --- data/templates/frr/bgpd.frr.tmpl | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'data/templates/frr/bgpd.frr.tmpl') diff --git a/data/templates/frr/bgpd.frr.tmpl b/data/templates/frr/bgpd.frr.tmpl index fbdbafd6e..a3c6431f6 100644 --- a/data/templates/frr/bgpd.frr.tmpl +++ b/data/templates/frr/bgpd.frr.tmpl @@ -17,6 +17,12 @@ {% endif %} {% if config.bfd is defined %} neighbor {{ neighbor }} bfd +{% if config.bfd.check_control_plane_failure is defined %} + neighbor {{ neighbor }} bfd check-control-plane-failure +{% endif %} +{% if config.bfd.profile is defined and config.bfd.profile is not none %} + neighbor {{ neighbor }} bfd profile {{ config.bfd.profile }} +{% endif %} {% endif %} {% if config.capability is defined and config.capability is not none %} {% if config.capability.dynamic is defined %} -- cgit v1.2.3 From ede5ba7c1e9e5e2862f91d3082b50b71a1ffe920 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 12 Dec 2021 09:56:46 +0100 Subject: bgp: T3967: add "parameters conditional-advertisement timer " option Set the period to rerun the conditional advertisement scanner process. The default is 60 seconds. --- data/templates/frr/bgpd.frr.tmpl | 5 +++++ .../include/bgp/protocol-common-config.xml.i | 20 ++++++++++++++++++++ smoketest/scripts/cli/test_protocols_bgp.py | 4 ++++ 3 files changed, 29 insertions(+) (limited to 'data/templates/frr/bgpd.frr.tmpl') diff --git a/data/templates/frr/bgpd.frr.tmpl b/data/templates/frr/bgpd.frr.tmpl index a3c6431f6..cae53d09c 100644 --- a/data/templates/frr/bgpd.frr.tmpl +++ b/data/templates/frr/bgpd.frr.tmpl @@ -475,6 +475,11 @@ router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none {% if parameters.cluster_id is defined and parameters.cluster_id is not none %} bgp cluster-id {{ parameters.cluster_id }} {% endif %} +{% if parameters.conditional_advertisement is defined and parameters.conditional_advertisement is not none %} +{% if parameters.conditional_advertisement.timer is defined and parameters.conditional_advertisement.timer is not none %} + bgp conditional-advertisement timer {{ parameters.conditional_advertisement.timer }} +{% endif %} +{% endif %} {% if parameters.confederation is defined and parameters.confederation is not none %} {% if parameters.confederation.identifier is defined and parameters.confederation.identifier is not none %} bgp confederation identifier {{ parameters.confederation.identifier }} diff --git a/interface-definitions/include/bgp/protocol-common-config.xml.i b/interface-definitions/include/bgp/protocol-common-config.xml.i index 2dfae517e..351ee8eda 100644 --- a/interface-definitions/include/bgp/protocol-common-config.xml.i +++ b/interface-definitions/include/bgp/protocol-common-config.xml.i @@ -1181,6 +1181,26 @@ + + + Conditional advertisement settings + + + + + Set period to rescan BGP table to check if condition is met + + u32:5-240 + Period to rerun the conditional advertisement scanner process (default: 60) + + + + + + 60 + + + Enable route-flap dampening diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py index 5fdca4fc2..8282d507a 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -218,6 +218,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): max_path_v4ibgp = '4' max_path_v6 = '8' max_path_v6ibgp = '16' + cond_adv_timer = '30' self.cli_set(base_path + ['parameters', 'router-id', router_id]) self.cli_set(base_path + ['parameters', 'log-neighbor-changes']) @@ -239,6 +240,8 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.cli_set(base_path + ['parameters', 'bestpath', 'bandwidth', 'default-weight-for-missing']) self.cli_set(base_path + ['parameters', 'bestpath', 'compare-routerid']) + self.cli_set(base_path + ['parameters', 'conditional-advertisement', 'timer', cond_adv_timer]) + # AFI maximum path support self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'maximum-paths', 'ebgp', max_path_v4]) self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'maximum-paths', 'ibgp', max_path_v4ibgp]) @@ -254,6 +257,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(f' bgp router-id {router_id}', frrconfig) self.assertIn(f' bgp log-neighbor-changes', frrconfig) self.assertIn(f' bgp default local-preference {local_pref}', frrconfig) + self.assertIn(f' bgp conditional-advertisement timer {cond_adv_timer}', frrconfig) self.assertIn(f' bgp graceful-restart stalepath-time {stalepath_time}', frrconfig) self.assertIn(f' bgp graceful-shutdown', frrconfig) self.assertIn(f' bgp bestpath as-path multipath-relax', frrconfig) -- cgit v1.2.3 From ee2c84b2f0cc13d71122bd2ee0640bb13aa8040e Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 12 Dec 2021 10:06:17 +0100 Subject: bgp: T4069: add "parameters fast-convergence" CLI option Whenever BGP peer address becomes unreachable we must bring down the BGP session immediately. Currently only single-hop EBGP sessions are brought down immediately. IBGP and multi-hop EBGP sessions wait for hold-timer expiry to bring down the sessions. This new configuration option helps user to teardown BGP sessions immediately whenever peer becomes unreachable. This configuration is available at the bgp level. When enabled, configuration is applied to all the neighbors configured in that bgp instance. --- data/templates/frr/bgpd.frr.tmpl | 3 +++ interface-definitions/include/bgp/protocol-common-config.xml.i | 6 ++++++ smoketest/scripts/cli/test_protocols_bgp.py | 2 ++ 3 files changed, 11 insertions(+) (limited to 'data/templates/frr/bgpd.frr.tmpl') diff --git a/data/templates/frr/bgpd.frr.tmpl b/data/templates/frr/bgpd.frr.tmpl index cae53d09c..351e4a7ed 100644 --- a/data/templates/frr/bgpd.frr.tmpl +++ b/data/templates/frr/bgpd.frr.tmpl @@ -510,6 +510,9 @@ router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none {% endfor %} {% endif %} {% endif %} +{% if parameters.fast_convergence is defined %} + bgp fast-convergence +{% endif %} {% if parameters.graceful_restart is defined %} bgp graceful-restart {{ 'stalepath-time ' ~ parameters.graceful_restart.stalepath_time if parameters.graceful_restart.stalepath_time is defined }} {% endif %} diff --git a/interface-definitions/include/bgp/protocol-common-config.xml.i b/interface-definitions/include/bgp/protocol-common-config.xml.i index 351ee8eda..5dd4e522b 100644 --- a/interface-definitions/include/bgp/protocol-common-config.xml.i +++ b/interface-definitions/include/bgp/protocol-common-config.xml.i @@ -1363,6 +1363,12 @@ + + + Teardown sessions immediately whenever peer becomes unreachable + + + Graceful restart capability parameters diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py index 8282d507a..2693ca5ba 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -241,6 +241,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.cli_set(base_path + ['parameters', 'bestpath', 'compare-routerid']) self.cli_set(base_path + ['parameters', 'conditional-advertisement', 'timer', cond_adv_timer]) + self.cli_set(base_path + ['parameters', 'fast-convergence']) # AFI maximum path support self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'maximum-paths', 'ebgp', max_path_v4]) @@ -258,6 +259,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(f' bgp log-neighbor-changes', frrconfig) self.assertIn(f' bgp default local-preference {local_pref}', frrconfig) self.assertIn(f' bgp conditional-advertisement timer {cond_adv_timer}', frrconfig) + self.assertIn(f' bgp fast-convergence', frrconfig) self.assertIn(f' bgp graceful-restart stalepath-time {stalepath_time}', frrconfig) self.assertIn(f' bgp graceful-shutdown', frrconfig) self.assertIn(f' bgp bestpath as-path multipath-relax', frrconfig) -- cgit v1.2.3 From 1d4c23ca9b62dfa6db6580440b21cd89c5d8f7e8 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 12 Dec 2021 10:06:57 +0100 Subject: bgp: T4069: add "parameters minimum-holdtime " CLI option This command allows user to prevent session establishment with BGP peers with lower holdtime less than configured minimum holdtime. When this command is not set, minimum holdtime does not work. --- data/templates/frr/bgpd.frr.tmpl | 3 +++ .../include/bgp/protocol-common-config.xml.i | 12 ++++++++++++ smoketest/scripts/cli/test_protocols_bgp.py | 3 +++ 3 files changed, 18 insertions(+) (limited to 'data/templates/frr/bgpd.frr.tmpl') diff --git a/data/templates/frr/bgpd.frr.tmpl b/data/templates/frr/bgpd.frr.tmpl index 351e4a7ed..c04475070 100644 --- a/data/templates/frr/bgpd.frr.tmpl +++ b/data/templates/frr/bgpd.frr.tmpl @@ -522,6 +522,9 @@ router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none {% if parameters.log_neighbor_changes is defined %} bgp log-neighbor-changes {% endif %} +{% if parameters.minimum_holdtime is defined and parameters.minimum_holdtime is not none %} + bgp minimum-holdtime {{ parameters.minimum_holdtime }} +{% endif %} {% if parameters.network_import_check is defined %} bgp network import-check {% endif %} diff --git a/interface-definitions/include/bgp/protocol-common-config.xml.i b/interface-definitions/include/bgp/protocol-common-config.xml.i index 5dd4e522b..20ac59c5b 100644 --- a/interface-definitions/include/bgp/protocol-common-config.xml.i +++ b/interface-definitions/include/bgp/protocol-common-config.xml.i @@ -1400,6 +1400,18 @@ + + + BGP minimum holdtime + + u32:1-65535 + Minimum holdtime in seconds + + + + + + Enable IGP route check for network statements diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py index 2693ca5ba..983f6ecd3 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -219,6 +219,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): max_path_v6 = '8' max_path_v6ibgp = '16' cond_adv_timer = '30' + min_hold_time = '2' self.cli_set(base_path + ['parameters', 'router-id', router_id]) self.cli_set(base_path + ['parameters', 'log-neighbor-changes']) @@ -242,6 +243,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.cli_set(base_path + ['parameters', 'conditional-advertisement', 'timer', cond_adv_timer]) self.cli_set(base_path + ['parameters', 'fast-convergence']) + self.cli_set(base_path + ['parameters', 'minimum-holdtime', min_hold_time]) # AFI maximum path support self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'maximum-paths', 'ebgp', max_path_v4]) @@ -265,6 +267,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(f' bgp bestpath as-path multipath-relax', frrconfig) self.assertIn(f' bgp bestpath bandwidth default-weight-for-missing', frrconfig) self.assertIn(f' bgp bestpath compare-routerid', frrconfig) + self.assertIn(f' bgp minimum-holdtime {min_hold_time}', frrconfig) self.assertNotIn(f'bgp ebgp-requires-policy', frrconfig) afiv4_config = self.getFRRconfig(' address-family ipv4 unicast') -- cgit v1.2.3 From bddabbf696ec8ff638b93c5260aa4823dcc43df3 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 12 Dec 2021 10:09:24 +0100 Subject: bgp: T4069: add "parameters reject-as-sets" CLI option This command enables rejection of incoming and outgoing routes having AS_SET or AS_CONFED_SET type. --- data/templates/frr/bgpd.frr.tmpl | 3 +++ interface-definitions/include/bgp/protocol-common-config.xml.i | 6 ++++++ smoketest/scripts/cli/test_protocols_bgp.py | 2 ++ 3 files changed, 11 insertions(+) (limited to 'data/templates/frr/bgpd.frr.tmpl') diff --git a/data/templates/frr/bgpd.frr.tmpl b/data/templates/frr/bgpd.frr.tmpl index c04475070..e49aaf12c 100644 --- a/data/templates/frr/bgpd.frr.tmpl +++ b/data/templates/frr/bgpd.frr.tmpl @@ -534,6 +534,9 @@ router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none {% if parameters.no_fast_external_failover is defined %} no bgp fast-external-failover {% endif %} +{% if parameters.reject_as_sets is defined %} + bgp reject-as-sets +{% endif %} {% if parameters.router_id is defined and parameters.router_id is not none %} bgp router-id {{ parameters.router_id }} {% endif %} diff --git a/interface-definitions/include/bgp/protocol-common-config.xml.i b/interface-definitions/include/bgp/protocol-common-config.xml.i index 20ac59c5b..82c8e55a0 100644 --- a/interface-definitions/include/bgp/protocol-common-config.xml.i +++ b/interface-definitions/include/bgp/protocol-common-config.xml.i @@ -1430,6 +1430,12 @@ + + + Reject routes with AS_SET or AS_CONFED_SET flag + + + #include diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py index 983f6ecd3..87673f459 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -244,6 +244,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.cli_set(base_path + ['parameters', 'conditional-advertisement', 'timer', cond_adv_timer]) self.cli_set(base_path + ['parameters', 'fast-convergence']) self.cli_set(base_path + ['parameters', 'minimum-holdtime', min_hold_time]) + self.cli_set(base_path + ['parameters', 'reject-as-sets']) # AFI maximum path support self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'maximum-paths', 'ebgp', max_path_v4]) @@ -268,6 +269,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(f' bgp bestpath bandwidth default-weight-for-missing', frrconfig) self.assertIn(f' bgp bestpath compare-routerid', frrconfig) self.assertIn(f' bgp minimum-holdtime {min_hold_time}', frrconfig) + self.assertIn(f' bgp reject-as-sets', frrconfig) self.assertNotIn(f'bgp ebgp-requires-policy', frrconfig) afiv4_config = self.getFRRconfig(' address-family ipv4 unicast') -- cgit v1.2.3 From aca9d98c818407b8009bb861ec0f5a817a9a5637 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 12 Dec 2021 10:10:10 +0100 Subject: bgp: T4069: add "parameters shutdown" CLI option Administrative shutdown of all peers of a bgp instance. Drop all BGP peers, but preserve their configurations. The peers are notified in accordance with RFC 8203 by sending a NOTIFICATION message with error code Cease and subcode Administrative Shutdown prior to terminating connections. This global shutdown is independent of the neighbor shutdown, meaning that individually shut down peers will not be affected by lifting it. --- data/templates/frr/bgpd.frr.tmpl | 3 +++ interface-definitions/include/bgp/protocol-common-config.xml.i | 6 ++++++ smoketest/scripts/cli/test_protocols_bgp.py | 2 ++ 3 files changed, 11 insertions(+) (limited to 'data/templates/frr/bgpd.frr.tmpl') diff --git a/data/templates/frr/bgpd.frr.tmpl b/data/templates/frr/bgpd.frr.tmpl index e49aaf12c..01e62a94b 100644 --- a/data/templates/frr/bgpd.frr.tmpl +++ b/data/templates/frr/bgpd.frr.tmpl @@ -540,6 +540,9 @@ router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none {% if parameters.router_id is defined and parameters.router_id is not none %} bgp router-id {{ parameters.router_id }} {% endif %} +{% if parameters.shutdown is defined %} + bgp shutdown +{% endif %} {% endif %} {% if timers is defined and timers.keepalive is defined and timers.holdtime is defined %} timers bgp {{ timers.keepalive }} {{ timers.holdtime }} diff --git a/interface-definitions/include/bgp/protocol-common-config.xml.i b/interface-definitions/include/bgp/protocol-common-config.xml.i index 82c8e55a0..2b2d6fa82 100644 --- a/interface-definitions/include/bgp/protocol-common-config.xml.i +++ b/interface-definitions/include/bgp/protocol-common-config.xml.i @@ -1436,6 +1436,12 @@ + + + Administrative shutdown of the BGP instance + + + #include diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py index 87673f459..74aff71eb 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -245,6 +245,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.cli_set(base_path + ['parameters', 'fast-convergence']) self.cli_set(base_path + ['parameters', 'minimum-holdtime', min_hold_time]) self.cli_set(base_path + ['parameters', 'reject-as-sets']) + self.cli_set(base_path + ['parameters', 'shutdown']) # AFI maximum path support self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'maximum-paths', 'ebgp', max_path_v4]) @@ -270,6 +271,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(f' bgp bestpath compare-routerid', frrconfig) self.assertIn(f' bgp minimum-holdtime {min_hold_time}', frrconfig) self.assertIn(f' bgp reject-as-sets', frrconfig) + self.assertIn(f' bgp shutdown', frrconfig) self.assertNotIn(f'bgp ebgp-requires-policy', frrconfig) afiv4_config = self.getFRRconfig(' address-family ipv4 unicast') -- cgit v1.2.3 From 6fab523565015fd4da5d7295bad684cb969e5d12 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 12 Dec 2021 10:11:49 +0100 Subject: bgp: T4069: add "parameters suppress-fib-pending" CLI option This command is applicable at the global level and at an individual bgp level. If applied at the global level all bgp instances will wait for fib installation before announcing routes and there is no way to turn it off for a particular BGP vrf. --- data/templates/frr/bgpd.frr.tmpl | 5 ++++- interface-definitions/include/bgp/protocol-common-config.xml.i | 8 +++++++- smoketest/scripts/cli/test_protocols_bgp.py | 4 +++- 3 files changed, 14 insertions(+), 3 deletions(-) (limited to 'data/templates/frr/bgpd.frr.tmpl') diff --git a/data/templates/frr/bgpd.frr.tmpl b/data/templates/frr/bgpd.frr.tmpl index 01e62a94b..9bb42fd2d 100644 --- a/data/templates/frr/bgpd.frr.tmpl +++ b/data/templates/frr/bgpd.frr.tmpl @@ -543,8 +543,11 @@ router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none {% if parameters.shutdown is defined %} bgp shutdown {% endif %} +{% if parameters.suppress_fib_pending is defined %} + bgp suppress-fib-pending +{% endif %} {% endif %} {% if timers is defined and timers.keepalive is defined and timers.holdtime is defined %} timers bgp {{ timers.keepalive }} {{ timers.holdtime }} {% endif %} -exit \ No newline at end of file +exit diff --git a/interface-definitions/include/bgp/protocol-common-config.xml.i b/interface-definitions/include/bgp/protocol-common-config.xml.i index 2b2d6fa82..8214d0779 100644 --- a/interface-definitions/include/bgp/protocol-common-config.xml.i +++ b/interface-definitions/include/bgp/protocol-common-config.xml.i @@ -1442,6 +1442,12 @@ + + + Advertise only routes that are programmed in kernel to peers + + + #include @@ -1491,4 +1497,4 @@ #include - \ No newline at end of file + diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py index 74aff71eb..a2bcd0685 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -246,6 +246,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.cli_set(base_path + ['parameters', 'minimum-holdtime', min_hold_time]) self.cli_set(base_path + ['parameters', 'reject-as-sets']) self.cli_set(base_path + ['parameters', 'shutdown']) + self.cli_set(base_path + ['parameters', 'suppress-fib-pending']) # AFI maximum path support self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'maximum-paths', 'ebgp', max_path_v4]) @@ -272,6 +273,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(f' bgp minimum-holdtime {min_hold_time}', frrconfig) self.assertIn(f' bgp reject-as-sets', frrconfig) self.assertIn(f' bgp shutdown', frrconfig) + self.assertIn(f' bgp suppress-fib-pending', frrconfig) self.assertNotIn(f'bgp ebgp-requires-policy', frrconfig) afiv4_config = self.getFRRconfig(' address-family ipv4 unicast') @@ -786,4 +788,4 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(f' exit-address-family', afi_config) if __name__ == '__main__': - unittest.main(verbosity=2) \ No newline at end of file + unittest.main(verbosity=2) -- cgit v1.2.3 From ebccc291865132d2dd03edd2a56d400dd087ef43 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 12 Dec 2021 12:29:46 +0100 Subject: bgp: T3967: add support for conditional advertisement The BGP conditional advertisement feature uses the non-exist-map or the exist-map and the advertise-map keywords of the neighbor advertise-map command in order to track routes by the route prefix. non-exist-map ============= * If a route prefix is not present in the output of non-exist-map command, then advertise the route specified by the advertise-map command. * If a route prefix is present in the output of non-exist-map command, then do not advertise the route specified by the addvertise-map command. exist-map ========= * If a route prefix is present in the output of exist-map command, then advertise the route specified by the advertise-map command. * If a route prefix is not present in the output of exist-map command, then do not advertise the route specified by the advertise-map command. This feature is useful when some prefixes are advertised to one of its peers only if the information from the other peer is not present (due to failure in peering session or partial reachability etc). The conditional BGP announcements are sent in addition to the normal announcements that a BGP router sends to its peer. CLI nodes can be found under: * set protocols bgp neighbor address-family conditional-advertisement * set protocols bgp peer-group

address-family conditional-advertisement --- data/templates/frr/bgpd.frr.tmpl | 11 +++ .../bgp/neighbor-afi-ipv4-ipv6-common.xml.i | 55 ++++++++++++++ smoketest/scripts/cli/test_protocols_bgp.py | 84 ++++++++++++++++++---- src/conf_mode/protocols_bgp.py | 22 ++++++ 4 files changed, 157 insertions(+), 15 deletions(-) (limited to 'data/templates/frr/bgpd.frr.tmpl') diff --git a/data/templates/frr/bgpd.frr.tmpl b/data/templates/frr/bgpd.frr.tmpl index 9bb42fd2d..45e0544b7 100644 --- a/data/templates/frr/bgpd.frr.tmpl +++ b/data/templates/frr/bgpd.frr.tmpl @@ -146,6 +146,17 @@ {% if afi_config.as_override is defined %} neighbor {{ neighbor }} as-override {% endif %} +{% if afi_config.conditionally_advertise is defined and afi_config.conditionally_advertise is not none %} +{% if afi_config.conditionally_advertise.advertise_map is defined and afi_config.conditionally_advertise.advertise_map is not none %} +{% set exist_non_exist_map = 'exist-map' %} +{% if afi_config.conditionally_advertise.exist_map is defined and afi_config.conditionally_advertise.exist_map is not none %} +{% set exist_non_exist_map = 'exist-map ' ~ afi_config.conditionally_advertise.exist_map %} +{% elif afi_config.conditionally_advertise.non_exist_map is defined and afi_config.conditionally_advertise.non_exist_map is not none %} +{% set exist_non_exist_map = 'non-exist-map ' ~ afi_config.conditionally_advertise.non_exist_map %} +{% endif %} + neighbor {{ neighbor }} advertise-map {{ afi_config.conditionally_advertise.advertise_map }} {{ exist_non_exist_map }} +{% endif %} +{% endif %} {% if afi_config.remove_private_as is defined %} neighbor {{ neighbor }} remove-private-AS {% endif %} diff --git a/interface-definitions/include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i b/interface-definitions/include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i index 498662b0a..f3fc4444c 100644 --- a/interface-definitions/include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i +++ b/interface-definitions/include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i @@ -11,6 +11,61 @@ + + + Use route-map to conditionally advertise routes + + + + + Route-map to conditionally advertise routes + + policy route-map + + + txt + Route map name + + + ^[-_a-zA-Z0-9.]+$ + + Name of route-map can only contain alpha-numeric letters, hyphen and underscores + + + + + Advertise routes only if prefixes in exist-map are installed in BGP table + + policy route-map + + + txt + Route map name + + + ^[-_a-zA-Z0-9.]+$ + + Name of route-map can only contain alpha-numeric letters, hyphen and underscores + + + + + Advertise routes only if prefixes in non-exist-map are not installed in BGP table + + policy route-map + + + txt + Route map name + + + ^[-_a-zA-Z0-9.]+$ + + Name of route-map can only contain alpha-numeric letters, hyphen and underscores + + + + #include diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py index 22cc3785f..d7230baf4 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -59,11 +59,14 @@ neighbor_config = { 'no_cap_nego' : '', 'port' : '667', 'cap_strict' : '', + 'advertise_map': route_map_in, + 'non_exist_map': route_map_out, 'pfx_list_in' : prefix_list_in, 'pfx_list_out' : prefix_list_out, 'no_send_comm_std' : '', }, '192.0.2.3' : { + 'advertise_map': route_map_in, 'description' : 'foo bar baz', 'remote_as' : '200', 'passive' : '', @@ -72,6 +75,8 @@ neighbor_config = { 'peer_group' : 'foo', }, '2001:db8::1' : { + 'advertise_map': route_map_in, + 'exist_map' : route_map_out, 'cap_dynamic' : '', 'cap_ext_next' : '', 'remote_as' : '123', @@ -104,6 +109,8 @@ neighbor_config = { peer_group_config = { 'foo' : { + 'advertise_map': route_map_in, + 'exist_map' : route_map_out, 'bfd' : '', 'remote_as' : '100', 'passive' : '', @@ -113,6 +120,7 @@ peer_group_config = { 'ttl_security': '5', }, 'foo-bar' : { + 'advertise_map': route_map_in, 'description' : 'foo peer bar group', 'remote_as' : '200', 'shutdown' : '', @@ -122,8 +130,9 @@ peer_group_config = { 'pfx_list_out' : prefix_list_out, 'no_send_comm_ext' : '', }, - 'baz' : { 'foo-bar_baz' : { + 'advertise_map': route_map_in, + 'non_exist_map': route_map_out, 'bfd_profile' : bfd_profile, 'cap_dynamic' : '', 'cap_ext_next' : '', @@ -137,23 +146,34 @@ peer_group_config = { } class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): - def setUp(self): - self.cli_set(['policy', 'route-map', route_map_in, 'rule', '10', 'action', 'permit']) - self.cli_set(['policy', 'route-map', route_map_out, 'rule', '10', 'action', 'permit']) - self.cli_set(['policy', 'prefix-list', prefix_list_in, 'rule', '10', 'action', 'permit']) - self.cli_set(['policy', 'prefix-list', prefix_list_in, 'rule', '10', 'prefix', '192.0.2.0/25']) - self.cli_set(['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'action', 'permit']) - self.cli_set(['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'prefix', '192.0.2.128/25']) - - self.cli_set(['policy', 'prefix-list6', prefix_list_in6, 'rule', '10', 'action', 'permit']) - self.cli_set(['policy', 'prefix-list6', prefix_list_in6, 'rule', '10', 'prefix', '2001:db8:1000::/64']) - self.cli_set(['policy', 'prefix-list6', prefix_list_out6, 'rule', '10', 'action', 'deny']) - self.cli_set(['policy', 'prefix-list6', prefix_list_out6, 'rule', '10', 'prefix', '2001:db8:2000::/64']) + @classmethod + def setUpClass(cls): + super(cls, cls).setUpClass() + + # ensure we can also run this test on a live system - so lets clean + # out the current configuration :) + cls.cli_delete(cls, base_path) + + cls.cli_set(cls, ['policy', 'route-map', route_map_in, 'rule', '10', 'action', 'permit']) + cls.cli_set(cls, ['policy', 'route-map', route_map_out, 'rule', '10', 'action', 'permit']) + cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_in, 'rule', '10', 'action', 'permit']) + cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_in, 'rule', '10', 'prefix', '192.0.2.0/25']) + cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'action', 'permit']) + cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'prefix', '192.0.2.128/25']) + + cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_in6, 'rule', '10', 'action', 'permit']) + cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_in6, 'rule', '10', 'prefix', '2001:db8:1000::/64']) + cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_out6, 'rule', '10', 'action', 'deny']) + cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_out6, 'rule', '10', 'prefix', '2001:db8:2000::/64']) + + @classmethod + def tearDownClass(cls): + cls.cli_delete(cls, ['policy']) + def setUp(self): self.cli_set(base_path + ['local-as', ASN]) def tearDown(self): - self.cli_delete(['policy']) self.cli_delete(['vrf']) self.cli_delete(base_path) self.cli_commit() @@ -212,7 +232,13 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(f' neighbor {peer} addpath-tx-all-paths', frrconfig) if 'addpath_per_as' in peer_config: self.assertIn(f' neighbor {peer} addpath-tx-bestpath-per-AS', frrconfig) - + if 'advertise_map' in peer_config: + base = f' neighbor {peer} advertise-map {peer_config["advertise_map"]}' + if 'exist_map' in peer_config: + base = f'{base} exist-map {peer_config["exist_map"]}' + if 'non_exist_map' in peer_config: + base = f'{base} non-exist-map {peer_config["non_exist_map"]}' + self.assertIn(base, frrconfig) def test_bgp_01_simple(self): router_id = '127.0.0.1' @@ -353,6 +379,20 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): if 'addpath_per_as' in peer_config: self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'addpath-tx-per-as']) + # Conditional advertisement + if 'advertise_map' in peer_config: + self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'conditionally-advertise', 'advertise-map', peer_config["advertise_map"]]) + # Either exist-map or non-exist-map needs to be specified + if 'exist_map' not in peer_config and 'non_exist_map' not in peer_config: + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'conditionally-advertise', 'exist-map', route_map_in]) + + if 'exist_map' in peer_config: + self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'conditionally-advertise', 'exist-map', peer_config["exist_map"]]) + if 'non_exist_map' in peer_config: + self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'conditionally-advertise', 'non-exist-map', peer_config["non_exist_map"]]) + # commit changes self.cli_commit() @@ -421,6 +461,20 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): if 'addpath_per_as' in config: self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'addpath-tx-per-as']) + # Conditional advertisement + if 'advertise_map' in config: + self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'conditionally-advertise', 'advertise-map', config["advertise_map"]]) + # Either exist-map or non-exist-map needs to be specified + if 'exist_map' not in config and 'non_exist_map' not in config: + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'conditionally-advertise', 'exist-map', route_map_in]) + + if 'exist_map' in config: + self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'conditionally-advertise', 'exist-map', config["exist_map"]]) + if 'non_exist_map' in config: + self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'conditionally-advertise', 'non-exist-map', config["non_exist_map"]]) + for peer, peer_config in neighbor_config.items(): if 'peer_group' in peer_config: self.cli_set(base_path + ['neighbor', peer, 'peer-group', peer_config['peer_group']]) diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py index 03fb17ba7..d8704727c 100755 --- a/src/conf_mode/protocols_bgp.py +++ b/src/conf_mode/protocols_bgp.py @@ -183,6 +183,28 @@ def verify(bgp): raise ConfigError(f'Neighbor "{peer}" cannot have both ipv6-unicast and ipv6-labeled-unicast configured at the same time!') afi_config = peer_config['address_family'][afi] + + if 'conditionally_advertise' in afi_config: + if 'advertise_map' not in afi_config['conditionally_advertise']: + raise ConfigError('Must speficy advertise-map when conditionally-advertise is in use!') + # Verify advertise-map (which is a route-map) exists + verify_route_map(afi_config['conditionally_advertise']['advertise_map'], bgp) + + if ('exist_map' not in afi_config['conditionally_advertise'] and + 'non_exist_map' not in afi_config['conditionally_advertise']): + raise ConfigError('Must either speficy exist-map or non-exist-map when ' \ + 'conditionally-advertise is in use!') + + if {'exist_map', 'non_exist_map'} <= set(afi_config['conditionally_advertise']): + raise ConfigError('Can not specify both exist-map and non-exist-map for ' \ + 'conditionally-advertise!') + + if 'exist_map' in afi_config['conditionally_advertise']: + verify_route_map(afi_config['conditionally_advertise']['exist_map'], bgp) + + if 'non_exist_map' in afi_config['conditionally_advertise']: + verify_route_map(afi_config['conditionally_advertise']['non_exist_map'], bgp) + # Validate if configured Prefix list exists if 'prefix_list' in afi_config: for tmp in ['import', 'export']: -- cgit v1.2.3