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