Skip to content

Commit d300395

Browse files
authored
Merge pull request #4663 from KawaiiNetworks/current
bgp: T7708: correct logic for route-reflector-client peer_as check
2 parents 380b7c5 + 1c8e789 commit d300395

File tree

2 files changed

+79
-23
lines changed

2 files changed

+79
-23
lines changed

smoketest/scripts/cli/test_protocols_bgp.py

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,17 +1438,64 @@ def test_bgp_26_ipv6_labeled_unicast_peer_group(self):
14381438
self.assertIn(f' neighbor {pg_ipv6} maximum-prefix {ipv6_max_prefix}', afiv6_config)
14391439

14401440
def test_bgp_27_route_reflector_client(self):
1441-
self.cli_set(base_path + ['peer-group', 'peer1', 'address-family', 'l2vpn-evpn', 'route-reflector-client'])
1442-
with self.assertRaises(ConfigSessionError) as e:
1443-
self.cli_commit()
1444-
1445-
self.cli_set(base_path + ['peer-group', 'peer1', 'remote-as', 'internal'])
1441+
int_neighbors = ['192.0.2.2', '192.0.2.3', '192.0.2.4', '192.0.2.5']
1442+
int_interfaces = ['dum0', 'dum1', 'dum2', 'dum3']
1443+
int_pg_names = ['SMOKETESTINT0', 'SMOKETESTINT1', 'SMOKETESTINT2']
1444+
remote_as_types = ['external', 'internal']
1445+
for int_interface in int_interfaces:
1446+
self.cli_set(['interfaces', 'dummy', int_interface])
14461447
self.cli_commit()
14471448

1448-
conf = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit',
1449-
substring=' address-family l2vpn evpn', endsubsection='^ exit-address-family')
1450-
1451-
self.assertIn('neighbor peer1 route-reflector-client', conf)
1449+
def _set_neighbor_0(neighbor, remote_as_type):
1450+
# set route-reflector-client in neighbor and set remote-as in peer_group
1451+
interface_cmd = ['interface'] if neighbor.startswith('dum') else []
1452+
self.cli_set(base_path + ['peer-group', int_pg_names[0], 'remote-as', remote_as_type])
1453+
self.cli_set(base_path + ['neighbor', neighbor, 'address-family', 'ipv4-unicast', 'route-reflector-client'])
1454+
self.cli_set(base_path + ['neighbor', neighbor] + interface_cmd + ['peer-group', int_pg_names[0]])
1455+
1456+
def _set_neighbor_1(neighbor, remote_as_type):
1457+
# set route-reflector-client in peer_group and set remote-as in neighbor
1458+
interface_cmd = ['interface'] if neighbor.startswith('dum') else []
1459+
self.cli_set(base_path + ['peer-group', int_pg_names[1], 'address-family', 'ipv4-unicast', 'route-reflector-client'])
1460+
self.cli_set(base_path + ['neighbor', neighbor] + interface_cmd + ['remote-as', remote_as_type])
1461+
self.cli_set(base_path + ['neighbor', neighbor] + interface_cmd + ['peer-group', int_pg_names[1]])
1462+
1463+
def _set_neighbor_2(neighbor, remote_as_type):
1464+
# set route-reflector-client and remote-as in peer_group
1465+
interface_cmd = ['interface'] if neighbor.startswith('dum') else []
1466+
self.cli_set(base_path + ['peer-group', int_pg_names[2], 'remote-as', remote_as_type])
1467+
self.cli_set(base_path + ['peer-group', int_pg_names[2], 'address-family', 'ipv4-unicast', 'route-reflector-client'])
1468+
self.cli_set(base_path + ['neighbor', neighbor] + interface_cmd + ['peer-group', int_pg_names[2]])
1469+
1470+
def _set_neighbor_3(neighbor, remote_as_type):
1471+
# set route-reflector-client and remote-as in neighbor
1472+
interface_cmd = ['interface'] if neighbor.startswith('dum') else []
1473+
self.cli_set(base_path + ['neighbor', neighbor, 'address-family', 'ipv4-unicast', 'route-reflector-client'])
1474+
self.cli_set(base_path + ['neighbor', neighbor] + interface_cmd + ['remote-as', remote_as_type])
1475+
1476+
set_neighbor_funcs = [_set_neighbor_0, _set_neighbor_1, _set_neighbor_2, _set_neighbor_3]
1477+
for remote_as_type in remote_as_types:
1478+
for func_count, set_neighbor_func in enumerate(set_neighbor_funcs):
1479+
for neighbors in [int_neighbors, int_interfaces]:
1480+
set_neighbor_func(neighbors[func_count], remote_as_type)
1481+
if remote_as_type == 'external':
1482+
with self.assertRaises(ConfigSessionError) as e:
1483+
self.cli_commit()
1484+
self.cli_discard()
1485+
else:
1486+
self.cli_commit()
1487+
1488+
frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit', substring=' address-family ipv4 unicast', endsubsection='^ exit-address-family')
1489+
neighbor_has_rr_client = [
1490+
int_neighbors[0], int_neighbors[3],
1491+
int_interfaces[0], int_interfaces[3],
1492+
int_pg_names[1], int_pg_names[2],
1493+
]
1494+
[self.assertIn(f'neighbor {neighbor} route-reflector-client', frrconfig) for neighbor in neighbor_has_rr_client]
1495+
1496+
# tearDown dummy interfaces
1497+
self.cli_delete(['interfaces', 'dummy'])
1498+
self.cli_commit()
14521499

