]> git.proxmox.com Git - mirror_frr.git/blob - ospfd/ospf_ri.c
Merge pull request #2620 from pacovn/PVS-Studio_null_check_2
[mirror_frr.git] / ospfd / ospf_ri.c
1 /*
2 * This is an implementation of RFC4970 Router Information
3 * with support of RFC5088 PCE Capabilites announcement
4 *
5 * Module name: Router Information
6 * Author: Olivier Dugeon <olivier.dugeon@orange.com>
7 * Copyright (C) 2012 - 2017 Orange Labs http://www.orange.com/
8 *
9 * This file is part of GNU Quagga.
10 *
11 * GNU Zebra is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2, or (at your option) any
14 * later version.
15 *
16 * GNU Quagga is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; see the file COPYING; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26 #include <zebra.h>
27 #include <math.h>
28
29 #include "linklist.h"
30 #include "prefix.h"
31 #include "if.h"
32 #include "table.h"
33 #include "memory.h"
34 #include "command.h"
35 #include "vty.h"
36 #include "stream.h"
37 #include "log.h"
38 #include "thread.h"
39 #include "hash.h"
40 #include "sockunion.h" /* for inet_aton() */
41 #include "mpls.h"
42
43 #include "ospfd/ospfd.h"
44 #include "ospfd/ospf_interface.h"
45 #include "ospfd/ospf_ism.h"
46 #include "ospfd/ospf_asbr.h"
47 #include "ospfd/ospf_lsa.h"
48 #include "ospfd/ospf_lsdb.h"
49 #include "ospfd/ospf_neighbor.h"
50 #include "ospfd/ospf_nsm.h"
51 #include "ospfd/ospf_flood.h"
52 #include "ospfd/ospf_packet.h"
53 #include "ospfd/ospf_spf.h"
54 #include "ospfd/ospf_dump.h"
55 #include "ospfd/ospf_route.h"
56 #include "ospfd/ospf_ase.h"
57 #include "ospfd/ospf_zebra.h"
58 #include "ospfd/ospf_sr.h"
59 #include "ospfd/ospf_ri.h"
60
61 /* Store Router Information PCE TLV and SubTLV in network byte order. */
62 struct ospf_pce_info {
63 bool enabled;
64 struct ri_tlv_pce pce_header;
65 struct ri_pce_subtlv_address pce_address;
66 struct ri_pce_subtlv_path_scope pce_scope;
67 struct list *pce_domain;
68 struct list *pce_neighbor;
69 struct ri_pce_subtlv_cap_flag pce_cap_flag;
70 };
71
72 /*
73 * Store Router Information Segment Routing TLV and SubTLV
74 * in network byte order
75 */
76 struct ospf_ri_sr_info {
77 bool enabled;
78 /* Algorithms supported by the node */
79 struct ri_sr_tlv_sr_algorithm algo;
80 /*
81 * Segment Routing Global Block i.e. label range
82 * Only one range supported in this code
83 */
84 struct ri_sr_tlv_sid_label_range range;
85 /* Maximum SID Depth supported by the node */
86 struct ri_sr_tlv_node_msd msd;
87 };
88
89 /* Following structure are internal use only. */
90 struct ospf_router_info {
91 bool enabled;
92
93 uint8_t registered;
94 uint8_t scope;
95
96 /* Flags to manage this router information. */
97 #define RIFLG_LSA_ENGAGED 0x1
98 #define RIFLG_LSA_FORCED_REFRESH 0x2
99 uint32_t flags;
100
101 /* area pointer if flooding is Type 10 Null if flooding is AS scope */
102 struct ospf_area *area;
103 struct in_addr area_id;
104
105 /* Store Router Information Capabilities LSA */
106 struct ri_tlv_router_cap router_cap;
107
108 /* Store PCE capability LSA */
109 struct ospf_pce_info pce_info;
110
111 /* Store SR capability LSA */
112 struct ospf_ri_sr_info sr_info;
113 };
114
115 /*
116 * Global variable to manage Opaque-LSA/Router Information on this node.
117 * Note that all parameter values are stored in network byte order.
118 */
119 static struct ospf_router_info OspfRI;
120
121 /*------------------------------------------------------------------------------*
122 * Followings are initialize/terminate functions for Router Information
123 *handling.
124 *------------------------------------------------------------------------------*/
125
126 static void ospf_router_info_ism_change(struct ospf_interface *oi,
127 int old_status);
128 static void ospf_router_info_nsm_change(struct ospf_neighbor *nbr,
129 int old_status);
130 static void ospf_router_info_config_write_router(struct vty *vty);
131 static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa);
132 static int ospf_router_info_lsa_originate(void *arg);
133 static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa);
134 static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode);
135 static void ospf_router_info_register_vty(void);
136 static int ospf_router_info_lsa_update(struct ospf_lsa *lsa);
137 static void del_pce_info(void *val);
138
139 int ospf_router_info_init(void)
140 {
141
142 zlog_info("RI -> Initialize Router Information");
143
144 memset(&OspfRI, 0, sizeof(struct ospf_router_info));
145 OspfRI.enabled = false;
146 OspfRI.registered = 0;
147 OspfRI.scope = OSPF_OPAQUE_AS_LSA;
148 OspfRI.area_id.s_addr = 0;
149 OspfRI.flags = 0;
150
151 /* Initialize pce domain and neighbor list */
152 OspfRI.pce_info.enabled = false;
153 OspfRI.pce_info.pce_domain = list_new();
154 OspfRI.pce_info.pce_domain->del = del_pce_info;
155 OspfRI.pce_info.pce_neighbor = list_new();
156 OspfRI.pce_info.pce_neighbor->del = del_pce_info;
157
158 /* Initialize Segment Routing information structure */
159 OspfRI.sr_info.enabled = false;
160
161 ospf_router_info_register_vty();
162
163 return 0;
164 }
165
166 static int ospf_router_info_register(uint8_t scope)
167 {
168 int rc = 0;
169
170 if (OspfRI.registered)
171 return rc;
172
173 zlog_info("RI -> Register Router Information with scope %s(%d)",
174 scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS", scope);
175 rc = ospf_register_opaque_functab(
176 scope, OPAQUE_TYPE_ROUTER_INFORMATION_LSA,
177 NULL, /* new interface */
178 NULL, /* del interface */
179 ospf_router_info_ism_change, ospf_router_info_nsm_change,
180 ospf_router_info_config_write_router,
181 NULL, /* Config. write interface */
182 NULL, /* Config. write debug */
183 ospf_router_info_show_info, ospf_router_info_lsa_originate,
184 ospf_router_info_lsa_refresh, ospf_router_info_lsa_update,
185 NULL); /* del_lsa_hook */
186
187 if (rc != 0) {
188 zlog_warn(
189 "ospf_router_info_init: Failed to register functions");
190 return rc;
191 }
192
193 OspfRI.registered = 1;
194 OspfRI.scope = scope;
195 return rc;
196 }
197
198 static int ospf_router_info_unregister()
199 {
200
201 if ((OspfRI.scope != OSPF_OPAQUE_AS_LSA)
202 && (OspfRI.scope != OSPF_OPAQUE_AREA_LSA)) {
203 zlog_warn(
204 "Unable to unregister Router Info functions: Wrong scope!");
205 return -1;
206 }
207
208 ospf_delete_opaque_functab(OspfRI.scope,
209 OPAQUE_TYPE_ROUTER_INFORMATION_LSA);
210
211 OspfRI.registered = 0;
212 return 0;
213 }
214
215 void ospf_router_info_term(void)
216 {
217
218 list_delete_and_null(&OspfRI.pce_info.pce_domain);
219 list_delete_and_null(&OspfRI.pce_info.pce_neighbor);
220
221 OspfRI.enabled = false;
222
223 ospf_router_info_unregister();
224
225 return;
226 }
227
228 void ospf_router_info_finish(void)
229 {
230 list_delete_all_node(OspfRI.pce_info.pce_domain);
231 list_delete_all_node(OspfRI.pce_info.pce_neighbor);
232
233 OspfRI.enabled = false;
234 }
235
236 static void del_pce_info(void *val)
237 {
238 XFREE(MTYPE_OSPF_PCE_PARAMS, val);
239 return;
240 }
241
242 /* Catch RI LSA flooding Scope for ospf_ext.[h,c] code */
243 struct scope_info ospf_router_info_get_flooding_scope(void)
244 {
245 struct scope_info flooding_scope;
246
247 if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) {
248 flooding_scope.scope = OSPF_OPAQUE_AS_LSA;
249 flooding_scope.area_id.s_addr = 0;
250 return flooding_scope;
251 }
252 flooding_scope.scope = OSPF_OPAQUE_AREA_LSA;
253 flooding_scope.area_id.s_addr = OspfRI.area_id.s_addr;
254 return flooding_scope;
255 }
256
257 /*------------------------------------------------------------------------*
258 * Followings are control functions for ROUTER INFORMATION parameters
259 *management.
260 *------------------------------------------------------------------------*/
261
262 static void set_router_info_capabilities(struct ri_tlv_router_cap *ric,
263 uint32_t cap)
264 {
265 ric->header.type = htons(RI_TLV_CAPABILITIES);
266 ric->header.length = htons(RI_TLV_LENGTH);
267 ric->value = htonl(cap);
268 return;
269 }
270
271 static int set_pce_header(struct ospf_pce_info *pce)
272 {
273 uint16_t length = 0;
274 struct listnode *node;
275 struct ri_pce_subtlv_domain *domain;
276 struct ri_pce_subtlv_neighbor *neighbor;
277
278 /* PCE Address */
279 if (ntohs(pce->pce_address.header.type) != 0)
280 length += TLV_SIZE(&pce->pce_address.header);
281
282 /* PCE Path Scope */
283 if (ntohs(pce->pce_scope.header.type) != 0)
284 length += TLV_SIZE(&pce->pce_scope.header);
285
286 /* PCE Domain */
287 for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
288 if (ntohs(domain->header.type) != 0)
289 length += TLV_SIZE(&domain->header);
290 }
291
292 /* PCE Neighbor */
293 for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
294 if (ntohs(neighbor->header.type) != 0)
295 length += TLV_SIZE(&neighbor->header);
296 }
297
298 /* PCE Capabilities */
299 if (ntohs(pce->pce_cap_flag.header.type) != 0)
300 length += TLV_SIZE(&pce->pce_cap_flag.header);
301
302 if (length != 0) {
303 pce->pce_header.header.type = htons(RI_TLV_PCE);
304 pce->pce_header.header.length = htons(length);
305 pce->enabled = true;
306 } else {
307 pce->pce_header.header.type = 0;
308 pce->pce_header.header.length = 0;
309 pce->enabled = false;
310 }
311
312 return length;
313 }
314
315 static void set_pce_address(struct in_addr ipv4, struct ospf_pce_info *pce)
316 {
317
318 /* Enable PCE Info */
319 pce->pce_header.header.type = htons(RI_TLV_PCE);
320 /* Set PCE Address */
321 pce->pce_address.header.type = htons(RI_PCE_SUBTLV_ADDRESS);
322 pce->pce_address.header.length = htons(PCE_ADDRESS_LENGTH_IPV4);
323 pce->pce_address.address.type = htons(PCE_ADDRESS_TYPE_IPV4);
324 pce->pce_address.address.value = ipv4;
325
326 return;
327 }
328
329 static void set_pce_path_scope(uint32_t scope, struct ospf_pce_info *pce)
330 {
331
332 /* Set PCE Scope */
333 pce->pce_scope.header.type = htons(RI_PCE_SUBTLV_PATH_SCOPE);
334 pce->pce_scope.header.length = htons(RI_TLV_LENGTH);
335 pce->pce_scope.value = htonl(scope);
336
337 return;
338 }
339
340 static void set_pce_domain(uint16_t type, uint32_t domain,
341 struct ospf_pce_info *pce)
342 {
343
344 struct ri_pce_subtlv_domain *new;
345
346 /* Create new domain info */
347 new = XCALLOC(MTYPE_OSPF_PCE_PARAMS,
348 sizeof(struct ri_pce_subtlv_domain));
349
350 new->header.type = htons(RI_PCE_SUBTLV_DOMAIN);
351 new->header.length = htons(PCE_ADDRESS_LENGTH_IPV4);
352 new->type = htons(type);
353 new->value = htonl(domain);
354
355 /* Add new domain to the list */
356 listnode_add(pce->pce_domain, new);
357
358 return;
359 }
360
361 static void unset_pce_domain(uint16_t type, uint32_t domain,
362 struct ospf_pce_info *pce)
363 {
364 struct listnode *node;
365 struct ri_pce_subtlv_domain *old = NULL;
366 int found = 0;
367
368 /* Search the corresponding node */
369 for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, old)) {
370 if ((old->type == htons(type))
371 && (old->value == htonl(domain))) {
372 found = 1;
373 break;
374 }
375 }
376
377 /* if found remove it */
378 if (found) {
379 listnode_delete(pce->pce_domain, old);
380
381 /* Avoid misjudgement in the next lookup. */
382 if (listcount(pce->pce_domain) == 0)
383 pce->pce_domain->head = pce->pce_domain->tail = NULL;
384
385 /* Finally free the old domain */
386 XFREE(MTYPE_OSPF_PCE_PARAMS, old);
387 }
388 }
389
390 static void set_pce_neighbor(uint16_t type, uint32_t domain,
391 struct ospf_pce_info *pce)
392 {
393
394 struct ri_pce_subtlv_neighbor *new;
395
396 /* Create new neighbor info */
397 new = XCALLOC(MTYPE_OSPF_PCE_PARAMS,
398 sizeof(struct ri_pce_subtlv_neighbor));
399
400 new->header.type = htons(RI_PCE_SUBTLV_NEIGHBOR);
401 new->header.length = htons(PCE_ADDRESS_LENGTH_IPV4);
402 new->type = htons(type);
403 new->value = htonl(domain);
404
405 /* Add new domain to the list */
406 listnode_add(pce->pce_neighbor, new);
407
408 return;
409 }
410
411 static void unset_pce_neighbor(uint16_t type, uint32_t domain,
412 struct ospf_pce_info *pce)
413 {
414 struct listnode *node;
415 struct ri_pce_subtlv_neighbor *old = NULL;
416 int found = 0;
417
418 /* Search the corresponding node */
419 for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, old)) {
420 if ((old->type == htons(type))
421 && (old->value == htonl(domain))) {
422 found = 1;
423 break;
424 }
425 }
426
427 /* if found remove it */
428 if (found) {
429 listnode_delete(pce->pce_neighbor, old);
430
431 /* Avoid misjudgement in the next lookup. */
432 if (listcount(pce->pce_neighbor) == 0)
433 pce->pce_neighbor->head = pce->pce_neighbor->tail =
434 NULL;
435
436 /* Finally free the old domain */
437 XFREE(MTYPE_OSPF_PCE_PARAMS, old);
438 }
439 }
440
441 static void set_pce_cap_flag(uint32_t cap, struct ospf_pce_info *pce)
442 {
443
444 /* Set PCE Capabilities flag */
445 pce->pce_cap_flag.header.type = htons(RI_PCE_SUBTLV_CAP_FLAG);
446 pce->pce_cap_flag.header.length = htons(RI_TLV_LENGTH);
447 pce->pce_cap_flag.value = htonl(cap);
448
449 return;
450 }
451
452 /* Segment Routing TLV setter */
453
454 /* Algorithm SubTLV - section 3.1 */
455 static void set_sr_algorithm(uint8_t algo)
456 {
457
458 OspfRI.sr_info.algo.value[0] = algo;
459 for (int i = 1; i < ALGORITHM_COUNT; i++)
460 OspfRI.sr_info.algo.value[i] = SR_ALGORITHM_UNSET;
461
462 /* Set TLV type and length == only 1 Algorithm */
463 TLV_TYPE(OspfRI.sr_info.algo) = htons(RI_SR_TLV_SR_ALGORITHM);
464 TLV_LEN(OspfRI.sr_info.algo) = htons(sizeof(uint8_t));
465 }
466
467 /* unset Aglogithm SubTLV */
468 static void unset_sr_algorithm(uint8_t algo)
469 {
470
471 for (int i = 0; i < ALGORITHM_COUNT; i++)
472 OspfRI.sr_info.algo.value[i] = SR_ALGORITHM_UNSET;
473
474 /* Unset TLV type and length */
475 TLV_TYPE(OspfRI.sr_info.algo) = htons(0);
476 TLV_LEN(OspfRI.sr_info.algo) = htons(0);
477 }
478
479 /* Segment Routing Global Block SubTLV - section 3.2 */
480 static void set_sr_sid_label_range(struct sr_srgb srgb)
481 {
482 /* Set Header */
483 TLV_TYPE(OspfRI.sr_info.range) = htons(RI_SR_TLV_SID_LABEL_RANGE);
484 TLV_LEN(OspfRI.sr_info.range) =
485 htons(SUBTLV_SID_LABEL_SIZE + sizeof(uint32_t));
486 /* Set Range Size */
487 OspfRI.sr_info.range.size = htonl(SET_RANGE_SIZE(srgb.range_size));
488 /* Set Lower bound label SubTLV */
489 TLV_TYPE(OspfRI.sr_info.range.lower) = htons(SUBTLV_SID_LABEL);
490 TLV_LEN(OspfRI.sr_info.range.lower) = htons(SID_RANGE_LABEL_LENGTH);
491 OspfRI.sr_info.range.lower.value = htonl(SET_LABEL(srgb.lower_bound));
492 }
493
494 /* Unset this SRGB SubTLV */
495 static void unset_sr_sid_label_range(void)
496 {
497
498 TLV_TYPE(OspfRI.sr_info.range) = htons(0);
499 TLV_LEN(OspfRI.sr_info.range) = htons(0);
500 TLV_TYPE(OspfRI.sr_info.range.lower) = htons(0);
501 TLV_LEN(OspfRI.sr_info.range.lower) = htons(0);
502 }
503
504 /* Set Maximum Stack Depth for this router */
505 static void set_sr_node_msd(uint8_t msd)
506 {
507 TLV_TYPE(OspfRI.sr_info.msd) = htons(RI_SR_TLV_NODE_MSD);
508 TLV_LEN(OspfRI.sr_info.msd) = htons(sizeof(uint32_t));
509 OspfRI.sr_info.msd.value = msd;
510 }
511
512 /* Unset this router MSD */
513 static void unset_sr_node_msd(void)
514 {
515 TLV_TYPE(OspfRI.sr_info.msd) = htons(0);
516 TLV_LEN(OspfRI.sr_info.msd) = htons(0);
517 }
518
519 static void unset_param(void *tlv_buffer)
520 {
521 struct tlv_header *tlv = (struct tlv_header *)tlv_buffer;
522
523 tlv->type = 0;
524 /* Fill the Value to 0 */
525 memset(TLV_DATA(tlv_buffer), 0, TLV_BODY_SIZE(tlv));
526 tlv->length = 0;
527
528 return;
529 }
530
531 static void initialize_params(struct ospf_router_info *ori)
532 {
533 uint32_t cap = 0;
534 struct ospf *top;
535
536 /*
537 * Initialize default Router Information Capabilities.
538 */
539 cap = RI_TE_SUPPORT;
540
541 set_router_info_capabilities(&ori->router_cap, cap);
542
543 /* If Area address is not null and exist, retrieve corresponding
544 * structure */
545 top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
546 zlog_info("RI-> Initialize Router Info for %s scope within area %s",
547 OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS",
548 inet_ntoa(OspfRI.area_id));
549
550 /* Try to get the Area context at this step. Do it latter if not
551 * available */
552 if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL))
553 OspfRI.area = ospf_area_lookup_by_area_id(top, OspfRI.area_id);
554
555 /*
556 * Initialize default PCE Information values
557 */
558 /* PCE address == OSPF Router ID */
559 set_pce_address(top->router_id, &ori->pce_info);
560
561 /* PCE scope */
562 cap = 7; /* Set L, R and Rd bits to one = intra & inter-area path
563 computation */
564 set_pce_path_scope(cap, &ori->pce_info);
565
566 /* PCE Capabilities */
567 cap = PCE_CAP_BIDIRECTIONAL | PCE_CAP_DIVERSE_PATH | PCE_CAP_OBJECTIVES
568 | PCE_CAP_ADDITIVE | PCE_CAP_MULTIPLE_REQ;
569 set_pce_cap_flag(cap, &ori->pce_info);
570
571 return;
572 }
573
574 static int is_mandated_params_set(struct ospf_router_info ori)
575 {
576 int rc = 0;
577
578 if (ntohs(ori.router_cap.header.type) == 0)
579 return rc;
580
581 if ((ntohs(ori.pce_info.pce_header.header.type) == RI_TLV_PCE)
582 && (ntohs(ori.pce_info.pce_address.header.type) == 0)
583 && (ntohs(ori.pce_info.pce_cap_flag.header.type) == 0))
584 return rc;
585
586 if ((ori.sr_info.enabled) && (ntohs(TLV_TYPE(ori.sr_info.algo)) == 0)
587 && (ntohs(TLV_TYPE(ori.sr_info.range)) == 0))
588 return rc;
589
590 rc = 1;
591
592 return rc;
593 }
594
595 /*
596 * Used by Segment Routing to set new TLVs and Sub-TLVs values
597 *
598 * @param enable To activate or not Segment Routing router Information flooding
599 * @param size Size of Label Range i.e. SRGB size
600 * @param lower Lower bound of the Label Range i.e. SRGB first label
601 * @param msd Maximum label Stack Depth suported by the router
602 *
603 * @return none
604 */
605 void ospf_router_info_update_sr(bool enable, struct sr_srgb srgb, uint8_t msd)
606 {
607
608 /* First activate and initialize Router Information is necessary */
609 if (!OspfRI.enabled) {
610 OspfRI.enabled = true;
611 initialize_params(&OspfRI);
612 }
613
614 if (IS_DEBUG_OSPF_SR)
615 zlog_debug("RI-> %s Routing Information for Segment Routing",
616 enable ? "Enable" : "Disable");
617
618 /* Unset or Set SR parameters */
619 if (!enable) {
620 unset_sr_algorithm(SR_ALGORITHM_SPF);
621 unset_sr_sid_label_range();
622 unset_sr_node_msd();
623 OspfRI.sr_info.enabled = false;
624 } else {
625 // Only SR_ALGORITHM_SPF is supported
626 set_sr_algorithm(SR_ALGORITHM_SPF);
627 set_sr_sid_label_range(srgb);
628 if (msd != 0)
629 set_sr_node_msd(msd);
630 else
631 unset_sr_node_msd();
632 OspfRI.sr_info.enabled = true;
633 }
634
635 /* Refresh if already engaged or originate RI LSA */
636 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
637 ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
638 else
639 ospf_router_info_lsa_schedule(REORIGINATE_THIS_LSA);
640 }
641
642 /*------------------------------------------------------------------------*
643 * Followings are callback functions against generic Opaque-LSAs handling.
644 *------------------------------------------------------------------------*/
645 static void ospf_router_info_ism_change(struct ospf_interface *oi,
646 int old_state)
647 {
648 /* So far, nothing to do here. */
649 return;
650 }
651
652 static void ospf_router_info_nsm_change(struct ospf_neighbor *nbr,
653 int old_state)
654 {
655 /* So far, nothing to do here. */
656 return;
657 }
658
659 /*------------------------------------------------------------------------*
660 * Followings are OSPF protocol processing functions for ROUTER INFORMATION
661 *------------------------------------------------------------------------*/
662
663 static void build_tlv_header(struct stream *s, struct tlv_header *tlvh)
664 {
665
666 stream_put(s, tlvh, sizeof(struct tlv_header));
667 return;
668 }
669
670 static void build_tlv(struct stream *s, struct tlv_header *tlvh)
671 {
672
673 if (ntohs(tlvh->type) != 0) {
674 build_tlv_header(s, tlvh);
675 stream_put(s, TLV_DATA(tlvh), TLV_BODY_SIZE(tlvh));
676 }
677 return;
678 }
679
680 static void ospf_router_info_lsa_body_set(struct stream *s)
681 {
682
683 struct listnode *node;
684 struct ri_pce_subtlv_domain *domain;
685 struct ri_pce_subtlv_neighbor *neighbor;
686
687 /* Build Router Information TLV */
688 build_tlv(s, &OspfRI.router_cap.header);
689
690 /* Build Segment Routing TLVs if enabled */
691 if (OspfRI.sr_info.enabled) {
692 /* Build Algorithm TLV */
693 build_tlv(s, &TLV_HDR(OspfRI.sr_info.algo));
694 /* Build SRGB TLV */
695 build_tlv(s, &TLV_HDR(OspfRI.sr_info.range));
696 /* Build MSD TLV */
697 build_tlv(s, &TLV_HDR(OspfRI.sr_info.msd));
698 }
699
700 /* Add RI PCE TLV if it is set */
701 if (OspfRI.pce_info.enabled) {
702
703 /* Compute PCE Info header first */
704 set_pce_header(&OspfRI.pce_info);
705
706 /* Build PCE TLV */
707 build_tlv_header(s, &OspfRI.pce_info.pce_header.header);
708
709 /* Build PCE address sub-tlv */
710 build_tlv(s, &OspfRI.pce_info.pce_address.header);
711
712 /* Build PCE path scope sub-tlv */
713 build_tlv(s, &OspfRI.pce_info.pce_scope.header);
714
715 /* Build PCE domain sub-tlv */
716 for (ALL_LIST_ELEMENTS_RO(OspfRI.pce_info.pce_domain, node,
717 domain))
718 build_tlv(s, &domain->header);
719
720 /* Build PCE neighbor sub-tlv */
721 for (ALL_LIST_ELEMENTS_RO(OspfRI.pce_info.pce_neighbor, node,
722 neighbor))
723 build_tlv(s, &neighbor->header);
724
725 /* Build PCE cap flag sub-tlv */
726 build_tlv(s, &OspfRI.pce_info.pce_cap_flag.header);
727 }
728
729 return;
730 }
731
732 /* Create new opaque-LSA. */
733 static struct ospf_lsa *ospf_router_info_lsa_new()
734 {
735 struct ospf *top;
736 struct stream *s;
737 struct lsa_header *lsah;
738 struct ospf_lsa *new = NULL;
739 uint8_t options, lsa_type;
740 struct in_addr lsa_id;
741 uint32_t tmp;
742 uint16_t length;
743
744 /* Create a stream for LSA. */
745 if ((s = stream_new(OSPF_MAX_LSA_SIZE)) == NULL) {
746 zlog_warn("ospf_router_info_lsa_new: stream_new() ?");
747 return NULL;
748 }
749 lsah = (struct lsa_header *)STREAM_DATA(s);
750
751 options = OSPF_OPTION_E; /* Enable AS external as we flood RI with
752 Opaque Type 11 */
753 options |= OSPF_OPTION_O; /* Don't forget this :-) */
754
755 lsa_type = OspfRI.scope;
756 /* LSA ID == 0 for Router Information see RFC 4970 */
757 tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_ROUTER_INFORMATION_LSA, 0);
758 lsa_id.s_addr = htonl(tmp);
759
760 if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
761 zlog_debug(
762 "LSA[Type%d:%s]: Create an Opaque-LSA/ROUTER INFORMATION instance",
763 lsa_type, inet_ntoa(lsa_id));
764
765 top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
766
767 /* Set opaque-LSA header fields. */
768 lsa_header_set(s, options, lsa_type, lsa_id, top->router_id);
769
770 /* Set opaque-LSA body fields. */
771 ospf_router_info_lsa_body_set(s);
772
773 /* Set length. */
774 length = stream_get_endp(s);
775 lsah->length = htons(length);
776
777 /* Now, create an OSPF LSA instance. */
778 if ((new = ospf_lsa_new()) == NULL) {
779 zlog_warn("ospf_router_info_lsa_new: ospf_lsa_new() ?");
780 stream_free(s);
781 return NULL;
782 }
783 if ((new->data = ospf_lsa_data_new(length)) == NULL) {
784 zlog_warn("ospf_router_info_lsa_new: ospf_lsa_data_new() ?");
785 ospf_lsa_unlock(&new);
786 new = NULL;
787 stream_free(s);
788 return new;
789 }
790
791 new->area = OspfRI.area; /* Area must be null if the Opaque type is AS
792 scope, fulfill otherwise */
793
794 if (new->area && new->area->ospf)
795 new->vrf_id = new->area->ospf->vrf_id;
796 else
797 new->vrf_id = VRF_DEFAULT;
798
799 SET_FLAG(new->flags, OSPF_LSA_SELF);
800 memcpy(new->data, lsah, length);
801 stream_free(s);
802
803 return new;
804 }
805
806 static int ospf_router_info_lsa_originate1(void *arg)
807 {
808 struct ospf_lsa *new;
809 struct ospf *top;
810 struct ospf_area *area;
811 int rc = -1;
812 vrf_id_t vrf_id = VRF_DEFAULT;
813
814 /* First check if the area is known if flooding scope is Area */
815 if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) {
816 area = (struct ospf_area *)arg;
817 if (area->area_id.s_addr != OspfRI.area_id.s_addr) {
818 zlog_debug(
819 "RI -> This is not the Router Information Area. Stop processing");
820 return rc;
821 }
822 OspfRI.area = area;
823 if (area->ospf)
824 vrf_id = area->ospf->vrf_id;
825 }
826
827 /* Create new Opaque-LSA/ROUTER INFORMATION instance. */
828 if ((new = ospf_router_info_lsa_new()) == NULL) {
829 zlog_warn(
830 "ospf_router_info_lsa_originate1: ospf_router_info_lsa_new() ?");
831 return rc;
832 }
833 new->vrf_id = vrf_id;
834
835 /* Get ospf info */
836 top = ospf_lookup_by_vrf_id(vrf_id);
837 if (top == NULL) {
838 zlog_debug("%s: ospf instance not found for vrf id %u",
839 __PRETTY_FUNCTION__, vrf_id);
840 ospf_lsa_unlock(&new);
841 return rc;
842 }
843
844 /* Install this LSA into LSDB. */
845 if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
846 zlog_warn(
847 "ospf_router_info_lsa_originate1: ospf_lsa_install() ?");
848 ospf_lsa_unlock(&new);
849 return rc;
850 }
851
852 /* Now this Router Info parameter entry has associated LSA. */
853 SET_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED);
854
855 /* Update new LSA origination count. */
856 top->lsa_originate_count++;
857
858 /* Flood new LSA through AS. */
859 if (OspfRI.scope == OSPF_OPAQUE_AS_LSA)
860 ospf_flood_through_as(top, NULL /*nbr */, new);
861 else
862 ospf_flood_through_area(OspfRI.area, NULL /*nbr */, new);
863
864 if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
865 zlog_debug(
866 "LSA[Type%d:%s]: Originate Opaque-LSA/ROUTER INFORMATION",
867 new->data->type, inet_ntoa(new->data->id));
868 ospf_lsa_header_dump(new->data);
869 }
870
871 rc = 0;
872 return rc;
873 }
874
875 static int ospf_router_info_lsa_originate(void *arg)
876 {
877
878 int rc = -1;
879
880 if (!OspfRI.enabled) {
881 zlog_info(
882 "ospf_router_info_lsa_originate: ROUTER INFORMATION is disabled now.");
883 rc = 0; /* This is not an error case. */
884 return rc;
885 }
886
887 /* Check if Router Information LSA is already engaged */
888 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED)) {
889 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_FORCED_REFRESH)) {
890 UNSET_FLAG(OspfRI.flags, RIFLG_LSA_FORCED_REFRESH);
891 ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
892 }
893 } else {
894 if (!is_mandated_params_set(OspfRI))
895 zlog_warn(
896 "ospf_router_info_lsa_originate: lacks mandated ROUTER INFORMATION parameters");
897
898 /* Ok, let's try to originate an LSA */
899 if (ospf_router_info_lsa_originate1(arg) != 0)
900 return rc;
901 }
902
903 rc = 0;
904 return rc;
905 }
906
907 static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
908 {
909 struct ospf_lsa *new = NULL;
910 struct ospf *top;
911
912 if (!OspfRI.enabled) {
913 /*
914 * This LSA must have flushed before due to ROUTER INFORMATION
915 * status change.
916 * It seems a slip among routers in the routing domain.
917 */
918 zlog_info(
919 "ospf_router_info_lsa_refresh: ROUTER INFORMATION is disabled now.");
920 lsa->data->ls_age =
921 htons(OSPF_LSA_MAXAGE); /* Flush it anyway. */
922 }
923
924 /* Verify that the Router Information ID is supported */
925 if (GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr)) != 0) {
926 zlog_warn(
927 "ospf_router_info_lsa_refresh: Unsupported Router Information ID");
928 return NULL;
929 }
930
931 /* If the lsa's age reached to MaxAge, start flushing procedure. */
932 if (IS_LSA_MAXAGE(lsa)) {
933 UNSET_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED);
934 ospf_opaque_lsa_flush_schedule(lsa);
935 return NULL;
936 }
937
938 /* Create new Opaque-LSA/ROUTER INFORMATION instance. */
939 if ((new = ospf_router_info_lsa_new()) == NULL) {
940 zlog_warn(
941 "ospf_router_info_lsa_refresh: ospf_router_info_lsa_new() ?");
942 return NULL;
943 }
944 new->data->ls_seqnum = lsa_seqnum_increment(lsa);
945 new->vrf_id = lsa->vrf_id;
946
947 /* Install this LSA into LSDB. */
948 /* Given "lsa" will be freed in the next function. */
949 top = ospf_lookup_by_vrf_id(lsa->vrf_id);
950 if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
951 zlog_warn("ospf_router_info_lsa_refresh: ospf_lsa_install() ?");
952 ospf_lsa_unlock(&new);
953 return new;
954 }
955
956 /* Flood updated LSA through AS or AREA depending of OspfRI.scope. */
957 if (OspfRI.scope == OSPF_OPAQUE_AS_LSA)
958 ospf_flood_through_as(top, NULL /*nbr */, new);
959 else
960 ospf_flood_through_area(OspfRI.area, NULL /*nbr */, new);
961
962 /* Debug logging. */
963 if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
964 zlog_debug(
965 "LSA[Type%d:%s]: Refresh Opaque-LSA/ROUTER INFORMATION",
966 new->data->type, inet_ntoa(new->data->id));
967 ospf_lsa_header_dump(new->data);
968 }
969
970 return new;
971 }
972
973 static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode)
974 {
975 struct ospf_lsa lsa;
976 struct lsa_header lsah;
977 struct ospf *top;
978 uint32_t tmp;
979
980 memset(&lsa, 0, sizeof(lsa));
981 memset(&lsah, 0, sizeof(lsah));
982
983 zlog_debug("RI-> LSA schedule %s%s%s",
984 opcode == REORIGINATE_THIS_LSA ? "Re-Originate" : "",
985 opcode == REFRESH_THIS_LSA ? "Refresh" : "",
986 opcode == FLUSH_THIS_LSA ? "Flush" : "");
987
988 /* Check LSA flags state coherence */
989 if (!CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED)
990 && (opcode != REORIGINATE_THIS_LSA))
991 return;
992
993 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED)
994 && (opcode == REORIGINATE_THIS_LSA))
995 opcode = REFRESH_THIS_LSA;
996
997 top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
998 if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) {
999 zlog_warn(
1000 "ospf_router_info_lsa_schedule(): Router Info is Area scope flooding but area is not set");
1001 OspfRI.area = ospf_area_lookup_by_area_id(top, OspfRI.area_id);
1002 }
1003 lsa.area = OspfRI.area;
1004 lsa.data = &lsah;
1005 lsah.type = OspfRI.scope;
1006
1007 /* LSA ID is set to 0 for the Router Information. See RFC 4970 */
1008 tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_ROUTER_INFORMATION_LSA, 0);
1009 lsah.id.s_addr = htonl(tmp);
1010
1011 switch (opcode) {
1012 case REORIGINATE_THIS_LSA:
1013 if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA)
1014 ospf_opaque_lsa_reoriginate_schedule(
1015 (void *)OspfRI.area, OSPF_OPAQUE_AREA_LSA,
1016 OPAQUE_TYPE_ROUTER_INFORMATION_LSA);
1017 else
1018 ospf_opaque_lsa_reoriginate_schedule(
1019 (void *)top, OSPF_OPAQUE_AS_LSA,
1020 OPAQUE_TYPE_ROUTER_INFORMATION_LSA);
1021 break;
1022 case REFRESH_THIS_LSA:
1023 ospf_opaque_lsa_refresh_schedule(&lsa);
1024 break;
1025 case FLUSH_THIS_LSA:
1026 UNSET_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED);
1027 ospf_opaque_lsa_flush_schedule(&lsa);
1028 break;
1029 default:
1030 zlog_warn("ospf_router_info_lsa_schedule: Unknown opcode (%u)",
1031 opcode);
1032 break;
1033 }
1034
1035 return;
1036 }
1037
1038 /* Callback to handle Segment Routing information */
1039 static int ospf_router_info_lsa_update(struct ospf_lsa *lsa)
1040 {
1041
1042 /* Sanity Check */
1043 if (lsa == NULL) {
1044 zlog_warn("OSPF-RI (%s): Abort! LSA is NULL", __func__);
1045 return -1;
1046 }
1047
1048 /* Process only Opaque LSA */
1049 if ((lsa->data->type != OSPF_OPAQUE_AREA_LSA)
1050 && (lsa->data->type != OSPF_OPAQUE_AS_LSA))
1051 return 0;
1052
1053 /* Process only Router Information LSA */
1054 if (GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr))
1055 != OPAQUE_TYPE_ROUTER_INFORMATION_LSA)
1056 return 0;
1057
1058 /* Check if it is not my LSA */
1059 if (IS_LSA_SELF(lsa))
1060 return 0;
1061
1062 /* Check if Router Info & Segment Routing are enable */
1063 if (!OspfRI.enabled || !OspfRI.sr_info.enabled)
1064 return 0;
1065
1066 /* Call Segment Routing LSA update or deletion */
1067 if (!IS_LSA_MAXAGE(lsa))
1068 ospf_sr_ri_lsa_update(lsa);
1069 else
1070 ospf_sr_ri_lsa_delete(lsa);
1071
1072 return 0;
1073 }
1074
1075 /*------------------------------------------------------------------------*
1076 * Followings are vty session control functions.
1077 *------------------------------------------------------------------------*/
1078
1079 static uint16_t show_vty_router_cap(struct vty *vty, struct tlv_header *tlvh)
1080 {
1081 struct ri_tlv_router_cap *top = (struct ri_tlv_router_cap *)tlvh;
1082
1083 if (vty != NULL)
1084 vty_out(vty, " Router Capabilities: 0x%x\n",
1085 ntohl(top->value));
1086 else
1087 zlog_debug(" Router Capabilities: 0x%x", ntohl(top->value));
1088
1089 return TLV_SIZE(tlvh);
1090 }
1091
1092 static uint16_t show_vty_pce_subtlv_address(struct vty *vty,
1093 struct tlv_header *tlvh)
1094 {
1095 struct ri_pce_subtlv_address *top =
1096 (struct ri_pce_subtlv_address *)tlvh;
1097
1098 if (ntohs(top->address.type) == PCE_ADDRESS_TYPE_IPV4) {
1099 if (vty != NULL)
1100 vty_out(vty, " PCE Address: %s\n",
1101 inet_ntoa(top->address.value));
1102 else
1103 zlog_debug(" PCE Address: %s",
1104 inet_ntoa(top->address.value));
1105 } else {
1106 /* TODO: Add support to IPv6 with inet_ntop() */
1107 if (vty != NULL)
1108 vty_out(vty, " PCE Address: 0x%x\n",
1109 ntohl(top->address.value.s_addr));
1110 else
1111 zlog_debug(" PCE Address: 0x%x",
1112 ntohl(top->address.value.s_addr));
1113 }
1114
1115 return TLV_SIZE(tlvh);
1116 }
1117
1118 static uint16_t show_vty_pce_subtlv_path_scope(struct vty *vty,
1119 struct tlv_header *tlvh)
1120 {
1121 struct ri_pce_subtlv_path_scope *top =
1122 (struct ri_pce_subtlv_path_scope *)tlvh;
1123
1124 if (vty != NULL)
1125 vty_out(vty, " PCE Path Scope: 0x%x\n", ntohl(top->value));
1126 else
1127 zlog_debug(" PCE Path Scope: 0x%x", ntohl(top->value));
1128
1129 return TLV_SIZE(tlvh);
1130 }
1131
1132 static uint16_t show_vty_pce_subtlv_domain(struct vty *vty,
1133 struct tlv_header *tlvh)
1134 {
1135 struct ri_pce_subtlv_domain *top = (struct ri_pce_subtlv_domain *)tlvh;
1136 struct in_addr tmp;
1137
1138 if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) {
1139 tmp.s_addr = top->value;
1140 if (vty != NULL)
1141 vty_out(vty, " PCE domain Area: %s\n", inet_ntoa(tmp));
1142 else
1143 zlog_debug(" PCE domain Area: %s", inet_ntoa(tmp));
1144 } else {
1145 if (vty != NULL)
1146 vty_out(vty, " PCE domain AS: %d\n",
1147 ntohl(top->value));
1148 else
1149 zlog_debug(" PCE domain AS: %d", ntohl(top->value));
1150 }
1151 return TLV_SIZE(tlvh);
1152 }
1153
1154 static uint16_t show_vty_pce_subtlv_neighbor(struct vty *vty,
1155 struct tlv_header *tlvh)
1156 {
1157
1158 struct ri_pce_subtlv_neighbor *top =
1159 (struct ri_pce_subtlv_neighbor *)tlvh;
1160 struct in_addr tmp;
1161
1162 if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) {
1163 tmp.s_addr = top->value;
1164 if (vty != NULL)
1165 vty_out(vty, " PCE neighbor Area: %s\n",
1166 inet_ntoa(tmp));
1167 else
1168 zlog_debug(" PCE neighbor Area: %s", inet_ntoa(tmp));
1169 } else {
1170 if (vty != NULL)
1171 vty_out(vty, " PCE neighbor AS: %d\n",
1172 ntohl(top->value));
1173 else
1174 zlog_debug(" PCE neighbor AS: %d",
1175 ntohl(top->value));
1176 }
1177 return TLV_SIZE(tlvh);
1178 }
1179
1180 static uint16_t show_vty_pce_subtlv_cap_flag(struct vty *vty,
1181 struct tlv_header *tlvh)
1182 {
1183 struct ri_pce_subtlv_cap_flag *top =
1184 (struct ri_pce_subtlv_cap_flag *)tlvh;
1185
1186 if (vty != NULL)
1187 vty_out(vty, " PCE Capabilities Flag: 0x%x\n",
1188 ntohl(top->value));
1189 else
1190 zlog_debug(" PCE Capabilities Flag: 0x%x",
1191 ntohl(top->value));
1192
1193 return TLV_SIZE(tlvh);
1194 }
1195
1196 static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh)
1197 {
1198 if (vty != NULL)
1199 vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
1200 ntohs(tlvh->type), ntohs(tlvh->length));
1201 else
1202 zlog_debug(" Unknown TLV: [type(0x%x), length(0x%x)]",
1203 ntohs(tlvh->type), ntohs(tlvh->length));
1204
1205 return TLV_SIZE(tlvh);
1206 }
1207
1208 static uint16_t show_vty_pce_info(struct vty *vty, struct tlv_header *ri,
1209 uint32_t total)
1210 {
1211 struct tlv_header *tlvh;
1212 uint16_t sum = 0;
1213
1214 for (tlvh = ri; sum < total; tlvh = TLV_HDR_NEXT(tlvh)) {
1215 switch (ntohs(tlvh->type)) {
1216 case RI_PCE_SUBTLV_ADDRESS:
1217 sum += show_vty_pce_subtlv_address(vty, tlvh);
1218 break;
1219 case RI_PCE_SUBTLV_PATH_SCOPE:
1220 sum += show_vty_pce_subtlv_path_scope(vty, tlvh);
1221 break;
1222 case RI_PCE_SUBTLV_DOMAIN:
1223 sum += show_vty_pce_subtlv_domain(vty, tlvh);
1224 break;
1225 case RI_PCE_SUBTLV_NEIGHBOR:
1226 sum += show_vty_pce_subtlv_neighbor(vty, tlvh);
1227 break;
1228 case RI_PCE_SUBTLV_CAP_FLAG:
1229 sum += show_vty_pce_subtlv_cap_flag(vty, tlvh);
1230 break;
1231 default:
1232 sum += show_vty_unknown_tlv(vty, tlvh);
1233 break;
1234 }
1235 }
1236 return sum;
1237 }
1238
1239 /* Display Segment Routing Algorithm TLV information */
1240 static uint16_t show_vty_sr_algorithm(struct vty *vty, struct tlv_header *tlvh)
1241 {
1242 struct ri_sr_tlv_sr_algorithm *algo =
1243 (struct ri_sr_tlv_sr_algorithm *)tlvh;
1244 int i;
1245
1246 if (vty != NULL) {
1247 vty_out(vty, " Segment Routing Algorithm TLV:\n");
1248 for (i = 0; i < ntohs(algo->header.length); i++) {
1249 switch (algo->value[i]) {
1250 case 0:
1251 vty_out(vty, " Algorithm %d: SPF\n", i);
1252 break;
1253 case 1:
1254 vty_out(vty, " Algorithm %d: Strict SPF\n",
1255 i);
1256 break;
1257 default:
1258 vty_out(vty,
1259 " Algorithm %d: Unknown value %d\n", i,
1260 algo->value[i]);
1261 break;
1262 }
1263 }
1264 }
1265
1266 else {
1267 zlog_debug(" Segment Routing Algorithm TLV:\n");
1268 for (i = 0; i < ntohs(algo->header.length); i++)
1269 switch (algo->value[i]) {
1270 case 0:
1271 zlog_debug(" Algorithm %d: SPF\n", i);
1272 break;
1273 case 1:
1274 zlog_debug(" Algorithm %d: Strict SPF\n", i);
1275 break;
1276 default:
1277 zlog_debug(
1278 " Algorithm %d: Unknown value %d\n",
1279 i, algo->value[i]);
1280 break;
1281 }
1282 }
1283
1284 return TLV_SIZE(tlvh);
1285 }
1286
1287 /* Display Segment Routing SID/Label Range TLV information */
1288 static uint16_t show_vty_sr_range(struct vty *vty, struct tlv_header *tlvh)
1289 {
1290 struct ri_sr_tlv_sid_label_range *range =
1291 (struct ri_sr_tlv_sid_label_range *)tlvh;
1292
1293 if (vty != NULL) {
1294 vty_out(vty,
1295 " Segment Routing Range TLV:\n"
1296 " Range Size = %d\n"
1297 " SID Label = %d\n\n",
1298 GET_RANGE_SIZE(ntohl(range->size)),
1299 GET_LABEL(ntohl(range->lower.value)));
1300 } else {
1301 zlog_debug(
1302 " Segment Routing Range TLV:\n"
1303 " Range Size = %d\n"
1304 " SID Label = %d\n\n",
1305 GET_RANGE_SIZE(ntohl(range->size)),
1306 GET_LABEL(ntohl(range->lower.value)));
1307 }
1308
1309 return TLV_SIZE(tlvh);
1310 }
1311
1312 /* Display Segment Routing Maximum Stack Depth TLV information */
1313 static uint16_t show_vty_sr_msd(struct vty *vty, struct tlv_header *tlvh)
1314 {
1315 struct ri_sr_tlv_node_msd *msd = (struct ri_sr_tlv_node_msd *)tlvh;
1316
1317 if (vty != NULL) {
1318 vty_out(vty,
1319 " Segment Routing MSD TLV:\n"
1320 " Node Maximum Stack Depth = %d\n",
1321 msd->value);
1322 } else {
1323 zlog_debug(
1324 " Segment Routing MSD TLV:\n"
1325 " Node Maximum Stack Depth = %d\n",
1326 msd->value);
1327 }
1328
1329 return TLV_SIZE(tlvh);
1330 }
1331
1332 static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa)
1333 {
1334 struct lsa_header *lsah = (struct lsa_header *)lsa->data;
1335 struct tlv_header *tlvh;
1336 uint16_t length = 0, sum = 0;
1337
1338 /* Initialize TLV browsing */
1339 length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
1340
1341 for (tlvh = TLV_HDR_TOP(lsah); sum < length;
1342 tlvh = TLV_HDR_NEXT(tlvh)) {
1343 switch (ntohs(tlvh->type)) {
1344 case RI_TLV_CAPABILITIES:
1345 sum += show_vty_router_cap(vty, tlvh);
1346 break;
1347 case RI_TLV_PCE:
1348 tlvh++;
1349 sum += TLV_HDR_SIZE;
1350 sum += show_vty_pce_info(vty, tlvh, length - sum);
1351 break;
1352 case RI_SR_TLV_SR_ALGORITHM:
1353 sum += show_vty_sr_algorithm(vty, tlvh);
1354 break;
1355 case RI_SR_TLV_SID_LABEL_RANGE:
1356 sum += show_vty_sr_range(vty, tlvh);
1357 break;
1358 case RI_SR_TLV_NODE_MSD:
1359 sum += show_vty_sr_msd(vty, tlvh);
1360 break;
1361
1362 default:
1363 sum += show_vty_unknown_tlv(vty, tlvh);
1364 break;
1365 }
1366 }
1367
1368 return;
1369 }
1370
1371 static void ospf_router_info_config_write_router(struct vty *vty)
1372 {
1373 struct ospf_pce_info *pce = &OspfRI.pce_info;
1374 struct listnode *node;
1375 struct ri_pce_subtlv_domain *domain;
1376 struct ri_pce_subtlv_neighbor *neighbor;
1377 struct in_addr tmp;
1378
1379 if (!OspfRI.enabled)
1380 return;
1381
1382 if (OspfRI.scope == OSPF_OPAQUE_AS_LSA)
1383 vty_out(vty, " router-info as\n");
1384 else
1385 vty_out(vty, " router-info area %s\n",
1386 inet_ntoa(OspfRI.area_id));
1387
1388 if (OspfRI.pce_info.enabled) {
1389
1390 if (pce->pce_address.header.type != 0)
1391 vty_out(vty, " pce address %s\n",
1392 inet_ntoa(pce->pce_address.address.value));
1393
1394 if (pce->pce_cap_flag.header.type != 0)
1395 vty_out(vty, " pce flag 0x%x\n",
1396 ntohl(pce->pce_cap_flag.value));
1397
1398 for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
1399 if (domain->header.type != 0) {
1400 if (domain->type == PCE_DOMAIN_TYPE_AREA) {
1401 tmp.s_addr = domain->value;
1402 vty_out(vty, " pce domain area %s\n",
1403 inet_ntoa(tmp));
1404 } else {
1405 vty_out(vty, " pce domain as %d\n",
1406 ntohl(domain->value));
1407 }
1408 }
1409 }
1410
1411 for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
1412 if (neighbor->header.type != 0) {
1413 if (neighbor->type == PCE_DOMAIN_TYPE_AREA) {
1414 tmp.s_addr = neighbor->value;
1415 vty_out(vty, " pce neighbor area %s\n",
1416 inet_ntoa(tmp));
1417 } else {
1418 vty_out(vty, " pce neighbor as %d\n",
1419 ntohl(neighbor->value));
1420 }
1421 }
1422 }
1423
1424 if (pce->pce_scope.header.type != 0)
1425 vty_out(vty, " pce scope 0x%x\n",
1426 ntohl(OspfRI.pce_info.pce_scope.value));
1427 }
1428 return;
1429 }
1430
1431 /*------------------------------------------------------------------------*
1432 * Followings are vty command functions.
1433 *------------------------------------------------------------------------*/
1434
1435 DEFUN (router_info,
1436 router_info_area_cmd,
1437 "router-info <as|area A.B.C.D>",
1438 OSPF_RI_STR
1439 "Enable the Router Information functionality with AS flooding scope\n"
1440 "Enable the Router Information functionality with Area flooding scope\n"
1441 "OSPF area ID in IP format\n")
1442 {
1443 int idx_ipv4 = 2;
1444 char *area = (argc == 3) ? argv[idx_ipv4]->arg : NULL;
1445
1446 uint8_t scope;
1447
1448 if (OspfRI.enabled)
1449 return CMD_SUCCESS;
1450
1451 /* Check and get Area value if present */
1452 if (area) {
1453 if (!inet_aton(area, &OspfRI.area_id)) {
1454 vty_out(vty, "%% specified Area ID %s is invalid\n",
1455 area);
1456 return CMD_WARNING_CONFIG_FAILED;
1457 }
1458 scope = OSPF_OPAQUE_AREA_LSA;
1459 } else {
1460 OspfRI.area_id.s_addr = 0;
1461 scope = OSPF_OPAQUE_AS_LSA;
1462 }
1463
1464 /* First start to register Router Information callbacks */
1465 if ((ospf_router_info_register(scope)) != 0) {
1466 zlog_warn(
1467 "Unable to register Router Information callbacks. Abort!");
1468 return CMD_WARNING_CONFIG_FAILED;
1469 }
1470
1471 OspfRI.enabled = true;
1472
1473 if (IS_DEBUG_OSPF_EVENT)
1474 zlog_debug("RI-> Router Information (%s flooding): OFF -> ON",
1475 OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area"
1476 : "AS");
1477
1478 /*
1479 * Following code is intended to handle two cases;
1480 *
1481 * 1) Router Information was disabled at startup time, but now become
1482 * enabled.
1483 * 2) Router Information was once enabled then disabled, and now enabled
1484 * again.
1485 */
1486
1487 initialize_params(&OspfRI);
1488
1489 /* Refresh RI LSA if already engaged */
1490 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED)) {
1491 zlog_debug("RI-> Refresh LSA following configuration");
1492 ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
1493 } else {
1494 zlog_debug("RI-> Initial origination following configuration");
1495 ospf_router_info_lsa_schedule(REORIGINATE_THIS_LSA);
1496 }
1497 return CMD_SUCCESS;
1498 }
1499
1500
1501 DEFUN (no_router_info,
1502 no_router_info_cmd,
1503 "no router-info",
1504 NO_STR
1505 "Disable the Router Information functionality\n")
1506 {
1507
1508 if (!OspfRI.enabled)
1509 return CMD_SUCCESS;
1510
1511 if (IS_DEBUG_OSPF_EVENT)
1512 zlog_debug("RI-> Router Information: ON -> OFF");
1513
1514 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
1515 ospf_router_info_lsa_schedule(FLUSH_THIS_LSA);
1516
1517 OspfRI.enabled = false;
1518
1519 return CMD_SUCCESS;
1520 }
1521
1522 static int ospf_ri_enabled(struct vty *vty)
1523 {
1524 if (OspfRI.enabled)
1525 return 1;
1526
1527 if (vty)
1528 vty_out(vty, "%% OSPF RI is not turned on\n");
1529
1530 return 0;
1531 }
1532
1533 DEFUN (pce_address,
1534 pce_address_cmd,
1535 "pce address A.B.C.D",
1536 PCE_STR
1537 "Stable IP address of the PCE\n"
1538 "PCE address in IPv4 address format\n")
1539 {
1540 int idx_ipv4 = 2;
1541 struct in_addr value;
1542 struct ospf_pce_info *pi = &OspfRI.pce_info;
1543
1544 if (!ospf_ri_enabled(vty))
1545 return CMD_WARNING_CONFIG_FAILED;
1546
1547 if (!inet_aton(argv[idx_ipv4]->arg, &value)) {
1548 vty_out(vty, "Please specify PCE Address by A.B.C.D\n");
1549 return CMD_WARNING_CONFIG_FAILED;
1550 }
1551
1552 if (ntohs(pi->pce_address.header.type) == 0
1553 || ntohl(pi->pce_address.address.value.s_addr)
1554 != ntohl(value.s_addr)) {
1555
1556 set_pce_address(value, pi);
1557
1558 /* Refresh RI LSA if already engaged */
1559 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
1560 ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
1561 }
1562
1563 return CMD_SUCCESS;
1564 }
1565
1566 DEFUN (no_pce_address,
1567 no_pce_address_cmd,
1568 "no pce address [A.B.C.D]",
1569 NO_STR
1570 PCE_STR
1571 "Disable PCE address\n"
1572 "PCE address in IPv4 address format\n")
1573 {
1574
1575 unset_param(&OspfRI.pce_info.pce_address);
1576
1577 /* Refresh RI LSA if already engaged */
1578 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
1579 ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
1580
1581 return CMD_SUCCESS;
1582 }
1583
1584 DEFUN (pce_path_scope,
1585 pce_path_scope_cmd,
1586 "pce scope BITPATTERN",
1587 PCE_STR
1588 "Path scope visibilities of the PCE for path computation\n"
1589 "32-bit Hexadecimal value\n")
1590 {
1591 int idx_bitpattern = 2;
1592 uint32_t scope;
1593 struct ospf_pce_info *pi = &OspfRI.pce_info;
1594
1595 if (!ospf_ri_enabled(vty))
1596 return CMD_WARNING_CONFIG_FAILED;
1597
1598 if (sscanf(argv[idx_bitpattern]->arg, "0x%x", &scope) != 1) {
1599 vty_out(vty, "pce_path_scope: fscanf: %s\n",
1600 safe_strerror(errno));
1601 return CMD_WARNING_CONFIG_FAILED;
1602 }
1603
1604 if (ntohl(pi->pce_scope.header.type) == 0
1605 || scope != pi->pce_scope.value) {
1606 set_pce_path_scope(scope, pi);
1607
1608 /* Refresh RI LSA if already engaged */
1609 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
1610 ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
1611 }
1612
1613 return CMD_SUCCESS;
1614 }
1615
1616 DEFUN (no_pce_path_scope,
1617 no_pce_path_scope_cmd,
1618 "no pce scope [BITPATTERN]",
1619 NO_STR
1620 PCE_STR
1621 "Disable PCE path scope\n"
1622 "32-bit Hexadecimal value\n")
1623 {
1624
1625 unset_param(&OspfRI.pce_info.pce_address);
1626
1627 /* Refresh RI LSA if already engaged */
1628 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
1629 ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
1630
1631 return CMD_SUCCESS;
1632 }
1633
1634 DEFUN (pce_domain,
1635 pce_domain_cmd,
1636 "pce domain as (0-65535)",
1637 PCE_STR
1638 "Configure PCE domain AS number\n"
1639 "AS number where the PCE as visibilities for path computation\n"
1640 "AS number in decimal <0-65535>\n")
1641 {
1642 int idx_number = 3;
1643
1644 uint32_t as;
1645 struct ospf_pce_info *pce = &OspfRI.pce_info;
1646 struct listnode *node;
1647 struct ri_pce_subtlv_domain *domain;
1648
1649 if (!ospf_ri_enabled(vty))
1650 return CMD_WARNING_CONFIG_FAILED;
1651
1652 if (sscanf(argv[idx_number]->arg, "%" SCNu32, &as) != 1) {
1653 vty_out(vty, "pce_domain: fscanf: %s\n", safe_strerror(errno));
1654 return CMD_WARNING_CONFIG_FAILED;
1655 }
1656
1657 /* Check if the domain is not already in the domain list */
1658 for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
1659 if (ntohl(domain->header.type) == 0 && as == domain->value)
1660 return CMD_SUCCESS;
1661 }
1662
1663 /* Create new domain if not found */
1664 set_pce_domain(PCE_DOMAIN_TYPE_AS, as, pce);
1665
1666 /* Refresh RI LSA if already engaged */
1667 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
1668 ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
1669
1670 return CMD_SUCCESS;
1671 }
1672
1673 DEFUN (no_pce_domain,
1674 no_pce_domain_cmd,
1675 "no pce domain as (0-65535)",
1676 NO_STR
1677 PCE_STR
1678 "Disable PCE domain AS number\n"
1679 "AS number where the PCE as visibilities for path computation\n"
1680 "AS number in decimal <0-65535>\n")
1681 {
1682 int idx_number = 4;
1683
1684 uint32_t as;
1685 struct ospf_pce_info *pce = &OspfRI.pce_info;
1686
1687 if (sscanf(argv[idx_number]->arg, "%" SCNu32, &as) != 1) {
1688 vty_out(vty, "no_pce_domain: fscanf: %s\n",
1689 safe_strerror(errno));
1690 return CMD_WARNING_CONFIG_FAILED;
1691 }
1692
1693 /* Unset corresponding PCE domain */
1694 unset_pce_domain(PCE_DOMAIN_TYPE_AS, as, pce);
1695
1696 /* Refresh RI LSA if already engaged */
1697 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
1698 ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
1699
1700 return CMD_SUCCESS;
1701 }
1702
1703 DEFUN (pce_neigbhor,
1704 pce_neighbor_cmd,
1705 "pce neighbor as (0-65535)",
1706 PCE_STR
1707 "Configure PCE neighbor domain AS number\n"
1708 "AS number of PCE neighbors\n"
1709 "AS number in decimal <0-65535>\n")
1710 {
1711 int idx_number = 3;
1712
1713 uint32_t as;
1714 struct ospf_pce_info *pce = &OspfRI.pce_info;
1715 struct listnode *node;
1716 struct ri_pce_subtlv_neighbor *neighbor;
1717
1718 if (!ospf_ri_enabled(vty))
1719 return CMD_WARNING_CONFIG_FAILED;
1720
1721 if (sscanf(argv[idx_number]->arg, "%" SCNu32, &as) != 1) {
1722 vty_out(vty, "pce_neighbor: fscanf: %s\n",
1723 safe_strerror(errno));
1724 return CMD_WARNING_CONFIG_FAILED;
1725 }
1726
1727 /* Check if the domain is not already in the domain list */
1728 for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
1729 if (ntohl(neighbor->header.type) == 0 && as == neighbor->value)
1730 return CMD_SUCCESS;
1731 }
1732
1733 /* Create new domain if not found */
1734 set_pce_neighbor(PCE_DOMAIN_TYPE_AS, as, pce);
1735
1736 /* Refresh RI LSA if already engaged */
1737 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
1738 ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
1739
1740 return CMD_SUCCESS;
1741 }
1742
1743 DEFUN (no_pce_neighbor,
1744 no_pce_neighbor_cmd,
1745 "no pce neighbor as (0-65535)",
1746 NO_STR
1747 PCE_STR
1748 "Disable PCE neighbor AS number\n"
1749 "AS number of PCE neighbor\n"
1750 "AS number in decimal <0-65535>\n")
1751 {
1752 int idx_number = 4;
1753
1754 uint32_t as;
1755 struct ospf_pce_info *pce = &OspfRI.pce_info;
1756
1757 if (sscanf(argv[idx_number]->arg, "%" SCNu32, &as) != 1) {
1758 vty_out(vty, "no_pce_neighbor: fscanf: %s\n",
1759 safe_strerror(errno));
1760 return CMD_WARNING_CONFIG_FAILED;
1761 }
1762
1763 /* Unset corresponding PCE domain */
1764 unset_pce_neighbor(PCE_DOMAIN_TYPE_AS, as, pce);
1765
1766 /* Refresh RI LSA if already engaged */
1767 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
1768 ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
1769
1770 return CMD_SUCCESS;
1771 }
1772
1773 DEFUN (pce_cap_flag,
1774 pce_cap_flag_cmd,
1775 "pce flag BITPATTERN",
1776 PCE_STR
1777 "Capabilities of the PCE for path computation\n"
1778 "32-bit Hexadecimal value\n")
1779 {
1780 int idx_bitpattern = 2;
1781
1782 uint32_t cap;
1783 struct ospf_pce_info *pce = &OspfRI.pce_info;
1784
1785 if (!ospf_ri_enabled(vty))
1786 return CMD_WARNING_CONFIG_FAILED;
1787
1788 if (sscanf(argv[idx_bitpattern]->arg, "0x%x", &cap) != 1) {
1789 vty_out(vty, "pce_cap_flag: fscanf: %s\n",
1790 safe_strerror(errno));
1791 return CMD_WARNING_CONFIG_FAILED;
1792 }
1793
1794 if (ntohl(pce->pce_cap_flag.header.type) == 0
1795 || cap != pce->pce_cap_flag.value) {
1796 set_pce_cap_flag(cap, pce);
1797
1798 /* Refresh RI LSA if already engaged */
1799 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
1800 ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
1801 }
1802
1803 return CMD_SUCCESS;
1804 }
1805
1806 DEFUN (no_pce_cap_flag,
1807 no_pce_cap_flag_cmd,
1808 "no pce flag",
1809 NO_STR
1810 PCE_STR
1811 "Disable PCE capabilities\n")
1812 {
1813
1814 unset_param(&OspfRI.pce_info.pce_cap_flag);
1815
1816 /* Refresh RI LSA if already engaged */
1817 if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
1818 ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
1819
1820 return CMD_SUCCESS;
1821 }
1822
1823 DEFUN (show_ip_ospf_router_info,
1824 show_ip_ospf_router_info_cmd,
1825 "show ip ospf router-info",
1826 SHOW_STR
1827 IP_STR
1828 OSPF_STR
1829 "Router Information\n")
1830 {
1831
1832 if (OspfRI.enabled) {
1833 vty_out(vty, "--- Router Information parameters ---\n");
1834 show_vty_router_cap(vty, &OspfRI.router_cap.header);
1835 } else {
1836 if (vty != NULL)
1837 vty_out(vty,
1838 " Router Information is disabled on this router\n");
1839 }
1840 return CMD_SUCCESS;
1841 }
1842
1843 DEFUN (show_ip_opsf_router_info_pce,
1844 show_ip_ospf_router_info_pce_cmd,
1845 "show ip ospf router-info pce",
1846 SHOW_STR
1847 IP_STR
1848 OSPF_STR
1849 "Router Information\n"
1850 "PCE information\n")
1851 {
1852
1853 struct ospf_pce_info *pce = &OspfRI.pce_info;
1854 struct listnode *node;
1855 struct ri_pce_subtlv_domain *domain;
1856 struct ri_pce_subtlv_neighbor *neighbor;
1857
1858 if ((OspfRI.enabled) && (OspfRI.pce_info.enabled)) {
1859 vty_out(vty, "--- PCE parameters ---\n");
1860
1861 if (pce->pce_address.header.type != 0)
1862 show_vty_pce_subtlv_address(vty,
1863 &pce->pce_address.header);
1864
1865 if (pce->pce_scope.header.type != 0)
1866 show_vty_pce_subtlv_path_scope(vty,
1867 &pce->pce_scope.header);
1868
1869 for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
1870 if (domain->header.type != 0)
1871 show_vty_pce_subtlv_domain(vty,
1872 &domain->header);
1873 }
1874
1875 for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
1876 if (neighbor->header.type != 0)
1877 show_vty_pce_subtlv_neighbor(vty,
1878 &neighbor->header);
1879 }
1880
1881 if (pce->pce_cap_flag.header.type != 0)
1882 show_vty_pce_subtlv_cap_flag(vty,
1883 &pce->pce_cap_flag.header);
1884
1885 } else {
1886 vty_out(vty, " PCE info is disabled on this router\n");
1887 }
1888
1889 return CMD_SUCCESS;
1890 }
1891
1892 /* Install new CLI commands */
1893 static void ospf_router_info_register_vty(void)
1894 {
1895 install_element(VIEW_NODE, &show_ip_ospf_router_info_cmd);
1896 install_element(VIEW_NODE, &show_ip_ospf_router_info_pce_cmd);
1897
1898 install_element(OSPF_NODE, &router_info_area_cmd);
1899 install_element(OSPF_NODE, &no_router_info_cmd);
1900 install_element(OSPF_NODE, &pce_address_cmd);
1901 install_element(OSPF_NODE, &no_pce_address_cmd);
1902 install_element(OSPF_NODE, &pce_path_scope_cmd);
1903 install_element(OSPF_NODE, &no_pce_path_scope_cmd);
1904 install_element(OSPF_NODE, &pce_domain_cmd);
1905 install_element(OSPF_NODE, &no_pce_domain_cmd);
1906 install_element(OSPF_NODE, &pce_neighbor_cmd);
1907 install_element(OSPF_NODE, &no_pce_neighbor_cmd);
1908 install_element(OSPF_NODE, &pce_cap_flag_cmd);
1909 install_element(OSPF_NODE, &no_pce_cap_flag_cmd);
1910
1911 return;
1912 }