Skip to content

Commit 66514ba

Browse files
authored
Implement 'bgp.rr_mesh' parameter to control IBGP sessions between RRs (#2847)
By default, netlab creates a full mesh of IBGP sessions between route reflectors in an AS. This commit introduces the 'bgp.rr_mesh' parameter (default: True) that controls the establishment of those sessions -- an IBGP session between a pair of route reflectors is not created when both nodes have 'bgp.rr_mesh' set to False Implements the suggestion by @aeangel in #2808
1 parent 4e8e85c commit 66514ba

File tree

5 files changed

+46
-57
lines changed

5 files changed

+46
-57
lines changed

docs/module/bgp.md

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ This configuration module configures the BGP routing process and BGP neighbors o
55

66
* EBGP sessions are established between directly connected IP addresses on every link where the connected routers belong to different autonomous systems. Parallel sessions are established for all address families (IPv4, IPv6) configured on the link.
77
* When two routers belong to the same autonomous system, netlab creates IBGP sessions between their loopback interfaces or with the first external interface if a router (or a routing daemon) does not have a loopback interface. Parallel sessions are established for all address families configured on the loopback interfaces.
8-
* IGBP sessions could form a full mesh (when no router reflectors are configured in the autonomous system) or a hubs-and-spokes topology with a single route reflector cluster and a full mesh of IBGP sessions between route reflectors.
9-
* Sessions (IBGP or EBGP) between directly connected IP addresses are established whenever the devices' real AS or local AS differ. This allows you to build scenarios like IBGP-over-EBGP (EVPN design) or IBGP mesh across multiple autonomous systems (ISP migration scenario).
8+
* IGBP sessions could form a full mesh (when no router reflectors are configured in the autonomous system) or a hubs-and-spokes topology with a single route reflector cluster and a (configurable) full mesh of IBGP sessions between route reflectors.
9+
* Sessions (IBGP or EBGP) between directly connected IP addresses are established whenever the devices' real AS or local AS differ. This allows you to build scenarios such as IBGP-over-EBGP (EVPN design) or an IBGP mesh across multiple autonomous systems (ISP migration scenario).
1010

1111
More interesting BGP topologies can be created with [custom plugins](../plugins.md).
1212

@@ -178,7 +178,8 @@ Advanced global configuration parameters include:
178178
* **bgp.community** -- configure BGP community propagation. By default, standard and extended communities are propagated to IBGP neighbors, and standard communities are propagated to EBGP neighbors. See *[BGP Community Propagation](#bgp-communities-propagation)* for more details.
179179
* **bgp.advertise_roles** -- a list of link types and roles. Links matching any element of the list will be advertised into BGP. See *[Advertised BGP Prefixes](bgp-advertise-prefix)* for details.
180180
* **bgp.ebgp_role** -- link role set on links connecting nodes from different autonomous systems. See *[Interaction with IGP](#interaction-with-igp)* for details.
181-
* **bgp.advertise_loopback** -- when set to `True` (default), the loopback IP addresses of the default loopback interface and any other [loopback links](links-loopback) are advertised as a BGP prefix. Set it to `False` in global defaults or as a node attribute to turn off loopback prefix advertisements.
181+
* **bgp.advertise_loopback** -- when set to `True` (default), the loopback IP addresses of the default loopback interface and any other [loopback links](links-loopback) are advertised as a BGP prefix. Set it to `False` in the global defaults or as a node attribute to turn off loopback prefix advertisements. You can also control the advertisement of individual loopback prefixes with the **bgp.advertise** interface attribute.
182+
* **bgp.rr_mesh** -- Set it to `False` (default: `True`) to remove the IBGP sessions between BGP route reflectors.
182183

183184
## Node Configuration Parameters
184185

@@ -207,6 +208,7 @@ Additional per-node BGP configuration parameters include:
207208
Finally, the BGP configuration module supports these advanced node parameters that you probably shouldn't touch without an excellent reason:
208209

209210
* **bgp.rr_cluster_id** -- set static route reflector cluster-ID. The default value is the lowest router ID of all route reflectors within the autonomous system.
211+
* **bgp.rr_mesh** -- Set it to `False` (default: `True`) to remove the IBGP sessions between BGP route reflectors.
210212
* **bgp.replace_global_as** (default: True) -- the default implementation of **neighbor local-as** command replaces the real autonomous system (**bgp.as**) with the *local* autonomous system. Set this parameter to *false* to turn off that functionality and include both autonomous systems in the AS path[^RAS_P].
211213
* **bgp.sessions** (node or global parameter) -- specifies which transport sessions (IPv4, IPv6) should be created for each BGP session type[^SESS_DM] (default: create all transport sessions). This parameter is a dictionary of address families (**ipv4** and **ipv6**) with values being a list of desired session types (**ibgp**, **ebgp**, **localas_ibgp**). See *[bgp-sessions](https://github.com/ipspace/netlab/blob/dev/tests/topology/input/bgp-sessions.yml)* test case for an example.
212214
* **bgp.activate** (node or global parameter) -- specifies which default address families (IPv4 AF on IPv4 session, IPv6 on IPv6 session) should be activated for each BGP session type[^ACT_CFG] (default: activate default address families on all BGP sessions). The format of this parameter is identical to the **bgp.sessions** parameter. See *[EVPN IBGP-over-EBGP](https://github.com/ipspace/netlab/blob/dev/tests/integration/evpn/12-vxlan-ibgp-ebgp.yml)* test case for an example.
@@ -235,7 +237,7 @@ Finally, the BGP configuration module supports these advanced node parameters th
235237

236238
**Limitations:**
237239

238-
* IBGP sessions cannot be used within a VRF instance. You can use the BGP **local-as** functionality to create what looks like an IBGP session to the BGP neighbors.
240+
* IBGP sessions cannot be used within a VRF instance. You can use the BGP **local-as** feature to create a session that behaves like an IBGP session.
239241
* You should not use the same BGP AS number on PE- and CE-routers; that would trigger the creation of impossible IBGP sessions between global PE loopbacks and in-VRF CE loopbacks. Use [](plugin-bgp-domain) to build a topology with overlapping AS numbers.
240242

241243
## Link-Level Parameters
@@ -274,7 +276,7 @@ The following IPv4/IPv6 prefixes are configured with **network** statements with
274276

275277
### Using bgp.advertise Link Attribute
276278

277-
* If you set **bgp.advertise** parameter on a link, all nodes connected to the link advertise the link prefix. In the following example, PE1 and PE2 advertise the link prefix.
279+
* If you set the **bgp.advertise** parameter on a link, all nodes connected to the link advertise the link prefix. In the following example, PE1 and PE2 advertise the link prefix.
278280

279281
```
280282
links:
@@ -310,7 +312,7 @@ An IP prefix assigned to a link with the **‌role** set to **‌stub** will not
310312

311313
### Using bgp.originate Node Attribute
312314

313-
When you set the **bgp.originate** parameter on a node, _netlab_ adds discard static routes for the IPv4 prefixes listed in that parameter prefix (the static routes point to *Null0*) and configures the corresponding BGP prefix.
315+
When a node has the **bgp.originate** parameter, _netlab_ adds discard static routes for the IPv4 prefixes listed in that parameter (the static routes point to *Null0*) and configures the corresponding BGP prefix.
314316

315317
For example, PE1 advertises `172.16.0.0/19' in the following topology. Please note that while the prefix is advertised via BGP, it does not have reachable IP addresses (the BGP prefix is based on a discard-everything static route).
316318

@@ -332,9 +334,10 @@ The BGP transformation module builds a list of BGP neighbors for every node. Tha
332334
(bgp-ibgp-sessions)=
333335
**IBGP sessions**
334336
* If there are no route reflectors within an autonomous system (no device within the autonomous system has **bgp.rr** set to *true*), you'll get a full mesh of IBGP sessions[^IB_D].
335-
* Router reflectors have IBGP sessions to all other nodes in the same AS. When the remote node is not a router reflector, *route-reflector-client* is configured on the IBGP session.
336337
* Route reflector clients have IBGP sessions with route reflectors (nodes within the same AS with **bgp.rr** set).
337-
* IBGP sessions are established between loopback interfaces. You should combine IBGP deployment with an IGP configuration module like [OSPF](ospf.md). The only exception to this rule is the routing daemons running on Linux hosts/containers that have no loopback interfaces -- their IBGP sessions originate from the IP address of the first physical interface.
338+
* Router reflectors usually have IBGP sessions to all other nodes in the same AS. When the remote node is not a router reflector, the *route-reflector-client* option is used on the IBGP session.
339+
* An IBGP session is not created between a pair of route reflectors if the **bgp.rr_mesh** parameter is set to `False` on both nodes.
340+
* IBGP sessions are established between loopback interfaces. You should combine IBGP deployment with an IGP configuration module (for example, [OSPF](ospf.md) or [IS-IS](isis.md)). The only exception to this rule is the routing daemons running on Linux hosts/containers that have no loopback interfaces -- their IBGP sessions originate from the IP address of the first physical interface.
338341
* Parallel IBGP sessions are established for all IP address families configured on loopback interfaces[^BSESS]. See also [IPv6 support](#ipv6-support).
339342

340343
[^IB_D]: Unless you disabled IBGP sessions with the **bgp.sessions** parameter ([more details](bgp-advanced-node))
@@ -344,7 +347,7 @@ The BGP transformation module builds a list of BGP neighbors for every node. Tha
344347
See the [IBGP Data Center Fabric](bgp_example/ibgp.md) example for more details.
345348

346349
```{tip}
347-
_netlab_ generates a warning for routers that have IBGP sessions without an underlying IGP. To turn off that warning (for example, when using IBGP-over-EBGP EVPN design), set **defaults.bgp.warnings.missing_igp** to _False_. To avoid IBGP sessions in scenarios that reuse the same BGP AS number on multiple sites, change the **‌[bgp.sessions](bgp-advanced-node)** parameter or use the [](plugin-bgp-domain).
350+
_netlab_ generates a warning for routers with IBGP sessions but no underlying IGP. To turn off that warning (for example, when using IBGP-over-EBGP EVPN design), set **defaults.bgp.warnings.missing_igp** to _False_. To avoid IBGP sessions in scenarios that reuse the same BGP AS number on multiple sites, change the **‌[bgp.sessions](bgp-advanced-node)** parameter or use the [](plugin-bgp-domain).
348351
```
349352

350353
(bgp-ebgp-sessions)=
@@ -423,7 +426,7 @@ nodes:
423426
community: [ standard, extended ]
424427
```
425428

426-
* A dictionary with two keys: **ibgp** and **ebgp**. The value of each key could be a string or a list (see above). The following example sets a network-wide default -- send standard and extended communities to the IBGP neighbors and standard communities to EBGP neighbors (this is the global default set in the built-in **topology-defaults.yml** file).
429+
* A dictionary with two keys: **ibgp** and **ebgp**. The value of each key could be a string or a list (see above). The following example sets a network-wide default -- send standard and extended communities to IBGP neighbors and standard communities to EBGP neighbors (this is the global default set in the built-in **topology-defaults.yml** file).
427430

428431
```
429432
bgp:
@@ -450,7 +453,7 @@ The **bgp.community** values can contain these keywords:
450453

451454
[^NAL]: Some devices might not propagate the large communities when using the **standard** keyword.
452455

453-
Only some devices support **large** and **2octet** keywords. Use the **[netlab show modules -m bgp](netlab-show-modules)** command to display BGP capabilities supported by individual devices and check the **community** column for more details. Devices without a value in that column support **standard** and **extended** keywords, but the meaning of the **standard** keyword might vary. Some devices (for example, Cisco IOSv and IOS XE) propagate large BGP communities as soon as the propagation of standard communities is configured. In contrast, others (for example, Arista EOS) require an explicit configuration of **large** community propagation.
456+
Only some devices support **large** and **2octet** keywords. Use the **[netlab show modules -m bgp](netlab-show-modules)** command to display BGP capabilities supported by individual devices and check the **community** column for more details. Devices without a value in that column support **standard** and **extended** keywords, but the meaning of the **standard** keyword might vary. Some devices (for example, Cisco IOSv and IOS XE) propagate large BGP communities as soon as the standard communities propagation is configured. In contrast, others (for example, Arista EOS) require an explicit configuration of **large** community propagation.
454457

455458
(bgp-confederations)=
456459
## BGP Confederations

netsim/modules/bgp.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,12 +183,17 @@ def build_ibgp_sessions(node: Box, sessions: Box, topology: Box) -> None:
183183
bgp_nhs = node.bgp.get("next_hop_self",None) # Do we have to set next hop on IBGP sessions?
184184
has_ibgp = False # Assume we have no IBGP sessions (yet)
185185
rrlist = [] if is_rr else find_bgp_rr(node_as,topology)
186-
186+
rr_mesh = node.bgp.get("rr_mesh",True) # Do we want to have a mesh between RRs (default: Yes)?
187187
if is_rr or not rrlist: # If the current node is RR or we have a full mesh
188188
ibgp_ngb_list = [ # ... we need IBGP sessions to all nodes in the AS
189189
ngb for ngb in topology.nodes.values() # ... but while building the node list
190190
if ngb.name != node.name and # ... skip current node
191191
ngb.get('bgp.as',None) == node_as] # ... and everyone not in the current AS (or not running BGP)
192+
if is_rr and not rr_mesh: # Are we a RR and the user hates inter-RR sessions?
193+
ibgp_ngb_list = [ # ... Let's exclude other RRs from neighbor list
194+
ngb for ngb in ibgp_ngb_list # Iterate over IBGP neighbors we found so far
195+
if not ngb.get('bgp.rr',False) # ... and keep the neighbor if it's not an RR
196+
or ngb.get('bgp.rr_mesh',True) ] # ... or if its rr_mesh is True (to keep symmetric sessions)
192197
else:
193198
ibgp_ngb_list = rrlist
194199

netsim/modules/bgp.yml

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
# BGP default settings and attributes
22
#
33
---
4-
ebgp_role: external
5-
advertise_roles: [ stub ]
6-
advertise_loopback: True
7-
community:
8-
ibgp: [ standard, extended ]
9-
ebgp: [ standard ]
104
no_propagate:
115
ebgp_role:
126
advertise_roles:
@@ -15,9 +9,18 @@ no_propagate:
159
confederation:
1610
transform_after: [ vlan ]
1711
config_after: [ routing, ospf, isis, eigrp, ripv2 ]
18-
next_hop_self: true
1912
hooks: [ normalize ]
2013

14+
# Default BGP attribute settings
15+
advertise_roles: [ stub ]
16+
advertise_loopback: True
17+
community:
18+
ibgp: [ standard, extended ]
19+
ebgp: [ standard ]
20+
ebgp_role: external
21+
next_hop_self: true
22+
23+
# Module attributes
2124
_top: # Define custom data types used by the BGP module
2225
attributes:
2326
bgp_session_type:
@@ -42,6 +45,7 @@ attributes:
4245
next_hop_self: bool
4346
rr_cluster_id: { type: ipv4, use: id }
4447
rr_list: list
48+
rr_mesh: bool # Rarely used, hard-coded default: True
4549
ebgp_role: str
4650
as_list: dict
4751
sessions:
@@ -73,15 +77,16 @@ attributes:
7377
as:
7478
type: asn
7579
_required: True
76-
next_hop_self:
80+
next_hop_self: { copy: global }
7781
rr: bool
78-
rr_cluster_id:
82+
rr_cluster_id: { copy: global }
83+
rr_mesh: { copy: global }
7984
originate:
8085
type: list
8186
_subtype: { type: ipv4, use: subnet_prefix, named: True }
82-
advertise_loopback:
83-
sessions:
84-
activate:
87+
advertise_loopback: { copy: global }
88+
sessions: { copy: global }
89+
activate: { copy: global }
8590
community: { copy: global }
8691
router_id: { type: ipv4, use: id }
8792
local_as: asn

tests/topology/expected/bgp-members.yml

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ bgp:
2020
- standard
2121
- extended
2222
next_hop_self: true
23+
rr_mesh: false
2324
groups:
2425
as65000:
2526
members:
@@ -159,6 +160,7 @@ nodes:
159160
type: ebgp
160161
next_hop_self: true
161162
router_id: 10.0.0.5
163+
rr_mesh: false
162164
box: cisco/iosv
163165
device: iosv
164166
id: 5
@@ -217,6 +219,7 @@ nodes:
217219
type: ebgp
218220
next_hop_self: true
219221
router_id: 10.0.0.6
222+
rr_mesh: false
220223
box: cisco/iosv
221224
device: iosv
222225
id: 6
@@ -305,6 +308,7 @@ nodes:
305308
type: ebgp
306309
next_hop_self: true
307310
router_id: 10.0.0.3
311+
rr_mesh: false
308312
box: cisco/iosv
309313
device: iosv
310314
id: 3
@@ -413,6 +417,7 @@ nodes:
413417
type: ebgp
414418
next_hop_self: true
415419
router_id: 10.0.0.4
420+
rr_mesh: false
416421
box: cisco/iosv
417422
device: iosv
418423
id: 4
@@ -482,21 +487,6 @@ nodes:
482487
- extended
483488
ipv4: true
484489
neighbors:
485-
- _source_intf:
486-
ifindex: 0
487-
ifname: Loopback0
488-
ipv4: 10.0.0.1/32
489-
neighbors: []
490-
type: loopback
491-
virtual_interface: true
492-
activate:
493-
ipv4: true
494-
as: 65000
495-
ipv4: 10.0.0.2
496-
name: rr2
497-
next_hop_self: ebgp
498-
rr: true
499-
type: ibgp
500490
- _source_intf:
501491
ifindex: 0
502492
ifname: Loopback0
@@ -531,6 +521,7 @@ nodes:
531521
router_id: 10.0.0.1
532522
rr: true
533523
rr_cluster_id: 10.0.0.1
524+
rr_mesh: false
534525
box: cisco/iosv
535526
device: iosv
536527
id: 1
@@ -589,21 +580,6 @@ nodes:
589580
- extended
590581
ipv4: true
591582
neighbors:
592-
- _source_intf:
593-
ifindex: 0
594-
ifname: Loopback0
595-
ipv4: 10.0.0.2/32
596-
neighbors: []
597-
type: loopback
598-
virtual_interface: true
599-
activate:
600-
ipv4: true
601-
as: 65000
602-
ipv4: 10.0.0.1
603-
name: rr1
604-
next_hop_self: ebgp
605-
rr: true
606-
type: ibgp
607583
- _source_intf:
608584
ifindex: 0
609585
ifname: Loopback0
@@ -638,6 +614,7 @@ nodes:
638614
router_id: 10.0.0.2
639615
rr: true
640616
rr_cluster_id: 10.0.0.1
617+
rr_mesh: false
641618
box: cisco/iosv
642619
device: iosv
643620
id: 2

tests/topology/input/bgp-members.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#
2-
# Sample multi-vendor configuration that tests most features supported by BGP configuration module
3-
#
4-
# Used in manual testing (feel free to write an automated test script ;)
2+
# Test pattern matching in bgp.as_list attributes and bgp.rr_mesh behavior
53
#
64
module: [bgp]
75

@@ -10,6 +8,7 @@ defaults:
108
bgp.warnings.missing_igp: False
119

1210
bgp:
11+
rr_mesh: False
1312
as_list:
1413
65000:
1514
members: [ rr1, rr*, pe*, pe2 ]

0 commit comments

Comments
 (0)