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