Coverage Report

Created: 2025-10-08 06:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/lib/link_state.h
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * Link State Database definition - ted.h
4
 *
5
 * Author: Olivier Dugeon <olivier.dugeon@orange.com>
6
 *
7
 * Copyright (C) 2020 Orange http://www.orange.com
8
 *
9
 * This file is part of Free Range Routing (FRR).
10
 */
11
12
#ifndef _FRR_LINK_STATE_H_
13
#define _FRR_LINK_STATE_H_
14
15
#include "admin_group.h"
16
#include "typesafe.h"
17
18
#ifdef __cplusplus
19
extern "C" {
20
#endif
21
22
/**
23
 * This file defines the model used to implement a Link State Database
24
 * suitable to be used by various protocol like RSVP-TE, BGP-LS, PCEP ...
25
 * This database is normally fulfill by the link state routing protocol,
26
 * commonly OSPF or ISIS, carrying Traffic Engineering information within
27
 * Link State Attributes. See, RFC3630.(OSPF-TE) and RFC5305 (ISIS-TE).
28
 *
29
 * At least, 3 types of Link State structure are defined:
30
 *  - Link State Node that groups all information related to a node
31
 *  - Link State Attributes that groups all information related to a link
32
 *  - Link State Prefix that groups all information related to a prefix
33
 *
34
 * These 3 types of structures are those handled by BGP-LS (see RFC7752).
35
 *
36
 * Each structure, in addition to the specific parameters, embed the node
37
 * identifier which advertises the Link State and a bit mask as flags to
38
 * indicates which parameters are valid i.e. for which the value corresponds
39
 * to a Link State information convey by the routing protocol.
40
 * Node identifier is composed of the route id as IPv4 address plus the area
41
 * id for OSPF and the ISO System id plus the IS-IS level for IS-IS.
42
 */
43
44
/* external reference */
45
struct zapi_opaque_reg_info;
46
struct zclient;
47
48
/* Link State Common definitions */
49
0
#define MAX_NAME_LENGTH   256
50
0
#define ISO_SYS_ID_LEN    6
51
52
/* Type of Node */
53
enum ls_node_type {
54
  NONE = 0, /* Unknown */
55
  STANDARD, /* a P or PE node */
56
  ABR,    /* an Array Border Node */
57
  ASBR,   /* an Autonomous System Border Node */
58
  RMT_ASBR, /* Remote ASBR */
59
  PSEUDO    /* a Pseudo Node */
60
};
61
62
/* Origin of the Link State information */
63
enum ls_origin { UNKNOWN = 0, ISIS_L1, ISIS_L2, OSPFv2, DIRECT, STATIC };
64
65
/**
66
 * Link State Node Identifier as:
67
 *  - IPv4 address + Area ID for OSPF
68
 *  - ISO System ID + ISIS Level for ISIS
69
 */
70
struct ls_node_id {
71
  enum ls_origin origin;    /* Origin of the LS information */
72
  union {
73
    struct {
74
      struct in_addr addr;    /* OSPF Router IS */
75
      struct in_addr area_id;   /* OSPF Area ID */
76
    } ip;
77
    struct {
78
      uint8_t sys_id[ISO_SYS_ID_LEN]; /* ISIS System ID */
79
      uint8_t level;      /* ISIS Level */
80
      uint8_t padding;
81
    } iso;
82
  } id;
83
};
84
85
/**
86
 * Check if two Link State Node IDs are equal. Note that this routine has the
87
 * same return value sense as '==' (which is different from a comparison).
88
 *
89
 * @param i1  First Link State Node Identifier
90
 * @param i2  Second Link State Node Identifier
91
 * @return  1 if equal, 0 otherwise
92
 */
93
extern int ls_node_id_same(struct ls_node_id i1, struct ls_node_id i2);
94
95
/* Supported number of algorithm by the link-state library */
96
#define LIB_LS_SR_ALGO_COUNT 2
97
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 */
111
struct 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 */
116
  struct in6_addr router_id6; /* IPv6 Router ID */
117
  uint8_t node_flag;    /* IS-IS or OSPF Node flag */
118
  enum ls_node_type type;   /* Type of Node */
119
  uint32_t as_number;   /* Local or neighbor AS number */
120
  struct ls_srgb {    /* Segment Routing Global Block */
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;
125
  struct ls_srlb {    /* Segment Routing Local Block */
126
    uint32_t lower_bound;   /* MPLS label lower bound */
127
    uint32_t range_size;    /* MPLS label range size */
128
  } srlb;
129
  uint8_t algo[LIB_LS_SR_ALGO_COUNT]; /* Segment Routing Algorithms */
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
158
#define LS_ATTR_ADJ_SID   0x01000000
159
#define LS_ATTR_BCK_ADJ_SID 0x02000000
160
#define LS_ATTR_ADJ_SID6  0x04000000
161
#define LS_ATTR_BCK_ADJ_SID6  0x08000000
162
#define LS_ATTR_SRLG    0x10000000
163
#define LS_ATTR_EXT_ADM_GRP 0x20000000
164
165
/* Link State Attributes */
166
struct 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 */
170
  uint32_t metric;    /* IGP standard metric */
171
  struct ls_standard {    /* Standard TE metrics */
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;
187
  struct ls_extended {    /* Extended TE Metrics */
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;
197
  struct admin_group ext_admin_group; /* Extended Admin. Group */
198
0
#define ADJ_PRI_IPV4  0
199
0
#define ADJ_BCK_IPV4  1
200
0
#define ADJ_PRI_IPV6  2
201
0
#define ADJ_BCK_IPV6  3
202
0
#define LS_ADJ_MAX  4
203
  struct ls_adjacency {   /* (LAN)-Adjacency SID for OSPF */
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;
211
  } adj_sid[4];   /* IPv4/IPv6 & Primary/Backup (LAN)-Adj. SID */
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 */
225
struct 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 */
233
  struct ls_sid {
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
 */
249
extern 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
 */
257
extern 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
 */
268
extern 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
 */
281
extern 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
286
/**
287
 * Remove SRLGs from Link State Attributes if defined.
288
 *
289
 * @param attr  Pointer to a valid Link State Attribute structure
290
 */
291
extern void ls_attributes_srlg_del(struct ls_attributes *attr);
292
293
/**
294
 * Remove Link State Attributes. Data structure is freed.
295
 *
296
 * @param attr  Pointer to a valid Link State Attribute structure
297
 */
298
extern 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
 */
309
extern int ls_attributes_same(struct ls_attributes *a1,
310
            struct ls_attributes *a2);
311
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
 */
320
extern struct ls_prefix *ls_prefix_new(struct ls_node_id adv, struct prefix *p);
321
322
/**
323
 * Remove Link State Prefix. Data Structure is freed.
324
 *
325
 * @param pref  Pointer to a valid Link State Attribute Prefix.
326
 */
327
extern 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
 */
338
extern int ls_prefix_same(struct ls_prefix *p1, struct ls_prefix *p2);
339
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
372
enum ls_status { UNSET = 0, NEW, UPDATE, DELETE, SYNC, ORPHAN };
373
enum ls_type { GENERIC = 0, VERTEX, EDGE, SUBNET };
374
375
/* Link State Vertex structure */
376
PREDECL_RBTREE_UNIQ(vertices);
377
struct ls_vertex {
378
  enum ls_type type;    /* Link State Type */
379
  enum ls_status status;    /* Status of the Vertex in the TED */
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
388
/* Link State Edge Key structure */
389
struct 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
398
/* Link State Edge structure */
399
PREDECL_RBTREE_UNIQ(edges);
400
struct ls_edge {
401
  enum ls_type type;    /* Link State Type */
402
  enum ls_status status;    /* Status of the Edge in the TED */
403
  struct edges_item entry;  /* Entry in RB tree */
404
  struct ls_edge_key key;   /* Unique Key identifier */
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 */
411
PREDECL_RBTREE_UNIQ(subnets);
412
struct ls_subnet {
413
  enum ls_type type;    /* Link State Type */
414
  enum ls_status status;    /* Status of the Subnet in the TED */
415
  struct subnets_item entry;  /* Entry in RB tree */
416
  struct prefix key;    /* Unique Key identifier */
417
  struct ls_prefix *ls_pref;  /* Link State Prefix */
418
  struct ls_vertex *vertex; /* Back pointer to the Vertex owner */
419
};
420
421
/* Declaration of Vertices, Edges and Prefixes RB Trees */
422
macro_inline int vertex_cmp(const struct ls_vertex *node1,
423
          const struct ls_vertex *node2)
424
0
{
425
0
  return numcmp(node1->key, node2->key);
426
0
}
Unexecuted instantiation: ospf_te.c:vertex_cmp
Unexecuted instantiation: cspf.c:vertex_cmp
Unexecuted instantiation: link_state.c:vertex_cmp
427
DECLARE_RBTREE_UNIQ(vertices, struct ls_vertex, entry, vertex_cmp);
428
429
macro_inline int edge_cmp(const struct ls_edge *edge1,
430
        const struct ls_edge *edge2)
431
0
{
432
0
  if (edge1->key.family != edge2->key.family)
433
0
    return numcmp(edge1->key.family, edge2->key.family);
434
435
0
  switch (edge1->key.family) {
436
0
  case AF_INET:
437
0
    return memcmp(&edge1->key.k.addr, &edge2->key.k.addr, 4);
438
0
  case AF_INET6:
439
0
    return memcmp(&edge1->key.k.addr6, &edge2->key.k.addr6, 16);
440
0
  case AF_LOCAL:
441
0
    return numcmp(edge1->key.k.link_id, edge2->key.k.link_id);
442
0
  default:
443
0
    return 0;
444
0
  }
445
0
}
Unexecuted instantiation: ospf_te.c:edge_cmp
Unexecuted instantiation: cspf.c:edge_cmp
Unexecuted instantiation: link_state.c:edge_cmp
446
DECLARE_RBTREE_UNIQ(edges, struct ls_edge, entry, edge_cmp);
447
448
/*
449
 * Prefix comparison are done to the host part so, 10.0.0.1/24
450
 * and 10.0.0.2/24 are considered different
451
 */
452
macro_inline int subnet_cmp(const struct ls_subnet *a,
453
          const struct ls_subnet *b)
454
0
{
455
0
  if (a->key.family != b->key.family)
456
0
    return numcmp(a->key.family, b->key.family);
457
458
0
  if (a->key.prefixlen != b->key.prefixlen)
459
0
    return numcmp(a->key.prefixlen, b->key.prefixlen);
460
461
0
  if (a->key.family == AF_INET)
462
0
    return memcmp(&a->key.u.val, &b->key.u.val, 4);
463
464
0
  return memcmp(&a->key.u.val, &b->key.u.val, 16);
465
0
}
Unexecuted instantiation: ospf_te.c:subnet_cmp
Unexecuted instantiation: cspf.c:subnet_cmp
Unexecuted instantiation: link_state.c:subnet_cmp
466
DECLARE_RBTREE_UNIQ(subnets, struct ls_subnet, entry, subnet_cmp);
467
468
/* Link State TED Structure */
469
struct 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
479
/* Generic Link State Element */
480
struct 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
486
/**
487
 * Add new vertex to the Link State DB. Vertex is created from the Link State
488
 * Node. Vertex data structure is dynamically allocated.
489
 *
490
 * @param ted Traffic Engineering Database structure
491
 * @param node  Link State Node
492
 *
493
 * @return  New Vertex or NULL in case of error
494
 */
495
extern struct ls_vertex *ls_vertex_add(struct ls_ted *ted,
496
               struct ls_node *node);
497
498
/**
499
 * Delete Link State Vertex. This function clean internal Vertex lists (incoming
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.
504
 *
505
 * @param ted   Traffic Engineering Database structure
506
 * @param vertex  Link State Vertex to be removed
507
 */
508
extern void ls_vertex_del(struct ls_ted *ted, struct ls_vertex *vertex);
509
510
/**
511
 * Delete Link State Vertex as ls_vertex_del() but also removed associated
512
 * Link State Node.
513
 *
514
 * @param ted   Traffic Engineering Database structure
515
 * @param vertex  Link State Vertex to be removed
516
 */
517
extern void ls_vertex_del_all(struct ls_ted *ted, struct ls_vertex *vertex);
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
 */
528
extern struct ls_vertex *ls_vertex_update(struct ls_ted *ted,
529
            struct ls_node *node);
530
531
/**
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.
534
 *
535
 * @param ted   Link State Data Base
536
 * @param vertex  Link State Vertex to be cleaned
537
 * @param zclient Reference to Zebra Client
538
 */
539
extern void ls_vertex_clean(struct ls_ted *ted, struct ls_vertex *vertex,
540
          struct zclient *zclient);
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
 */
549
extern uint64_t sysid_to_key(const uint8_t sysid[ISO_SYS_ID_LEN]);
550
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
 */
559
extern 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
 */
570
extern 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
 */
582
extern 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
 */
593
extern 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
 */
605
extern struct ls_edge *ls_edge_update(struct ls_ted *ted,
606
              struct ls_attributes *attributes);
607
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
 */
617
extern int ls_edge_same(struct ls_edge *e1, struct ls_edge *e2);
618
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
 */
627
extern void ls_edge_del(struct ls_ted *ted, struct ls_edge *edge);
628
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
 */
636
extern void ls_edge_del_all(struct ls_ted *ted, struct ls_edge *edge);
637
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
 */
646
extern struct ls_edge *ls_find_edge_by_key(struct ls_ted *ted,
647
             const struct ls_edge_key key);
648
649
/**
650
 * Find Edge in the Link State Data Base by the source (local IPv4 or IPv6
651
 * address or local ID) informations of the Link State Attributes
652
 *
653
 * @param ted   Link State Data Base
654
 * @param attributes  Link State Attributes
655
 *
656
 * @return    Edge if found, NULL otherwise
657
 */
658
extern struct ls_edge *
659
ls_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
 */
670
extern struct ls_edge *
671
ls_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
 */
683
extern struct ls_subnet *ls_subnet_add(struct ls_ted *ted,
684
               struct ls_prefix *pref);
685
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
 */
695
extern 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
 */
707
extern int ls_subnet_same(struct ls_subnet *s1, struct ls_subnet *s2);
708
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
 */
717
extern void ls_subnet_del(struct ls_ted *ted, struct ls_subnet *subnet);
718
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
 */
726
extern void ls_subnet_del_all(struct ls_ted *ted, struct ls_subnet *subnet);
727
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
 */
736
extern struct ls_subnet *ls_find_subnet(struct ls_ted *ted,
737
          const struct prefix *prefix);
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)
744
 * @param asn AS Number for this data base. 0 if unknown
745
 *
746
 * @return  New Link State Database or NULL in case of error
747
 */
748
extern struct ls_ted *ls_ted_new(const uint32_t key, const char *name,
749
         uint32_t asn);
750
751
/**
752
 * Delete existing Link State Data Base. Vertices, Edges, and Subnets are not
753
 * removed.
754
 *
755
 * @param ted Link State Data Base
756
 */
757
extern void ls_ted_del(struct ls_ted *ted);
758
759
/**
760
 * Delete all Link State Vertices, Edges and SubNets and the Link State DB.
761
 *
762
 * @param ted Link State Data Base
763
 */
764
extern void ls_ted_del_all(struct ls_ted **ted);
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
 */
772
extern void ls_ted_clean(struct ls_ted *ted);
773
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
 */
782
extern 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
 */
793
extern 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
 */
804
extern 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
 */
812
extern 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 */
835
0
#define LS_MSG_EVENT_UNDEF  0
836
0
#define LS_MSG_EVENT_SYNC 1
837
0
#define LS_MSG_EVENT_ADD  2
838
0
#define LS_MSG_EVENT_UPDATE 3
839
0
#define LS_MSG_EVENT_DELETE 4
840
841
/* ZAPI Opaque Link State Message sub-Type */
842
0
#define LS_MSG_TYPE_NODE  1
843
0
#define LS_MSG_TYPE_ATTRIBUTES  2
844
0
#define LS_MSG_TYPE_PREFIX  3
845
846
/* Link State Message */
847
struct 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
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
 */
866
extern 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
 */
876
extern 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
 */
885
extern int ls_request_sync(struct zclient *zclient);
886
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
 */
895
extern struct ls_message *ls_parse_msg(struct stream *s);
896
897
/**
898
 * Delete existing message. Data structure is freed.
899
 *
900
 * @param msg Link state message to be deleted
901
 */
902
extern 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
 */
916
extern 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
 */
929
extern 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
 */
942
extern 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
 */
955
extern struct ls_message *ls_subnet2msg(struct ls_message *msg,
956
          struct ls_subnet *subnet);
957
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
 */
970
extern 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
 */
985
extern 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
 */
1000
extern 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
 */
1015
extern 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
 */
1030
extern struct ls_element *ls_stream2ted(struct ls_ted *ted, struct stream *s,
1031
          bool delete);
1032
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
 */
1045
extern int ls_sync_ted(struct ls_ted *ted, struct zclient *zclient,
1046
           struct zapi_opaque_reg_info *dst);
1047
1048
struct json_object;
1049
struct 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
 */
1059
extern 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
 */
1071
extern 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
 */
1083
extern 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
 */
1095
extern 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
 */
1107
extern 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
 */
1119
extern 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
 */
1131
extern void ls_show_ted(struct ls_ted *ted, struct vty *vty,
1132
      struct json_object *json, bool verbose);
1133
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
 */
1140
extern void ls_dump_ted(struct ls_ted *ted);
1141
1142
#ifdef __cplusplus
1143
}
1144
#endif
1145
1146
#endif /* _FRR_LINK_STATE_H_ */