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