]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_mpls.h
Merge branch 'stable/3.0'
[mirror_frr.git] / zebra / zebra_mpls.h
1 /*
2 * Zebra MPLS Data structures and definitions
3 * Copyright (C) 2015 Cumulus Networks, Inc.
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #ifndef _ZEBRA_MPLS_H
23 #define _ZEBRA_MPLS_H
24
25 #include "prefix.h"
26 #include "table.h"
27 #include "queue.h"
28 #include "hash.h"
29 #include "jhash.h"
30 #include "nexthop.h"
31 #include "vty.h"
32 #include "memory.h"
33 #include "mpls.h"
34 #include "zebra/zserv.h"
35 #include "zebra/zebra_vrf.h"
36
37
38 /* Definitions and macros. */
39
40 #define MPLS_MAX_LABELS 2 /* Maximum # labels that can be pushed. */
41
42 #define NHLFE_FAMILY(nhlfe) \
43 (((nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6 || \
44 (nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) ? AF_INET6 : AF_INET)
45
46
47 /* Typedefs */
48
49 typedef struct zebra_ile_t_ zebra_ile_t;
50 typedef struct zebra_snhlfe_t_ zebra_snhlfe_t;
51 typedef struct zebra_slsp_t_ zebra_slsp_t;
52 typedef struct zebra_nhlfe_t_ zebra_nhlfe_t;
53 typedef struct zebra_lsp_t_ zebra_lsp_t;
54 typedef struct zebra_fec_t_ zebra_fec_t;
55
56 /*
57 * (Outgoing) nexthop label forwarding entry configuration
58 */
59 struct zebra_snhlfe_t_
60 {
61 /* Nexthop information */
62 enum nexthop_types_t gtype;
63 union g_addr gate;
64 char *ifname;
65 ifindex_t ifindex;
66
67 /* Out label. */
68 mpls_label_t out_label;
69
70 /* Backpointer to base entry. */
71 zebra_slsp_t *slsp;
72
73 /* Pointers to more outgoing information for same in-label */
74 zebra_snhlfe_t *next;
75 zebra_snhlfe_t *prev;
76 };
77
78 /*
79 * (Outgoing) nexthop label forwarding entry
80 */
81 struct zebra_nhlfe_t_
82 {
83 /* Type of entry - static etc. */
84 enum lsp_types_t type;
85
86 /* Nexthop information (with outgoing label) */
87 struct nexthop *nexthop;
88
89 /* Backpointer to base entry. */
90 zebra_lsp_t *lsp;
91
92 /* Runtime info - flags, pointers etc. */
93 u_int32_t flags;
94 #define NHLFE_FLAG_CHANGED (1 << 0)
95 #define NHLFE_FLAG_SELECTED (1 << 1)
96 #define NHLFE_FLAG_MULTIPATH (1 << 2)
97 #define NHLFE_FLAG_DELETED (1 << 3)
98 #define NHLFE_FLAG_INSTALLED (1 << 4)
99
100 zebra_nhlfe_t *next;
101 zebra_nhlfe_t *prev;
102 u_char distance;
103 };
104
105 /*
106 * Incoming label entry
107 */
108 struct zebra_ile_t_
109 {
110 mpls_label_t in_label;
111 };
112
113 /*
114 * Label swap entry static configuration.
115 */
116 struct zebra_slsp_t_
117 {
118 /* Incoming label */
119 zebra_ile_t ile;
120
121 /* List of outgoing nexthop static configuration */
122 zebra_snhlfe_t *snhlfe_list;
123
124 };
125
126 /*
127 * Label swap entry (ile -> list of nhlfes)
128 */
129 struct zebra_lsp_t_
130 {
131 /* Incoming label */
132 zebra_ile_t ile;
133
134 /* List of NHLFE, pointer to best and num equal-cost. */
135 zebra_nhlfe_t *nhlfe_list;
136 zebra_nhlfe_t *best_nhlfe;
137 u_int32_t num_ecmp;
138
139 /* Flags */
140 u_int32_t flags;
141 #define LSP_FLAG_SCHEDULED (1 << 0)
142 #define LSP_FLAG_INSTALLED (1 << 1)
143 #define LSP_FLAG_CHANGED (1 << 2)
144
145 /* Address-family of NHLFE - saved here for delete. All NHLFEs */
146 /* have to be of the same AF */
147 u_char addr_family;
148 };
149
150 /*
151 * FEC to label binding.
152 */
153 struct zebra_fec_t_
154 {
155 /* FEC (prefix) */
156 struct route_node *rn;
157
158 /* In-label - either statically bound or derived from label block. */
159 mpls_label_t label;
160
161 /* Label index (into global label block), if valid */
162 u_int32_t label_index;
163
164 /* Flags. */
165 u_int32_t flags;
166 #define FEC_FLAG_CONFIGURED (1 << 0)
167
168 /* Clients interested in this FEC. */
169 struct list *client_list;
170 };
171
172 /* Function declarations. */
173
174 /*
175 * String to label conversion, labels separated by '/'.
176 */
177 int
178 mpls_str2label (const char *label_str, u_int8_t *num_labels,
179 mpls_label_t *labels);
180
181 /*
182 * Label to string conversion, labels in string separated by '/'.
183 */
184 char *
185 mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
186 char *buf, int len, int pretty);
187
188 /*
189 * Add/update global label block.
190 */
191 int
192 zebra_mpls_label_block_add (struct zebra_vrf *zvrf, u_int32_t start_label,
193 u_int32_t end_label);
194
195 /*
196 * Delete global label block.
197 */
198 int
199 zebra_mpls_label_block_del (struct zebra_vrf *vrf);
200
201 /*
202 * Display MPLS global label block configuration (VTY command handler).
203 */
204 int
205 zebra_mpls_write_label_block_config (struct vty *vty, struct zebra_vrf *vrf);
206
207 /*
208 * Install dynamic LSP entry.
209 */
210 int
211 zebra_mpls_lsp_install (struct zebra_vrf *zvrf, struct route_node *rn, struct rib *rib);
212
213 /*
214 * Uninstall dynamic LSP entry, if any.
215 */
216 int
217 zebra_mpls_lsp_uninstall (struct zebra_vrf *zvrf, struct route_node *rn, struct rib *rib);
218
219 /*
220 * Registration from a client for the label binding for a FEC. If a binding
221 * already exists, it is informed to the client.
222 * NOTE: If there is a manually configured label binding, that is used.
223 * Otherwise, if aa label index is specified, it means we have to allocate the
224 * label from a locally configured label block (SRGB), if one exists and index
225 * is acceptable.
226 */
227 int
228 zebra_mpls_fec_register (struct zebra_vrf *zvrf, struct prefix *p,
229 u_int32_t label_index, struct zserv *client);
230
231 /*
232 * Deregistration from a client for the label binding for a FEC. The FEC
233 * itself is deleted if no other registered clients exist and there is no
234 * label bound to the FEC.
235 */
236 int
237 zebra_mpls_fec_unregister (struct zebra_vrf *zvrf, struct prefix *p,
238 struct zserv *client);
239
240 /*
241 * Cleanup any FECs registered by this client.
242 */
243 int
244 zebra_mpls_cleanup_fecs_for_client (struct zebra_vrf *zvrf, struct zserv *client);
245
246 /*
247 * Return FEC (if any) to which this label is bound.
248 * Note: Only works for per-prefix binding and when the label is not
249 * implicit-null.
250 * TODO: Currently walks entire table, can optimize later with another
251 * hash..
252 */
253 zebra_fec_t *
254 zebra_mpls_fec_for_label (struct zebra_vrf *zvrf, mpls_label_t label);
255
256 /*
257 * Inform if specified label is currently bound to a FEC or not.
258 */
259 int
260 zebra_mpls_label_already_bound (struct zebra_vrf *zvrf, mpls_label_t label);
261
262 /*
263 * Add static FEC to label binding. If there are clients registered for this
264 * FEC, notify them. If there are labeled routes for this FEC, install the
265 * label forwarding entry.
266 */
267 int
268 zebra_mpls_static_fec_add (struct zebra_vrf *zvrf, struct prefix *p,
269 mpls_label_t in_label);
270
271 /*
272 * Remove static FEC to label binding. If there are no clients registered
273 * for this FEC, delete the FEC; else notify clients.
274 * Note: Upon delete of static binding, if label index exists for this FEC,
275 * client may need to be updated with derived label.
276 */
277 int
278 zebra_mpls_static_fec_del (struct zebra_vrf *zvrf, struct prefix *p);
279
280 /*
281 * Display MPLS FEC to label binding configuration (VTY command handler).
282 */
283 int
284 zebra_mpls_write_fec_config (struct vty *vty, struct zebra_vrf *zvrf);
285
286 /*
287 * Display MPLS FEC to label binding (VTY command handler).
288 */
289 void
290 zebra_mpls_print_fec_table (struct vty *vty, struct zebra_vrf *zvrf);
291
292 /*
293 * Display MPLS FEC to label binding for a specific FEC (VTY command handler).
294 */
295 void
296 zebra_mpls_print_fec (struct vty *vty, struct zebra_vrf *zvrf, struct prefix *p);
297
298 /*
299 * Install/uninstall a FEC-To-NHLFE (FTN) binding.
300 */
301 int
302 mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
303 struct prefix *prefix, enum nexthop_types_t gtype,
304 union g_addr *gate, ifindex_t ifindex, u_int8_t distance,
305 mpls_label_t out_label);
306
307 /*
308 * Install/update a NHLFE for an LSP in the forwarding table. This may be
309 * a new LSP entry or a new NHLFE for an existing in-label or an update of
310 * the out-label for an existing NHLFE (update case).
311 */
312 int
313 mpls_lsp_install (struct zebra_vrf *zvrf, enum lsp_types_t type,
314 mpls_label_t in_label, mpls_label_t out_label,
315 enum nexthop_types_t gtype, union g_addr *gate,
316 ifindex_t ifindex);
317
318 /*
319 * Uninstall a particular NHLFE in the forwarding table. If this is
320 * the only NHLFE, the entire LSP forwarding entry has to be deleted.
321 */
322 int
323 mpls_lsp_uninstall (struct zebra_vrf *zvrf, enum lsp_types_t type,
324 mpls_label_t in_label, enum nexthop_types_t gtype,
325 union g_addr *gate, ifindex_t ifindex);
326
327 /*
328 * Uninstall all LDP NHLFEs for a particular LSP forwarding entry.
329 * If no other NHLFEs exist, the entry would be deleted.
330 */
331 void
332 mpls_ldp_lsp_uninstall_all (struct hash_backet *backet, void *ctxt);
333
334 /*
335 * Uninstall all LDP FEC-To-NHLFE (FTN) bindings of the given address-family.
336 */
337 void
338 mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi);
339
340 #if defined(HAVE_CUMULUS)
341 /*
342 * Check that the label values used in LSP creation are consistent. The
343 * main criteria is that if there is ECMP, the label operation must still
344 * be consistent - i.e., all paths either do a swap or do PHP. This is due
345 * to current HW restrictions.
346 */
347 int
348 zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label,
349 mpls_label_t out_label, enum nexthop_types_t gtype,
350 union g_addr *gate, ifindex_t ifindex);
351 #endif /* HAVE_CUMULUS */
352
353 /*
354 * Add static LSP entry. This may be the first entry for this incoming label
355 * or an additional nexthop; an existing entry may also have outgoing label
356 * changed.
357 * Note: The label operation (swap or PHP) is common for the LSP entry (all
358 * NHLFEs).
359 */
360 int
361 zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,
362 mpls_label_t out_label, enum nexthop_types_t gtype,
363 union g_addr *gate, ifindex_t ifindex);
364
365 /*
366 * Delete static LSP entry. This may be the delete of one particular
367 * NHLFE for this incoming label or the delete of the entire entry (i.e.,
368 * all NHLFEs).
369 * NOTE: Delete of the only NHLFE will also end up deleting the entire
370 * LSP configuration.
371 */
372 int
373 zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label,
374 enum nexthop_types_t gtype, union g_addr *gate,
375 ifindex_t ifindex);
376
377 /*
378 * Schedule all MPLS label forwarding entries for processing.
379 * Called upon changes that may affect one or more of them such as
380 * interface or nexthop state changes.
381 */
382 void
383 zebra_mpls_lsp_schedule (struct zebra_vrf *zvrf);
384
385 /*
386 * Display MPLS label forwarding table for a specific LSP
387 * (VTY command handler).
388 */
389 void
390 zebra_mpls_print_lsp (struct vty *vty, struct zebra_vrf *zvrf, mpls_label_t label,
391 u_char use_json);
392
393 /*
394 * Display MPLS label forwarding table (VTY command handler).
395 */
396 void
397 zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf,
398 u_char use_json);
399
400 /*
401 * Display MPLS LSP configuration of all static LSPs (VTY command handler).
402 */
403 int
404 zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf);
405
406 /*
407 * Called upon process exiting, need to delete LSP forwarding
408 * entries from the kernel.
409 * NOTE: Currently supported only for default VRF.
410 */
411 void
412 zebra_mpls_close_tables (struct zebra_vrf *zvrf);
413
414 /*
415 * Allocate MPLS tables for this VRF.
416 * NOTE: Currently supported only for default VRF.
417 */
418 void
419 zebra_mpls_init_tables (struct zebra_vrf *zvrf);
420
421 /*
422 * Global MPLS initialization.
423 */
424 void
425 zebra_mpls_init (void);
426
427 /*
428 * MPLS VTY.
429 */
430 void
431 zebra_mpls_vty_init (void);
432
433 /* Inline functions. */
434
435 /*
436 * Distance (priority) definition for LSP NHLFE.
437 */
438 static inline u_char
439 lsp_distance (enum lsp_types_t type)
440 {
441 if (type == ZEBRA_LSP_STATIC)
442 return (route_distance (ZEBRA_ROUTE_STATIC));
443
444 return 150;
445 }
446
447 /*
448 * Map RIB type to LSP type. Used when labeled-routes from BGP
449 * are converted into LSPs.
450 */
451 static inline enum lsp_types_t
452 lsp_type_from_rib_type (int rib_type)
453 {
454 switch (rib_type)
455 {
456 case ZEBRA_ROUTE_STATIC:
457 return ZEBRA_LSP_STATIC;
458 case ZEBRA_ROUTE_BGP:
459 return ZEBRA_LSP_BGP;
460 default:
461 return ZEBRA_LSP_NONE;
462 }
463 }
464
465 /* NHLFE type as printable string. */
466 static inline const char *
467 nhlfe_type2str(enum lsp_types_t lsp_type)
468 {
469 switch (lsp_type)
470 {
471 case ZEBRA_LSP_STATIC:
472 return "Static";
473 case ZEBRA_LSP_LDP:
474 return "LDP";
475 case ZEBRA_LSP_BGP:
476 return "BGP";
477 default:
478 return "Unknown";
479 }
480 }
481
482 static inline void
483 mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf)
484 {
485 if (!zvrf)
486 return;
487
488 zvrf->mpls_flags |= MPLS_FLAG_SCHEDULE_LSPS;
489 }
490
491 static inline void
492 mpls_unmark_lsps_for_processing(struct zebra_vrf *zvrf)
493 {
494 if (!zvrf)
495 return;
496
497 zvrf->mpls_flags &= ~MPLS_FLAG_SCHEDULE_LSPS;
498 }
499
500 static inline int
501 mpls_should_lsps_be_processed(struct zebra_vrf *zvrf)
502 {
503 if (!zvrf)
504 return 0;
505
506 return ((zvrf->mpls_flags & MPLS_FLAG_SCHEDULE_LSPS) ? 1 : 0);
507 }
508
509 /* Global variables. */
510 extern int mpls_enabled;
511
512 #endif /*_ZEBRA_MPLS_H */