summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/frr/bgpd.frr.tmpl9
-rw-r--r--data/templates/frr/policy.frr.tmpl11
-rw-r--r--interface-definitions/include/bgp/protocol-common-config.xml.i23
-rw-r--r--interface-definitions/policy.xml.in88
-rw-r--r--smoketest/configs/bgp-rpki7
-rwxr-xr-xsmoketest/scripts/cli/test_policy.py27
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_bgp.py7
-rwxr-xr-xsrc/migration-scripts/policy/0-to-165
8 files changed, 205 insertions, 32 deletions
diff --git a/data/templates/frr/bgpd.frr.tmpl b/data/templates/frr/bgpd.frr.tmpl
index 158da3605..c21e7f234 100644
--- a/data/templates/frr/bgpd.frr.tmpl
+++ b/data/templates/frr/bgpd.frr.tmpl
@@ -402,15 +402,18 @@ router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none
bgp always-compare-med
{% endif %}
{% if parameters.bestpath is defined and parameters.bestpath is not none %}
-{% if parameters.bestpath.compare_routerid is defined %}
- bgp bestpath compare-routerid
-{% endif %}
{% if parameters.bestpath.as_path is defined and parameters.bestpath.as_path is not none %}
{% for option in parameters.bestpath.as_path %}
{# replace is required for multipath-relax option #}
bgp bestpath as-path {{ option|replace('_', '-') }}
{% endfor %}
{% endif %}
+{% if parameters.bestpath.bandwidth is defined and parameters.bestpath.bandwidth is not none %}
+ bgp bestpath bandwidth {{ parameters.bestpath.bandwidth }}
+{% endif %}
+{% if parameters.bestpath.compare_routerid is defined %}
+ bgp bestpath compare-routerid
+{% endif %}
{% if parameters.bestpath.med is defined and parameters.bestpath.med is not none %}
bgp bestpath med {{ 'confed' if parameters.bestpath.med.confed is defined }} {{ 'missing-as-worst' if parameters.bestpath.med.missing_as_worst is defined }}
{% endif %}
diff --git a/data/templates/frr/policy.frr.tmpl b/data/templates/frr/policy.frr.tmpl
index 507ee2a14..b5649b44e 100644
--- a/data/templates/frr/policy.frr.tmpl
+++ b/data/templates/frr/policy.frr.tmpl
@@ -247,11 +247,14 @@ route-map {{ route_map }} {{ rule_config.action }} {{ rule }}
{% if rule_config.set.distance is defined and rule_config.set.distance is not none %}
set distance {{ rule_config.set.distance }}
{% endif %}
-{% if rule_config.set.extcommunity_rt is defined and rule_config.set.extcommunity_rt is not none %}
- set extcommunity rt {{ rule_config.set.extcommunity_rt }}
+{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.bandwidth is defined and rule_config.set.extcommunity.bandwidth is not none %}
+ set extcommunity bandwidth {{ rule_config.set.extcommunity.bandwidth }}
{% endif %}
-{% if rule_config.set.extcommunity_soo is defined and rule_config.set.extcommunity_soo is not none %}
- set extcommunity soo {{ rule_config.set.extcommunity_soo }}
+{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.rt is defined and rule_config.set.extcommunity.rt is not none %}
+ set extcommunity rt {{ rule_config.set.extcommunity.rt }}
+{% endif %}
+{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.soo is defined and rule_config.set.extcommunity.soo is not none %}
+ set extcommunity soo {{ rule_config.set.extcommunity.soo }}
{% endif %}
{% if rule_config.set.ip_next_hop is defined and rule_config.set.ip_next_hop is not none %}
set ip next-hop {{ rule_config.set.ip_next_hop }}
diff --git a/interface-definitions/include/bgp/protocol-common-config.xml.i b/interface-definitions/include/bgp/protocol-common-config.xml.i
index 78a4fb763..37fc7259f 100644
--- a/interface-definitions/include/bgp/protocol-common-config.xml.i
+++ b/interface-definitions/include/bgp/protocol-common-config.xml.i
@@ -1114,6 +1114,29 @@
</leafNode>
</children>
</node>
+ <leafNode name="bandwidth">
+ <properties>
+ <help>Link Bandwidth attribute</help>
+ <completionHelp>
+ <list>default-weight-for-missing ignore skip-missing</list>
+ </completionHelp>
+ <valueHelp>
+ <format>default-weight-for-missing</format>
+ <description>Assign low default weight (1) to paths not having link bandwidth</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ignore</format>
+ <description>Ignore link bandwidth (do regular ECMP, not weighted)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>skip-missing</format>
+ <description>Ignore paths without link bandwidth for ECMP (if other paths have it)</description>
+ </valueHelp>
+ <constraint>
+ <regex>^(default-weight-for-missing|ignore|skip-missing)$</regex>
+ </constraint>
+ </properties>
+ </leafNode>
<leafNode name="compare-routerid">
<properties>
<help>Compare the router-id for identical EBGP paths</help>
diff --git a/interface-definitions/policy.xml.in b/interface-definitions/policy.xml.in
index 195e074a3..6a002cc20 100644
--- a/interface-definitions/policy.xml.in
+++ b/interface-definitions/policy.xml.in
@@ -925,15 +925,6 @@
<valueless/>
</properties>
</leafNode>
- <leafNode name="bgp-extcommunity-rt">
- <properties>
- <help>Set route target value</help>
- <valueHelp>
- <format>&lt;aa:nn&gt;</format>
- <description>ExtCommunity in format: asn:value</description>
- </valueHelp>
- </properties>
- </leafNode>
<node name="comm-list">
<properties>
<help>Border Gateway Protocol (BGP) communities matching a community-list</help>
@@ -1007,24 +998,71 @@
</constraint>
</properties>
</leafNode>
- <leafNode name="extcommunity-rt">
+ <node name="extcommunity">
<properties>
- <help>Set route target value</help>
- <valueHelp>
- <format>txt</format>
- <description>ASN:nn_or_IP_address:nn VPN extended community</description>
- </valueHelp>
+ <help>BGP extended community attribute</help>
</properties>
- </leafNode>
- <leafNode name="extcommunity-soo">
- <properties>
- <help>Set Site of Origin value</help>
- <valueHelp>
- <format>txt</format>
- <description>ASN:nn_or_IP_address:nn VPN extended community</description>
- </valueHelp>
- </properties>
- </leafNode>
+ <children>
+ <leafNode name="bandwidth">
+ <properties>
+ <help>Bandwidth value in Mbps</help>
+ <completionHelp>
+ <list>cumulative num-multipaths</list>
+ </completionHelp>
+ <valueHelp>
+ <format>u32:1-25600</format>
+ <description>Bandwidth value in Mbps</description>
+ </valueHelp>
+ <valueHelp>
+ <format>cumulative</format>
+ <description>Cumulative bandwidth of all multipaths (outbound-only)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>num-multipaths</format>
+ <description>Internally computed bandwidth based on number of multipaths (outbound-only)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-25600"/>
+ <regex>^(cumulative|num-multipaths)$</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="rt">
+ <properties>
+ <help>Set route target value</help>
+ <valueHelp>
+ <format>ASN:NN</format>
+ <description>based on autonomous system number</description>
+ </valueHelp>
+ <valueHelp>
+ <format>IP:NN</format>
+ <description>Based on a router-id IP address</description>
+ </valueHelp>
+ <constraint>
+ <regex>^((?:[0-9]{1,3}\.){3}[0-9]{1,3}|\d+):\d+$</regex>
+ </constraint>
+ <constraintErrorMessage>Should be in form: ASN:NN or IPADDR:NN where ASN is autonomous system number</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="soo">
+ <properties>
+ <help>Set Site of Origin value</help>
+ <valueHelp>
+ <format>ASN:NN</format>
+ <description>based on autonomous system number</description>
+ </valueHelp>
+ <valueHelp>
+ <format>IP:NN</format>
+ <description>Based on a router-id IP address</description>
+ </valueHelp>
+ <constraint>
+ <regex>^((?:[0-9]{1,3}\.){3}[0-9]{1,3}|\d+):\d+$</regex>
+ </constraint>
+ <constraintErrorMessage>Should be in form: ASN:NN or IPADDR:NN where ASN is autonomous system number</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
<leafNode name="ip-next-hop">
<properties>
<help>Nexthop IP address</help>
diff --git a/smoketest/configs/bgp-rpki b/smoketest/configs/bgp-rpki
index e11ec9e72..dffab4c69 100644
--- a/smoketest/configs/bgp-rpki
+++ b/smoketest/configs/bgp-rpki
@@ -34,6 +34,13 @@ policy {
local-preference 100
}
}
+ rule 40 {
+ action permit
+ set {
+ extcommunity-rt 192.0.2.100:100
+ extcommunity-soo 64500:100
+ }
+ }
}
}
protocols {
diff --git a/smoketest/scripts/cli/test_policy.py b/smoketest/scripts/cli/test_policy.py
index 59425b789..2d7b78048 100755
--- a/smoketest/scripts/cli/test_policy.py
+++ b/smoketest/scripts/cli/test_policy.py
@@ -773,6 +773,9 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
'as-path-prepend' : '1234567890 987654321',
'atomic-aggregate' : '',
'distance' : '110',
+ 'extcommunity-bw' : '20000',
+ 'extcommunity-rt' : '123:456',
+ 'extcommunity-soo' : '456:789',
'ipv6-next-hop-global': '2001::1',
'ipv6-next-hop-local' : 'fe80::1',
'ip-next-hop' : '192.168.1.1',
@@ -789,6 +792,18 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
},
},
},
+ 'bandwidth-configuration' : {
+ 'rule' : {
+ '10' : {
+ 'action' : 'deny',
+ 'set' : {
+ 'as-path-prepend' : '100 100',
+ 'distance' : '200',
+ 'extcommunity-bw' : 'num-multipaths',
+ },
+ },
+ },
+ },
}
self.cli_set(['policy', 'access-list', access_list, 'rule', '10', 'action', 'permit'])
@@ -896,6 +911,12 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
self.cli_set(path + ['rule', rule, 'set', 'atomic-aggregate'])
if 'distance' in rule_config['set']:
self.cli_set(path + ['rule', rule, 'set', 'distance', rule_config['set']['distance']])
+ if 'extcommunity-bw' in rule_config['set']:
+ self.cli_set(path + ['rule', rule, 'set', 'extcommunity', 'bandwidth', rule_config['set']['extcommunity-bw']])
+ if 'extcommunity-rt' in rule_config['set']:
+ self.cli_set(path + ['rule', rule, 'set', 'extcommunity', 'rt', rule_config['set']['extcommunity-rt']])
+ if 'extcommunity-soo' in rule_config['set']:
+ self.cli_set(path + ['rule', rule, 'set', 'extcommunity', 'soo', rule_config['set']['extcommunity-soo']])
if 'ipv6-next-hop-global' in rule_config['set']:
self.cli_set(path + ['rule', rule, 'set', 'ipv6-next-hop', 'global', rule_config['set']['ipv6-next-hop-global']])
if 'ipv6-next-hop-local' in rule_config['set']:
@@ -1035,6 +1056,12 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
tmp += 'atomic-aggregate'
elif 'distance' in rule_config['set']:
tmp += 'distance ' + rule_config['set']['distance']
+ elif 'extcommunity-bw' in rule_config['set']:
+ tmp += 'extcommunity bandwidth' + rule_config['set']['extcommunity-bw']
+ elif 'extcommunity-rt' in rule_config['set']:
+ tmp += 'extcommunity rt' + rule_config['set']['extcommunity-rt']
+ elif 'extcommunity-soo' in rule_config['set']:
+ tmp += 'extcommunity rt' + rule_config['set']['extcommunity-soo']
elif 'ip-next-hop' in rule_config['set']:
tmp += 'ip next-hop ' + rule_config['set']['ip-next-hop']
elif 'ipv6-next-hop-global' in rule_config['set']:
diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py
index 10adc06e1..c51d83875 100755
--- a/smoketest/scripts/cli/test_protocols_bgp.py
+++ b/smoketest/scripts/cli/test_protocols_bgp.py
@@ -224,6 +224,10 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['parameters', 'graceful-shutdown'])
self.cli_set(base_path + ['parameters', 'ebgp-requires-policy'])
+ self.cli_set(base_path + ['parameters', 'bestpath', 'as-path', 'multipath-relax'])
+ self.cli_set(base_path + ['parameters', 'bestpath', 'bandwidth', 'default-weight-for-missing'])
+ self.cli_set(base_path + ['parameters', 'bestpath', 'compare-routerid'])
+
# 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])
@@ -242,6 +246,9 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' no bgp default ipv4-unicast', 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)
+ self.assertIn(f' bgp bestpath bandwidth default-weight-for-missing', frrconfig)
+ self.assertIn(f' bgp bestpath compare-routerid', frrconfig)
self.assertNotIn(f'bgp ebgp-requires-policy', frrconfig)
afiv4_config = self.getFRRconfig(' address-family ipv4 unicast')
diff --git a/src/migration-scripts/policy/0-to-1 b/src/migration-scripts/policy/0-to-1
new file mode 100755
index 000000000..7134920ad
--- /dev/null
+++ b/src/migration-scripts/policy/0-to-1
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# T3631: route-map: migrate "set extcommunity-rt" and "set extcommunity-soo"
+# to "set extcommunity rt|soo" to match FRR syntax
+
+
+from sys import argv
+from sys import exit
+
+from vyos.configtree import ConfigTree
+
+if (len(argv) < 1):
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+base = ['policy', 'route-map']
+config = ConfigTree(config_file)
+
+if not config.exists(base):
+ # Nothing to do
+ exit(0)
+
+
+for route_map in config.list_nodes(base):
+ if not config.exists(base + [route_map, 'rule']):
+ continue
+ for rule in config.list_nodes(base + [route_map, 'rule']):
+ base_rule = base + [route_map, 'rule', rule]
+
+ if config.exists(base_rule + ['set', 'extcommunity-rt']):
+ tmp = config.return_value(base_rule + ['set', 'extcommunity-rt'])
+ config.delete(base_rule + ['set', 'extcommunity-rt'])
+ config.set(base_rule + ['set', 'extcommunity', 'rt'], value=tmp)
+
+
+ if config.exists(base_rule + ['set', 'extcommunity-soo']):
+ tmp = config.return_value(base_rule + ['set', 'extcommunity-soo'])
+ config.delete(base_rule + ['set', 'extcommunity-soo'])
+ config.set(base_rule + ['set', 'extcommunity', 'soo'], value=tmp)
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print(f'Failed to save the modified config: {e}')
+ exit(1)