]> git.proxmox.com Git - mirror_frr.git/blob - lib/link_state.c
Merge pull request #13326 from opensourcerouting/feature/rip_topotest_distribute_list
[mirror_frr.git] / lib / link_state.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Link State Database - link_state.c
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 #include <zebra.h>
13
14 #include "if.h"
15 #include "linklist.h"
16 #include "log.h"
17 #include "command.h"
18 #include "termtable.h"
19 #include "memory.h"
20 #include "prefix.h"
21 #include "table.h"
22 #include "vty.h"
23 #include "zclient.h"
24 #include "stream.h"
25 #include "sbuf.h"
26 #include "printfrr.h"
27 #include <lib/json.h>
28 #include "link_state.h"
29 #include "iso.h"
30
31 /* Link State Memory allocation */
32 DEFINE_MTYPE_STATIC(LIB, LS_DB, "Link State Database");
33
34 /**
35 * Link State Node management functions
36 */
37 int ls_node_id_same(struct ls_node_id i1, struct ls_node_id i2)
38 {
39 if (i1.origin != i2.origin)
40 return 0;
41
42 if (i1.origin == UNKNOWN)
43 return 1;
44
45 if (i1.origin == ISIS_L1 || i1.origin == ISIS_L2) {
46 if (memcmp(i1.id.iso.sys_id, i2.id.iso.sys_id, ISO_SYS_ID_LEN)
47 != 0
48 || (i1.id.iso.level != i2.id.iso.level))
49 return 0;
50 } else {
51 if (!IPV4_ADDR_SAME(&i1.id.ip.addr, &i2.id.ip.addr)
52 || !IPV4_ADDR_SAME(&i1.id.ip.area_id, &i2.id.ip.area_id))
53 return 1;
54 }
55
56 return 1;
57 }
58
59 struct ls_node *ls_node_new(struct ls_node_id adv, struct in_addr rid,
60 struct in6_addr rid6)
61 {
62 struct ls_node *new;
63
64 if (adv.origin == UNKNOWN)
65 return NULL;
66
67 new = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_node));
68 new->adv = adv;
69 if (!IPV4_NET0(rid.s_addr)) {
70 new->router_id = rid;
71 SET_FLAG(new->flags, LS_NODE_ROUTER_ID);
72 } else {
73 if (adv.origin == OSPFv2 || adv.origin == STATIC
74 || adv.origin == DIRECT) {
75 new->router_id = adv.id.ip.addr;
76 SET_FLAG(new->flags, LS_NODE_ROUTER_ID);
77 }
78 }
79 if (!IN6_IS_ADDR_UNSPECIFIED(&rid6)) {
80 new->router_id6 = rid6;
81 SET_FLAG(new->flags, LS_NODE_ROUTER_ID6);
82 }
83 return new;
84 }
85
86 void ls_node_del(struct ls_node *node)
87 {
88 if (!node)
89 return;
90
91 XFREE(MTYPE_LS_DB, node);
92 }
93
94 int ls_node_same(struct ls_node *n1, struct ls_node *n2)
95 {
96 /* First, check pointer */
97 if ((n1 && !n2) || (!n1 && n2))
98 return 0;
99
100 if (n1 == n2)
101 return 1;
102
103 /* Then, verify Flags and Origin */
104 if (n1->flags != n2->flags)
105 return 0;
106
107 if (!ls_node_id_same(n1->adv, n2->adv))
108 return 0;
109
110 /* Finally, check each individual parameters that are valid */
111 if (CHECK_FLAG(n1->flags, LS_NODE_NAME)
112 && (strncmp(n1->name, n2->name, MAX_NAME_LENGTH) != 0))
113 return 0;
114 if (CHECK_FLAG(n1->flags, LS_NODE_ROUTER_ID)
115 && !IPV4_ADDR_SAME(&n1->router_id, &n2->router_id))
116 return 0;
117 if (CHECK_FLAG(n1->flags, LS_NODE_ROUTER_ID6)
118 && !IPV6_ADDR_SAME(&n1->router_id6, &n2->router_id6))
119 return 0;
120 if (CHECK_FLAG(n1->flags, LS_NODE_FLAG)
121 && (n1->node_flag != n2->node_flag))
122 return 0;
123 if (CHECK_FLAG(n1->flags, LS_NODE_TYPE) && (n1->type != n2->type))
124 return 0;
125 if (CHECK_FLAG(n1->flags, LS_NODE_AS_NUMBER)
126 && (n1->as_number != n2->as_number))
127 return 0;
128 if (CHECK_FLAG(n1->flags, LS_NODE_SR)) {
129 if (n1->srgb.flag != n2->srgb.flag
130 || n1->srgb.lower_bound != n2->srgb.lower_bound
131 || n1->srgb.range_size != n2->srgb.range_size)
132 return 0;
133 if ((n1->algo[0] != n2->algo[0])
134 || (n1->algo[1] != n2->algo[1]))
135 return 0;
136 if (CHECK_FLAG(n1->flags, LS_NODE_SRLB)
137 && ((n1->srlb.lower_bound != n2->srlb.lower_bound
138 || n1->srlb.range_size != n2->srlb.range_size)))
139 return 0;
140 if (CHECK_FLAG(n1->flags, LS_NODE_MSD) && (n1->msd != n2->msd))
141 return 0;
142 }
143
144 /* OK, n1 & n2 are equal */
145 return 1;
146 }
147
148 /**
149 * Link State Attributes management functions
150 */
151 struct ls_attributes *ls_attributes_new(struct ls_node_id adv,
152 struct in_addr local,
153 struct in6_addr local6,
154 uint32_t local_id)
155 {
156 struct ls_attributes *new;
157
158 if (adv.origin == UNKNOWN)
159 return NULL;
160
161 new = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_attributes));
162 new->adv = adv;
163 if (!IPV4_NET0(local.s_addr)) {
164 new->standard.local = local;
165 SET_FLAG(new->flags, LS_ATTR_LOCAL_ADDR);
166 }
167 if (!IN6_IS_ADDR_UNSPECIFIED(&local6)) {
168 new->standard.local6 = local6;
169 SET_FLAG(new->flags, LS_ATTR_LOCAL_ADDR6);
170 }
171 if (local_id != 0) {
172 new->standard.local_id = local_id;
173 SET_FLAG(new->flags, LS_ATTR_LOCAL_ID);
174 }
175
176 /* Check that almost one identifier is set */
177 if (!CHECK_FLAG(new->flags, LS_ATTR_LOCAL_ADDR | LS_ATTR_LOCAL_ADDR6
178 | LS_ATTR_LOCAL_ID)) {
179 XFREE(MTYPE_LS_DB, new);
180 return NULL;
181 }
182
183 admin_group_init(&new->ext_admin_group);
184
185 return new;
186 }
187
188 void ls_attributes_srlg_del(struct ls_attributes *attr)
189 {
190 if (!attr)
191 return;
192
193 if (attr->srlgs)
194 XFREE(MTYPE_LS_DB, attr->srlgs);
195
196 attr->srlgs = NULL;
197 attr->srlg_len = 0;
198 UNSET_FLAG(attr->flags, LS_ATTR_SRLG);
199 }
200
201 void ls_attributes_del(struct ls_attributes *attr)
202 {
203 if (!attr)
204 return;
205
206 ls_attributes_srlg_del(attr);
207
208 admin_group_term(&attr->ext_admin_group);
209
210 XFREE(MTYPE_LS_DB, attr);
211 }
212
213 int ls_attributes_same(struct ls_attributes *l1, struct ls_attributes *l2)
214 {
215 /* First, check pointer */
216 if ((l1 && !l2) || (!l1 && l2))
217 return 0;
218
219 if (l1 == l2)
220 return 1;
221
222 /* Then, verify Flags and Origin */
223 if (l1->flags != l2->flags)
224 return 0;
225
226 if (!ls_node_id_same(l1->adv, l2->adv))
227 return 0;
228
229 /* Finally, check each individual parameters that are valid */
230 if (CHECK_FLAG(l1->flags, LS_ATTR_NAME)
231 && strncmp(l1->name, l2->name, MAX_NAME_LENGTH) != 0)
232 return 0;
233 if (CHECK_FLAG(l1->flags, LS_ATTR_METRIC) && (l1->metric != l2->metric))
234 return 0;
235 if (CHECK_FLAG(l1->flags, LS_ATTR_TE_METRIC)
236 && (l1->standard.te_metric != l2->standard.te_metric))
237 return 0;
238 if (CHECK_FLAG(l1->flags, LS_ATTR_ADM_GRP)
239 && (l1->standard.admin_group != l2->standard.admin_group))
240 return 0;
241 if (CHECK_FLAG(l1->flags, LS_ATTR_EXT_ADM_GRP) &&
242 !admin_group_cmp(&l1->ext_admin_group, &l2->ext_admin_group))
243 return 0;
244 if (CHECK_FLAG(l1->flags, LS_ATTR_LOCAL_ADDR)
245 && !IPV4_ADDR_SAME(&l1->standard.local, &l2->standard.local))
246 return 0;
247 if (CHECK_FLAG(l1->flags, LS_ATTR_NEIGH_ADDR)
248 && !IPV4_ADDR_SAME(&l1->standard.remote, &l2->standard.remote))
249 return 0;
250 if (CHECK_FLAG(l1->flags, LS_ATTR_LOCAL_ADDR6)
251 && !IPV6_ADDR_SAME(&l1->standard.local6, &l2->standard.local6))
252 return 0;
253 if (CHECK_FLAG(l1->flags, LS_ATTR_NEIGH_ADDR6)
254 && !IPV6_ADDR_SAME(&l1->standard.remote6, &l2->standard.remote6))
255 return 0;
256 if (CHECK_FLAG(l1->flags, LS_ATTR_LOCAL_ID)
257 && (l1->standard.local_id != l2->standard.local_id))
258 return 0;
259 if (CHECK_FLAG(l1->flags, LS_ATTR_NEIGH_ID)
260 && (l1->standard.remote_id != l2->standard.remote_id))
261 return 0;
262 if (CHECK_FLAG(l1->flags, LS_ATTR_MAX_BW)
263 && (l1->standard.max_bw != l2->standard.max_bw))
264 return 0;
265 if (CHECK_FLAG(l1->flags, LS_ATTR_MAX_RSV_BW)
266 && (l1->standard.max_rsv_bw != l2->standard.max_rsv_bw))
267 return 0;
268 if (CHECK_FLAG(l1->flags, LS_ATTR_UNRSV_BW)
269 && memcmp(&l1->standard.unrsv_bw, &l2->standard.unrsv_bw, 32) != 0)
270 return 0;
271 if (CHECK_FLAG(l1->flags, LS_ATTR_REMOTE_AS)
272 && (l1->standard.remote_as != l2->standard.remote_as))
273 return 0;
274 if (CHECK_FLAG(l1->flags, LS_ATTR_REMOTE_ADDR)
275 && !IPV4_ADDR_SAME(&l1->standard.remote_addr,
276 &l2->standard.remote_addr))
277 return 0;
278 if (CHECK_FLAG(l1->flags, LS_ATTR_REMOTE_ADDR6)
279 && !IPV6_ADDR_SAME(&l1->standard.remote_addr6,
280 &l2->standard.remote_addr6))
281 return 0;
282 if (CHECK_FLAG(l1->flags, LS_ATTR_DELAY)
283 && (l1->extended.delay != l2->extended.delay))
284 return 0;
285 if (CHECK_FLAG(l1->flags, LS_ATTR_MIN_MAX_DELAY)
286 && ((l1->extended.min_delay != l2->extended.min_delay)
287 || (l1->extended.max_delay != l2->extended.max_delay)))
288 return 0;
289 if (CHECK_FLAG(l1->flags, LS_ATTR_JITTER)
290 && (l1->extended.jitter != l2->extended.jitter))
291 return 0;
292 if (CHECK_FLAG(l1->flags, LS_ATTR_PACKET_LOSS)
293 && (l1->extended.pkt_loss != l2->extended.pkt_loss))
294 return 0;
295 if (CHECK_FLAG(l1->flags, LS_ATTR_AVA_BW)
296 && (l1->extended.ava_bw != l2->extended.ava_bw))
297 return 0;
298 if (CHECK_FLAG(l1->flags, LS_ATTR_RSV_BW)
299 && (l1->extended.rsv_bw != l2->extended.rsv_bw))
300 return 0;
301 if (CHECK_FLAG(l1->flags, LS_ATTR_USE_BW)
302 && (l1->extended.used_bw != l2->extended.used_bw))
303 return 0;
304 for (int i = 0; i < LS_ADJ_MAX; i++) {
305 if (!CHECK_FLAG(l1->flags, (LS_ATTR_ADJ_SID << i)))
306 continue;
307 if ((l1->adj_sid[i].sid != l2->adj_sid[i].sid)
308 || (l1->adj_sid[i].flags != l2->adj_sid[i].flags)
309 || (l1->adj_sid[i].weight != l2->adj_sid[i].weight))
310 return 0;
311 if (((l1->adv.origin == ISIS_L1) || (l1->adv.origin == ISIS_L2))
312 && (memcmp(&l1->adj_sid[i].neighbor.sysid,
313 &l2->adj_sid[i].neighbor.sysid, ISO_SYS_ID_LEN)
314 != 0))
315 return 0;
316 if (((l1->adv.origin == OSPFv2) || (l1->adv.origin == STATIC)
317 || (l1->adv.origin == DIRECT))
318 && (i < ADJ_PRI_IPV6)
319 && (!IPV4_ADDR_SAME(&l1->adj_sid[i].neighbor.addr,
320 &l2->adj_sid[i].neighbor.addr)))
321 return 0;
322 }
323 if (CHECK_FLAG(l1->flags, LS_ATTR_SRLG)
324 && ((l1->srlg_len != l2->srlg_len)
325 || memcmp(l1->srlgs, l2->srlgs,
326 l1->srlg_len * sizeof(uint32_t))
327 != 0))
328 return 0;
329
330 /* OK, l1 & l2 are equal */
331 return 1;
332 }
333
334 /**
335 * Link State prefix management functions
336 */
337 struct ls_prefix *ls_prefix_new(struct ls_node_id adv, struct prefix *p)
338 {
339 struct ls_prefix *new;
340
341 if (adv.origin == UNKNOWN)
342 return NULL;
343
344 new = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_prefix));
345 new->adv = adv;
346 new->pref = *p;
347
348 return new;
349 }
350
351 void ls_prefix_del(struct ls_prefix *pref)
352 {
353 if (!pref)
354 return;
355
356 XFREE(MTYPE_LS_DB, pref);
357 }
358
359 int ls_prefix_same(struct ls_prefix *p1, struct ls_prefix *p2)
360 {
361 /* First, check pointer */
362 if ((p1 && !p2) || (!p1 && p2))
363 return 0;
364
365 if (p1 == p2)
366 return 1;
367
368 /* Then, verify Flags and Origin */
369 if (p1->flags != p2->flags)
370 return 0;
371
372 if (!ls_node_id_same(p1->adv, p2->adv))
373 return 0;
374
375 /* Finally, check each individual parameters that are valid */
376 if (prefix_same(&p1->pref, &p2->pref) == 0)
377 return 0;
378 if (CHECK_FLAG(p1->flags, LS_PREF_IGP_FLAG)
379 && (p1->igp_flag != p2->igp_flag))
380 return 0;
381 if (CHECK_FLAG(p1->flags, LS_PREF_ROUTE_TAG)
382 && (p1->route_tag != p2->route_tag))
383 return 0;
384 if (CHECK_FLAG(p1->flags, LS_PREF_EXTENDED_TAG)
385 && (p1->extended_tag != p2->extended_tag))
386 return 0;
387 if (CHECK_FLAG(p1->flags, LS_PREF_METRIC) && (p1->metric != p2->metric))
388 return 0;
389 if (CHECK_FLAG(p1->flags, LS_PREF_SR)) {
390 if ((p1->sr.algo != p2->sr.algo) || (p1->sr.sid != p2->sr.sid)
391 || (p1->sr.sid_flag != p2->sr.sid_flag))
392 return 0;
393 }
394
395 /* OK, p1 & p2 are equal */
396 return 1;
397 }
398
399 /**
400 * Link State Vertices management functions
401 */
402 uint64_t sysid_to_key(const uint8_t sysid[ISO_SYS_ID_LEN])
403 {
404 uint64_t key = 0;
405
406 #if BYTE_ORDER == LITTLE_ENDIAN
407 uint8_t *byte = (uint8_t *)&key;
408
409 for (int i = 0; i < ISO_SYS_ID_LEN; i++)
410 byte[i] = sysid[ISO_SYS_ID_LEN - i - 1];
411
412 byte[6] = 0;
413 byte[7] = 0;
414 #else
415 memcpy(&key, sysid, ISO_SYS_ID_LEN);
416 #endif
417
418 return key;
419 }
420
421 struct ls_vertex *ls_vertex_add(struct ls_ted *ted, struct ls_node *node)
422 {
423 struct ls_vertex *new;
424 uint64_t key = 0;
425
426 if ((ted == NULL) || (node == NULL))
427 return NULL;
428
429 /* set Key as the IPv4/Ipv6 Router ID or ISO System ID */
430 switch (node->adv.origin) {
431 case OSPFv2:
432 case STATIC:
433 case DIRECT:
434 key = ((uint64_t)ntohl(node->adv.id.ip.addr.s_addr))
435 & 0xffffffff;
436 break;
437 case ISIS_L1:
438 case ISIS_L2:
439 key = sysid_to_key(node->adv.id.iso.sys_id);
440 break;
441 case UNKNOWN:
442 key = 0;
443 break;
444 }
445
446 /* Check that key is valid */
447 if (key == 0)
448 return NULL;
449
450 /* Create Vertex and add it to the TED */
451 new = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_vertex));
452 if (!new)
453 return NULL;
454
455 new->key = key;
456 new->node = node;
457 new->status = NEW;
458 new->type = VERTEX;
459 new->incoming_edges = list_new();
460 new->incoming_edges->cmp = (int (*)(void *, void *))edge_cmp;
461 new->outgoing_edges = list_new();
462 new->outgoing_edges->cmp = (int (*)(void *, void *))edge_cmp;
463 new->prefixes = list_new();
464 new->prefixes->cmp = (int (*)(void *, void *))subnet_cmp;
465 vertices_add(&ted->vertices, new);
466
467 return new;
468 }
469
470 void ls_vertex_del(struct ls_ted *ted, struct ls_vertex *vertex)
471 {
472 struct listnode *node, *nnode;
473 struct ls_edge *edge;
474 struct ls_subnet *subnet;
475
476 if (!ted || !vertex)
477 return;
478
479 /* Remove outgoing Edges and list */
480 for (ALL_LIST_ELEMENTS(vertex->outgoing_edges, node, nnode, edge))
481 ls_edge_del_all(ted, edge);
482 list_delete(&vertex->outgoing_edges);
483
484 /* Disconnect incoming Edges and remove list */
485 for (ALL_LIST_ELEMENTS(vertex->incoming_edges, node, nnode, edge)) {
486 ls_disconnect(vertex, edge, false);
487 if (edge->source == NULL)
488 ls_edge_del_all(ted, edge);
489 }
490 list_delete(&vertex->incoming_edges);
491
492 /* Remove subnet and list */
493 for (ALL_LIST_ELEMENTS(vertex->prefixes, node, nnode, subnet))
494 ls_subnet_del_all(ted, subnet);
495 list_delete(&vertex->prefixes);
496
497 /* Then remove Vertex from Link State Data Base and free memory */
498 vertices_del(&ted->vertices, vertex);
499 XFREE(MTYPE_LS_DB, vertex);
500 vertex = NULL;
501 }
502
503 void ls_vertex_del_all(struct ls_ted *ted, struct ls_vertex *vertex)
504 {
505 if (!ted || !vertex)
506 return;
507
508 /* First remove associated Link State Node */
509 ls_node_del(vertex->node);
510
511 /* Then, Vertex itself */
512 ls_vertex_del(ted, vertex);
513 }
514
515 struct ls_vertex *ls_vertex_update(struct ls_ted *ted, struct ls_node *node)
516 {
517 struct ls_vertex *old;
518
519 if (node == NULL)
520 return NULL;
521
522 old = ls_find_vertex_by_id(ted, node->adv);
523 if (old) {
524 if (!ls_node_same(old->node, node)) {
525 ls_node_del(old->node);
526 old->node = node;
527 }
528 old->status = UPDATE;
529 return old;
530 }
531
532 return ls_vertex_add(ted, node);
533 }
534
535 struct ls_vertex *ls_find_vertex_by_key(struct ls_ted *ted, const uint64_t key)
536 {
537 struct ls_vertex vertex = {};
538
539 if (key == 0)
540 return NULL;
541
542 vertex.key = key;
543 return vertices_find(&ted->vertices, &vertex);
544 }
545
546 struct ls_vertex *ls_find_vertex_by_id(struct ls_ted *ted,
547 struct ls_node_id nid)
548 {
549 struct ls_vertex vertex = {};
550
551 vertex.key = 0;
552 switch (nid.origin) {
553 case OSPFv2:
554 case STATIC:
555 case DIRECT:
556 vertex.key =
557 ((uint64_t)ntohl(nid.id.ip.addr.s_addr)) & 0xffffffff;
558 break;
559 case ISIS_L1:
560 case ISIS_L2:
561 vertex.key = sysid_to_key(nid.id.iso.sys_id);
562 break;
563 case UNKNOWN:
564 return NULL;
565 }
566
567 return vertices_find(&ted->vertices, &vertex);
568 }
569
570 int ls_vertex_same(struct ls_vertex *v1, struct ls_vertex *v2)
571 {
572 if ((v1 && !v2) || (!v1 && v2))
573 return 0;
574
575 if (!v1 && !v2)
576 return 1;
577
578 if (v1->key != v2->key)
579 return 0;
580
581 if (v1->node == v2->node)
582 return 1;
583
584 return ls_node_same(v1->node, v2->node);
585 }
586
587 void ls_vertex_clean(struct ls_ted *ted, struct ls_vertex *vertex,
588 struct zclient *zclient)
589 {
590 struct listnode *node, *nnode;
591 struct ls_edge *edge;
592 struct ls_subnet *subnet;
593 struct ls_message msg;
594
595 /* Remove Orphan Edge ... */
596 for (ALL_LIST_ELEMENTS(vertex->outgoing_edges, node, nnode, edge)) {
597 if (edge->status == ORPHAN) {
598 if (zclient) {
599 edge->status = DELETE;
600 ls_edge2msg(&msg, edge);
601 ls_send_msg(zclient, &msg, NULL);
602 }
603 ls_edge_del_all(ted, edge);
604 }
605 }
606 for (ALL_LIST_ELEMENTS(vertex->incoming_edges, node, nnode, edge)) {
607 if (edge->status == ORPHAN) {
608 if (zclient) {
609 edge->status = DELETE;
610 ls_edge2msg(&msg, edge);
611 ls_send_msg(zclient, &msg, NULL);
612 }
613 ls_edge_del_all(ted, edge);
614 }
615 }
616
617 /* ... and Subnet from the Vertex */
618 for (ALL_LIST_ELEMENTS(vertex->prefixes, node, nnode, subnet)) {
619 if (subnet->status == ORPHAN) {
620 if (zclient) {
621 subnet->status = DELETE;
622 ls_subnet2msg(&msg, subnet);
623 ls_send_msg(zclient, &msg, NULL);
624 }
625 ls_subnet_del_all(ted, subnet);
626 }
627 }
628 }
629
630 /**
631 * Link State Edges management functions
632 */
633
634 /**
635 * This function allows to connect the Edge to the vertices present in the TED.
636 * A temporary vertex that corresponds to the source of this Edge i.e. the
637 * advertised router, is created if not found in the Data Base. If a Edge that
638 * corresponds to the reverse path is found, the Edge is attached to the
639 * destination vertex as destination and reverse Edge is attached to the source
640 * vertex as source.
641 *
642 * @param ted Link State Data Base
643 * @param edge Link State Edge to be attached
644 */
645 static void ls_edge_connect_to(struct ls_ted *ted, struct ls_edge *edge)
646 {
647 struct ls_vertex *vertex = NULL;
648 struct ls_node *node;
649 struct ls_edge *dst;
650 const struct in_addr inaddr_any = {.s_addr = INADDR_ANY};
651
652 /* First, search if there is a Vertex that correspond to the Node ID */
653 vertex = ls_find_vertex_by_id(ted, edge->attributes->adv);
654 if (vertex == NULL) {
655 /* Create a new temporary Node & Vertex if not found */
656 node = ls_node_new(edge->attributes->adv, inaddr_any,
657 in6addr_any);
658 vertex = ls_vertex_add(ted, node);
659 }
660 /* and attach the edge as source to the vertex */
661 listnode_add_sort_nodup(vertex->outgoing_edges, edge);
662 edge->source = vertex;
663
664 /* Then search if there is a reverse Edge */
665 dst = ls_find_edge_by_destination(ted, edge->attributes);
666 /* attach the destination edge to the vertex */
667 if (dst) {
668 listnode_add_sort_nodup(vertex->incoming_edges, dst);
669 dst->destination = vertex;
670 /* and destination vertex to this edge */
671 vertex = dst->source;
672 listnode_add_sort_nodup(vertex->incoming_edges, edge);
673 edge->destination = vertex;
674 }
675 }
676
677 static struct ls_edge_key get_edge_key(struct ls_attributes *attr, bool dst)
678 {
679 struct ls_edge_key key = {.family = AF_UNSPEC};
680 struct ls_standard *std;
681
682 if (!attr)
683 return key;
684
685 std = &attr->standard;
686
687 if (dst) {
688 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR)) {
689 /* Key is the IPv4 remote address */
690 key.family = AF_INET;
691 IPV4_ADDR_COPY(&key.k.addr, &std->remote);
692 } else if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR6)) {
693 /* or the IPv6 remote address */
694 key.family = AF_INET6;
695 IPV6_ADDR_COPY(&key.k.addr6, &std->remote6);
696 } else if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ID)) {
697 /* or Remote identifier if IP addr. are not defined */
698 key.family = AF_LOCAL;
699 key.k.link_id =
700 (((uint64_t)std->remote_id) & 0xffffffff) |
701 ((uint64_t)std->local_id << 32);
702 }
703 } else {
704 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR)) {
705 /* Key is the IPv4 local address */
706 key.family = AF_INET;
707 IPV4_ADDR_COPY(&key.k.addr, &std->local);
708 } else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6)) {
709 /* or the 64 bits LSB of IPv6 local address */
710 key.family = AF_INET6;
711 IPV6_ADDR_COPY(&key.k.addr6, &std->local6);
712 } else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID)) {
713 /* or Remote identifier if IP addr. are not defined */
714 key.family = AF_LOCAL;
715 key.k.link_id =
716 (((uint64_t)std->local_id) & 0xffffffff) |
717 ((uint64_t)std->remote_id << 32);
718 }
719 }
720
721 return key;
722 }
723
724 struct ls_edge *ls_edge_add(struct ls_ted *ted,
725 struct ls_attributes *attributes)
726 {
727 struct ls_edge *new;
728 struct ls_edge_key key;
729
730 if (attributes == NULL)
731 return NULL;
732
733 key = get_edge_key(attributes, false);
734 if (key.family == AF_UNSPEC)
735 return NULL;
736
737 /* Create Edge and add it to the TED */
738 new = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_edge));
739
740 new->attributes = attributes;
741 new->key = key;
742 new->status = NEW;
743 new->type = EDGE;
744 edges_add(&ted->edges, new);
745
746 /* Finally, connect Edge to Vertices */
747 ls_edge_connect_to(ted, new);
748
749 return new;
750 }
751
752 struct ls_edge *ls_find_edge_by_key(struct ls_ted *ted,
753 const struct ls_edge_key key)
754 {
755 struct ls_edge edge = {};
756
757 if (key.family == AF_UNSPEC)
758 return NULL;
759
760 edge.key = key;
761 return edges_find(&ted->edges, &edge);
762 }
763
764 struct ls_edge *ls_find_edge_by_source(struct ls_ted *ted,
765 struct ls_attributes *attributes)
766 {
767 struct ls_edge edge = {};
768
769 if (attributes == NULL)
770 return NULL;
771
772 edge.key = get_edge_key(attributes, false);
773 if (edge.key.family == AF_UNSPEC)
774 return NULL;
775
776 return edges_find(&ted->edges, &edge);
777 }
778
779 struct ls_edge *ls_find_edge_by_destination(struct ls_ted *ted,
780 struct ls_attributes *attributes)
781 {
782 struct ls_edge edge = {};
783
784 if (attributes == NULL)
785 return NULL;
786
787 edge.key = get_edge_key(attributes, true);
788 if (edge.key.family == AF_UNSPEC)
789 return NULL;
790
791 return edges_find(&ted->edges, &edge);
792 }
793
794 struct ls_edge *ls_edge_update(struct ls_ted *ted,
795 struct ls_attributes *attributes)
796 {
797 struct ls_edge *old;
798
799 if (attributes == NULL)
800 return NULL;
801
802 /* First, search for an existing Edge */
803 old = ls_find_edge_by_source(ted, attributes);
804 if (old) {
805 /* Check if attributes are similar */
806 if (!ls_attributes_same(old->attributes, attributes)) {
807 ls_attributes_del(old->attributes);
808 old->attributes = attributes;
809 }
810 old->status = UPDATE;
811 return old;
812 }
813
814 /* If not found, add new Edge from the attributes */
815 return ls_edge_add(ted, attributes);
816 }
817
818 int ls_edge_same(struct ls_edge *e1, struct ls_edge *e2)
819 {
820 if ((e1 && !e2) || (!e1 && e2))
821 return 0;
822
823 if (!e1 && !e2)
824 return 1;
825
826 if (edge_cmp(e1, e2) != 0)
827 return 0;
828
829 if (e1->attributes == e2->attributes)
830 return 1;
831
832 return ls_attributes_same(e1->attributes, e2->attributes);
833 }
834
835 void ls_edge_del(struct ls_ted *ted, struct ls_edge *edge)
836 {
837 if (!ted || !edge)
838 return;
839
840 /* Fist disconnect Edge from Vertices */
841 ls_disconnect_edge(edge);
842 /* Then remove it from the Data Base */
843 edges_del(&ted->edges, edge);
844 XFREE(MTYPE_LS_DB, edge);
845 }
846
847 void ls_edge_del_all(struct ls_ted *ted, struct ls_edge *edge)
848 {
849 if (!ted || !edge)
850 return;
851
852 /* Remove associated Link State Attributes */
853 ls_attributes_del(edge->attributes);
854 /* Then Edge itself */
855 ls_edge_del(ted, edge);
856 }
857
858 /**
859 * Link State Subnet Management functions.
860 */
861 struct ls_subnet *ls_subnet_add(struct ls_ted *ted,
862 struct ls_prefix *ls_pref)
863 {
864 struct ls_subnet *new;
865 struct ls_vertex *vertex;
866 struct ls_node *node;
867 const struct in_addr inaddr_any = {.s_addr = INADDR_ANY};
868
869 if (ls_pref == NULL)
870 return NULL;
871
872 new = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_subnet));
873 new->ls_pref = ls_pref;
874 new->key = ls_pref->pref;
875 new->status = NEW;
876 new->type = SUBNET;
877
878 /* Find Vertex */
879 vertex = ls_find_vertex_by_id(ted, ls_pref->adv);
880 if (vertex == NULL) {
881 /* Create a new temporary Node & Vertex if not found */
882 node = ls_node_new(ls_pref->adv, inaddr_any, in6addr_any);
883 vertex = ls_vertex_add(ted, node);
884 }
885 /* And attach the subnet to the corresponding Vertex */
886 new->vertex = vertex;
887 listnode_add_sort_nodup(vertex->prefixes, new);
888
889 subnets_add(&ted->subnets, new);
890
891 return new;
892 }
893
894 struct ls_subnet *ls_subnet_update(struct ls_ted *ted, struct ls_prefix *pref)
895 {
896 struct ls_subnet *old;
897
898 if (pref == NULL)
899 return NULL;
900
901 old = ls_find_subnet(ted, &pref->pref);
902 if (old) {
903 if (!ls_prefix_same(old->ls_pref, pref)) {
904 ls_prefix_del(old->ls_pref);
905 old->ls_pref = pref;
906 }
907 old->status = UPDATE;
908 return old;
909 }
910
911 return ls_subnet_add(ted, pref);
912 }
913
914 int ls_subnet_same(struct ls_subnet *s1, struct ls_subnet *s2)
915 {
916 if ((s1 && !s2) || (!s1 && s2))
917 return 0;
918
919 if (!s1 && !s2)
920 return 1;
921
922 if (!prefix_same(&s1->key, &s2->key))
923 return 0;
924
925 if (s1->ls_pref == s2->ls_pref)
926 return 1;
927
928 return ls_prefix_same(s1->ls_pref, s2->ls_pref);
929 }
930
931 void ls_subnet_del(struct ls_ted *ted, struct ls_subnet *subnet)
932 {
933 if (!ted || !subnet)
934 return;
935
936 /* First, disconnect Subnet from associated Vertex */
937 listnode_delete(subnet->vertex->prefixes, subnet);
938 /* Then delete Subnet */
939 subnets_del(&ted->subnets, subnet);
940 XFREE(MTYPE_LS_DB, subnet);
941 }
942
943 void ls_subnet_del_all(struct ls_ted *ted, struct ls_subnet *subnet)
944 {
945 if (!ted || !subnet)
946 return;
947
948 /* First, remove associated Link State Subnet */
949 ls_prefix_del(subnet->ls_pref);
950 /* Then, delete Subnet itself */
951 ls_subnet_del(ted, subnet);
952 }
953
954 struct ls_subnet *ls_find_subnet(struct ls_ted *ted,
955 const struct prefix *prefix)
956 {
957 struct ls_subnet subnet = {};
958
959 subnet.key = *prefix;
960 return subnets_find(&ted->subnets, &subnet);
961 }
962
963 /**
964 * Link State TED management functions
965 */
966 struct ls_ted *ls_ted_new(const uint32_t key, const char *name,
967 uint32_t as_number)
968 {
969 struct ls_ted *new;
970
971 new = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_ted));
972
973 /* Set basic information for this ted */
974 new->key = key;
975 new->as_number = as_number;
976 strlcpy(new->name, name, MAX_NAME_LENGTH);
977
978 /* Initialize the various RB tree */
979 vertices_init(&new->vertices);
980 edges_init(&new->edges);
981 subnets_init(&new->subnets);
982
983 return new;
984 }
985
986 void ls_ted_del(struct ls_ted *ted)
987 {
988 if (ted == NULL)
989 return;
990
991 /* Check that TED is empty */
992 if (vertices_count(&ted->vertices) || edges_count(&ted->edges)
993 || subnets_count(&ted->subnets))
994 return;
995
996 /* Release RB Tree */
997 vertices_fini(&ted->vertices);
998 edges_fini(&ted->edges);
999 subnets_fini(&ted->subnets);
1000
1001 XFREE(MTYPE_LS_DB, ted);
1002 }
1003
1004 void ls_ted_del_all(struct ls_ted **ted)
1005 {
1006 struct ls_vertex *vertex;
1007 struct ls_edge *edge;
1008 struct ls_subnet *subnet;
1009
1010 if (*ted == NULL)
1011 return;
1012
1013 /* First remove Vertices, Edges and Subnets and associated Link State */
1014 frr_each_safe (vertices, &(*ted)->vertices, vertex)
1015 ls_vertex_del_all(*ted, vertex);
1016 frr_each_safe (edges, &(*ted)->edges, edge)
1017 ls_edge_del_all(*ted, edge);
1018 frr_each_safe (subnets, &(*ted)->subnets, subnet)
1019 ls_subnet_del_all(*ted, subnet);
1020
1021 /* then remove TED itself */
1022 ls_ted_del(*ted);
1023 *ted = NULL;
1024 }
1025
1026 void ls_ted_clean(struct ls_ted *ted)
1027 {
1028 struct ls_vertex *vertex;
1029 struct ls_edge *edge;
1030 struct ls_subnet *subnet;
1031
1032 if (ted == NULL)
1033 return;
1034
1035 /* First, start with Vertices */
1036 frr_each_safe (vertices, &ted->vertices, vertex)
1037 if (vertex->status == ORPHAN)
1038 ls_vertex_del_all(ted, vertex);
1039
1040 /* Then Edges */
1041 frr_each_safe (edges, &ted->edges, edge)
1042 if (edge->status == ORPHAN)
1043 ls_edge_del_all(ted, edge);
1044
1045 /* and Subnets */
1046 frr_each_safe (subnets, &ted->subnets, subnet)
1047 if (subnet->status == ORPHAN)
1048 ls_subnet_del_all(ted, subnet);
1049
1050 }
1051
1052 void ls_connect(struct ls_vertex *vertex, struct ls_edge *edge, bool source)
1053 {
1054 if (vertex == NULL || edge == NULL)
1055 return;
1056
1057 if (source) {
1058 listnode_add_sort_nodup(vertex->outgoing_edges, edge);
1059 edge->source = vertex;
1060 } else {
1061 listnode_add_sort_nodup(vertex->incoming_edges, edge);
1062 edge->destination = vertex;
1063 }
1064 }
1065
1066 void ls_disconnect(struct ls_vertex *vertex, struct ls_edge *edge, bool source)
1067 {
1068
1069 if (vertex == NULL || edge == NULL)
1070 return;
1071
1072 if (source) {
1073 listnode_delete(vertex->outgoing_edges, edge);
1074 edge->source = NULL;
1075 } else {
1076 listnode_delete(vertex->incoming_edges, edge);
1077 edge->destination = NULL;
1078 }
1079 }
1080
1081 void ls_connect_vertices(struct ls_vertex *src, struct ls_vertex *dst,
1082 struct ls_edge *edge)
1083 {
1084 if (edge == NULL)
1085 return;
1086
1087 edge->source = src;
1088 edge->destination = dst;
1089
1090 if (src != NULL)
1091 listnode_add_sort_nodup(src->outgoing_edges, edge);
1092
1093 if (dst != NULL)
1094 listnode_add_sort_nodup(dst->incoming_edges, edge);
1095 }
1096
1097 void ls_disconnect_edge(struct ls_edge *edge)
1098 {
1099 if (edge == NULL)
1100 return;
1101
1102 ls_disconnect(edge->source, edge, true);
1103 ls_disconnect(edge->destination, edge, false);
1104
1105 /* Mark this Edge as ORPHAN for future cleanup */
1106 edge->status = ORPHAN;
1107 }
1108
1109 /**
1110 * Link State Message management functions
1111 */
1112
1113 int ls_register(struct zclient *zclient, bool server)
1114 {
1115 int rc;
1116
1117 if (server)
1118 rc = zclient_register_opaque(zclient, LINK_STATE_SYNC);
1119 else
1120 rc = zclient_register_opaque(zclient, LINK_STATE_UPDATE);
1121
1122 return rc;
1123 }
1124
1125 int ls_unregister(struct zclient *zclient, bool server)
1126 {
1127 int rc;
1128
1129 if (server)
1130 rc = zclient_unregister_opaque(zclient, LINK_STATE_SYNC);
1131 else
1132 rc = zclient_unregister_opaque(zclient, LINK_STATE_UPDATE);
1133
1134 return rc;
1135 }
1136
1137 int ls_request_sync(struct zclient *zclient)
1138 {
1139 struct stream *s;
1140 uint16_t flags = 0;
1141
1142 /* Check buffer size */
1143 if (STREAM_SIZE(zclient->obuf)
1144 < (ZEBRA_HEADER_SIZE + 3 * sizeof(uint32_t)))
1145 return -1;
1146
1147 s = zclient->obuf;
1148 stream_reset(s);
1149
1150 zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
1151
1152 /* Set type and flags */
1153 stream_putl(s, LINK_STATE_SYNC);
1154 stream_putw(s, flags);
1155 /* Send destination client info */
1156 stream_putc(s, zclient->redist_default);
1157 stream_putw(s, zclient->instance);
1158 stream_putl(s, zclient->session_id);
1159
1160 /* Put length into the header at the start of the stream. */
1161 stream_putw_at(s, 0, stream_get_endp(s));
1162
1163 return zclient_send_message(zclient);
1164 }
1165
1166 static struct ls_node *ls_parse_node(struct stream *s)
1167 {
1168 struct ls_node *node;
1169 size_t len;
1170
1171 node = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_node));
1172
1173 STREAM_GET(&node->adv, s, sizeof(struct ls_node_id));
1174 STREAM_GETW(s, node->flags);
1175 if (CHECK_FLAG(node->flags, LS_NODE_NAME)) {
1176 STREAM_GETC(s, len);
1177 STREAM_GET(node->name, s, len);
1178 }
1179 if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID))
1180 node->router_id.s_addr = stream_get_ipv4(s);
1181 if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID6))
1182 STREAM_GET(&node->router_id6, s, IPV6_MAX_BYTELEN);
1183 if (CHECK_FLAG(node->flags, LS_NODE_FLAG))
1184 STREAM_GETC(s, node->node_flag);
1185 if (CHECK_FLAG(node->flags, LS_NODE_TYPE))
1186 STREAM_GETC(s, node->type);
1187 if (CHECK_FLAG(node->flags, LS_NODE_AS_NUMBER))
1188 STREAM_GETL(s, node->as_number);
1189 if (CHECK_FLAG(node->flags, LS_NODE_SR)) {
1190 STREAM_GETL(s, node->srgb.lower_bound);
1191 STREAM_GETL(s, node->srgb.range_size);
1192 STREAM_GETC(s, node->srgb.flag);
1193 STREAM_GET(node->algo, s, 2);
1194 }
1195 if (CHECK_FLAG(node->flags, LS_NODE_SRLB)) {
1196 STREAM_GETL(s, node->srlb.lower_bound);
1197 STREAM_GETL(s, node->srlb.range_size);
1198 }
1199 if (CHECK_FLAG(node->flags, LS_NODE_MSD))
1200 STREAM_GETC(s, node->msd);
1201
1202 return node;
1203
1204 stream_failure:
1205 zlog_err("LS(%s): Could not parse Link State Node. Abort!", __func__);
1206 XFREE(MTYPE_LS_DB, node);
1207 return NULL;
1208 }
1209
1210 static struct ls_attributes *ls_parse_attributes(struct stream *s)
1211 {
1212 struct ls_attributes *attr;
1213 uint8_t nb_ext_adm_grp;
1214 uint32_t bitmap_data;
1215 size_t len;
1216
1217 attr = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_attributes));
1218 admin_group_init(&attr->ext_admin_group);
1219 attr->srlgs = NULL;
1220
1221 STREAM_GET(&attr->adv, s, sizeof(struct ls_node_id));
1222 STREAM_GETL(s, attr->flags);
1223 if (CHECK_FLAG(attr->flags, LS_ATTR_NAME)) {
1224 STREAM_GETC(s, len);
1225 STREAM_GET(attr->name, s, len);
1226 }
1227 if (CHECK_FLAG(attr->flags, LS_ATTR_METRIC))
1228 STREAM_GETL(s, attr->metric);
1229 if (CHECK_FLAG(attr->flags, LS_ATTR_TE_METRIC))
1230 STREAM_GETL(s, attr->standard.te_metric);
1231 if (CHECK_FLAG(attr->flags, LS_ATTR_ADM_GRP))
1232 STREAM_GETL(s, attr->standard.admin_group);
1233 if (CHECK_FLAG(attr->flags, LS_ATTR_EXT_ADM_GRP)) {
1234 /* Extended Administrative Group */
1235 STREAM_GETC(s, nb_ext_adm_grp);
1236 for (size_t i = 0; i < nb_ext_adm_grp; i++) {
1237 STREAM_GETL(s, bitmap_data);
1238 admin_group_bulk_set(&attr->ext_admin_group,
1239 bitmap_data, i);
1240 }
1241 }
1242 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR))
1243 attr->standard.local.s_addr = stream_get_ipv4(s);
1244 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR))
1245 attr->standard.remote.s_addr = stream_get_ipv4(s);
1246 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6))
1247 STREAM_GET(&attr->standard.local6, s, IPV6_MAX_BYTELEN);
1248 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR6))
1249 STREAM_GET(&attr->standard.remote6, s, IPV6_MAX_BYTELEN);
1250 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID))
1251 STREAM_GETL(s, attr->standard.local_id);
1252 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ID))
1253 STREAM_GETL(s, attr->standard.remote_id);
1254 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_BW))
1255 STREAM_GETF(s, attr->standard.max_bw);
1256 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_RSV_BW))
1257 STREAM_GETF(s, attr->standard.max_rsv_bw);
1258 if (CHECK_FLAG(attr->flags, LS_ATTR_UNRSV_BW))
1259 for (len = 0; len < MAX_CLASS_TYPE; len++)
1260 STREAM_GETF(s, attr->standard.unrsv_bw[len]);
1261 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_AS))
1262 STREAM_GETL(s, attr->standard.remote_as);
1263 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR))
1264 attr->standard.remote_addr.s_addr = stream_get_ipv4(s);
1265 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR6))
1266 STREAM_GET(&attr->standard.remote_addr6, s, IPV6_MAX_BYTELEN);
1267 if (CHECK_FLAG(attr->flags, LS_ATTR_DELAY))
1268 STREAM_GETL(s, attr->extended.delay);
1269 if (CHECK_FLAG(attr->flags, LS_ATTR_MIN_MAX_DELAY)) {
1270 STREAM_GETL(s, attr->extended.min_delay);
1271 STREAM_GETL(s, attr->extended.max_delay);
1272 }
1273 if (CHECK_FLAG(attr->flags, LS_ATTR_JITTER))
1274 STREAM_GETL(s, attr->extended.jitter);
1275 if (CHECK_FLAG(attr->flags, LS_ATTR_PACKET_LOSS))
1276 STREAM_GETL(s, attr->extended.pkt_loss);
1277 if (CHECK_FLAG(attr->flags, LS_ATTR_AVA_BW))
1278 STREAM_GETF(s, attr->extended.ava_bw);
1279 if (CHECK_FLAG(attr->flags, LS_ATTR_RSV_BW))
1280 STREAM_GETF(s, attr->extended.rsv_bw);
1281 if (CHECK_FLAG(attr->flags, LS_ATTR_USE_BW))
1282 STREAM_GETF(s, attr->extended.used_bw);
1283 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID)) {
1284 STREAM_GETL(s, attr->adj_sid[ADJ_PRI_IPV4].sid);
1285 STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV4].flags);
1286 STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV4].weight);
1287 attr->adj_sid[ADJ_PRI_IPV4].neighbor.addr.s_addr =
1288 stream_get_ipv4(s);
1289 }
1290 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) {
1291 STREAM_GETL(s, attr->adj_sid[ADJ_BCK_IPV4].sid);
1292 STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV4].flags);
1293 STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV4].weight);
1294 attr->adj_sid[ADJ_BCK_IPV4].neighbor.addr.s_addr =
1295 stream_get_ipv4(s);
1296 }
1297 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) {
1298 STREAM_GETL(s, attr->adj_sid[ADJ_PRI_IPV6].sid);
1299 STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV6].flags);
1300 STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV6].weight);
1301 STREAM_GET(attr->adj_sid[ADJ_PRI_IPV6].neighbor.sysid, s,
1302 ISO_SYS_ID_LEN);
1303 }
1304 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) {
1305 STREAM_GETL(s, attr->adj_sid[ADJ_BCK_IPV6].sid);
1306 STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV6].flags);
1307 STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV6].weight);
1308 STREAM_GET(attr->adj_sid[ADJ_BCK_IPV6].neighbor.sysid, s,
1309 ISO_SYS_ID_LEN);
1310 }
1311 if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
1312 STREAM_GETC(s, len);
1313 attr->srlgs = XCALLOC(MTYPE_LS_DB, len*sizeof(uint32_t));
1314 attr->srlg_len = len;
1315 for (len = 0; len < attr->srlg_len; len++)
1316 STREAM_GETL(s, attr->srlgs[len]);
1317 }
1318
1319 return attr;
1320
1321 stream_failure:
1322 zlog_err("LS(%s): Could not parse Link State Attributes. Abort!",
1323 __func__);
1324 /* Clean memory allocation */
1325 if (attr->srlgs != NULL)
1326 XFREE(MTYPE_LS_DB, attr->srlgs);
1327 XFREE(MTYPE_LS_DB, attr);
1328 return NULL;
1329
1330 }
1331
1332 static struct ls_prefix *ls_parse_prefix(struct stream *s)
1333 {
1334 struct ls_prefix *ls_pref;
1335 size_t len;
1336
1337 ls_pref = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_prefix));
1338
1339 STREAM_GET(&ls_pref->adv, s, sizeof(struct ls_node_id));
1340 STREAM_GETW(s, ls_pref->flags);
1341 STREAM_GETC(s, ls_pref->pref.family);
1342 STREAM_GETW(s, ls_pref->pref.prefixlen);
1343 len = prefix_blen(&ls_pref->pref);
1344 STREAM_GET(&ls_pref->pref.u.prefix, s, len);
1345 if (CHECK_FLAG(ls_pref->flags, LS_PREF_IGP_FLAG))
1346 STREAM_GETC(s, ls_pref->igp_flag);
1347 if (CHECK_FLAG(ls_pref->flags, LS_PREF_ROUTE_TAG))
1348 STREAM_GETL(s, ls_pref->route_tag);
1349 if (CHECK_FLAG(ls_pref->flags, LS_PREF_EXTENDED_TAG))
1350 STREAM_GETQ(s, ls_pref->extended_tag);
1351 if (CHECK_FLAG(ls_pref->flags, LS_PREF_METRIC))
1352 STREAM_GETL(s, ls_pref->metric);
1353 if (CHECK_FLAG(ls_pref->flags, LS_PREF_SR)) {
1354 STREAM_GETL(s, ls_pref->sr.sid);
1355 STREAM_GETC(s, ls_pref->sr.sid_flag);
1356 STREAM_GETC(s, ls_pref->sr.algo);
1357 }
1358
1359 return ls_pref;
1360
1361 stream_failure:
1362 zlog_err("LS(%s): Could not parse Link State Prefix. Abort!", __func__);
1363 XFREE(MTYPE_LS_DB, ls_pref);
1364 return NULL;
1365 }
1366
1367 struct ls_message *ls_parse_msg(struct stream *s)
1368 {
1369 struct ls_message *msg;
1370
1371 msg = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_message));
1372
1373 /* Read LS Message header */
1374 STREAM_GETC(s, msg->event);
1375 STREAM_GETC(s, msg->type);
1376
1377 /* Read Message Payload */
1378 switch (msg->type) {
1379 case LS_MSG_TYPE_NODE:
1380 msg->data.node = ls_parse_node(s);
1381 break;
1382 case LS_MSG_TYPE_ATTRIBUTES:
1383 STREAM_GET(&msg->remote_id, s, sizeof(struct ls_node_id));
1384 msg->data.attr = ls_parse_attributes(s);
1385 break;
1386 case LS_MSG_TYPE_PREFIX:
1387 msg->data.prefix = ls_parse_prefix(s);
1388 break;
1389 default:
1390 zlog_err("Unsupported Payload");
1391 goto stream_failure;
1392 }
1393
1394 if (msg->data.node == NULL || msg->data.attr == NULL
1395 || msg->data.prefix == NULL)
1396 goto stream_failure;
1397
1398 return msg;
1399
1400 stream_failure:
1401 zlog_err("LS(%s): Could not parse LS message. Abort!", __func__);
1402 XFREE(MTYPE_LS_DB, msg);
1403 return NULL;
1404 }
1405
1406 static int ls_format_node(struct stream *s, struct ls_node *node)
1407 {
1408 size_t len;
1409
1410 /* Push Advertise node information first */
1411 stream_put(s, &node->adv, sizeof(struct ls_node_id));
1412
1413 /* Push Flags & Origin then Node information if there are present */
1414 stream_putw(s, node->flags);
1415 if (CHECK_FLAG(node->flags, LS_NODE_NAME)) {
1416 len = strlen(node->name);
1417 stream_putc(s, len + 1);
1418 stream_put(s, node->name, len);
1419 stream_putc(s, '\0');
1420 }
1421 if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID))
1422 stream_put_ipv4(s, node->router_id.s_addr);
1423 if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID6))
1424 stream_put(s, &node->router_id6, IPV6_MAX_BYTELEN);
1425 if (CHECK_FLAG(node->flags, LS_NODE_FLAG))
1426 stream_putc(s, node->node_flag);
1427 if (CHECK_FLAG(node->flags, LS_NODE_TYPE))
1428 stream_putc(s, node->type);
1429 if (CHECK_FLAG(node->flags, LS_NODE_AS_NUMBER))
1430 stream_putl(s, node->as_number);
1431 if (CHECK_FLAG(node->flags, LS_NODE_SR)) {
1432 stream_putl(s, node->srgb.lower_bound);
1433 stream_putl(s, node->srgb.range_size);
1434 stream_putc(s, node->srgb.flag);
1435 stream_put(s, node->algo, 2);
1436 }
1437 if (CHECK_FLAG(node->flags, LS_NODE_SRLB)) {
1438 stream_putl(s, node->srlb.lower_bound);
1439 stream_putl(s, node->srlb.range_size);
1440 }
1441 if (CHECK_FLAG(node->flags, LS_NODE_MSD))
1442 stream_putc(s, node->msd);
1443
1444 return 0;
1445 }
1446
1447 static int ls_format_attributes(struct stream *s, struct ls_attributes *attr)
1448 {
1449 size_t len, nb_ext_adm_grp;
1450
1451 /* Push Advertise node information first */
1452 stream_put(s, &attr->adv, sizeof(struct ls_node_id));
1453
1454 /* Push Flags & Origin then LS attributes if there are present */
1455 stream_putl(s, attr->flags);
1456 if (CHECK_FLAG(attr->flags, LS_ATTR_NAME)) {
1457 len = strlen(attr->name);
1458 stream_putc(s, len + 1);
1459 stream_put(s, attr->name, len);
1460 stream_putc(s, '\0');
1461 }
1462 if (CHECK_FLAG(attr->flags, LS_ATTR_METRIC))
1463 stream_putl(s, attr->metric);
1464 if (CHECK_FLAG(attr->flags, LS_ATTR_TE_METRIC))
1465 stream_putl(s, attr->standard.te_metric);
1466 if (CHECK_FLAG(attr->flags, LS_ATTR_ADM_GRP))
1467 stream_putl(s, attr->standard.admin_group);
1468 if (CHECK_FLAG(attr->flags, LS_ATTR_EXT_ADM_GRP)) {
1469 /* Extended Administrative Group */
1470 nb_ext_adm_grp = admin_group_nb_words(&attr->ext_admin_group);
1471 stream_putc(s, nb_ext_adm_grp);
1472 for (size_t i = 0; i < nb_ext_adm_grp; i++)
1473 stream_putl(s, admin_group_get_offset(
1474 &attr->ext_admin_group, i));
1475 }
1476 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR))
1477 stream_put_ipv4(s, attr->standard.local.s_addr);
1478 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR))
1479 stream_put_ipv4(s, attr->standard.remote.s_addr);
1480 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6))
1481 stream_put(s, &attr->standard.local6, IPV6_MAX_BYTELEN);
1482 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR6))
1483 stream_put(s, &attr->standard.remote6, IPV6_MAX_BYTELEN);
1484 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID))
1485 stream_putl(s, attr->standard.local_id);
1486 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ID))
1487 stream_putl(s, attr->standard.remote_id);
1488 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_BW))
1489 stream_putf(s, attr->standard.max_bw);
1490 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_RSV_BW))
1491 stream_putf(s, attr->standard.max_rsv_bw);
1492 if (CHECK_FLAG(attr->flags, LS_ATTR_UNRSV_BW))
1493 for (len = 0; len < MAX_CLASS_TYPE; len++)
1494 stream_putf(s, attr->standard.unrsv_bw[len]);
1495 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_AS))
1496 stream_putl(s, attr->standard.remote_as);
1497 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR))
1498 stream_put_ipv4(s, attr->standard.remote_addr.s_addr);
1499 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR6))
1500 stream_put(s, &attr->standard.remote_addr6, IPV6_MAX_BYTELEN);
1501 if (CHECK_FLAG(attr->flags, LS_ATTR_DELAY))
1502 stream_putl(s, attr->extended.delay);
1503 if (CHECK_FLAG(attr->flags, LS_ATTR_MIN_MAX_DELAY)) {
1504 stream_putl(s, attr->extended.min_delay);
1505 stream_putl(s, attr->extended.max_delay);
1506 }
1507 if (CHECK_FLAG(attr->flags, LS_ATTR_JITTER))
1508 stream_putl(s, attr->extended.jitter);
1509 if (CHECK_FLAG(attr->flags, LS_ATTR_PACKET_LOSS))
1510 stream_putl(s, attr->extended.pkt_loss);
1511 if (CHECK_FLAG(attr->flags, LS_ATTR_AVA_BW))
1512 stream_putf(s, attr->extended.ava_bw);
1513 if (CHECK_FLAG(attr->flags, LS_ATTR_RSV_BW))
1514 stream_putf(s, attr->extended.rsv_bw);
1515 if (CHECK_FLAG(attr->flags, LS_ATTR_USE_BW))
1516 stream_putf(s, attr->extended.used_bw);
1517 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID)) {
1518 stream_putl(s, attr->adj_sid[ADJ_PRI_IPV4].sid);
1519 stream_putc(s, attr->adj_sid[ADJ_PRI_IPV4].flags);
1520 stream_putc(s, attr->adj_sid[ADJ_PRI_IPV4].weight);
1521 stream_put_ipv4(
1522 s, attr->adj_sid[ADJ_PRI_IPV4].neighbor.addr.s_addr);
1523 }
1524 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) {
1525 stream_putl(s, attr->adj_sid[ADJ_BCK_IPV4].sid);
1526 stream_putc(s, attr->adj_sid[ADJ_BCK_IPV4].flags);
1527 stream_putc(s, attr->adj_sid[ADJ_BCK_IPV4].weight);
1528 stream_put_ipv4(
1529 s, attr->adj_sid[ADJ_BCK_IPV4].neighbor.addr.s_addr);
1530 }
1531 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) {
1532 stream_putl(s, attr->adj_sid[ADJ_PRI_IPV6].sid);
1533 stream_putc(s, attr->adj_sid[ADJ_PRI_IPV6].flags);
1534 stream_putc(s, attr->adj_sid[ADJ_PRI_IPV6].weight);
1535 stream_put(s, attr->adj_sid[ADJ_PRI_IPV6].neighbor.sysid,
1536 ISO_SYS_ID_LEN);
1537 }
1538 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) {
1539 stream_putl(s, attr->adj_sid[ADJ_BCK_IPV6].sid);
1540 stream_putc(s, attr->adj_sid[ADJ_BCK_IPV6].flags);
1541 stream_putc(s, attr->adj_sid[ADJ_BCK_IPV6].weight);
1542 stream_put(s, attr->adj_sid[ADJ_BCK_IPV6].neighbor.sysid,
1543 ISO_SYS_ID_LEN);
1544 }
1545 if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
1546 stream_putc(s, attr->srlg_len);
1547 for (len = 0; len < attr->srlg_len; len++)
1548 stream_putl(s, attr->srlgs[len]);
1549 }
1550
1551 return 0;
1552 }
1553
1554 static int ls_format_prefix(struct stream *s, struct ls_prefix *ls_pref)
1555 {
1556 size_t len;
1557
1558 /* Push Advertise node information first */
1559 stream_put(s, &ls_pref->adv, sizeof(struct ls_node_id));
1560
1561 /* Push Flags, Origin & Prefix then information if there are present */
1562 stream_putw(s, ls_pref->flags);
1563 stream_putc(s, ls_pref->pref.family);
1564 stream_putw(s, ls_pref->pref.prefixlen);
1565 len = prefix_blen(&ls_pref->pref);
1566 stream_put(s, &ls_pref->pref.u.prefix, len);
1567 if (CHECK_FLAG(ls_pref->flags, LS_PREF_IGP_FLAG))
1568 stream_putc(s, ls_pref->igp_flag);
1569 if (CHECK_FLAG(ls_pref->flags, LS_PREF_ROUTE_TAG))
1570 stream_putl(s, ls_pref->route_tag);
1571 if (CHECK_FLAG(ls_pref->flags, LS_PREF_EXTENDED_TAG))
1572 stream_putq(s, ls_pref->extended_tag);
1573 if (CHECK_FLAG(ls_pref->flags, LS_PREF_METRIC))
1574 stream_putl(s, ls_pref->metric);
1575 if (CHECK_FLAG(ls_pref->flags, LS_PREF_SR)) {
1576 stream_putl(s, ls_pref->sr.sid);
1577 stream_putc(s, ls_pref->sr.sid_flag);
1578 stream_putc(s, ls_pref->sr.algo);
1579 }
1580
1581 return 0;
1582 }
1583
1584 static int ls_format_msg(struct stream *s, struct ls_message *msg)
1585 {
1586
1587 /* Prepare Link State header */
1588 stream_putc(s, msg->event);
1589 stream_putc(s, msg->type);
1590
1591 /* Add Message Payload */
1592 switch (msg->type) {
1593 case LS_MSG_TYPE_NODE:
1594 return ls_format_node(s, msg->data.node);
1595 case LS_MSG_TYPE_ATTRIBUTES:
1596 /* Add remote node first */
1597 stream_put(s, &msg->remote_id, sizeof(struct ls_node_id));
1598 return ls_format_attributes(s, msg->data.attr);
1599 case LS_MSG_TYPE_PREFIX:
1600 return ls_format_prefix(s, msg->data.prefix);
1601 default:
1602 zlog_warn("Unsupported Payload");
1603 break;
1604 }
1605
1606 return -1;
1607 }
1608
1609 int ls_send_msg(struct zclient *zclient, struct ls_message *msg,
1610 struct zapi_opaque_reg_info *dst)
1611 {
1612 struct stream *s;
1613 uint16_t flags = 0;
1614
1615 /* Check if we have a valid message */
1616 if (msg->event == LS_MSG_EVENT_UNDEF)
1617 return -1;
1618
1619 /* Check buffer size */
1620 if (STREAM_SIZE(zclient->obuf) <
1621 (ZEBRA_HEADER_SIZE + sizeof(uint32_t) + sizeof(msg)))
1622 return -1;
1623
1624 s = zclient->obuf;
1625 stream_reset(s);
1626
1627 zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
1628
1629 /* Set sub-type, flags and destination for unicast message */
1630 stream_putl(s, LINK_STATE_UPDATE);
1631 if (dst != NULL) {
1632 SET_FLAG(flags, ZAPI_OPAQUE_FLAG_UNICAST);
1633 stream_putw(s, flags);
1634 /* Send destination client info */
1635 stream_putc(s, dst->proto);
1636 stream_putw(s, dst->instance);
1637 stream_putl(s, dst->session_id);
1638 } else {
1639 stream_putw(s, flags);
1640 }
1641
1642 /* Format Link State message */
1643 if (ls_format_msg(s, msg) < 0) {
1644 stream_reset(s);
1645 return -1;
1646 }
1647
1648 /* Put length into the header at the start of the stream. */
1649 stream_putw_at(s, 0, stream_get_endp(s));
1650
1651 return zclient_send_message(zclient);
1652 }
1653 struct ls_message *ls_vertex2msg(struct ls_message *msg,
1654 struct ls_vertex *vertex)
1655 {
1656 /* Allocate space if needed */
1657 if (msg == NULL)
1658 msg = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_message));
1659 else
1660 memset(msg, 0, sizeof(*msg));
1661
1662 msg->type = LS_MSG_TYPE_NODE;
1663 switch (vertex->status) {
1664 case NEW:
1665 msg->event = LS_MSG_EVENT_ADD;
1666 break;
1667 case UPDATE:
1668 msg->event = LS_MSG_EVENT_UPDATE;
1669 break;
1670 case DELETE:
1671 msg->event = LS_MSG_EVENT_DELETE;
1672 break;
1673 case SYNC:
1674 msg->event = LS_MSG_EVENT_SYNC;
1675 break;
1676 case UNSET:
1677 case ORPHAN:
1678 msg->event = LS_MSG_EVENT_UNDEF;
1679 break;
1680 }
1681 msg->data.node = vertex->node;
1682 msg->remote_id.origin = UNKNOWN;
1683
1684 return msg;
1685 }
1686
1687 struct ls_message *ls_edge2msg(struct ls_message *msg, struct ls_edge *edge)
1688 {
1689 /* Allocate space if needed */
1690 if (msg == NULL)
1691 msg = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_message));
1692 else
1693 memset(msg, 0, sizeof(*msg));
1694
1695 msg->type = LS_MSG_TYPE_ATTRIBUTES;
1696 switch (edge->status) {
1697 case NEW:
1698 msg->event = LS_MSG_EVENT_ADD;
1699 break;
1700 case UPDATE:
1701 msg->event = LS_MSG_EVENT_UPDATE;
1702 break;
1703 case DELETE:
1704 msg->event = LS_MSG_EVENT_DELETE;
1705 break;
1706 case SYNC:
1707 msg->event = LS_MSG_EVENT_SYNC;
1708 break;
1709 case UNSET:
1710 case ORPHAN:
1711 msg->event = LS_MSG_EVENT_UNDEF;
1712 break;
1713 }
1714 msg->data.attr = edge->attributes;
1715 if (edge->destination != NULL)
1716 msg->remote_id = edge->destination->node->adv;
1717 else
1718 msg->remote_id.origin = UNKNOWN;
1719
1720 return msg;
1721 }
1722
1723 struct ls_message *ls_subnet2msg(struct ls_message *msg,
1724 struct ls_subnet *subnet)
1725 {
1726 /* Allocate space if needed */
1727 if (msg == NULL)
1728 msg = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_message));
1729 else
1730 memset(msg, 0, sizeof(*msg));
1731
1732 msg->type = LS_MSG_TYPE_PREFIX;
1733 switch (subnet->status) {
1734 case NEW:
1735 msg->event = LS_MSG_EVENT_ADD;
1736 break;
1737 case UPDATE:
1738 msg->event = LS_MSG_EVENT_UPDATE;
1739 break;
1740 case DELETE:
1741 msg->event = LS_MSG_EVENT_DELETE;
1742 break;
1743 case SYNC:
1744 msg->event = LS_MSG_EVENT_SYNC;
1745 break;
1746 case UNSET:
1747 case ORPHAN:
1748 msg->event = LS_MSG_EVENT_UNDEF;
1749 break;
1750 }
1751 msg->data.prefix = subnet->ls_pref;
1752 msg->remote_id.origin = UNKNOWN;
1753
1754 return msg;
1755 }
1756
1757 struct ls_vertex *ls_msg2vertex(struct ls_ted *ted, struct ls_message *msg,
1758 bool delete)
1759 {
1760 struct ls_node *node = (struct ls_node *)msg->data.node;
1761 struct ls_vertex *vertex = NULL;
1762
1763 switch (msg->event) {
1764 case LS_MSG_EVENT_SYNC:
1765 vertex = ls_vertex_add(ted, node);
1766 if (vertex)
1767 vertex->status = SYNC;
1768 break;
1769 case LS_MSG_EVENT_ADD:
1770 vertex = ls_vertex_add(ted, node);
1771 if (vertex)
1772 vertex->status = NEW;
1773 break;
1774 case LS_MSG_EVENT_UPDATE:
1775 vertex = ls_vertex_update(ted, node);
1776 if (vertex)
1777 vertex->status = UPDATE;
1778 break;
1779 case LS_MSG_EVENT_DELETE:
1780 vertex = ls_find_vertex_by_id(ted, node->adv);
1781 if (vertex) {
1782 if (delete)
1783 ls_vertex_del_all(ted, vertex);
1784 else
1785 vertex->status = DELETE;
1786 }
1787 break;
1788 default:
1789 vertex = NULL;
1790 break;
1791 }
1792
1793 return vertex;
1794 }
1795
1796 struct ls_edge *ls_msg2edge(struct ls_ted *ted, struct ls_message *msg,
1797 bool delete)
1798 {
1799 struct ls_attributes *attr = (struct ls_attributes *)msg->data.attr;
1800 struct ls_edge *edge = NULL;
1801
1802 switch (msg->event) {
1803 case LS_MSG_EVENT_SYNC:
1804 edge = ls_edge_add(ted, attr);
1805 if (edge)
1806 edge->status = SYNC;
1807 break;
1808 case LS_MSG_EVENT_ADD:
1809 edge = ls_edge_add(ted, attr);
1810 if (edge)
1811 edge->status = NEW;
1812 break;
1813 case LS_MSG_EVENT_UPDATE:
1814 edge = ls_edge_update(ted, attr);
1815 if (edge)
1816 edge->status = UPDATE;
1817 break;
1818 case LS_MSG_EVENT_DELETE:
1819 edge = ls_find_edge_by_source(ted, attr);
1820 if (edge) {
1821 if (delete) {
1822 ls_edge_del_all(ted, edge);
1823 edge = NULL;
1824 } else
1825 edge->status = DELETE;
1826 }
1827 break;
1828 default:
1829 edge = NULL;
1830 break;
1831 }
1832
1833 return edge;
1834 }
1835
1836 struct ls_subnet *ls_msg2subnet(struct ls_ted *ted, struct ls_message *msg,
1837 bool delete)
1838 {
1839 struct ls_prefix *pref = (struct ls_prefix *)msg->data.prefix;
1840 struct ls_subnet *subnet = NULL;
1841
1842 switch (msg->event) {
1843 case LS_MSG_EVENT_SYNC:
1844 subnet = ls_subnet_add(ted, pref);
1845 if (subnet)
1846 subnet->status = SYNC;
1847 break;
1848 case LS_MSG_EVENT_ADD:
1849 subnet = ls_subnet_add(ted, pref);
1850 if (subnet)
1851 subnet->status = NEW;
1852 break;
1853 case LS_MSG_EVENT_UPDATE:
1854 subnet = ls_subnet_update(ted, pref);
1855 if (subnet)
1856 subnet->status = UPDATE;
1857 break;
1858 case LS_MSG_EVENT_DELETE:
1859 subnet = ls_find_subnet(ted, &pref->pref);
1860 if (subnet) {
1861 if (delete)
1862 ls_subnet_del_all(ted, subnet);
1863 else
1864 subnet->status = DELETE;
1865 }
1866 break;
1867 default:
1868 subnet = NULL;
1869 break;
1870 }
1871
1872 return subnet;
1873 }
1874
1875 struct ls_element *ls_msg2ted(struct ls_ted *ted, struct ls_message *msg,
1876 bool delete)
1877 {
1878 struct ls_element *lse = NULL;
1879
1880 switch (msg->type) {
1881 case LS_MSG_TYPE_NODE:
1882 lse = (struct ls_element *)ls_msg2vertex(ted, msg, delete);
1883 break;
1884 case LS_MSG_TYPE_ATTRIBUTES:
1885 lse = (struct ls_element *)ls_msg2edge(ted, msg, delete);
1886 break;
1887 case LS_MSG_TYPE_PREFIX:
1888 lse = (struct ls_element *)ls_msg2subnet(ted, msg, delete);
1889 break;
1890 default:
1891 lse = NULL;
1892 break;
1893 }
1894
1895 return lse;
1896 }
1897
1898 struct ls_element *ls_stream2ted(struct ls_ted *ted, struct stream *s,
1899 bool delete)
1900 {
1901 struct ls_message *msg;
1902 struct ls_element *lse = NULL;
1903
1904 msg = ls_parse_msg(s);
1905 if (msg) {
1906 lse = ls_msg2ted(ted, msg, delete);
1907 ls_delete_msg(msg);
1908 }
1909
1910 return lse;
1911 }
1912
1913 void ls_delete_msg(struct ls_message *msg)
1914 {
1915 if (msg == NULL)
1916 return;
1917
1918 if (msg->event == LS_MSG_EVENT_DELETE) {
1919 switch (msg->type) {
1920 case LS_MSG_TYPE_NODE:
1921 ls_node_del(msg->data.node);
1922 break;
1923 case LS_MSG_TYPE_ATTRIBUTES:
1924 ls_attributes_del(msg->data.attr);
1925 break;
1926 case LS_MSG_TYPE_PREFIX:
1927 ls_prefix_del(msg->data.prefix);
1928 break;
1929 }
1930 }
1931
1932 XFREE(MTYPE_LS_DB, msg);
1933 }
1934
1935 int ls_sync_ted(struct ls_ted *ted, struct zclient *zclient,
1936 struct zapi_opaque_reg_info *dst)
1937 {
1938 struct ls_vertex *vertex;
1939 struct ls_edge *edge;
1940 struct ls_subnet *subnet;
1941 struct ls_message msg;
1942
1943 /* Loop TED, start sending Node, then Attributes and finally Prefix */
1944 frr_each(vertices, &ted->vertices, vertex) {
1945 ls_vertex2msg(&msg, vertex);
1946 ls_send_msg(zclient, &msg, dst);
1947 }
1948 frr_each(edges, &ted->edges, edge) {
1949 ls_edge2msg(&msg, edge);
1950 ls_send_msg(zclient, &msg, dst);
1951 }
1952 frr_each(subnets, &ted->subnets, subnet) {
1953 ls_subnet2msg(&msg, subnet);
1954 ls_send_msg(zclient, &msg, dst);
1955 }
1956 return 0;
1957 }
1958
1959 /**
1960 * Link State Show functions
1961 */
1962 static const char *const origin2txt[] = {
1963 "Unknown",
1964 "ISIS_L1",
1965 "ISIS_L2",
1966 "OSPFv2",
1967 "Direct",
1968 "Static"
1969 };
1970
1971 static const char *const type2txt[] = {
1972 "Unknown",
1973 "Standard",
1974 "ABR",
1975 "ASBR",
1976 "Remote ASBR",
1977 "Pseudo"
1978 };
1979
1980 static const char *const status2txt[] = {
1981 "Unknown",
1982 "New",
1983 "Update",
1984 "Delete",
1985 "Sync",
1986 "Orphan"
1987 };
1988
1989 static const char *ls_node_id_to_text(struct ls_node_id lnid, char *str,
1990 size_t size)
1991 {
1992 if (lnid.origin == ISIS_L1 || lnid.origin == ISIS_L2)
1993 snprintfrr(str, size, "%pSY", lnid.id.iso.sys_id);
1994 else
1995 snprintfrr(str, size, "%pI4", &lnid.id.ip.addr);
1996
1997 return str;
1998 }
1999
2000 static void ls_show_vertex_vty(struct ls_vertex *vertex, struct vty *vty,
2001 bool verbose)
2002 {
2003 struct listnode *node;
2004 struct ls_node *lsn;
2005 struct ls_edge *edge;
2006 struct ls_attributes *attr;
2007 struct ls_subnet *subnet;
2008 struct sbuf sbuf;
2009 uint32_t upper;
2010
2011 /* Sanity Check */
2012 if (!vertex)
2013 return;
2014
2015 lsn = vertex->node;
2016
2017 sbuf_init(&sbuf, NULL, 0);
2018
2019 sbuf_push(&sbuf, 2, "Vertex (%" PRIu64 "): %s", vertex->key, lsn->name);
2020 sbuf_push(&sbuf, 0, "\tRouter Id: %pI4", &lsn->router_id);
2021 sbuf_push(&sbuf, 0, "\tOrigin: %s", origin2txt[lsn->adv.origin]);
2022 sbuf_push(&sbuf, 0, "\tStatus: %s\n", status2txt[vertex->status]);
2023 if (!verbose) {
2024 sbuf_push(
2025 &sbuf, 0,
2026 "\t%d Outgoing Edges, %d Incoming Edges, %d Subnets\n",
2027 listcount(vertex->outgoing_edges),
2028 listcount(vertex->incoming_edges),
2029 listcount(vertex->prefixes));
2030 goto end;
2031 }
2032
2033 if (CHECK_FLAG(lsn->flags, LS_NODE_TYPE))
2034 sbuf_push(&sbuf, 4, "Type: %s\n", type2txt[lsn->type]);
2035 if (CHECK_FLAG(lsn->flags, LS_NODE_AS_NUMBER))
2036 sbuf_push(&sbuf, 4, "AS number: %u\n", lsn->as_number);
2037 if (CHECK_FLAG(lsn->flags, LS_NODE_SR)) {
2038 sbuf_push(&sbuf, 4, "Segment Routing Capabilities:\n");
2039 upper = lsn->srgb.lower_bound + lsn->srgb.range_size - 1;
2040 sbuf_push(&sbuf, 8, "SRGB: [%d/%d]", lsn->srgb.lower_bound,
2041 upper);
2042 if (CHECK_FLAG(lsn->flags, LS_NODE_SRLB)) {
2043 upper = lsn->srlb.lower_bound + lsn->srlb.range_size
2044 - 1;
2045 sbuf_push(&sbuf, 0, "\tSRLB: [%d/%d]",
2046 lsn->srlb.lower_bound, upper);
2047 }
2048 sbuf_push(&sbuf, 0, "\tAlgo: ");
2049 for (int i = 0; i < 2; i++) {
2050 if (lsn->algo[i] == 255)
2051 continue;
2052
2053 sbuf_push(&sbuf, 0,
2054 lsn->algo[i] == 0 ? "SPF " : "S-SPF ");
2055 }
2056 if (CHECK_FLAG(lsn->flags, LS_NODE_MSD))
2057 sbuf_push(&sbuf, 0, "\tMSD: %d", lsn->msd);
2058 sbuf_push(&sbuf, 0, "\n");
2059 }
2060
2061 sbuf_push(&sbuf, 4, "Outgoing Edges: %d\n",
2062 listcount(vertex->outgoing_edges));
2063 for (ALL_LIST_ELEMENTS_RO(vertex->outgoing_edges, node, edge)) {
2064 if (edge->destination) {
2065 lsn = edge->destination->node;
2066 sbuf_push(&sbuf, 6, "To:\t%s(%pI4)", lsn->name,
2067 &lsn->router_id);
2068 } else {
2069 sbuf_push(&sbuf, 6, "To:\t- (0.0.0.0)");
2070 }
2071 attr = edge->attributes;
2072 if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR)))
2073 sbuf_push(&sbuf, 0, "\tLocal: %pI4\tRemote: %pI4\n",
2074 &attr->standard.local,
2075 &attr->standard.remote);
2076 else if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6)))
2077 sbuf_push(&sbuf, 0, "\tLocal: %pI6\tRemote: %pI6\n",
2078 &attr->standard.local6,
2079 &attr->standard.remote6);
2080 }
2081
2082 sbuf_push(&sbuf, 4, "Incoming Edges: %d\n",
2083 listcount(vertex->incoming_edges));
2084 for (ALL_LIST_ELEMENTS_RO(vertex->incoming_edges, node, edge)) {
2085 if (edge->source) {
2086 lsn = edge->source->node;
2087 sbuf_push(&sbuf, 6, "From:\t%s(%pI4)", lsn->name,
2088 &lsn->router_id);
2089 } else {
2090 sbuf_push(&sbuf, 6, "From:\t- (0.0.0.0)");
2091 }
2092 attr = edge->attributes;
2093 if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR)))
2094 sbuf_push(&sbuf, 0, "\tLocal: %pI4\tRemote: %pI4\n",
2095 &attr->standard.local,
2096 &attr->standard.remote);
2097 else if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6)))
2098 sbuf_push(&sbuf, 0, "\tLocal: %pI6\tRemote: %pI6\n",
2099 &attr->standard.local6,
2100 &attr->standard.remote6);
2101 }
2102
2103 sbuf_push(&sbuf, 4, "Subnets: %d\n", listcount(vertex->prefixes));
2104 for (ALL_LIST_ELEMENTS_RO(vertex->prefixes, node, subnet))
2105 sbuf_push(&sbuf, 6, "Prefix:\t%pFX\n", &subnet->key);
2106
2107 end:
2108 vty_out(vty, "%s\n", sbuf_buf(&sbuf));
2109 sbuf_free(&sbuf);
2110 }
2111
2112 static void ls_show_vertex_json(struct ls_vertex *vertex,
2113 struct json_object *json)
2114 {
2115 struct ls_node *lsn;
2116 json_object *jsr, *jalgo, *jobj;
2117 char buf[INET6_BUFSIZ];
2118
2119 /* Sanity Check */
2120 if (!vertex)
2121 return;
2122
2123 lsn = vertex->node;
2124
2125 json_object_int_add(json, "vertex-id", vertex->key);
2126 json_object_string_add(json, "status", status2txt[vertex->status]);
2127 json_object_string_add(json, "origin", origin2txt[lsn->adv.origin]);
2128 if (CHECK_FLAG(lsn->flags, LS_NODE_NAME))
2129 json_object_string_add(json, "name", lsn->name);
2130 if (CHECK_FLAG(lsn->flags, LS_NODE_ROUTER_ID)) {
2131 snprintfrr(buf, INET6_BUFSIZ, "%pI4", &lsn->router_id);
2132 json_object_string_add(json, "router-id", buf);
2133 }
2134 if (CHECK_FLAG(lsn->flags, LS_NODE_ROUTER_ID6)) {
2135 snprintfrr(buf, INET6_BUFSIZ, "%pI6", &lsn->router_id6);
2136 json_object_string_add(json, "router-id-v6", buf);
2137 }
2138 if (CHECK_FLAG(lsn->flags, LS_NODE_TYPE))
2139 json_object_string_add(json, "vertex-type",
2140 type2txt[lsn->type]);
2141 if (CHECK_FLAG(lsn->flags, LS_NODE_AS_NUMBER))
2142 json_object_int_add(json, "asn", lsn->as_number);
2143 if (CHECK_FLAG(lsn->flags, LS_NODE_SR)) {
2144 jsr = json_object_new_object();
2145 json_object_object_add(json, "segment-routing", jsr);
2146 json_object_int_add(jsr, "srgb-size", lsn->srgb.range_size);
2147 json_object_int_add(jsr, "srgb-lower", lsn->srgb.lower_bound);
2148 jalgo = json_object_new_array();
2149 json_object_object_add(jsr, "algorithms", jalgo);
2150 for (int i = 0; i < 2; i++) {
2151 if (lsn->algo[i] == 255)
2152 continue;
2153 jobj = json_object_new_object();
2154
2155 snprintfrr(buf, 2, "%u", i);
2156 json_object_string_add(
2157 jobj, buf, lsn->algo[i] == 0 ? "SPF" : "S-SPF");
2158 json_object_array_add(jalgo, jobj);
2159 }
2160 if (CHECK_FLAG(lsn->flags, LS_NODE_SRLB)) {
2161 json_object_int_add(jsr, "srlb-size",
2162 lsn->srlb.range_size);
2163 json_object_int_add(jsr, "srlb-lower",
2164 lsn->srlb.lower_bound);
2165 }
2166 if (CHECK_FLAG(lsn->flags, LS_NODE_MSD))
2167 json_object_int_add(jsr, "msd", lsn->msd);
2168 }
2169 }
2170
2171 void ls_show_vertex(struct ls_vertex *vertex, struct vty *vty,
2172 struct json_object *json, bool verbose)
2173 {
2174 if (json)
2175 ls_show_vertex_json(vertex, json);
2176 else if (vty)
2177 ls_show_vertex_vty(vertex, vty, verbose);
2178 }
2179
2180 void ls_show_vertices(struct ls_ted *ted, struct vty *vty,
2181 struct json_object *json, bool verbose)
2182 {
2183 struct ls_vertex *vertex;
2184 json_object *jnodes, *jnode;
2185
2186 if (json) {
2187 jnodes = json_object_new_array();
2188 json_object_object_add(json, "vertices", jnodes);
2189 frr_each (vertices, &ted->vertices, vertex) {
2190 jnode = json_object_new_object();
2191 ls_show_vertex(vertex, NULL, jnode, verbose);
2192 json_object_array_add(jnodes, jnode);
2193 }
2194 } else if (vty) {
2195 frr_each (vertices, &ted->vertices, vertex)
2196 ls_show_vertex(vertex, vty, NULL, verbose);
2197 }
2198 }
2199
2200 static const char *edge_key_to_text(struct ls_edge_key key)
2201 {
2202 #define FORMAT_BUF_COUNT 4
2203 static char buf_ring[FORMAT_BUF_COUNT][INET6_BUFSIZ];
2204 static size_t cur_buf = 0;
2205 char *rv;
2206
2207 rv = buf_ring[cur_buf];
2208 cur_buf = (cur_buf + 1) % FORMAT_BUF_COUNT;
2209
2210 switch (key.family) {
2211 case AF_INET:
2212 snprintfrr(rv, INET6_BUFSIZ, "%pI4", &key.k.addr);
2213 break;
2214 case AF_INET6:
2215 snprintfrr(rv, INET6_BUFSIZ, "%pI6", &key.k.addr6);
2216 break;
2217 case AF_LOCAL:
2218 snprintfrr(rv, INET6_BUFSIZ, "%" PRIu64, key.k.link_id);
2219 break;
2220 default:
2221 snprintfrr(rv, INET6_BUFSIZ, "(Unknown)");
2222 break;
2223 }
2224
2225 return rv;
2226 }
2227
2228 static void ls_show_edge_vty(struct ls_edge *edge, struct vty *vty,
2229 bool verbose)
2230 {
2231 char admin_group_buf[ADMIN_GROUP_PRINT_MAX_SIZE];
2232 struct ls_attributes *attr;
2233 struct sbuf sbuf;
2234 char buf[INET6_BUFSIZ];
2235 int indent;
2236
2237 attr = edge->attributes;
2238 sbuf_init(&sbuf, NULL, 0);
2239
2240 sbuf_push(&sbuf, 2, "Edge (%s): ", edge_key_to_text(edge->key));
2241 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR))
2242 sbuf_push(&sbuf, 0, "%pI4", &attr->standard.local);
2243 else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6))
2244 sbuf_push(&sbuf, 0, "%pI6", &attr->standard.local6);
2245 else
2246 sbuf_push(&sbuf, 0, "%u/%u", attr->standard.local_id,
2247 attr->standard.remote_id);
2248 ls_node_id_to_text(attr->adv, buf, INET6_BUFSIZ);
2249 sbuf_push(&sbuf, 0, "\tAdv. Vertex: %s", buf);
2250 sbuf_push(&sbuf, 0, "\tMetric: %u", attr->metric);
2251 sbuf_push(&sbuf, 0, "\tStatus: %s\n", status2txt[edge->status]);
2252
2253 if (!verbose)
2254 goto end;
2255
2256 sbuf_push(&sbuf, 4, "Origin: %s\n", origin2txt[attr->adv.origin]);
2257 if (CHECK_FLAG(attr->flags, LS_ATTR_NAME))
2258 sbuf_push(&sbuf, 4, "Name: %s\n", attr->name);
2259 if (CHECK_FLAG(attr->flags, LS_ATTR_TE_METRIC))
2260 sbuf_push(&sbuf, 4, "TE Metric: %u\n",
2261 attr->standard.te_metric);
2262 if (CHECK_FLAG(attr->flags, LS_ATTR_ADM_GRP))
2263 sbuf_push(&sbuf, 4, "Admin Group: 0x%x\n",
2264 attr->standard.admin_group);
2265 if (CHECK_FLAG(attr->flags, LS_ATTR_EXT_ADM_GRP) &&
2266 admin_group_nb_words(&attr->ext_admin_group) != 0) {
2267 indent = 4;
2268 sbuf_push(&sbuf, indent, "Ext Admin Group: %s\n",
2269 admin_group_string(
2270 admin_group_buf, ADMIN_GROUP_PRINT_MAX_SIZE,
2271 indent + strlen("Ext Admin Group: "),
2272 &attr->ext_admin_group));
2273 if (admin_group_buf[0] != '\0' &&
2274 (sbuf.pos + strlen(admin_group_buf) +
2275 SBUF_DEFAULT_SIZE / 2) < sbuf.size)
2276 sbuf_push(&sbuf, indent + 2, "Bit positions: %s\n",
2277 admin_group_buf);
2278 }
2279 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR))
2280 sbuf_push(&sbuf, 4, "Local IPv4 address: %pI4\n",
2281 &attr->standard.local);
2282 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR))
2283 sbuf_push(&sbuf, 4, "Remote IPv4 address: %pI4\n",
2284 &attr->standard.remote);
2285 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6))
2286 sbuf_push(&sbuf, 4, "Local IPv6 address: %pI6\n",
2287 &attr->standard.local6);
2288 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR6))
2289 sbuf_push(&sbuf, 4, "Remote IPv6 address: %pI6\n",
2290 &attr->standard.remote6);
2291 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID))
2292 sbuf_push(&sbuf, 4, "Local Identifier: %u\n",
2293 attr->standard.local_id);
2294 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ID))
2295 sbuf_push(&sbuf, 4, "Remote Identifier: %u\n",
2296 attr->standard.remote_id);
2297 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_BW))
2298 sbuf_push(&sbuf, 4, "Maximum Bandwidth: %g (Bytes/s)\n",
2299 attr->standard.max_bw);
2300 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_RSV_BW))
2301 sbuf_push(&sbuf, 4,
2302 "Maximum Reservable Bandwidth: %g (Bytes/s)\n",
2303 attr->standard.max_rsv_bw);
2304 if (CHECK_FLAG(attr->flags, LS_ATTR_UNRSV_BW)) {
2305 sbuf_push(&sbuf, 4, "Unreserved Bandwidth per Class Type\n");
2306 for (int i = 0; i < MAX_CLASS_TYPE; i += 2)
2307 sbuf_push(&sbuf, 8,
2308 "[%d]: %g (Bytes/sec)\t[%d]: %g (Bytes/s)\n",
2309 i, attr->standard.unrsv_bw[i], i + 1,
2310 attr->standard.unrsv_bw[i + 1]);
2311 }
2312 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_AS))
2313 sbuf_push(&sbuf, 4, "Remote AS: %u\n",
2314 attr->standard.remote_as);
2315 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR))
2316 sbuf_push(&sbuf, 4, "Remote ASBR IPv4 address: %pI4\n",
2317 &attr->standard.remote_addr);
2318 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR6))
2319 sbuf_push(&sbuf, 4, "Remote ASBR IPv6 address: %pI6\n",
2320 &attr->standard.remote_addr6);
2321 if (CHECK_FLAG(attr->flags, LS_ATTR_DELAY))
2322 sbuf_push(&sbuf, 4, "Average Link Delay: %d (micro-sec)\n",
2323 attr->extended.delay);
2324 if (CHECK_FLAG(attr->flags, LS_ATTR_MIN_MAX_DELAY))
2325 sbuf_push(&sbuf, 4, "Min/Max Link Delay: %d/%d (micro-sec)\n",
2326 attr->extended.min_delay, attr->extended.max_delay);
2327 if (CHECK_FLAG(attr->flags, LS_ATTR_JITTER))
2328 sbuf_push(&sbuf, 4, "Delay Variation: %d (micro-sec)\n",
2329 attr->extended.jitter);
2330 if (CHECK_FLAG(attr->flags, LS_ATTR_PACKET_LOSS))
2331 sbuf_push(&sbuf, 4, "Link Loss: %g (%%)\n",
2332 (float)(attr->extended.pkt_loss * LOSS_PRECISION));
2333 if (CHECK_FLAG(attr->flags, LS_ATTR_AVA_BW))
2334 sbuf_push(&sbuf, 4, "Available Bandwidth: %g (Bytes/s)\n",
2335 attr->extended.ava_bw);
2336 if (CHECK_FLAG(attr->flags, LS_ATTR_RSV_BW))
2337 sbuf_push(&sbuf, 4, "Residual Bandwidth: %g (Bytes/s)\n",
2338 attr->extended.rsv_bw);
2339 if (CHECK_FLAG(attr->flags, LS_ATTR_USE_BW))
2340 sbuf_push(&sbuf, 4, "Utilized Bandwidth: %g (Bytes/s)\n",
2341 attr->extended.used_bw);
2342 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID)) {
2343 sbuf_push(&sbuf, 4, "IPv4 Adjacency-SID: %u",
2344 attr->adj_sid[ADJ_PRI_IPV4].sid);
2345 sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n",
2346 attr->adj_sid[ADJ_PRI_IPV4].flags,
2347 attr->adj_sid[ADJ_PRI_IPV4].weight);
2348 }
2349 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) {
2350 sbuf_push(&sbuf, 4, "IPv4 Bck. Adjacency-SID: %u",
2351 attr->adj_sid[ADJ_BCK_IPV4].sid);
2352 sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n",
2353 attr->adj_sid[ADJ_BCK_IPV4].flags,
2354 attr->adj_sid[ADJ_BCK_IPV4].weight);
2355 }
2356 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) {
2357 sbuf_push(&sbuf, 4, "IPv6 Adjacency-SID: %u",
2358 attr->adj_sid[ADJ_PRI_IPV6].sid);
2359 sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n",
2360 attr->adj_sid[ADJ_PRI_IPV6].flags,
2361 attr->adj_sid[ADJ_PRI_IPV6].weight);
2362 }
2363 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) {
2364 sbuf_push(&sbuf, 4, "IPv6 Bck. Adjacency-SID: %u",
2365 attr->adj_sid[ADJ_BCK_IPV6].sid);
2366 sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n",
2367 attr->adj_sid[ADJ_BCK_IPV6].flags,
2368 attr->adj_sid[ADJ_BCK_IPV6].weight);
2369 }
2370 if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
2371 sbuf_push(&sbuf, 4, "SRLGs: %d", attr->srlg_len);
2372 for (int i = 1; i < attr->srlg_len; i++) {
2373 if (i % 8)
2374 sbuf_push(&sbuf, 8, "\n%u", attr->srlgs[i]);
2375 else
2376 sbuf_push(&sbuf, 8, ", %u", attr->srlgs[i]);
2377 }
2378 sbuf_push(&sbuf, 0, "\n");
2379 }
2380
2381 end:
2382 vty_out(vty, "%s\n", sbuf_buf(&sbuf));
2383 sbuf_free(&sbuf);
2384 }
2385
2386 static void ls_show_edge_json(struct ls_edge *edge, struct json_object *json)
2387 {
2388 struct ls_attributes *attr;
2389 struct json_object *jte, *jbw, *jobj, *jsr = NULL, *jsrlg, *js_ext_ag,
2390 *js_ext_ag_arr_word,
2391 *js_ext_ag_arr_bit;
2392 char buf[INET6_BUFSIZ];
2393 char buf_ag[strlen("0xffffffff") + 1];
2394 uint32_t bitmap;
2395 size_t i;
2396
2397 attr = edge->attributes;
2398
2399 json_object_string_add(json, "edge-id", edge_key_to_text(edge->key));
2400 json_object_string_add(json, "status", status2txt[edge->status]);
2401 json_object_string_add(json, "origin", origin2txt[attr->adv.origin]);
2402 ls_node_id_to_text(attr->adv, buf, INET6_BUFSIZ);
2403 json_object_string_add(json, "advertised-router", buf);
2404 if (edge->source)
2405 json_object_int_add(json, "local-vertex-id", edge->source->key);
2406 if (edge->destination)
2407 json_object_int_add(json, "remote-vertex-id",
2408 edge->destination->key);
2409 json_object_int_add(json, "metric", attr->metric);
2410 if (CHECK_FLAG(attr->flags, LS_ATTR_NAME))
2411 json_object_string_add(json, "name", attr->name);
2412 jte = json_object_new_object();
2413 json_object_object_add(json, "edge-attributes", jte);
2414 if (CHECK_FLAG(attr->flags, LS_ATTR_TE_METRIC))
2415 json_object_int_add(jte, "te-metric", attr->standard.te_metric);
2416 if (CHECK_FLAG(attr->flags, LS_ATTR_ADM_GRP))
2417 json_object_int_add(jte, "admin-group",
2418 attr->standard.admin_group);
2419 if (CHECK_FLAG(attr->flags, LS_ATTR_EXT_ADM_GRP)) {
2420 js_ext_ag = json_object_new_object();
2421 json_object_object_add(jte, "extAdminGroup", js_ext_ag);
2422 js_ext_ag_arr_word = json_object_new_array();
2423 json_object_object_add(js_ext_ag, "words", js_ext_ag_arr_word);
2424 js_ext_ag_arr_bit = json_object_new_array();
2425 json_object_object_add(js_ext_ag, "bitPositions",
2426 js_ext_ag_arr_bit);
2427 for (i = 0; i < admin_group_nb_words(&attr->ext_admin_group);
2428 i++) {
2429 bitmap = admin_group_get_offset(&attr->ext_admin_group,
2430 i);
2431 snprintf(buf_ag, sizeof(buf_ag), "0x%08x", bitmap);
2432 json_object_array_add(js_ext_ag_arr_word,
2433 json_object_new_string(buf_ag));
2434 }
2435 for (i = 0;
2436 i < (admin_group_size(&attr->ext_admin_group) * WORD_SIZE);
2437 i++) {
2438 if (admin_group_get(&attr->ext_admin_group, i))
2439 json_object_array_add(js_ext_ag_arr_bit,
2440 json_object_new_int(i));
2441 }
2442 }
2443 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR)) {
2444 snprintfrr(buf, INET6_BUFSIZ, "%pI4", &attr->standard.local);
2445 json_object_string_add(jte, "local-address", buf);
2446 }
2447 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR)) {
2448 snprintfrr(buf, INET6_BUFSIZ, "%pI4", &attr->standard.remote);
2449 json_object_string_add(jte, "remote-address", buf);
2450 }
2451 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6)) {
2452 snprintfrr(buf, INET6_BUFSIZ, "%pI6", &attr->standard.local6);
2453 json_object_string_add(jte, "local-address-v6", buf);
2454 }
2455 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR6)) {
2456 snprintfrr(buf, INET6_BUFSIZ, "%pI6", &attr->standard.remote6);
2457 json_object_string_add(jte, "remote-address-v6", buf);
2458 }
2459 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID))
2460 json_object_int_add(jte, "local-identifier",
2461 attr->standard.local_id);
2462 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ID))
2463 json_object_int_add(jte, "remote-identifier",
2464 attr->standard.remote_id);
2465 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_BW))
2466 json_object_double_add(jte, "max-link-bandwidth",
2467 attr->standard.max_bw);
2468 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_RSV_BW))
2469 json_object_double_add(jte, "max-resv-link-bandwidth",
2470 attr->standard.max_rsv_bw);
2471 if (CHECK_FLAG(attr->flags, LS_ATTR_UNRSV_BW)) {
2472 jbw = json_object_new_array();
2473 json_object_object_add(jte, "unreserved-bandwidth", jbw);
2474 for (int i = 0; i < MAX_CLASS_TYPE; i++) {
2475 jobj = json_object_new_object();
2476 snprintfrr(buf, 13, "class-type-%u", i);
2477 json_object_double_add(jobj, buf,
2478 attr->standard.unrsv_bw[i]);
2479 json_object_array_add(jbw, jobj);
2480 }
2481 }
2482 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_AS))
2483 json_object_int_add(jte, "remote-asn",
2484 attr->standard.remote_as);
2485 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR)) {
2486 snprintfrr(buf, INET6_BUFSIZ, "%pI4",
2487 &attr->standard.remote_addr);
2488 json_object_string_add(jte, "remote-as-address", buf);
2489 }
2490 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR6)) {
2491 snprintfrr(buf, INET6_BUFSIZ, "%pI6",
2492 &attr->standard.remote_addr6);
2493 json_object_string_add(jte, "remote-as-address-v6", buf);
2494 }
2495 if (CHECK_FLAG(attr->flags, LS_ATTR_DELAY))
2496 json_object_int_add(jte, "delay", attr->extended.delay);
2497 if (CHECK_FLAG(attr->flags, LS_ATTR_MIN_MAX_DELAY)) {
2498 json_object_int_add(jte, "min-delay", attr->extended.min_delay);
2499 json_object_int_add(jte, "max-delay", attr->extended.max_delay);
2500 }
2501 if (CHECK_FLAG(attr->flags, LS_ATTR_JITTER))
2502 json_object_int_add(jte, "jitter", attr->extended.jitter);
2503 if (CHECK_FLAG(attr->flags, LS_ATTR_PACKET_LOSS))
2504 json_object_double_add(
2505 jte, "loss", attr->extended.pkt_loss * LOSS_PRECISION);
2506 if (CHECK_FLAG(attr->flags, LS_ATTR_AVA_BW))
2507 json_object_double_add(jte, "available-bandwidth",
2508 attr->extended.ava_bw);
2509 if (CHECK_FLAG(attr->flags, LS_ATTR_RSV_BW))
2510 json_object_double_add(jte, "residual-bandwidth",
2511 attr->extended.rsv_bw);
2512 if (CHECK_FLAG(attr->flags, LS_ATTR_USE_BW))
2513 json_object_double_add(jte, "utilized-bandwidth",
2514 attr->extended.used_bw);
2515 if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
2516 jsrlg = json_object_new_array();
2517 json_object_object_add(jte, "srlgs", jsrlg);
2518 for (int i = 1; i < attr->srlg_len; i++) {
2519 jobj = json_object_new_object();
2520 json_object_int_add(jobj, "srlg", attr->srlgs[i]);
2521 json_object_array_add(jsrlg, jobj);
2522 }
2523 }
2524 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID)) {
2525 jsr = json_object_new_array();
2526 json_object_object_add(json, "segment-routing", jsr);
2527 jobj = json_object_new_object();
2528 json_object_int_add(jobj, "adj-sid",
2529 attr->adj_sid[ADJ_PRI_IPV4].sid);
2530 snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_PRI_IPV4].flags);
2531 json_object_string_add(jobj, "flags", buf);
2532 json_object_int_add(jobj, "weight",
2533 attr->adj_sid[ADJ_PRI_IPV4].weight);
2534 json_object_array_add(jsr, jobj);
2535 }
2536 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) {
2537 if (!jsr) {
2538 jsr = json_object_new_array();
2539 json_object_object_add(json, "segment-routing", jsr);
2540 }
2541 jobj = json_object_new_object();
2542 json_object_int_add(jobj, "adj-sid",
2543 attr->adj_sid[ADJ_BCK_IPV4].sid);
2544 snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_BCK_IPV4].flags);
2545 json_object_string_add(jobj, "flags", buf);
2546 json_object_int_add(jobj, "weight",
2547 attr->adj_sid[ADJ_BCK_IPV4].weight);
2548 json_object_array_add(jsr, jobj);
2549 }
2550 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) {
2551 jsr = json_object_new_array();
2552 json_object_object_add(json, "segment-routing", jsr);
2553 jobj = json_object_new_object();
2554 json_object_int_add(jobj, "adj-sid",
2555 attr->adj_sid[ADJ_PRI_IPV6].sid);
2556 snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_PRI_IPV6].flags);
2557 json_object_string_add(jobj, "flags", buf);
2558 json_object_int_add(jobj, "weight",
2559 attr->adj_sid[ADJ_PRI_IPV6].weight);
2560 json_object_array_add(jsr, jobj);
2561 }
2562 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) {
2563 if (!jsr) {
2564 jsr = json_object_new_array();
2565 json_object_object_add(json, "segment-routing", jsr);
2566 }
2567 jobj = json_object_new_object();
2568 json_object_int_add(jobj, "adj-sid",
2569 attr->adj_sid[ADJ_BCK_IPV6].sid);
2570 snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_BCK_IPV6].flags);
2571 json_object_string_add(jobj, "flags", buf);
2572 json_object_int_add(jobj, "weight",
2573 attr->adj_sid[ADJ_BCK_IPV6].weight);
2574 json_object_array_add(jsr, jobj);
2575 }
2576 }
2577
2578 void ls_show_edge(struct ls_edge *edge, struct vty *vty,
2579 struct json_object *json, bool verbose)
2580 {
2581 /* Sanity Check */
2582 if (!edge)
2583 return;
2584
2585 if (json)
2586 ls_show_edge_json(edge, json);
2587 else if (vty)
2588 ls_show_edge_vty(edge, vty, verbose);
2589 }
2590
2591 void ls_show_edges(struct ls_ted *ted, struct vty *vty,
2592 struct json_object *json, bool verbose)
2593 {
2594 struct ls_edge *edge;
2595 json_object *jedges, *jedge;
2596
2597 if (json) {
2598 jedges = json_object_new_array();
2599 json_object_object_add(json, "edges", jedges);
2600 frr_each (edges, &ted->edges, edge) {
2601 jedge = json_object_new_object();
2602 ls_show_edge(edge, NULL, jedge, verbose);
2603 json_object_array_add(jedges, jedge);
2604 }
2605 } else if (vty) {
2606 frr_each (edges, &ted->edges, edge)
2607 ls_show_edge(edge, vty, NULL, verbose);
2608 }
2609 }
2610
2611 static void ls_show_subnet_vty(struct ls_subnet *subnet, struct vty *vty,
2612 bool verbose)
2613 {
2614 struct ls_prefix *pref;
2615 struct sbuf sbuf;
2616 char buf[INET6_BUFSIZ];
2617
2618 pref = subnet->ls_pref;
2619 sbuf_init(&sbuf, NULL, 0);
2620
2621 sbuf_push(&sbuf, 2, "Subnet: %pFX", &subnet->key);
2622 ls_node_id_to_text(pref->adv, buf, INET6_BUFSIZ);
2623 sbuf_push(&sbuf, 0, "\tAdv. Vertex: %s", buf);
2624 sbuf_push(&sbuf, 0, "\tMetric: %d", pref->metric);
2625 sbuf_push(&sbuf, 0, "\tStatus: %s\n", status2txt[subnet->status]);
2626
2627 if (!verbose)
2628 goto end;
2629
2630 sbuf_push(&sbuf, 4, "Origin: %s\n", origin2txt[pref->adv.origin]);
2631 if (CHECK_FLAG(pref->flags, LS_PREF_IGP_FLAG))
2632 sbuf_push(&sbuf, 4, "Flags: %d\n", pref->igp_flag);
2633
2634 if (CHECK_FLAG(pref->flags, LS_PREF_ROUTE_TAG))
2635 sbuf_push(&sbuf, 4, "Tag: %d\n", pref->route_tag);
2636
2637 if (CHECK_FLAG(pref->flags, LS_PREF_EXTENDED_TAG))
2638 sbuf_push(&sbuf, 4, "Extended Tag: %" PRIu64 "\n",
2639 pref->extended_tag);
2640
2641 if (CHECK_FLAG(pref->flags, LS_PREF_SR))
2642 sbuf_push(&sbuf, 4, "SID: %d\tAlgorithm: %d\tFlags: 0x%x\n",
2643 pref->sr.sid, pref->sr.algo, pref->sr.sid_flag);
2644
2645 end:
2646 vty_out(vty, "%s\n", sbuf_buf(&sbuf));
2647 sbuf_free(&sbuf);
2648 }
2649
2650 static void ls_show_subnet_json(struct ls_subnet *subnet,
2651 struct json_object *json)
2652 {
2653 struct ls_prefix *pref;
2654 json_object *jsr;
2655 char buf[INET6_BUFSIZ];
2656
2657 pref = subnet->ls_pref;
2658
2659 snprintfrr(buf, INET6_BUFSIZ, "%pFX", &subnet->key);
2660 json_object_string_add(json, "subnet-id", buf);
2661 json_object_string_add(json, "status", status2txt[subnet->status]);
2662 json_object_string_add(json, "origin", origin2txt[pref->adv.origin]);
2663 ls_node_id_to_text(pref->adv, buf, INET6_BUFSIZ);
2664 json_object_string_add(json, "advertised-router", buf);
2665 if (subnet->vertex)
2666 json_object_int_add(json, "vertex-id", subnet->vertex->key);
2667 json_object_int_add(json, "metric", pref->metric);
2668 if (CHECK_FLAG(pref->flags, LS_PREF_IGP_FLAG)) {
2669 snprintfrr(buf, INET6_BUFSIZ, "0x%x", pref->igp_flag);
2670 json_object_string_add(json, "flags", buf);
2671 }
2672 if (CHECK_FLAG(pref->flags, LS_PREF_ROUTE_TAG))
2673 json_object_int_add(json, "tag", pref->route_tag);
2674 if (CHECK_FLAG(pref->flags, LS_PREF_EXTENDED_TAG))
2675 json_object_int_add(json, "extended-tag", pref->extended_tag);
2676 if (CHECK_FLAG(pref->flags, LS_PREF_SR)) {
2677 jsr = json_object_new_object();
2678 json_object_object_add(json, "segment-routing", jsr);
2679 json_object_int_add(jsr, "pref-sid", pref->sr.sid);
2680 json_object_int_add(jsr, "algo", pref->sr.algo);
2681 snprintfrr(buf, INET6_BUFSIZ, "0x%x", pref->sr.sid_flag);
2682 json_object_string_add(jsr, "flags", buf);
2683 }
2684 }
2685
2686 void ls_show_subnet(struct ls_subnet *subnet, struct vty *vty,
2687 struct json_object *json, bool verbose)
2688 {
2689 /* Sanity Check */
2690 if (!subnet)
2691 return;
2692
2693 if (json)
2694 ls_show_subnet_json(subnet, json);
2695 else if (vty)
2696 ls_show_subnet_vty(subnet, vty, verbose);
2697 }
2698
2699 void ls_show_subnets(struct ls_ted *ted, struct vty *vty,
2700 struct json_object *json, bool verbose)
2701 {
2702 struct ls_subnet *subnet;
2703 json_object *jsubs, *jsub;
2704
2705 if (json) {
2706 jsubs = json_object_new_array();
2707 json_object_object_add(json, "subnets", jsubs);
2708 frr_each (subnets, &ted->subnets, subnet) {
2709 jsub = json_object_new_object();
2710 ls_show_subnet(subnet, NULL, jsub, verbose);
2711 json_object_array_add(jsubs, jsub);
2712 }
2713 } else if (vty) {
2714 frr_each (subnets, &ted->subnets, subnet)
2715 ls_show_subnet(subnet, vty, NULL, verbose);
2716 }
2717 }
2718
2719 void ls_show_ted(struct ls_ted *ted, struct vty *vty, struct json_object *json,
2720 bool verbose)
2721 {
2722 json_object *jted;
2723
2724 if (json) {
2725 jted = json_object_new_object();
2726 json_object_object_add(json, "ted", jted);
2727 json_object_string_add(jted, "name", ted->name);
2728 json_object_int_add(jted, "key", ted->key);
2729 json_object_int_add(jted, "verticesCount",
2730 vertices_count(&ted->vertices));
2731 json_object_int_add(jted, "edgesCount",
2732 edges_count(&ted->edges));
2733 json_object_int_add(jted, "subnetsCount",
2734 subnets_count(&ted->subnets));
2735 ls_show_vertices(ted, NULL, jted, verbose);
2736 ls_show_edges(ted, NULL, jted, verbose);
2737 ls_show_subnets(ted, NULL, jted, verbose);
2738 return;
2739 }
2740
2741 if (vty) {
2742 vty_out(vty,
2743 "\n\tTraffic Engineering Database: %s (key: %d)\n\n",
2744 ted->name, ted->key);
2745 ls_show_vertices(ted, vty, NULL, verbose);
2746 ls_show_edges(ted, vty, NULL, verbose);
2747 ls_show_subnets(ted, vty, NULL, verbose);
2748 vty_out(vty,
2749 "\n\tTotal: %zu Vertices, %zu Edges, %zu Subnets\n\n",
2750 vertices_count(&ted->vertices),
2751 edges_count(&ted->edges), subnets_count(&ted->subnets));
2752 }
2753 }
2754
2755 void ls_dump_ted(struct ls_ted *ted)
2756 {
2757 struct ls_vertex *vertex;
2758 struct ls_edge *edge;
2759 struct ls_subnet *subnet;
2760 const struct in_addr inaddr_any = {.s_addr = INADDR_ANY};
2761
2762 zlog_debug("(%s) Ted init", __func__);
2763
2764 /* Loop TED, start printing Node, then Attributes and finally Prefix */
2765 frr_each (vertices, &ted->vertices, vertex) {
2766 zlog_debug(" Ted node (%s %pI4 %s)",
2767 vertex->node->name[0] ? vertex->node->name
2768 : "no name node",
2769 &vertex->node->router_id,
2770 origin2txt[vertex->node->adv.origin]);
2771 struct listnode *lst_node;
2772 struct ls_edge *vertex_edge;
2773
2774 for (ALL_LIST_ELEMENTS_RO(vertex->incoming_edges, lst_node,
2775 vertex_edge)) {
2776 zlog_debug(
2777 " inc edge key:%s attr key:%pI4 loc:(%pI4) rmt:(%pI4)",
2778 edge_key_to_text(vertex_edge->key),
2779 &vertex_edge->attributes->adv.id.ip.addr,
2780 &vertex_edge->attributes->standard.local,
2781 &vertex_edge->attributes->standard.remote);
2782 }
2783 for (ALL_LIST_ELEMENTS_RO(vertex->outgoing_edges, lst_node,
2784 vertex_edge)) {
2785 zlog_debug(
2786 " out edge key:%s attr key:%pI4 loc:(%pI4) rmt:(%pI4)",
2787 edge_key_to_text(vertex_edge->key),
2788 &vertex_edge->attributes->adv.id.ip.addr,
2789 &vertex_edge->attributes->standard.local,
2790 &vertex_edge->attributes->standard.remote);
2791 }
2792 }
2793 frr_each (edges, &ted->edges, edge) {
2794 zlog_debug(" Ted edge key:%s src:%pI4 dst:%pI4",
2795 edge_key_to_text(edge->key),
2796 edge->source ? &edge->source->node->router_id
2797 : &inaddr_any,
2798 edge->destination
2799 ? &edge->destination->node->router_id
2800 : &inaddr_any);
2801 }
2802 frr_each (subnets, &ted->subnets, subnet) {
2803 zlog_debug(" Ted subnet key:%pFX vertex:%pI4",
2804 &subnet->ls_pref->pref,
2805 &subnet->vertex->node->adv.id.ip.addr);
2806 }
2807 zlog_debug("(%s) Ted end", __func__);
2808 }