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