Skip to content

Commit a22cf73

Browse files
authored
Plugin examples: SR-ISIS TE with (attempted) MACsec encryption (#3)
Co-authored-by: Jeroen van Bemmel <[email protected]>
1 parent f68a98d commit a22cf73

File tree

9 files changed

+322
-1
lines changed

9 files changed

+322
-1
lines changed

routing/sr-isis-te/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# L2 example: ePipe service over SR-ISIS with Traffic Engineering and MACsec
2+
3+
See [original use case by Derek Cheung](https://medium.com/r/?url=https%3A%2F%2Fderekcheung.medium.com%2Fsegment-routing-b69f6ea2e3f5)
4+
5+
Netsim-Tools release 1.0.6 introduces support for [custom plugins](https://github.com/ipspace/netsim-tools/blob/master/docs/plugins.md).
6+
This example illustrates 3 of them:
7+
* An MPLS-TE plugin to define custom MPLS paths
8+
* An SDP ePipe plugin to build ePipe services
9+
* A MACSEC plugin to configure security parameters
10+
11+
All plugins are relatively simple, by design; following the [Unix philosophy](https://en.wikipedia.org/wiki/Unix_philosophy):
12+
* Make each program do one thing well. To do a new job, build afresh rather than complicate old programs by adding new "features".
13+
* Expect the output of every program to become the input to another, as yet unknown, program. Don't clutter output with extraneous information. Avoid stringently columnar or binary input formats. Don't insist on interactive input.
14+
* Design and build software, even operating systems, to be tried early, ideally within weeks. Don't hesitate to throw away the clumsy parts and rebuild them.
15+
* Use tools in preference to unskilled help to lighten a programming task, even if you have to detour to build the tools and expect to throw some of them out after you've finished using them.
16+
17+
## Modeling extended L2 segments
18+
This use case is different in that it models an extended L2 service: Host 1 and host 2 are both on the same subnet,
19+
separated by an MPLS network topology that features a traffic-engineered ePipe service over SR-ISIS.
20+
21+
Netsim-Tools currently assumes 'atomic' links, i.e. different links are assigned different prefixes from a pool.
22+
This example uses custom manual addressing; including these concepts in Netsim-Tools is FFS.
23+
24+
## MACsec: For Future Study / work in progress
25+
Note that the MACsec association doesn't currently work in this setup: MACsec is designed for hop-by-hop security, and this multi-hop MPLS scenario requires more thought/knobs.

routing/sr-isis-te/epipe.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from box import Box
2+
3+
def post_transform(topo: Box) -> None:
4+
"""
5+
Processes links with 'epipe' attribute, and resolves to the loopback IP of the peer
6+
"""
7+
print( f"JvB epipe post_transform" )
8+
9+
# Need to modify node.links, not global topo.links
10+
for node in topo.nodes.values():
11+
for link in node.links: # topo.links:
12+
if 'epipe' in link:
13+
peer = topo.nodes[ link.epipe ].loopback.ipv4
14+
print( f"JvB: Resolved {link.epipe} to {peer}" )
15+
link.epipe_peer = peer
16+
17+
# Check consistency of models
18+
# print( f"POST: nodes={topo.nodes}" )
19+
# print( f"POST: links={topo.links}" )

routing/sr-isis-te/macsec.j2

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{# assumes addressing pools are extended with MACsec parameters #}
2+
updates:
3+
{% for l in links if l.type=='lan' and 'macsec' in pools['lan'] %}
4+
{% set macsec = pools['lan'].macsec %}
5+
{% set port_id = l.ifname + ('/1' if 'c' in l.ifname else '') %}
6+
{% set ca_name = "to-%s" | format( l.epipe|default('wherever') ) %}
7+
- path: configure/macsec/connectivity-association[ca-name={{ ca_name }}]
8+
val:
9+
admin-state: enable
10+
macsec-encrypt: True
11+
static-cak:
12+
pre-shared-key:
13+
- psk-id: 1
14+
encryption-type: aes-128-cmac
15+
cak: {{ macsec.cak }}
16+
cak-name: {{ macsec.cak_name }}
17+
18+
- path: configure/port[port-id={{port_id}}]/ethernet/dot1x/macsec/sub-port[sub-port-id=1]
19+
val:
20+
admin-state: disable # Disable for now, still missing some way to establish multi-hop MACsec
21+
ca-name: "{{ ca_name }}"
22+
max-peers: 1
23+
24+
{% endfor %}

routing/sr-isis-te/mpls-te-path.j2

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{# epipe modeled as a virtual link between r1-r4 #}
2+
updates:
3+
{% for l in links if 'te_path_ips' in l %}
4+
{% set lsp_name = "lsp_" + l.traffic_engineering_path|join('-') + "-TE" %}
5+
- path: configure/router[router-name=Base]/mpls
6+
val:
7+
admin-state: enable
8+
path:
9+
- path-name: "{{ l.traffic_engineering_path|join('-') }}-TE-strict"
10+
admin-state: enable
11+
hop:
12+
{% for ip in l.te_path_ips %}
13+
- hop-index: {{ loop.index }}
14+
ip-address: "{{ ip|ipaddr('address') }}"
15+
type: strict
16+
{% endfor %}
17+
18+
lsp:
19+
- lsp-name: "{{ lsp_name }}"
20+
admin-state: enable
21+
type: p2p-sr-te
22+
to: "{{ l.te_path_ips[-1]|ipaddr('address') }}"
23+
primary:
24+
- path-name: "{{ l.traffic_engineering_path|join('-') }}-TE-strict"
25+
26+
{# Activate the LSP path, disabling the SR-ISIS shortest IGP path #}
27+
- path: configure/service/sdp[sdp-id={{l.ifindex}}]
28+
val:
29+
sr-isis: False
30+
lsp:
31+
- lsp-name: "{{ lsp_name }}"
32+
33+
{% endfor %}
34+
35+
# RSVP must be present along with mpls, even though it is not used here
36+
- path: configure/router[router-name=Base]/rsvp
37+
val: {}
38+
39+
# Remove system interface from MPLS
40+
delete:
41+
- configure/router[router-name=Base]/mpls/interface[interface-name=system]

routing/sr-isis-te/mpls-te.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from box import Box
2+
from netsim import common
3+
4+
def post_transform(topo: Box) -> None:
5+
"""
6+
Processes links with 'traffic-engineering-path' attribute, and resolves
7+
the loopback IPs of the peers included in the path
8+
"""
9+
print( f"JvB mpls-te post_transform" )
10+
11+
# Need to modify node.links, not global topo.links
12+
for node in topo.nodes.values():
13+
for link in node.links: # topo.links:
14+
if 'traffic_engineering_path' in link:
15+
te_path_ips = []
16+
for node in link.traffic_engineering_path:
17+
if node not in topo.nodes:
18+
common.error( f"Invalid node in TE-path: {node}", module='mpls-te')
19+
continue
20+
te_path_ips.append( topo.nodes[ node ].loopback.ipv4 )
21+
link.te_path_ips = te_path_ips
22+
23+
# Check consistency of models
24+
# print( f"POST: nodes={topo.nodes}" )
25+
# print( f"POST: links={topo.links}" )

routing/sr-isis-te/sdp-epipe.j2

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{# epipe modeled as a virtual link between r1-r4 #}
2+
updates:
3+
{% for l in links if 'epipe_peer' in l %}
4+
{% set peer=l.epipe_peer|ipaddr('address') %}
5+
- path: configure/router[router-name=Base]/ldp
6+
val:
7+
admin-state: enable
8+
targeted-session:
9+
peer:
10+
- ip-address: "{{ peer }}"
11+
12+
- path: configure/service/sdp[sdp-id={{l.ifindex}}]
13+
val:
14+
admin-state: enable
15+
delivery-type: mpls
16+
sr-isis: True
17+
far-end:
18+
ip-address: "{{ peer }}"
19+
20+
# Note: could set md-auto-id service range
21+
{% set svc_id = 100 + l.ifindex %}
22+
- path: configure/service/epipe[service-name=to-{{l.epipe}}]
23+
val:
24+
admin-state: enable
25+
customer: "1"
26+
service-id: {{ svc_id }}
27+
spoke-sdp:
28+
- sdp-bind-id: "{{ l.ifindex }}:{{ svc_id }}"
29+
admin-state: enable
30+
# Could enable BFD here too...
31+
sap:
32+
- sap-id: "{{ l.ifname }}{{ '/1' if 'c' in l.ifname else '' }}"
33+
admin-state: enable
34+
{% endfor %}
35+
36+
{# FFS: MACsec encryption #}

routing/sr-isis-te/topology.yml

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#
2+
# Inspired by https://derekcheung.medium.com/segment-routing-b69f6ea2e3f5
3+
# this topology demonstrates SR-ISIS between SROS devices,
4+
# including Loop-Free-Alternative and MPLS-TE use cases
5+
#
6+
# The goal: demonstrate the power of networking
7+
#
8+
9+
provider: clab
10+
11+
module: [ bfd, isis, sr ]
12+
13+
plugin: [ epipe, mpls-te ]
14+
15+
defaults:
16+
# custom_link_types: [ epipe ]
17+
device: sros
18+
devices:
19+
sros:
20+
# interface_name: 1/1/%d # sr-a4 does not use connectors
21+
interface_name: 1/x1/1/c%d # sr-1s use connectors and XIOM
22+
providers:
23+
clab:
24+
devices:
25+
srlinux:
26+
provider_type: ixr6 # Need IXR for MPLS support
27+
sros:
28+
provider_type: sr-1s-macsec # Added to vrnetlab to support macsec
29+
30+
isis.traffic_engineering: True
31+
isis.loop_free_alternate: True
32+
33+
addressing:
34+
lan:
35+
ipv4: 192.168.1.0/24 # "Must be longer than /24"
36+
macsec: # Custom parameters used by macsec plugin, ends up in group_vars
37+
cak: "228ef255aa23ff6729ee664acb66e91f"
38+
cak_name: "37c9c2c45ddd012aa5bc8ef284aa23ff6729ee2e4acb66e91fe34ba2cd9fe311"
39+
40+
groups:
41+
sros:
42+
members: [ r1,r4 ]
43+
config: [ sdp-epipe.j2, macsec.j2 ]
44+
srlinux:
45+
members: [ r2,r3 ]
46+
hosts:
47+
members: [ h1,h2 ]
48+
49+
nodes:
50+
# Edge router
51+
r1:
52+
device: sros
53+
license: /Projects/SR_OS_VSR-SIM_license.txt
54+
config: [ mpls-te-path.j2 ]
55+
56+
# Core routers (future SRL), need sros for SR-TE and Adj SIDs
57+
r2:
58+
device: sros
59+
license: /Projects/SR_OS_VSR-SIM_license.txt
60+
r3:
61+
device: sros
62+
license: /Projects/SR_OS_VSR-SIM_license.txt
63+
64+
r4:
65+
device: sros
66+
license: /Projects/SR_OS_VSR-SIM_license.txt
67+
68+
# Hosts connected via L2 ePipe
69+
h1:
70+
device: linux
71+
module: []
72+
h2:
73+
device: linux
74+
module: []
75+
76+
links:
77+
# Core links
78+
- r1-r2
79+
- r1-r3
80+
- r2-r3
81+
- r2-r4
82+
- r3-r4
83+
84+
- type: lan
85+
# role: lan cannot use this, assigns different prefixes from pool
86+
prefix: 192.168.1.0/24
87+
r1:
88+
ipv4: False
89+
epipe: r4
90+
traffic_engineering_path: [ r3, r2, r4 ]
91+
h1:
92+
ipv4: 1 # Relative IP addressing offset into prefix
93+
94+
- type: lan
95+
# role: lan
96+
prefix: 192.168.1.0/24
97+
r4:
98+
ipv4: False
99+
epipe: r1
100+
h2:
101+
ipv4: 2
102+
103+
# Could model ePipe service as a special type of 'link', but custom types not allowed
104+
# Also, this does not make the association with the port on which h1/h2 are connected
105+
# - type: epipe
106+
# r1:
107+
# ipv4: 10.0.0.1/32 # TODO get from loopback.ipv4
108+
# r4:
109+
# ipv4: 10.0.0.4/32 # TODO get from loopback

routing/sr-mpls-bgp-srlinux/topology.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ defaults:
1616
srlinux:
1717
provider_type: ixr6 # SR-MPLS only supported on 7250 IXR platform
1818

19+
addressing:
20+
unnumbered:
21+
unnumbered: True
22+
# p2p:
23+
# ipv6: 2001:db8:1234::/48 # Links need ipv6 in order to form ISIS adjacencies
24+
# loopback:
25+
# ipv6: 2001:db8:cafe::/48
26+
1927
# SR Global Block label range
2028
sr.srgb_range_start: 500000
2129
sr.srgb_range_size: 1000
@@ -66,7 +74,11 @@ links:
6674
- e1-c1
6775
- e1-c2
6876
- e2-c1
69-
- e2-c2
77+
78+
- e2:
79+
c2:
80+
# unnumbered: True
81+
role: unnumbered
7082

7183
# External links
7284
- x1-e1

topology/LAN/topology.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Test multi-node links
2+
#
3+
provider: clab
4+
5+
defaults:
6+
device: srlinux
7+
8+
nodes:
9+
- r1
10+
- r2
11+
- r3
12+
13+
links:
14+
15+
# P2P link
16+
- r1-r2
17+
18+
# LAN link
19+
- [ r1, r2, r3 ]
20+
21+
# Named P2P link
22+
- r1:
23+
r2:
24+
name: P2P link
25+
26+
# Named LAN link
27+
- r1:
28+
r2:
29+
r3:
30+
name: LAN link

0 commit comments

Comments
 (0)