]> git.proxmox.com Git - mirror_frr.git/blob - lib/link_state.c
Merge pull request #10348 from ton31337/fix/gr_dynamic_neighbors2
[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_attributes));
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 default:
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 default:
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 }
1020
1021 void ls_ted_clean(struct ls_ted *ted)
1022 {
1023 struct ls_vertex *vertex;
1024 struct ls_edge *edge;
1025 struct ls_subnet *subnet;
1026
1027 if (ted == NULL)
1028 return;
1029
1030 /* First, start with Vertices */
1031 frr_each_safe (vertices, &ted->vertices, vertex)
1032 if (vertex->status == ORPHAN)
1033 ls_vertex_del_all(ted, vertex);
1034
1035 /* Then Edges */
1036 frr_each_safe (edges, &ted->edges, edge)
1037 if (edge->status == ORPHAN)
1038 ls_edge_del_all(ted, edge);
1039
1040 /* and Subnets */
1041 frr_each_safe (subnets, &ted->subnets, subnet)
1042 if (subnet->status == ORPHAN)
1043 ls_subnet_del_all(ted, subnet);
1044
1045 }
1046
1047 void ls_connect(struct ls_vertex *vertex, struct ls_edge *edge, bool source)
1048 {
1049 if (vertex == NULL || edge == NULL)
1050 return;
1051
1052 if (source) {
1053 listnode_add_sort_nodup(vertex->outgoing_edges, edge);
1054 edge->source = vertex;
1055 } else {
1056 listnode_add_sort_nodup(vertex->incoming_edges, edge);
1057 edge->destination = vertex;
1058 }
1059 }
1060
1061 void ls_disconnect(struct ls_vertex *vertex, struct ls_edge *edge, bool source)
1062 {
1063
1064 if (vertex == NULL || edge == NULL)
1065 return;
1066
1067 if (source) {
1068 listnode_delete(vertex->outgoing_edges, edge);
1069 edge->source = NULL;
1070 } else {
1071 listnode_delete(vertex->incoming_edges, edge);
1072 edge->destination = NULL;
1073 }
1074 }
1075
1076 void ls_connect_vertices(struct ls_vertex *src, struct ls_vertex *dst,
1077 struct ls_edge *edge)
1078 {
1079 if (edge == NULL)
1080 return;
1081
1082 edge->source = src;
1083 edge->destination = dst;
1084
1085 if (src != NULL)
1086 listnode_add_sort_nodup(src->outgoing_edges, edge);
1087
1088 if (dst != NULL)
1089 listnode_add_sort_nodup(dst->incoming_edges, edge);
1090 }
1091
1092 void ls_disconnect_edge(struct ls_edge *edge)
1093 {
1094 if (edge == NULL)
1095 return;
1096
1097 ls_disconnect(edge->source, edge, true);
1098 ls_disconnect(edge->destination, edge, false);
1099
1100 /* Mark this Edge as ORPHAN for future cleanup */
1101 edge->status = ORPHAN;
1102 }
1103
1104 /**
1105 * Link State Message management functions
1106 */
1107
1108 int ls_register(struct zclient *zclient, bool server)
1109 {
1110 int rc;
1111
1112 if (server)
1113 rc = zclient_register_opaque(zclient, LINK_STATE_SYNC);
1114 else
1115 rc = zclient_register_opaque(zclient, LINK_STATE_UPDATE);
1116
1117 return rc;
1118 }
1119
1120 int ls_unregister(struct zclient *zclient, bool server)
1121 {
1122 int rc;
1123
1124 if (server)
1125 rc = zclient_unregister_opaque(zclient, LINK_STATE_SYNC);
1126 else
1127 rc = zclient_unregister_opaque(zclient, LINK_STATE_UPDATE);
1128
1129 return rc;
1130 }
1131
1132 int ls_request_sync(struct zclient *zclient)
1133 {
1134 struct stream *s;
1135 uint16_t flags = 0;
1136
1137 /* Check buffer size */
1138 if (STREAM_SIZE(zclient->obuf)
1139 < (ZEBRA_HEADER_SIZE + 3 * sizeof(uint32_t)))
1140 return -1;
1141
1142 s = zclient->obuf;
1143 stream_reset(s);
1144
1145 zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
1146
1147 /* Set type and flags */
1148 stream_putl(s, LINK_STATE_SYNC);
1149 stream_putw(s, flags);
1150 /* Send destination client info */
1151 stream_putc(s, zclient->redist_default);
1152 stream_putw(s, zclient->instance);
1153 stream_putl(s, zclient->session_id);
1154
1155 /* Put length into the header at the start of the stream. */
1156 stream_putw_at(s, 0, stream_get_endp(s));
1157
1158 return zclient_send_message(zclient);
1159 }
1160
1161 static struct ls_node *ls_parse_node(struct stream *s)
1162 {
1163 struct ls_node *node;
1164 size_t len;
1165
1166 node = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_node));
1167
1168 STREAM_GET(&node->adv, s, sizeof(struct ls_node_id));
1169 STREAM_GETW(s, node->flags);
1170 if (CHECK_FLAG(node->flags, LS_NODE_NAME)) {
1171 STREAM_GETC(s, len);
1172 STREAM_GET(node->name, s, len);
1173 }
1174 if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID))
1175 node->router_id.s_addr = stream_get_ipv4(s);
1176 if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID6))
1177 STREAM_GET(&node->router_id6, s, IPV6_MAX_BYTELEN);
1178 if (CHECK_FLAG(node->flags, LS_NODE_FLAG))
1179 STREAM_GETC(s, node->node_flag);
1180 if (CHECK_FLAG(node->flags, LS_NODE_TYPE))
1181 STREAM_GETC(s, node->type);
1182 if (CHECK_FLAG(node->flags, LS_NODE_AS_NUMBER))
1183 STREAM_GETL(s, node->as_number);
1184 if (CHECK_FLAG(node->flags, LS_NODE_SR)) {
1185 STREAM_GETL(s, node->srgb.lower_bound);
1186 STREAM_GETL(s, node->srgb.range_size);
1187 STREAM_GETC(s, node->srgb.flag);
1188 STREAM_GET(node->algo, s, 2);
1189 }
1190 if (CHECK_FLAG(node->flags, LS_NODE_SRLB)) {
1191 STREAM_GETL(s, node->srlb.lower_bound);
1192 STREAM_GETL(s, node->srlb.range_size);
1193 }
1194 if (CHECK_FLAG(node->flags, LS_NODE_MSD))
1195 STREAM_GETC(s, node->msd);
1196
1197 return node;
1198
1199 stream_failure:
1200 zlog_err("LS(%s): Could not parse Link State Node. Abort!", __func__);
1201 XFREE(MTYPE_LS_DB, node);
1202 return NULL;
1203 }
1204
1205 static struct ls_attributes *ls_parse_attributes(struct stream *s)
1206 {
1207 struct ls_attributes *attr;
1208 size_t len;
1209
1210 attr = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_attributes));
1211 attr->srlgs = NULL;
1212
1213 STREAM_GET(&attr->adv, s, sizeof(struct ls_node_id));
1214 STREAM_GETL(s, attr->flags);
1215 if (CHECK_FLAG(attr->flags, LS_ATTR_NAME)) {
1216 STREAM_GETC(s, len);
1217 STREAM_GET(attr->name, s, len);
1218 }
1219 if (CHECK_FLAG(attr->flags, LS_ATTR_METRIC))
1220 STREAM_GETL(s, attr->metric);
1221 if (CHECK_FLAG(attr->flags, LS_ATTR_TE_METRIC))
1222 STREAM_GETL(s, attr->standard.te_metric);
1223 if (CHECK_FLAG(attr->flags, LS_ATTR_ADM_GRP))
1224 STREAM_GETL(s, attr->standard.admin_group);
1225 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR))
1226 attr->standard.local.s_addr = stream_get_ipv4(s);
1227 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR))
1228 attr->standard.remote.s_addr = stream_get_ipv4(s);
1229 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6))
1230 STREAM_GET(&attr->standard.local6, s, IPV6_MAX_BYTELEN);
1231 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR6))
1232 STREAM_GET(&attr->standard.remote6, s, IPV6_MAX_BYTELEN);
1233 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID))
1234 STREAM_GETL(s, attr->standard.local_id);
1235 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ID))
1236 STREAM_GETL(s, attr->standard.remote_id);
1237 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_BW))
1238 STREAM_GETF(s, attr->standard.max_bw);
1239 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_RSV_BW))
1240 STREAM_GETF(s, attr->standard.max_rsv_bw);
1241 if (CHECK_FLAG(attr->flags, LS_ATTR_UNRSV_BW))
1242 for (len = 0; len < MAX_CLASS_TYPE; len++)
1243 STREAM_GETF(s, attr->standard.unrsv_bw[len]);
1244 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_AS))
1245 STREAM_GETL(s, attr->standard.remote_as);
1246 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR))
1247 attr->standard.remote_addr.s_addr = stream_get_ipv4(s);
1248 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR6))
1249 STREAM_GET(&attr->standard.remote_addr6, s, IPV6_MAX_BYTELEN);
1250 if (CHECK_FLAG(attr->flags, LS_ATTR_DELAY))
1251 STREAM_GETL(s, attr->extended.delay);
1252 if (CHECK_FLAG(attr->flags, LS_ATTR_MIN_MAX_DELAY)) {
1253 STREAM_GETL(s, attr->extended.min_delay);
1254 STREAM_GETL(s, attr->extended.max_delay);
1255 }
1256 if (CHECK_FLAG(attr->flags, LS_ATTR_JITTER))
1257 STREAM_GETL(s, attr->extended.jitter);
1258 if (CHECK_FLAG(attr->flags, LS_ATTR_PACKET_LOSS))
1259 STREAM_GETL(s, attr->extended.pkt_loss);
1260 if (CHECK_FLAG(attr->flags, LS_ATTR_AVA_BW))
1261 STREAM_GETF(s, attr->extended.ava_bw);
1262 if (CHECK_FLAG(attr->flags, LS_ATTR_RSV_BW))
1263 STREAM_GETF(s, attr->extended.rsv_bw);
1264 if (CHECK_FLAG(attr->flags, LS_ATTR_USE_BW))
1265 STREAM_GETF(s, attr->extended.used_bw);
1266 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID)) {
1267 STREAM_GETL(s, attr->adj_sid[ADJ_PRI_IPV4].sid);
1268 STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV4].flags);
1269 STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV4].weight);
1270 attr->adj_sid[ADJ_PRI_IPV4].neighbor.addr.s_addr =
1271 stream_get_ipv4(s);
1272 }
1273 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) {
1274 STREAM_GETL(s, attr->adj_sid[ADJ_BCK_IPV4].sid);
1275 STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV4].flags);
1276 STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV4].weight);
1277 attr->adj_sid[ADJ_BCK_IPV4].neighbor.addr.s_addr =
1278 stream_get_ipv4(s);
1279 }
1280 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) {
1281 STREAM_GETL(s, attr->adj_sid[ADJ_PRI_IPV6].sid);
1282 STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV6].flags);
1283 STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV6].weight);
1284 STREAM_GET(attr->adj_sid[ADJ_PRI_IPV6].neighbor.sysid, s,
1285 ISO_SYS_ID_LEN);
1286 }
1287 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) {
1288 STREAM_GETL(s, attr->adj_sid[ADJ_BCK_IPV6].sid);
1289 STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV6].flags);
1290 STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV6].weight);
1291 STREAM_GET(attr->adj_sid[ADJ_BCK_IPV6].neighbor.sysid, s,
1292 ISO_SYS_ID_LEN);
1293 }
1294 if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
1295 STREAM_GETC(s, len);
1296 attr->srlgs = XCALLOC(MTYPE_LS_DB, len*sizeof(uint32_t));
1297 attr->srlg_len = len;
1298 for (len = 0; len < attr->srlg_len; len++)
1299 STREAM_GETL(s, attr->srlgs[len]);
1300 }
1301
1302 return attr;
1303
1304 stream_failure:
1305 zlog_err("LS(%s): Could not parse Link State Attributes. Abort!",
1306 __func__);
1307 /* Clean memory allocation */
1308 if (attr->srlgs != NULL)
1309 XFREE(MTYPE_LS_DB, attr->srlgs);
1310 XFREE(MTYPE_LS_DB, attr);
1311 return NULL;
1312
1313 }
1314
1315 static struct ls_prefix *ls_parse_prefix(struct stream *s)
1316 {
1317 struct ls_prefix *ls_pref;
1318 size_t len;
1319
1320 ls_pref = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_prefix));
1321
1322 STREAM_GET(&ls_pref->adv, s, sizeof(struct ls_node_id));
1323 STREAM_GETW(s, ls_pref->flags);
1324 STREAM_GETC(s, ls_pref->pref.family);
1325 STREAM_GETW(s, ls_pref->pref.prefixlen);
1326 len = prefix_blen(&ls_pref->pref);
1327 STREAM_GET(&ls_pref->pref.u.prefix, s, len);
1328 if (CHECK_FLAG(ls_pref->flags, LS_PREF_IGP_FLAG))
1329 STREAM_GETC(s, ls_pref->igp_flag);
1330 if (CHECK_FLAG(ls_pref->flags, LS_PREF_ROUTE_TAG))
1331 STREAM_GETL(s, ls_pref->route_tag);
1332 if (CHECK_FLAG(ls_pref->flags, LS_PREF_EXTENDED_TAG))
1333 STREAM_GETQ(s, ls_pref->extended_tag);
1334 if (CHECK_FLAG(ls_pref->flags, LS_PREF_METRIC))
1335 STREAM_GETL(s, ls_pref->metric);
1336 if (CHECK_FLAG(ls_pref->flags, LS_PREF_SR)) {
1337 STREAM_GETL(s, ls_pref->sr.sid);
1338 STREAM_GETC(s, ls_pref->sr.sid_flag);
1339 STREAM_GETC(s, ls_pref->sr.algo);
1340 }
1341
1342 return ls_pref;
1343
1344 stream_failure:
1345 zlog_err("LS(%s): Could not parse Link State Prefix. Abort!", __func__);
1346 XFREE(MTYPE_LS_DB, ls_pref);
1347 return NULL;
1348 }
1349
1350 struct ls_message *ls_parse_msg(struct stream *s)
1351 {
1352 struct ls_message *msg;
1353
1354 msg = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_message));
1355
1356 /* Read LS Message header */
1357 STREAM_GETC(s, msg->event);
1358 STREAM_GETC(s, msg->type);
1359 STREAM_GET(&msg->remote_id, s, sizeof(struct ls_node_id));
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 msg->data.attr = ls_parse_attributes(s);
1368 break;
1369 case LS_MSG_TYPE_PREFIX:
1370 msg->data.prefix = ls_parse_prefix(s);
1371 break;
1372 default:
1373 zlog_err("Unsupported Payload");
1374 goto stream_failure;
1375 }
1376
1377 if (msg->data.node == NULL || msg->data.attr == NULL
1378 || msg->data.prefix == NULL)
1379 goto stream_failure;
1380
1381 return msg;
1382
1383 stream_failure:
1384 zlog_err("LS(%s): Could not parse LS message. Abort!", __func__);
1385 XFREE(MTYPE_LS_DB, msg);
1386 return NULL;
1387 }
1388
1389 static int ls_format_node(struct stream *s, struct ls_node *node)
1390 {
1391 size_t len;
1392
1393 /* Push Advertise node information first */
1394 stream_put(s, &node->adv, sizeof(struct ls_node_id));
1395
1396 /* Push Flags & Origin then Node information if there are present */
1397 stream_putw(s, node->flags);
1398 if (CHECK_FLAG(node->flags, LS_NODE_NAME)) {
1399 len = strlen(node->name);
1400 stream_putc(s, len + 1);
1401 stream_put(s, node->name, len);
1402 stream_putc(s, '\0');
1403 }
1404 if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID))
1405 stream_put_ipv4(s, node->router_id.s_addr);
1406 if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID6))
1407 stream_put(s, &node->router_id6, IPV6_MAX_BYTELEN);
1408 if (CHECK_FLAG(node->flags, LS_NODE_FLAG))
1409 stream_putc(s, node->node_flag);
1410 if (CHECK_FLAG(node->flags, LS_NODE_TYPE))
1411 stream_putc(s, node->type);
1412 if (CHECK_FLAG(node->flags, LS_NODE_AS_NUMBER))
1413 stream_putl(s, node->as_number);
1414 if (CHECK_FLAG(node->flags, LS_NODE_SR)) {
1415 stream_putl(s, node->srgb.lower_bound);
1416 stream_putl(s, node->srgb.range_size);
1417 stream_putc(s, node->srgb.flag);
1418 stream_put(s, node->algo, 2);
1419 }
1420 if (CHECK_FLAG(node->flags, LS_NODE_SRLB)) {
1421 stream_putl(s, node->srlb.lower_bound);
1422 stream_putl(s, node->srlb.range_size);
1423 }
1424 if (CHECK_FLAG(node->flags, LS_NODE_MSD))
1425 stream_putc(s, node->msd);
1426
1427 return 0;
1428 }
1429
1430 static int ls_format_attributes(struct stream *s, struct ls_attributes *attr)
1431 {
1432 size_t len;
1433
1434 /* Push Advertise node information first */
1435 stream_put(s, &attr->adv, sizeof(struct ls_node_id));
1436
1437 /* Push Flags & Origin then LS attributes if there are present */
1438 stream_putl(s, attr->flags);
1439 if (CHECK_FLAG(attr->flags, LS_ATTR_NAME)) {
1440 len = strlen(attr->name);
1441 stream_putc(s, len + 1);
1442 stream_put(s, attr->name, len);
1443 stream_putc(s, '\0');
1444 }
1445 if (CHECK_FLAG(attr->flags, LS_ATTR_METRIC))
1446 stream_putl(s, attr->metric);
1447 if (CHECK_FLAG(attr->flags, LS_ATTR_TE_METRIC))
1448 stream_putl(s, attr->standard.te_metric);
1449 if (CHECK_FLAG(attr->flags, LS_ATTR_ADM_GRP))
1450 stream_putl(s, attr->standard.admin_group);
1451 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR))
1452 stream_put_ipv4(s, attr->standard.local.s_addr);
1453 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR))
1454 stream_put_ipv4(s, attr->standard.remote.s_addr);
1455 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6))
1456 stream_put(s, &attr->standard.local6, IPV6_MAX_BYTELEN);
1457 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR6))
1458 stream_put(s, &attr->standard.remote6, IPV6_MAX_BYTELEN);
1459 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID))
1460 stream_putl(s, attr->standard.local_id);
1461 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ID))
1462 stream_putl(s, attr->standard.remote_id);
1463 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_BW))
1464 stream_putf(s, attr->standard.max_bw);
1465 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_RSV_BW))
1466 stream_putf(s, attr->standard.max_rsv_bw);
1467 if (CHECK_FLAG(attr->flags, LS_ATTR_UNRSV_BW))
1468 for (len = 0; len < MAX_CLASS_TYPE; len++)
1469 stream_putf(s, attr->standard.unrsv_bw[len]);
1470 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_AS))
1471 stream_putl(s, attr->standard.remote_as);
1472 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR))
1473 stream_put_ipv4(s, attr->standard.remote_addr.s_addr);
1474 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR6))
1475 stream_put(s, &attr->standard.remote_addr6, IPV6_MAX_BYTELEN);
1476 if (CHECK_FLAG(attr->flags, LS_ATTR_DELAY))
1477 stream_putl(s, attr->extended.delay);
1478 if (CHECK_FLAG(attr->flags, LS_ATTR_MIN_MAX_DELAY)) {
1479 stream_putl(s, attr->extended.min_delay);
1480 stream_putl(s, attr->extended.max_delay);
1481 }
1482 if (CHECK_FLAG(attr->flags, LS_ATTR_JITTER))
1483 stream_putl(s, attr->extended.jitter);
1484 if (CHECK_FLAG(attr->flags, LS_ATTR_PACKET_LOSS))
1485 stream_putl(s, attr->extended.pkt_loss);
1486 if (CHECK_FLAG(attr->flags, LS_ATTR_AVA_BW))
1487 stream_putf(s, attr->extended.ava_bw);
1488 if (CHECK_FLAG(attr->flags, LS_ATTR_RSV_BW))
1489 stream_putf(s, attr->extended.rsv_bw);
1490 if (CHECK_FLAG(attr->flags, LS_ATTR_USE_BW))
1491 stream_putf(s, attr->extended.used_bw);
1492 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID)) {
1493 stream_putl(s, attr->adj_sid[ADJ_PRI_IPV4].sid);
1494 stream_putc(s, attr->adj_sid[ADJ_PRI_IPV4].flags);
1495 stream_putc(s, attr->adj_sid[ADJ_PRI_IPV4].weight);
1496 stream_put_ipv4(
1497 s, attr->adj_sid[ADJ_PRI_IPV4].neighbor.addr.s_addr);
1498 }
1499 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) {
1500 stream_putl(s, attr->adj_sid[ADJ_BCK_IPV4].sid);
1501 stream_putc(s, attr->adj_sid[ADJ_BCK_IPV4].flags);
1502 stream_putc(s, attr->adj_sid[ADJ_BCK_IPV4].weight);
1503 stream_put_ipv4(
1504 s, attr->adj_sid[ADJ_BCK_IPV4].neighbor.addr.s_addr);
1505 }
1506 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) {
1507 stream_putl(s, attr->adj_sid[ADJ_PRI_IPV6].sid);
1508 stream_putc(s, attr->adj_sid[ADJ_PRI_IPV6].flags);
1509 stream_putc(s, attr->adj_sid[ADJ_PRI_IPV6].weight);
1510 stream_put(s, attr->adj_sid[ADJ_PRI_IPV6].neighbor.sysid,
1511 ISO_SYS_ID_LEN);
1512 }
1513 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) {
1514 stream_putl(s, attr->adj_sid[ADJ_BCK_IPV6].sid);
1515 stream_putc(s, attr->adj_sid[ADJ_BCK_IPV6].flags);
1516 stream_putc(s, attr->adj_sid[ADJ_BCK_IPV6].weight);
1517 stream_put(s, attr->adj_sid[ADJ_BCK_IPV6].neighbor.sysid,
1518 ISO_SYS_ID_LEN);
1519 }
1520 if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
1521 stream_putc(s, attr->srlg_len);
1522 for (len = 0; len < attr->srlg_len; len++)
1523 stream_putl(s, attr->srlgs[len]);
1524 }
1525
1526 return 0;
1527 }
1528
1529 static int ls_format_prefix(struct stream *s, struct ls_prefix *ls_pref)
1530 {
1531 size_t len;
1532
1533 /* Push Advertise node information first */
1534 stream_put(s, &ls_pref->adv, sizeof(struct ls_node_id));
1535
1536 /* Push Flags, Origin & Prefix then information if there are present */
1537 stream_putw(s, ls_pref->flags);
1538 stream_putc(s, ls_pref->pref.family);
1539 stream_putw(s, ls_pref->pref.prefixlen);
1540 len = prefix_blen(&ls_pref->pref);
1541 stream_put(s, &ls_pref->pref.u.prefix, len);
1542 if (CHECK_FLAG(ls_pref->flags, LS_PREF_IGP_FLAG))
1543 stream_putc(s, ls_pref->igp_flag);
1544 if (CHECK_FLAG(ls_pref->flags, LS_PREF_ROUTE_TAG))
1545 stream_putl(s, ls_pref->route_tag);
1546 if (CHECK_FLAG(ls_pref->flags, LS_PREF_EXTENDED_TAG))
1547 stream_putq(s, ls_pref->extended_tag);
1548 if (CHECK_FLAG(ls_pref->flags, LS_PREF_METRIC))
1549 stream_putl(s, ls_pref->metric);
1550 if (CHECK_FLAG(ls_pref->flags, LS_PREF_SR)) {
1551 stream_putl(s, ls_pref->sr.sid);
1552 stream_putc(s, ls_pref->sr.sid_flag);
1553 stream_putc(s, ls_pref->sr.algo);
1554 }
1555
1556 return 0;
1557 }
1558
1559 static int ls_format_msg(struct stream *s, struct ls_message *msg)
1560 {
1561
1562 /* Prepare Link State header */
1563 stream_putc(s, msg->event);
1564 stream_putc(s, msg->type);
1565 stream_put(s, &msg->remote_id, sizeof(struct ls_node_id));
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 return ls_format_attributes(s, msg->data.attr);
1573 case LS_MSG_TYPE_PREFIX:
1574 return ls_format_prefix(s, msg->data.prefix);
1575 default:
1576 zlog_warn("Unsupported Payload");
1577 break;
1578 }
1579
1580 return -1;
1581 }
1582
1583 int ls_send_msg(struct zclient *zclient, struct ls_message *msg,
1584 struct zapi_opaque_reg_info *dst)
1585 {
1586 struct stream *s;
1587 uint16_t flags = 0;
1588
1589 /* Check if we have a valid message */
1590 if (msg->event == LS_MSG_EVENT_UNDEF)
1591 return -1;
1592
1593 /* Check buffer size */
1594 if (STREAM_SIZE(zclient->obuf) <
1595 (ZEBRA_HEADER_SIZE + sizeof(uint32_t) + sizeof(msg)))
1596 return -1;
1597
1598 s = zclient->obuf;
1599 stream_reset(s);
1600
1601 zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
1602
1603 /* Set sub-type, flags and destination for unicast message */
1604 stream_putl(s, LINK_STATE_UPDATE);
1605 if (dst != NULL) {
1606 SET_FLAG(flags, ZAPI_OPAQUE_FLAG_UNICAST);
1607 stream_putw(s, flags);
1608 /* Send destination client info */
1609 stream_putc(s, dst->proto);
1610 stream_putw(s, dst->instance);
1611 stream_putl(s, dst->session_id);
1612 } else {
1613 stream_putw(s, flags);
1614 }
1615
1616 /* Format Link State message */
1617 if (ls_format_msg(s, msg) < 0) {
1618 stream_reset(s);
1619 return -1;
1620 }
1621
1622 /* Put length into the header at the start of the stream. */
1623 stream_putw_at(s, 0, stream_get_endp(s));
1624
1625 return zclient_send_message(zclient);
1626 }
1627
1628 struct ls_message *ls_vertex2msg(struct ls_message *msg,
1629 struct ls_vertex *vertex)
1630 {
1631 /* Allocate space if needed */
1632 if (msg == NULL)
1633 msg = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_message));
1634 else
1635 memset(msg, 0, sizeof(*msg));
1636
1637 msg->type = LS_MSG_TYPE_NODE;
1638 switch (vertex->status) {
1639 case NEW:
1640 msg->event = LS_MSG_EVENT_ADD;
1641 break;
1642 case UPDATE:
1643 msg->event = LS_MSG_EVENT_UPDATE;
1644 break;
1645 case DELETE:
1646 msg->event = LS_MSG_EVENT_DELETE;
1647 break;
1648 case SYNC:
1649 msg->event = LS_MSG_EVENT_SYNC;
1650 break;
1651 default:
1652 msg->event = LS_MSG_EVENT_UNDEF;
1653 break;
1654 }
1655 msg->data.node = vertex->node;
1656 msg->remote_id.origin = UNKNOWN;
1657
1658 return msg;
1659 }
1660
1661 struct ls_message *ls_edge2msg(struct ls_message *msg, struct ls_edge *edge)
1662 {
1663 /* Allocate space if needed */
1664 if (msg == NULL)
1665 msg = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_message));
1666 else
1667 memset(msg, 0, sizeof(*msg));
1668
1669 msg->type = LS_MSG_TYPE_ATTRIBUTES;
1670 switch (edge->status) {
1671 case NEW:
1672 msg->event = LS_MSG_EVENT_ADD;
1673 break;
1674 case UPDATE:
1675 msg->event = LS_MSG_EVENT_UPDATE;
1676 break;
1677 case DELETE:
1678 msg->event = LS_MSG_EVENT_DELETE;
1679 break;
1680 case SYNC:
1681 msg->event = LS_MSG_EVENT_SYNC;
1682 break;
1683 default:
1684 msg->event = LS_MSG_EVENT_UNDEF;
1685 break;
1686 }
1687 msg->data.attr = edge->attributes;
1688 if (edge->destination != NULL)
1689 msg->remote_id = edge->destination->node->adv;
1690 else
1691 msg->remote_id.origin = UNKNOWN;
1692
1693 return msg;
1694 }
1695
1696 struct ls_message *ls_subnet2msg(struct ls_message *msg,
1697 struct ls_subnet *subnet)
1698 {
1699 /* Allocate space if needed */
1700 if (msg == NULL)
1701 msg = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_message));
1702 else
1703 memset(msg, 0, sizeof(*msg));
1704
1705 msg->type = LS_MSG_TYPE_PREFIX;
1706 switch (subnet->status) {
1707 case NEW:
1708 msg->event = LS_MSG_EVENT_ADD;
1709 break;
1710 case UPDATE:
1711 msg->event = LS_MSG_EVENT_UPDATE;
1712 break;
1713 case DELETE:
1714 msg->event = LS_MSG_EVENT_DELETE;
1715 break;
1716 case SYNC:
1717 msg->event = LS_MSG_EVENT_SYNC;
1718 break;
1719 default:
1720 msg->event = LS_MSG_EVENT_UNDEF;
1721 break;
1722 }
1723 msg->data.prefix = subnet->ls_pref;
1724 msg->remote_id.origin = UNKNOWN;
1725
1726 return msg;
1727 }
1728
1729 struct ls_vertex *ls_msg2vertex(struct ls_ted *ted, struct ls_message *msg,
1730 bool delete)
1731 {
1732 struct ls_node *node = (struct ls_node *)msg->data.node;
1733 struct ls_vertex *vertex = NULL;
1734
1735 switch (msg->event) {
1736 case LS_MSG_EVENT_SYNC:
1737 vertex = ls_vertex_add(ted, node);
1738 if (vertex)
1739 vertex->status = SYNC;
1740 break;
1741 case LS_MSG_EVENT_ADD:
1742 vertex = ls_vertex_add(ted, node);
1743 if (vertex)
1744 vertex->status = NEW;
1745 break;
1746 case LS_MSG_EVENT_UPDATE:
1747 vertex = ls_vertex_update(ted, node);
1748 if (vertex)
1749 vertex->status = UPDATE;
1750 break;
1751 case LS_MSG_EVENT_DELETE:
1752 vertex = ls_find_vertex_by_id(ted, node->adv);
1753 if (vertex) {
1754 if (delete)
1755 ls_vertex_del_all(ted, vertex);
1756 else
1757 vertex->status = DELETE;
1758 }
1759 break;
1760 default:
1761 vertex = NULL;
1762 break;
1763 }
1764
1765 return vertex;
1766 }
1767
1768 struct ls_edge *ls_msg2edge(struct ls_ted *ted, struct ls_message *msg,
1769 bool delete)
1770 {
1771 struct ls_attributes *attr = (struct ls_attributes *)msg->data.attr;
1772 struct ls_edge *edge = NULL;
1773
1774 switch (msg->event) {
1775 case LS_MSG_EVENT_SYNC:
1776 edge = ls_edge_add(ted, attr);
1777 if (edge)
1778 edge->status = SYNC;
1779 break;
1780 case LS_MSG_EVENT_ADD:
1781 edge = ls_edge_add(ted, attr);
1782 if (edge)
1783 edge->status = NEW;
1784 break;
1785 case LS_MSG_EVENT_UPDATE:
1786 edge = ls_edge_update(ted, attr);
1787 if (edge)
1788 edge->status = UPDATE;
1789 break;
1790 case LS_MSG_EVENT_DELETE:
1791 edge = ls_find_edge_by_source(ted, attr);
1792 if (edge) {
1793 if (delete)
1794 ls_edge_del_all(ted, edge);
1795 else
1796 edge->status = DELETE;
1797 }
1798 break;
1799 default:
1800 edge = NULL;
1801 break;
1802 }
1803
1804 return edge;
1805 }
1806
1807 struct ls_subnet *ls_msg2subnet(struct ls_ted *ted, struct ls_message *msg,
1808 bool delete)
1809 {
1810 struct ls_prefix *pref = (struct ls_prefix *)msg->data.prefix;
1811 struct ls_subnet *subnet = NULL;
1812
1813 switch (msg->event) {
1814 case LS_MSG_EVENT_SYNC:
1815 subnet = ls_subnet_add(ted, pref);
1816 if (subnet)
1817 subnet->status = SYNC;
1818 break;
1819 case LS_MSG_EVENT_ADD:
1820 subnet = ls_subnet_add(ted, pref);
1821 if (subnet)
1822 subnet->status = NEW;
1823 break;
1824 case LS_MSG_EVENT_UPDATE:
1825 subnet = ls_subnet_update(ted, pref);
1826 if (subnet)
1827 subnet->status = UPDATE;
1828 break;
1829 case LS_MSG_EVENT_DELETE:
1830 subnet = ls_find_subnet(ted, pref->pref);
1831 if (subnet) {
1832 if (delete)
1833 ls_subnet_del_all(ted, subnet);
1834 else
1835 subnet->status = DELETE;
1836 }
1837 break;
1838 default:
1839 subnet = NULL;
1840 break;
1841 }
1842
1843 return subnet;
1844 }
1845
1846 struct ls_element *ls_msg2ted(struct ls_ted *ted, struct ls_message *msg,
1847 bool delete)
1848 {
1849 struct ls_element *lse = NULL;
1850
1851 switch (msg->type) {
1852 case LS_MSG_TYPE_NODE:
1853 lse = (struct ls_element *)ls_msg2vertex(ted, msg, delete);
1854 break;
1855 case LS_MSG_TYPE_ATTRIBUTES:
1856 lse = (struct ls_element *)ls_msg2edge(ted, msg, delete);
1857 break;
1858 case LS_MSG_TYPE_PREFIX:
1859 lse = (struct ls_element *)ls_msg2subnet(ted, msg, delete);
1860 break;
1861 default:
1862 lse = NULL;
1863 break;
1864 }
1865
1866 return lse;
1867 }
1868
1869 struct ls_element *ls_stream2ted(struct ls_ted *ted, struct stream *s,
1870 bool delete)
1871 {
1872 struct ls_message *msg;
1873 struct ls_element *lse = NULL;
1874
1875 msg = ls_parse_msg(s);
1876 if (msg) {
1877 lse = ls_msg2ted(ted, msg, delete);
1878 ls_delete_msg(msg);
1879 }
1880
1881 return lse;
1882 }
1883
1884 void ls_delete_msg(struct ls_message *msg)
1885 {
1886 if (msg == NULL)
1887 return;
1888
1889 XFREE(MTYPE_LS_DB, msg);
1890 }
1891
1892 int ls_sync_ted(struct ls_ted *ted, struct zclient *zclient,
1893 struct zapi_opaque_reg_info *dst)
1894 {
1895 struct ls_vertex *vertex;
1896 struct ls_edge *edge;
1897 struct ls_subnet *subnet;
1898 struct ls_message msg;
1899
1900 /* Loop TED, start sending Node, then Attributes and finally Prefix */
1901 frr_each(vertices, &ted->vertices, vertex) {
1902 ls_vertex2msg(&msg, vertex);
1903 ls_send_msg(zclient, &msg, dst);
1904 }
1905 frr_each(edges, &ted->edges, edge) {
1906 ls_edge2msg(&msg, edge);
1907 ls_send_msg(zclient, &msg, dst);
1908 }
1909 frr_each(subnets, &ted->subnets, subnet) {
1910 ls_subnet2msg(&msg, subnet);
1911 ls_send_msg(zclient, &msg, dst);
1912 }
1913 return 0;
1914 }
1915
1916 /**
1917 * Link State Show functions
1918 */
1919 static const char *const origin2txt[] = {
1920 "Unknown",
1921 "ISIS_L1",
1922 "ISIS_L2",
1923 "OSPFv2",
1924 "Direct",
1925 "Static"
1926 };
1927
1928 static const char *const type2txt[] = {
1929 "Unknown",
1930 "Standard",
1931 "ABR",
1932 "ASBR",
1933 "Remote ASBR",
1934 "Pseudo"
1935 };
1936
1937 static const char *const status2txt[] = {
1938 "Unknown",
1939 "New",
1940 "Update",
1941 "Delete",
1942 "Sync",
1943 "Orphan"
1944 };
1945
1946 static const char *ls_node_id_to_text(struct ls_node_id lnid, char *str,
1947 size_t size)
1948 {
1949 if (lnid.origin == ISIS_L1 || lnid.origin == ISIS_L2) {
1950 uint8_t *id;
1951
1952 id = lnid.id.iso.sys_id;
1953 snprintfrr(str, size, "%02x%02x.%02x%02x.%02x%02x", id[0],
1954 id[1], id[2], id[3], id[4], id[5]);
1955 } else
1956 snprintfrr(str, size, "%pI4", &lnid.id.ip.addr);
1957
1958 return str;
1959 }
1960
1961 static void ls_show_vertex_vty(struct ls_vertex *vertex, struct vty *vty,
1962 bool verbose)
1963 {
1964 struct listnode *node;
1965 struct ls_node *lsn;
1966 struct ls_edge *edge;
1967 struct ls_attributes *attr;
1968 struct ls_subnet *subnet;
1969 struct sbuf sbuf;
1970 uint32_t upper;
1971
1972 /* Sanity Check */
1973 if (!vertex)
1974 return;
1975
1976 lsn = vertex->node;
1977
1978 sbuf_init(&sbuf, NULL, 0);
1979
1980 sbuf_push(&sbuf, 2, "Vertex (%" PRIu64 "): %s", vertex->key, lsn->name);
1981 sbuf_push(&sbuf, 0, "\tRouter Id: %pI4", &lsn->router_id);
1982 sbuf_push(&sbuf, 0, "\tOrigin: %s", origin2txt[lsn->adv.origin]);
1983 sbuf_push(&sbuf, 0, "\tStatus: %s\n", status2txt[vertex->status]);
1984 if (!verbose) {
1985 sbuf_push(
1986 &sbuf, 0,
1987 "\t%d Outgoing Edges, %d Incoming Edges, %d Subnets\n",
1988 listcount(vertex->outgoing_edges),
1989 listcount(vertex->incoming_edges),
1990 listcount(vertex->prefixes));
1991 goto end;
1992 }
1993
1994 if (CHECK_FLAG(lsn->flags, LS_NODE_TYPE))
1995 sbuf_push(&sbuf, 4, "Type: %s\n", type2txt[lsn->type]);
1996 if (CHECK_FLAG(lsn->flags, LS_NODE_AS_NUMBER))
1997 sbuf_push(&sbuf, 4, "AS number: %u\n", lsn->as_number);
1998 if (CHECK_FLAG(lsn->flags, LS_NODE_SR)) {
1999 sbuf_push(&sbuf, 4, "Segment Routing Capabilities:\n");
2000 upper = lsn->srgb.lower_bound + lsn->srgb.range_size - 1;
2001 sbuf_push(&sbuf, 8, "SRGB: [%d/%d]", lsn->srgb.lower_bound,
2002 upper);
2003 if (CHECK_FLAG(lsn->flags, LS_NODE_SRLB)) {
2004 upper = lsn->srlb.lower_bound + lsn->srlb.range_size
2005 - 1;
2006 sbuf_push(&sbuf, 0, "\tSRLB: [%d/%d]",
2007 lsn->srlb.lower_bound, upper);
2008 }
2009 sbuf_push(&sbuf, 0, "\tAlgo: ");
2010 for (int i = 0; i < 2; i++) {
2011 if (lsn->algo[i] == 255)
2012 continue;
2013
2014 sbuf_push(&sbuf, 0,
2015 lsn->algo[i] == 0 ? "SPF " : "S-SPF ");
2016 }
2017 if (CHECK_FLAG(lsn->flags, LS_NODE_MSD))
2018 sbuf_push(&sbuf, 0, "\tMSD: %d", lsn->msd);
2019 sbuf_push(&sbuf, 0, "\n");
2020 }
2021
2022 sbuf_push(&sbuf, 4, "Outgoing Edges: %d\n",
2023 listcount(vertex->outgoing_edges));
2024 for (ALL_LIST_ELEMENTS_RO(vertex->outgoing_edges, node, edge)) {
2025 if (edge->destination) {
2026 lsn = edge->destination->node;
2027 sbuf_push(&sbuf, 6, "To:\t%s(%pI4)", lsn->name,
2028 &lsn->router_id);
2029 } else {
2030 sbuf_push(&sbuf, 6, "To:\t- (0.0.0.0)");
2031 }
2032 attr = edge->attributes;
2033 if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR)))
2034 sbuf_push(&sbuf, 0, "\tLocal: %pI4\tRemote: %pI4\n",
2035 &attr->standard.local,
2036 &attr->standard.remote);
2037 else if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6)))
2038 sbuf_push(&sbuf, 0, "\tLocal: %pI6\tRemote: %pI6\n",
2039 &attr->standard.local6,
2040 &attr->standard.remote6);
2041 }
2042
2043 sbuf_push(&sbuf, 4, "Incoming Edges: %d\n",
2044 listcount(vertex->incoming_edges));
2045 for (ALL_LIST_ELEMENTS_RO(vertex->incoming_edges, node, edge)) {
2046 if (edge->source) {
2047 lsn = edge->source->node;
2048 sbuf_push(&sbuf, 6, "From:\t%s(%pI4)", lsn->name,
2049 &lsn->router_id);
2050 } else {
2051 sbuf_push(&sbuf, 6, "From:\t- (0.0.0.0)");
2052 }
2053 attr = edge->attributes;
2054 if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR)))
2055 sbuf_push(&sbuf, 0, "\tLocal: %pI4\tRemote: %pI4\n",
2056 &attr->standard.local,
2057 &attr->standard.remote);
2058 else if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6)))
2059 sbuf_push(&sbuf, 0, "\tLocal: %pI6\tRemote: %pI6\n",
2060 &attr->standard.local6,
2061 &attr->standard.remote6);
2062 }
2063
2064 sbuf_push(&sbuf, 4, "Subnets: %d\n", listcount(vertex->prefixes));
2065 for (ALL_LIST_ELEMENTS_RO(vertex->prefixes, node, subnet))
2066 sbuf_push(&sbuf, 6, "Prefix:\t%pFX\n", &subnet->key);
2067
2068 end:
2069 vty_out(vty, "%s\n", sbuf_buf(&sbuf));
2070 sbuf_free(&sbuf);
2071 }
2072
2073 static void ls_show_vertex_json(struct ls_vertex *vertex,
2074 struct json_object *json)
2075 {
2076 struct ls_node *lsn;
2077 json_object *jsr, *jalgo, *jobj;
2078 char buf[INET6_BUFSIZ];
2079
2080 /* Sanity Check */
2081 if (!vertex)
2082 return;
2083
2084 lsn = vertex->node;
2085
2086 json_object_int_add(json, "vertex-id", vertex->key);
2087 json_object_string_add(json, "status", status2txt[vertex->status]);
2088 json_object_string_add(json, "origin", origin2txt[lsn->adv.origin]);
2089 if (CHECK_FLAG(lsn->flags, LS_NODE_NAME))
2090 json_object_string_add(json, "name", lsn->name);
2091 if (CHECK_FLAG(lsn->flags, LS_NODE_ROUTER_ID)) {
2092 snprintfrr(buf, INET6_BUFSIZ, "%pI4", &lsn->router_id);
2093 json_object_string_add(json, "router-id", buf);
2094 }
2095 if (CHECK_FLAG(lsn->flags, LS_NODE_ROUTER_ID6)) {
2096 snprintfrr(buf, INET6_BUFSIZ, "%pI6", &lsn->router_id6);
2097 json_object_string_add(json, "router-id-v6", buf);
2098 }
2099 if (CHECK_FLAG(lsn->flags, LS_NODE_TYPE))
2100 json_object_string_add(json, "vertex-type",
2101 type2txt[lsn->type]);
2102 if (CHECK_FLAG(lsn->flags, LS_NODE_AS_NUMBER))
2103 json_object_int_add(json, "asn", lsn->as_number);
2104 if (CHECK_FLAG(lsn->flags, LS_NODE_SR)) {
2105 jsr = json_object_new_object();
2106 json_object_object_add(json, "segment-routing", jsr);
2107 json_object_int_add(jsr, "srgb-size", lsn->srgb.range_size);
2108 json_object_int_add(jsr, "srgb-lower", lsn->srgb.lower_bound);
2109 jalgo = json_object_new_array();
2110 json_object_object_add(jsr, "algorithms", jalgo);
2111 for (int i = 0; i < 2; i++) {
2112 if (lsn->algo[i] == 255)
2113 continue;
2114 jobj = json_object_new_object();
2115
2116 snprintfrr(buf, 2, "%u", i);
2117 json_object_string_add(
2118 jobj, buf, lsn->algo[i] == 0 ? "SPF" : "S-SPF");
2119 json_object_array_add(jalgo, jobj);
2120 }
2121 if (CHECK_FLAG(lsn->flags, LS_NODE_SRLB)) {
2122 json_object_int_add(jsr, "srlb-size",
2123 lsn->srlb.range_size);
2124 json_object_int_add(jsr, "srlb-lower",
2125 lsn->srlb.lower_bound);
2126 }
2127 if (CHECK_FLAG(lsn->flags, LS_NODE_MSD))
2128 json_object_int_add(jsr, "msd", lsn->msd);
2129 }
2130 }
2131
2132 void ls_show_vertex(struct ls_vertex *vertex, struct vty *vty,
2133 struct json_object *json, bool verbose)
2134 {
2135 if (json)
2136 ls_show_vertex_json(vertex, json);
2137 else if (vty)
2138 ls_show_vertex_vty(vertex, vty, verbose);
2139 }
2140
2141 void ls_show_vertices(struct ls_ted *ted, struct vty *vty,
2142 struct json_object *json, bool verbose)
2143 {
2144 struct ls_vertex *vertex;
2145 json_object *jnodes, *jnode;
2146
2147 if (json) {
2148 jnodes = json_object_new_array();
2149 json_object_object_add(json, "vertices", jnodes);
2150 frr_each (vertices, &ted->vertices, vertex) {
2151 jnode = json_object_new_object();
2152 ls_show_vertex(vertex, NULL, jnode, verbose);
2153 json_object_array_add(jnodes, jnode);
2154 }
2155 } else if (vty) {
2156 frr_each (vertices, &ted->vertices, vertex)
2157 ls_show_vertex(vertex, vty, NULL, verbose);
2158 }
2159 }
2160
2161 static void ls_show_edge_vty(struct ls_edge *edge, struct vty *vty,
2162 bool verbose)
2163 {
2164 struct ls_attributes *attr;
2165 struct sbuf sbuf;
2166 char buf[INET6_BUFSIZ];
2167
2168 attr = edge->attributes;
2169 sbuf_init(&sbuf, NULL, 0);
2170
2171 sbuf_push(&sbuf, 2, "Edge (%" PRIu64 "): ", edge->key);
2172 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR))
2173 sbuf_push(&sbuf, 0, "%pI4", &attr->standard.local);
2174 else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6))
2175 sbuf_push(&sbuf, 0, "%pI6", &attr->standard.local6);
2176 else
2177 sbuf_push(&sbuf, 0, "%u/%u", attr->standard.local_id,
2178 attr->standard.remote_id);
2179 ls_node_id_to_text(attr->adv, buf, INET6_BUFSIZ);
2180 sbuf_push(&sbuf, 0, "\tAdv. Vertex: %s", buf);
2181 sbuf_push(&sbuf, 0, "\tMetric: %u", attr->metric);
2182 sbuf_push(&sbuf, 0, "\tStatus: %s\n", status2txt[edge->status]);
2183
2184 if (!verbose)
2185 goto end;
2186
2187 sbuf_push(&sbuf, 4, "Origin: %s\n", origin2txt[attr->adv.origin]);
2188 if (CHECK_FLAG(attr->flags, LS_ATTR_NAME))
2189 sbuf_push(&sbuf, 4, "Name: %s\n", attr->name);
2190 if (CHECK_FLAG(attr->flags, LS_ATTR_TE_METRIC))
2191 sbuf_push(&sbuf, 4, "TE Metric: %u\n",
2192 attr->standard.te_metric);
2193 if (CHECK_FLAG(attr->flags, LS_ATTR_ADM_GRP))
2194 sbuf_push(&sbuf, 4, "Admin Group: 0x%x\n",
2195 attr->standard.admin_group);
2196 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR))
2197 sbuf_push(&sbuf, 4, "Local IPv4 address: %pI4\n",
2198 &attr->standard.local);
2199 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR))
2200 sbuf_push(&sbuf, 4, "Remote IPv4 address: %pI4\n",
2201 &attr->standard.remote);
2202 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6))
2203 sbuf_push(&sbuf, 4, "Local IPv6 address: %pI6\n",
2204 &attr->standard.local6);
2205 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR6))
2206 sbuf_push(&sbuf, 4, "Remote IPv6 address: %pI6\n",
2207 &attr->standard.remote6);
2208 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID))
2209 sbuf_push(&sbuf, 4, "Local Identifier: %u\n",
2210 attr->standard.local_id);
2211 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ID))
2212 sbuf_push(&sbuf, 4, "Remote Identifier: %u\n",
2213 attr->standard.remote_id);
2214 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_BW))
2215 sbuf_push(&sbuf, 4, "Maximum Bandwidth: %g (Bytes/s)\n",
2216 attr->standard.max_bw);
2217 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_RSV_BW))
2218 sbuf_push(&sbuf, 4,
2219 "Maximum Reservable Bandwidth: %g (Bytes/s)\n",
2220 attr->standard.max_rsv_bw);
2221 if (CHECK_FLAG(attr->flags, LS_ATTR_UNRSV_BW)) {
2222 sbuf_push(&sbuf, 4, "Unreserved Bandwidth per Class Type\n");
2223 for (int i = 0; i < MAX_CLASS_TYPE; i += 2)
2224 sbuf_push(&sbuf, 8,
2225 "[%d]: %g (Bytes/sec)\t[%d]: %g (Bytes/s)\n",
2226 i, attr->standard.unrsv_bw[i], i + 1,
2227 attr->standard.unrsv_bw[i + 1]);
2228 }
2229 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_AS))
2230 sbuf_push(&sbuf, 4, "Remote AS: %u\n",
2231 attr->standard.remote_as);
2232 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR))
2233 sbuf_push(&sbuf, 4, "Remote ASBR IPv4 address: %pI4\n",
2234 &attr->standard.remote_addr);
2235 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR6))
2236 sbuf_push(&sbuf, 4, "Remote ASBR IPv6 address: %pI6\n",
2237 &attr->standard.remote_addr6);
2238 if (CHECK_FLAG(attr->flags, LS_ATTR_DELAY))
2239 sbuf_push(&sbuf, 4, "Average Link Delay: %d (micro-sec)\n",
2240 attr->extended.delay);
2241 if (CHECK_FLAG(attr->flags, LS_ATTR_MIN_MAX_DELAY))
2242 sbuf_push(&sbuf, 4, "Min/Max Link Delay: %d/%d (micro-sec)\n",
2243 attr->extended.min_delay, attr->extended.max_delay);
2244 if (CHECK_FLAG(attr->flags, LS_ATTR_JITTER))
2245 sbuf_push(&sbuf, 4, "Delay Variation: %d (micro-sec)\n",
2246 attr->extended.jitter);
2247 if (CHECK_FLAG(attr->flags, LS_ATTR_PACKET_LOSS))
2248 sbuf_push(&sbuf, 4, "Link Loss: %g (%%)\n",
2249 (float)(attr->extended.pkt_loss * LOSS_PRECISION));
2250 if (CHECK_FLAG(attr->flags, LS_ATTR_AVA_BW))
2251 sbuf_push(&sbuf, 4, "Available Bandwidth: %g (Bytes/s)\n",
2252 attr->extended.ava_bw);
2253 if (CHECK_FLAG(attr->flags, LS_ATTR_RSV_BW))
2254 sbuf_push(&sbuf, 4, "Residual Bandwidth: %g (Bytes/s)\n",
2255 attr->extended.rsv_bw);
2256 if (CHECK_FLAG(attr->flags, LS_ATTR_USE_BW))
2257 sbuf_push(&sbuf, 4, "Utilized Bandwidth: %g (Bytes/s)\n",
2258 attr->extended.used_bw);
2259 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID)) {
2260 sbuf_push(&sbuf, 4, "IPv4 Adjacency-SID: %u",
2261 attr->adj_sid[ADJ_PRI_IPV4].sid);
2262 sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n",
2263 attr->adj_sid[ADJ_PRI_IPV4].flags,
2264 attr->adj_sid[ADJ_PRI_IPV4].weight);
2265 }
2266 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) {
2267 sbuf_push(&sbuf, 4, "IPv4 Bck. Adjacency-SID: %u",
2268 attr->adj_sid[ADJ_BCK_IPV4].sid);
2269 sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n",
2270 attr->adj_sid[ADJ_BCK_IPV4].flags,
2271 attr->adj_sid[ADJ_BCK_IPV4].weight);
2272 }
2273 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) {
2274 sbuf_push(&sbuf, 4, "IPv6 Adjacency-SID: %u",
2275 attr->adj_sid[ADJ_PRI_IPV6].sid);
2276 sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n",
2277 attr->adj_sid[ADJ_PRI_IPV6].flags,
2278 attr->adj_sid[ADJ_PRI_IPV6].weight);
2279 }
2280 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) {
2281 sbuf_push(&sbuf, 4, "IPv6 Bck. Adjacency-SID: %u",
2282 attr->adj_sid[ADJ_BCK_IPV6].sid);
2283 sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n",
2284 attr->adj_sid[ADJ_BCK_IPV6].flags,
2285 attr->adj_sid[ADJ_BCK_IPV6].weight);
2286 }
2287 if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
2288 sbuf_push(&sbuf, 4, "SRLGs: %d", attr->srlg_len);
2289 for (int i = 1; i < attr->srlg_len; i++) {
2290 if (i % 8)
2291 sbuf_push(&sbuf, 8, "\n%u", attr->srlgs[i]);
2292 else
2293 sbuf_push(&sbuf, 8, ", %u", attr->srlgs[i]);
2294 }
2295 sbuf_push(&sbuf, 0, "\n");
2296 }
2297
2298 end:
2299 vty_out(vty, "%s\n", sbuf_buf(&sbuf));
2300 sbuf_free(&sbuf);
2301 }
2302
2303 static void ls_show_edge_json(struct ls_edge *edge, struct json_object *json)
2304 {
2305 struct ls_attributes *attr;
2306 struct json_object *jte, *jbw, *jobj, *jsr = NULL, *jsrlg;
2307 char buf[INET6_BUFSIZ];
2308
2309 attr = edge->attributes;
2310
2311 json_object_int_add(json, "edge-id", edge->key);
2312 json_object_string_add(json, "status", status2txt[edge->status]);
2313 json_object_string_add(json, "origin", origin2txt[attr->adv.origin]);
2314 ls_node_id_to_text(attr->adv, buf, INET6_BUFSIZ);
2315 json_object_string_add(json, "advertised-router", buf);
2316 if (edge->source)
2317 json_object_int_add(json, "local-vertex-id", edge->source->key);
2318 if (edge->destination)
2319 json_object_int_add(json, "remote-vertex-id",
2320 edge->destination->key);
2321 json_object_int_add(json, "metric", attr->metric);
2322 if (CHECK_FLAG(attr->flags, LS_ATTR_NAME))
2323 json_object_string_add(json, "name", attr->name);
2324 jte = json_object_new_object();
2325 json_object_object_add(json, "edge-attributes", jte);
2326 if (CHECK_FLAG(attr->flags, LS_ATTR_TE_METRIC))
2327 json_object_int_add(jte, "te-metric", attr->standard.te_metric);
2328 if (CHECK_FLAG(attr->flags, LS_ATTR_ADM_GRP))
2329 json_object_int_add(jte, "admin-group",
2330 attr->standard.admin_group);
2331 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR)) {
2332 snprintfrr(buf, INET6_BUFSIZ, "%pI4", &attr->standard.local);
2333 json_object_string_add(jte, "local-address", buf);
2334 }
2335 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR)) {
2336 snprintfrr(buf, INET6_BUFSIZ, "%pI4", &attr->standard.remote);
2337 json_object_string_add(jte, "remote-address", buf);
2338 }
2339 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6)) {
2340 snprintfrr(buf, INET6_BUFSIZ, "%pI6", &attr->standard.local6);
2341 json_object_string_add(jte, "local-address-v6", buf);
2342 }
2343 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR6)) {
2344 snprintfrr(buf, INET6_BUFSIZ, "%pI6", &attr->standard.remote6);
2345 json_object_string_add(jte, "remote-address-v6", buf);
2346 }
2347 if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID))
2348 json_object_int_add(jte, "local-identifier",
2349 attr->standard.local_id);
2350 if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ID))
2351 json_object_int_add(jte, "remote-identifier",
2352 attr->standard.remote_id);
2353 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_BW))
2354 json_object_double_add(jte, "max-link-bandwidth",
2355 attr->standard.max_bw);
2356 if (CHECK_FLAG(attr->flags, LS_ATTR_MAX_RSV_BW))
2357 json_object_double_add(jte, "max-resv-link-bandwidth",
2358 attr->standard.max_rsv_bw);
2359 if (CHECK_FLAG(attr->flags, LS_ATTR_UNRSV_BW)) {
2360 jbw = json_object_new_array();
2361 json_object_object_add(jte, "unreserved-bandwidth", jbw);
2362 for (int i = 0; i < MAX_CLASS_TYPE; i++) {
2363 jobj = json_object_new_object();
2364 snprintfrr(buf, 13, "class-type-%u", i);
2365 json_object_double_add(jobj, buf,
2366 attr->standard.unrsv_bw[i]);
2367 json_object_array_add(jbw, jobj);
2368 }
2369 }
2370 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_AS))
2371 json_object_int_add(jte, "remote-asn",
2372 attr->standard.remote_as);
2373 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR)) {
2374 snprintfrr(buf, INET6_BUFSIZ, "%pI4",
2375 &attr->standard.remote_addr);
2376 json_object_string_add(jte, "remote-as-address", buf);
2377 }
2378 if (CHECK_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR6)) {
2379 snprintfrr(buf, INET6_BUFSIZ, "%pI6",
2380 &attr->standard.remote_addr6);
2381 json_object_string_add(jte, "remote-as-address-v6", buf);
2382 }
2383 if (CHECK_FLAG(attr->flags, LS_ATTR_DELAY))
2384 json_object_int_add(jte, "delay", attr->extended.delay);
2385 if (CHECK_FLAG(attr->flags, LS_ATTR_MIN_MAX_DELAY)) {
2386 json_object_int_add(jte, "min-delay", attr->extended.min_delay);
2387 json_object_int_add(jte, "max-delay", attr->extended.max_delay);
2388 }
2389 if (CHECK_FLAG(attr->flags, LS_ATTR_JITTER))
2390 json_object_int_add(jte, "jitter", attr->extended.jitter);
2391 if (CHECK_FLAG(attr->flags, LS_ATTR_PACKET_LOSS))
2392 json_object_double_add(
2393 jte, "loss", attr->extended.pkt_loss * LOSS_PRECISION);
2394 if (CHECK_FLAG(attr->flags, LS_ATTR_AVA_BW))
2395 json_object_double_add(jte, "available-bandwidth",
2396 attr->extended.ava_bw);
2397 if (CHECK_FLAG(attr->flags, LS_ATTR_RSV_BW))
2398 json_object_double_add(jte, "residual-bandwidth",
2399 attr->extended.rsv_bw);
2400 if (CHECK_FLAG(attr->flags, LS_ATTR_USE_BW))
2401 json_object_double_add(jte, "utilized-bandwidth",
2402 attr->extended.used_bw);
2403 if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
2404 jsrlg = json_object_new_array();
2405 json_object_object_add(jte, "srlgs", jsrlg);
2406 for (int i = 1; i < attr->srlg_len; i++) {
2407 jobj = json_object_new_object();
2408 json_object_int_add(jobj, "srlg", attr->srlgs[i]);
2409 json_object_array_add(jsrlg, jobj);
2410 }
2411 }
2412 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID)) {
2413 jsr = json_object_new_array();
2414 json_object_object_add(json, "segment-routing", jsr);
2415 jobj = json_object_new_object();
2416 json_object_int_add(jobj, "adj-sid",
2417 attr->adj_sid[ADJ_PRI_IPV4].sid);
2418 snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_PRI_IPV4].flags);
2419 json_object_string_add(jobj, "flags", buf);
2420 json_object_int_add(jobj, "weight",
2421 attr->adj_sid[ADJ_PRI_IPV4].weight);
2422 json_object_array_add(jsr, jobj);
2423 }
2424 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) {
2425 if (!jsr) {
2426 jsr = json_object_new_array();
2427 json_object_object_add(json, "segment-routing", jsr);
2428 }
2429 jobj = json_object_new_object();
2430 json_object_int_add(jobj, "adj-sid",
2431 attr->adj_sid[ADJ_BCK_IPV4].sid);
2432 snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_BCK_IPV4].flags);
2433 json_object_string_add(jobj, "flags", buf);
2434 json_object_int_add(jobj, "weight",
2435 attr->adj_sid[ADJ_BCK_IPV4].weight);
2436 json_object_array_add(jsr, jobj);
2437 }
2438 if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) {
2439 jsr = json_object_new_array();
2440 json_object_object_add(json, "segment-routing", jsr);
2441 jobj = json_object_new_object();
2442 json_object_int_add(jobj, "adj-sid",
2443 attr->adj_sid[ADJ_PRI_IPV6].sid);
2444 snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_PRI_IPV6].flags);
2445 json_object_string_add(jobj, "flags", buf);
2446 json_object_int_add(jobj, "weight",
2447 attr->adj_sid[ADJ_PRI_IPV6].weight);
2448 json_object_array_add(jsr, jobj);
2449 }
2450 if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) {
2451 if (!jsr) {
2452 jsr = json_object_new_array();
2453 json_object_object_add(json, "segment-routing", jsr);
2454 }
2455 jobj = json_object_new_object();
2456 json_object_int_add(jobj, "adj-sid",
2457 attr->adj_sid[ADJ_BCK_IPV6].sid);
2458 snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_BCK_IPV6].flags);
2459 json_object_string_add(jobj, "flags", buf);
2460 json_object_int_add(jobj, "weight",
2461 attr->adj_sid[ADJ_BCK_IPV6].weight);
2462 json_object_array_add(jsr, jobj);
2463 }
2464 }
2465
2466 void ls_show_edge(struct ls_edge *edge, struct vty *vty,
2467 struct json_object *json, bool verbose)
2468 {
2469 /* Sanity Check */
2470 if (!edge)
2471 return;
2472
2473 if (json)
2474 ls_show_edge_json(edge, json);
2475 else if (vty)
2476 ls_show_edge_vty(edge, vty, verbose);
2477 }
2478
2479 void ls_show_edges(struct ls_ted *ted, struct vty *vty,
2480 struct json_object *json, bool verbose)
2481 {
2482 struct ls_edge *edge;
2483 json_object *jedges, *jedge;
2484
2485 if (json) {
2486 jedges = json_object_new_array();
2487 json_object_object_add(json, "edges", jedges);
2488 frr_each (edges, &ted->edges, edge) {
2489 jedge = json_object_new_object();
2490 ls_show_edge(edge, NULL, jedge, verbose);
2491 json_object_array_add(jedges, jedge);
2492 }
2493 } else if (vty) {
2494 frr_each (edges, &ted->edges, edge)
2495 ls_show_edge(edge, vty, NULL, verbose);
2496 }
2497 }
2498
2499 static void ls_show_subnet_vty(struct ls_subnet *subnet, struct vty *vty,
2500 bool verbose)
2501 {
2502 struct ls_prefix *pref;
2503 struct sbuf sbuf;
2504 char buf[INET6_BUFSIZ];
2505
2506 pref = subnet->ls_pref;
2507 sbuf_init(&sbuf, NULL, 0);
2508
2509 sbuf_push(&sbuf, 2, "Subnet: %pFX", &subnet->key);
2510 ls_node_id_to_text(pref->adv, buf, INET6_BUFSIZ);
2511 sbuf_push(&sbuf, 0, "\tAdv. Vertex: %s", buf);
2512 sbuf_push(&sbuf, 0, "\tMetric: %d", pref->metric);
2513 sbuf_push(&sbuf, 0, "\tStatus: %s\n", status2txt[subnet->status]);
2514
2515 if (!verbose)
2516 goto end;
2517
2518 sbuf_push(&sbuf, 4, "Origin: %s\n", origin2txt[pref->adv.origin]);
2519 if (CHECK_FLAG(pref->flags, LS_PREF_IGP_FLAG))
2520 sbuf_push(&sbuf, 4, "Flags: %d\n", pref->igp_flag);
2521
2522 if (CHECK_FLAG(pref->flags, LS_PREF_ROUTE_TAG))
2523 sbuf_push(&sbuf, 4, "Tag: %d\n", pref->route_tag);
2524
2525 if (CHECK_FLAG(pref->flags, LS_PREF_EXTENDED_TAG))
2526 sbuf_push(&sbuf, 4, "Extended Tag: %" PRIu64 "\n",
2527 pref->extended_tag);
2528
2529 if (CHECK_FLAG(pref->flags, LS_PREF_SR))
2530 sbuf_push(&sbuf, 4, "SID: %d\tAlgorithm: %d\tFlags: 0x%x\n",
2531 pref->sr.sid, pref->sr.algo, pref->sr.sid_flag);
2532
2533 end:
2534 vty_out(vty, "%s\n", sbuf_buf(&sbuf));
2535 sbuf_free(&sbuf);
2536 }
2537
2538 static void ls_show_subnet_json(struct ls_subnet *subnet,
2539 struct json_object *json)
2540 {
2541 struct ls_prefix *pref;
2542 json_object *jsr;
2543 char buf[INET6_BUFSIZ];
2544
2545 pref = subnet->ls_pref;
2546
2547 snprintfrr(buf, INET6_BUFSIZ, "%pFX", &subnet->key);
2548 json_object_string_add(json, "subnet-id", buf);
2549 json_object_string_add(json, "status", status2txt[subnet->status]);
2550 json_object_string_add(json, "origin", origin2txt[pref->adv.origin]);
2551 ls_node_id_to_text(pref->adv, buf, INET6_BUFSIZ);
2552 json_object_string_add(json, "advertised-router", buf);
2553 if (subnet->vertex)
2554 json_object_int_add(json, "vertex-id", subnet->vertex->key);
2555 json_object_int_add(json, "metric", pref->metric);
2556 if (CHECK_FLAG(pref->flags, LS_PREF_IGP_FLAG)) {
2557 snprintfrr(buf, INET6_BUFSIZ, "0x%x", pref->igp_flag);
2558 json_object_string_add(json, "flags", buf);
2559 }
2560 if (CHECK_FLAG(pref->flags, LS_PREF_ROUTE_TAG))
2561 json_object_int_add(json, "tag", pref->route_tag);
2562 if (CHECK_FLAG(pref->flags, LS_PREF_EXTENDED_TAG))
2563 json_object_int_add(json, "extended-tag", pref->extended_tag);
2564 if (CHECK_FLAG(pref->flags, LS_PREF_SR)) {
2565 jsr = json_object_new_object();
2566 json_object_object_add(json, "segment-routing", jsr);
2567 json_object_int_add(jsr, "pref-sid", pref->sr.sid);
2568 json_object_int_add(jsr, "algo", pref->sr.algo);
2569 snprintfrr(buf, INET6_BUFSIZ, "0x%x", pref->sr.sid_flag);
2570 json_object_string_add(jsr, "flags", buf);
2571 }
2572 }
2573
2574 void ls_show_subnet(struct ls_subnet *subnet, struct vty *vty,
2575 struct json_object *json, bool verbose)
2576 {
2577 /* Sanity Check */
2578 if (!subnet)
2579 return;
2580
2581 if (json)
2582 ls_show_subnet_json(subnet, json);
2583 else if (vty)
2584 ls_show_subnet_vty(subnet, vty, verbose);
2585 }
2586
2587 void ls_show_subnets(struct ls_ted *ted, struct vty *vty,
2588 struct json_object *json, bool verbose)
2589 {
2590 struct ls_subnet *subnet;
2591 json_object *jsubs, *jsub;
2592
2593 if (json) {
2594 jsubs = json_object_new_array();
2595 json_object_object_add(json, "subnets", jsubs);
2596 frr_each (subnets, &ted->subnets, subnet) {
2597 jsub = json_object_new_object();
2598 ls_show_subnet(subnet, NULL, jsub, verbose);
2599 json_object_array_add(jsubs, jsub);
2600 }
2601 } else if (vty) {
2602 frr_each (subnets, &ted->subnets, subnet)
2603 ls_show_subnet(subnet, vty, NULL, verbose);
2604 }
2605 }
2606
2607 void ls_show_ted(struct ls_ted *ted, struct vty *vty, struct json_object *json,
2608 bool verbose)
2609 {
2610 json_object *jted;
2611
2612 if (json) {
2613 jted = json_object_new_object();
2614 json_object_object_add(json, "ted", jted);
2615 json_object_string_add(jted, "name", ted->name);
2616 json_object_int_add(jted, "key", ted->key);
2617 json_object_int_add(jted, "verticesCount",
2618 vertices_count(&ted->vertices));
2619 json_object_int_add(jted, "edgesCount",
2620 edges_count(&ted->edges));
2621 json_object_int_add(jted, "subnetsCount",
2622 subnets_count(&ted->subnets));
2623 ls_show_vertices(ted, NULL, jted, verbose);
2624 ls_show_edges(ted, NULL, jted, verbose);
2625 ls_show_subnets(ted, NULL, jted, verbose);
2626 return;
2627 }
2628
2629 if (vty) {
2630 vty_out(vty,
2631 "\n\tTraffic Engineering Database: %s (key: %d)\n\n",
2632 ted->name, ted->key);
2633 ls_show_vertices(ted, vty, NULL, verbose);
2634 ls_show_edges(ted, vty, NULL, verbose);
2635 ls_show_subnets(ted, vty, NULL, verbose);
2636 vty_out(vty,
2637 "\n\tTotal: %zu Vertices, %zu Edges, %zu Subnets\n\n",
2638 vertices_count(&ted->vertices),
2639 edges_count(&ted->edges), subnets_count(&ted->subnets));
2640 }
2641 }
2642
2643 void ls_dump_ted(struct ls_ted *ted)
2644 {
2645 struct ls_vertex *vertex;
2646 struct ls_edge *edge;
2647 struct ls_subnet *subnet;
2648 const struct in_addr inaddr_any = {.s_addr = INADDR_ANY};
2649
2650 zlog_debug("(%s) Ted init", __func__);
2651
2652 /* Loop TED, start printing Node, then Attributes and finally Prefix */
2653 frr_each (vertices, &ted->vertices, vertex) {
2654 zlog_debug(" Ted node (%s %pI4 %s)",
2655 vertex->node->name[0] ? vertex->node->name
2656 : "no name node",
2657 &vertex->node->router_id,
2658 origin2txt[vertex->node->adv.origin]);
2659 struct listnode *lst_node;
2660 struct ls_edge *vertex_edge;
2661
2662 for (ALL_LIST_ELEMENTS_RO(vertex->incoming_edges, lst_node,
2663 vertex_edge)) {
2664 zlog_debug(
2665 " inc edge key:%" PRIu64 " attr key:%pI4 loc:(%pI4) rmt:(%pI4)",
2666 vertex_edge->key,
2667 &vertex_edge->attributes->adv.id.ip.addr,
2668 &vertex_edge->attributes->standard.local,
2669 &vertex_edge->attributes->standard.remote);
2670 }
2671 for (ALL_LIST_ELEMENTS_RO(vertex->outgoing_edges, lst_node,
2672 vertex_edge)) {
2673 zlog_debug(
2674 " out edge key:%" PRIu64 " attr key:%pI4 loc:(%pI4) rmt:(%pI4)",
2675 vertex_edge->key,
2676 &vertex_edge->attributes->adv.id.ip.addr,
2677 &vertex_edge->attributes->standard.local,
2678 &vertex_edge->attributes->standard.remote);
2679 }
2680 }
2681 frr_each (edges, &ted->edges, edge) {
2682 zlog_debug(" Ted edge key:%" PRIu64 "src:%pI4 dst:%pI4", edge->key,
2683 edge->source ? &edge->source->node->router_id
2684 : &inaddr_any,
2685 edge->destination
2686 ? &edge->destination->node->router_id
2687 : &inaddr_any);
2688 }
2689 frr_each (subnets, &ted->subnets, subnet) {
2690 zlog_debug(" Ted subnet key:%pFX vertex:%pI4",
2691 &subnet->ls_pref->pref,
2692 &subnet->vertex->node->adv.id.ip.addr);
2693 }
2694 zlog_debug("(%s) Ted end", __func__);
2695 }