summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/frr/bgpd.frr.j24
-rw-r--r--interface-definitions/include/bgp/afi-redistribute-common-protocols.xml.i8
-rw-r--r--interface-definitions/include/version/bgp-version.xml.i2
-rw-r--r--smoketest/config-tests/bgp-rpki1
-rw-r--r--smoketest/configs/bgp-rpki7
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_bgp.py76
-rw-r--r--src/migration-scripts/bgp/5-to-639
7 files changed, 116 insertions, 21 deletions
diff --git a/data/templates/frr/bgpd.frr.j2 b/data/templates/frr/bgpd.frr.j2
index 2f3719fdf..3b462b4a9 100644
--- a/data/templates/frr/bgpd.frr.j2
+++ b/data/templates/frr/bgpd.frr.j2
@@ -310,8 +310,8 @@ router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }}
{% if afi_config.redistribute is vyos_defined %}
{% for protocol, protocol_config in afi_config.redistribute.items() %}
{% if protocol == 'table' %}
-{% for table in protocol_config %}
- redistribute table-direct {{ table }}
+{% for table, table_config in protocol_config.items() %}
+ redistribute table-direct {{ table }} {{ 'metric ' ~ table_config.metric if table_config.metric is vyos_defined }} {{ 'route-map ' ~ table_config.route_map if table_config.route_map is vyos_defined }}
{% endfor %}
{% else %}
{% set redistribution_protocol = protocol %}
diff --git a/interface-definitions/include/bgp/afi-redistribute-common-protocols.xml.i b/interface-definitions/include/bgp/afi-redistribute-common-protocols.xml.i
index f4d18bc70..141a704c7 100644
--- a/interface-definitions/include/bgp/afi-redistribute-common-protocols.xml.i
+++ b/interface-definitions/include/bgp/afi-redistribute-common-protocols.xml.i
@@ -39,14 +39,16 @@
#include <include/bgp/afi-redistribute-metric-route-map.xml.i>
</children>
</node>
-<leafNode name="table">
+<tagNode name="table">
<properties>
<help>Redistribute non-main Kernel Routing Table</help>
<completionHelp>
<path>protocols static table</path>
</completionHelp>
#include <include/constraint/protocols-static-table.xml.i>
- <multi/>
</properties>
-</leafNode>
+ <children>
+ #include <include/bgp/afi-redistribute-metric-route-map.xml.i>
+ </children>
+</tagNode>
<!-- include end -->
diff --git a/interface-definitions/include/version/bgp-version.xml.i b/interface-definitions/include/version/bgp-version.xml.i
index 6bed7189f..c90276151 100644
--- a/interface-definitions/include/version/bgp-version.xml.i
+++ b/interface-definitions/include/version/bgp-version.xml.i
@@ -1,3 +1,3 @@
<!-- include start from include/version/bgp-version.xml.i -->
-<syntaxVersion component='bgp' version='5'></syntaxVersion>
+<syntaxVersion component='bgp' version='6'></syntaxVersion>
<!-- include end -->
diff --git a/smoketest/config-tests/bgp-rpki b/smoketest/config-tests/bgp-rpki
index 587de67c6..657d4abcc 100644
--- a/smoketest/config-tests/bgp-rpki
+++ b/smoketest/config-tests/bgp-rpki
@@ -13,6 +13,7 @@ set policy route-map ebgp-transit-rpki rule 30 set local-preference '100'
set policy route-map ebgp-transit-rpki rule 40 action 'permit'
set policy route-map ebgp-transit-rpki rule 40 set extcommunity rt '192.0.2.100:100'
set policy route-map ebgp-transit-rpki rule 40 set extcommunity soo '64500:100'
+set protocols bgp address-family ipv4-unicast redistribute table 100
set protocols bgp neighbor 1.2.3.4 address-family ipv4-unicast nexthop-self
set protocols bgp neighbor 1.2.3.4 address-family ipv4-unicast route-map import 'ebgp-transit-rpki'
set protocols bgp neighbor 1.2.3.4 remote-as '10'
diff --git a/smoketest/configs/bgp-rpki b/smoketest/configs/bgp-rpki
index 5588f15c9..2d136d545 100644
--- a/smoketest/configs/bgp-rpki
+++ b/smoketest/configs/bgp-rpki
@@ -46,6 +46,13 @@ policy {
}
protocols {
bgp 64500 {
+ address-family {
+ ipv4-unicast {
+ redistribute {
+ table 100
+ }
+ }
+ }
neighbor 1.2.3.4 {
address-family {
ipv4-unicast {
diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py
index 0eda52ff6..0c6d36213 100755
--- a/smoketest/scripts/cli/test_protocols_bgp.py
+++ b/smoketest/scripts/cli/test_protocols_bgp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright (C) 2021-2025 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
@@ -685,14 +685,30 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
'route_map' : 'redistr-ipv4-static',
},
'table' : {
- 'number' : ['10', '20', '30', '40'],
+ '10' : {
+ 'metric' : '810',
+ 'route_map' : 'redistr-ipv4-table-10',
+ },
+ '20' : {
+ 'metric' : '820',
+ 'route_map' : 'redistr-ipv4-table-20',
+ },
+ '30' : {
+ 'metric' : '830',
+ 'route_map' : 'redistr-ipv4-table-30',
+ },
},
}
for proto, proto_config in redistributes.items():
proto_path = base_path + ['address-family', 'ipv4-unicast', 'redistribute', proto]
- if proto == 'table' and 'number' in proto_config:
- for number in proto_config['number']:
- self.cli_set(proto_path, value=number)
+ if proto == 'table':
+ for table, table_config in proto_config.items():
+ self.cli_set(proto_path + [table])
+ if 'metric' in table_config:
+ self.cli_set(proto_path + [table, 'metric'], value=table_config['metric'])
+ if 'route_map' in table_config:
+ self.cli_set(['policy', 'route-map', table_config['route_map'], 'rule', '10', 'action'], value='permit')
+ self.cli_set(proto_path + [table, 'route-map'], value=table_config['route_map'])
else:
self.cli_set(proto_path)
if 'metric' in proto_config:
@@ -723,9 +739,16 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.assertIn(' address-family ipv4 unicast', frrconfig)
for proto, proto_config in redistributes.items():
- if proto == 'table' and 'number' in proto_config:
- for number in proto_config['number']:
- self.assertIn(f' redistribute table-direct {number}', frrconfig)
+ if proto == 'table':
+ for table, table_config in proto_config.items():
+ tmp = f' redistribute table-direct {table}'
+ if 'metric' in proto_config:
+ metric = proto_config['metric']
+ tmp += f' metric {metric}'
+ if 'route_map' in proto_config:
+ route_map = proto_config['route_map']
+ tmp += f' route-map {route_map}'
+ self.assertIn(tmp, frrconfig)
else:
tmp = f' redistribute {proto}'
if 'metric' in proto_config:
@@ -794,14 +817,30 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
'route_map' : 'redistr-ipv6-static',
},
'table' : {
- 'number' : ['100', '120', '130', '140'],
+ '110' : {
+ 'metric' : '811',
+ 'route_map' : 'redistr-ipv6-table-110',
+ },
+ '120' : {
+ 'metric' : '821',
+ 'route_map' : 'redistr-ipv6-table-120',
+ },
+ '130' : {
+ 'metric' : '831',
+ 'route_map' : 'redistr-ipv6-table-130',
+ },
},
}
for proto, proto_config in redistributes.items():
proto_path = base_path + ['address-family', 'ipv6-unicast', 'redistribute', proto]
- if proto == 'table' and 'number' in proto_config:
- for number in proto_config['number']:
- self.cli_set(proto_path, value=number)
+ if proto == 'table':
+ for table, table_config in proto_config.items():
+ self.cli_set(proto_path + [table])
+ if 'metric' in table_config:
+ self.cli_set(proto_path + [table, 'metric'], value=table_config['metric'])
+ if 'route_map' in table_config:
+ self.cli_set(['policy', 'route-map', table_config['route_map'], 'rule', '10', 'action'], value='permit')
+ self.cli_set(proto_path + [table, 'route-map'], value=table_config['route_map'])
else:
self.cli_set(proto_path)
if 'metric' in proto_config:
@@ -829,9 +868,16 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.assertIn(' no bgp ebgp-requires-policy', frrconfig)
for proto, proto_config in redistributes.items():
- if proto == 'table' and 'number' in proto_config:
- for number in proto_config['number']:
- self.assertIn(f' redistribute table-direct {number}', frrconfig)
+ if proto == 'table':
+ for table, table_config in proto_config.items():
+ tmp = f' redistribute table-direct {table}'
+ if 'metric' in proto_config:
+ metric = proto_config['metric']
+ tmp += f' metric {metric}'
+ if 'route_map' in proto_config:
+ route_map = proto_config['route_map']
+ tmp += f' route-map {route_map}'
+ self.assertIn(tmp, frrconfig)
else:
# FRR calls this OSPF6
if proto == 'ospfv3':
diff --git a/src/migration-scripts/bgp/5-to-6 b/src/migration-scripts/bgp/5-to-6
new file mode 100644
index 000000000..e6fea6574
--- /dev/null
+++ b/src/migration-scripts/bgp/5-to-6
@@ -0,0 +1,39 @@
+# Copyright 2025 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+# T7163: migrate "address-family ipv4|6-unicast redistribute table" from a multi
+# leafNode to a tagNode. This is needed to support per table definition of a
+# route-map and/or metric
+
+from vyos.configtree import ConfigTree
+
+def migrate(config: ConfigTree) -> None:
+ bgp_base = ['protocols', 'bgp']
+ if not config.exists(bgp_base):
+ return
+
+ for address_family in ['ipv4-unicast', 'ipv6-unicast']:
+ # there is no non-main routing table beeing redistributed under this addres family
+ # bail out early and continue with next AFI
+ table_path = bgp_base + ['address-family', address_family, 'redistribute', 'table']
+ if not config.exists(table_path):
+ continue
+
+ tables = config.return_values(table_path)
+ config.delete(table_path)
+
+ for table in tables:
+ config.set(table_path + [table])
+ config.set_tag(table_path)