Skip to content

Commit

Permalink
RIPv2/RIPng route import (#1306)
Browse files Browse the repository at this point in the history
  • Loading branch information
ipspace authored Sep 7, 2024
1 parent be101e3 commit 465bdf3
Show file tree
Hide file tree
Showing 11 changed files with 158 additions and 25 deletions.
1 change: 1 addition & 0 deletions docs/caveats.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ See also [Cisco IOSv](caveats-iosv) SSH, OSPF, RIPng, and BGP caveats.
* Multiple OSPFv2 processes on Cisco IOS cannot have the same OSPF router ID. By default, _netlab_ generates the same router ID for global and VRF OSPF processes, resulting in non-fatal configuration errors that Ansible silently ignores.
* It's impossible to configure RIPv2 on individual subnets on Cisco IOS. RIPv2 might be running on more interfaces than intended. _netlab_ configures those interfaces to be *passive*.
* Cisco IOS does not support passive interfaces in RIPng.
* Cisco IOS requires a *default metric* when redistributing routes into RIPv2. The RIPv2 configuration template sets the default metric to the value of the **netlab_ripv2_default_metric** node parameter (default: 5)
* You cannot use VLANs 1002 through 1005 with Cisco IOSvL2 image

(cisco-iosv-ssh)=
Expand Down
20 changes: 11 additions & 9 deletions docs/module/ripv2.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ This configuration module configures the RIPv2 and RIPng. The module supports th

The following table describes per-platform support of individual RIPv2/RIPng features:

| Operating system | IPv4<br>(RIPv2) | IPv6<br>(RIPng) | Passive<br>interfaces |
| ------------------ | :-: | :-: | :-: |
| Arista EOS ||||
| Cisco IOSv/IOSvL2 |||[](caveats-iosv) |
| Cisco IOS XE[^18v] |||[](caveats-iosv) |
| Cumulus Linux ||||
| FRR ||||
| VyOS ||||
| Operating system | IPv4<br>(RIPv2) | IPv6<br>(RIPng) | Passive<br>interfaces | Route<br>import |
| ------------------ | :-: | :-: | :-: | :-: |
| Arista EOS |||||
| Cisco IOSv/IOSvL2 |||[](caveats-iosv) |[](caveats-iosv) |
| Cisco IOS XE[^18v] |||[](caveats-iosv) |[](caveats-iosv) |
| Cumulus Linux |||||
| FRR |||||
| VyOS |||||

```{tip}
See [RIP Integration Tests Results](https://release.netlab.tools/_html/coverage.ripv2) for more details.
Expand All @@ -34,7 +34,9 @@ See [RIP Integration Tests Results](https://release.netlab.tools/_html/coverage.

## Lab Topology Parameters

RIPv2/RIPng module does not have global or node parameters. It supports [](routing_passive) and [](routing_external).
RIPv2/RIPng module does not have global parameters. The only relevant node parameter is the **ripv2.import** parameter specifying the [import (redistribution) of routes](routing_import) into the global RIP instance (default: no route import).

RIPv2 also supports [](routing_passive) and [](routing_external).

## Example

Expand Down
12 changes: 6 additions & 6 deletions netsim/ansible/templates/bgp/ios.j2
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
ip bgp-community new-format
!
router bgp {{ bgp.as }}
no bgp default ipv4-unicast
bgp update-delay 5
bgp nopeerup-delay cold-boot 1
bgp nopeerup-delay user-initiated 1
no bgp default ipv4-unicast
bgp update-delay 5
bgp nopeerup-delay cold-boot 1
bgp nopeerup-delay user-initiated 1
{% if bgp.router_id|ipv4 %}
bgp router-id {{ bgp.router_id }}
bgp router-id {{ bgp.router_id }}
{% endif %}
{% if bgp.rr|default(False) and bgp.rr_cluster_id|default(False) %}
bgp cluster-id {{ bgp.rr_cluster_id }}
bgp cluster-id {{ bgp.rr_cluster_id }}
{% endif %}
{#
Configure IPv4 and IPv6 BGP neighbors
Expand Down
13 changes: 8 additions & 5 deletions netsim/ansible/templates/ripv2/frr.j2
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
{% import "templates/routing/_redistribute.frr.j2" as redistribute with context %}
!
{% if ripv2.af.ipv4|default(False) %}
router rip
version 2
version 2
{{ redistribute.config(ripv2,af='ipv4') }}
{% for intf in netlab_interfaces if 'ripv2' in intf and 'ipv4' in intf %}
network {{ intf.ifname }}
network {{ intf.ifname }}
{% if intf.ripv2.passive|default(False) %}
passive-interface {{ intf.ifname }}
passive-interface {{ intf.ifname }}
{% endif %}
{% endfor %}
{% endif %}
!
{% if ripv2.af.ipv6|default(False) %}
router ripng
{{ redistribute.config(ripv2,af='ipv6') }}
{% for intf in netlab_interfaces if 'ripv2' in intf and 'ipv6' in intf %}
network {{ intf.ifname }}
network {{ intf.ifname }}
{% if intf.ripv2.passive|default(False) %}
passive-interface {{ intf.ifname }}
passive-interface {{ intf.ifname }}
{% endif %}
{% endfor %}
{% endif %}
Expand Down
13 changes: 10 additions & 3 deletions netsim/ansible/templates/ripv2/ios.j2
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
{% import "templates/routing/_redistribute.ios.j2" as redistribute with context %}
!
{% if ripv2.af.ipv4|default(False) %}
router rip
version 2
no auto-summary
version 2
no auto-summary
{% if 'import' in ripv2 %}
default-metric {{ netlab_ripv2_default_metric|default(5) }}
{% endif %}
{{ redistribute.config(ripv2,af='ipv4',ospf_pid=ospf.process|default(1)) }}
{% for intf in netlab_interfaces if 'ipv4' in intf and not 'vrf' in intf %}
network {{ intf.ipv4|ipaddr('address') }}
{% if intf.ripv2.passive|default(False) or not 'ripv2' in intf %}
passive-interface {{ intf.ifname }}
passive-interface {{ intf.ifname }}
{% endif %}
{% endfor %}
{% endif %}
!
{% if ripv2.af.ipv6|default(False) %}
ipv6 router rip Gandalf
{{ redistribute.config(ripv2,af='ipv6',ospf_pid=ospf.process|default(1)) }}
!
{% for intf in netlab_interfaces if 'ripv2' in intf and 'ipv6' in intf %}
!
interface {{ intf.ifname }}
Expand Down
2 changes: 2 additions & 0 deletions netsim/ansible/templates/routing/_redistribute.ios.j2
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
{% set sp_config = sp_config + ' ' + isis.instance + ' level-1-2' %}
{% elif s_proto == 'ospf' %}
{% set sp_config = sp_config + ' ' + ospf_pid|string + ' match internal external' %}
{% elif s_proto == 'rip' and af == 'ipv6' %}
{% set sp_config = sp_config + ' Gandalf' %}
{% endif %}
redistribute {{ sp_config }}{{ policy(s_data,af) }}
{% endfor %}
Expand Down
1 change: 1 addition & 0 deletions netsim/devices/cumulus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ features:
ipv4: true
ipv6: true
passive: true
import: [ bgp, isis, ospf, connected ]
routing:
policy:
set:
Expand Down
3 changes: 2 additions & 1 deletion netsim/devices/frr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ features:
irb: true
asymmetrical_irb: True
isis:
import: [ bgp, ripv2, ospf, connected, vrf ]
import: [ bgp, ripv2, ospf, connected ]
unnumbered:
ipv4: true
ipv6: true
Expand All @@ -81,6 +81,7 @@ features:
ipv4: true
ipv6: true
passive: true
import: [ bgp, isis, ospf, connected ]
routing:
policy:
set:
Expand Down
3 changes: 2 additions & 1 deletion netsim/devices/iosv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ features:
ipv6:
lla: true
isis:
import: [ bgp, ospf, ripv2, connected, vrf ]
import: [ bgp, ospf, ripv2, connected ]
unnumbered:
ipv4: true
ipv6: true
Expand All @@ -69,6 +69,7 @@ features:
ipv4: true
ipv6: true
passive: true
import: [ bgp, isis, ospf, connected ]
routing:
policy:
set:
Expand Down
1 change: 1 addition & 0 deletions netsim/modules/ripv2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ attributes:
_alt_types: [ bool ]
node:
af:
import: _r_import
vrf:
active: bool
link:
Expand Down
114 changes: 114 additions & 0 deletions tests/integration/ripv2/21-import-ds.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
message: |
Use this topology to test the two-way redistribution between RIPv2 and OSPFv2/OSPFv3/BGP
defaults.interfaces.mtu: 1500

addressing:
loopback:
ipv6: 2001:db8:1::/48
lan:
ipv6: 2001:db8:2::/48
p2p:
ipv6: 2001:db8:3::/48

groups:
probes:
device: frr
provider: clab
members: [ x1, r2, r3 ]

nodes:
dut:
module: [ bgp, ripv2, ospf ]
bgp.as: 65000
bgp.import: [ ripv2 ]
ospf.import: [ ripv2 ]
ripv2.import: [ bgp, ospf ]
x1:
bgp.as: 65100
module: [ bgp ]
r2:
module: [ ospf ]
r3:
module: [ ripv2 ]

links:
- r3
- dut-x1
- dut-r2
- dut-r3

validate:
ipv4_ebgp:
description: IPv4 EBGP session (X1-DUT) should be established
wait_msg: Wait for EBGP session
wait: 20
nodes: [ x1 ]
plugin: bgp_neighbor(node.bgp.neighbors,'dut')
ipv6_ebgp:
description: IPv6 EBGP session (X1-DUT) should be established
wait_msg: Wait for EBGP session
wait: 20
nodes: [ x1 ]
plugin: bgp_neighbor(node.bgp.neighbors,'dut',af='ipv6')
ipv4_ospf:
description: OSPF session (R2-DUT) should be established
wait_msg: Wait for OSPF session
wait: 20
nodes: [ r2 ]
plugin: ospf_neighbor(nodes.dut.ospf.router_id)
ipv6_ospf:
description: OSPFv3 session (R2-DUT) should be established
wait_msg: Wait for OSPF session
wait: 30
nodes: [ r2 ]
plugin: ospf6_neighbor(nodes.dut.ospf.router_id)
rip_bgp_v4:
description: Check whether X1 BGP IPv4 prefix is redistributed into RIP
wait: 30
wait_msg: Waiting for the loopback prefix to be originated and redistributed
nodes: [ r3 ]
plugin: rt_prefix(pfx=nodes.x1.loopback.ipv4,af='ipv4',proto='rip')
rip_bgp_v6:
description: Check whether X1 BGP IPv6 prefix is redistributed into RIP
wait: 10
wait_msg: Waiting for the loopback prefix to be originated and redistributed
nodes: [ r3 ]
plugin: rt_prefix(pfx=nodes.x1.loopback.ipv6,af='ipv6',proto='rip')
rip_ospf_v4:
description: Check whether R2 OSPF IPv4 prefix is redistributed into RIP
wait: 15
wait_msg: Waiting for the loopback prefix to be originated and redistributed
nodes: [ r3 ]
plugin: rt_prefix(pfx=nodes.r2.loopback.ipv4,af='ipv4',proto='rip')
rip_ospf_v6:
description: Check whether R2 OSPF IPv6 prefix is redistributed into RIP
wait: 10
wait_msg: Waiting for the loopback prefix to be originated and redistributed
nodes: [ r3 ]
plugin: rt_prefix(pfx=nodes.r2.loopback.ipv6,af='ipv6',proto='rip')
ospf_v4:
description: Check whether R3 RIP IPv4 prefix is redistributed into OSPF
wait: 20
wait_msg: Waiting for the loopback prefix to be originated and redistributed
nodes: [ r2 ]
plugin: ospf_prefix(pfx=nodes.r3.loopback.ipv4)
ospf_v6:
description: Check whether R3 RIP IPv6 prefix is redistributed into OSPF
wait: 10
wait_msg: Waiting for the loopback prefix to be originated and redistributed
nodes: [ r2 ]
plugin: ospf6_prefix(pfx=nodes.r3.interfaces[0].ipv6)
bgp_v4:
description: Check whether R3 RIP IPv4 prefix is redistributed into BGP
wait: 5
wait_msg: Waiting for the loopback prefix to be originated and redistributed
nodes: [ x1 ]
plugin: bgp_prefix(pfx=nodes.r3.loopback.ipv4,af='ipv4')
bgp_v6:
description: Check whether R3 RIP IPv6 prefix is redistributed into BGP
wait: 5
wait_msg: Waiting for the loopback prefix to be originated and redistributed
nodes: [ x1 ]
plugin: bgp_prefix(pfx=nodes.r3.interfaces[0].ipv6,af='ipv6')

0 comments on commit 465bdf3

Please sign in to comment.