1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
|
/*
* Link State Database definition - ted.h
*
* Author: Olivier Dugeon <olivier.dugeon@orange.com>
*
* Copyright (C) 2020 Orange http://www.orange.com
*
* This file is part of Free Range Routing (FRR).
*
* FRR is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* FRR is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _FRR_LINK_STATE_H_
#define _FRR_LINK_STATE_H_
#include "typesafe.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* This file defines the model used to implement a Link State Database
* suitable to be used by various protocol like RSVP-TE, BGP-LS, PCEP ...
* This database is normally fulfill by the link state routing protocol,
* commonly OSPF or ISIS, carrying Traffic Engineering information within
* Link State Attributes. See, RFC3630.(OSPF-TE) and RFC5305 (ISIS-TE).
*
* At least, 3 types of Link State structure are defined:
* - Link State Node that groups all information related to a node
* - Link State Attributes that groups all information related to a link
* - Link State Prefix that groups all information related to a prefix
*
* These 3 types of structures are those handled by BGP-LS (see RFC7752).
*
* Each structure, in addition to the specific parameters, embed the node
* identifier which advertises the Link State and a bit mask as flags to
* indicates which parameters are valid i.e. for which the value corresponds
* to a Link State information convey by the routing protocol.
* Node identifier is composed of the route id as IPv4 address plus the area
* id for OSPF and the ISO System id plus the IS-IS level for IS-IS.
*/
/* Link State Common definitions */
#define MAX_NAME_LENGTH 256
#define ISO_SYS_ID_LEN 6
/* Type of Node */
enum ls_node_type {
STANDARD, /* a P or PE node */
ABR, /* an Array Border Node */
ASBR, /* an Autonomous System Border Node */
PSEUDO, /* a Pseudo Node */
};
/* Origin of the Link State information */
enum ls_origin {NONE = 0, ISIS_L1, ISIS_L2, OSPFv2, DIRECT, STATIC};
/**
* Link State Node Identifier as:
* - IPv4 address + Area ID for OSPF
* - ISO System ID + ISIS Level for ISIS
*/
struct ls_node_id {
enum ls_origin origin; /* Origin of the LS information */
union {
struct {
struct in_addr addr; /* OSPF Router IS */
struct in_addr area_id; /* OSPF Area ID */
} ip;
struct {
uint8_t sys_id[ISO_SYS_ID_LEN]; /* ISIS System ID */
uint8_t level; /* ISIS Level */
uint8_t padding;
} iso;
} id __attribute__((aligned(8)));
};
/* Link State flags to indicate which Node parameters are valid */
#define LS_NODE_UNSET 0x0000
#define LS_NODE_NAME 0x0001
#define LS_NODE_ROUTER_ID 0x0002
#define LS_NODE_ROUTER_ID6 0x0004
#define LS_NODE_FLAG 0x0008
#define LS_NODE_TYPE 0x0010
#define LS_NODE_AS_NUMBER 0x0020
#define LS_NODE_SR 0x0040
#define LS_NODE_SRLB 0x0080
#define LS_NODE_MSD 0x0100
/* Link State Node structure */
struct ls_node {
uint16_t flags; /* Flag for parameters validity */
struct ls_node_id adv; /* Adv. Router of this Link State */
char name[MAX_NAME_LENGTH]; /* Name of the Node (IS-IS only) */
struct in_addr router_id; /* IPv4 Router ID */
struct in6_addr router6_id; /* IPv6 Router ID */
uint8_t node_flag; /* IS-IS or OSPF Node flag */
enum node_type type; /* Type of Node */
uint32_t as_number; /* Local or neighbor AS number */
struct { /* Segment Routing Global Block */
uint32_t lower_bound; /* MPLS label lower bound */
uint32_t range_size; /* MPLS label range size */
uint8_t flag; /* IS-IS SRGB flags */
} srgb;
#define LS_NODE_SRGB_SIZE 9
struct { /* Segment Routing Local Block */
uint32_t lower_bound; /* MPLS label lower bound */
uint32_t range_size; /* MPLS label range size */
} srlb;
#define LS_NODE_SRLB_SIZE 8
uint8_t algo[2]; /* Segment Routing Algorithms */
uint8_t msd; /* Maximum Stack Depth */
};
/* Link State flags to indicate which Attribute parameters are valid */
#define LS_ATTR_UNSET 0x00000000
#define LS_ATTR_NAME 0x00000001
#define LS_ATTR_METRIC 0x00000002
#define LS_ATTR_TE_METRIC 0x00000004
#define LS_ATTR_ADM_GRP 0x00000008
#define LS_ATTR_LOCAL_ADDR 0x00000010
#define LS_ATTR_NEIGH_ADDR 0x00000020
#define LS_ATTR_LOCAL_ADDR6 0x00000040
#define LS_ATTR_NEIGH_ADDR6 0x00000080
#define LS_ATTR_LOCAL_ID 0x00000100
#define LS_ATTR_NEIGH_ID 0x00000200
#define LS_ATTR_MAX_BW 0x00000400
#define LS_ATTR_MAX_RSV_BW 0x00000800
#define LS_ATTR_UNRSV_BW 0x00001000
#define LS_ATTR_REMOTE_AS 0x00002000
#define LS_ATTR_REMOTE_ADDR 0x00004000
#define LS_ATTR_REMOTE_ADDR6 0x00008000
#define LS_ATTR_DELAY 0x00010000
#define LS_ATTR_MIN_MAX_DELAY 0x00020000
#define LS_ATTR_JITTER 0x00040000
#define LS_ATTR_PACKET_LOSS 0x00080000
#define LS_ATTR_AVA_BW 0x00100000
#define LS_ATTR_RSV_BW 0x00200000
#define LS_ATTR_USE_BW 0x00400000
#define LS_ATTR_ADJ_SID 0x00800000
#define LS_ATTR_BCK_ADJ_SID 0x01000000
#define LS_ATTR_SRLG 0x02000000
/* Link State Attributes */
struct ls_attributes {
uint32_t flags; /* Flag for parameters validity */
struct ls_node_id adv; /* Adv. Router of this Link State */
char name[MAX_NAME_LENGTH]; /* Name of the Edge. Could be null */
struct { /* Standard TE metrics */
uint32_t metric; /* IGP standard metric */
uint32_t te_metric; /* Traffic Engineering metric */
uint32_t admin_group; /* Administrative Group */
struct in_addr local; /* Local IPv4 address */
struct in_addr remote; /* Remote IPv4 address */
struct in6_addr local6; /* Local IPv6 address */
struct in6_addr remote6; /* Remote IPv6 address */
uint32_t local_id; /* Local Identifier */
uint32_t remote_id; /* Remote Identifier */
float max_bw; /* Maximum Link Bandwidth */
float max_rsv_bw; /* Maximum Reservable BW */
float unrsv_bw[8]; /* Unreserved BW per CT (8) */
uint32_t remote_as; /* Remote AS number */
struct in_addr remote_addr; /* Remote IPv4 address */
struct in6_addr remote_addr6; /* Remote IPv6 address */
} standard;
#define LS_ATTR_STANDARD_SIZE 124
struct { /* Extended TE Metrics */
uint32_t delay; /* Unidirectional average delay */
uint32_t min_delay; /* Unidirectional minimum delay */
uint32_t max_delay; /* Unidirectional maximum delay */
uint32_t jitter; /* Unidirectional delay variation */
uint32_t pkt_loss; /* Unidirectional packet loss */
float ava_bw; /* Available Bandwidth */
float rsv_bw; /* Reserved Bandwidth */
float used_bw; /* Utilized Bandwidth */
} extended;
#define LS_ATTR_EXTENDED_SIZE 32
struct { /* (LAN)-Adjacency SID for OSPF */
uint32_t sid; /* SID as MPLS label or index */
uint8_t flags; /* Flags */
uint8_t weight; /* Administrative weight */
union {
struct in_addr addr; /* Neighbor @IP for OSPF */
uint8_t sysid[ISO_SYS_ID_LEN]; /* or Sys-ID for ISIS */
} neighbor;
} adj_sid[2]; /* Primary & Backup (LAN)-Adj. SID */
#define LS_ATTR_ADJ_SID_SIZE 120
uint32_t *srlgs; /* List of Shared Risk Link Group */
uint8_t srlg_len; /* number of SRLG in the list */
};
/* Link State flags to indicate which Prefix parameters are valid */
#define LS_PREF_UNSET 0x00
#define LS_PREF_IGP_FLAG 0x01
#define LS_PREF_ROUTE_TAG 0x02
#define LS_PREF_EXTENDED_TAG 0x04
#define LS_PREF_METRIC 0x08
#define LS_PREF_SR 0x10
/* Link State Prefix */
struct ls_prefix {
uint8_t flags; /* Flag for parameters validity */
struct ls_node_id adv; /* Adv. Router of this Link State */
struct prefix pref; /* IPv4 or IPv6 prefix */
uint8_t igp_flag; /* IGP Flags associated to the prefix */
uint32_t route_tag; /* IGP Route Tag */
uint64_t extended_tag; /* IGP Extended Route Tag */
uint32_t metric; /* Route metric for this prefix */
struct {
uint32_t sid; /* Segment Routing ID */
uint8_t sid_flag; /* Segment Routing Flags */
uint8_t algo; /* Algorithm for Segment Routing */
} sr;
};
/**
* Create a new Link State Node. Structure is dynamically allocated.
*
* @param adv Mandatory Link State Node ID i.e. advertise router information
* @param rid Router ID as IPv4 address
* @param rid6 Router ID as IPv6 address
*
* @return New Link State Node
*/
extern struct ls_node *ls_node_new(struct ls_node_id adv, struct in_addr rid,
struct in6_addr rid6);
/**
* Remove Link State Node. Data structure is freed.
*
* @param node Pointer to a valid Link State Node structure
*/
extern void ls_node_del(struct ls_node *node);
/**
* Check if two Link State Nodes are equal. Note that this routine has the same
* return value sense as '==' (which is different from a comparison).
*
* @param n1 First Link State Node to be compare
* @param n2 Second Link State Node to be compare
*
* @return 1 if equal, 0 otherwise
*/
extern int ls_node_same(struct ls_node *n1, struct ls_node *n2);
/**
* Create a new Link State Attributes. Structure is dynamically allocated.
* At least one of parameters MUST be valid and not equal to 0.
*
* @param adv Mandatory Link State Node ID i.e. advertise router ID
* @param local Local IPv4 address
* @param local6 Local Ipv6 address
* @param local_id Local Identifier
*
* @return New Link State Attributes
*/
extern struct ls_attributes *ls_attributes_new(struct ls_node_id adv,
struct in_addr local,
struct in6_addr local6,
uint32_t local_id);
/**
* Remove Link State Attributes. Data structure is freed.
*
* @param attr Pointer to a valid Link State Attribute structure
*/
extern void ls_attributes_del(struct ls_attributes *attr);
/**
* Check if two Link State Attributes are equal. Note that this routine has the
* same return value sense as '==' (which is different from a comparison).
*
* @param a1 First Link State Attributes to be compare
* @param a2 Second Link State Attributes to be compare
*
* @return 1 if equal, 0 otherwise
*/
extern int ls_attributes_same(struct ls_attributes *a1,
struct ls_attributes *a2);
/**
* In addition a Graph model is defined as an overlay on top of link state
* database in order to ease Path Computation algorithm implementation.
* Denoted G(V, E), a graph is composed by a list of Vertices (V) which
* represents the network Node and a list of Edges (E) which represents node
* Link. An additional list of prefixes (P) is also added.
* A prefix (P) is also attached to the Vertex (V) which advertise it.
*
* Vertex (V) contains the list of outgoing Edges (E) that connect this Vertex
* with its direct neighbors and the list of incoming Edges (E) that connect
* the direct neighbors to this Vertex. Indeed, the Edge (E) is unidirectional,
* thus, it is necessary to add 2 Edges to model a bidirectional relation
* between 2 Vertices.
*
* Edge (E) contains the source and destination Vertex that this Edge
* is connecting.
*
* A unique Key is used to identify both Vertices and Edges within the Graph.
* An easy way to build this key is to used the IP address: i.e. loopback
* address for Vertices and link IP address for Edges.
*
* -------------- --------------------------- --------------
* | Connected |---->| Connected Edge Va to Vb |--->| Connected |
* --->| Vertex | --------------------------- | Vertex |---->
* | | | |
* | - Key (Va) | | - Key (Vb) |
* <---| - Vertex | --------------------------- | - Vertex |<----
* | |<----| Connected Edge Vb to Va |<---| |
* -------------- --------------------------- --------------
*
*/
/* Link State Vertex structure */
PREDECL_RBTREE_UNIQ(vertices)
struct ls_vertex {
struct vertices_item entry; /* Entry in RB Tree */
uint64_t key; /* Unique Key identifier */
struct ls_node *node; /* Link State Node */
struct list *incoming_edges; /* List of incoming Link State links */
struct list *outgoing_edges; /* List of outgoing Link State links */
struct list *prefixes; /* List of advertised prefix */
};
/* Link State Edge structure */
PREDECL_RBTREE_UNIQ(edges)
struct ls_edge {
struct edges_item entry; /* Entry in RB tree */
uint64_t key; /* Unique Key identifier */
struct ls_attributes *attributes; /* Link State attributes */
struct ls_vertex *source; /* Pointer to the source Vertex */
struct ls_vertex *destination; /* Pointer to the destination Vertex */
};
/* Link State Subnet structure */
PREDECL_RBTREE_UNIQ(subnets)
struct ls_subnet {
struct subnets_item entry; /* Entry in RB tree */
struct prefix key; /* Unique Key identifier */
struct ls_vertex *vertex; /* Back pointer to the Vertex owner */
struct ls_prefix *ls_pref; /* Link State Prefix */
};
/* Declaration of Vertices, Edges and Prefixes RB Trees */
macro_inline int vertex_cmp(const struct ls_vertex *node1,
const struct ls_vertex *node2)
{
return (node1->key - node2->key);
}
DECLARE_RBTREE_UNIQ(vertices, struct ls_vertex, entry, vertex_cmp)
macro_inline int edge_cmp(const struct ls_edge *edge1,
const struct ls_edge *edge2)
{
return (edge1->key - edge2->key);
}
DECLARE_RBTREE_UNIQ(edges, struct ls_edge, entry, edge_cmp)
macro_inline int subnet_cmp(const struct ls_subnet *a,
const struct ls_subnet *b)
{
return prefix_cmp(&a->key, &b->key);
}
DECLARE_RBTREE_UNIQ(subnets, struct ls_subnet, entry, subnet_cmp)
/* Link State TED Structure */
struct ls_ted {
uint32_t key; /* Unique identifier */
char name[MAX_NAME_LENGTH]; /* Name of this graph. Could be null */
uint32_t as_number; /* AS number of the modeled network */
struct ls_vertex *self; /* Vertex of the FRR instance */
struct vertices_head vertices; /* List of Vertices */
struct edges_head edges; /* List of Edges */
struct subnets_head subnets; /* List of Subnets */
};
/**
* Create a new Link State Vertex structure and initialize is with the Link
* State Node parameter.
*
* @param node Link State Node
*
* @return New Vertex
*/
extern struct ls_vertex *ls_vertex_new(struct ls_node *node);
/**
* Delete Link State Vertex. This function clean internal Vertex lists (incoming
* and outgoing Link State Edge and Link State Subnet). Note that referenced
* objects of the different lists (Edges & SubNet) are not removed as they could
* be connected to other Vertices.
*
* @param vertex Link State Vertex to be removed
*/
extern void ls_vertex_del(struct ls_vertex *vertex);
/**
* Add new vertex to the Link State DB. Vertex is created from the Link State
* Node. Vertex data structure is dynamically allocated.
*
* @param ted Traffic Engineering Database structure
* @param node Link State Node
*
* @return New Vertex or NULL in case of error
*/
extern struct ls_vertex *ls_vertex_add(struct ls_ted *ted,
struct ls_node *node);
/**
* Update Vertex with the Link State Node. A new vertex is created if no one
* corresponds to the Link State Node.
*
* @param ted Link State Data Base
* @param node Link State Node to be updated
*
* @return Updated Link State Vertex or Null in case of error
*/
extern struct ls_vertex *ls_vertex_update(struct ls_ted *ted,
struct ls_node *node);
/**
* Remove Vertex from the Link State DB. Vertex Data structure is freed but
* not the Link State Node. Link State DB is not modified if Vertex is NULL or
* not found in the Data Base.
*
* @param ted Link State Data Base
* @param vertex Vertex to be removed
*/
extern void ls_vertex_remove(struct ls_ted *ted, struct ls_vertex *vertex);
/**
* Find Vertex in the Link State DB by its unique key.
*
* @param ted Link State Data Base
* @param key Vertex Key different from 0
*
* @return Vertex if found, NULL otherwise
*/
extern struct ls_vertex *ls_find_vertex_by_key(struct ls_ted *ted,
const uint64_t key);
/**
* Find Vertex in the Link State DB by its Link State Node.
*
* @param ted Link State Data Base
* @param nid Link State Node ID
*
* @return Vertex if found, NULL otherwise
*/
extern struct ls_vertex *ls_find_vertex_by_id(struct ls_ted *ted,
struct ls_node_id nid);
/**
* Check if two Vertices are equal. Note that this routine has the same return
* value sense as '==' (which is different from a comparison).
*
* @param v1 First vertex to compare
* @param v2 Second vertex to compare
*
* @return 1 if equal, 0 otherwise
*/
extern int ls_vertex_same(struct ls_vertex *v1, struct ls_vertex *v2);
/**
* Add new Edge to the Link State DB. Edge is created from the Link State
* Attributes. Edge data structure is dynamically allocated.
*
* @param ted Link State Data Base
* @param attributes Link State attributes
*
* @return New Edge or NULL in case of error
*/
extern struct ls_edge *ls_edge_add(struct ls_ted *ted,
struct ls_attributes *attributes);
/**
* Update the Link State Attributes information of an existing Edge. If there is
* no corresponding Edge in the Link State Data Base, a new Edge is created.
*
* @param ted Link State Data Base
* @param attributes Link State Attributes
*
* @return Updated Link State Edge, or NULL in case of error
*/
extern struct ls_edge *ls_edge_update(struct ls_ted *ted,
struct ls_attributes *attributes);
/**
* Remove Edge from the Link State DB. Edge data structure is freed but not the
* Link State Attributes data structure. Link State DB is not modified if Edge
* is NULL or not found in the Data Base.
*
* @param ted Link State Data Base
* @param edge Edge to be removed
*/
extern void ls_edge_del(struct ls_ted *ted, struct ls_edge *edge);
/**
* Find Edge in the Link State Data Base by Edge key.
*
* @param ted Link State Data Base
* @param key Edge key
*
* @return Edge if found, NULL otherwise
*/
extern struct ls_edge *ls_find_edge_by_key(struct ls_ted *ted,
const uint64_t key);
/**
* Find Edge in the Link State Data Base by the source (local IPv4 or IPv6
* address or local ID) informations of the Link
* State Attributes
*
* @param ted Link State Data Base
* @param attributes Link State Attributes
*
* @return Edge if found, NULL otherwise
*/
extern struct ls_edge *
ls_find_edge_by_source(struct ls_ted *ted, struct ls_attributes *attributes);
/**
* Find Edge in the Link State Data Base by the destination (remote IPv4 or IPv6
* address of remote ID) information of the Link State Attributes
*
* @param ted Link State Data Base
* @param attributes Link State Attributes
*
* @return Edge if found, NULL otherwise
*/
extern struct ls_edge *
ls_find_edge_by_destination(struct ls_ted *ted,
struct ls_attributes *attributes);
/**
* Add new Subnet to the Link State DB. Subnet is created from the Link State
* prefix. Subnet data structure is dynamically allocated.
*
* @param ted Link State Data Base
* @param pref Link State Prefix
*
* @return New Subnet
*/
extern struct ls_subnet *ls_subnet_add(struct ls_ted *ted,
struct ls_prefix *pref);
/**
* Remove Subnet from the Link State DB. Subnet data structure is freed but
* not the Link State prefix data structure. Link State DB is not modified
* if Subnet is NULL or not found in the Data Base.
*
* @param ted Link State Data Base
* @param subnet Subnet to be removed
*/
extern void ls_subnet_del(struct ls_ted *ted, struct ls_subnet *subnet);
/**
* Find Subnet in the Link State Data Base by prefix.
*
* @param ted Link State Data Base
* @param prefix Link State Prefix
*
* @return Subnet if found, NULL otherwise
*/
extern struct ls_subnet *ls_find_subnet(struct ls_ted *ted,
const struct prefix prefix);
/**
* Create a new Link State Data Base.
*
* @param key Unique key of the data base. Must be different from 0
* @param name Name of the data base (may be NULL)
* @param asn AS Number for this data base. Must be different from 0
*
* @return New Link State Database or NULL in case of error
*/
extern struct ls_ted *ls_ted_new(const uint32_t key, const char *name,
uint32_t asn);
/**
* Delete existing Link State Data Base.
*
* @param ted Link State Data Base
*/
extern void ls_ted_del(struct ls_ted *ted);
/**
* Connect Source and Destination Vertices by given Edge. Only non NULL source
* and destination vertices are connected.
*
* @param src Link State Source Vertex
* @param dst Link State Destination Vertex
* @param edge Link State Edge. Must not be NULL
*/
extern void ls_connect_vertices(struct ls_vertex *src, struct ls_vertex *dst,
struct ls_edge *edge);
/**
* Connect Link State Edge to the Link State Vertex which could be a Source or
* a Destination Vertex.
*
* @param vertex Link State Vertex to be connected. Must not be NULL
* @param edge Link State Edge connection. Must not be NULL
* @param source True for a Source, false for a Destination Vertex
*/
extern void ls_connect(struct ls_vertex *vertex, struct ls_edge *edge,
bool source);
/**
* Disconnect Link State Edge from the Link State Vertex which could be a
* Source or a Destination Vertex.
*
* @param vertex Link State Vertex to be connected. Must not be NULL
* @param edge Link State Edge connection. Must not be NULL
* @param source True for a Source, false for a Destination Vertex
*/
extern void ls_disconnect(struct ls_vertex *vertex, struct ls_edge *edge,
bool source);
/**
* Disconnect Link State Edge from both Source and Destination Vertex.
*
* @param edge Link State Edge to be disconnected
*/
extern void ls_disconnect_edge(struct ls_edge *edge);
/**
* The Link State Message is defined to convey Link State parameters from
* the routing protocol (OSPF or IS-IS) to other daemons e.g. BGP.
*
* The structure is composed of:
* - Event of the message:
* - Sync: Send the whole LS DB following a request
* - Add: Send the a new Link State element
* - Update: Send an update of an existing Link State element
* - Delete: Indicate that the given Link State element is removed
* - Type of Link State element: Node, Attribute or Prefix
* - Remote node id when known
* - Data: Node, Attributes or Prefix
*
* A Link State Message can carry only one Link State Element (Node, Attributes
* of Prefix) at once, and only one Link State Message is sent through ZAPI
* Opaque Link State type at once.
*/
/* ZAPI Opaque Link State Message Event */
#define LS_MSG_EVENT_SYNC 1
#define LS_MSG_EVENT_ADD 2
#define LS_MSG_EVENT_UPDATE 3
#define LS_MSG_EVENT_DELETE 4
/* ZAPI Opaque Link State Message sub-Type */
#define LS_MSG_TYPE_NODE 1
#define LS_MSG_TYPE_ATTRIBUTES 2
#define LS_MSG_TYPE_PREFIX 3
/* Link State Message */
struct ls_message {
uint8_t event; /* Message Event: Sync, Add, Update, Delete */
uint8_t type; /* Message Data Type: Node, Attribute, Prefix */
struct ls_node_id remote_id; /* Remote Link State Node ID */
union {
struct ls_node *node; /* Link State Node */
struct ls_attributes *attr; /* Link State Attributes */
struct ls_prefix *prefix; /* Link State Prefix */
} data;
};
/**
* Parse Link State Message from stream. Used this function once receiving a
* new ZAPI Opaque message of type Link State.
*
* @param s Stream buffer. Must not be NULL.
*
* @return New Link State Message or NULL in case of error
*/
extern struct ls_message *ls_parse_msg(struct stream *s);
/**
* Delete existing message, freeing all substructure.
*
* @param msg Link state message to be deleted
*/
extern void ls_delete_msg(struct ls_message *msg);
/**
* Send Link State Message as new ZAPI Opaque message of type Link State.
* If destination is not NULL, message is sent as Unicast otherwise it is
* broadcast to all registered daemon.
*
* @param zclient Zebra Client
* @param msg Link State Message to be sent
* @param dst Destination daemon for unicast message,
* NULL for broadcast message
*
* @return 0 on success, -1 otherwise
*/
extern int ls_send_msg(struct zclient *zclient, struct ls_message *msg,
struct zapi_opaque_reg_info *dst);
/**
* Create a new Link State Message from a Link State Vertex. If Link State
* Message is NULL, a new data structure is dynamically allocated.
*
* @param msg Link State Message to be filled or NULL
* @param vertex Link State Vertex. Must not be NULL
*
* @return New Link State Message msg parameter is NULL or pointer
* to the provided Link State Message
*/
extern struct ls_message *ls_vertex2msg(struct ls_message *msg,
struct ls_vertex *vertex);
/**
* Create a new Link State Message from a Link State Edge. If Link State
* Message is NULL, a new data structure is dynamically allocated.
*
* @param msg Link State Message to be filled or NULL
* @param edge Link State Edge. Must not be NULL
*
* @return New Link State Message msg parameter is NULL or pointer
* to the provided Link State Message
*/
extern struct ls_message *ls_edge2msg(struct ls_message *msg,
struct ls_edge *edge);
/**
* Create a new Link State Message from a Link State Subnet. If Link State
* Message is NULL, a new data structure is dynamically allocated.
*
* @param msg Link State Message to be filled or NULL
* @param subnet Link State Subnet. Must not be NULL
*
* @return New Link State Message msg parameter is NULL or pointer
* to the provided Link State Message
*/
extern struct ls_message *ls_subnet2msg(struct ls_message *msg,
struct ls_subnet *subnet);
/**
* Send all the content of the Link State Data Base to the given destination.
* Link State content is sent is this order: Vertices, Edges, Subnet.
* This function must be used when a daemon request a Link State Data Base
* Synchronization.
*
* @param ted Link State Data Base. Must not be NULL
* @param zclient Zebra Client. Must not be NULL
* @param dst Destination FRR daemon. Must not be NULL
*
* @return 0 on success, -1 otherwise
*/
extern int ls_sync_ted(struct ls_ted *ted, struct zclient *zclient,
struct zapi_opaque_reg_info *dst);
/**
* Dump all Link State Data Base elements for debugging purposes
*
* @param ted Link State Data Base. Must not be NULL
*
*/
extern void ls_dump_ted(struct ls_ted *ted);
#ifdef __cplusplus
}
#endif
#endif /* _FRR_LINK_STATE_H_ */
|