Examples to understand the support of MPLS in NeST¶
This directory contains the examples to demonstrate how Multi Protocol Label
Switching (MPLS) can be used in NeST
.
IMPORTANT
Note 1: MPLS modules are not enabled by default in Linux. Hence, before
running these programs, enable the MPLS modules as explained below (ignore if
MPLS modules are already enabled):
modprobe mpls_iptunnel
modprobe mpls_router
modprobe mpls_gso
Verify whether the MPLS modules are loaded:
`lsmod | grep mpls`
Note 2: The third example listed below, which demonstrates the usage of Label
Distribution Protocol (LDP), requires Free Range Routing (FRR) suite to be
pre-installed. See the README in examples/routing/frr
to install FRR. It is
highly recommended that, after installing FRR, at least one of the examples
provided in examples/routing/frr
is run to confirm that FRR is successfully
installed.
1. mpls-basic-ce-pe-routers.py¶
This program demonstrates how to set up a MPLS network that connects two
customer edge (ce) routers ce1
and ce2
via two provider edge (pe) routers
pe1
and pe2
. All routers are MPLS enabled. The labels are assigned
manually and Penultimate Hop Popping (PHP) is used in this program. Address
helper is used to assign the IPv4 addresses to the interfaces. Five ping
packets are sent from ce1
to ce2
, and the success/failure of these packets
is reported.
1# SPDX-License-Identifier: GPL-2.0-only
2# Copyright (c) 2019-2022 NITK Surathkal
3
4########################
5# SHOULD BE RUN AS ROOT
6########################
7from nest.topology import *
8from nest.topology.network import Network
9from nest.topology.address_helper import AddressHelper
10
11# This program demonstrates how to set up a MPLS network that connects two
12# customer edge (ce) routers `ce1` and `ce2` via two provider edge (pe) routers
13# `pe1` and `pe2`. All routers are MPLS enabled. The labels are assigned
14# manually and Penultimate Hop Popping (PHP) is used in this program. Address
15# helper is used to assign the IPv4 addresses to the interfaces. Five ping
16# packets are sent from `ce1` to `ce2`, and the success/failure of these
17# packets is reported.
18
19##################################################################################
20# Network Topology #
21# #
22# Label: 101 --> Label: 102 --> PHP #
23# #
24# 50mbit, 5ms --> 10mbit, 10ms --> 50mbit, 5ms --> #
25# ce1 -------------------- pe1 -------------------- pe2 -------------------- ce2 #
26# <-- 50mbit, 5ms <-- 10mbit, 10ms <-- 50mbit, 5ms #
27# #
28# PHP <-- Label: 202 <-- Label: 201 #
29# #
30##################################################################################
31
32# Create two ce routers `ce1` and `ce2`, and two pe routers `pe1` and `pe2`
33ce1 = Router("ce1")
34ce2 = Router("ce2")
35pe1 = Router("pe1")
36pe2 = Router("pe2")
37
38# Set the IPv4 address for the networks.
39# This example has three networks: one on the left of `pe1`, second between
40# the two `pe` routers, and third on the right of `pe2`.
41n1 = Network("192.168.1.0/24") # network on the left of `pe1`
42n2 = Network("192.168.2.0/24") # network between two `pe` routers
43n3 = Network("192.168.3.0/24") # network on the right of `pe2`
44
45# Connect `ce1` to `pe1`, `pe1` to `pe2`, and then `pe2` to `ce2`
46# `etce1` and `etce2` are the interfaces at `ce1` and `ce2`, respectively.
47# `etpe1a` is the first interface at `pe1` which connects it with `ce1`
48# `etpe1b` is the second interface at `pe1` which connects it with `pe2`
49# `etpe2a` is the first interface at `pe2` which connects it with `pe1`
50# `etpe2b` is the second interface at `pe2` which connects it with `ce2`
51(etce1, etpe1a) = connect(ce1, pe1, network=n1)
52(etpe1b, etpe2a) = connect(pe1, pe2, network=n2)
53(etpe2b, etce2) = connect(pe2, ce2, network=n3)
54
55# Assign IPv4 addresses to all the interfaces in the network.
56AddressHelper.assign_addresses()
57
58# Enable MPLS on all the interfaces in the network
59etce1.enable_mpls()
60etpe1a.enable_mpls()
61etpe1b.enable_mpls()
62etpe2a.enable_mpls()
63etpe2b.enable_mpls()
64etce2.enable_mpls()
65
66# Configure MPLS routes: `ce1` --> `pe1` --> `pe2` --> `ce2`
67ce1.add_route_mpls_push("192.168.3.0/24", etpe1a.address, 101) # Push label 101
68pe1.add_route_mpls_switch(101, etpe2a.address, 102) # Replace label 101 by 102
69pe2.add_route_mpls_pop(102, etce2.address) # Pop label 102 (PHP)
70
71# Configure MPLS routes: `ce2` --> `pe2` --> `pe1` --> `ce1`
72ce2.add_route_mpls_push("192.168.1.0/24", etpe2b.address, 201) # Push label 201
73pe2.add_route_mpls_switch(201, etpe1b.address, 202) # Replace label 201 by 202
74pe1.add_route_mpls_pop(202, etce1.address) # Pop label 202 (PHP)
75
76# Set the link attributes: `ce1` --> `pe1` --> `pe2` --> `ce2`
77etce1.set_attributes("50mbit", "5ms") # from `ce1` to `pe1`
78etpe1b.set_attributes("10mbit", "10ms") # from `pe1` to `pe2`
79etpe2b.set_attributes("50mbit", "5ms") # from `pe2` to `ce2`
80
81# Set the link attributes: `ce2` --> `pe2` --> `pe1` --> `ce1`
82etce2.set_attributes("50mbit", "5ms") # from `ce2` to `pe2`
83etpe2a.set_attributes("10mbit", "10ms") # from `pe2` to `pe1`
84etpe1a.set_attributes("50mbit", "5ms") # from `pe1` to `ce1`
85
86# `Ping` from `ce1` to `ce2`.
87ce1.ping(etce2.address)
2. mpls-ce-pe-p-routers.py¶
This program demonstrates how to set up a MPLS network that connects two
customer edge (ce) routers ce1
and ce2
via two provider edge (pe) routers
pe1
and pe2
, which are further connected via a provider (p) router. Only
pe
and p
routers are MPLS enabled. ce
routers do not use MPLS. The
labels are assigned manually and Penultimate Hop Popping (PHP) is used in
this program. Address helper is used to assign the IPv4 addresses to the
interfaces. Five ping packets are sent from ce1
to ce2
, and the
success/failure of these packets is reported.
1# SPDX-License-Identifier: GPL-2.0-only
2# Copyright (c) 2019-2022 NITK Surathkal
3
4########################
5# SHOULD BE RUN AS ROOT
6########################
7from nest.topology import *
8from nest.topology.network import Network
9from nest.topology.address_helper import AddressHelper
10
11# This program demonstrates how to set up a MPLS network that connects two
12# customer edge (ce) routers `ce1` and `ce2` via two provider edge (pe) routers
13# `pe1` and `pe2`, which are further connected via a provider (p) router. Only
14# `pe` and `p` routers are MPLS enabled. `ce` routers do not use MPLS. The
15# labels are assigned manually and Penultimate Hop Popping (PHP) is used in
16# this program. Address helper is used to assign the IPv4 addresses to the
17# interfaces. Five ping packets are sent from `ce1` to `ce2`, and the
18# success/failure of these packets is reported.
19
20###################################################################################
21# Network Topology #
22# #
23# Label: 101 --> PHP #
24# #
25# 50mbit, 5ms -> 10mbit, 10ms -> 10mbit, 10ms -> 50mbit, 5ms -> #
26# ce1 -------------- pe1 --------------- p --------------- pe2 -------------- ce2 #
27# <- 50mbit, 5ms <- 10mbit, 10ms <- 10mbit, 10ms <- 50mbit, 5ms #
28# #
29# PHP <-- Label: 201 #
30# #
31###################################################################################
32
33# Create two `ce` routers, two `pe` routers and one `p` router
34ce1 = Router("ce1")
35ce2 = Router("ce2")
36pe1 = Router("pe1")
37pe2 = Router("pe2")
38p = Router("p")
39
40# Set the IPv4 address for the networks.
41# This example has four networks: one on the left of `pe1`, second between
42# `pe1` and `p`, third between `p` and `pe2`, and fourth on the right of `pe2`.
43n1 = Network("192.168.1.0/24") # network on the left of `pe1`
44n2 = Network("192.168.2.0/24") # network between `pe1` and `p`
45n3 = Network("192.168.3.0/24") # network between `p` and `pe2`
46n4 = Network("192.168.4.0/24") # network on the right of `pe2`
47
48# Connect `ce1` to `pe1`, `pe1` to `p`, `p` to `pe2`, and `pe2` to `ce2`
49# `etce1` and `etce2` are the interfaces at `ce1` and `ce2`, respectively.
50# `etpe1a` is the first interface at `pe1` which connects it with `ce1`
51# `etpe1b` is the second interface at `pe1` which connects it with `p`
52# `etpa` is the first interface at `p` which connects it with `pe1`
53# `etpb` is the second interface at `p` which connects it with `pe2`
54# `etpe2a` is the first interface at `pe2` which connects it with `p`
55# `etpe2b` is the second interface at `pe2` which connects it with `ce2`
56(etce1, etpe1a) = connect(ce1, pe1, network=n1)
57(etpe1b, etpa) = connect(pe1, p, network=n2)
58(etpb, etpe2a) = connect(p, pe2, network=n3)
59(etpe2b, etce2) = connect(pe2, ce2, network=n4)
60
61# Assign IPv4 addresses to all the interfaces in the network.
62AddressHelper.assign_addresses()
63
64# Enable MPLS on the required interfaces in the network.
65etpe1b.enable_mpls()
66etpa.enable_mpls()
67etpb.enable_mpls()
68etpe2a.enable_mpls()
69
70# Set default routes in `ce1` and `ce2`.
71ce1.add_route("DEFAULT", etce1)
72ce2.add_route("DEFAULT", etce2)
73
74# Configure MPLS routes: `pe1` --> `p` --> `pe2`
75pe1.add_route_mpls_push("192.168.4.0/24", etpa.address, 101) # Push label 101
76p.add_route_mpls_pop(101, etpe2a.address) # Pop label 101 (PHP)
77
78# Configure MPLS routes: `pe2` --> `p` --> `pe1`
79pe2.add_route_mpls_push("192.168.1.0/24", etpb.address, 201) # Push label 201
80p.add_route_mpls_pop(201, etpe1b.address) # Pop label 201 (PHP)
81
82# Set the link attributes: `ce1` --> `pe1` --> `p` --> `pe2` --> `ce2`
83etce1.set_attributes("50mbit", "5ms") # from `ce1` to `pe1`
84etpe1b.set_attributes("10mbit", "10ms") # from `pe1` to `p`
85etpb.set_attributes("10mbit", "10ms") # from `p` to `pe2`
86etpe2b.set_attributes("50mbit", "5ms") # from `pe2` to `ce2`
87
88# Set the link attributes: `ce2` --> `pe2` --> `p` --> `pe1` --> `ce1`
89etce2.set_attributes("50mbit", "5ms") # from `ce2` to `pe2`
90etpe2a.set_attributes("10mbit", "10ms") # from `pe2` to `p`
91etpa.set_attributes("10mbit", "10ms") # from `p` to `pe1`
92etpe1a.set_attributes("50mbit", "5ms") # from `pe1` to `ce1`
93
94# `Ping` from `ce1` to `ce2`.
95ce1.ping(etce2.address)
3. mpls-ldp-ce-pe-p-routers.py¶
This program demonstrates how to set up a MPLS network that connects two
customer edge (ce) routers ce1
and ce2
via two provider edge (pe) routers
pe1
and pe2
, which are further connected via a provider (p) router. Only
pe
and p
routers are MPLS enabled. ce
routers do not use MPLS. The
labels are assigned automatically using the Label Distribution Protocol (LDP).
This program uses LDP from Free Range Routing (FRR) suite. LDP requires an IP
based dynamic routing protocol to be already in place for it to find out the
IP addresses. In this program, we use Open Shortest Path First (OSPF) routing
protocol. Penultimate Hop Popping (PHP) is used in this program. Address helper
is used to assign the IPv4 addresses to the interfaces. Five ping packets are
sent from ce1
to ce2
, and the success/failure of these packets is reported.
1# SPDX-License-Identifier: GPL-2.0-only
2# Copyright (c) 2019-2022 NITK Surathkal
3
4########################
5# SHOULD BE RUN AS ROOT
6########################
7from nest.topology import *
8from nest import config
9from nest.topology.network import Network
10from nest.topology.address_helper import AddressHelper
11from nest.routing.routing_helper import RoutingHelper
12
13# This program demonstrates how to set up a MPLS network that connects two
14# customer edge (ce) routers `ce1` and `ce2` via two provider edge (pe) routers
15# `pe1` and `pe2`, which are further connected via a provider (p) router. Only
16# `pe` and `p` routers are MPLS enabled. `ce` routers do not use MPLS. The
17# labels are assigned automatically using the Label Distribution Protocol (LDP).
18# This program uses LDP from Free Range Routing (FRR) suite. Penultimate Hop
19# Popping (PHP) is used in this program. Address helper is used to assign the
20# IPv4 addresses to the interfaces. Five ping packets are sent from `ce1` to
21# `ce2`, and the success/failure of these packets is reported.
22
23###################################################################################
24# Network Topology #
25# #
26# Labels are auto-assigned using LDP -> #
27# | #
28# 50mbit, 5ms -> 10mbit, 10ms -> 10mbit, 10ms -> 50mbit, 5ms -> #
29# ce1 -------------- pe1 --------------- p --------------- pe2 -------------- ce2 #
30# <- 50mbit, 5ms <- 10mbit, 10ms <- 10mbit, 10ms <- 50mbit, 5ms #
31# | #
32# <- Labels are auto-assigned using LDP #
33# #
34###################################################################################
35
36# Configure the program to use FRR suite (for LDP).
37config.set_value("routing_suite", "frr")
38
39# Create two `ce` routers, two `pe` routers and one `p` router
40ce1 = Router("ce1")
41ce2 = Router("ce2")
42pe1 = Router("pe1")
43pe2 = Router("pe2")
44p = Router("p")
45
46# Set the IPv4 address for the networks.
47# This example has four networks: one on the left of `pe1`, second between
48# `pe1` and `p`, third between `p` and `pe2`, and fourth on the right of `pe2`.
49n1 = Network("192.168.1.0/24") # network on the left of `pe1`
50n2 = Network("192.168.2.0/24") # network between `pe1` and `p`
51n3 = Network("192.168.3.0/24") # network between `p` and `pe2`
52n4 = Network("192.168.4.0/24") # network on the right of `pe2`
53
54# Connect `ce1` to `pe1`, `pe1` to `p`, `p` to `pe2`, and `pe2` to `ce2`
55# `etce1` and `etce2` are the interfaces at `ce1` and `ce2`, respectively.
56# `etpe1a` is the first interface at `pe1` which connects it with `ce1`
57# `etpe1b` is the second interface at `pe1` which connects it with `p`
58# `etpa` is the first interface at `p` which connects it with `pe1`
59# `etpb` is the second interface at `p` which connects it with `pe2`
60# `etpe2a` is the first interface at `pe2` which connects it with `p`
61# `etpe2b` is the second interface at `pe2` which connects it with `ce2`
62(etce1, etpe1a) = connect(ce1, pe1, network=n1)
63(etpe1b, etpa) = connect(pe1, p, network=n2)
64(etpb, etpe2a) = connect(p, pe2, network=n3)
65(etpe2b, etce2) = connect(pe2, ce2, network=n4)
66
67# Assign IPv4 addresses to all the interfaces in the network.
68AddressHelper.assign_addresses()
69
70# Enable MPLS on the required interfaces in the network.
71etpe1b.enable_mpls()
72etpa.enable_mpls()
73etpb.enable_mpls()
74etpe2a.enable_mpls()
75
76# Use LDP to auto-assign labels on MPLS enabled interfaces. LDP requires an IP
77# based dynamic routing protocol to be already in place for it to find out the
78# IP addresses. In this program, we use Open Shortest Path First (OSPF).
79# Initially, the OSPF routing protocol runs as usual, and then LDP runs on
80# the MPLS enabled routers: `pe` and `p`.
81RoutingHelper("ospf", ldp_routers=[pe1, p, pe2]).populate_routing_tables()
82
83# Add `sleep` time to allow LDP to install routes. Depending on the size of the
84# topology, the amount of time specified for `sleep` may vary. The following
85# two lines may be added as topology grows in size and complexity. Note: this
86# example does not require `sleep` time as the topology is simple and small.
87#
88# from time import sleep
89# sleep(20)
90
91# Set the link attributes: `ce1` --> `pe1` --> `p` --> `pe2` --> `ce2`
92etce1.set_attributes("50mbit", "5ms") # from `ce1` to `pe1`
93etpe1b.set_attributes("10mbit", "10ms") # from `pe1` to `p`
94etpb.set_attributes("10mbit", "10ms") # from `p` to `pe2`
95etpe2b.set_attributes("50mbit", "5ms") # from `pe2` to `ce2`
96
97# Set the link attributes: `ce2` --> `pe2` --> `p` --> `pe1` --> `ce1`
98etce2.set_attributes("50mbit", "5ms") # from `ce2` to `pe2`
99etpe2a.set_attributes("10mbit", "10ms") # from `pe2` to `p`
100etpa.set_attributes("10mbit", "10ms") # from `p` to `pe1`
101etpe1a.set_attributes("50mbit", "5ms") # from `pe1` to `ce1`
102
103# `Ping` from `ce1` to `ce2`.
104ce1.ping(etce2.address)
4. mpls-ldp-ce-pe-p-routers-multi-address.py¶
This program demonstrates how to set up a MPLS network that connects two
customer edge (ce) routers ce1
and ce2
via two provider edge (pe) routers
pe1
and pe2
, which are further connected via a provider (p) router. But
here both IPv4 and IPv6 addresses are assigned to the interfaces. Only pe
and
p
routers are MPLS enabled. ce
routers do not use MPLS. The labels are
assigned automatically using the Label Distribution Protocol (LDP). This
program uses LDP from Free Range Routing (FRR) suite. Penultimate Hop Popping
(PHP) is used in this program. Address helper is used to assign the IPv6
addresses to the interfaces, IPv4 addresses are added manually. Five ping
packets are sent from ce1
to ce2
, and the success/failure of these packets
is reported.
1# SPDX-License-Identifier: GPL-2.0-only
2# Copyright (c) 2019-2022 NITK Surathkal
3
4########################
5# SHOULD BE RUN AS ROOT
6########################
7from nest.topology import *
8from nest import config
9from nest.topology.network import Network
10from nest.topology.address_helper import AddressHelper
11from nest.routing.routing_helper import RoutingHelper
12
13# This program demonstrates how to set up a MPLS network that connects two
14# customer edge (ce) routers `ce1` and `ce2` via two provider edge (pe) routers
15# `pe1` and `pe2`, which are further connected via a provider (p) router. But
16# here both IPv4 and IPv6 addresses are assigned to the interfaces. Only
17# `pe` and `p` routers are MPLS enabled. `ce` routers do not use MPLS. The
18# labels are assigned automatically using the Label Distribution Protocol (LDP).
19# This program uses LDP from Free Range Routing (FRR) suite. Penultimate Hop
20# Popping (PHP) is used in this program. Address helper is used to assign the
21# IPv6 addresses to the interfaces, IPv4 addresses are added manually. Five ping
22# packets are sent from `ce1` to `ce2`, and the success/failure of these packets
23# is reported.
24
25###################################################################################
26# Network Topology #
27# #
28# Labels are auto-assigned using LDP -> #
29# | #
30# 50mbit, 5ms -> 10mbit, 10ms -> 10mbit, 10ms -> 50mbit, 5ms -> #
31# ce1 -------------- pe1 --------------- p --------------- pe2 -------------- ce2 #
32# <- 50mbit, 5ms <- 10mbit, 10ms <- 10mbit, 10ms <- 50mbit, 5ms #
33# | #
34# <- Labels are auto-assigned using LDP #
35# #
36###################################################################################
37
38# Configure the program to use FRR suite (for LDP).
39config.set_value("routing_suite", "frr")
40
41# Create two `ce` routers, two `pe` routers and one `p` router
42ce1 = Router("ce1")
43ce2 = Router("ce2")
44pe1 = Router("pe1")
45pe2 = Router("pe2")
46p = Router("p")
47
48# Set the IPv6 address for the networks.
49# This example has four networks: one on the left of `pe1`, second between
50# `pe1` and `p`, third between `p` and `pe2`, and fourth on the right of `pe2`.
51n1 = Network("2001::1:0/122") # network on the left of `pe1`
52n2 = Network("2001::2:0/122") # network between `pe1` and `p`
53n3 = Network("2001::3:0/122") # network between `p` and `pe2`
54n4 = Network("2001::4:0/122") # network on the right of `pe2`
55
56# Connect `ce1` to `pe1`, `pe1` to `p`, `p` to `pe2`, and `pe2` to `ce2`
57# `etce1` and `etce2` are the interfaces at `ce1` and `ce2`, respectively.
58# `etpe1a` is the first interface at `pe1` which connects it with `ce1`
59# `etpe1b` is the second interface at `pe1` which connects it with `p`
60# `etpa` is the first interface at `p` which connects it with `pe1`
61# `etpb` is the second interface at `p` which connects it with `pe2`
62# `etpe2a` is the first interface at `pe2` which connects it with `p`
63# `etpe2b` is the second interface at `pe2` which connects it with `ce2`
64(etce1, etpe1a) = connect(ce1, pe1, network=n1)
65(etpe1b, etpa) = connect(pe1, p, network=n2)
66(etpb, etpe2a) = connect(p, pe2, network=n3)
67(etpe2b, etce2) = connect(pe2, ce2, network=n4)
68
69# Assign IPv6 addresses to all the interfaces in the network.
70AddressHelper.assign_addresses()
71
72# Assign IPv4 addresses to all the interfaces in the network.
73etce1.add_address("192.168.1.1/24")
74etpe1a.add_address("192.168.1.2/24")
75etpa.add_address("192.168.2.2/24")
76etpe1b.add_address("192.168.2.1/24")
77etpe2a.add_address("192.168.3.2/24")
78etpb.add_address("192.168.3.1/24")
79etce2.add_address("192.168.4.2/24")
80etpe2b.add_address("192.168.4.1/24")
81
82# Enable MPLS on the required interfaces in the network.
83etpe1b.enable_mpls()
84etpa.enable_mpls()
85etpb.enable_mpls()
86etpe2a.enable_mpls()
87
88# Use LDP to auto-assign labels on MPLS enabled interfaces. LDP requires an IP
89# based dynamic routing protocol to be already in place for it to find out the
90# IP addresses. In this program, we use Open Shortest Path First (OSPF).
91# Initially, the OSPF routing protocol runs as usual, and then LDP runs on
92# the MPLS enabled routers: `pe` and `p`.
93RoutingHelper(
94 "ospf", ipv6_routing=True, ldp_routers=[pe1, p, pe2]
95).populate_routing_tables()
96RoutingHelper("ospf", ldp_routers=[pe1, p, pe2]).populate_routing_tables()
97
98# Add `sleep` time to allow LDP to install routes. Depending on the size of the
99# topology, the amount of time specified for `sleep` may vary. The following
100# two lines may be added as topology grows in size and complexity.
101from time import sleep
102
103sleep(20)
104
105# Set the link attributes: `ce1` --> `pe1` --> `p` --> `pe2` --> `ce2`
106etce1.set_attributes("50mbit", "5ms") # from `ce1` to `pe1`
107etpe1b.set_attributes("10mbit", "10ms") # from `pe1` to `p`
108etpb.set_attributes("10mbit", "10ms") # from `p` to `pe2`
109etpe2b.set_attributes("50mbit", "5ms") # from `pe2` to `ce2`
110
111# Set the link attributes: `ce2` --> `pe2` --> `p` --> `pe1` --> `ce1`
112etce2.set_attributes("50mbit", "5ms") # from `ce2` to `pe2`
113etpe2a.set_attributes("10mbit", "10ms") # from `pe2` to `p`
114etpa.set_attributes("10mbit", "10ms") # from `p` to `pe1`
115etpe1a.set_attributes("50mbit", "5ms") # from `pe1` to `ce1`
116
117# `Ping` from `ce1` to `ce2`.
118ce1.ping(etce2.get_address(False, True, True)[0])
119ce1.ping(etce2.get_address(True, False, True)[0])
Once these programs are understood, and if MPLS modules are no longer needed, they can be disabled using:
rmmod mpls_iptunnel
rmmod mpls_router
rmmod mpls_gso