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