File: mpls.rst.txt

package info (click to toggle)
pyroute2 0.5.14-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 5,220 kB
  • sloc: python: 31,916; javascript: 8,256; ansic: 81; makefile: 14
file content (130 lines) | stat: -rw-r--r-- 3,311 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
.. _mpls:

MPLS howto
----------

Short introduction into Linux MPLS. Requirements:

* kernel >= 4.4
* modules: `mpls_router`, `mpls_iptunnel`
* `$ sudo sysctl net.mpls.platform_labels=$x`, where `$x` -- number of labels
* `pyroute2` >= 0.4.0

MPLS labels
===========

Possible label formats::

    # int
    "newdst": 20

    # list of ints
    "newdst": [20]
    "newdst": [20, 30]

    # string
    "newdst": "20/30"

    # dict
    "newdst": {"label": 20}

    # list of dicts
    "newdst": [{"label": 20, "tc": 0, "bos": 0, "ttl": 16},
               {"label": 30, "tc": 0, "bos": 1, "ttl": 16}]


IPRoute
=======

MPLS routes
~~~~~~~~~~~

Label swap::

    from pyroute2 import IPRoute
    from pyroute2.common import AF_MPLS

    ipr = IPRoute()
    # get the `eth0` interface's index:
    idx = ipr.link_lookup(ifname="eth0")[0]
    # create the request
    req = {"family": AF_MPLS,
           "oif": idx,
           "dst": 20,
           "newdst": [30]}
    # set up the route
    ipr.route("add", **req)

Please notice that "dst" can specify only one label, even being a list.
Label push::

    req = {"family": AF_MPLS,
           "oif": idx,
           "dst": 20,
           "newdst": [20, 30]}
    ipr.route("add", **req)

One can set up also the `via` field::

    from socket import AF_INET

    req = {"family": AF_MPLS,
           "oif": idx,
           "dst": 20,
           "newdst": [30],
           "via": {"family": AF_INET,
                   "addr": "1.2.3.4"}}
    ipr.route("add", **req)

MPLS lwtunnel
~~~~~~~~~~~~~

To inject IP packets into MPLS::

    req = {"dst": "1.2.3.0/24",
           "oif": idx,
           "encap": {"type": "mpls",
                     "labels": [202, 303]}}
    ipr.route("add", **req)

NDB
===

.. note:: basic MPLS routes management in NDB since version 0.5.11

List MPLS routes::

    >>> from pyroute2.common import AF_MPLS
    >>> ndb.routes.dump().filter(family=AF_MPLS)
    ('localhost', 0, 28, 20, 0, 0, 254, 4, 0, 1, 0, ...
    ('localhost', 0, 28, 20, 0, 0, 254, 4, 0, 1, 0, ...

    >>> ndb.routes.dump().filter(family=AF_MPLS).select('oif', 'dst', 'newdst')
    (40627, '[{"label": 16, "tc": 0, "bos": 1, "ttl": 0}]', '[{"label": 500, ...
    (40627, '[{"label": 40, "tc": 0, "bos": 1, "ttl": 0}]', '[{"label": 40, ...

List lwtunnel routes::

    >>> ndb.routes.dump().filter(lambda x: x.encap is not None)
    ('localhost', 0, 2, 24, 0, 0, 254, 4, 0, 1, 16, '10.255.145.0', ...
    ('localhost', 0, 2, 24, 0, 0, 254, 4, 0, 1, 0, '192.168.142.0', ...

    >>> ndb.routes.dump().filter(lambda x: x.encap is not None).select('dst', 'encap') 
    ('10.255.145.0', '[{"label": 20, "tc": 0, "bos": 0, "ttl": 0}, ...
    ('192.168.142.0', '[{"label": 20, "tc": 0, "bos": 0, "ttl": 0}, ...

Create MPLS routes::

    >>> from pyroute2.common import AF_MPLS
    >>> ndb.routes.create(family=AF_MPLS,
                          dst=128,                       # label
                          oif=1,                         # output interface
                          newdst=[128, 132]).commit()    # label stack

Create lwtunnel::

    >>> ndb.routes.create(dst='192.168.145.0/24',
                          gateway='192.168.140.5', 
                          encap={'type': 'mpls',
                                 'labels': [128, 132]}).commit()