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