summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Christ <r.christ@partimus.com>2026-03-29 12:25:26 +0200
committerRobin Christ <r.christ@partimus.com>2026-03-29 12:25:40 +0200
commitd0b9b7037478d2374007c87cd7cc5d424d3674e6 (patch)
tree7705f51bb269efa933c8a51a5f09f6a4a8ffd84a
parentad6f703b16464a6cb73f9052077a6100aff4db73 (diff)
downloadvyos-1x-d0b9b7037478d2374007c87cd7cc5d424d3674e6.tar.gz
vyos-1x-d0b9b7037478d2374007c87cd7cc5d424d3674e6.zip
bgp: T7338: Add support for "parameters as-notation <asdot|asdot+>"
We explicitly omit the "plain" option, as it is the implicit default in FRR We also do not want to add "plain" as VyOS default value and emit it by default as this makes the config a bit ugly (frr puts it in the router line so you get "router bgp <AS> as-notation plain"). Additionally, setting plain as default value and emitting it by default would break pretty much all BGP tests, as they commonly do self.getFRRconfig(f'router bgp {ASN}', stop_section='^exit') and getFRRConfig does a "^<content>$" match, which breaks when you add the "as-notation plain"
-rw-r--r--data/templates/frr/bgpd.frr.j22
-rw-r--r--interface-definitions/include/bgp/protocol-common-config.xml.i19
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_bgp.py51
3 files changed, 71 insertions, 1 deletions
diff --git a/data/templates/frr/bgpd.frr.j2 b/data/templates/frr/bgpd.frr.j2
index 44022f738..929e57d9c 100644
--- a/data/templates/frr/bgpd.frr.j2
+++ b/data/templates/frr/bgpd.frr.j2
@@ -259,7 +259,7 @@
{# j2lint: disable=jinja-statements-delimeter #}
{%- endmacro -%}
!
-router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }}
+router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }} {{ 'as-notation ' ~ parameters.as_notation | replace('as', '') if parameters.as_notation is vyos_defined }}
{% if parameters.ebgp_requires_policy is vyos_defined %}
bgp ebgp-requires-policy
{% else %}
diff --git a/interface-definitions/include/bgp/protocol-common-config.xml.i b/interface-definitions/include/bgp/protocol-common-config.xml.i
index f4bcf1509..ccf976b29 100644
--- a/interface-definitions/include/bgp/protocol-common-config.xml.i
+++ b/interface-definitions/include/bgp/protocol-common-config.xml.i
@@ -1153,6 +1153,25 @@
<help>BGP parameters</help>
</properties>
<children>
+ <leafNode name="as-notation">
+ <properties>
+ <help>BGP AS-notation output format</help>
+ <completionHelp>
+ <list>asdot asdot+</list>
+ </completionHelp>
+ <valueHelp>
+ <format>asdot</format>
+ <description>Use asdot notation only for 4 byte AS numbers</description>
+ </valueHelp>
+ <valueHelp>
+ <format>asdot+</format>
+ <description>Use asdot notation for all AS numbers</description>
+ </valueHelp>
+ <constraint>
+ <regex>(asdot\+|asdot)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
<leafNode name="allow-martian-nexthop">
<properties>
<help>Allow Martian nexthops to be received in the NLRI from a peer</help>
diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py
index edd797cf6..7df563239 100755
--- a/smoketest/scripts/cli/test_protocols_bgp.py
+++ b/smoketest/scripts/cli/test_protocols_bgp.py
@@ -1638,6 +1638,57 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' bgp router-id {router_id}', frr_vrf_config)
+ def test_bgp_31_as_notation(self):
+ # Test BGP AS-notation output format for both global and VRF BGP instances.
+ # Verify all three notation types render correctly on the router bgp line.
+ router_id = '127.0.0.4'
+ vrf = 'red'
+
+ for vrf in ['', 'red']:
+ vrf_base = ['vrf', 'name', vrf] if vrf else []
+ vrf_frr_bit = f' vrf {vrf}' if vrf else ''
+ bgp_path = vrf_base + base_path
+
+ if vrf_base:
+ self.cli_set(vrf_base + ['table', '2000'])
+
+ self.cli_set(bgp_path + ['system-as', ASN])
+ self.cli_set(bgp_path + ['parameters', 'router-id', router_id])
+
+ for notation in ['asdot', 'asdot+']:
+ self.cli_set(bgp_path + ['parameters', 'as-notation', notation])
+ self.cli_commit()
+
+ # our config options are called 'asdot' and 'asdot+' as in
+ # RFC 5396
+ # but FRR calls them 'dot' and 'dot+' in the router bgp line
+ # e.g. router bgp 12345 as-notation dot
+ # or
+ # router bgp 12345 vrf red as-notation dot
+ router_str = f'router bgp {ASN}{vrf_frr_bit} as-notation {notation.replace("as", "")}'
+ # getFRRConfig interprets the arguments as regex, so escape '+' if present
+ frrconfig = self.getFRRconfig(
+ router_str.replace('+', r'\+'), stop_section='^exit'
+ )
+ self.assertIn(router_str, frrconfig)
+
+ # Verify removing as-notation works
+ self.cli_delete(bgp_path + ['parameters', 'as-notation'])
+ self.cli_commit()
+
+ router_str = f'router bgp {ASN}{vrf_frr_bit}'
+
+ frrconfig = self.getFRRconfig(router_str, stop_section='^exit')
+ self.assertIn(router_str, frrconfig)
+ self.assertNotIn('as-notation', frrconfig.splitlines()[0])
+
+ # Cleanup
+ self.cli_delete(bgp_path)
+ if vrf_base:
+ self.cli_delete(vrf_base)
+
+ self.cli_commit()
+
def test_bgp_99_bmp(self):
target_name = 'instance-bmp'
target_address = '127.0.0.1'