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.

Source code

 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.

Source code

 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.

Source code

  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.

Source code

  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