]> git.proxmox.com Git - mirror_frr.git/blob - lib/link_state.h
e4b97a34ed5fbb9d4fcff162335e28e9112bb08b
[mirror_frr.git] / lib / link_state.h
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Link State Database definition - ted.h
4 *
5 * Author: Olivier Dugeon <olivier.dugeon@orange.com>
6 *
7 * Copyright (C) 2020 Orange http://www.orange.com
8 *
9 * This file is part of Free Range Routing (FRR).
10 */
11
12 #ifndef _FRR_LINK_STATE_H_
13 #define _FRR_LINK_STATE_H_
14
15 #include "admin_group.h"
16 #include "typesafe.h"
17
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21
22 /**
23 * This file defines the model used to implement a Link State Database
24 * suitable to be used by various protocol like RSVP-TE, BGP-LS, PCEP ...
25 * This database is normally fulfill by the link state routing protocol,
26 * commonly OSPF or ISIS, carrying Traffic Engineering information within
27 * Link State Attributes. See, RFC3630.(OSPF-TE) and RFC5305 (ISIS-TE).
28 *
29 * At least, 3 types of Link State structure are defined:
30 * - Link State Node that groups all information related to a node
31 * - Link State Attributes that groups all information related to a link
32 * - Link State Prefix that groups all information related to a prefix
33 *
34 * These 3 types of structures are those handled by BGP-LS (see RFC7752).
35 *
36 * Each structure, in addition to the specific parameters, embed the node
37 * identifier which advertises the Link State and a bit mask as flags to
38 * indicates which parameters are valid i.e. for which the value corresponds
39 * to a Link State information convey by the routing protocol.
40 * Node identifier is composed of the route id as IPv4 address plus the area
41 * id for OSPF and the ISO System id plus the IS-IS level for IS-IS.
42 */
43
44 /* external reference */
45 struct zapi_opaque_reg_info;
46 struct zclient;
47
48 /* Link State Common definitions */
49 #define MAX_NAME_LENGTH 256
50 #define ISO_SYS_ID_LEN 6
51
52 /* Type of Node */
53 enum ls_node_type {
54 NONE = 0, /* Unknown */
55 STANDARD, /* a P or PE node */
56 ABR, /* an Array Border Node */
57 ASBR, /* an Autonomous System Border Node */
58 RMT_ASBR, /* Remote ASBR */
59 PSEUDO /* a Pseudo Node */
60 };
61
62 /* Origin of the Link State information */
63 enum ls_origin { UNKNOWN = 0, ISIS_L1, ISIS_L2, OSPFv2, DIRECT, STATIC };
64
65 /**
66 * Link State Node Identifier as:
67 * - IPv4 address + Area ID for OSPF
68 * - ISO System ID + ISIS Level for ISIS
69 */
70 struct ls_node_id {
71 enum ls_origin origin; /* Origin of the LS information */
72 union {
73 struct {
74 struct in_addr addr; /* OSPF Router IS */
75 struct in_addr area_id; /* OSPF Area ID */
76 } ip;
77 struct {
78 uint8_t sys_id[ISO_SYS_ID_LEN]; /* ISIS System ID */
79 uint8_t level; /* ISIS Level */
80 uint8_t padding;
81 } iso;
82 } id;
83 };
84
85 /**
86 * Check if two Link State Node IDs are equal. Note that this routine has the
87 * same return value sense as '==' (which is different from a comparison).
88 *
89 * @param i1 First Link State Node Identifier
90 * @param i2 Second Link State Node Identifier
91 * @return 1 if equal, 0 otherwise
92 */
93 extern int ls_node_id_same(struct ls_node_id i1, struct ls_node_id i2);
94
95 /* Link State flags to indicate which Node parameters are valid */
96 #define LS_NODE_UNSET 0x0000
97 #define LS_NODE_NAME 0x0001
98 #define LS_NODE_ROUTER_ID 0x0002
99 #define LS_NODE_ROUTER_ID6 0x0004
100 #define LS_NODE_FLAG 0x0008
101 #define LS_NODE_TYPE 0x0010
102 #define LS_NODE_AS_NUMBER 0x0020
103 #define LS_NODE_SR 0x0040
104 #define LS_NODE_SRLB 0x0080
105 #define LS_NODE_MSD 0x0100
106
107 /* Link State Node structure */
108 struct ls_node {
109 uint16_t flags; /* Flag for parameters validity */
110 struct ls_node_id adv; /* Adv. Router of this Link State */
111 char name[MAX_NAME_LENGTH]; /* Name of the Node (IS-IS only) */
112 struct in_addr router_id; /* IPv4 Router ID */
113 struct in6_addr router_id6; /* IPv6 Router ID */
114 uint8_t node_flag; /* IS-IS or OSPF Node flag */
115 enum ls_node_type type; /* Type of Node */
116 uint32_t as_number; /* Local or neighbor AS number */
117 struct ls_srgb { /* Segment Routing Global Block */
118 uint32_t lower_bound; /* MPLS label lower bound */
119 uint32_t range_size; /* MPLS label range size */
120 uint8_t flag; /* IS-IS SRGB flags */
121 } srgb;
122 struct ls_srlb { /* Segment Routing Local Block */
123 uint32_t lower_bound; /* MPLS label lower bound */
124 uint32_t range_size; /* MPLS label range size */
125 } srlb;
126 uint8_t algo[2]; /* Segment Routing Algorithms */
127 uint8_t msd; /* Maximum Stack Depth */
128 };
129
130 /* Link State flags to indicate which Attribute parameters are valid */
131 #define LS_ATTR_UNSET 0x00000000
132 #define LS_ATTR_NAME 0x00000001
133 #define LS_ATTR_METRIC 0x00000002
134 #define LS_ATTR_TE_METRIC 0x00000004
135 #define LS_ATTR_ADM_GRP 0x00000008
136 #define LS_ATTR_LOCAL_ADDR 0x00000010
137 #define LS_ATTR_NEIGH_ADDR 0x00000020
138 #define LS_ATTR_LOCAL_ADDR6 0x00000040
139 #define LS_ATTR_NEIGH_ADDR6 0x00000080
140 #define LS_ATTR_LOCAL_ID 0x00000100
141 #define LS_ATTR_NEIGH_ID 0x00000200
142 #define LS_ATTR_MAX_BW 0x00000400
143 #define LS_ATTR_MAX_RSV_BW 0x00000800
144 #define LS_ATTR_UNRSV_BW 0x00001000
145 #define LS_ATTR_REMOTE_AS 0x00002000
146 #define LS_ATTR_REMOTE_ADDR 0x00004000
147 #define LS_ATTR_REMOTE_ADDR6 0x00008000
148 #define LS_ATTR_DELAY 0x00010000
149 #define LS_ATTR_MIN_MAX_DELAY 0x00020000
150 #define LS_ATTR_JITTER 0x00040000
151 #define LS_ATTR_PACKET_LOSS 0x00080000
152 #define LS_ATTR_AVA_BW 0x00100000
153 #define LS_ATTR_RSV_BW 0x00200000
154 #define LS_ATTR_USE_BW 0x00400000
155 #define LS_ATTR_ADJ_SID 0x01000000
156 #define LS_ATTR_BCK_ADJ_SID 0x02000000
157 #define LS_ATTR_ADJ_SID6 0x04000000
158 #define LS_ATTR_BCK_ADJ_SID6 0x08000000
159 #define LS_ATTR_SRLG 0x10000000
160 #define LS_ATTR_EXT_ADM_GRP 0x20000000
161
162 /* Link State Attributes */
163 struct ls_attributes {
164 uint32_t flags; /* Flag for parameters validity */
165 struct ls_node_id adv; /* Adv. Router of this Link State */
166 char name[MAX_NAME_LENGTH]; /* Name of the Edge. Could be null */
167 uint32_t metric; /* IGP standard metric */
168 struct ls_standard { /* Standard TE metrics */
169 uint32_t te_metric; /* Traffic Engineering metric */
170 uint32_t admin_group; /* Administrative Group */
171 struct in_addr local; /* Local IPv4 address */
172 struct in_addr remote; /* Remote IPv4 address */
173 struct in6_addr local6; /* Local IPv6 address */
174 struct in6_addr remote6; /* Remote IPv6 address */
175 uint32_t local_id; /* Local Identifier */
176 uint32_t remote_id; /* Remote Identifier */
177 float max_bw; /* Maximum Link Bandwidth */
178 float max_rsv_bw; /* Maximum Reservable BW */
179 float unrsv_bw[8]; /* Unreserved BW per CT (8) */
180 uint32_t remote_as; /* Remote AS number */
181 struct in_addr remote_addr; /* Remote IPv4 address */
182 struct in6_addr remote_addr6; /* Remote IPv6 address */
183 } standard;
184 struct ls_extended { /* Extended TE Metrics */
185 uint32_t delay; /* Unidirectional average delay */
186 uint32_t min_delay; /* Unidirectional minimum delay */
187 uint32_t max_delay; /* Unidirectional maximum delay */
188 uint32_t jitter; /* Unidirectional delay variation */
189 uint32_t pkt_loss; /* Unidirectional packet loss */
190 float ava_bw; /* Available Bandwidth */
191 float rsv_bw; /* Reserved Bandwidth */
192 float used_bw; /* Utilized Bandwidth */
193 } extended;
194 struct admin_group ext_admin_group; /* Extended Admin. Group */
195 #define ADJ_PRI_IPV4 0
196 #define ADJ_BCK_IPV4 1
197 #define ADJ_PRI_IPV6 2
198 #define ADJ_BCK_IPV6 3
199 #define LS_ADJ_MAX 4
200 struct ls_adjacency { /* (LAN)-Adjacency SID for OSPF */
201 uint32_t sid; /* SID as MPLS label or index */
202 uint8_t flags; /* Flags */
203 uint8_t weight; /* Administrative weight */
204 union {
205 struct in_addr addr; /* Neighbor @IP for OSPF */
206 uint8_t sysid[ISO_SYS_ID_LEN]; /* or Sys-ID for ISIS */
207 } neighbor;
208 } adj_sid[4]; /* IPv4/IPv6 & Primary/Backup (LAN)-Adj. SID */
209 uint32_t *srlgs; /* List of Shared Risk Link Group */
210 uint8_t srlg_len; /* number of SRLG in the list */
211 };
212
213 /* Link State flags to indicate which Prefix parameters are valid */
214 #define LS_PREF_UNSET 0x00
215 #define LS_PREF_IGP_FLAG 0x01
216 #define LS_PREF_ROUTE_TAG 0x02
217 #define LS_PREF_EXTENDED_TAG 0x04
218 #define LS_PREF_METRIC 0x08
219 #define LS_PREF_SR 0x10
220
221 /* Link State Prefix */
222 struct ls_prefix {
223 uint8_t flags; /* Flag for parameters validity */
224 struct ls_node_id adv; /* Adv. Router of this Link State */
225 struct prefix pref; /* IPv4 or IPv6 prefix */
226 uint8_t igp_flag; /* IGP Flags associated to the prefix */
227 uint32_t route_tag; /* IGP Route Tag */
228 uint64_t extended_tag; /* IGP Extended Route Tag */
229 uint32_t metric; /* Route metric for this prefix */
230 struct ls_sid {
231 uint32_t sid; /* Segment Routing ID */
232 uint8_t sid_flag; /* Segment Routing Flags */
233 uint8_t algo; /* Algorithm for Segment Routing */
234 } sr;
235 };
236
237 /**
238 * Create a new Link State Node. Structure is dynamically allocated.
239 *
240 * @param adv Mandatory Link State Node ID i.e. advertise router information
241 * @param rid Router ID as IPv4 address
242 * @param rid6 Router ID as IPv6 address
243 *
244 * @return New Link State Node
245 */
246 extern struct ls_node *ls_node_new(struct ls_node_id adv, struct in_addr rid,
247 struct in6_addr rid6);
248
249 /**
250 * Remove Link State Node. Data structure is freed.
251 *
252 * @param node Pointer to a valid Link State Node structure
253 */
254 extern void ls_node_del(struct ls_node *node);
255
256 /**
257 * Check if two Link State Nodes are equal. Note that this routine has the same
258 * return value sense as '==' (which is different from a comparison).
259 *
260 * @param n1 First Link State Node to be compare
261 * @param n2 Second Link State Node to be compare
262 *
263 * @return 1 if equal, 0 otherwise
264 */
265 extern int ls_node_same(struct ls_node *n1, struct ls_node *n2);
266
267 /**
268 * Create a new Link State Attributes. Structure is dynamically allocated.
269 * At least one of parameters MUST be valid and not equal to 0.
270 *
271 * @param adv Mandatory Link State Node ID i.e. advertise router ID
272 * @param local Local IPv4 address
273 * @param local6 Local Ipv6 address
274 * @param local_id Local Identifier
275 *
276 * @return New Link State Attributes
277 */
278 extern struct ls_attributes *ls_attributes_new(struct ls_node_id adv,
279 struct in_addr local,
280 struct in6_addr local6,
281 uint32_t local_id);
282
283 /**
284 * Remove SRLGs from Link State Attributes if defined.
285 *
286 * @param attr Pointer to a valid Link State Attribute structure
287 */
288 extern void ls_attributes_srlg_del(struct ls_attributes *attr);
289
290 /**
291 * Remove Link State Attributes. Data structure is freed.
292 *
293 * @param attr Pointer to a valid Link State Attribute structure
294 */
295 extern void ls_attributes_del(struct ls_attributes *attr);
296
297 /**
298 * Check if two Link State Attributes are equal. Note that this routine has the
299 * same return value sense as '==' (which is different from a comparison).
300 *
301 * @param a1 First Link State Attributes to be compare
302 * @param a2 Second Link State Attributes to be compare
303 *
304 * @return 1 if equal, 0 otherwise
305 */
306 extern int ls_attributes_same(struct ls_attributes *a1,
307 struct ls_attributes *a2);
308
309 /**
310 * Create a new Link State Prefix. Structure is dynamically allocated.
311 *
312 * @param adv Mandatory Link State Node ID i.e. advertise router ID
313 * @param p Mandatory Prefix
314 *
315 * @return New Link State Prefix
316 */
317 extern struct ls_prefix *ls_prefix_new(struct ls_node_id adv, struct prefix p);
318
319 /**
320 * Remove Link State Prefix. Data Structure is freed.
321 *
322 * @param pref Pointer to a valid Link State Attribute Prefix.
323 */
324 extern void ls_prefix_del(struct ls_prefix *pref);
325
326 /**
327 * Check if two Link State Prefix are equal. Note that this routine has the
328 * same return value sense as '==' (which is different from a comparison).
329 *
330 * @param p1 First Link State Prefix to be compare
331 * @param p2 Second Link State Prefix to be compare
332 *
333 * @return 1 if equal, 0 otherwise
334 */
335 extern int ls_prefix_same(struct ls_prefix *p1, struct ls_prefix *p2);
336
337 /**
338 * In addition a Graph model is defined as an overlay on top of link state
339 * database in order to ease Path Computation algorithm implementation.
340 * Denoted G(V, E), a graph is composed by a list of Vertices (V) which
341 * represents the network Node and a list of Edges (E) which represents node
342 * Link. An additional list of prefixes (P) is also added.
343 * A prefix (P) is also attached to the Vertex (V) which advertise it.
344 *
345 * Vertex (V) contains the list of outgoing Edges (E) that connect this Vertex
346 * with its direct neighbors and the list of incoming Edges (E) that connect
347 * the direct neighbors to this Vertex. Indeed, the Edge (E) is unidirectional,
348 * thus, it is necessary to add 2 Edges to model a bidirectional relation
349 * between 2 Vertices.
350 *
351 * Edge (E) contains the source and destination Vertex that this Edge
352 * is connecting.
353 *
354 * A unique Key is used to identify both Vertices and Edges within the Graph.
355 * An easy way to build this key is to used the IP address: i.e. loopback
356 * address for Vertices and link IP address for Edges.
357 *
358 * -------------- --------------------------- --------------
359 * | Connected |---->| Connected Edge Va to Vb |--->| Connected |
360 * --->| Vertex | --------------------------- | Vertex |---->
361 * | | | |
362 * | - Key (Va) | | - Key (Vb) |
363 * <---| - Vertex | --------------------------- | - Vertex |<----
364 * | |<----| Connected Edge Vb to Va |<---| |
365 * -------------- --------------------------- --------------
366 *
367 */
368
369 enum ls_status { UNSET = 0, NEW, UPDATE, DELETE, SYNC, ORPHAN };
370 enum ls_type { GENERIC = 0, VERTEX, EDGE, SUBNET };
371
372 /* Link State Vertex structure */
373 PREDECL_RBTREE_UNIQ(vertices);
374 struct ls_vertex {
375 enum ls_type type; /* Link State Type */
376 enum ls_status status; /* Status of the Vertex in the TED */
377 struct vertices_item entry; /* Entry in RB Tree */
378 uint64_t key; /* Unique Key identifier */
379 struct ls_node *node; /* Link State Node */
380 struct list *incoming_edges; /* List of incoming Link State links */
381 struct list *outgoing_edges; /* List of outgoing Link State links */
382 struct list *prefixes; /* List of advertised prefix */
383 };
384
385 /* Link State Edge Key structure */
386 struct ls_edge_key {
387 uint8_t family;
388 union {
389 struct in_addr addr;
390 struct in6_addr addr6;
391 uint64_t link_id;
392 } k;
393 };
394
395 /* Link State Edge structure */
396 PREDECL_RBTREE_UNIQ(edges);
397 struct ls_edge {
398 enum ls_type type; /* Link State Type */
399 enum ls_status status; /* Status of the Edge in the TED */
400 struct edges_item entry; /* Entry in RB tree */
401 struct ls_edge_key key; /* Unique Key identifier */
402 struct ls_attributes *attributes; /* Link State attributes */
403 struct ls_vertex *source; /* Pointer to the source Vertex */
404 struct ls_vertex *destination; /* Pointer to the destination Vertex */
405 };
406
407 /* Link State Subnet structure */
408 PREDECL_RBTREE_UNIQ(subnets);
409 struct ls_subnet {
410 enum ls_type type; /* Link State Type */
411 enum ls_status status; /* Status of the Subnet in the TED */
412 struct subnets_item entry; /* Entry in RB tree */
413 struct prefix key; /* Unique Key identifier */
414 struct ls_prefix *ls_pref; /* Link State Prefix */
415 struct ls_vertex *vertex; /* Back pointer to the Vertex owner */
416 };
417
418 /* Declaration of Vertices, Edges and Prefixes RB Trees */
419 macro_inline int vertex_cmp(const struct ls_vertex *node1,
420 const struct ls_vertex *node2)
421 {
422 return numcmp(node1->key, node2->key);
423 }
424 DECLARE_RBTREE_UNIQ(vertices, struct ls_vertex, entry, vertex_cmp);
425
426 macro_inline int edge_cmp(const struct ls_edge *edge1,
427 const struct ls_edge *edge2)
428 {
429 if (edge1->key.family != edge2->key.family)
430 return numcmp(edge1->key.family, edge2->key.family);
431
432 switch (edge1->key.family) {
433 case AF_INET:
434 return memcmp(&edge1->key.k.addr, &edge2->key.k.addr, 4);
435 case AF_INET6:
436 return memcmp(&edge1->key.k.addr6, &edge2->key.k.addr6, 16);
437 case AF_LOCAL:
438 return numcmp(edge1->key.k.link_id, edge2->key.k.link_id);
439 default:
440 return 0;
441 }
442 }
443 DECLARE_RBTREE_UNIQ(edges, struct ls_edge, entry, edge_cmp);
444
445 /*
446 * Prefix comparison are done to the host part so, 10.0.0.1/24
447 * and 10.0.0.2/24 are considered different
448 */
449 macro_inline int subnet_cmp(const struct ls_subnet *a,
450 const struct ls_subnet *b)
451 {
452 if (a->key.family != b->key.family)
453 return numcmp(a->key.family, b->key.family);
454
455 if (a->key.prefixlen != b->key.prefixlen)
456 return numcmp(a->key.prefixlen, b->key.prefixlen);
457
458 if (a->key.family == AF_INET)
459 return memcmp(&a->key.u.val, &b->key.u.val, 4);
460
461 return memcmp(&a->key.u.val, &b->key.u.val, 16);
462 }
463 DECLARE_RBTREE_UNIQ(subnets, struct ls_subnet, entry, subnet_cmp);
464
465 /* Link State TED Structure */
466 struct ls_ted {
467 uint32_t key; /* Unique identifier */
468 char name[MAX_NAME_LENGTH]; /* Name of this graph. Could be null */
469 uint32_t as_number; /* AS number of the modeled network */
470 struct ls_vertex *self; /* Vertex of the FRR instance */
471 struct vertices_head vertices; /* List of Vertices */
472 struct edges_head edges; /* List of Edges */
473 struct subnets_head subnets; /* List of Subnets */
474 };
475
476 /* Generic Link State Element */
477 struct ls_element {
478 enum ls_type type; /* Link State Element Type */
479 enum ls_status status; /* Link State Status in the TED */
480 void *data; /* Link State payload */
481 };
482
483 /**
484 * Add new vertex to the Link State DB. Vertex is created from the Link State
485 * Node. Vertex data structure is dynamically allocated.
486 *
487 * @param ted Traffic Engineering Database structure
488 * @param node Link State Node
489 *
490 * @return New Vertex or NULL in case of error
491 */
492 extern struct ls_vertex *ls_vertex_add(struct ls_ted *ted,
493 struct ls_node *node);
494
495 /**
496 * Delete Link State Vertex. This function clean internal Vertex lists (incoming
497 * and outgoing Link State Edge and Link State Subnet). Vertex Data structure
498 * is freed but not the Link State Node. Link State DB is not modified if Vertex
499 * is NULL or not found in the Data Base. Note that referenced to Link State
500 * Edges & SubNets are not removed as they could be connected to other Vertices.
501 *
502 * @param ted Traffic Engineering Database structure
503 * @param vertex Link State Vertex to be removed
504 */
505 extern void ls_vertex_del(struct ls_ted *ted, struct ls_vertex *vertex);
506
507 /**
508 * Delete Link State Vertex as ls_vertex_del() but also removed associated
509 * Link State Node.
510 *
511 * @param ted Traffic Engineering Database structure
512 * @param vertex Link State Vertex to be removed
513 */
514 extern void ls_vertex_del_all(struct ls_ted *ted, struct ls_vertex *vertex);
515
516 /**
517 * Update Vertex with the Link State Node. A new vertex is created if no one
518 * corresponds to the Link State Node.
519 *
520 * @param ted Link State Data Base
521 * @param node Link State Node to be updated
522 *
523 * @return Updated Link State Vertex or Null in case of error
524 */
525 extern struct ls_vertex *ls_vertex_update(struct ls_ted *ted,
526 struct ls_node *node);
527
528 /**
529 * Clean Vertex structure by removing all Edges and Subnets marked as ORPHAN
530 * from this vertex. Link State Update message is sent if zclient is not NULL.
531 *
532 * @param ted Link State Data Base
533 * @param vertex Link State Vertex to be cleaned
534 * @param zclient Reference to Zebra Client
535 */
536 extern void ls_vertex_clean(struct ls_ted *ted, struct ls_vertex *vertex,
537 struct zclient *zclient);
538
539 /**
540 * This function convert the ISIS ISO system ID into a 64 bits unsigned integer
541 * following the architecture dependent byte order.
542 *
543 * @param sysid The ISO system ID
544 * @return Key as 64 bits unsigned integer
545 */
546 extern uint64_t sysid_to_key(const uint8_t sysid[ISO_SYS_ID_LEN]);
547
548 /**
549 * Find Vertex in the Link State DB by its unique key.
550 *
551 * @param ted Link State Data Base
552 * @param key Vertex Key different from 0
553 *
554 * @return Vertex if found, NULL otherwise
555 */
556 extern struct ls_vertex *ls_find_vertex_by_key(struct ls_ted *ted,
557 const uint64_t key);
558
559 /**
560 * Find Vertex in the Link State DB by its Link State Node.
561 *
562 * @param ted Link State Data Base
563 * @param nid Link State Node ID
564 *
565 * @return Vertex if found, NULL otherwise
566 */
567 extern struct ls_vertex *ls_find_vertex_by_id(struct ls_ted *ted,
568 struct ls_node_id nid);
569
570 /**
571 * Check if two Vertices are equal. Note that this routine has the same return
572 * value sense as '==' (which is different from a comparison).
573 *
574 * @param v1 First vertex to compare
575 * @param v2 Second vertex to compare
576 *
577 * @return 1 if equal, 0 otherwise
578 */
579 extern int ls_vertex_same(struct ls_vertex *v1, struct ls_vertex *v2);
580
581 /**
582 * Add new Edge to the Link State DB. Edge is created from the Link State
583 * Attributes. Edge data structure is dynamically allocated.
584 *
585 * @param ted Link State Data Base
586 * @param attributes Link State attributes
587 *
588 * @return New Edge or NULL in case of error
589 */
590 extern struct ls_edge *ls_edge_add(struct ls_ted *ted,
591 struct ls_attributes *attributes);
592
593 /**
594 * Update the Link State Attributes information of an existing Edge. If there is
595 * no corresponding Edge in the Link State Data Base, a new Edge is created.
596 *
597 * @param ted Link State Data Base
598 * @param attributes Link State Attributes
599 *
600 * @return Updated Link State Edge, or NULL in case of error
601 */
602 extern struct ls_edge *ls_edge_update(struct ls_ted *ted,
603 struct ls_attributes *attributes);
604
605 /**
606 * Check if two Edges are equal. Note that this routine has the same return
607 * value sense as '==' (which is different from a comparison).
608 *
609 * @param e1 First edge to compare
610 * @param e2 Second edge to compare
611 *
612 * @return 1 if equal, 0 otherwise
613 */
614 extern int ls_edge_same(struct ls_edge *e1, struct ls_edge *e2);
615
616 /**
617 * Remove Edge from the Link State DB. Edge data structure is freed but not the
618 * Link State Attributes data structure. Link State DB is not modified if Edge
619 * is NULL or not found in the Data Base.
620 *
621 * @param ted Link State Data Base
622 * @param edge Edge to be removed
623 */
624 extern void ls_edge_del(struct ls_ted *ted, struct ls_edge *edge);
625
626 /**
627 * Remove Edge and associated Link State Attributes from the Link State DB.
628 * Link State DB is not modified if Edge is NULL or not found.
629 *
630 * @param ted Link State Data Base
631 * @param edge Edge to be removed
632 */
633 extern void ls_edge_del_all(struct ls_ted *ted, struct ls_edge *edge);
634
635 /**
636 * Find Edge in the Link State Data Base by Edge key.
637 *
638 * @param ted Link State Data Base
639 * @param key Edge key
640 *
641 * @return Edge if found, NULL otherwise
642 */
643 extern struct ls_edge *ls_find_edge_by_key(struct ls_ted *ted,
644 const struct ls_edge_key key);
645
646 /**
647 * Find Edge in the Link State Data Base by the source (local IPv4 or IPv6
648 * address or local ID) informations of the Link State Attributes
649 *
650 * @param ted Link State Data Base
651 * @param attributes Link State Attributes
652 *
653 * @return Edge if found, NULL otherwise
654 */
655 extern struct ls_edge *
656 ls_find_edge_by_source(struct ls_ted *ted, struct ls_attributes *attributes);
657
658 /**
659 * Find Edge in the Link State Data Base by the destination (remote IPv4 or IPv6
660 * address of remote ID) information of the Link State Attributes
661 *
662 * @param ted Link State Data Base
663 * @param attributes Link State Attributes
664 *
665 * @return Edge if found, NULL otherwise
666 */
667 extern struct ls_edge *
668 ls_find_edge_by_destination(struct ls_ted *ted,
669 struct ls_attributes *attributes);
670
671 /**
672 * Add new Subnet to the Link State DB. Subnet is created from the Link State
673 * prefix. Subnet data structure is dynamically allocated.
674 *
675 * @param ted Link State Data Base
676 * @param pref Link State Prefix
677 *
678 * @return New Subnet
679 */
680 extern struct ls_subnet *ls_subnet_add(struct ls_ted *ted,
681 struct ls_prefix *pref);
682
683 /**
684 * Update the Link State Prefix information of an existing Subnet. If there is
685 * no corresponding Subnet in the Link State Data Base, a new Subnet is created.
686 *
687 * @param ted Link State Data Base
688 * @param pref Link State Prefix
689 *
690 * @return Updated Link State Subnet, or NULL in case of error
691 */
692 extern struct ls_subnet *ls_subnet_update(struct ls_ted *ted,
693 struct ls_prefix *pref);
694
695 /**
696 * Check if two Subnets are equal. Note that this routine has the same return
697 * value sense as '==' (which is different from a comparison).
698 *
699 * @param s1 First subnet to compare
700 * @param s2 Second subnet to compare
701 *
702 * @return 1 if equal, 0 otherwise
703 */
704 extern int ls_subnet_same(struct ls_subnet *s1, struct ls_subnet *s2);
705
706 /**
707 * Remove Subnet from the Link State DB. Subnet data structure is freed but
708 * not the Link State prefix data structure. Link State DB is not modified
709 * if Subnet is NULL or not found in the Data Base.
710 *
711 * @param ted Link State Data Base
712 * @param subnet Subnet to be removed
713 */
714 extern void ls_subnet_del(struct ls_ted *ted, struct ls_subnet *subnet);
715
716 /**
717 * Remove Subnet and the associated Link State Prefix from the Link State DB.
718 * Link State DB is not modified if Subnet is NULL or not found.
719 *
720 * @param ted Link State Data Base
721 * @param subnet Subnet to be removed
722 */
723 extern void ls_subnet_del_all(struct ls_ted *ted, struct ls_subnet *subnet);
724
725 /**
726 * Find Subnet in the Link State Data Base by prefix.
727 *
728 * @param ted Link State Data Base
729 * @param prefix Link State Prefix
730 *
731 * @return Subnet if found, NULL otherwise
732 */
733 extern struct ls_subnet *ls_find_subnet(struct ls_ted *ted,
734 const struct prefix prefix);
735
736 /**
737 * Create a new Link State Data Base.
738 *
739 * @param key Unique key of the data base. Must be different from 0
740 * @param name Name of the data base (may be NULL)
741 * @param asn AS Number for this data base. 0 if unknown
742 *
743 * @return New Link State Database or NULL in case of error
744 */
745 extern struct ls_ted *ls_ted_new(const uint32_t key, const char *name,
746 uint32_t asn);
747
748 /**
749 * Delete existing Link State Data Base. Vertices, Edges, and Subnets are not
750 * removed.
751 *
752 * @param ted Link State Data Base
753 */
754 extern void ls_ted_del(struct ls_ted *ted);
755
756 /**
757 * Delete all Link State Vertices, Edges and SubNets and the Link State DB.
758 *
759 * @param ted Link State Data Base
760 */
761 extern void ls_ted_del_all(struct ls_ted **ted);
762
763 /**
764 * Clean Link State Data Base by removing all Vertices, Edges and SubNets marked
765 * as ORPHAN.
766 *
767 * @param ted Link State Data Base
768 */
769 extern void ls_ted_clean(struct ls_ted *ted);
770
771 /**
772 * Connect Source and Destination Vertices by given Edge. Only non NULL source
773 * and destination vertices are connected.
774 *
775 * @param src Link State Source Vertex
776 * @param dst Link State Destination Vertex
777 * @param edge Link State Edge. Must not be NULL
778 */
779 extern void ls_connect_vertices(struct ls_vertex *src, struct ls_vertex *dst,
780 struct ls_edge *edge);
781
782 /**
783 * Connect Link State Edge to the Link State Vertex which could be a Source or
784 * a Destination Vertex.
785 *
786 * @param vertex Link State Vertex to be connected. Must not be NULL
787 * @param edge Link State Edge connection. Must not be NULL
788 * @param source True for a Source, false for a Destination Vertex
789 */
790 extern void ls_connect(struct ls_vertex *vertex, struct ls_edge *edge,
791 bool source);
792
793 /**
794 * Disconnect Link State Edge from the Link State Vertex which could be a
795 * Source or a Destination Vertex.
796 *
797 * @param vertex Link State Vertex to be connected. Must not be NULL
798 * @param edge Link State Edge connection. Must not be NULL
799 * @param source True for a Source, false for a Destination Vertex
800 */
801 extern void ls_disconnect(struct ls_vertex *vertex, struct ls_edge *edge,
802 bool source);
803
804 /**
805 * Disconnect Link State Edge from both Source and Destination Vertex.
806 *
807 * @param edge Link State Edge to be disconnected
808 */
809 extern void ls_disconnect_edge(struct ls_edge *edge);
810
811
812 /**
813 * The Link State Message is defined to convey Link State parameters from
814 * the routing protocol (OSPF or IS-IS) to other daemons e.g. BGP.
815 *
816 * The structure is composed of:
817 * - Event of the message:
818 * - Sync: Send the whole LS DB following a request
819 * - Add: Send the a new Link State element
820 * - Update: Send an update of an existing Link State element
821 * - Delete: Indicate that the given Link State element is removed
822 * - Type of Link State element: Node, Attribute or Prefix
823 * - Remote node id when known
824 * - Data: Node, Attributes or Prefix
825 *
826 * A Link State Message can carry only one Link State Element (Node, Attributes
827 * of Prefix) at once, and only one Link State Message is sent through ZAPI
828 * Opaque Link State type at once.
829 */
830
831 /* ZAPI Opaque Link State Message Event */
832 #define LS_MSG_EVENT_UNDEF 0
833 #define LS_MSG_EVENT_SYNC 1
834 #define LS_MSG_EVENT_ADD 2
835 #define LS_MSG_EVENT_UPDATE 3
836 #define LS_MSG_EVENT_DELETE 4
837
838 /* ZAPI Opaque Link State Message sub-Type */
839 #define LS_MSG_TYPE_NODE 1
840 #define LS_MSG_TYPE_ATTRIBUTES 2
841 #define LS_MSG_TYPE_PREFIX 3
842
843 /* Link State Message */
844 struct ls_message {
845 uint8_t event; /* Message Event: Sync, Add, Update, Delete */
846 uint8_t type; /* Message Data Type: Node, Attribute, Prefix */
847 struct ls_node_id remote_id; /* Remote Link State Node ID */
848 union {
849 struct ls_node *node; /* Link State Node */
850 struct ls_attributes *attr; /* Link State Attributes */
851 struct ls_prefix *prefix; /* Link State Prefix */
852 } data;
853 };
854
855 /**
856 * Register Link State daemon as a server or client for Zebra OPAQUE API.
857 *
858 * @param zclient Zebra client structure
859 * @param server Register daemon as a server (true) or as a client (false)
860 *
861 * @return 0 if success, -1 otherwise
862 */
863 extern int ls_register(struct zclient *zclient, bool server);
864
865 /**
866 * Unregister Link State daemon as a server or client for Zebra OPAQUE API.
867 *
868 * @param zclient Zebra client structure
869 * @param server Unregister daemon as a server (true) or as a client (false)
870 *
871 * @return 0 if success, -1 otherwise
872 */
873 extern int ls_unregister(struct zclient *zclient, bool server);
874
875 /**
876 * Send Link State SYNC message to request the complete Link State Database.
877 *
878 * @param zclient Zebra client
879 *
880 * @return 0 if success, -1 otherwise
881 */
882 extern int ls_request_sync(struct zclient *zclient);
883
884 /**
885 * Parse Link State Message from stream. Used this function once receiving a
886 * new ZAPI Opaque message of type Link State.
887 *
888 * @param s Stream buffer. Must not be NULL.
889 *
890 * @return New Link State Message or NULL in case of error
891 */
892 extern struct ls_message *ls_parse_msg(struct stream *s);
893
894 /**
895 * Delete existing message. Data structure is freed.
896 *
897 * @param msg Link state message to be deleted
898 */
899 extern void ls_delete_msg(struct ls_message *msg);
900
901 /**
902 * Send Link State Message as new ZAPI Opaque message of type Link State.
903 * If destination is not NULL, message is sent as Unicast otherwise it is
904 * broadcast to all registered daemon.
905 *
906 * @param zclient Zebra Client
907 * @param msg Link State Message to be sent
908 * @param dst Destination daemon for unicast message,
909 * NULL for broadcast message
910 *
911 * @return 0 on success, -1 otherwise
912 */
913 extern int ls_send_msg(struct zclient *zclient, struct ls_message *msg,
914 struct zapi_opaque_reg_info *dst);
915
916 /**
917 * Create a new Link State Message from a Link State Vertex. If Link State
918 * Message is NULL, a new data structure is dynamically allocated.
919 *
920 * @param msg Link State Message to be filled or NULL
921 * @param vertex Link State Vertex. Must not be NULL
922 *
923 * @return New Link State Message msg parameter is NULL or pointer
924 * to the provided Link State Message
925 */
926 extern struct ls_message *ls_vertex2msg(struct ls_message *msg,
927 struct ls_vertex *vertex);
928
929 /**
930 * Create a new Link State Message from a Link State Edge. If Link State
931 * Message is NULL, a new data structure is dynamically allocated.
932 *
933 * @param msg Link State Message to be filled or NULL
934 * @param edge Link State Edge. Must not be NULL
935 *
936 * @return New Link State Message msg parameter is NULL or pointer
937 * to the provided Link State Message
938 */
939 extern struct ls_message *ls_edge2msg(struct ls_message *msg,
940 struct ls_edge *edge);
941
942 /**
943 * Create a new Link State Message from a Link State Subnet. If Link State
944 * Message is NULL, a new data structure is dynamically allocated.
945 *
946 * @param msg Link State Message to be filled or NULL
947 * @param subnet Link State Subnet. Must not be NULL
948 *
949 * @return New Link State Message msg parameter is NULL or pointer
950 * to the provided Link State Message
951 */
952 extern struct ls_message *ls_subnet2msg(struct ls_message *msg,
953 struct ls_subnet *subnet);
954
955 /**
956 * Convert Link State Message into Vertex and update TED accordingly to
957 * the message event: SYNC, ADD, UPDATE or DELETE.
958 *
959 * @param ted Link State Database
960 * @param msg Link State Message
961 * @param delete True to delete the Link State Vertex from the Database,
962 * False otherwise. If true, return value is NULL in case
963 * of deletion.
964 *
965 * @return Vertex if success, NULL otherwise or if Vertex is removed
966 */
967 extern struct ls_vertex *ls_msg2vertex(struct ls_ted *ted,
968 struct ls_message *msg, bool delete);
969
970 /**
971 * Convert Link State Message into Edge and update TED accordingly to
972 * the message event: SYNC, ADD, UPDATE or DELETE.
973 *
974 * @param ted Link State Database
975 * @param msg Link State Message
976 * @param delete True to delete the Link State Edge from the Database,
977 * False otherwise. If true, return value is NULL in case
978 * of deletion.
979 *
980 * @return Edge if success, NULL otherwise or if Edge is removed
981 */
982 extern struct ls_edge *ls_msg2edge(struct ls_ted *ted, struct ls_message *msg,
983 bool delete);
984
985 /**
986 * Convert Link State Message into Subnet and update TED accordingly to
987 * the message event: SYNC, ADD, UPDATE or DELETE.
988 *
989 * @param ted Link State Database
990 * @param msg Link State Message
991 * @param delete True to delete the Link State Subnet from the Database,
992 * False otherwise. If true, return value is NULL in case
993 * of deletion.
994 *
995 * @return Subnet if success, NULL otherwise or if Subnet is removed
996 */
997 extern struct ls_subnet *ls_msg2subnet(struct ls_ted *ted,
998 struct ls_message *msg, bool delete);
999
1000 /**
1001 * Convert Link State Message into Link State element (Vertex, Edge or Subnet)
1002 * and update TED accordingly to the message event: SYNC, ADD, UPDATE or DELETE.
1003 *
1004 * @param ted Link State Database
1005 * @param msg Link State Message
1006 * @param delete True to delete the Link State Element from the Database,
1007 * False otherwise. If true, return value is NULL in case
1008 * of deletion.
1009 *
1010 * @return Element if success, NULL otherwise or if Element is removed
1011 */
1012 extern struct ls_element *ls_msg2ted(struct ls_ted *ted, struct ls_message *msg,
1013 bool delete);
1014
1015 /**
1016 * Convert stream buffer into Link State element (Vertex, Edge or Subnet) and
1017 * update TED accordingly to the message event: SYNC, ADD, UPDATE or DELETE.
1018 *
1019 * @param ted Link State Database
1020 * @param s Stream buffer
1021 * @param delete True to delete the Link State Element from the Database,
1022 * False otherwise. If true, return value is NULL in case
1023 * of deletion.
1024 *
1025 * @return Element if success, NULL otherwise or if Element is removed
1026 */
1027 extern struct ls_element *ls_stream2ted(struct ls_ted *ted, struct stream *s,
1028 bool delete);
1029
1030 /**
1031 * Send all the content of the Link State Data Base to the given destination.
1032 * Link State content is sent is this order: Vertices, Edges, Subnet.
1033 * This function must be used when a daemon request a Link State Data Base
1034 * Synchronization.
1035 *
1036 * @param ted Link State Data Base. Must not be NULL
1037 * @param zclient Zebra Client. Must not be NULL
1038 * @param dst Destination FRR daemon. Must not be NULL
1039 *
1040 * @return 0 on success, -1 otherwise
1041 */
1042 extern int ls_sync_ted(struct ls_ted *ted, struct zclient *zclient,
1043 struct zapi_opaque_reg_info *dst);
1044
1045 struct json_object;
1046 struct vty;
1047 /**
1048 * Show Link State Vertex information. If both vty and json are specified,
1049 * Json format output supersedes standard vty output.
1050 *
1051 * @param vertex Link State Vertex to show. Must not be NULL
1052 * @param vty Pointer to vty output, could be NULL
1053 * @param json Pointer to json output, could be NULL
1054 * @param verbose Set to true for more detail
1055 */
1056 extern void ls_show_vertex(struct ls_vertex *vertex, struct vty *vty,
1057 struct json_object *json, bool verbose);
1058
1059 /**
1060 * Show all Link State Vertices information. If both vty and json are specified,
1061 * Json format output supersedes standard vty output.
1062 *
1063 * @param ted Link State Data Base. Must not be NULL
1064 * @param vty Pointer to vty output, could be NULL
1065 * @param json Pointer to json output, could be NULL
1066 * @param verbose Set to true for more detail
1067 */
1068 extern void ls_show_vertices(struct ls_ted *ted, struct vty *vty,
1069 struct json_object *json, bool verbose);
1070
1071 /**
1072 * Show Link State Edge information. If both vty and json are specified,
1073 * Json format output supersedes standard vty output.
1074 *
1075 * @param edge Link State Edge to show. Must not be NULL
1076 * @param vty Pointer to vty output, could be NULL
1077 * @param json Pointer to json output, could be NULL
1078 * @param verbose Set to true for more detail
1079 */
1080 extern void ls_show_edge(struct ls_edge *edge, struct vty *vty,
1081 struct json_object *json, bool verbose);
1082
1083 /**
1084 * Show all Link State Edges information. If both vty and json are specified,
1085 * Json format output supersedes standard vty output.
1086 *
1087 * @param ted Link State Data Base. Must not be NULL
1088 * @param vty Pointer to vty output, could be NULL
1089 * @param json Pointer to json output, could be NULL
1090 * @param verbose Set to true for more detail
1091 */
1092 extern void ls_show_edges(struct ls_ted *ted, struct vty *vty,
1093 struct json_object *json, bool verbose);
1094
1095 /**
1096 * Show Link State Subnets information. If both vty and json are specified,
1097 * Json format output supersedes standard vty output.
1098 *
1099 * @param subnet Link State Subnet to show. Must not be NULL
1100 * @param vty Pointer to vty output, could be NULL
1101 * @param json Pointer to json output, could be NULL
1102 * @param verbose Set to true for more detail
1103 */
1104 extern void ls_show_subnet(struct ls_subnet *subnet, struct vty *vty,
1105 struct json_object *json, bool verbose);
1106
1107 /**
1108 * Show all Link State Subnet information. If both vty and json are specified,
1109 * Json format output supersedes standard vty output.
1110 *
1111 * @param ted Link State Data Base. Must not be NULL
1112 * @param vty Pointer to vty output, could be NULL
1113 * @param json Pointer to json output, could be NULL
1114 * @param verbose Set to true for more detail
1115 */
1116 extern void ls_show_subnets(struct ls_ted *ted, struct vty *vty,
1117 struct json_object *json, bool verbose);
1118
1119 /**
1120 * Show Link State Data Base information. If both vty and json are specified,
1121 * Json format output supersedes standard vty output.
1122 *
1123 * @param ted Link State Data Base to show. Must not be NULL
1124 * @param vty Pointer to vty output, could be NULL
1125 * @param json Pointer to json output, could be NULL
1126 * @param verbose Set to true for more detail
1127 */
1128 extern void ls_show_ted(struct ls_ted *ted, struct vty *vty,
1129 struct json_object *json, bool verbose);
1130
1131 /**
1132 * Dump all Link State Data Base elements for debugging purposes
1133 *
1134 * @param ted Link State Data Base. Must not be NULL
1135 *
1136 */
1137 extern void ls_dump_ted(struct ls_ted *ted);
1138
1139 #ifdef __cplusplus
1140 }
1141 #endif
1142
1143 #endif /* _FRR_LINK_STATE_H_ */