summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2026-06-25 16:38:50 +0200
committerGitHub <noreply@github.com>2026-06-25 16:38:50 +0200
commitd4e384f69497030469d0e935d7c95f563867edc7 (patch)
tree518d03ed6929e0e5965930454248e5cbf1e2083b
parentfe78ab4165456fd1d7bcd2ec99d7601dc2e71d2c (diff)
parentf04dfac8772c7a1326bad4f12ec3aedea9a4d8d9 (diff)
downloadvyos-1x-d4e384f69497030469d0e935d7c95f563867edc7.tar.gz
vyos-1x-d4e384f69497030469d0e935d7c95f563867edc7.zip
Merge pull request #5272 from natali-rs1985/T5526
bgp: T5526: Fix BGP neighbor validation not raising when interface does not exist
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_bgp.py34
-rwxr-xr-xsrc/conf_mode/protocols_bgp.py17
2 files changed, 47 insertions, 4 deletions
diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py
index cee52e548..27fd9f1fc 100755
--- a/smoketest/scripts/cli/test_protocols_bgp.py
+++ b/smoketest/scripts/cli/test_protocols_bgp.py
@@ -1841,6 +1841,40 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' rt vpn import {ASN}:300', frrconfig)
self.assertNotIn('route-target vpn', frrconfig)
+ def test_bgp_34_interface_neighbor(self):
+ peer_group = 'TESTPG'
+ interface = 'eth0'
+ self.cli_set(base_path + ['peer-group', peer_group, 'remote-as', ASN])
+
+ # Setting peer-group directly on an interface neighbor must be rejected
+ self.cli_set(base_path + ['neighbor', interface, 'peer-group', peer_group])
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base_path + ['neighbor', interface, 'peer-group'])
+
+ # Correct syntax: peer-group under the interface sub-node must succeed
+ self.cli_set(
+ base_path + ['neighbor', interface, 'interface', 'peer-group', peer_group]
+ )
+ self.cli_commit()
+
+ # Remove remote-as from peer-group so the neighbor resolves it via interface node
+ self.cli_delete(base_path + ['peer-group', peer_group, 'remote-as'])
+
+ # remote-as set directly on an interface neighbor must be rejected
+ self.cli_set(base_path + ['neighbor', interface, 'remote-as', ASN])
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base_path + ['neighbor', interface, 'remote-as'])
+
+ # Correct syntax: remote-as under the interface sub-node must succeed
+ self.cli_set(base_path + ['neighbor', interface, 'interface', 'remote-as', ASN])
+ self.cli_commit()
+ frrconfig = self.getFRRconfig(f'router bgp {ASN}', stop_section='^exit')
+ self.assertIn(
+ f' neighbor {interface} interface peer-group {peer_group}', frrconfig
+ )
+
def test_bgp_99_bmp(self):
target_name = 'instance-bmp'
target_address = '127.0.0.1'
diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py
index b2bc3a6a6..2ec631f4c 100755
--- a/src/conf_mode/protocols_bgp.py
+++ b/src/conf_mode/protocols_bgp.py
@@ -26,7 +26,6 @@ from vyos.configverify import verify_vrf
from vyos.frrender import FRRender
from vyos.frrender import get_frrender_dict
from vyos.template import is_ip
-from vyos.template import is_interface
from vyos.utils.dict import dict_search
from vyos.utils.network import get_interface_vrf
from vyos.utils.network import is_addr_assigned
@@ -382,11 +381,21 @@ def verify(config_dict):
if is_ip(peer) and is_addr_assigned(peer, vrf):
raise ConfigError(f'Cannot configure local address as neighbor "{peer}"{vrf_error_msg}')
- elif is_interface(peer):
+ elif not is_ip(peer):
+ # T5526: Neighbor is not an IP address — treat as interface name
+ # regardless of whether the interface currently exists on the system.
+ # Checking physical existence would silently skip validation during
+ # boot or config restore, allowing invalid config to reach FRR.
if 'peer_group' in peer_config:
- raise ConfigError(f'peer-group must be set under the interface node of "{peer}"')
+ raise ConfigError(
+ f'To assign a peer-group to an interface-based neighbor, use: '
+ f'"set protocols bgp neighbor {peer} interface peer-group <name>"'
+ )
if 'remote_as' in peer_config:
- raise ConfigError(f'remote-as must be set under the interface node of "{peer}"')
+ raise ConfigError(
+ f'To set remote-as for an interface-based neighbor, use: '
+ f'"set protocols bgp neighbor {peer} interface remote-as <asn>"'
+ )
if 'source_interface' in peer_config['interface']:
raise ConfigError(f'"source-interface" option not allowed for neighbor "{peer}"')