]>
Commit | Line | Data |
---|---|---|
cf9b9f77 OD |
1 | OSPF Segment Routing |
2 | ==================== | |
3 | ||
6f751f14 | 4 | This is an EXPERIMENTAL support of `RFC 8665`. |
cf9b9f77 OD |
5 | DON'T use it for production network. |
6 | ||
e3e3afff QY |
7 | Supported Features |
8 | ------------------ | |
9 | ||
10 | * Automatic computation of Primary and Backup Adjacency SID with | |
11 | Cisco experimental remote IP address | |
6f751f14 | 12 | * SRGB & SRLB configuration |
e3e3afff QY |
13 | * Prefix configuration for Node SID with optional NO-PHP flag (Linux |
14 | kernel support both mode) | |
15 | * Node MSD configuration (with Linux Kernel >= 4.10 a maximum of 32 labels | |
16 | could be stack) | |
17 | * Automatic provisioning of MPLS table | |
6f751f14 | 18 | * Equal Cost Multi-Path (ECMP) |
e3e3afff QY |
19 | * Static route configuration with label stack up to 32 labels |
20 | ||
21 | Interoperability | |
22 | ---------------- | |
23 | ||
24 | * Tested on various topology including point-to-point and LAN interfaces | |
8678d638 | 25 | in a mix of FRRouting instance and Cisco IOS-XR 6.0.x |
e3e3afff QY |
26 | * Check OSPF LSA conformity with latest wireshark release 2.5.0-rc |
27 | ||
cf9b9f77 OD |
28 | Implementation details |
29 | ---------------------- | |
7743f2f8 OD |
30 | |
31 | Concepts | |
75ca3b11 | 32 | ^^^^^^^^ |
cf9b9f77 | 33 | |
56f0bea7 | 34 | Segment Routing used 3 different OPAQUE LSA in OSPF to carry the various |
fd3b19f2 OD |
35 | information: |
36 | ||
7743f2f8 OD |
37 | * **Router Information:** flood the Segment Routing capabilities of the node. |
38 | This include the supported algorithms, the Segment Routing Global Block | |
39 | (SRGB) and the Maximum Stack Depth (MSD). | |
40 | * **Extended Link:** flood the Adjaceny and Lan Adjacency Segment Identifier | |
41 | * **Extended Prefix:** flood the Prefix Segment Identifier | |
cf9b9f77 | 42 | |
56f0bea7 | 43 | The implementation follows previous TE and Router Information codes. It used the |
7743f2f8 | 44 | OPAQUE LSA functions defined in ospf_opaque.[c,h] as well as the OSPF API. This |
fd3b19f2 OD |
45 | latter is mandatory for the implementation as it provides the Callback to |
46 | Segment Routing functions (see below) when an Extended Link / Prefix or Router | |
7743f2f8 | 47 | Information LSA s are received. |
cf9b9f77 | 48 | |
7743f2f8 | 49 | Overview |
75ca3b11 | 50 | ^^^^^^^^ |
7726c479 | 51 | |
cf9b9f77 | 52 | Following files where modified or added: |
7743f2f8 OD |
53 | |
54 | * ospd_ri.[c,h] have been modified to add the new TLVs for Segment Routing. | |
55 | * ospf_ext.[c,h] implement RFC7684 as base support of Extended Link and Prefix | |
56 | Opaque LSA. | |
57 | * ospf_sr.[c,h] implement the earth of Segment Routing. It adds a new Segment | |
58 | Routing database to manage Segment Identifiers per Link and Prefix and | |
59 | Segment Routing enable node, Callback functions to process incoming LSA and | |
60 | install MPLS FIB entry through Zebra. | |
fd3b19f2 OD |
61 | |
62 | The figure below shows the relation between the various files: | |
63 | ||
7743f2f8 OD |
64 | * ospf_sr.c centralized all the Segment Routing processing. It receives Opaque |
65 | LSA Router Information (4.0.0.0) from ospf_ri.c and Extended Prefix | |
66 | (7.0.0.X) Link (8.0.0.X) from ospf_ext.c. Once received, it parse TLVs and | |
67 | SubTLVs and store information in SRDB (which is defined in ospf_sr.h). For | |
68 | each received LSA, NHLFE is computed and send to Zebra to add/remove new | |
69 | MPLS labels entries and FEC. New CLI configurations are also centralized in | |
70 | ospf_sr.c. This CLI will trigger the flooding of new LSA Router Information | |
71 | (4.0.0.0), Extended Prefix (7.0.0.X) and Link (8.0.0.X) by ospf_ri.c, | |
72 | respectively ospf_ext.c. | |
73 | * ospf_ri.c send back to ospf_sr.c received Router Information LSA and update | |
56f0bea7 | 74 | Self Router Information LSA with parameters provided by ospf_sr.c i.e. SRGB |
7743f2f8 OD |
75 | and MSD. It use ospf_opaque.c functions to send/received these Opaque LSAs. |
76 | * ospf_ext.c send back to ospf_sr.c received Extended Prefix and Link Opaque | |
77 | LSA and send self Extended Prefix and Link Opaque LSA through ospf_opaque.c | |
78 | functions. | |
fd3b19f2 OD |
79 | |
80 | :: | |
cf9b9f77 OD |
81 | |
82 | +-----------+ +-------+ | |
83 | | | | | | |
84 | | ospf_sr.c +-----+ SRDB | | |
85 | +-----------+ +--+ | | | |
86 | | +-^-------^-+ | +-------+ | |
87 | | | | | | | |
88 | | | | | | | |
89 | | | | | +--------+ | |
90 | | | | | | | |
91 | +---v----------+ | | | +-----v-------+ | |
92 | | | | | | | | | |
93 | | ospf_ri.c +--+ | +-------+ ospf_ext.c | | |
94 | | LSA 4.0.0.0 | | | LSA 7.0.0.X | | |
95 | | | | | LSA 8.0.0.X | | |
96 | +---^----------+ | | | | |
97 | | | +-----^-------+ | |
98 | | | | | |
99 | | | | | |
100 | | +--------v------------+ | | |
101 | | | | | | |
102 | | | ZEBRA: Labels + FEC | | | |
103 | | | | | | |
104 | | +---------------------+ | | |
105 | | | | |
106 | | | | |
107 | | +---------------+ | | |
108 | | | | | | |
109 | +---------> ospf_opaque.c <---------+ | |
110 | | | | |
111 | +---------------+ | |
112 | ||
7743f2f8 OD |
113 | Figure 1: Overview of Segment Routing interaction |
114 | ||
115 | Module interactions | |
75ca3b11 | 116 | ^^^^^^^^^^^^^^^^^^^ |
7743f2f8 OD |
117 | |
118 | To process incoming LSA, the code is based on the capability to call `hook()` | |
119 | functions when LSA are inserted or delete to / from the LSDB and the | |
120 | possibility to register particular treatment for Opaque LSA. The first point | |
121 | is provided by the OSPF API feature and the second by the Opaque implementation | |
122 | itself. Indeed, it is possible to register callback function for a given Opaque | |
123 | LSA ID (see `ospf_register_opaque_functab()` function defined in | |
124 | `ospf_opaque.c`). Each time a new LSA is added to the LSDB, the | |
125 | `new_lsa_hook()` function previously register for this LSA type is called. For | |
126 | Opaque LSA it is the `ospf_opaque_lsa_install_hook()`. For deletion, it is | |
127 | `ospf_opaque_lsa_delete_hook()`. | |
128 | ||
129 | Note that incoming LSA which is already present in the LSDB will be inserted | |
130 | after the old instance of this LSA remove from the LSDB. Thus, after the first | |
131 | time, each incoming LSA will trigger a `delete` following by an `install`. This | |
56f0bea7 RK |
132 | is not very helpful to handle real LSA deletion. In fact, LSA deletion is done |
133 | by Flushing LSA i.e. flood LSA after setting its age to MAX_AGE. Then, a garbage | |
7743f2f8 OD |
134 | function has the role to remove all LSA with `age == MAX_AGE` in the LSDB. So, |
135 | to handle LSA Flush, the best is to look to the LSA age to determine if it is | |
136 | an installation or a future deletion i.e. the flushed LSA is first store in the | |
137 | LSDB with MAX_AGE waiting for the garbage collector function. | |
138 | ||
139 | Router Information LSAs | |
140 | ^^^^^^^^^^^^^^^^^^^^^^^ | |
141 | ||
142 | To activate Segment Routing, new CLI command `segment-routing on` has been | |
143 | introduced. When this command is activated, function | |
144 | `ospf_router_info_update_sr()` is called to indicate to Router Information | |
145 | process that Segment Routing TLVs must be flood. Same function is called to | |
146 | modify the Segment Routing Global Block (SRGB) and Maximum Stack Depth (MSD) | |
56f0bea7 | 147 | TLV. Only Shortest Path First (SPF) Algorithm is supported, so no possibility |
7743f2f8 OD |
148 | to modify this TLV is offer by the code. |
149 | ||
39e97e87 | 150 | When Opaque LSA Type 4 i.e. Router Information are stored in LSDB, function |
7743f2f8 OD |
151 | `ospf_opaque_lsa_install_hook()` will call the previously registered function |
152 | `ospf_router_info_lsa_update()`. In turn, the function will simply trigger | |
153 | `ospf_sr_ri_lsa_update()` or `ospf_sr_ri_lsa_delete` in function of the LSA | |
154 | age. Before, it verifies that the LSA Opaque Type is 4 (Router Information). | |
155 | Self Opaque LSA are not send back to the Segment Routing functions as | |
156 | information are already stored. | |
157 | ||
158 | Extended Link Prefix LSAs | |
159 | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
160 | ||
161 | Like for Router Information, Segment Routing is activate at the Extended | |
56f0bea7 RK |
162 | Link/Prefix level with new `segment-routing on` command. This triggers |
163 | automatically the flooding of Extended Link LSA for all ospf interfaces where | |
7743f2f8 OD |
164 | adjacency is full. For Extended Prefix LSA, the new CLI command |
165 | `segment-routing prefix ...` will trigger the flooding of Prefix SID | |
166 | TLV/SubTLVs. | |
167 | ||
168 | When Opaque LSA Type 7 i.e. Extended Prefix and Type 8 i.e. Extended Link are | |
169 | store in the LSDB, `ospf_ext_pref_update_lsa()` respectively | |
170 | `ospf_ext_link_update_lsa()` are called like for Router Information LSA. In | |
171 | turn, they respectively trigger `ospf_sr_ext_prefix_lsa_update()` / | |
172 | `ospf_sr_ext_link_lsa_update()` or `ospf_sr_ext_prefix_lsa_delete()` / | |
173 | `ospf_sr_ext_link_lsa_delete()` if the LSA age is equal to MAX_AGE. | |
174 | ||
175 | Zebra | |
176 | ^^^^^ | |
177 | ||
178 | When a new MPLS entry or new Forwarding Equivalent Class (FEC) must be added or | |
179 | deleted in the data plane, `add_sid_nhlfe()` respectively `del_sid_nhlfe()` are | |
180 | called. Once check the validity of labels, they are send to ZEBRA layer through | |
181 | `ZEBRA_MPLS_LABELS_ADD` command, respectively `ZEBRA_MPLS_LABELS_DELETE` | |
182 | command for deletion. This is completed by a new labelled route through | |
183 | `ZEBRA_ROUTE_ADD` command, respectively `ZEBRA_ROUTE_DELETE` command. | |
fd3b19f2 | 184 | |
7743f2f8 OD |
185 | Configuration |
186 | ------------- | |
7726c479 | 187 | |
7743f2f8 | 188 | Linux Kernel |
75ca3b11 | 189 | ^^^^^^^^^^^^ |
7726c479 | 190 | |
7743f2f8 OD |
191 | In order to use OSPF Segment Routing, you must setup MPLS data plane. Up to |
192 | know, only Linux Kernel version >= 4.5 is supported. | |
7726c479 | 193 | |
7743f2f8 OD |
194 | First, the MPLS modules aren't loaded by default, so you'll need to load them |
195 | yourself: | |
7726c479 | 196 | |
7743f2f8 | 197 | :: |
7726c479 | 198 | |
e3e3afff QY |
199 | modprobe mpls_router |
200 | modprobe mpls_gso | |
201 | modprobe mpls_iptunnel | |
7726c479 | 202 | |
7743f2f8 | 203 | Then, you must activate MPLS on the interface you would used: |
7726c479 | 204 | |
7743f2f8 | 205 | :: |
7726c479 | 206 | |
e3e3afff QY |
207 | sysctl -w net.mpls.conf.enp0s9.input=1 |
208 | sysctl -w net.mpls.conf.lo.input=1 | |
209 | sysctl -w net.mpls.platform_labels=1048575 | |
7726c479 | 210 | |
7743f2f8 | 211 | The last line fix the maximum MPLS label value. |
7726c479 | 212 | |
7743f2f8 OD |
213 | Once OSPFd start with Segment Routing, you could check that MPLS routes are |
214 | enable with: | |
fd3b19f2 | 215 | |
7743f2f8 OD |
216 | :: |
217 | ||
e3e3afff QY |
218 | ip -M route |
219 | ip route | |
7743f2f8 OD |
220 | |
221 | The first command show the MPLS LFIB table while the second show the FIB | |
222 | table which contains route with MPLS label encapsulation. | |
223 | ||
224 | If you disable Penultimate Hop Popping with the `no-php-flag` (see below), you | |
225 | MUST check that RP filter is not enable for the interface you intend to use, | |
226 | especially the `lo` one. For that purpose, disable RP filtering with: | |
227 | ||
228 | :: | |
229 | ||
e3e3afff QY |
230 | systcl -w net.ipv4.conf.all.rp_filter=0 |
231 | sysctl -w net.ipv4.conf.lo.rp_filter=0 | |
7743f2f8 OD |
232 | |
233 | OSPFd | |
75ca3b11 | 234 | ^^^^^ |
fd3b19f2 OD |
235 | |
236 | Here it is a simple example of configuration to enable Segment Routing. Note | |
7743f2f8 OD |
237 | that `opaque capability` and `router information` must be set to activate |
238 | Opaque LSA prior to Segment | |
fd3b19f2 OD |
239 | Routing. |
240 | ||
241 | :: | |
242 | ||
e3e3afff QY |
243 | router ospf |
244 | ospf router-id 192.168.1.11 | |
245 | capability opaque | |
e3e3afff QY |
246 | segment-routing on |
247 | segment-routing global-block 10000 19999 | |
6f751f14 | 248 | segment-routing local-block 5000 5999 |
e3e3afff QY |
249 | segment-routing node-msd 8 |
250 | segment-routing prefix 192.168.1.11/32 index 1100 | |
fd3b19f2 | 251 | |
6f751f14 OD |
252 | The first segment-routing statement enables it. The second and third one set |
253 | the SRGB and SRLB respectively, fourth line the MSD and finally, set the | |
254 | Prefix SID index for a given prefix. | |
255 | ||
fd3b19f2 | 256 | Note that only prefix of Loopback interface could be configured with a Prefix |
7743f2f8 | 257 | SID. It is possible to add `no-php-flag` at the end of the prefix command to |
56f0bea7 | 258 | disable Penultimate Hop Popping. This advertises to peers that they MUST NOT pop |
7743f2f8 | 259 | the MPLS label prior to sending the packet. |
cf9b9f77 OD |
260 | |
261 | Known limitations | |
262 | ----------------- | |
263 | ||
7743f2f8 OD |
264 | * Runs only within default VRF |
265 | * Only single Area is supported. ABR is not yet supported | |
266 | * Only SPF algorithm is supported | |
267 | * Extended Prefix Range is not supported | |
7743f2f8 OD |
268 | * With NO Penultimate Hop Popping, it is not possible to express a Segment |
269 | Path with an Adjacency SID due to the impossibility for the Linux Kernel to | |
270 | perform double POP instruction. | |
cf9b9f77 | 271 | |
fd3b19f2 OD |
272 | Credits |
273 | ------- | |
7743f2f8 OD |
274 | |
275 | * Author: Anselme Sawadogo <anselmesawadogo@gmail.com> | |
276 | * Author: Olivier Dugeon <olivier.dugeon@orange.com> | |
277 | * Copyright (C) 2016 - 2018 Orange Labs http://www.orange.com | |
fd3b19f2 OD |
278 | |
279 | This work has been performed in the framework of the H2020-ICT-2014 | |
280 | project 5GEx (Grant Agreement no. 671636), which is partially funded | |
281 | by the European Commission. | |
282 |