]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_interface.c
Merge pull request #12818 from imzyxwvu/fix/other-table-inactive
[mirror_frr.git] / ospf6d / ospf6_interface.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2003 Yasuhiro Ohara
4 */
5
6 #include <zebra.h>
7
8 #include "memory.h"
9 #include "if.h"
10 #include "log.h"
11 #include "command.h"
12 #include "thread.h"
13 #include "prefix.h"
14 #include "plist.h"
15 #include "zclient.h"
16
17 #include "ospf6_lsa.h"
18 #include "ospf6_lsdb.h"
19 #include "ospf6_top.h"
20 #include "ospf6_network.h"
21 #include "ospf6_message.h"
22 #include "ospf6_route.h"
23 #include "ospf6_area.h"
24 #include "ospf6_abr.h"
25 #include "ospf6_nssa.h"
26 #include "ospf6_interface.h"
27 #include "ospf6_neighbor.h"
28 #include "ospf6_intra.h"
29 #include "ospf6_spf.h"
30 #include "ospf6d.h"
31 #include "ospf6_bfd.h"
32 #include "ospf6_zebra.h"
33 #include "ospf6_gr.h"
34 #include "lib/json.h"
35 #include "ospf6_proto.h"
36 #include "lib/keychain.h"
37 #include "ospf6_auth_trailer.h"
38
39 DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_IF, "OSPF6 interface");
40 DEFINE_MTYPE(OSPF6D, OSPF6_AUTH_KEYCHAIN, "OSPF6 auth keychain");
41 DEFINE_MTYPE(OSPF6D, OSPF6_AUTH_MANUAL_KEY, "OSPF6 auth key");
42 DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names");
43 DEFINE_QOBJ_TYPE(ospf6_interface);
44 DEFINE_HOOK(ospf6_interface_change,
45 (struct ospf6_interface * oi, int state, int old_state),
46 (oi, state, old_state));
47
48 unsigned char conf_debug_ospf6_interface = 0;
49
50 const char *const ospf6_interface_state_str[] = {
51 "None", "Down", "Loopback", "Waiting", "PointToPoint",
52 "DROther", "BDR", "DR", NULL};
53
54 int ospf6_interface_neighbor_count(struct ospf6_interface *oi)
55 {
56 int count = 0;
57 struct ospf6_neighbor *nbr = NULL;
58 struct listnode *node;
59
60 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, nbr)) {
61 /* Down state is not shown. */
62 if (nbr->state == OSPF6_NEIGHBOR_DOWN)
63 continue;
64 count++;
65 }
66
67 return count;
68 }
69
70 struct ospf6_interface *ospf6_interface_lookup_by_ifindex(ifindex_t ifindex,
71 vrf_id_t vrf_id)
72 {
73 struct ospf6_interface *oi;
74 struct interface *ifp;
75
76 ifp = if_lookup_by_index(ifindex, vrf_id);
77 if (ifp == NULL)
78 return (struct ospf6_interface *)NULL;
79
80 oi = (struct ospf6_interface *)ifp->info;
81 return oi;
82 }
83
84 /* schedule routing table recalculation */
85 static void ospf6_interface_lsdb_hook(struct ospf6_lsa *lsa,
86 unsigned int reason)
87 {
88 struct ospf6_interface *oi;
89
90 if (lsa == NULL)
91 return;
92
93 oi = lsa->lsdb->data;
94 switch (ntohs(lsa->header->type)) {
95 case OSPF6_LSTYPE_LINK:
96 if (oi->state == OSPF6_INTERFACE_DR)
97 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
98 if (oi->area)
99 ospf6_spf_schedule(oi->area->ospf6, reason);
100 break;
101
102 default:
103 break;
104 }
105 }
106
107 static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa *lsa)
108 {
109 ospf6_interface_lsdb_hook(lsa, ospf6_lsadd_to_spf_reason(lsa));
110 }
111
112 static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa *lsa)
113 {
114 ospf6_interface_lsdb_hook(lsa, ospf6_lsremove_to_spf_reason(lsa));
115 }
116
117 static uint8_t ospf6_default_iftype(struct interface *ifp)
118 {
119 if (if_is_pointopoint(ifp))
120 return OSPF_IFTYPE_POINTOPOINT;
121 else if (if_is_loopback(ifp))
122 return OSPF_IFTYPE_LOOPBACK;
123 else
124 return OSPF_IFTYPE_BROADCAST;
125 }
126
127 static uint32_t ospf6_interface_get_cost(struct ospf6_interface *oi)
128 {
129 /* If all else fails, use default OSPF cost */
130 uint32_t cost;
131 uint32_t bw, refbw;
132 struct ospf6 *ospf6;
133 /* interface speed and bw can be 0 in some platforms,
134 * use ospf default bw. If bw is configured then it would
135 * be used.
136 */
137 if (!oi->interface->bandwidth && oi->interface->speed) {
138 bw = oi->interface->speed;
139 } else {
140 bw = oi->interface->bandwidth ? oi->interface->bandwidth
141 : OSPF6_INTERFACE_BANDWIDTH;
142 }
143
144 ospf6 = oi->interface->vrf->info;
145 refbw = ospf6 ? ospf6->ref_bandwidth : OSPF6_REFERENCE_BANDWIDTH;
146
147 /* A specified ip ospf cost overrides a calculated one. */
148 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
149 cost = oi->cost;
150 else {
151 cost = (uint32_t)((double)refbw / (double)bw + (double)0.5);
152 if (cost < 1)
153 cost = 1;
154 }
155
156 return cost;
157 }
158
159 static void ospf6_interface_force_recalculate_cost(struct ospf6_interface *oi)
160 {
161 /* update cost held in route_connected list in ospf6_interface */
162 ospf6_interface_connected_route_update(oi->interface);
163
164 /* execute LSA hooks */
165 if (oi->area) {
166 OSPF6_LINK_LSA_SCHEDULE(oi);
167 OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
168 OSPF6_NETWORK_LSA_SCHEDULE(oi);
169 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
170 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
171 }
172 }
173
174 static void ospf6_interface_recalculate_cost(struct ospf6_interface *oi)
175 {
176 uint32_t newcost;
177
178 newcost = ospf6_interface_get_cost(oi);
179 if (newcost == oi->cost)
180 return;
181 oi->cost = newcost;
182
183 ospf6_interface_force_recalculate_cost(oi);
184 }
185
186 /* Create new ospf6 interface structure */
187 struct ospf6_interface *ospf6_interface_create(struct interface *ifp)
188 {
189 struct ospf6_interface *oi;
190 unsigned int iobuflen;
191
192 oi = XCALLOC(MTYPE_OSPF6_IF, sizeof(struct ospf6_interface));
193
194 oi->obuf = ospf6_fifo_new();
195
196 oi->area = (struct ospf6_area *)NULL;
197 oi->neighbor_list = list_new();
198 oi->neighbor_list->cmp = ospf6_neighbor_cmp;
199 oi->linklocal_addr = (struct in6_addr *)NULL;
200 oi->instance_id = OSPF6_INTERFACE_INSTANCE_ID;
201 oi->transdelay = OSPF6_INTERFACE_TRANSDELAY;
202 oi->priority = OSPF6_INTERFACE_PRIORITY;
203
204 oi->hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
205 oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
206 oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
207 oi->type = ospf6_default_iftype(ifp);
208 oi->state = OSPF6_INTERFACE_DOWN;
209 oi->flag = 0;
210 oi->mtu_ignore = 0;
211 oi->c_ifmtu = 0;
212
213 /* Try to adjust I/O buffer size with IfMtu */
214 oi->ifmtu = ifp->mtu6;
215 iobuflen = ospf6_iobuf_size(ifp->mtu6);
216 if (oi->ifmtu > iobuflen) {
217 if (IS_OSPF6_DEBUG_INTERFACE)
218 zlog_debug(
219 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
220 ifp->name, iobuflen);
221 oi->ifmtu = iobuflen;
222 }
223
224 QOBJ_REG(oi, ospf6_interface);
225
226 oi->lsupdate_list = ospf6_lsdb_create(oi);
227 oi->lsack_list = ospf6_lsdb_create(oi);
228 oi->lsdb = ospf6_lsdb_create(oi);
229 oi->lsdb->hook_add = ospf6_interface_lsdb_hook_add;
230 oi->lsdb->hook_remove = ospf6_interface_lsdb_hook_remove;
231 oi->lsdb_self = ospf6_lsdb_create(oi);
232
233 oi->route_connected =
234 OSPF6_ROUTE_TABLE_CREATE(INTERFACE, CONNECTED_ROUTES);
235 oi->route_connected->scope = oi;
236
237 /* link both */
238 oi->interface = ifp;
239 ifp->info = oi;
240
241 /* Compute cost. */
242 oi->cost = ospf6_interface_get_cost(oi);
243
244 oi->at_data.flags = 0;
245
246 return oi;
247 }
248
249 void ospf6_interface_delete(struct ospf6_interface *oi)
250 {
251 struct listnode *node, *nnode;
252 struct ospf6_neighbor *on;
253
254 QOBJ_UNREG(oi);
255
256 ospf6_fifo_free(oi->obuf);
257
258 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
259 ospf6_neighbor_delete(on);
260
261 list_delete(&oi->neighbor_list);
262
263 THREAD_OFF(oi->thread_send_hello);
264 THREAD_OFF(oi->thread_send_lsupdate);
265 THREAD_OFF(oi->thread_send_lsack);
266 THREAD_OFF(oi->thread_sso);
267 THREAD_OFF(oi->thread_wait_timer);
268
269 ospf6_lsdb_remove_all(oi->lsdb);
270 ospf6_lsdb_remove_all(oi->lsupdate_list);
271 ospf6_lsdb_remove_all(oi->lsack_list);
272
273 ospf6_lsdb_delete(oi->lsdb);
274 ospf6_lsdb_delete(oi->lsdb_self);
275
276 ospf6_lsdb_delete(oi->lsupdate_list);
277 ospf6_lsdb_delete(oi->lsack_list);
278
279 ospf6_route_table_delete(oi->route_connected);
280
281 /* cut link */
282 oi->interface->info = NULL;
283
284 /* plist_name */
285 if (oi->plist_name)
286 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
287
288 /* disable from area list if possible */
289 ospf6_area_interface_delete(oi);
290
291 if (oi->at_data.auth_key)
292 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY, oi->at_data.auth_key);
293
294 /* Free BFD allocated data. */
295 XFREE(MTYPE_TMP, oi->bfd_config.profile);
296
297 XFREE(MTYPE_OSPF6_IF, oi);
298 }
299
300 void ospf6_interface_enable(struct ospf6_interface *oi)
301 {
302 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
303 ospf6_interface_state_update(oi->interface);
304 }
305
306 void ospf6_interface_disable(struct ospf6_interface *oi)
307 {
308 SET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
309
310 thread_execute(master, interface_down, oi, 0);
311
312 ospf6_lsdb_remove_all(oi->lsdb);
313 ospf6_lsdb_remove_all(oi->lsdb_self);
314 ospf6_lsdb_remove_all(oi->lsupdate_list);
315 ospf6_lsdb_remove_all(oi->lsack_list);
316
317 THREAD_OFF(oi->thread_send_hello);
318 THREAD_OFF(oi->thread_send_lsupdate);
319 THREAD_OFF(oi->thread_send_lsack);
320 THREAD_OFF(oi->thread_sso);
321
322 THREAD_OFF(oi->thread_network_lsa);
323 THREAD_OFF(oi->thread_link_lsa);
324 THREAD_OFF(oi->thread_intra_prefix_lsa);
325 THREAD_OFF(oi->thread_as_extern_lsa);
326 THREAD_OFF(oi->thread_wait_timer);
327 }
328
329 static struct in6_addr *
330 ospf6_interface_get_linklocal_address(struct interface *ifp)
331 {
332 struct listnode *n;
333 struct connected *c;
334 struct in6_addr *l = (struct in6_addr *)NULL;
335
336 /* for each connected address */
337 for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
338 /* if family not AF_INET6, ignore */
339 if (c->address->family != AF_INET6)
340 continue;
341
342 /* linklocal scope check */
343 if (IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
344 l = &c->address->u.prefix6;
345 }
346 return l;
347 }
348
349 void ospf6_interface_state_update(struct interface *ifp)
350 {
351 struct ospf6_interface *oi;
352 unsigned int iobuflen;
353
354 oi = (struct ospf6_interface *)ifp->info;
355 if (oi == NULL)
356 return;
357 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
358 return;
359
360 /* Adjust the mtu values if the kernel told us something new */
361 if (ifp->mtu6 != oi->ifmtu) {
362 /* If nothing configured, accept it and check for buffer size */
363 if (!oi->c_ifmtu) {
364 oi->ifmtu = ifp->mtu6;
365 iobuflen = ospf6_iobuf_size(ifp->mtu6);
366 if (oi->ifmtu > iobuflen) {
367 if (IS_OSPF6_DEBUG_INTERFACE)
368 zlog_debug(
369 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
370 ifp->name, iobuflen);
371 oi->ifmtu = iobuflen;
372 }
373 } else if (oi->c_ifmtu > ifp->mtu6) {
374 oi->ifmtu = ifp->mtu6;
375 zlog_warn(
376 "Configured mtu %u on %s overridden by kernel %u",
377 oi->c_ifmtu, ifp->name, ifp->mtu6);
378 } else
379 oi->ifmtu = oi->c_ifmtu;
380 }
381
382 if (if_is_operative(ifp)
383 && (ospf6_interface_get_linklocal_address(oi->interface)
384 || if_is_loopback(oi->interface)))
385 thread_execute(master, interface_up, oi, 0);
386 else
387 thread_execute(master, interface_down, oi, 0);
388
389 return;
390 }
391
392 void ospf6_interface_connected_route_update(struct interface *ifp)
393 {
394 struct ospf6_interface *oi;
395 struct ospf6_route *route;
396 struct connected *c;
397 struct listnode *node, *nnode;
398 struct in6_addr nh_addr;
399
400 oi = (struct ospf6_interface *)ifp->info;
401 if (oi == NULL)
402 return;
403
404 /* reset linklocal pointer */
405 oi->linklocal_addr = ospf6_interface_get_linklocal_address(ifp);
406
407 /* if area is null, do not make connected-route list */
408 if (oi->area == NULL)
409 return;
410
411 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
412 return;
413
414 /* update "route to advertise" interface route table */
415 ospf6_route_remove_all(oi->route_connected);
416
417 for (ALL_LIST_ELEMENTS(oi->interface->connected, node, nnode, c)) {
418 if (c->address->family != AF_INET6)
419 continue;
420
421 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE,
422 c->address);
423 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE,
424 c->address);
425 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE,
426 c->address);
427 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE,
428 c->address);
429 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE,
430 c->address);
431
432 /* apply filter */
433 if (oi->plist_name) {
434 struct prefix_list *plist;
435 enum prefix_list_type ret;
436
437 plist = prefix_list_lookup(AFI_IP6, oi->plist_name);
438 ret = prefix_list_apply(plist, (void *)c->address);
439 if (ret == PREFIX_DENY) {
440 if (IS_OSPF6_DEBUG_INTERFACE)
441 zlog_debug(
442 "%pFX on %s filtered by prefix-list %s ",
443 c->address, oi->interface->name,
444 oi->plist_name);
445 continue;
446 }
447 }
448
449 route = ospf6_route_create(oi->area->ospf6);
450 memcpy(&route->prefix, c->address, sizeof(struct prefix));
451 apply_mask(&route->prefix);
452 route->type = OSPF6_DEST_TYPE_NETWORK;
453 route->path.area_id = oi->area->area_id;
454 route->path.type = OSPF6_PATH_TYPE_INTRA;
455 route->path.cost = oi->cost;
456 inet_pton(AF_INET6, "::1", &nh_addr);
457 ospf6_route_add_nexthop(route, oi->interface->ifindex,
458 &nh_addr);
459 ospf6_route_add(route, oi->route_connected);
460 }
461
462 /* create new Link-LSA */
463 OSPF6_LINK_LSA_SCHEDULE(oi);
464 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
465 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
466 }
467
468 static int ospf6_interface_state_change(uint8_t next_state,
469 struct ospf6_interface *oi)
470 {
471 uint8_t prev_state;
472 struct ospf6 *ospf6;
473
474 prev_state = oi->state;
475 oi->state = next_state;
476
477 if (prev_state == next_state)
478 return -1;
479
480 if (!oi->area)
481 return -1;
482
483 /* log */
484 if (IS_OSPF6_DEBUG_INTERFACE) {
485 zlog_debug("Interface state change %s: %s -> %s",
486 oi->interface->name,
487 ospf6_interface_state_str[prev_state],
488 ospf6_interface_state_str[next_state]);
489 }
490 oi->state_change++;
491
492 ospf6 = oi->area->ospf6;
493
494 if ((prev_state == OSPF6_INTERFACE_DR
495 || prev_state == OSPF6_INTERFACE_BDR)
496 && (next_state != OSPF6_INTERFACE_DR
497 && next_state != OSPF6_INTERFACE_BDR))
498 ospf6_sso(oi->interface->ifindex, &alldrouters6,
499 IPV6_LEAVE_GROUP, ospf6->fd);
500
501 if ((prev_state != OSPF6_INTERFACE_DR
502 && prev_state != OSPF6_INTERFACE_BDR)
503 && (next_state == OSPF6_INTERFACE_DR
504 || next_state == OSPF6_INTERFACE_BDR))
505 ospf6_sso(oi->interface->ifindex, &alldrouters6,
506 IPV6_JOIN_GROUP, ospf6->fd);
507
508 OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
509 OSPF6_LINK_LSA_SCHEDULE(oi);
510 if (next_state == OSPF6_INTERFACE_DOWN) {
511 OSPF6_NETWORK_LSA_EXECUTE(oi);
512 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
513 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
514 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
515 } else if (prev_state == OSPF6_INTERFACE_DR
516 || next_state == OSPF6_INTERFACE_DR) {
517 OSPF6_NETWORK_LSA_SCHEDULE(oi);
518 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
519 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
520 }
521
522 hook_call(ospf6_interface_change, oi, next_state, prev_state);
523
524 return 0;
525 }
526
527
528 /* DR Election, RFC2328 section 9.4 */
529
530 #define IS_ELIGIBLE(n) \
531 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
532
533 static struct ospf6_neighbor *better_bdrouter(struct ospf6_neighbor *a,
534 struct ospf6_neighbor *b)
535 {
536 if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id)
537 && (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id))
538 return NULL;
539 else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id)
540 return b;
541 else if (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id)
542 return a;
543
544 if (a->bdrouter == a->router_id && b->bdrouter != b->router_id)
545 return a;
546 if (a->bdrouter != a->router_id && b->bdrouter == b->router_id)
547 return b;
548
549 if (a->priority > b->priority)
550 return a;
551 if (a->priority < b->priority)
552 return b;
553
554 if (ntohl(a->router_id) > ntohl(b->router_id))
555 return a;
556 if (ntohl(a->router_id) < ntohl(b->router_id))
557 return b;
558
559 zlog_warn("Router-ID duplicate ?");
560 return a;
561 }
562
563 static struct ospf6_neighbor *better_drouter(struct ospf6_neighbor *a,
564 struct ospf6_neighbor *b)
565 {
566 if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id)
567 && (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id))
568 return NULL;
569 else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id)
570 return b;
571 else if (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id)
572 return a;
573
574 if (a->drouter == a->router_id && b->drouter != b->router_id)
575 return a;
576 if (a->drouter != a->router_id && b->drouter == b->router_id)
577 return b;
578
579 if (a->priority > b->priority)
580 return a;
581 if (a->priority < b->priority)
582 return b;
583
584 if (ntohl(a->router_id) > ntohl(b->router_id))
585 return a;
586 if (ntohl(a->router_id) < ntohl(b->router_id))
587 return b;
588
589 zlog_warn("Router-ID duplicate ?");
590 return a;
591 }
592
593 uint8_t dr_election(struct ospf6_interface *oi)
594 {
595 struct listnode *node, *nnode;
596 struct ospf6_neighbor *on, *drouter, *bdrouter, myself;
597 struct ospf6_neighbor *best_drouter, *best_bdrouter;
598 uint8_t next_state = 0;
599
600 drouter = bdrouter = NULL;
601 best_drouter = best_bdrouter = NULL;
602
603 /* pseudo neighbor myself, including noting current DR/BDR (1) */
604 memset(&myself, 0, sizeof(myself));
605 inet_ntop(AF_INET, &oi->area->ospf6->router_id, myself.name,
606 sizeof(myself.name));
607 myself.state = OSPF6_NEIGHBOR_TWOWAY;
608 myself.drouter = oi->drouter;
609 myself.bdrouter = oi->bdrouter;
610 myself.priority = oi->priority;
611 myself.router_id = oi->area->ospf6->router_id;
612
613 /* Electing BDR (2) */
614 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
615 bdrouter = better_bdrouter(bdrouter, on);
616
617 best_bdrouter = bdrouter;
618 bdrouter = better_bdrouter(best_bdrouter, &myself);
619
620 /* Electing DR (3) */
621 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
622 drouter = better_drouter(drouter, on);
623
624 best_drouter = drouter;
625 drouter = better_drouter(best_drouter, &myself);
626 if (drouter == NULL)
627 drouter = bdrouter;
628
629 /* the router itself is newly/no longer DR/BDR (4) */
630 if ((drouter == &myself && myself.drouter != myself.router_id)
631 || (drouter != &myself && myself.drouter == myself.router_id)
632 || (bdrouter == &myself && myself.bdrouter != myself.router_id)
633 || (bdrouter != &myself && myself.bdrouter == myself.router_id)) {
634 myself.drouter = (drouter ? drouter->router_id : htonl(0));
635 myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl(0));
636
637 /* compatible to Electing BDR (2) */
638 bdrouter = better_bdrouter(best_bdrouter, &myself);
639
640 /* compatible to Electing DR (3) */
641 drouter = better_drouter(best_drouter, &myself);
642 if (drouter == NULL)
643 drouter = bdrouter;
644 }
645
646 /* Set interface state accordingly (5) */
647 if (drouter && drouter == &myself)
648 next_state = OSPF6_INTERFACE_DR;
649 else if (bdrouter && bdrouter == &myself)
650 next_state = OSPF6_INTERFACE_BDR;
651 else
652 next_state = OSPF6_INTERFACE_DROTHER;
653
654 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
655 /* XXX */
656
657 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
658 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
659 accordingly after AdjOK */
660 if (oi->drouter != (drouter ? drouter->router_id : htonl(0))
661 || oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl(0))) {
662 if (IS_OSPF6_DEBUG_INTERFACE)
663 zlog_debug("DR Election on %s: DR: %s BDR: %s",
664 oi->interface->name,
665 (drouter ? drouter->name : "0.0.0.0"),
666 (bdrouter ? bdrouter->name : "0.0.0.0"));
667
668 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, on)) {
669 if (on->state < OSPF6_NEIGHBOR_TWOWAY)
670 continue;
671 /* Schedule AdjOK. */
672 thread_add_event(master, adj_ok, on, 0,
673 &on->thread_adj_ok);
674 }
675 }
676
677 oi->drouter = (drouter ? drouter->router_id : htonl(0));
678 oi->bdrouter = (bdrouter ? bdrouter->router_id : htonl(0));
679 return next_state;
680 }
681
682 #ifdef __FreeBSD__
683
684 #include <ifaddrs.h>
685
686 static bool ifmaddr_check(ifindex_t ifindex, struct in6_addr *addr)
687 {
688 struct ifmaddrs *ifmap, *ifma;
689 struct sockaddr_dl *sdl;
690 struct sockaddr_in6 *sin6;
691 bool found = false;
692
693 if (getifmaddrs(&ifmap) != 0)
694 return false;
695
696 for (ifma = ifmap; ifma; ifma = ifma->ifma_next) {
697 if (ifma->ifma_name == NULL || ifma->ifma_addr == NULL)
698 continue;
699 if (ifma->ifma_name->sa_family != AF_LINK)
700 continue;
701 if (ifma->ifma_addr->sa_family != AF_INET6)
702 continue;
703 sdl = (struct sockaddr_dl *)ifma->ifma_name;
704 sin6 = (struct sockaddr_in6 *)ifma->ifma_addr;
705 if (sdl->sdl_index == ifindex
706 && memcmp(&sin6->sin6_addr, addr, IPV6_MAX_BYTELEN) == 0) {
707 found = true;
708 break;
709 }
710 }
711
712 if (ifmap)
713 freeifmaddrs(ifmap);
714
715 return found;
716 }
717
718 #endif /* __FreeBSD__ */
719
720 /* Interface State Machine */
721 void interface_up(struct thread *thread)
722 {
723 struct ospf6_interface *oi;
724 struct ospf6 *ospf6;
725
726 oi = (struct ospf6_interface *)THREAD_ARG(thread);
727 assert(oi && oi->interface);
728
729 if (!oi->type_cfg)
730 oi->type = ospf6_default_iftype(oi->interface);
731
732 thread_cancel(&oi->thread_sso);
733
734 if (IS_OSPF6_DEBUG_INTERFACE)
735 zlog_debug("Interface Event %s: [InterfaceUp]",
736 oi->interface->name);
737
738 /* check physical interface is up */
739 if (!if_is_operative(oi->interface)) {
740 zlog_warn("Interface %s is down, can't execute [InterfaceUp]",
741 oi->interface->name);
742 return;
743 }
744
745 /* check interface has a link-local address */
746 if (!(ospf6_interface_get_linklocal_address(oi->interface)
747 || if_is_loopback(oi->interface))) {
748 zlog_warn(
749 "Interface %s has no link local address, can't execute [InterfaceUp]",
750 oi->interface->name);
751 return;
752 }
753
754 /* Recompute cost */
755 ospf6_interface_recalculate_cost(oi);
756
757 /* if already enabled, do nothing */
758 if (oi->state > OSPF6_INTERFACE_DOWN) {
759 if (IS_OSPF6_DEBUG_INTERFACE)
760 zlog_debug("Interface %s already enabled",
761 oi->interface->name);
762 return;
763 }
764
765 /* If no area assigned, return */
766 if (oi->area == NULL) {
767 zlog_warn(
768 "%s: Not scheduling Hello for %s as there is no area assigned yet",
769 __func__, oi->interface->name);
770 return;
771 }
772
773 #ifdef __FreeBSD__
774 /*
775 * There's a delay in FreeBSD between issuing a command to leave a
776 * multicast group and an actual leave. If we execute "no router ospf6"
777 * and "router ospf6" fast enough, we can end up in a situation when OS
778 * performs the leave later than it performs the join and the interface
779 * remains without a multicast group. We have to do the join only after
780 * the interface actually left the group.
781 */
782 if (ifmaddr_check(oi->interface->ifindex, &allspfrouters6)) {
783 zlog_info(
784 "Interface %s is still in all routers group, rescheduling for SSO",
785 oi->interface->name);
786 thread_add_timer(master, interface_up, oi,
787 OSPF6_INTERFACE_SSO_RETRY_INT,
788 &oi->thread_sso);
789 return;
790 }
791 #endif /* __FreeBSD__ */
792
793 ospf6 = oi->area->ospf6;
794
795 /* Join AllSPFRouters */
796 if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP,
797 ospf6->fd)
798 < 0) {
799 if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX) {
800 zlog_info(
801 "Scheduling %s for sso retry, trial count: %d",
802 oi->interface->name, oi->sso_try_cnt);
803 thread_add_timer(master, interface_up, oi,
804 OSPF6_INTERFACE_SSO_RETRY_INT,
805 &oi->thread_sso);
806 }
807 return;
808 }
809 oi->sso_try_cnt = 0; /* Reset on success */
810
811 /* Update interface route */
812 ospf6_interface_connected_route_update(oi->interface);
813
814 /* Schedule Hello */
815 if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)
816 && !if_is_loopback(oi->interface)) {
817 thread_add_timer(master, ospf6_hello_send, oi, 0,
818 &oi->thread_send_hello);
819 }
820
821 /* decide next interface state */
822 if (oi->type == OSPF_IFTYPE_LOOPBACK) {
823 ospf6_interface_state_change(OSPF6_INTERFACE_LOOPBACK, oi);
824 } else if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
825 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT, oi);
826 } else if (oi->priority == 0)
827 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER, oi);
828 else {
829 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING, oi);
830 thread_add_timer(master, wait_timer, oi, oi->dead_interval,
831 &oi->thread_wait_timer);
832 }
833 }
834
835 void wait_timer(struct thread *thread)
836 {
837 struct ospf6_interface *oi;
838
839 oi = (struct ospf6_interface *)THREAD_ARG(thread);
840 assert(oi && oi->interface);
841
842 if (IS_OSPF6_DEBUG_INTERFACE)
843 zlog_debug("Interface Event %s: [WaitTimer]",
844 oi->interface->name);
845
846 if (oi->state == OSPF6_INTERFACE_WAITING)
847 ospf6_interface_state_change(dr_election(oi), oi);
848 }
849
850 void backup_seen(struct thread *thread)
851 {
852 struct ospf6_interface *oi;
853
854 oi = (struct ospf6_interface *)THREAD_ARG(thread);
855 assert(oi && oi->interface);
856
857 if (IS_OSPF6_DEBUG_INTERFACE)
858 zlog_debug("Interface Event %s: [BackupSeen]",
859 oi->interface->name);
860
861 if (oi->state == OSPF6_INTERFACE_WAITING)
862 ospf6_interface_state_change(dr_election(oi), oi);
863 }
864
865 void neighbor_change(struct thread *thread)
866 {
867 struct ospf6_interface *oi;
868
869 oi = (struct ospf6_interface *)THREAD_ARG(thread);
870 assert(oi && oi->interface);
871
872 if (IS_OSPF6_DEBUG_INTERFACE)
873 zlog_debug("Interface Event %s: [NeighborChange]",
874 oi->interface->name);
875
876 if (oi->state == OSPF6_INTERFACE_DROTHER
877 || oi->state == OSPF6_INTERFACE_BDR
878 || oi->state == OSPF6_INTERFACE_DR)
879 ospf6_interface_state_change(dr_election(oi), oi);
880 }
881
882 void interface_down(struct thread *thread)
883 {
884 struct ospf6_interface *oi;
885 struct listnode *node, *nnode;
886 struct ospf6_neighbor *on;
887 struct ospf6 *ospf6;
888
889 oi = (struct ospf6_interface *)THREAD_ARG(thread);
890 assert(oi && oi->interface);
891
892 if (IS_OSPF6_DEBUG_INTERFACE)
893 zlog_debug("Interface Event %s: [InterfaceDown]",
894 oi->interface->name);
895
896 /* Stop Hellos */
897 THREAD_OFF(oi->thread_send_hello);
898
899 /* Stop trying to set socket options. */
900 THREAD_OFF(oi->thread_sso);
901
902 /* Cease the HELPER role for all the neighbours
903 * of this interface.
904 */
905 if (ospf6_interface_neighbor_count(oi)) {
906 struct listnode *ln;
907 struct ospf6_neighbor *nbr = NULL;
908
909 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, ln, nbr))
910 ospf6_gr_helper_exit(nbr, OSPF6_GR_HELPER_TOPO_CHG);
911 }
912
913 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
914 ospf6_neighbor_delete(on);
915
916 list_delete_all_node(oi->neighbor_list);
917
918 /* When interface state is reset, also reset information about
919 * DR election, as it is no longer valid. */
920 oi->drouter = oi->prev_drouter = htonl(0);
921 oi->bdrouter = oi->prev_bdrouter = htonl(0);
922
923 if (oi->area == NULL)
924 return;
925
926 ospf6 = oi->area->ospf6;
927 /* Leave AllSPFRouters */
928 if (oi->state > OSPF6_INTERFACE_DOWN)
929 ospf6_sso(oi->interface->ifindex, &allspfrouters6,
930 IPV6_LEAVE_GROUP, ospf6->fd);
931
932 /* deal with write fifo */
933 ospf6_fifo_flush(oi->obuf);
934 if (oi->on_write_q) {
935 listnode_delete(ospf6->oi_write_q, oi);
936 if (list_isempty(ospf6->oi_write_q))
937 thread_cancel(&ospf6->t_write);
938 oi->on_write_q = 0;
939 }
940
941 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN, oi);
942 }
943
944
945 static const char *ospf6_iftype_str(uint8_t iftype)
946 {
947 switch (iftype) {
948 case OSPF_IFTYPE_LOOPBACK:
949 return "LOOPBACK";
950 case OSPF_IFTYPE_BROADCAST:
951 return "BROADCAST";
952 case OSPF_IFTYPE_POINTOPOINT:
953 return "POINTOPOINT";
954 }
955 return "UNKNOWN";
956 }
957
958 /* show specified interface structure */
959 static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
960 json_object *json_obj, bool use_json)
961 {
962 struct ospf6_interface *oi;
963 struct connected *c;
964 struct prefix *p;
965 struct listnode *i;
966 char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32];
967 uint8_t default_iftype;
968 struct timeval res, now;
969 char duration[32];
970 struct ospf6_lsa *lsa, *lsanext;
971 json_object *json_arr;
972 json_object *json_addr;
973 struct json_object *json_auth = NULL;
974
975 default_iftype = ospf6_default_iftype(ifp);
976
977 if (use_json) {
978 json_object_string_add(json_obj, "status",
979 (if_is_operative(ifp) ? "up" : "down"));
980 json_object_string_add(json_obj, "type",
981 ospf6_iftype_str(default_iftype));
982 json_object_int_add(json_obj, "interfaceId", ifp->ifindex);
983
984 if (ifp->info == NULL)
985 return 0;
986
987 oi = (struct ospf6_interface *)ifp->info;
988
989 if (if_is_operative(ifp) && oi->type != default_iftype)
990 json_object_string_add(json_obj, "operatingAsType",
991 ospf6_iftype_str(oi->type));
992
993 } else {
994 vty_out(vty, "%s is %s, type %s\n", ifp->name,
995 (if_is_operative(ifp) ? "up" : "down"),
996 ospf6_iftype_str(default_iftype));
997 vty_out(vty, " Interface ID: %d\n", ifp->ifindex);
998
999 if (ifp->info == NULL) {
1000 vty_out(vty, " OSPF not enabled on this interface\n");
1001 return 0;
1002 }
1003 oi = (struct ospf6_interface *)ifp->info;
1004
1005 if (if_is_operative(ifp) && oi->type != default_iftype)
1006 vty_out(vty, " Operating as type %s\n",
1007 ospf6_iftype_str(oi->type));
1008 }
1009
1010 if (use_json) {
1011 json_arr = json_object_new_array();
1012 for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
1013 json_addr = json_object_new_object();
1014 p = c->address;
1015 prefix2str(p, strbuf, sizeof(strbuf));
1016 switch (p->family) {
1017 case AF_INET:
1018 json_object_string_add(json_addr, "type",
1019 "inet");
1020 json_object_string_add(json_addr, "address",
1021 strbuf);
1022 json_object_array_add(json_arr, json_addr);
1023 break;
1024 case AF_INET6:
1025 json_object_string_add(json_addr, "type",
1026 "inet6");
1027 json_object_string_add(json_addr, "address",
1028 strbuf);
1029 json_object_array_add(json_arr, json_addr);
1030 break;
1031 default:
1032 json_object_string_add(json_addr, "type",
1033 "unknown");
1034 json_object_string_add(json_addr, "address",
1035 strbuf);
1036 json_object_array_add(json_arr, json_addr);
1037 break;
1038 }
1039 }
1040 json_object_object_add(json_obj, "internetAddress", json_arr);
1041 } else {
1042 vty_out(vty, " Internet Address:\n");
1043
1044 for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
1045 p = c->address;
1046 prefix2str(p, strbuf, sizeof(strbuf));
1047 switch (p->family) {
1048 case AF_INET:
1049 vty_out(vty, " inet : %pFX\n", p);
1050 break;
1051 case AF_INET6:
1052 vty_out(vty, " inet6: %pFX\n", p);
1053 break;
1054 default:
1055 vty_out(vty, " ??? : %pFX\n", p);
1056 break;
1057 }
1058 }
1059 }
1060
1061 if (use_json) {
1062 if (oi->area) {
1063 json_object_boolean_true_add(json_obj,
1064 "attachedToArea");
1065 json_object_int_add(json_obj, "instanceId",
1066 oi->instance_id);
1067 json_object_int_add(json_obj, "interfaceMtu",
1068 oi->ifmtu);
1069 json_object_int_add(json_obj, "autoDetect", ifp->mtu6);
1070 json_object_string_add(json_obj, "mtuMismatchDetection",
1071 oi->mtu_ignore ? "disabled"
1072 : "enabled");
1073 inet_ntop(AF_INET, &oi->area->area_id, strbuf,
1074 sizeof(strbuf));
1075 json_object_string_add(json_obj, "areaId", strbuf);
1076 json_object_int_add(json_obj, "cost", oi->cost);
1077 } else
1078 json_object_boolean_false_add(json_obj,
1079 "attachedToArea");
1080
1081 } else {
1082 if (oi->area) {
1083 vty_out(vty,
1084 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
1085 oi->instance_id, oi->ifmtu, ifp->mtu6);
1086 vty_out(vty, " MTU mismatch detection: %s\n",
1087 oi->mtu_ignore ? "disabled" : "enabled");
1088 inet_ntop(AF_INET, &oi->area->area_id, strbuf,
1089 sizeof(strbuf));
1090 vty_out(vty, " Area ID %s, Cost %u\n", strbuf,
1091 oi->cost);
1092 } else
1093 vty_out(vty, " Not Attached to Area\n");
1094 }
1095
1096 if (use_json) {
1097 json_object_string_add(json_obj, "ospf6InterfaceState",
1098 ospf6_interface_state_str[oi->state]);
1099 json_object_int_add(json_obj, "transmitDelaySec",
1100 oi->transdelay);
1101 json_object_int_add(json_obj, "priority", oi->priority);
1102 json_object_int_add(json_obj, "timerIntervalsConfigHello",
1103 oi->hello_interval);
1104 json_object_int_add(json_obj, "timerIntervalsConfigDead",
1105 oi->dead_interval);
1106 json_object_int_add(json_obj, "timerIntervalsConfigRetransmit",
1107 oi->rxmt_interval);
1108 json_object_boolean_add(
1109 json_obj, "timerPassiveIface",
1110 !!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE));
1111 } else {
1112 vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n",
1113 ospf6_interface_state_str[oi->state], oi->transdelay,
1114 oi->priority);
1115 vty_out(vty, " Timer intervals configured:\n");
1116 if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE))
1117 vty_out(vty,
1118 " Hello %d(%pTHd), Dead %d, Retransmit %d\n",
1119 oi->hello_interval, oi->thread_send_hello,
1120 oi->dead_interval, oi->rxmt_interval);
1121 else
1122 vty_out(vty, " No Hellos (Passive interface)\n");
1123 }
1124
1125 inet_ntop(AF_INET, &oi->drouter, drouter, sizeof(drouter));
1126 inet_ntop(AF_INET, &oi->bdrouter, bdrouter, sizeof(bdrouter));
1127 if (use_json) {
1128 json_object_string_add(json_obj, "dr", drouter);
1129 json_object_string_add(json_obj, "bdr", bdrouter);
1130 json_object_int_add(json_obj, "numberOfInterfaceScopedLsa",
1131 oi->lsdb->count);
1132 } else {
1133 vty_out(vty, " DR: %s BDR: %s\n", drouter, bdrouter);
1134 vty_out(vty, " Number of I/F scoped LSAs is %u\n",
1135 oi->lsdb->count);
1136 }
1137
1138 monotime(&now);
1139
1140 if (use_json) {
1141 timerclear(&res);
1142 if (thread_is_scheduled(oi->thread_send_lsupdate))
1143 timersub(&oi->thread_send_lsupdate->u.sands, &now,
1144 &res);
1145 timerstring(&res, duration, sizeof(duration));
1146 json_object_int_add(json_obj, "pendingLsaLsUpdateCount",
1147 oi->lsupdate_list->count);
1148 json_object_string_add(json_obj, "pendingLsaLsUpdateTime",
1149 duration);
1150 json_object_string_add(
1151 json_obj, "lsUpdateSendThread",
1152 (thread_is_scheduled(oi->thread_send_lsupdate)
1153 ? "on"
1154 : "off"));
1155
1156 json_arr = json_object_new_array();
1157 for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
1158 json_object_array_add(
1159 json_arr, json_object_new_string(lsa->name));
1160 json_object_object_add(json_obj, "pendingLsaLsUpdate",
1161 json_arr);
1162
1163 timerclear(&res);
1164 if (thread_is_scheduled(oi->thread_send_lsack))
1165 timersub(&oi->thread_send_lsack->u.sands, &now, &res);
1166 timerstring(&res, duration, sizeof(duration));
1167
1168 json_object_int_add(json_obj, "pendingLsaLsAckCount",
1169 oi->lsack_list->count);
1170 json_object_string_add(json_obj, "pendingLsaLsAckTime",
1171 duration);
1172 json_object_string_add(
1173 json_obj, "lsAckSendThread",
1174 (thread_is_scheduled(oi->thread_send_lsack) ? "on"
1175 : "off"));
1176
1177 json_arr = json_object_new_array();
1178 for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
1179 json_object_array_add(
1180 json_arr, json_object_new_string(lsa->name));
1181 json_object_object_add(json_obj, "pendingLsaLsAck", json_arr);
1182
1183 } else {
1184 timerclear(&res);
1185 if (thread_is_scheduled(oi->thread_send_lsupdate))
1186 timersub(&oi->thread_send_lsupdate->u.sands, &now,
1187 &res);
1188 timerstring(&res, duration, sizeof(duration));
1189 vty_out(vty,
1190 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
1191 oi->lsupdate_list->count, duration,
1192 (thread_is_scheduled(oi->thread_send_lsupdate)
1193 ? "on"
1194 : "off"));
1195 for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
1196 vty_out(vty, " %s\n", lsa->name);
1197
1198 timerclear(&res);
1199 if (thread_is_scheduled(oi->thread_send_lsack))
1200 timersub(&oi->thread_send_lsack->u.sands, &now, &res);
1201 timerstring(&res, duration, sizeof(duration));
1202 vty_out(vty,
1203 " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
1204 oi->lsack_list->count, duration,
1205 (thread_is_scheduled(oi->thread_send_lsack) ? "on"
1206 : "off"));
1207 for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
1208 vty_out(vty, " %s\n", lsa->name);
1209 }
1210
1211 /* BFD specific. */
1212 if (oi->bfd_config.enabled) {
1213 if (use_json) {
1214 struct json_object *json_bfd = json_object_new_object();
1215
1216 json_object_int_add(
1217 json_bfd, "detectMultiplier",
1218 oi->bfd_config.detection_multiplier);
1219 json_object_int_add(json_bfd, "rxMinInterval",
1220 oi->bfd_config.min_rx);
1221 json_object_int_add(json_bfd, "txMinInterval",
1222 oi->bfd_config.min_tx);
1223 json_object_object_add(json_obj, "peerBfdInfo",
1224 json_bfd);
1225 } else {
1226 vty_out(vty,
1227 " BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
1228 oi->bfd_config.detection_multiplier,
1229 oi->bfd_config.min_rx, oi->bfd_config.min_tx);
1230 }
1231 }
1232
1233 if (use_json)
1234 json_auth = json_object_new_object();
1235 if (oi->at_data.flags != 0) {
1236 if (use_json) {
1237 if (CHECK_FLAG(oi->at_data.flags,
1238 OSPF6_AUTH_TRAILER_KEYCHAIN)) {
1239 json_object_string_add(json_auth, "authType",
1240 "keychain");
1241 json_object_string_add(json_auth,
1242 "keychainName",
1243 oi->at_data.keychain);
1244 } else if (CHECK_FLAG(oi->at_data.flags,
1245 OSPF6_AUTH_TRAILER_MANUAL_KEY))
1246 json_object_string_add(json_auth, "authType",
1247 "manualkey");
1248 json_object_int_add(json_auth, "txPktDrop",
1249 oi->at_data.tx_drop);
1250 json_object_int_add(json_auth, "rxPktDrop",
1251 oi->at_data.rx_drop);
1252 } else {
1253 if (CHECK_FLAG(oi->at_data.flags,
1254 OSPF6_AUTH_TRAILER_KEYCHAIN))
1255 vty_out(vty,
1256 " Authentication Trailer is enabled with key-chain %s\n",
1257 oi->at_data.keychain);
1258 else if (CHECK_FLAG(oi->at_data.flags,
1259 OSPF6_AUTH_TRAILER_MANUAL_KEY))
1260 vty_out(vty,
1261 " Authentication trailer is enabled with manual key\n");
1262 vty_out(vty,
1263 " Packet drop Tx %u, Packet drop Rx %u\n",
1264 oi->at_data.tx_drop, oi->at_data.rx_drop);
1265 }
1266 } else {
1267 if (use_json)
1268 json_object_string_add(json_auth, "authType", "NULL");
1269 else
1270 vty_out(vty, " Authentication Trailer is disabled\n");
1271 }
1272
1273 if (use_json)
1274 json_object_object_add(json_obj, "authInfo", json_auth);
1275
1276 return 0;
1277 }
1278
1279 /* Find the global address to be used as a forwarding address in NSSA LSA.*/
1280 struct in6_addr *ospf6_interface_get_global_address(struct interface *ifp)
1281 {
1282 struct listnode *n;
1283 struct connected *c;
1284
1285 /* for each connected address */
1286 for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
1287 /* if family not AF_INET6, ignore */
1288 if (c->address->family != AF_INET6)
1289 continue;
1290
1291 if (!IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
1292 return &c->address->u.prefix6;
1293 }
1294
1295 return NULL;
1296 }
1297
1298
1299 static int show_ospf6_interface_common(struct vty *vty, vrf_id_t vrf_id,
1300 int argc, struct cmd_token **argv,
1301 int idx_ifname, int intf_idx,
1302 int json_idx, bool uj)
1303 {
1304
1305 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
1306 struct interface *ifp;
1307 json_object *json;
1308 json_object *json_int;
1309
1310 if (uj) {
1311 json = json_object_new_object();
1312 if (argc == json_idx) {
1313 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
1314 json_int = json_object_new_object();
1315 if (ifp == NULL) {
1316 json_object_string_add(json, "noSuchInterface",
1317 argv[idx_ifname]->arg);
1318 vty_json(vty, json);
1319 json_object_free(json_int);
1320 return CMD_WARNING;
1321 }
1322 ospf6_interface_show(vty, ifp, json_int, uj);
1323 json_object_object_add(json, ifp->name, json_int);
1324 } else {
1325 FOR_ALL_INTERFACES (vrf, ifp) {
1326 json_int = json_object_new_object();
1327 ospf6_interface_show(vty, ifp, json_int, uj);
1328 json_object_object_add(json, ifp->name,
1329 json_int);
1330 }
1331 }
1332 vty_json(vty, json);
1333 } else {
1334 if (argc == intf_idx) {
1335 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
1336 if (ifp == NULL) {
1337 vty_out(vty, "No such Interface: %s\n",
1338 argv[idx_ifname]->arg);
1339 return CMD_WARNING;
1340 }
1341 ospf6_interface_show(vty, ifp, NULL, uj);
1342 } else {
1343 FOR_ALL_INTERFACES (vrf, ifp)
1344 ospf6_interface_show(vty, ifp, NULL, uj);
1345 }
1346 }
1347 return CMD_SUCCESS;
1348 }
1349
1350 /* show interface */
1351 DEFUN(show_ipv6_ospf6_interface, show_ipv6_ospf6_interface_ifname_cmd,
1352 "show ipv6 ospf6 [vrf <NAME|all>] interface [IFNAME] [json]",
1353 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1354 "All VRFs\n" INTERFACE_STR IFNAME_STR JSON_STR)
1355 {
1356 int idx_ifname = 4;
1357 int intf_idx = 5;
1358 int json_idx = 6;
1359 struct listnode *node;
1360 struct ospf6 *ospf6;
1361 const char *vrf_name = NULL;
1362 bool all_vrf = false;
1363 int idx_vrf = 0;
1364 bool uj = use_json(argc, argv);
1365
1366 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1367 if (idx_vrf > 0) {
1368 idx_ifname += 2;
1369 intf_idx += 2;
1370 json_idx += 2;
1371 }
1372
1373 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1374 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1375 show_ospf6_interface_common(vty, ospf6->vrf_id, argc,
1376 argv, idx_ifname, intf_idx,
1377 json_idx, uj);
1378
1379 if (!all_vrf)
1380 break;
1381 }
1382 }
1383
1384 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1385
1386 return CMD_SUCCESS;
1387 }
1388
1389 static int ospf6_interface_show_traffic(struct vty *vty,
1390 struct interface *intf_ifp,
1391 int display_once, json_object *json,
1392 bool use_json, vrf_id_t vrf_id)
1393 {
1394 struct interface *ifp;
1395 struct vrf *vrf = NULL;
1396 struct ospf6_interface *oi = NULL;
1397 json_object *json_interface;
1398
1399 if (!display_once && !use_json) {
1400 vty_out(vty, "\n");
1401 vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1402 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1403 " LS-Ack");
1404 vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
1405 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1406 " Rx/Tx");
1407 vty_out(vty,
1408 "--------------------------------------------------------------------------------------------\n");
1409 }
1410
1411 if (intf_ifp == NULL) {
1412 vrf = vrf_lookup_by_id(vrf_id);
1413 FOR_ALL_INTERFACES (vrf, ifp) {
1414 if (ifp->info)
1415 oi = (struct ospf6_interface *)ifp->info;
1416 else
1417 continue;
1418
1419 if (use_json) {
1420 json_interface = json_object_new_object();
1421 json_object_int_add(json_interface, "helloRx",
1422 oi->hello_in);
1423 json_object_int_add(json_interface, "helloTx",
1424 oi->hello_out);
1425 json_object_int_add(json_interface, "dbDescRx",
1426 oi->db_desc_in);
1427 json_object_int_add(json_interface, "dbDescTx",
1428 oi->db_desc_out);
1429 json_object_int_add(json_interface, "lsReqRx",
1430 oi->ls_req_in);
1431 json_object_int_add(json_interface, "lsReqTx",
1432 oi->ls_req_out);
1433 json_object_int_add(json_interface,
1434 "lsUpdateRx",
1435 oi->ls_upd_in);
1436 json_object_int_add(json_interface,
1437 "lsUpdateTx",
1438 oi->ls_upd_out);
1439 json_object_int_add(json_interface, "lsAckRx",
1440 oi->ls_ack_in);
1441 json_object_int_add(json_interface, "lsAckTx",
1442 oi->ls_ack_out);
1443
1444 json_object_object_add(json,
1445 oi->interface->name,
1446 json_interface);
1447 } else
1448 vty_out(vty,
1449 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1450 oi->interface->name, oi->hello_in,
1451 oi->hello_out, oi->db_desc_in,
1452 oi->db_desc_out, oi->ls_req_in,
1453 oi->ls_req_out, oi->ls_upd_in,
1454 oi->ls_upd_out, oi->ls_ack_in,
1455 oi->ls_ack_out);
1456 }
1457 } else {
1458 oi = intf_ifp->info;
1459 if (oi == NULL)
1460 return CMD_WARNING;
1461
1462 if (use_json) {
1463 json_interface = json_object_new_object();
1464 json_object_int_add(json_interface, "helloRx",
1465 oi->hello_in);
1466 json_object_int_add(json_interface, "helloTx",
1467 oi->hello_out);
1468 json_object_int_add(json_interface, "dbDescRx",
1469 oi->db_desc_in);
1470 json_object_int_add(json_interface, "dbDescTx",
1471 oi->db_desc_out);
1472 json_object_int_add(json_interface, "lsReqRx",
1473 oi->ls_req_in);
1474 json_object_int_add(json_interface, "lsReqTx",
1475 oi->ls_req_out);
1476 json_object_int_add(json_interface, "lsUpdateRx",
1477 oi->ls_upd_in);
1478 json_object_int_add(json_interface, "lsUpdateTx",
1479 oi->ls_upd_out);
1480 json_object_int_add(json_interface, "lsAckRx",
1481 oi->ls_ack_in);
1482 json_object_int_add(json_interface, "lsAckTx",
1483 oi->ls_ack_out);
1484
1485 json_object_object_add(json, oi->interface->name,
1486 json_interface);
1487 } else
1488 vty_out(vty,
1489 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1490 oi->interface->name, oi->hello_in,
1491 oi->hello_out, oi->db_desc_in, oi->db_desc_out,
1492 oi->ls_req_in, oi->ls_req_out, oi->ls_upd_in,
1493 oi->ls_upd_out, oi->ls_ack_in, oi->ls_ack_out);
1494 }
1495
1496 return CMD_SUCCESS;
1497 }
1498
1499 static int ospf6_interface_show_traffic_common(struct vty *vty, int argc,
1500 struct cmd_token **argv,
1501 vrf_id_t vrf_id, bool uj)
1502 {
1503 int idx_ifname = 0;
1504 int display_once = 0;
1505 char *intf_name = NULL;
1506 struct interface *ifp = NULL;
1507 json_object *json = NULL;
1508
1509 if (uj)
1510 json = json_object_new_object();
1511
1512 if (argv_find(argv, argc, "IFNAME", &idx_ifname)) {
1513 intf_name = argv[idx_ifname]->arg;
1514 ifp = if_lookup_by_name(intf_name, vrf_id);
1515 if (uj) {
1516 if (ifp == NULL) {
1517 json_object_string_add(json, "status",
1518 "No Such Interface");
1519 json_object_string_add(json, "interface",
1520 intf_name);
1521 vty_json(vty, json);
1522 return CMD_WARNING;
1523 }
1524 if (ifp->info == NULL) {
1525 json_object_string_add(
1526 json, "status",
1527 "OSPF not enabled on this interface");
1528 json_object_string_add(json, "interface",
1529 intf_name);
1530 vty_json(vty, json);
1531 return 0;
1532 }
1533 } else {
1534 if (ifp == NULL) {
1535 vty_out(vty, "No such Interface: %s\n",
1536 intf_name);
1537 return CMD_WARNING;
1538 }
1539 if (ifp->info == NULL) {
1540 vty_out(vty,
1541 " OSPF not enabled on this interface %s\n",
1542 intf_name);
1543 return 0;
1544 }
1545 }
1546 }
1547
1548 ospf6_interface_show_traffic(vty, ifp, display_once, json, uj, vrf_id);
1549
1550 if (uj)
1551 vty_json(vty, json);
1552
1553 return CMD_SUCCESS;
1554 }
1555
1556 /* show interface */
1557 DEFUN(show_ipv6_ospf6_interface_traffic, show_ipv6_ospf6_interface_traffic_cmd,
1558 "show ipv6 ospf6 [vrf <NAME|all>] interface traffic [IFNAME] [json]",
1559 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1560 "All VRFs\n" INTERFACE_STR
1561 "Protocol Packet counters\n" IFNAME_STR JSON_STR)
1562 {
1563 struct ospf6 *ospf6;
1564 struct listnode *node;
1565 const char *vrf_name = NULL;
1566 bool all_vrf = false;
1567 int idx_vrf = 0;
1568 bool uj = use_json(argc, argv);
1569
1570 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1571
1572 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1573 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1574 ospf6_interface_show_traffic_common(vty, argc, argv,
1575 ospf6->vrf_id, uj);
1576
1577 if (!all_vrf)
1578 break;
1579 }
1580 }
1581
1582 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1583
1584 return CMD_SUCCESS;
1585 }
1586
1587
1588 DEFUN(show_ipv6_ospf6_interface_ifname_prefix,
1589 show_ipv6_ospf6_interface_ifname_prefix_cmd,
1590 "show ipv6 ospf6 [vrf <NAME|all>] interface IFNAME prefix\
1591 [<\
1592 detail\
1593 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1594 >] [json]",
1595 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1596 "All VRFs\n" INTERFACE_STR IFNAME_STR
1597 "Display connected prefixes to advertise\n"
1598 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1599 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1600 "Display details of the prefixes\n" JSON_STR)
1601 {
1602 int idx_ifname = 4;
1603 int idx_prefix = 6;
1604 struct ospf6_interface *oi;
1605 bool uj = use_json(argc, argv);
1606
1607 struct ospf6 *ospf6;
1608 struct listnode *node;
1609 struct interface *ifp;
1610 const char *vrf_name = NULL;
1611 bool all_vrf = false;
1612 int idx_vrf = 0;
1613
1614 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1615 if (idx_vrf > 0) {
1616 idx_ifname += 2;
1617 idx_prefix += 2;
1618 }
1619
1620 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1621 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1622 ifp = if_lookup_by_name(argv[idx_ifname]->arg,
1623 ospf6->vrf_id);
1624 if (ifp == NULL) {
1625 vty_out(vty, "No such Interface: %s\n",
1626 argv[idx_ifname]->arg);
1627 return CMD_WARNING;
1628 }
1629
1630 oi = ifp->info;
1631 if (oi == NULL
1632 || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) {
1633 vty_out(vty,
1634 "Interface %s not attached to area\n",
1635 argv[idx_ifname]->arg);
1636 return CMD_WARNING;
1637 }
1638
1639 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1640 oi->route_connected, uj);
1641
1642 if (!all_vrf)
1643 break;
1644 }
1645 }
1646
1647 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1648
1649 return CMD_SUCCESS;
1650 }
1651
1652 DEFUN(show_ipv6_ospf6_interface_prefix, show_ipv6_ospf6_interface_prefix_cmd,
1653 "show ipv6 ospf6 [vrf <NAME|all>] interface prefix\
1654 [<\
1655 detail\
1656 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1657 >] [json]",
1658 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1659 "All VRFs\n" INTERFACE_STR
1660 "Display connected prefixes to advertise\n"
1661 "Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
1662 OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
1663 "Display details of the prefixes\n" JSON_STR)
1664 {
1665 struct vrf *vrf = NULL;
1666 int idx_prefix = 5;
1667 struct ospf6_interface *oi;
1668 struct interface *ifp;
1669 bool uj = use_json(argc, argv);
1670 struct listnode *node;
1671 struct ospf6 *ospf6;
1672 const char *vrf_name = NULL;
1673 bool all_vrf = false;
1674 int idx_vrf = 0;
1675
1676 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1677 if (idx_vrf > 0)
1678 idx_prefix += 2;
1679
1680 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1681 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1682 vrf = vrf_lookup_by_id(ospf6->vrf_id);
1683 FOR_ALL_INTERFACES (vrf, ifp) {
1684 oi = (struct ospf6_interface *)ifp->info;
1685 if (oi == NULL
1686 || CHECK_FLAG(oi->flag,
1687 OSPF6_INTERFACE_DISABLE))
1688 continue;
1689
1690 ospf6_route_table_show(vty, idx_prefix, argc,
1691 argv,
1692 oi->route_connected, uj);
1693 }
1694 if (!all_vrf)
1695 break;
1696 }
1697 }
1698
1699 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1700
1701 return CMD_SUCCESS;
1702 }
1703
1704 void ospf6_interface_start(struct ospf6_interface *oi)
1705 {
1706 struct ospf6 *ospf6;
1707 struct ospf6_area *oa;
1708
1709 if (oi->area_id_format == OSPF6_AREA_FMT_UNSET)
1710 return;
1711
1712 if (oi->area) {
1713 /* Recompute cost */
1714 ospf6_interface_recalculate_cost(oi);
1715 return;
1716 }
1717
1718 ospf6 = oi->interface->vrf->info;
1719 if (!ospf6)
1720 return;
1721
1722 oa = ospf6_area_lookup(oi->area_id, ospf6);
1723 if (oa == NULL)
1724 oa = ospf6_area_create(oi->area_id, ospf6, oi->area_id_format);
1725
1726 /* attach interface to area */
1727 listnode_add(oa->if_list, oi);
1728 oi->area = oa;
1729
1730 SET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
1731
1732 /* start up */
1733 ospf6_interface_enable(oi);
1734
1735 /* If the router is ABR, originate summary routes */
1736 if (ospf6_check_and_set_router_abr(ospf6)) {
1737 ospf6_abr_enable_area(oa);
1738 ospf6_schedule_abr_task(ospf6);
1739 }
1740 }
1741
1742 void ospf6_interface_stop(struct ospf6_interface *oi)
1743 {
1744 struct ospf6_area *oa;
1745
1746 oa = oi->area;
1747 if (!oa)
1748 return;
1749
1750 ospf6_interface_disable(oi);
1751
1752 listnode_delete(oa->if_list, oi);
1753 oi->area = NULL;
1754
1755 if (oa->if_list->count == 0) {
1756 UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
1757 ospf6_abr_disable_area(oa);
1758 }
1759 }
1760
1761 /* interface variable set command */
1762 DEFUN (ipv6_ospf6_area,
1763 ipv6_ospf6_area_cmd,
1764 "ipv6 ospf6 area <A.B.C.D|(0-4294967295)>",
1765 IP6_STR
1766 OSPF6_STR
1767 "Specify the OSPF6 area ID\n"
1768 "OSPF6 area ID in IPv4 address notation\n"
1769 "OSPF6 area ID in decimal notation\n")
1770 {
1771 VTY_DECLVAR_CONTEXT(interface, ifp);
1772 struct ospf6_interface *oi;
1773 int idx_ipv4 = 3;
1774 uint32_t area_id;
1775 int format;
1776
1777 assert(ifp);
1778
1779 oi = (struct ospf6_interface *)ifp->info;
1780 if (oi == NULL)
1781 oi = ospf6_interface_create(ifp);
1782 assert(oi);
1783
1784 if (oi->area) {
1785 vty_out(vty, "%s already attached to Area %s\n",
1786 oi->interface->name, oi->area->name);
1787 return CMD_SUCCESS;
1788 }
1789
1790 if (str2area_id(argv[idx_ipv4]->arg, &area_id, &format)) {
1791 vty_out(vty, "Malformed Area-ID: %s\n", argv[idx_ipv4]->arg);
1792 return CMD_WARNING_CONFIG_FAILED;
1793 }
1794
1795 oi->area_id = area_id;
1796 oi->area_id_format = format;
1797
1798 ospf6_interface_start(oi);
1799
1800 return CMD_SUCCESS;
1801 }
1802
1803 DEFUN (no_ipv6_ospf6_area,
1804 no_ipv6_ospf6_area_cmd,
1805 "no ipv6 ospf6 area [<A.B.C.D|(0-4294967295)>]",
1806 NO_STR
1807 IP6_STR
1808 OSPF6_STR
1809 "Specify the OSPF6 area ID\n"
1810 "OSPF6 area ID in IPv4 address notation\n"
1811 "OSPF6 area ID in decimal notation\n")
1812 {
1813 VTY_DECLVAR_CONTEXT(interface, ifp);
1814 struct ospf6_interface *oi;
1815
1816 assert(ifp);
1817
1818 oi = (struct ospf6_interface *)ifp->info;
1819 if (oi == NULL)
1820 oi = ospf6_interface_create(ifp);
1821 assert(oi);
1822
1823 ospf6_interface_stop(oi);
1824
1825 oi->area_id = 0;
1826 oi->area_id_format = OSPF6_AREA_FMT_UNSET;
1827
1828 return CMD_SUCCESS;
1829 }
1830
1831 DEFUN (ipv6_ospf6_ifmtu,
1832 ipv6_ospf6_ifmtu_cmd,
1833 "ipv6 ospf6 ifmtu (1-65535)",
1834 IP6_STR
1835 OSPF6_STR
1836 "Interface MTU\n"
1837 "OSPFv3 Interface MTU\n"
1838 )
1839 {
1840 VTY_DECLVAR_CONTEXT(interface, ifp);
1841 int idx_number = 3;
1842 struct ospf6_interface *oi;
1843 unsigned int ifmtu, iobuflen;
1844 struct listnode *node, *nnode;
1845 struct ospf6_neighbor *on;
1846
1847 assert(ifp);
1848
1849 oi = (struct ospf6_interface *)ifp->info;
1850 if (oi == NULL)
1851 oi = ospf6_interface_create(ifp);
1852 assert(oi);
1853
1854 ifmtu = strtol(argv[idx_number]->arg, NULL, 10);
1855
1856 if (oi->c_ifmtu == ifmtu)
1857 return CMD_SUCCESS;
1858
1859 if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) {
1860 vty_out(vty,
1861 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1862 ifp->name, ifp->mtu6);
1863 return CMD_WARNING_CONFIG_FAILED;
1864 }
1865
1866 if (oi->ifmtu < ifmtu) {
1867 iobuflen = ospf6_iobuf_size(ifmtu);
1868 if (iobuflen < ifmtu) {
1869 vty_out(vty,
1870 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1871 ifp->name, iobuflen);
1872 oi->ifmtu = oi->c_ifmtu = iobuflen;
1873 } else
1874 oi->ifmtu = oi->c_ifmtu = ifmtu;
1875 } else
1876 oi->ifmtu = oi->c_ifmtu = ifmtu;
1877
1878 /* re-establish adjacencies */
1879 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1880 THREAD_OFF(on->inactivity_timer);
1881 thread_add_event(master, inactivity_timer, on, 0, NULL);
1882 }
1883
1884 return CMD_SUCCESS;
1885 }
1886
1887 DEFUN (no_ipv6_ospf6_ifmtu,
1888 no_ipv6_ospf6_ifmtu_cmd,
1889 "no ipv6 ospf6 ifmtu [(1-65535)]",
1890 NO_STR
1891 IP6_STR
1892 OSPF6_STR
1893 "Interface MTU\n"
1894 "OSPFv3 Interface MTU\n"
1895 )
1896 {
1897 VTY_DECLVAR_CONTEXT(interface, ifp);
1898 struct ospf6_interface *oi;
1899 unsigned int iobuflen;
1900 struct listnode *node, *nnode;
1901 struct ospf6_neighbor *on;
1902
1903 assert(ifp);
1904
1905 oi = (struct ospf6_interface *)ifp->info;
1906 if (oi == NULL)
1907 oi = ospf6_interface_create(ifp);
1908 assert(oi);
1909
1910 if (oi->ifmtu < ifp->mtu) {
1911 iobuflen = ospf6_iobuf_size(ifp->mtu);
1912 if (iobuflen < ifp->mtu) {
1913 vty_out(vty,
1914 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1915 ifp->name, iobuflen);
1916 oi->ifmtu = iobuflen;
1917 } else
1918 oi->ifmtu = ifp->mtu;
1919 } else
1920 oi->ifmtu = ifp->mtu;
1921
1922 oi->c_ifmtu = 0;
1923
1924 /* re-establish adjacencies */
1925 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1926 THREAD_OFF(on->inactivity_timer);
1927 thread_add_event(master, inactivity_timer, on, 0, NULL);
1928 }
1929
1930 return CMD_SUCCESS;
1931 }
1932
1933 DEFUN (ipv6_ospf6_cost,
1934 ipv6_ospf6_cost_cmd,
1935 "ipv6 ospf6 cost (1-65535)",
1936 IP6_STR
1937 OSPF6_STR
1938 "Interface cost\n"
1939 "Outgoing metric of this interface\n")
1940 {
1941 VTY_DECLVAR_CONTEXT(interface, ifp);
1942 int idx_number = 3;
1943 struct ospf6_interface *oi;
1944 unsigned long int lcost;
1945
1946 assert(ifp);
1947
1948 oi = (struct ospf6_interface *)ifp->info;
1949 if (oi == NULL)
1950 oi = ospf6_interface_create(ifp);
1951 assert(oi);
1952
1953 lcost = strtol(argv[idx_number]->arg, NULL, 10);
1954
1955 if (lcost > UINT32_MAX) {
1956 vty_out(vty, "Cost %ld is out of range\n", lcost);
1957 return CMD_WARNING_CONFIG_FAILED;
1958 }
1959
1960 SET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1961 if (oi->cost == lcost)
1962 return CMD_SUCCESS;
1963
1964 oi->cost = lcost;
1965 ospf6_interface_force_recalculate_cost(oi);
1966
1967 return CMD_SUCCESS;
1968 }
1969
1970 DEFUN (no_ipv6_ospf6_cost,
1971 no_ipv6_ospf6_cost_cmd,
1972 "no ipv6 ospf6 cost [(1-65535)]",
1973 NO_STR
1974 IP6_STR
1975 OSPF6_STR
1976 "Calculate interface cost from bandwidth\n"
1977 "Outgoing metric of this interface\n")
1978 {
1979 VTY_DECLVAR_CONTEXT(interface, ifp);
1980 struct ospf6_interface *oi;
1981 assert(ifp);
1982
1983 oi = (struct ospf6_interface *)ifp->info;
1984 if (oi == NULL)
1985 oi = ospf6_interface_create(ifp);
1986 assert(oi);
1987
1988 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1989
1990 ospf6_interface_recalculate_cost(oi);
1991
1992 return CMD_SUCCESS;
1993 }
1994
1995 DEFUN (auto_cost_reference_bandwidth,
1996 auto_cost_reference_bandwidth_cmd,
1997 "auto-cost reference-bandwidth (1-4294967)",
1998 "Calculate OSPF interface cost according to bandwidth\n"
1999 "Use reference bandwidth method to assign OSPF cost\n"
2000 "The reference bandwidth in terms of Mbits per second\n")
2001 {
2002 VTY_DECLVAR_CONTEXT(ospf6, o);
2003 int idx_number = 2;
2004 struct ospf6_area *oa;
2005 struct ospf6_interface *oi;
2006 struct listnode *i, *j;
2007 uint32_t refbw;
2008
2009 refbw = strtol(argv[idx_number]->arg, NULL, 10);
2010 if (refbw < 1 || refbw > 4294967) {
2011 vty_out(vty, "reference-bandwidth value is invalid\n");
2012 return CMD_WARNING_CONFIG_FAILED;
2013 }
2014
2015 /* If reference bandwidth is changed. */
2016 if ((refbw) == o->ref_bandwidth)
2017 return CMD_SUCCESS;
2018
2019 o->ref_bandwidth = refbw;
2020 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
2021 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
2022 ospf6_interface_recalculate_cost(oi);
2023
2024 return CMD_SUCCESS;
2025 }
2026
2027 DEFUN (no_auto_cost_reference_bandwidth,
2028 no_auto_cost_reference_bandwidth_cmd,
2029 "no auto-cost reference-bandwidth [(1-4294967)]",
2030 NO_STR
2031 "Calculate OSPF interface cost according to bandwidth\n"
2032 "Use reference bandwidth method to assign OSPF cost\n"
2033 "The reference bandwidth in terms of Mbits per second\n")
2034 {
2035 VTY_DECLVAR_CONTEXT(ospf6, o);
2036 struct ospf6_area *oa;
2037 struct ospf6_interface *oi;
2038 struct listnode *i, *j;
2039
2040 if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH)
2041 return CMD_SUCCESS;
2042
2043 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
2044 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
2045 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
2046 ospf6_interface_recalculate_cost(oi);
2047
2048 return CMD_SUCCESS;
2049 }
2050
2051
2052 DEFUN (ospf6_write_multiplier,
2053 ospf6_write_multiplier_cmd,
2054 "write-multiplier (1-100)",
2055 "Write multiplier\n"
2056 "Maximum number of interface serviced per write\n")
2057 {
2058 VTY_DECLVAR_CONTEXT(ospf6, o);
2059 uint32_t write_oi_count;
2060
2061 write_oi_count = strtol(argv[1]->arg, NULL, 10);
2062 if (write_oi_count < 1 || write_oi_count > 100) {
2063 vty_out(vty, "write-multiplier value is invalid\n");
2064 return CMD_WARNING_CONFIG_FAILED;
2065 }
2066
2067 o->write_oi_count = write_oi_count;
2068 return CMD_SUCCESS;
2069 }
2070
2071 DEFUN (no_ospf6_write_multiplier,
2072 no_ospf6_write_multiplier_cmd,
2073 "no write-multiplier (1-100)",
2074 NO_STR
2075 "Write multiplier\n"
2076 "Maximum number of interface serviced per write\n")
2077 {
2078 VTY_DECLVAR_CONTEXT(ospf6, o);
2079
2080 o->write_oi_count = OSPF6_WRITE_INTERFACE_COUNT_DEFAULT;
2081 return CMD_SUCCESS;
2082 }
2083
2084 DEFUN (ipv6_ospf6_hellointerval,
2085 ipv6_ospf6_hellointerval_cmd,
2086 "ipv6 ospf6 hello-interval (1-65535)",
2087 IP6_STR
2088 OSPF6_STR
2089 "Time between HELLO packets\n"
2090 SECONDS_STR)
2091 {
2092 VTY_DECLVAR_CONTEXT(interface, ifp);
2093 int idx_number = 3;
2094 struct ospf6_interface *oi;
2095 assert(ifp);
2096
2097 oi = (struct ospf6_interface *)ifp->info;
2098 if (oi == NULL)
2099 oi = ospf6_interface_create(ifp);
2100 assert(oi);
2101
2102 oi->hello_interval = strmatch(argv[0]->text, "no")
2103 ? OSPF_HELLO_INTERVAL_DEFAULT
2104 : strtoul(argv[idx_number]->arg, NULL, 10);
2105
2106 /*
2107 * If the thread is scheduled, send the new hello now.
2108 */
2109 if (thread_is_scheduled(oi->thread_send_hello)) {
2110 THREAD_OFF(oi->thread_send_hello);
2111
2112 thread_add_timer(master, ospf6_hello_send, oi, 0,
2113 &oi->thread_send_hello);
2114 }
2115 return CMD_SUCCESS;
2116 }
2117
2118 ALIAS (ipv6_ospf6_hellointerval,
2119 no_ipv6_ospf6_hellointerval_cmd,
2120 "no ipv6 ospf6 hello-interval [(1-65535)]",
2121 NO_STR
2122 IP6_STR
2123 OSPF6_STR
2124 "Time between HELLO packets\n"
2125 SECONDS_STR)
2126
2127 /* interface variable set command */
2128 DEFUN (ipv6_ospf6_deadinterval,
2129 ipv6_ospf6_deadinterval_cmd,
2130 "ipv6 ospf6 dead-interval (1-65535)",
2131 IP6_STR
2132 OSPF6_STR
2133 "Interval time after which a neighbor is declared down\n"
2134 SECONDS_STR)
2135 {
2136 VTY_DECLVAR_CONTEXT(interface, ifp);
2137 int idx_number = 3;
2138 struct ospf6_interface *oi;
2139 assert(ifp);
2140
2141 oi = (struct ospf6_interface *)ifp->info;
2142 if (oi == NULL)
2143 oi = ospf6_interface_create(ifp);
2144 assert(oi);
2145
2146 oi->dead_interval = strmatch(argv[0]->arg, "no")
2147 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
2148 : strtoul(argv[idx_number]->arg, NULL, 10);
2149 return CMD_SUCCESS;
2150 }
2151
2152 ALIAS (ipv6_ospf6_deadinterval,
2153 no_ipv6_ospf6_deadinterval_cmd,
2154 "no ipv6 ospf6 dead-interval [(1-65535)]",
2155 NO_STR
2156 IP6_STR
2157 OSPF6_STR
2158 "Interval time after which a neighbor is declared down\n"
2159 SECONDS_STR)
2160
2161 /* interface variable set command */
2162 DEFUN (ipv6_ospf6_transmitdelay,
2163 ipv6_ospf6_transmitdelay_cmd,
2164 "ipv6 ospf6 transmit-delay (1-3600)",
2165 IP6_STR
2166 OSPF6_STR
2167 "Link state transmit delay\n"
2168 SECONDS_STR)
2169 {
2170 VTY_DECLVAR_CONTEXT(interface, ifp);
2171 int idx_number = 3;
2172 struct ospf6_interface *oi;
2173 assert(ifp);
2174
2175 oi = (struct ospf6_interface *)ifp->info;
2176 if (oi == NULL)
2177 oi = ospf6_interface_create(ifp);
2178 assert(oi);
2179
2180 oi->transdelay = strmatch(argv[0]->text, "no")
2181 ? OSPF6_INTERFACE_TRANSDELAY
2182 : strtoul(argv[idx_number]->arg, NULL, 10);
2183 return CMD_SUCCESS;
2184 }
2185
2186 ALIAS (ipv6_ospf6_transmitdelay,
2187 no_ipv6_ospf6_transmitdelay_cmd,
2188 "no ipv6 ospf6 transmit-delay [(1-3600)]",
2189 NO_STR
2190 IP6_STR
2191 OSPF6_STR
2192 "Link state transmit delay\n"
2193 SECONDS_STR)
2194
2195 /* interface variable set command */
2196 DEFUN (ipv6_ospf6_retransmitinterval,
2197 ipv6_ospf6_retransmitinterval_cmd,
2198 "ipv6 ospf6 retransmit-interval (1-65535)",
2199 IP6_STR
2200 OSPF6_STR
2201 "Time between retransmitting lost link state advertisements\n"
2202 SECONDS_STR)
2203 {
2204 VTY_DECLVAR_CONTEXT(interface, ifp);
2205 int idx_number = 3;
2206 struct ospf6_interface *oi;
2207 assert(ifp);
2208
2209 oi = (struct ospf6_interface *)ifp->info;
2210 if (oi == NULL)
2211 oi = ospf6_interface_create(ifp);
2212 assert(oi);
2213
2214 oi->rxmt_interval = strmatch(argv[0]->text, "no")
2215 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
2216 : strtoul(argv[idx_number]->arg, NULL, 10);
2217 return CMD_SUCCESS;
2218 }
2219
2220 ALIAS (ipv6_ospf6_retransmitinterval,
2221 no_ipv6_ospf6_retransmitinterval_cmd,
2222 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
2223 NO_STR
2224 IP6_STR
2225 OSPF6_STR
2226 "Time between retransmitting lost link state advertisements\n"
2227 SECONDS_STR)
2228
2229 /* interface variable set command */
2230 DEFUN (ipv6_ospf6_priority,
2231 ipv6_ospf6_priority_cmd,
2232 "ipv6 ospf6 priority (0-255)",
2233 IP6_STR
2234 OSPF6_STR
2235 "Router priority\n"
2236 "Priority value\n")
2237 {
2238 VTY_DECLVAR_CONTEXT(interface, ifp);
2239 int idx_number = 3;
2240 struct ospf6_interface *oi;
2241 assert(ifp);
2242
2243 oi = (struct ospf6_interface *)ifp->info;
2244 if (oi == NULL)
2245 oi = ospf6_interface_create(ifp);
2246 assert(oi);
2247
2248 oi->priority = strmatch(argv[0]->text, "no")
2249 ? OSPF6_INTERFACE_PRIORITY
2250 : strtoul(argv[idx_number]->arg, NULL, 10);
2251
2252 if (oi->area
2253 && (oi->state == OSPF6_INTERFACE_DROTHER
2254 || oi->state == OSPF6_INTERFACE_BDR
2255 || oi->state == OSPF6_INTERFACE_DR)) {
2256 if (ospf6_interface_state_change(dr_election(oi), oi) == -1)
2257 OSPF6_LINK_LSA_SCHEDULE(oi);
2258 }
2259
2260 return CMD_SUCCESS;
2261 }
2262
2263 ALIAS (ipv6_ospf6_priority,
2264 no_ipv6_ospf6_priority_cmd,
2265 "no ipv6 ospf6 priority [(0-255)]",
2266 NO_STR
2267 IP6_STR
2268 OSPF6_STR
2269 "Router priority\n"
2270 "Priority value\n")
2271
2272 DEFUN (ipv6_ospf6_instance,
2273 ipv6_ospf6_instance_cmd,
2274 "ipv6 ospf6 instance-id (0-255)",
2275 IP6_STR
2276 OSPF6_STR
2277 "Instance ID for this interface\n"
2278 "Instance ID value\n")
2279 {
2280 VTY_DECLVAR_CONTEXT(interface, ifp);
2281 int idx_number = 3;
2282 struct ospf6_interface *oi;
2283 assert(ifp);
2284
2285 oi = (struct ospf6_interface *)ifp->info;
2286 if (oi == NULL)
2287 oi = ospf6_interface_create(ifp);
2288 assert(oi);
2289
2290 oi->instance_id = strmatch(argv[0]->text, "no")
2291 ? OSPF6_INTERFACE_INSTANCE_ID
2292 : strtoul(argv[idx_number]->arg, NULL, 10);
2293 return CMD_SUCCESS;
2294 }
2295
2296 ALIAS (ipv6_ospf6_instance,
2297 no_ipv6_ospf6_instance_cmd,
2298 "no ipv6 ospf6 instance-id [(0-255)]",
2299 NO_STR
2300 IP6_STR
2301 OSPF6_STR
2302 "Instance ID for this interface\n"
2303 "Instance ID value\n")
2304
2305 DEFUN (ipv6_ospf6_passive,
2306 ipv6_ospf6_passive_cmd,
2307 "ipv6 ospf6 passive",
2308 IP6_STR
2309 OSPF6_STR
2310 "Passive interface; no adjacency will be formed on this interface\n"
2311 )
2312 {
2313 VTY_DECLVAR_CONTEXT(interface, ifp);
2314 struct ospf6_interface *oi;
2315 struct listnode *node, *nnode;
2316 struct ospf6_neighbor *on;
2317
2318 assert(ifp);
2319
2320 oi = (struct ospf6_interface *)ifp->info;
2321 if (oi == NULL)
2322 oi = ospf6_interface_create(ifp);
2323 assert(oi);
2324
2325 SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
2326 THREAD_OFF(oi->thread_send_hello);
2327 THREAD_OFF(oi->thread_sso);
2328
2329 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
2330 THREAD_OFF(on->inactivity_timer);
2331 thread_add_event(master, inactivity_timer, on, 0, NULL);
2332 }
2333
2334 return CMD_SUCCESS;
2335 }
2336
2337 DEFUN (no_ipv6_ospf6_passive,
2338 no_ipv6_ospf6_passive_cmd,
2339 "no ipv6 ospf6 passive",
2340 NO_STR
2341 IP6_STR
2342 OSPF6_STR
2343 "passive interface: No Adjacency will be formed on this I/F\n"
2344 )
2345 {
2346 VTY_DECLVAR_CONTEXT(interface, ifp);
2347 struct ospf6_interface *oi;
2348 assert(ifp);
2349
2350 oi = (struct ospf6_interface *)ifp->info;
2351 if (oi == NULL)
2352 oi = ospf6_interface_create(ifp);
2353 assert(oi);
2354
2355 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
2356 THREAD_OFF(oi->thread_send_hello);
2357 THREAD_OFF(oi->thread_sso);
2358
2359 /* don't send hellos over loopback interface */
2360 if (!if_is_loopback(oi->interface))
2361 thread_add_timer(master, ospf6_hello_send, oi, 0,
2362 &oi->thread_send_hello);
2363
2364 return CMD_SUCCESS;
2365 }
2366
2367 DEFUN (ipv6_ospf6_mtu_ignore,
2368 ipv6_ospf6_mtu_ignore_cmd,
2369 "ipv6 ospf6 mtu-ignore",
2370 IP6_STR
2371 OSPF6_STR
2372 "Disable MTU mismatch detection on this interface\n"
2373 )
2374 {
2375 VTY_DECLVAR_CONTEXT(interface, ifp);
2376 struct ospf6_interface *oi;
2377 assert(ifp);
2378
2379 oi = (struct ospf6_interface *)ifp->info;
2380 if (oi == NULL)
2381 oi = ospf6_interface_create(ifp);
2382 assert(oi);
2383
2384 oi->mtu_ignore = 1;
2385
2386 return CMD_SUCCESS;
2387 }
2388
2389 DEFUN (no_ipv6_ospf6_mtu_ignore,
2390 no_ipv6_ospf6_mtu_ignore_cmd,
2391 "no ipv6 ospf6 mtu-ignore",
2392 NO_STR
2393 IP6_STR
2394 OSPF6_STR
2395 "Disable MTU mismatch detection on this interface\n"
2396 )
2397 {
2398 VTY_DECLVAR_CONTEXT(interface, ifp);
2399 struct ospf6_interface *oi;
2400 assert(ifp);
2401
2402 oi = (struct ospf6_interface *)ifp->info;
2403 if (oi == NULL)
2404 oi = ospf6_interface_create(ifp);
2405 assert(oi);
2406
2407 oi->mtu_ignore = 0;
2408
2409 return CMD_SUCCESS;
2410 }
2411
2412 DEFUN (ipv6_ospf6_advertise_prefix_list,
2413 ipv6_ospf6_advertise_prefix_list_cmd,
2414 "ipv6 ospf6 advertise prefix-list WORD",
2415 IP6_STR
2416 OSPF6_STR
2417 "Advertising options\n"
2418 "Filter prefix using prefix-list\n"
2419 "Prefix list name\n"
2420 )
2421 {
2422 VTY_DECLVAR_CONTEXT(interface, ifp);
2423 int idx_word = 4;
2424 struct ospf6_interface *oi;
2425 assert(ifp);
2426
2427 oi = (struct ospf6_interface *)ifp->info;
2428 if (oi == NULL)
2429 oi = ospf6_interface_create(ifp);
2430 assert(oi);
2431
2432 if (oi->plist_name)
2433 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
2434 oi->plist_name = XSTRDUP(MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg);
2435
2436 ospf6_interface_connected_route_update(oi->interface);
2437
2438 if (oi->area) {
2439 OSPF6_LINK_LSA_SCHEDULE(oi);
2440 if (oi->state == OSPF6_INTERFACE_DR) {
2441 OSPF6_NETWORK_LSA_SCHEDULE(oi);
2442 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
2443 }
2444 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
2445 }
2446
2447 return CMD_SUCCESS;
2448 }
2449
2450 DEFUN (no_ipv6_ospf6_advertise_prefix_list,
2451 no_ipv6_ospf6_advertise_prefix_list_cmd,
2452 "no ipv6 ospf6 advertise prefix-list [WORD]",
2453 NO_STR
2454 IP6_STR
2455 OSPF6_STR
2456 "Advertising options\n"
2457 "Filter prefix using prefix-list\n"
2458 "Prefix list name\n")
2459 {
2460 VTY_DECLVAR_CONTEXT(interface, ifp);
2461 struct ospf6_interface *oi;
2462 assert(ifp);
2463
2464 oi = (struct ospf6_interface *)ifp->info;
2465 if (oi == NULL)
2466 oi = ospf6_interface_create(ifp);
2467 assert(oi);
2468
2469 if (oi->plist_name)
2470 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
2471
2472 ospf6_interface_connected_route_update(oi->interface);
2473
2474 if (oi->area) {
2475 OSPF6_LINK_LSA_SCHEDULE(oi);
2476 if (oi->state == OSPF6_INTERFACE_DR) {
2477 OSPF6_NETWORK_LSA_SCHEDULE(oi);
2478 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
2479 }
2480 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
2481 }
2482
2483 return CMD_SUCCESS;
2484 }
2485
2486 DEFUN (ipv6_ospf6_network,
2487 ipv6_ospf6_network_cmd,
2488 "ipv6 ospf6 network <broadcast|point-to-point>",
2489 IP6_STR
2490 OSPF6_STR
2491 "Network type\n"
2492 "Specify OSPF6 broadcast network\n"
2493 "Specify OSPF6 point-to-point network\n"
2494 )
2495 {
2496 VTY_DECLVAR_CONTEXT(interface, ifp);
2497 int idx_network = 3;
2498 struct ospf6_interface *oi;
2499 assert(ifp);
2500
2501 oi = (struct ospf6_interface *)ifp->info;
2502 if (oi == NULL) {
2503 oi = ospf6_interface_create(ifp);
2504 }
2505 assert(oi);
2506
2507 oi->type_cfg = true;
2508
2509 if (strncmp(argv[idx_network]->arg, "b", 1) == 0) {
2510 if (oi->type == OSPF_IFTYPE_BROADCAST)
2511 return CMD_SUCCESS;
2512
2513 oi->type = OSPF_IFTYPE_BROADCAST;
2514 } else if (strncmp(argv[idx_network]->arg, "point-to-p", 10) == 0) {
2515 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
2516 return CMD_SUCCESS;
2517 }
2518 oi->type = OSPF_IFTYPE_POINTOPOINT;
2519 }
2520
2521 /* Reset the interface */
2522 thread_execute(master, interface_down, oi, 0);
2523 thread_execute(master, interface_up, oi, 0);
2524
2525 return CMD_SUCCESS;
2526 }
2527
2528 DEFUN (no_ipv6_ospf6_network,
2529 no_ipv6_ospf6_network_cmd,
2530 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
2531 NO_STR
2532 IP6_STR
2533 OSPF6_STR
2534 "Set default network type\n"
2535 "Specify OSPF6 broadcast network\n"
2536 "Specify OSPF6 point-to-point network\n")
2537 {
2538 VTY_DECLVAR_CONTEXT(interface, ifp);
2539 struct ospf6_interface *oi;
2540 int type;
2541
2542 assert(ifp);
2543
2544 oi = (struct ospf6_interface *)ifp->info;
2545 if (oi == NULL) {
2546 return CMD_SUCCESS;
2547 }
2548
2549 oi->type_cfg = false;
2550
2551 type = ospf6_default_iftype(ifp);
2552 if (oi->type == type) {
2553 return CMD_SUCCESS;
2554 }
2555 oi->type = type;
2556
2557 /* Reset the interface */
2558 thread_execute(master, interface_down, oi, 0);
2559 thread_execute(master, interface_up, oi, 0);
2560
2561 return CMD_SUCCESS;
2562 }
2563
2564 static int config_write_ospf6_interface(struct vty *vty, struct vrf *vrf)
2565 {
2566 struct ospf6_interface *oi;
2567 struct interface *ifp;
2568 char buf[INET_ADDRSTRLEN];
2569
2570 FOR_ALL_INTERFACES (vrf, ifp) {
2571 oi = (struct ospf6_interface *)ifp->info;
2572 if (oi == NULL)
2573 continue;
2574
2575 if_vty_config_start(vty, ifp);
2576
2577 if (ifp->desc)
2578 vty_out(vty, " description %s\n", ifp->desc);
2579 if (oi->area_id_format != OSPF6_AREA_FMT_UNSET) {
2580 area_id2str(buf, sizeof(buf), oi->area_id,
2581 oi->area_id_format);
2582 vty_out(vty, " ipv6 ospf6 area %s\n", buf);
2583 }
2584 if (oi->c_ifmtu)
2585 vty_out(vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu);
2586
2587 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
2588 vty_out(vty, " ipv6 ospf6 cost %d\n", oi->cost);
2589
2590 if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
2591 vty_out(vty, " ipv6 ospf6 hello-interval %d\n",
2592 oi->hello_interval);
2593
2594 if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
2595 vty_out(vty, " ipv6 ospf6 dead-interval %d\n",
2596 oi->dead_interval);
2597
2598 if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
2599 vty_out(vty, " ipv6 ospf6 retransmit-interval %d\n",
2600 oi->rxmt_interval);
2601
2602 if (oi->priority != OSPF6_INTERFACE_PRIORITY)
2603 vty_out(vty, " ipv6 ospf6 priority %d\n", oi->priority);
2604
2605 if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
2606 vty_out(vty, " ipv6 ospf6 transmit-delay %d\n",
2607 oi->transdelay);
2608
2609 if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
2610 vty_out(vty, " ipv6 ospf6 instance-id %d\n",
2611 oi->instance_id);
2612
2613 if (oi->plist_name)
2614 vty_out(vty, " ipv6 ospf6 advertise prefix-list %s\n",
2615 oi->plist_name);
2616
2617 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE))
2618 vty_out(vty, " ipv6 ospf6 passive\n");
2619
2620 if (oi->mtu_ignore)
2621 vty_out(vty, " ipv6 ospf6 mtu-ignore\n");
2622
2623 if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT)
2624 vty_out(vty, " ipv6 ospf6 network point-to-point\n");
2625 else if (oi->type_cfg && oi->type == OSPF_IFTYPE_BROADCAST)
2626 vty_out(vty, " ipv6 ospf6 network broadcast\n");
2627
2628 ospf6_bfd_write_config(vty, oi);
2629
2630 ospf6_auth_write_config(vty, &oi->at_data);
2631 if_vty_config_end(vty);
2632 }
2633 return 0;
2634 }
2635
2636 /* Configuration write function for ospfd. */
2637 static int config_write_interface(struct vty *vty)
2638 {
2639 int write = 0;
2640 struct vrf *vrf = NULL;
2641
2642 /* Display all VRF aware OSPF interface configuration */
2643 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2644 write += config_write_ospf6_interface(vty, vrf);
2645 }
2646
2647 return write;
2648 }
2649
2650 static int ospf6_ifp_create(struct interface *ifp)
2651 {
2652 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2653 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp->name,
2654 ifp->ifindex, ifp->mtu6);
2655
2656 if (ifp->info)
2657 ospf6_interface_start(ifp->info);
2658
2659 return 0;
2660 }
2661
2662 static int ospf6_ifp_up(struct interface *ifp)
2663 {
2664 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2665 zlog_debug(
2666 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2667 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
2668 ifp->metric, ifp->mtu6, ifp->bandwidth);
2669
2670 ospf6_interface_state_update(ifp);
2671
2672 return 0;
2673 }
2674
2675 static int ospf6_ifp_down(struct interface *ifp)
2676 {
2677 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2678 zlog_debug(
2679 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2680 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
2681 ifp->metric, ifp->mtu6, ifp->bandwidth);
2682
2683 ospf6_interface_state_update(ifp);
2684
2685 return 0;
2686 }
2687
2688 static int ospf6_ifp_destroy(struct interface *ifp)
2689 {
2690 if (if_is_up(ifp))
2691 zlog_warn("Zebra: got delete of %s, but interface is still up",
2692 ifp->name);
2693
2694 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2695 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
2696 ifp->name, ifp->ifindex, ifp->mtu6);
2697
2698 if (ifp->info)
2699 ospf6_interface_stop(ifp->info);
2700
2701 return 0;
2702 }
2703
2704 void ospf6_interface_init(void)
2705 {
2706 /* Install interface node. */
2707 if_cmd_init(config_write_interface);
2708 if_zapi_callbacks(ospf6_ifp_create, ospf6_ifp_up,
2709 ospf6_ifp_down, ospf6_ifp_destroy);
2710
2711 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
2712 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
2713 install_element(VIEW_NODE,
2714 &show_ipv6_ospf6_interface_ifname_prefix_cmd);
2715 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd);
2716
2717 install_element(INTERFACE_NODE, &ipv6_ospf6_area_cmd);
2718 install_element(INTERFACE_NODE, &no_ipv6_ospf6_area_cmd);
2719 install_element(INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
2720 install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
2721 install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
2722 install_element(INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
2723
2724 install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
2725 install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
2726 install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
2727 install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
2728 install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
2729 install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
2730 install_element(INTERFACE_NODE, &no_ipv6_ospf6_deadinterval_cmd);
2731 install_element(INTERFACE_NODE, &no_ipv6_ospf6_hellointerval_cmd);
2732 install_element(INTERFACE_NODE, &no_ipv6_ospf6_priority_cmd);
2733 install_element(INTERFACE_NODE, &no_ipv6_ospf6_retransmitinterval_cmd);
2734 install_element(INTERFACE_NODE, &no_ipv6_ospf6_transmitdelay_cmd);
2735 install_element(INTERFACE_NODE, &no_ipv6_ospf6_instance_cmd);
2736
2737 install_element(INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
2738 install_element(INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
2739
2740 install_element(INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
2741 install_element(INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
2742
2743 install_element(INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
2744 install_element(INTERFACE_NODE,
2745 &no_ipv6_ospf6_advertise_prefix_list_cmd);
2746
2747 install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd);
2748 install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
2749
2750 /* reference bandwidth commands */
2751 install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
2752 install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
2753 /* write-multiplier commands */
2754 install_element(OSPF6_NODE, &ospf6_write_multiplier_cmd);
2755 install_element(OSPF6_NODE, &no_ospf6_write_multiplier_cmd);
2756 }
2757
2758 /* Clear the specified interface structure */
2759 void ospf6_interface_clear(struct interface *ifp)
2760 {
2761 struct ospf6_interface *oi;
2762
2763 if (!if_is_operative(ifp))
2764 return;
2765
2766 if (ifp->info == NULL)
2767 return;
2768
2769 oi = (struct ospf6_interface *)ifp->info;
2770
2771 if (IS_OSPF6_DEBUG_INTERFACE)
2772 zlog_debug("Interface %s: clear by reset", ifp->name);
2773
2774 /* Reset the interface */
2775 thread_execute(master, interface_down, oi, 0);
2776 thread_execute(master, interface_up, oi, 0);
2777 }
2778
2779 /* Clear interface */
2780 DEFUN (clear_ipv6_ospf6_interface,
2781 clear_ipv6_ospf6_interface_cmd,
2782 "clear ipv6 ospf6 [vrf NAME] interface [IFNAME]",
2783 CLEAR_STR
2784 IP6_STR
2785 OSPF6_STR
2786 VRF_CMD_HELP_STR
2787 INTERFACE_STR
2788 IFNAME_STR
2789 )
2790 {
2791 struct vrf *vrf;
2792 int idx_vrf = 3;
2793 int idx_ifname = 4;
2794 struct interface *ifp;
2795 const char *vrf_name;
2796
2797 if (argv_find(argv, argc, "vrf", &idx_vrf))
2798 vrf_name = argv[idx_vrf + 1]->arg;
2799 else
2800 vrf_name = VRF_DEFAULT_NAME;
2801 vrf = vrf_lookup_by_name(vrf_name);
2802 if (!vrf) {
2803 vty_out(vty, "%% VRF %s not found\n", vrf_name);
2804 return CMD_WARNING;
2805 }
2806
2807 if (!argv_find(argv, argc, "IFNAME", &idx_ifname)) {
2808 /* Clear all the ospfv3 interfaces. */
2809 FOR_ALL_INTERFACES (vrf, ifp)
2810 ospf6_interface_clear(ifp);
2811 } else {
2812 /* Interface name is specified. */
2813 ifp = if_lookup_by_name_vrf(argv[idx_ifname]->arg, vrf);
2814 if (!ifp) {
2815 vty_out(vty, "No such Interface: %s\n",
2816 argv[idx_ifname]->arg);
2817 return CMD_WARNING;
2818 }
2819 ospf6_interface_clear(ifp);
2820 }
2821
2822 return CMD_SUCCESS;
2823 }
2824
2825 void install_element_ospf6_clear_interface(void)
2826 {
2827 install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
2828 }
2829
2830 DEFUN (debug_ospf6_interface,
2831 debug_ospf6_interface_cmd,
2832 "debug ospf6 interface",
2833 DEBUG_STR
2834 OSPF6_STR
2835 "Debug OSPFv3 Interface\n"
2836 )
2837 {
2838 OSPF6_DEBUG_INTERFACE_ON();
2839 return CMD_SUCCESS;
2840 }
2841
2842 DEFUN (no_debug_ospf6_interface,
2843 no_debug_ospf6_interface_cmd,
2844 "no debug ospf6 interface",
2845 NO_STR
2846 DEBUG_STR
2847 OSPF6_STR
2848 "Debug OSPFv3 Interface\n"
2849 )
2850 {
2851 OSPF6_DEBUG_INTERFACE_OFF();
2852 return CMD_SUCCESS;
2853 }
2854
2855 int config_write_ospf6_debug_interface(struct vty *vty)
2856 {
2857 if (IS_OSPF6_DEBUG_INTERFACE)
2858 vty_out(vty, "debug ospf6 interface\n");
2859 return 0;
2860 }
2861
2862 void install_element_ospf6_debug_interface(void)
2863 {
2864 install_element(ENABLE_NODE, &debug_ospf6_interface_cmd);
2865 install_element(ENABLE_NODE, &no_debug_ospf6_interface_cmd);
2866 install_element(CONFIG_NODE, &debug_ospf6_interface_cmd);
2867 install_element(CONFIG_NODE, &no_debug_ospf6_interface_cmd);
2868 }
2869
2870 void ospf6_auth_write_config(struct vty *vty, struct ospf6_auth_data *at_data)
2871 {
2872 if (CHECK_FLAG(at_data->flags, OSPF6_AUTH_TRAILER_KEYCHAIN))
2873 vty_out(vty, " ipv6 ospf6 authentication keychain %s\n",
2874 at_data->keychain);
2875 else if (CHECK_FLAG(at_data->flags, OSPF6_AUTH_TRAILER_MANUAL_KEY))
2876 vty_out(vty,
2877 " ipv6 ospf6 authentication key-id %d hash-algo %s key %s\n",
2878 at_data->key_id,
2879 keychain_get_algo_name_by_id(at_data->hash_algo),
2880 at_data->auth_key);
2881 }
2882
2883 DEFUN(ipv6_ospf6_intf_auth_trailer_keychain,
2884 ipv6_ospf6_intf_auth_trailer_keychain_cmd,
2885 "ipv6 ospf6 authentication keychain KEYCHAIN_NAME",
2886 IP6_STR OSPF6_STR
2887 "Enable authentication on this interface\n"
2888 "Keychain\n"
2889 "Keychain name\n")
2890 {
2891 VTY_DECLVAR_CONTEXT(interface, ifp);
2892 int keychain_idx = 4;
2893 struct ospf6_interface *oi;
2894
2895 oi = (struct ospf6_interface *)ifp->info;
2896 if (oi == NULL)
2897 oi = ospf6_interface_create(ifp);
2898
2899 assert(oi);
2900 if (CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_MANUAL_KEY)) {
2901 vty_out(vty,
2902 "Manual key configured, unconfigure it before configuring key chain\n");
2903 return CMD_WARNING_CONFIG_FAILED;
2904 }
2905
2906 SET_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_KEYCHAIN);
2907 if (oi->at_data.keychain)
2908 XFREE(MTYPE_OSPF6_AUTH_KEYCHAIN, oi->at_data.keychain);
2909
2910 oi->at_data.keychain =
2911 XSTRDUP(MTYPE_OSPF6_AUTH_KEYCHAIN, argv[keychain_idx]->arg);
2912
2913 return CMD_SUCCESS;
2914 }
2915
2916 DEFUN(no_ipv6_ospf6_intf_auth_trailer_keychain,
2917 no_ipv6_ospf6_intf_auth_trailer_keychain_cmd,
2918 "no ipv6 ospf6 authentication keychain [KEYCHAIN_NAME]",
2919 NO_STR IP6_STR OSPF6_STR
2920 "Enable authentication on this interface\n"
2921 "Keychain\n"
2922 "Keychain name\n")
2923 {
2924 VTY_DECLVAR_CONTEXT(interface, ifp);
2925 struct ospf6_interface *oi;
2926
2927 oi = (struct ospf6_interface *)ifp->info;
2928 if (oi == NULL)
2929 oi = ospf6_interface_create(ifp);
2930
2931 assert(oi);
2932 if (!CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_KEYCHAIN))
2933 return CMD_SUCCESS;
2934
2935 if (oi->at_data.keychain) {
2936 oi->at_data.flags = 0;
2937 XFREE(MTYPE_OSPF6_AUTH_KEYCHAIN, oi->at_data.keychain);
2938 oi->at_data.keychain = NULL;
2939 }
2940
2941 return CMD_SUCCESS;
2942 }
2943
2944 DEFUN(ipv6_ospf6_intf_auth_trailer_key, ipv6_ospf6_intf_auth_trailer_key_cmd,
2945 "ipv6 ospf6 authentication key-id (1-65535) hash-algo "
2946 "<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512> "
2947 "key WORD",
2948 IP6_STR OSPF6_STR
2949 "Authentication\n"
2950 "Key ID\n"
2951 "Key ID value\n"
2952 "Cryptographic-algorithm\n"
2953 "Use MD5 algorithm\n"
2954 "Use HMAC-SHA-1 algorithm\n"
2955 "Use HMAC-SHA-256 algorithm\n"
2956 "Use HMAC-SHA-384 algorithm\n"
2957 "Use HMAC-SHA-512 algorithm\n"
2958 "Password\n"
2959 "Password string (key)\n")
2960 {
2961 VTY_DECLVAR_CONTEXT(interface, ifp);
2962 int key_id_idx = 4;
2963 int hash_algo_idx = 6;
2964 int password_idx = 8;
2965 struct ospf6_interface *oi;
2966 uint8_t hash_algo = KEYCHAIN_ALGO_NULL;
2967
2968 oi = (struct ospf6_interface *)ifp->info;
2969 if (oi == NULL)
2970 oi = ospf6_interface_create(ifp);
2971
2972 assert(oi);
2973 if (CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_KEYCHAIN)) {
2974 vty_out(vty,
2975 "key chain configured, unconfigure it before configuring manual key\n");
2976 return CMD_WARNING_CONFIG_FAILED;
2977 }
2978
2979 hash_algo = keychain_get_algo_id_by_name(argv[hash_algo_idx]->arg);
2980 #ifndef CRYPTO_OPENSSL
2981 if (hash_algo == KEYCHAIN_ALGO_NULL) {
2982 vty_out(vty,
2983 "Hash algorithm not supported, compile with --with-crypto=openssl\n");
2984 return CMD_WARNING_CONFIG_FAILED;
2985 }
2986 #endif /* CRYPTO_OPENSSL */
2987
2988 SET_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_MANUAL_KEY);
2989 oi->at_data.hash_algo = hash_algo;
2990 oi->at_data.key_id = (uint16_t)strtol(argv[key_id_idx]->arg, NULL, 10);
2991 if (oi->at_data.auth_key)
2992 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY, oi->at_data.auth_key);
2993 oi->at_data.auth_key =
2994 XSTRDUP(MTYPE_OSPF6_AUTH_MANUAL_KEY, argv[password_idx]->arg);
2995
2996 return CMD_SUCCESS;
2997 }
2998
2999 DEFUN(no_ipv6_ospf6_intf_auth_trailer_key,
3000 no_ipv6_ospf6_intf_auth_trailer_key_cmd,
3001 "no ipv6 ospf6 authentication key-id [(1-65535) hash-algo "
3002 "<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512> "
3003 "key WORD]",
3004 NO_STR IP6_STR OSPF6_STR
3005 "Authentication\n"
3006 "Key ID\n"
3007 "Key ID value\n"
3008 "Cryptographic-algorithm\n"
3009 "Use MD5 algorithm\n"
3010 "Use HMAC-SHA-1 algorithm\n"
3011 "Use HMAC-SHA-256 algorithm\n"
3012 "Use HMAC-SHA-384 algorithm\n"
3013 "Use HMAC-SHA-512 algorithm\n"
3014 "Password\n"
3015 "Password string (key)\n")
3016 {
3017 VTY_DECLVAR_CONTEXT(interface, ifp);
3018 struct ospf6_interface *oi;
3019 #ifndef CRYPTO_OPENSSL
3020 int hash_algo_idx = 7;
3021 uint8_t hash_algo = KEYCHAIN_ALGO_NULL;
3022 #endif /* CRYPTO_OPENSSL */
3023
3024 oi = (struct ospf6_interface *)ifp->info;
3025 if (oi == NULL)
3026 oi = ospf6_interface_create(ifp);
3027
3028 assert(oi);
3029 if (!CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_MANUAL_KEY))
3030 return CMD_SUCCESS;
3031
3032 #ifndef CRYPTO_OPENSSL
3033 hash_algo = keychain_get_algo_id_by_name(argv[hash_algo_idx]->arg);
3034 if (hash_algo == KEYCHAIN_ALGO_NULL) {
3035 vty_out(vty,
3036 "Hash algorithm not supported, compile with --with-crypto=openssl\n");
3037 return CMD_WARNING_CONFIG_FAILED;
3038 }
3039 #endif /* CRYPTO_OPENSSL */
3040
3041 if (oi->at_data.auth_key) {
3042 oi->at_data.flags = 0;
3043 XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY, oi->at_data.auth_key);
3044 oi->at_data.auth_key = NULL;
3045 }
3046
3047 return CMD_SUCCESS;
3048 }
3049
3050 void ospf6_interface_auth_trailer_cmd_init(void)
3051 {
3052 /*Install OSPF6 auth trailer commands at interface level */
3053 install_element(INTERFACE_NODE,
3054 &ipv6_ospf6_intf_auth_trailer_keychain_cmd);
3055 install_element(INTERFACE_NODE,
3056 &no_ipv6_ospf6_intf_auth_trailer_keychain_cmd);
3057 install_element(INTERFACE_NODE, &ipv6_ospf6_intf_auth_trailer_key_cmd);
3058 install_element(INTERFACE_NODE,
3059 &no_ipv6_ospf6_intf_auth_trailer_key_cmd);
3060 }