14531500
def test_bgp_28_peer_group_member_all_internal_or_external(self):
14541501
def _common_config_check(conf, include_ras=True):

src/conf_mode/protocols_bgp.py

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ def verify(config_dict):
316316
Warning(f'BGP neighbor "{peer}" requires address-family!')
317317

318318
# Peer-group member cannot override remote-as of peer-group
319+
peer_group = None
319320
if 'peer_group' in peer_config:
320321
peer_group = peer_config['peer_group']
321322
if 'remote_as' in peer_config and 'remote_as' in bgp['peer_group'][peer_group]:
@@ -330,6 +331,27 @@ def verify(config_dict):
330331
peer_group = peer_config['interface']['v6only']['peer_group']
331332
if 'remote_as' in peer_config['interface']['v6only'] and 'remote_as' in bgp['peer_group'][peer_group]:
332333
raise ConfigError(f'Peer-group member "{peer}" cannot override remote-as of peer-group "{peer_group}"!')
334+
335+
for afi in ['ipv4_unicast', 'ipv4_multicast', 'ipv4_labeled_unicast', 'ipv4_flowspec',
336+
'ipv6_unicast', 'ipv6_multicast', 'ipv6_labeled_unicast', 'ipv6_flowspec',
337+
'l2vpn_evpn']:
338+
if dict_search(
339+
f'address_family.{afi}.route_reflector_client',
340+
peer_config,
341+
) == {} or (
342+
peer_group
343+
and dict_search(
344+
f'peer_group.{peer_group}.address_family.{afi}.route_reflector_client',
345+
bgp,
346+
)
347+
== {}
348+
):
349+
peer_as = verify_remote_as(peer_config, bgp)
350+
if peer_as != 'internal' and peer_as != bgp['system_as']:
351+
raise ConfigError('route-reflector-client only supported for iBGP peers')
352+
else:
353+
# It doesn’t make sense to check the remote-as of a peer group.
354+
pass
333355

334356
# Only checks for ipv4 and ipv6 neighbors
335357
# Check if neighbor address is assigned as system interface address
@@ -412,20 +434,7 @@ def verify(config_dict):
412434
if tmp in afi_config['route_map']:
413435
verify_route_map(afi_config['route_map'][tmp], bgp)
414436

415-
if 'route_reflector_client' in afi_config:
416-
peer_as = peer_config.get('remote_as')
417-
418-
if peer_as is not None and (peer_as != 'internal' and peer_as != bgp['system_as']):
419-
raise ConfigError('route-reflector-client only supported for iBGP peers')
420-
else:
421-
# Check into the peer group for the remote as, if we are in a peer group, check in peer itself
422-
if 'peer_group' in peer_config:
423-
peer_group_as = dict_search(f'peer_group.{peer_group}.remote_as', bgp)
424-
elif neighbor == 'peer_group':
425-
peer_group_as = peer_config.get('remote_as')
426-
427-
if peer_group_as is None or (peer_group_as != 'internal' and peer_group_as != bgp['system_as']):
428-
raise ConfigError('route-reflector-client only supported for iBGP peers')
437+
# route-reflector-client verification has been moved to neighbor-only part
429438

430439
# T5833 not all AFIs are supported for VRF
431440
if 'vrf' in bgp and 'address_family' in peer_config:

0 commit comments

Comments
 (0)