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