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