]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_interface.c
Merge pull request #8576 from pguibert6WIND/macvlan_crash
[mirror_frr.git] / ospf6d / ospf6_interface.c
1 /*
2 * Copyright (C) 2003 Yasuhiro Ohara
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "memory.h"
24 #include "if.h"
25 #include "log.h"
26 #include "command.h"
27 #include "thread.h"
28 #include "prefix.h"
29 #include "plist.h"
30 #include "zclient.h"
31
32 #include "ospf6_lsa.h"
33 #include "ospf6_lsdb.h"
34 #include "ospf6_top.h"
35 #include "ospf6_network.h"
36 #include "ospf6_message.h"
37 #include "ospf6_route.h"
38 #include "ospf6_area.h"
39 #include "ospf6_interface.h"
40 #include "ospf6_neighbor.h"
41 #include "ospf6_intra.h"
42 #include "ospf6_spf.h"
43 #include "ospf6d.h"
44 #include "ospf6_bfd.h"
45 #include "ospf6_zebra.h"
46 #include "lib/json.h"
47
48 DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_IF, "OSPF6 interface");
49 DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names");
50 DEFINE_QOBJ_TYPE(ospf6_interface);
51 DEFINE_HOOK(ospf6_interface_change,
52 (struct ospf6_interface * oi, int state, int old_state),
53 (oi, state, old_state));
54
55 unsigned char conf_debug_ospf6_interface = 0;
56
57 const char *const ospf6_interface_state_str[] = {
58 "None", "Down", "Loopback", "Waiting", "PointToPoint",
59 "DROther", "BDR", "DR", NULL};
60
61 struct ospf6_interface *ospf6_interface_lookup_by_ifindex(ifindex_t ifindex,
62 vrf_id_t vrf_id)
63 {
64 struct ospf6_interface *oi;
65 struct interface *ifp;
66
67 ifp = if_lookup_by_index(ifindex, vrf_id);
68 if (ifp == NULL)
69 return (struct ospf6_interface *)NULL;
70
71 oi = (struct ospf6_interface *)ifp->info;
72 return oi;
73 }
74
75 /* schedule routing table recalculation */
76 static void ospf6_interface_lsdb_hook(struct ospf6_lsa *lsa,
77 unsigned int reason)
78 {
79 struct ospf6_interface *oi;
80
81 if (lsa == NULL)
82 return;
83
84 oi = lsa->lsdb->data;
85 switch (ntohs(lsa->header->type)) {
86 case OSPF6_LSTYPE_LINK:
87 if (oi->state == OSPF6_INTERFACE_DR)
88 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
89 if (oi->area)
90 ospf6_spf_schedule(oi->area->ospf6, reason);
91 break;
92
93 default:
94 break;
95 }
96 }
97
98 static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa *lsa)
99 {
100 ospf6_interface_lsdb_hook(lsa, ospf6_lsadd_to_spf_reason(lsa));
101 }
102
103 static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa *lsa)
104 {
105 ospf6_interface_lsdb_hook(lsa, ospf6_lsremove_to_spf_reason(lsa));
106 }
107
108 static uint8_t ospf6_default_iftype(struct interface *ifp)
109 {
110 if (if_is_pointopoint(ifp))
111 return OSPF_IFTYPE_POINTOPOINT;
112 else if (if_is_loopback(ifp))
113 return OSPF_IFTYPE_LOOPBACK;
114 else
115 return OSPF_IFTYPE_BROADCAST;
116 }
117
118 static uint32_t ospf6_interface_get_cost(struct ospf6_interface *oi)
119 {
120 /* If all else fails, use default OSPF cost */
121 uint32_t cost;
122 uint32_t bw, refbw;
123 struct ospf6 *ospf6;
124 /* interface speed and bw can be 0 in some platforms,
125 * use ospf default bw. If bw is configured then it would
126 * be used.
127 */
128 if (!oi->interface->bandwidth && oi->interface->speed) {
129 bw = oi->interface->speed;
130 } else {
131 bw = oi->interface->bandwidth ? oi->interface->bandwidth
132 : OSPF6_INTERFACE_BANDWIDTH;
133 }
134
135 ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id);
136 refbw = ospf6 ? ospf6->ref_bandwidth : OSPF6_REFERENCE_BANDWIDTH;
137
138 /* A specifed ip ospf cost overrides a calculated one. */
139 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
140 cost = oi->cost;
141 else {
142 cost = (uint32_t)((double)refbw / (double)bw + (double)0.5);
143 if (cost < 1)
144 cost = 1;
145 else if (cost > UINT32_MAX)
146 cost = UINT32_MAX;
147 }
148
149 return cost;
150 }
151
152 static void ospf6_interface_force_recalculate_cost(struct ospf6_interface *oi)
153 {
154 /* update cost held in route_connected list in ospf6_interface */
155 ospf6_interface_connected_route_update(oi->interface);
156
157 /* execute LSA hooks */
158 if (oi->area) {
159 OSPF6_LINK_LSA_SCHEDULE(oi);
160 OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
161 OSPF6_NETWORK_LSA_SCHEDULE(oi);
162 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
163 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
164 }
165 }
166
167 static void ospf6_interface_recalculate_cost(struct ospf6_interface *oi)
168 {
169 uint32_t newcost;
170
171 newcost = ospf6_interface_get_cost(oi);
172 if (newcost == oi->cost)
173 return;
174 oi->cost = newcost;
175
176 ospf6_interface_force_recalculate_cost(oi);
177 }
178
179 /* Create new ospf6 interface structure */
180 struct ospf6_interface *ospf6_interface_create(struct interface *ifp)
181 {
182 struct ospf6_interface *oi;
183 unsigned int iobuflen;
184
185 oi = XCALLOC(MTYPE_OSPF6_IF, sizeof(struct ospf6_interface));
186
187 oi->area = (struct ospf6_area *)NULL;
188 oi->neighbor_list = list_new();
189 oi->neighbor_list->cmp = ospf6_neighbor_cmp;
190 oi->linklocal_addr = (struct in6_addr *)NULL;
191 oi->instance_id = OSPF6_INTERFACE_INSTANCE_ID;
192 oi->transdelay = OSPF6_INTERFACE_TRANSDELAY;
193 oi->priority = OSPF6_INTERFACE_PRIORITY;
194
195 oi->hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
196 oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
197 oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
198 oi->type = ospf6_default_iftype(ifp);
199 oi->state = OSPF6_INTERFACE_DOWN;
200 oi->flag = 0;
201 oi->mtu_ignore = 0;
202 oi->c_ifmtu = 0;
203
204 /* Try to adjust I/O buffer size with IfMtu */
205 oi->ifmtu = ifp->mtu6;
206 iobuflen = ospf6_iobuf_size(ifp->mtu6);
207 if (oi->ifmtu > iobuflen) {
208 if (IS_OSPF6_DEBUG_INTERFACE)
209 zlog_debug(
210 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
211 ifp->name, iobuflen);
212 oi->ifmtu = iobuflen;
213 }
214
215 QOBJ_REG(oi, ospf6_interface);
216
217 oi->lsupdate_list = ospf6_lsdb_create(oi);
218 oi->lsack_list = ospf6_lsdb_create(oi);
219 oi->lsdb = ospf6_lsdb_create(oi);
220 oi->lsdb->hook_add = ospf6_interface_lsdb_hook_add;
221 oi->lsdb->hook_remove = ospf6_interface_lsdb_hook_remove;
222 oi->lsdb_self = ospf6_lsdb_create(oi);
223
224 oi->route_connected =
225 OSPF6_ROUTE_TABLE_CREATE(INTERFACE, CONNECTED_ROUTES);
226 oi->route_connected->scope = oi;
227
228 /* link both */
229 oi->interface = ifp;
230 ifp->info = oi;
231
232 /* Compute cost. */
233 oi->cost = ospf6_interface_get_cost(oi);
234
235 return oi;
236 }
237
238 void ospf6_interface_delete(struct ospf6_interface *oi)
239 {
240 struct listnode *node, *nnode;
241 struct ospf6_neighbor *on;
242
243 QOBJ_UNREG(oi);
244
245 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
246 ospf6_neighbor_delete(on);
247
248 list_delete(&oi->neighbor_list);
249
250 THREAD_OFF(oi->thread_send_hello);
251 THREAD_OFF(oi->thread_send_lsupdate);
252 THREAD_OFF(oi->thread_send_lsack);
253 THREAD_OFF(oi->thread_sso);
254 THREAD_OFF(oi->thread_wait_timer);
255
256 ospf6_lsdb_remove_all(oi->lsdb);
257 ospf6_lsdb_remove_all(oi->lsupdate_list);
258 ospf6_lsdb_remove_all(oi->lsack_list);
259
260 ospf6_lsdb_delete(oi->lsdb);
261 ospf6_lsdb_delete(oi->lsdb_self);
262
263 ospf6_lsdb_delete(oi->lsupdate_list);
264 ospf6_lsdb_delete(oi->lsack_list);
265
266 ospf6_route_table_delete(oi->route_connected);
267
268 /* cut link */
269 oi->interface->info = NULL;
270
271 /* plist_name */
272 if (oi->plist_name)
273 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
274
275 /* disable from area list if possible */
276 ospf6_area_interface_delete(oi);
277
278 /* Free BFD allocated data. */
279 XFREE(MTYPE_TMP, oi->bfd_config.profile);
280
281 XFREE(MTYPE_OSPF6_IF, oi);
282 }
283
284 void ospf6_interface_enable(struct ospf6_interface *oi)
285 {
286 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
287 ospf6_interface_state_update(oi->interface);
288 }
289
290 void ospf6_interface_disable(struct ospf6_interface *oi)
291 {
292 SET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
293
294 thread_execute(master, interface_down, oi, 0);
295
296 ospf6_lsdb_remove_all(oi->lsdb);
297 ospf6_lsdb_remove_all(oi->lsdb_self);
298 ospf6_lsdb_remove_all(oi->lsupdate_list);
299 ospf6_lsdb_remove_all(oi->lsack_list);
300
301 THREAD_OFF(oi->thread_send_hello);
302 THREAD_OFF(oi->thread_send_lsupdate);
303 THREAD_OFF(oi->thread_send_lsack);
304 THREAD_OFF(oi->thread_sso);
305
306 THREAD_OFF(oi->thread_network_lsa);
307 THREAD_OFF(oi->thread_link_lsa);
308 THREAD_OFF(oi->thread_intra_prefix_lsa);
309 THREAD_OFF(oi->thread_as_extern_lsa);
310 THREAD_OFF(oi->thread_wait_timer);
311 }
312
313 static struct in6_addr *
314 ospf6_interface_get_linklocal_address(struct interface *ifp)
315 {
316 struct listnode *n;
317 struct connected *c;
318 struct in6_addr *l = (struct in6_addr *)NULL;
319
320 /* for each connected address */
321 for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
322 /* if family not AF_INET6, ignore */
323 if (c->address->family != AF_INET6)
324 continue;
325
326 /* linklocal scope check */
327 if (IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
328 l = &c->address->u.prefix6;
329 }
330 return l;
331 }
332
333 void ospf6_interface_if_add(struct interface *ifp)
334 {
335 struct ospf6_interface *oi;
336 unsigned int iobuflen;
337
338 oi = (struct ospf6_interface *)ifp->info;
339 if (oi == NULL)
340 return;
341
342 /* Try to adjust I/O buffer size with IfMtu */
343 if (oi->ifmtu == 0)
344 oi->ifmtu = ifp->mtu6;
345 iobuflen = ospf6_iobuf_size(ifp->mtu6);
346 if (oi->ifmtu > iobuflen) {
347 if (IS_OSPF6_DEBUG_INTERFACE)
348 zlog_debug(
349 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
350 ifp->name, iobuflen);
351 oi->ifmtu = iobuflen;
352 }
353
354 /* interface start */
355 ospf6_interface_state_update(oi->interface);
356 }
357
358 void ospf6_interface_state_update(struct interface *ifp)
359 {
360 struct ospf6_interface *oi;
361 unsigned int iobuflen;
362
363 oi = (struct ospf6_interface *)ifp->info;
364 if (oi == NULL)
365 return;
366 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
367 return;
368
369 /* Adjust the mtu values if the kernel told us something new */
370 if (ifp->mtu6 != oi->ifmtu) {
371 /* If nothing configured, accept it and check for buffer size */
372 if (!oi->c_ifmtu) {
373 oi->ifmtu = ifp->mtu6;
374 iobuflen = ospf6_iobuf_size(ifp->mtu6);
375 if (oi->ifmtu > iobuflen) {
376 if (IS_OSPF6_DEBUG_INTERFACE)
377 zlog_debug(
378 "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
379 ifp->name, iobuflen);
380 oi->ifmtu = iobuflen;
381 }
382 } else if (oi->c_ifmtu > ifp->mtu6) {
383 oi->ifmtu = ifp->mtu6;
384 zlog_warn(
385 "Configured mtu %u on %s overridden by kernel %u",
386 oi->c_ifmtu, ifp->name, ifp->mtu6);
387 } else
388 oi->ifmtu = oi->c_ifmtu;
389 }
390
391 if (if_is_operative(ifp)
392 && (ospf6_interface_get_linklocal_address(oi->interface)
393 || if_is_loopback(oi->interface)))
394 thread_execute(master, interface_up, oi, 0);
395 else
396 thread_execute(master, interface_down, oi, 0);
397
398 return;
399 }
400
401 void ospf6_interface_connected_route_update(struct interface *ifp)
402 {
403 struct ospf6_interface *oi;
404 struct ospf6_route *route;
405 struct connected *c;
406 struct listnode *node, *nnode;
407 struct in6_addr nh_addr;
408
409 oi = (struct ospf6_interface *)ifp->info;
410 if (oi == NULL)
411 return;
412
413 /* reset linklocal pointer */
414 oi->linklocal_addr = ospf6_interface_get_linklocal_address(ifp);
415
416 /* if area is null, do not make connected-route list */
417 if (oi->area == NULL)
418 return;
419
420 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
421 return;
422
423 /* update "route to advertise" interface route table */
424 ospf6_route_remove_all(oi->route_connected);
425
426 for (ALL_LIST_ELEMENTS(oi->interface->connected, node, nnode, c)) {
427 if (c->address->family != AF_INET6)
428 continue;
429
430 CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE,
431 c->address);
432 CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE,
433 c->address);
434 CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE,
435 c->address);
436 CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE,
437 c->address);
438 CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE,
439 c->address);
440
441 /* apply filter */
442 if (oi->plist_name) {
443 struct prefix_list *plist;
444 enum prefix_list_type ret;
445
446 plist = prefix_list_lookup(AFI_IP6, oi->plist_name);
447 ret = prefix_list_apply(plist, (void *)c->address);
448 if (ret == PREFIX_DENY) {
449 if (IS_OSPF6_DEBUG_INTERFACE)
450 zlog_debug(
451 "%pFX on %s filtered by prefix-list %s ",
452 c->address, oi->interface->name,
453 oi->plist_name);
454 continue;
455 }
456 }
457
458 route = ospf6_route_create();
459 memcpy(&route->prefix, c->address, sizeof(struct prefix));
460 apply_mask(&route->prefix);
461 route->type = OSPF6_DEST_TYPE_NETWORK;
462 route->path.area_id = oi->area->area_id;
463 route->path.type = OSPF6_PATH_TYPE_INTRA;
464 route->path.cost = oi->cost;
465 inet_pton(AF_INET6, "::1", &nh_addr);
466 ospf6_route_add_nexthop(route, oi->interface->ifindex,
467 &nh_addr);
468 ospf6_route_add(route, oi->route_connected);
469 }
470
471 /* create new Link-LSA */
472 OSPF6_LINK_LSA_SCHEDULE(oi);
473 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
474 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
475 }
476
477 static void ospf6_interface_state_change(uint8_t next_state,
478 struct ospf6_interface *oi)
479 {
480 uint8_t prev_state;
481 struct ospf6 *ospf6;
482
483 prev_state = oi->state;
484 oi->state = next_state;
485
486 if (prev_state == next_state)
487 return;
488
489 /* log */
490 if (IS_OSPF6_DEBUG_INTERFACE) {
491 zlog_debug("Interface state change %s: %s -> %s",
492 oi->interface->name,
493 ospf6_interface_state_str[prev_state],
494 ospf6_interface_state_str[next_state]);
495 }
496 oi->state_change++;
497 ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id);
498
499 if ((prev_state == OSPF6_INTERFACE_DR
500 || prev_state == OSPF6_INTERFACE_BDR)
501 && (next_state != OSPF6_INTERFACE_DR
502 && next_state != OSPF6_INTERFACE_BDR))
503 ospf6_sso(oi->interface->ifindex, &alldrouters6,
504 IPV6_LEAVE_GROUP, ospf6->fd);
505
506 if ((prev_state != OSPF6_INTERFACE_DR
507 && prev_state != OSPF6_INTERFACE_BDR)
508 && (next_state == OSPF6_INTERFACE_DR
509 || next_state == OSPF6_INTERFACE_BDR))
510 ospf6_sso(oi->interface->ifindex, &alldrouters6,
511 IPV6_JOIN_GROUP, ospf6->fd);
512
513 OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
514 OSPF6_LINK_LSA_SCHEDULE(oi);
515 if (next_state == OSPF6_INTERFACE_DOWN) {
516 OSPF6_NETWORK_LSA_EXECUTE(oi);
517 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
518 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
519 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
520 } else if (prev_state == OSPF6_INTERFACE_DR
521 || next_state == OSPF6_INTERFACE_DR) {
522 OSPF6_NETWORK_LSA_SCHEDULE(oi);
523 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
524 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
525 }
526
527 hook_call(ospf6_interface_change, oi, next_state, prev_state);
528 }
529
530
531 /* DR Election, RFC2328 section 9.4 */
532
533 #define IS_ELIGIBLE(n) \
534 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
535
536 static struct ospf6_neighbor *better_bdrouter(struct ospf6_neighbor *a,
537 struct ospf6_neighbor *b)
538 {
539 if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id)
540 && (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id))
541 return NULL;
542 else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id)
543 return b;
544 else if (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id)
545 return a;
546
547 if (a->bdrouter == a->router_id && b->bdrouter != b->router_id)
548 return a;
549 if (a->bdrouter != a->router_id && b->bdrouter == b->router_id)
550 return b;
551
552 if (a->priority > b->priority)
553 return a;
554 if (a->priority < b->priority)
555 return b;
556
557 if (ntohl(a->router_id) > ntohl(b->router_id))
558 return a;
559 if (ntohl(a->router_id) < ntohl(b->router_id))
560 return b;
561
562 zlog_warn("Router-ID duplicate ?");
563 return a;
564 }
565
566 static struct ospf6_neighbor *better_drouter(struct ospf6_neighbor *a,
567 struct ospf6_neighbor *b)
568 {
569 if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id)
570 && (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id))
571 return NULL;
572 else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id)
573 return b;
574 else if (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id)
575 return a;
576
577 if (a->drouter == a->router_id && b->drouter != b->router_id)
578 return a;
579 if (a->drouter != a->router_id && b->drouter == b->router_id)
580 return b;
581
582 if (a->priority > b->priority)
583 return a;
584 if (a->priority < b->priority)
585 return b;
586
587 if (ntohl(a->router_id) > ntohl(b->router_id))
588 return a;
589 if (ntohl(a->router_id) < ntohl(b->router_id))
590 return b;
591
592 zlog_warn("Router-ID duplicate ?");
593 return a;
594 }
595
596 static uint8_t dr_election(struct ospf6_interface *oi)
597 {
598 struct listnode *node, *nnode;
599 struct ospf6_neighbor *on, *drouter, *bdrouter, myself;
600 struct ospf6_neighbor *best_drouter, *best_bdrouter;
601 uint8_t next_state = 0;
602
603 drouter = bdrouter = NULL;
604 best_drouter = best_bdrouter = NULL;
605
606 /* pseudo neighbor myself, including noting current DR/BDR (1) */
607 memset(&myself, 0, sizeof(myself));
608 inet_ntop(AF_INET, &oi->area->ospf6->router_id, myself.name,
609 sizeof(myself.name));
610 myself.state = OSPF6_NEIGHBOR_TWOWAY;
611 myself.drouter = oi->drouter;
612 myself.bdrouter = oi->bdrouter;
613 myself.priority = oi->priority;
614 myself.router_id = oi->area->ospf6->router_id;
615
616 /* Electing BDR (2) */
617 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
618 bdrouter = better_bdrouter(bdrouter, on);
619
620 best_bdrouter = bdrouter;
621 bdrouter = better_bdrouter(best_bdrouter, &myself);
622
623 /* Electing DR (3) */
624 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
625 drouter = better_drouter(drouter, on);
626
627 best_drouter = drouter;
628 drouter = better_drouter(best_drouter, &myself);
629 if (drouter == NULL)
630 drouter = bdrouter;
631
632 /* the router itself is newly/no longer DR/BDR (4) */
633 if ((drouter == &myself && myself.drouter != myself.router_id)
634 || (drouter != &myself && myself.drouter == myself.router_id)
635 || (bdrouter == &myself && myself.bdrouter != myself.router_id)
636 || (bdrouter != &myself && myself.bdrouter == myself.router_id)) {
637 myself.drouter = (drouter ? drouter->router_id : htonl(0));
638 myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl(0));
639
640 /* compatible to Electing BDR (2) */
641 bdrouter = better_bdrouter(best_bdrouter, &myself);
642
643 /* compatible to Electing DR (3) */
644 drouter = better_drouter(best_drouter, &myself);
645 if (drouter == NULL)
646 drouter = bdrouter;
647 }
648
649 /* Set interface state accordingly (5) */
650 if (drouter && drouter == &myself)
651 next_state = OSPF6_INTERFACE_DR;
652 else if (bdrouter && bdrouter == &myself)
653 next_state = OSPF6_INTERFACE_BDR;
654 else
655 next_state = OSPF6_INTERFACE_DROTHER;
656
657 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
658 /* XXX */
659
660 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
661 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
662 accordingly after AdjOK */
663 if (oi->drouter != (drouter ? drouter->router_id : htonl(0))
664 || oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl(0))) {
665 if (IS_OSPF6_DEBUG_INTERFACE)
666 zlog_debug("DR Election on %s: DR: %s BDR: %s",
667 oi->interface->name,
668 (drouter ? drouter->name : "0.0.0.0"),
669 (bdrouter ? bdrouter->name : "0.0.0.0"));
670
671 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, on)) {
672 if (on->state < OSPF6_NEIGHBOR_TWOWAY)
673 continue;
674 /* Schedule AdjOK. */
675 thread_add_event(master, adj_ok, on, 0, NULL);
676 }
677 }
678
679 oi->drouter = (drouter ? drouter->router_id : htonl(0));
680 oi->bdrouter = (bdrouter ? bdrouter->router_id : htonl(0));
681 return next_state;
682 }
683
684
685 /* Interface State Machine */
686 int interface_up(struct thread *thread)
687 {
688 struct ospf6_interface *oi;
689 struct ospf6 *ospf6;
690
691 oi = (struct ospf6_interface *)THREAD_ARG(thread);
692 assert(oi && oi->interface);
693
694 if (!oi->type_cfg)
695 oi->type = ospf6_default_iftype(oi->interface);
696
697 /*
698 * Remove old pointer. If this thread wasn't a timer this
699 * operation won't make a difference, because it is already NULL.
700 */
701 oi->thread_sso = NULL;
702
703 if (IS_OSPF6_DEBUG_INTERFACE)
704 zlog_debug("Interface Event %s: [InterfaceUp]",
705 oi->interface->name);
706
707 /* check physical interface is up */
708 if (!if_is_operative(oi->interface)) {
709 if (IS_OSPF6_DEBUG_INTERFACE)
710 zlog_debug(
711 "Interface %s is down, can't execute [InterfaceUp]",
712 oi->interface->name);
713 return 0;
714 }
715
716 /* check interface has a link-local address */
717 if (!(ospf6_interface_get_linklocal_address(oi->interface)
718 || if_is_loopback(oi->interface))) {
719 if (IS_OSPF6_DEBUG_INTERFACE)
720 zlog_debug(
721 "Interface %s has no link local address, can't execute [InterfaceUp]",
722 oi->interface->name);
723 return 0;
724 }
725
726 /* Recompute cost */
727 ospf6_interface_recalculate_cost(oi);
728
729 /* if already enabled, do nothing */
730 if (oi->state > OSPF6_INTERFACE_DOWN) {
731 if (IS_OSPF6_DEBUG_INTERFACE)
732 zlog_debug("Interface %s already enabled",
733 oi->interface->name);
734 return 0;
735 }
736
737 /* If no area assigned, return */
738 if (oi->area == NULL) {
739 zlog_debug(
740 "%s: Not scheduleing Hello for %s as there is no area assigned yet",
741 __func__, oi->interface->name);
742 return 0;
743 }
744
745 #ifdef __FreeBSD__
746 /*
747 * XXX: Schedule IPv6 group join for later, otherwise we might
748 * lose the multicast group registration caused by IPv6 group
749 * leave race.
750 */
751 if (oi->sso_try_cnt == 0) {
752 oi->sso_try_cnt++;
753 zlog_info("Scheduling %s for sso", oi->interface->name);
754 thread_add_timer(master, interface_up, oi,
755 OSPF6_INTERFACE_SSO_RETRY_INT,
756 &oi->thread_sso);
757 return 0;
758 }
759 #endif /* __FreeBSD__ */
760 if (oi->area->ospf6)
761 ospf6 = oi->area->ospf6;
762 else
763 ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id);
764
765 /* Join AllSPFRouters */
766 if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP,
767 ospf6->fd)
768 < 0) {
769 if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX) {
770 zlog_info(
771 "Scheduling %s for sso retry, trial count: %d",
772 oi->interface->name, oi->sso_try_cnt);
773 thread_add_timer(master, interface_up, oi,
774 OSPF6_INTERFACE_SSO_RETRY_INT,
775 &oi->thread_sso);
776 }
777 return 0;
778 }
779 oi->sso_try_cnt = 0; /* Reset on success */
780
781 /* Update interface route */
782 ospf6_interface_connected_route_update(oi->interface);
783
784 /* Schedule Hello */
785 if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)
786 && !if_is_loopback(oi->interface)) {
787 oi->thread_send_hello = NULL;
788 thread_add_event(master, ospf6_hello_send, oi, 0,
789 &oi->thread_send_hello);
790 }
791
792 /* decide next interface state */
793 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
794 ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT, oi);
795 } else if (oi->priority == 0)
796 ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER, oi);
797 else {
798 ospf6_interface_state_change(OSPF6_INTERFACE_WAITING, oi);
799 thread_add_timer(master, wait_timer, oi, oi->dead_interval,
800 &oi->thread_wait_timer);
801 }
802
803 return 0;
804 }
805
806 int wait_timer(struct thread *thread)
807 {
808 struct ospf6_interface *oi;
809
810 oi = (struct ospf6_interface *)THREAD_ARG(thread);
811 assert(oi && oi->interface);
812
813 if (IS_OSPF6_DEBUG_INTERFACE)
814 zlog_debug("Interface Event %s: [WaitTimer]",
815 oi->interface->name);
816
817 if (oi->state == OSPF6_INTERFACE_WAITING)
818 ospf6_interface_state_change(dr_election(oi), oi);
819
820 return 0;
821 }
822
823 int backup_seen(struct thread *thread)
824 {
825 struct ospf6_interface *oi;
826
827 oi = (struct ospf6_interface *)THREAD_ARG(thread);
828 assert(oi && oi->interface);
829
830 if (IS_OSPF6_DEBUG_INTERFACE)
831 zlog_debug("Interface Event %s: [BackupSeen]",
832 oi->interface->name);
833
834 if (oi->state == OSPF6_INTERFACE_WAITING)
835 ospf6_interface_state_change(dr_election(oi), oi);
836
837 return 0;
838 }
839
840 int neighbor_change(struct thread *thread)
841 {
842 struct ospf6_interface *oi;
843
844 oi = (struct ospf6_interface *)THREAD_ARG(thread);
845 assert(oi && oi->interface);
846
847 if (IS_OSPF6_DEBUG_INTERFACE)
848 zlog_debug("Interface Event %s: [NeighborChange]",
849 oi->interface->name);
850
851 if (oi->state == OSPF6_INTERFACE_DROTHER
852 || oi->state == OSPF6_INTERFACE_BDR
853 || oi->state == OSPF6_INTERFACE_DR)
854 ospf6_interface_state_change(dr_election(oi), oi);
855
856 return 0;
857 }
858
859 int interface_down(struct thread *thread)
860 {
861 struct ospf6_interface *oi;
862 struct listnode *node, *nnode;
863 struct ospf6_neighbor *on;
864 struct ospf6 *ospf6;
865
866 oi = (struct ospf6_interface *)THREAD_ARG(thread);
867 assert(oi && oi->interface);
868
869 if (IS_OSPF6_DEBUG_INTERFACE)
870 zlog_debug("Interface Event %s: [InterfaceDown]",
871 oi->interface->name);
872
873 /* Stop Hellos */
874 THREAD_OFF(oi->thread_send_hello);
875
876 /* Stop trying to set socket options. */
877 THREAD_OFF(oi->thread_sso);
878 ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id);
879 /* Leave AllSPFRouters */
880 if (oi->state > OSPF6_INTERFACE_DOWN)
881 ospf6_sso(oi->interface->ifindex, &allspfrouters6,
882 IPV6_LEAVE_GROUP, ospf6->fd);
883
884 ospf6_interface_state_change(OSPF6_INTERFACE_DOWN, oi);
885
886 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
887 ospf6_neighbor_delete(on);
888
889 list_delete_all_node(oi->neighbor_list);
890
891 /* When interface state is reset, also reset information about
892 * DR election, as it is no longer valid. */
893 oi->drouter = oi->prev_drouter = htonl(0);
894 oi->bdrouter = oi->prev_bdrouter = htonl(0);
895 return 0;
896 }
897
898
899 static const char *ospf6_iftype_str(uint8_t iftype)
900 {
901 switch (iftype) {
902 case OSPF_IFTYPE_LOOPBACK:
903 return "LOOPBACK";
904 case OSPF_IFTYPE_BROADCAST:
905 return "BROADCAST";
906 case OSPF_IFTYPE_POINTOPOINT:
907 return "POINTOPOINT";
908 }
909 return "UNKNOWN";
910 }
911
912 /* show specified interface structure */
913 static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
914 json_object *json_obj, bool use_json)
915 {
916 struct ospf6_interface *oi;
917 struct connected *c;
918 struct prefix *p;
919 struct listnode *i;
920 char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32];
921 uint8_t default_iftype;
922 struct timeval res, now;
923 char duration[32];
924 struct ospf6_lsa *lsa, *lsanext;
925 json_object *json_arr;
926 json_object *json_addr;
927
928 default_iftype = ospf6_default_iftype(ifp);
929
930 if (use_json) {
931 json_object_string_add(json_obj, "status",
932 (if_is_operative(ifp) ? "up" : "down"));
933 json_object_string_add(json_obj, "type",
934 ospf6_iftype_str(default_iftype));
935 json_object_int_add(json_obj, "interfaceId", ifp->ifindex);
936
937 if (ifp->info == NULL) {
938 json_object_boolean_false_add(json_obj, "ospf6Enabled");
939 return 0;
940 }
941 json_object_boolean_true_add(json_obj, "ospf6Enabled");
942
943 oi = (struct ospf6_interface *)ifp->info;
944
945 if (if_is_operative(ifp) && oi->type != default_iftype)
946 json_object_string_add(json_obj, "operatingAsType",
947 ospf6_iftype_str(oi->type));
948
949 } else {
950 vty_out(vty, "%s is %s, type %s\n", ifp->name,
951 (if_is_operative(ifp) ? "up" : "down"),
952 ospf6_iftype_str(default_iftype));
953 vty_out(vty, " Interface ID: %d\n", ifp->ifindex);
954
955 if (ifp->info == NULL) {
956 vty_out(vty, " OSPF not enabled on this interface\n");
957 return 0;
958 }
959 oi = (struct ospf6_interface *)ifp->info;
960
961 if (if_is_operative(ifp) && oi->type != default_iftype)
962 vty_out(vty, " Operating as type %s\n",
963 ospf6_iftype_str(oi->type));
964 }
965
966 if (use_json) {
967 json_arr = json_object_new_array();
968 for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
969 json_addr = json_object_new_object();
970 p = c->address;
971 prefix2str(p, strbuf, sizeof(strbuf));
972 switch (p->family) {
973 case AF_INET:
974 json_object_string_add(json_addr, "type",
975 "inet");
976 json_object_string_add(json_addr, "address",
977 strbuf);
978 json_object_array_add(json_arr, json_addr);
979 break;
980 case AF_INET6:
981 json_object_string_add(json_addr, "type",
982 "inet6");
983 json_object_string_add(json_addr, "address",
984 strbuf);
985 json_object_array_add(json_arr, json_addr);
986 break;
987 default:
988 json_object_string_add(json_addr, "type",
989 "unknown");
990 json_object_string_add(json_addr, "address",
991 strbuf);
992 json_object_array_add(json_arr, json_addr);
993 break;
994 }
995 }
996 json_object_object_add(json_obj, "internetAddress", json_arr);
997 } else {
998 vty_out(vty, " Internet Address:\n");
999
1000 for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
1001 p = c->address;
1002 prefix2str(p, strbuf, sizeof(strbuf));
1003 switch (p->family) {
1004 case AF_INET:
1005 vty_out(vty, " inet : %pFX\n", p);
1006 break;
1007 case AF_INET6:
1008 vty_out(vty, " inet6: %pFX\n", p);
1009 break;
1010 default:
1011 vty_out(vty, " ??? : %pFX\n", p);
1012 break;
1013 }
1014 }
1015 }
1016
1017 if (use_json) {
1018 if (oi->area) {
1019 json_object_boolean_true_add(json_obj,
1020 "attachedToArea");
1021 json_object_int_add(json_obj, "instanceId",
1022 oi->instance_id);
1023 json_object_int_add(json_obj, "interfaceMtu",
1024 oi->ifmtu);
1025 json_object_int_add(json_obj, "autoDetect", ifp->mtu6);
1026 json_object_string_add(json_obj, "mtuMismatchDetection",
1027 oi->mtu_ignore ? "disabled"
1028 : "enabled");
1029 inet_ntop(AF_INET, &oi->area->area_id, strbuf,
1030 sizeof(strbuf));
1031 json_object_string_add(json_obj, "areaId", strbuf);
1032 json_object_int_add(json_obj, "cost", oi->cost);
1033 } else
1034 json_object_boolean_false_add(json_obj,
1035 "attachedToArea");
1036
1037 } else {
1038 if (oi->area) {
1039 vty_out(vty,
1040 " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
1041 oi->instance_id, oi->ifmtu, ifp->mtu6);
1042 vty_out(vty, " MTU mismatch detection: %s\n",
1043 oi->mtu_ignore ? "disabled" : "enabled");
1044 inet_ntop(AF_INET, &oi->area->area_id, strbuf,
1045 sizeof(strbuf));
1046 vty_out(vty, " Area ID %s, Cost %u\n", strbuf,
1047 oi->cost);
1048 } else
1049 vty_out(vty, " Not Attached to Area\n");
1050 }
1051
1052 if (use_json) {
1053 json_object_string_add(json_obj, "ospf6InterfaceState",
1054 ospf6_interface_state_str[oi->state]);
1055 json_object_int_add(json_obj, "transmitDelaySec",
1056 oi->transdelay);
1057 json_object_int_add(json_obj, "priority", oi->priority);
1058 json_object_int_add(json_obj, "timerIntervalsConfigHello",
1059 oi->hello_interval);
1060 json_object_int_add(json_obj, "timerIntervalsConfigDead",
1061 oi->dead_interval);
1062 json_object_int_add(json_obj, "timerIntervalsConfigRetransmit",
1063 oi->rxmt_interval);
1064 } else {
1065 vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n",
1066 ospf6_interface_state_str[oi->state], oi->transdelay,
1067 oi->priority);
1068 vty_out(vty, " Timer intervals configured:\n");
1069 vty_out(vty, " Hello %d, Dead %d, Retransmit %d\n",
1070 oi->hello_interval, oi->dead_interval,
1071 oi->rxmt_interval);
1072 }
1073
1074 inet_ntop(AF_INET, &oi->drouter, drouter, sizeof(drouter));
1075 inet_ntop(AF_INET, &oi->bdrouter, bdrouter, sizeof(bdrouter));
1076 if (use_json) {
1077 json_object_string_add(json_obj, "dr", drouter);
1078 json_object_string_add(json_obj, "bdr", bdrouter);
1079 json_object_int_add(json_obj, "numberOfInterfaceScopedLsa",
1080 oi->lsdb->count);
1081 } else {
1082 vty_out(vty, " DR: %s BDR: %s\n", drouter, bdrouter);
1083 vty_out(vty, " Number of I/F scoped LSAs is %u\n",
1084 oi->lsdb->count);
1085 }
1086
1087 monotime(&now);
1088
1089 if (use_json) {
1090 timerclear(&res);
1091 if (oi->thread_send_lsupdate)
1092 timersub(&oi->thread_send_lsupdate->u.sands, &now,
1093 &res);
1094 timerstring(&res, duration, sizeof(duration));
1095 json_object_int_add(json_obj, "pendingLsaLsUpdateCount",
1096 oi->lsupdate_list->count);
1097 json_object_string_add(json_obj, "pendingLsaLsUpdateTime",
1098 duration);
1099 json_object_string_add(
1100 json_obj, "lsUpdateSendThread",
1101 (oi->thread_send_lsupdate ? "on" : "off"));
1102
1103 json_arr = json_object_new_array();
1104 for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
1105 json_object_array_add(
1106 json_arr, json_object_new_string(lsa->name));
1107 json_object_object_add(json_obj, "pendingLsaLsUpdate",
1108 json_arr);
1109
1110 timerclear(&res);
1111 if (oi->thread_send_lsack)
1112 timersub(&oi->thread_send_lsack->u.sands, &now, &res);
1113 timerstring(&res, duration, sizeof(duration));
1114
1115 json_object_int_add(json_obj, "pendingLsaLsAckCount",
1116 oi->lsack_list->count);
1117 json_object_string_add(json_obj, "pendingLsaLsAckTime",
1118 duration);
1119 json_object_string_add(json_obj, "lsAckSendThread",
1120 (oi->thread_send_lsack ? "on" : "off"));
1121
1122 json_arr = json_object_new_array();
1123 for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
1124 json_object_array_add(
1125 json_arr, json_object_new_string(lsa->name));
1126 json_object_object_add(json_obj, "pendingLsaLsAck", json_arr);
1127
1128 } else {
1129 timerclear(&res);
1130 if (oi->thread_send_lsupdate)
1131 timersub(&oi->thread_send_lsupdate->u.sands, &now,
1132 &res);
1133 timerstring(&res, duration, sizeof(duration));
1134 vty_out(vty,
1135 " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
1136 oi->lsupdate_list->count, duration,
1137 (oi->thread_send_lsupdate ? "on" : "off"));
1138 for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
1139 vty_out(vty, " %s\n", lsa->name);
1140
1141 timerclear(&res);
1142 if (oi->thread_send_lsack)
1143 timersub(&oi->thread_send_lsack->u.sands, &now, &res);
1144 timerstring(&res, duration, sizeof(duration));
1145 vty_out(vty,
1146 " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
1147 oi->lsack_list->count, duration,
1148 (oi->thread_send_lsack ? "on" : "off"));
1149 for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
1150 vty_out(vty, " %s\n", lsa->name);
1151 }
1152
1153 /* BFD specific. */
1154 if (oi->bfd_config.enabled) {
1155 if (use_json) {
1156 struct json_object *json_bfd = json_object_new_object();
1157
1158 json_object_int_add(
1159 json_bfd, "detectMultiplier",
1160 oi->bfd_config.detection_multiplier);
1161 json_object_int_add(json_bfd, "rxMinInterval",
1162 oi->bfd_config.min_rx);
1163 json_object_int_add(json_bfd, "txMinInterval",
1164 oi->bfd_config.min_tx);
1165 json_object_object_add(json_obj, "peerBfdInfo",
1166 json_bfd);
1167 } else {
1168 vty_out(vty,
1169 " BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
1170 oi->bfd_config.detection_multiplier,
1171 oi->bfd_config.min_rx, oi->bfd_config.min_tx);
1172 }
1173 }
1174
1175 return 0;
1176 }
1177
1178 /* show interface */
1179 DEFUN(show_ipv6_ospf6_interface,
1180 show_ipv6_ospf6_interface_ifname_cmd,
1181 "show ipv6 ospf6 interface [IFNAME] [json]",
1182 SHOW_STR
1183 IP6_STR
1184 OSPF6_STR
1185 INTERFACE_STR
1186 IFNAME_STR
1187 JSON_STR)
1188 {
1189 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1190 int idx_ifname = 4;
1191 struct interface *ifp;
1192 json_object *json;
1193 json_object *json_int;
1194 bool uj = use_json(argc, argv);
1195
1196 if (uj) {
1197 json = json_object_new_object();
1198 if (argc == 6) {
1199 ifp = if_lookup_by_name(argv[idx_ifname]->arg,
1200 VRF_DEFAULT);
1201 json_int = json_object_new_object();
1202 if (ifp == NULL) {
1203 json_object_string_add(json, "noSuchInterface",
1204 argv[idx_ifname]->arg);
1205 vty_out(vty, "%s\n",
1206 json_object_to_json_string_ext(
1207 json, JSON_C_TO_STRING_PRETTY));
1208 json_object_free(json);
1209 json_object_free(json_int);
1210 return CMD_WARNING;
1211 }
1212 ospf6_interface_show(vty, ifp, json_int, uj);
1213 json_object_object_add(json, ifp->name, json_int);
1214 } else {
1215 FOR_ALL_INTERFACES (vrf, ifp) {
1216 json_int = json_object_new_object();
1217 ospf6_interface_show(vty, ifp, json_int, uj);
1218 json_object_object_add(json, ifp->name,
1219 json_int);
1220 }
1221 }
1222 vty_out(vty, "%s\n",
1223 json_object_to_json_string_ext(
1224 json, JSON_C_TO_STRING_PRETTY));
1225 json_object_free(json);
1226 } else {
1227 if (argc == 5) {
1228 ifp = if_lookup_by_name(argv[idx_ifname]->arg,
1229 VRF_DEFAULT);
1230 if (ifp == NULL) {
1231 vty_out(vty, "No such Interface: %s\n",
1232 argv[idx_ifname]->arg);
1233 return CMD_WARNING;
1234 }
1235 ospf6_interface_show(vty, ifp, NULL, uj);
1236 } else {
1237 FOR_ALL_INTERFACES (vrf, ifp)
1238 ospf6_interface_show(vty, ifp, NULL, uj);
1239 }
1240 }
1241
1242 return CMD_SUCCESS;
1243 }
1244
1245 static int ospf6_interface_show_traffic(struct vty *vty,
1246 struct interface *intf_ifp,
1247 int display_once, json_object *json,
1248 bool use_json)
1249 {
1250 struct interface *ifp;
1251 struct vrf *vrf = NULL;
1252 struct ospf6_interface *oi = NULL;
1253 json_object *json_interface;
1254
1255 if (intf_ifp)
1256 vrf = vrf_lookup_by_id(intf_ifp->vrf_id);
1257 else
1258 vrf = vrf_lookup_by_id(VRF_DEFAULT);
1259
1260 if (!display_once && !use_json) {
1261 vty_out(vty, "\n");
1262 vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
1263 " HELLO", " DB-Desc", " LS-Req", " LS-Update",
1264 " LS-Ack");
1265 vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
1266 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1267 " Rx/Tx");
1268 vty_out(vty,
1269 "--------------------------------------------------------------------------------------------\n");
1270 }
1271
1272 if (intf_ifp == NULL) {
1273 FOR_ALL_INTERFACES (vrf, ifp) {
1274 if (ifp->info)
1275 oi = (struct ospf6_interface *)ifp->info;
1276 else
1277 continue;
1278
1279 if (use_json) {
1280 json_interface = json_object_new_object();
1281 json_object_int_add(json_interface, "helloRx",
1282 oi->hello_in);
1283 json_object_int_add(json_interface, "helloTx",
1284 oi->hello_out);
1285 json_object_int_add(json_interface, "dbDescRx",
1286 oi->db_desc_in);
1287 json_object_int_add(json_interface, "dbDescTx",
1288 oi->db_desc_out);
1289 json_object_int_add(json_interface, "lsReqRx",
1290 oi->ls_req_in);
1291 json_object_int_add(json_interface, "lsReqTx",
1292 oi->ls_req_out);
1293 json_object_int_add(json_interface,
1294 "lsUpdateRx",
1295 oi->ls_upd_in);
1296 json_object_int_add(json_interface,
1297 "lsUpdateTx",
1298 oi->ls_upd_out);
1299 json_object_int_add(json_interface, "lsAckRx",
1300 oi->ls_ack_in);
1301 json_object_int_add(json_interface, "lsAckTx",
1302 oi->ls_ack_out);
1303
1304 json_object_object_add(json,
1305 oi->interface->name,
1306 json_interface);
1307 } else
1308 vty_out(vty,
1309 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1310 oi->interface->name, oi->hello_in,
1311 oi->hello_out, oi->db_desc_in,
1312 oi->db_desc_out, oi->ls_req_in,
1313 oi->ls_req_out, oi->ls_upd_in,
1314 oi->ls_upd_out, oi->ls_ack_in,
1315 oi->ls_ack_out);
1316 }
1317 } else {
1318 oi = intf_ifp->info;
1319 if (oi == NULL)
1320 return CMD_WARNING;
1321
1322 if (use_json) {
1323 json_interface = json_object_new_object();
1324 json_object_int_add(json_interface, "helloRx",
1325 oi->hello_in);
1326 json_object_int_add(json_interface, "helloTx",
1327 oi->hello_out);
1328 json_object_int_add(json_interface, "dbDescRx",
1329 oi->db_desc_in);
1330 json_object_int_add(json_interface, "dbDescTx",
1331 oi->db_desc_out);
1332 json_object_int_add(json_interface, "lsReqRx",
1333 oi->ls_req_in);
1334 json_object_int_add(json_interface, "lsReqTx",
1335 oi->ls_req_out);
1336 json_object_int_add(json_interface, "lsUpdateRx",
1337 oi->ls_upd_in);
1338 json_object_int_add(json_interface, "lsUpdateTx",
1339 oi->ls_upd_out);
1340 json_object_int_add(json_interface, "lsAckRx",
1341 oi->ls_ack_in);
1342 json_object_int_add(json_interface, "lsAckTx",
1343 oi->ls_ack_out);
1344
1345 json_object_object_add(json, oi->interface->name,
1346 json_interface);
1347 } else
1348 vty_out(vty,
1349 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
1350 oi->interface->name, oi->hello_in,
1351 oi->hello_out, oi->db_desc_in, oi->db_desc_out,
1352 oi->ls_req_in, oi->ls_req_out, oi->ls_upd_in,
1353 oi->ls_upd_out, oi->ls_ack_in, oi->ls_ack_out);
1354 }
1355
1356 return CMD_SUCCESS;
1357 }
1358
1359 /* show interface */
1360 DEFUN(show_ipv6_ospf6_interface_traffic,
1361 show_ipv6_ospf6_interface_traffic_cmd,
1362 "show ipv6 ospf6 interface traffic [IFNAME] [json]",
1363 SHOW_STR
1364 IP6_STR
1365 OSPF6_STR
1366 INTERFACE_STR
1367 "Protocol Packet counters\n"
1368 IFNAME_STR
1369 JSON_STR)
1370 {
1371 int idx_ifname = 0;
1372 int display_once = 0;
1373 char *intf_name = NULL;
1374 struct interface *ifp = NULL;
1375 json_object *json = NULL;
1376 bool uj = use_json(argc, argv);
1377
1378 if (uj)
1379 json = json_object_new_object();
1380
1381 if (argv_find(argv, argc, "IFNAME", &idx_ifname)) {
1382 intf_name = argv[idx_ifname]->arg;
1383 ifp = if_lookup_by_name(intf_name, VRF_DEFAULT);
1384 if (uj) {
1385 if (ifp == NULL) {
1386 json_object_string_add(json, "status",
1387 "No Such Interface");
1388 json_object_string_add(json, "interface",
1389 intf_name);
1390 vty_out(vty, "%s\n",
1391 json_object_to_json_string_ext(
1392 json, JSON_C_TO_STRING_PRETTY));
1393 json_object_free(json);
1394 return CMD_WARNING;
1395 }
1396 if (ifp->info == NULL) {
1397 json_object_string_add(
1398 json, "status",
1399 "OSPF not enabled on this interface");
1400 json_object_string_add(json, "interface",
1401 intf_name);
1402 vty_out(vty, "%s\n",
1403 json_object_to_json_string_ext(
1404 json, JSON_C_TO_STRING_PRETTY));
1405 json_object_free(json);
1406 return 0;
1407 }
1408 } else {
1409 if (ifp == NULL) {
1410 vty_out(vty, "No such Interface: %s\n",
1411 intf_name);
1412 return CMD_WARNING;
1413 }
1414 if (ifp->info == NULL) {
1415 vty_out(vty,
1416 " OSPF not enabled on this interface %s\n",
1417 intf_name);
1418 return 0;
1419 }
1420 }
1421 }
1422
1423 ospf6_interface_show_traffic(vty, ifp, display_once, json, uj);
1424
1425 if (uj) {
1426 vty_out(vty, "%s\n",
1427 json_object_to_json_string_ext(
1428 json, JSON_C_TO_STRING_PRETTY));
1429 json_object_free(json);
1430 }
1431
1432
1433 return CMD_SUCCESS;
1434 }
1435
1436
1437 DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
1438 show_ipv6_ospf6_interface_ifname_prefix_cmd,
1439 "show ipv6 ospf6 interface IFNAME prefix\
1440 [<\
1441 detail\
1442 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1443 >] [json]",
1444 SHOW_STR
1445 IP6_STR
1446 OSPF6_STR
1447 INTERFACE_STR
1448 IFNAME_STR
1449 "Display connected prefixes to advertise\n"
1450 "Display details of the prefixes\n"
1451 OSPF6_ROUTE_ADDRESS_STR
1452 OSPF6_ROUTE_PREFIX_STR
1453 OSPF6_ROUTE_MATCH_STR
1454 "Display details of the prefixes\n"
1455 JSON_STR)
1456 {
1457 int idx_ifname = 4;
1458 int idx_prefix = 6;
1459 struct interface *ifp;
1460 struct ospf6_interface *oi;
1461 bool uj = use_json(argc, argv);
1462
1463 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
1464 if (ifp == NULL) {
1465 vty_out(vty, "No such Interface: %s\n", argv[idx_ifname]->arg);
1466 return CMD_WARNING;
1467 }
1468
1469 oi = ifp->info;
1470 if (oi == NULL) {
1471 vty_out(vty, "OSPFv3 is not enabled on %s\n",
1472 argv[idx_ifname]->arg);
1473 return CMD_WARNING;
1474 }
1475
1476 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) {
1477 vty_out(vty, "Interface %s not attached to area\n",
1478 argv[idx_ifname]->arg);
1479 return CMD_WARNING;
1480 }
1481
1482 ospf6_route_table_show(vty, idx_prefix, argc, argv, oi->route_connected,
1483 uj);
1484
1485 return CMD_SUCCESS;
1486 }
1487
1488 DEFUN (show_ipv6_ospf6_interface_prefix,
1489 show_ipv6_ospf6_interface_prefix_cmd,
1490 "show ipv6 ospf6 interface prefix\
1491 [<\
1492 detail\
1493 |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
1494 >] [json]",
1495 SHOW_STR
1496 IP6_STR
1497 OSPF6_STR
1498 INTERFACE_STR
1499 "Display connected prefixes to advertise\n"
1500 "Display details of the prefixes\n"
1501 OSPF6_ROUTE_ADDRESS_STR
1502 OSPF6_ROUTE_PREFIX_STR
1503 OSPF6_ROUTE_MATCH_STR
1504 "Display details of the prefixes\n"
1505 JSON_STR)
1506 {
1507 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1508 int idx_prefix = 5;
1509 struct ospf6_interface *oi;
1510 struct interface *ifp;
1511 bool uj = use_json(argc, argv);
1512
1513 FOR_ALL_INTERFACES (vrf, ifp) {
1514 oi = (struct ospf6_interface *)ifp->info;
1515 if (oi == NULL || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
1516 continue;
1517
1518 ospf6_route_table_show(vty, idx_prefix, argc, argv,
1519 oi->route_connected, uj);
1520 }
1521
1522 return CMD_SUCCESS;
1523 }
1524
1525 /* interface variable set command */
1526 DEFUN (ipv6_ospf6_ifmtu,
1527 ipv6_ospf6_ifmtu_cmd,
1528 "ipv6 ospf6 ifmtu (1-65535)",
1529 IP6_STR
1530 OSPF6_STR
1531 "Interface MTU\n"
1532 "OSPFv3 Interface MTU\n"
1533 )
1534 {
1535 VTY_DECLVAR_CONTEXT(interface, ifp);
1536 int idx_number = 3;
1537 struct ospf6_interface *oi;
1538 unsigned int ifmtu, iobuflen;
1539 struct listnode *node, *nnode;
1540 struct ospf6_neighbor *on;
1541
1542 assert(ifp);
1543
1544 oi = (struct ospf6_interface *)ifp->info;
1545 if (oi == NULL)
1546 oi = ospf6_interface_create(ifp);
1547 assert(oi);
1548
1549 ifmtu = strtol(argv[idx_number]->arg, NULL, 10);
1550
1551 if (oi->c_ifmtu == ifmtu)
1552 return CMD_SUCCESS;
1553
1554 if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) {
1555 vty_out(vty,
1556 "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n",
1557 ifp->name, ifp->mtu6);
1558 return CMD_WARNING_CONFIG_FAILED;
1559 }
1560
1561 if (oi->ifmtu < ifmtu) {
1562 iobuflen = ospf6_iobuf_size(ifmtu);
1563 if (iobuflen < ifmtu) {
1564 vty_out(vty,
1565 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1566 ifp->name, iobuflen);
1567 oi->ifmtu = oi->c_ifmtu = iobuflen;
1568 } else
1569 oi->ifmtu = oi->c_ifmtu = ifmtu;
1570 } else
1571 oi->ifmtu = oi->c_ifmtu = ifmtu;
1572
1573 /* re-establish adjacencies */
1574 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1575 THREAD_OFF(on->inactivity_timer);
1576 thread_add_event(master, inactivity_timer, on, 0, NULL);
1577 }
1578
1579 return CMD_SUCCESS;
1580 }
1581
1582 DEFUN (no_ipv6_ospf6_ifmtu,
1583 no_ipv6_ospf6_ifmtu_cmd,
1584 "no ipv6 ospf6 ifmtu [(1-65535)]",
1585 NO_STR
1586 IP6_STR
1587 OSPF6_STR
1588 "Interface MTU\n"
1589 "OSPFv3 Interface MTU\n"
1590 )
1591 {
1592 VTY_DECLVAR_CONTEXT(interface, ifp);
1593 struct ospf6_interface *oi;
1594 unsigned int iobuflen;
1595 struct listnode *node, *nnode;
1596 struct ospf6_neighbor *on;
1597
1598 assert(ifp);
1599
1600 oi = (struct ospf6_interface *)ifp->info;
1601 if (oi == NULL)
1602 oi = ospf6_interface_create(ifp);
1603 assert(oi);
1604
1605 if (oi->ifmtu < ifp->mtu) {
1606 iobuflen = ospf6_iobuf_size(ifp->mtu);
1607 if (iobuflen < ifp->mtu) {
1608 vty_out(vty,
1609 "%s's ifmtu is adjusted to I/O buffer size (%d).\n",
1610 ifp->name, iobuflen);
1611 oi->ifmtu = iobuflen;
1612 } else
1613 oi->ifmtu = ifp->mtu;
1614 } else
1615 oi->ifmtu = ifp->mtu;
1616
1617 oi->c_ifmtu = 0;
1618
1619 /* re-establish adjacencies */
1620 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1621 THREAD_OFF(on->inactivity_timer);
1622 thread_add_event(master, inactivity_timer, on, 0, NULL);
1623 }
1624
1625 return CMD_SUCCESS;
1626 }
1627
1628 DEFUN (ipv6_ospf6_cost,
1629 ipv6_ospf6_cost_cmd,
1630 "ipv6 ospf6 cost (1-65535)",
1631 IP6_STR
1632 OSPF6_STR
1633 "Interface cost\n"
1634 "Outgoing metric of this interface\n")
1635 {
1636 VTY_DECLVAR_CONTEXT(interface, ifp);
1637 int idx_number = 3;
1638 struct ospf6_interface *oi;
1639 unsigned long int lcost;
1640
1641 assert(ifp);
1642
1643 oi = (struct ospf6_interface *)ifp->info;
1644 if (oi == NULL)
1645 oi = ospf6_interface_create(ifp);
1646 assert(oi);
1647
1648 lcost = strtol(argv[idx_number]->arg, NULL, 10);
1649
1650 if (lcost > UINT32_MAX) {
1651 vty_out(vty, "Cost %ld is out of range\n", lcost);
1652 return CMD_WARNING_CONFIG_FAILED;
1653 }
1654
1655 SET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1656 if (oi->cost == lcost)
1657 return CMD_SUCCESS;
1658
1659 oi->cost = lcost;
1660 ospf6_interface_force_recalculate_cost(oi);
1661
1662 return CMD_SUCCESS;
1663 }
1664
1665 DEFUN (no_ipv6_ospf6_cost,
1666 no_ipv6_ospf6_cost_cmd,
1667 "no ipv6 ospf6 cost [(1-65535)]",
1668 NO_STR
1669 IP6_STR
1670 OSPF6_STR
1671 "Calculate interface cost from bandwidth\n"
1672 "Outgoing metric of this interface\n")
1673 {
1674 VTY_DECLVAR_CONTEXT(interface, ifp);
1675 struct ospf6_interface *oi;
1676 assert(ifp);
1677
1678 oi = (struct ospf6_interface *)ifp->info;
1679 if (oi == NULL)
1680 oi = ospf6_interface_create(ifp);
1681 assert(oi);
1682
1683 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1684
1685 ospf6_interface_recalculate_cost(oi);
1686
1687 return CMD_SUCCESS;
1688 }
1689
1690 DEFUN (auto_cost_reference_bandwidth,
1691 auto_cost_reference_bandwidth_cmd,
1692 "auto-cost reference-bandwidth (1-4294967)",
1693 "Calculate OSPF interface cost according to bandwidth\n"
1694 "Use reference bandwidth method to assign OSPF cost\n"
1695 "The reference bandwidth in terms of Mbits per second\n")
1696 {
1697 VTY_DECLVAR_CONTEXT(ospf6, o);
1698 int idx_number = 2;
1699 struct ospf6_area *oa;
1700 struct ospf6_interface *oi;
1701 struct listnode *i, *j;
1702 uint32_t refbw;
1703
1704 refbw = strtol(argv[idx_number]->arg, NULL, 10);
1705 if (refbw < 1 || refbw > 4294967) {
1706 vty_out(vty, "reference-bandwidth value is invalid\n");
1707 return CMD_WARNING_CONFIG_FAILED;
1708 }
1709
1710 /* If reference bandwidth is changed. */
1711 if ((refbw) == o->ref_bandwidth)
1712 return CMD_SUCCESS;
1713
1714 o->ref_bandwidth = refbw;
1715 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1716 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1717 ospf6_interface_recalculate_cost(oi);
1718
1719 return CMD_SUCCESS;
1720 }
1721
1722 DEFUN (no_auto_cost_reference_bandwidth,
1723 no_auto_cost_reference_bandwidth_cmd,
1724 "no auto-cost reference-bandwidth [(1-4294967)]",
1725 NO_STR
1726 "Calculate OSPF interface cost according to bandwidth\n"
1727 "Use reference bandwidth method to assign OSPF cost\n"
1728 "The reference bandwidth in terms of Mbits per second\n")
1729 {
1730 VTY_DECLVAR_CONTEXT(ospf6, o);
1731 struct ospf6_area *oa;
1732 struct ospf6_interface *oi;
1733 struct listnode *i, *j;
1734
1735 if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH)
1736 return CMD_SUCCESS;
1737
1738 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
1739 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa))
1740 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
1741 ospf6_interface_recalculate_cost(oi);
1742
1743 return CMD_SUCCESS;
1744 }
1745
1746
1747 DEFUN (ipv6_ospf6_hellointerval,
1748 ipv6_ospf6_hellointerval_cmd,
1749 "ipv6 ospf6 hello-interval (1-65535)",
1750 IP6_STR
1751 OSPF6_STR
1752 "Time between HELLO packets\n"
1753 SECONDS_STR)
1754 {
1755 VTY_DECLVAR_CONTEXT(interface, ifp);
1756 int idx_number = 3;
1757 struct ospf6_interface *oi;
1758 assert(ifp);
1759
1760 oi = (struct ospf6_interface *)ifp->info;
1761 if (oi == NULL)
1762 oi = ospf6_interface_create(ifp);
1763 assert(oi);
1764
1765 oi->hello_interval = strmatch(argv[0]->text, "no")
1766 ? OSPF_HELLO_INTERVAL_DEFAULT
1767 : strtoul(argv[idx_number]->arg, NULL, 10);
1768 return CMD_SUCCESS;
1769 }
1770
1771 ALIAS (ipv6_ospf6_hellointerval,
1772 no_ipv6_ospf6_hellointerval_cmd,
1773 "no ipv6 ospf6 hello-interval [(1-65535)]",
1774 NO_STR
1775 IP6_STR
1776 OSPF6_STR
1777 "Time between HELLO packets\n"
1778 SECONDS_STR)
1779
1780 /* interface variable set command */
1781 DEFUN (ipv6_ospf6_deadinterval,
1782 ipv6_ospf6_deadinterval_cmd,
1783 "ipv6 ospf6 dead-interval (1-65535)",
1784 IP6_STR
1785 OSPF6_STR
1786 "Interval time after which a neighbor is declared down\n"
1787 SECONDS_STR)
1788 {
1789 VTY_DECLVAR_CONTEXT(interface, ifp);
1790 int idx_number = 3;
1791 struct ospf6_interface *oi;
1792 assert(ifp);
1793
1794 oi = (struct ospf6_interface *)ifp->info;
1795 if (oi == NULL)
1796 oi = ospf6_interface_create(ifp);
1797 assert(oi);
1798
1799 oi->dead_interval = strmatch(argv[0]->arg, "no")
1800 ? OSPF_ROUTER_DEAD_INTERVAL_DEFAULT
1801 : strtoul(argv[idx_number]->arg, NULL, 10);
1802 return CMD_SUCCESS;
1803 }
1804
1805 ALIAS (ipv6_ospf6_deadinterval,
1806 no_ipv6_ospf6_deadinterval_cmd,
1807 "no ipv6 ospf6 dead-interval [(1-65535)]",
1808 NO_STR
1809 IP6_STR
1810 OSPF6_STR
1811 "Interval time after which a neighbor is declared down\n"
1812 SECONDS_STR)
1813
1814 /* interface variable set command */
1815 DEFUN (ipv6_ospf6_transmitdelay,
1816 ipv6_ospf6_transmitdelay_cmd,
1817 "ipv6 ospf6 transmit-delay (1-3600)",
1818 IP6_STR
1819 OSPF6_STR
1820 "Link state transmit delay\n"
1821 SECONDS_STR)
1822 {
1823 VTY_DECLVAR_CONTEXT(interface, ifp);
1824 int idx_number = 3;
1825 struct ospf6_interface *oi;
1826 assert(ifp);
1827
1828 oi = (struct ospf6_interface *)ifp->info;
1829 if (oi == NULL)
1830 oi = ospf6_interface_create(ifp);
1831 assert(oi);
1832
1833 oi->transdelay = strmatch(argv[0]->text, "no")
1834 ? OSPF6_INTERFACE_TRANSDELAY
1835 : strtoul(argv[idx_number]->arg, NULL, 10);
1836 return CMD_SUCCESS;
1837 }
1838
1839 ALIAS (ipv6_ospf6_transmitdelay,
1840 no_ipv6_ospf6_transmitdelay_cmd,
1841 "no ipv6 ospf6 transmit-delay [(1-3600)]",
1842 NO_STR
1843 IP6_STR
1844 OSPF6_STR
1845 "Link state transmit delay\n"
1846 SECONDS_STR)
1847
1848 /* interface variable set command */
1849 DEFUN (ipv6_ospf6_retransmitinterval,
1850 ipv6_ospf6_retransmitinterval_cmd,
1851 "ipv6 ospf6 retransmit-interval (1-65535)",
1852 IP6_STR
1853 OSPF6_STR
1854 "Time between retransmitting lost link state advertisements\n"
1855 SECONDS_STR)
1856 {
1857 VTY_DECLVAR_CONTEXT(interface, ifp);
1858 int idx_number = 3;
1859 struct ospf6_interface *oi;
1860 assert(ifp);
1861
1862 oi = (struct ospf6_interface *)ifp->info;
1863 if (oi == NULL)
1864 oi = ospf6_interface_create(ifp);
1865 assert(oi);
1866
1867 oi->rxmt_interval = strmatch(argv[0]->text, "no")
1868 ? OSPF_RETRANSMIT_INTERVAL_DEFAULT
1869 : strtoul(argv[idx_number]->arg, NULL, 10);
1870 return CMD_SUCCESS;
1871 }
1872
1873 ALIAS (ipv6_ospf6_retransmitinterval,
1874 no_ipv6_ospf6_retransmitinterval_cmd,
1875 "no ipv6 ospf6 retransmit-interval [(1-65535)]",
1876 NO_STR
1877 IP6_STR
1878 OSPF6_STR
1879 "Time between retransmitting lost link state advertisements\n"
1880 SECONDS_STR)
1881
1882 /* interface variable set command */
1883 DEFUN (ipv6_ospf6_priority,
1884 ipv6_ospf6_priority_cmd,
1885 "ipv6 ospf6 priority (0-255)",
1886 IP6_STR
1887 OSPF6_STR
1888 "Router priority\n"
1889 "Priority value\n")
1890 {
1891 VTY_DECLVAR_CONTEXT(interface, ifp);
1892 int idx_number = 3;
1893 struct ospf6_interface *oi;
1894 assert(ifp);
1895
1896 oi = (struct ospf6_interface *)ifp->info;
1897 if (oi == NULL)
1898 oi = ospf6_interface_create(ifp);
1899 assert(oi);
1900
1901 oi->priority = strmatch(argv[0]->text, "no")
1902 ? OSPF6_INTERFACE_PRIORITY
1903 : strtoul(argv[idx_number]->arg, NULL, 10);
1904
1905 if (oi->area && (oi->state == OSPF6_INTERFACE_DROTHER
1906 || oi->state == OSPF6_INTERFACE_BDR
1907 || oi->state == OSPF6_INTERFACE_DR))
1908 ospf6_interface_state_change(dr_election(oi), oi);
1909
1910 return CMD_SUCCESS;
1911 }
1912
1913 ALIAS (ipv6_ospf6_priority,
1914 no_ipv6_ospf6_priority_cmd,
1915 "no ipv6 ospf6 priority [(0-255)]",
1916 NO_STR
1917 IP6_STR
1918 OSPF6_STR
1919 "Router priority\n"
1920 "Priority value\n")
1921
1922 DEFUN (ipv6_ospf6_instance,
1923 ipv6_ospf6_instance_cmd,
1924 "ipv6 ospf6 instance-id (0-255)",
1925 IP6_STR
1926 OSPF6_STR
1927 "Instance ID for this interface\n"
1928 "Instance ID value\n")
1929 {
1930 VTY_DECLVAR_CONTEXT(interface, ifp);
1931 int idx_number = 3;
1932 struct ospf6_interface *oi;
1933 assert(ifp);
1934
1935 oi = (struct ospf6_interface *)ifp->info;
1936 if (oi == NULL)
1937 oi = ospf6_interface_create(ifp);
1938 assert(oi);
1939
1940 oi->instance_id = strmatch(argv[0]->text, "no")
1941 ? OSPF6_INTERFACE_INSTANCE_ID
1942 : strtoul(argv[idx_number]->arg, NULL, 10);
1943 return CMD_SUCCESS;
1944 }
1945
1946 ALIAS (ipv6_ospf6_instance,
1947 no_ipv6_ospf6_instance_cmd,
1948 "no ipv6 ospf6 instance-id [(0-255)]",
1949 NO_STR
1950 IP6_STR
1951 OSPF6_STR
1952 "Instance ID for this interface\n"
1953 "Instance ID value\n")
1954
1955 DEFUN (ipv6_ospf6_passive,
1956 ipv6_ospf6_passive_cmd,
1957 "ipv6 ospf6 passive",
1958 IP6_STR
1959 OSPF6_STR
1960 "Passive interface; no adjacency will be formed on this interface\n"
1961 )
1962 {
1963 VTY_DECLVAR_CONTEXT(interface, ifp);
1964 struct ospf6_interface *oi;
1965 struct listnode *node, *nnode;
1966 struct ospf6_neighbor *on;
1967
1968 assert(ifp);
1969
1970 oi = (struct ospf6_interface *)ifp->info;
1971 if (oi == NULL)
1972 oi = ospf6_interface_create(ifp);
1973 assert(oi);
1974
1975 SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
1976 THREAD_OFF(oi->thread_send_hello);
1977 THREAD_OFF(oi->thread_sso);
1978
1979 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
1980 THREAD_OFF(on->inactivity_timer);
1981 thread_add_event(master, inactivity_timer, on, 0, NULL);
1982 }
1983
1984 return CMD_SUCCESS;
1985 }
1986
1987 DEFUN (no_ipv6_ospf6_passive,
1988 no_ipv6_ospf6_passive_cmd,
1989 "no ipv6 ospf6 passive",
1990 NO_STR
1991 IP6_STR
1992 OSPF6_STR
1993 "passive interface: No Adjacency will be formed on this I/F\n"
1994 )
1995 {
1996 VTY_DECLVAR_CONTEXT(interface, ifp);
1997 struct ospf6_interface *oi;
1998 assert(ifp);
1999
2000 oi = (struct ospf6_interface *)ifp->info;
2001 if (oi == NULL)
2002 oi = ospf6_interface_create(ifp);
2003 assert(oi);
2004
2005 UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
2006 THREAD_OFF(oi->thread_send_hello);
2007 THREAD_OFF(oi->thread_sso);
2008
2009 /* don't send hellos over loopback interface */
2010 if (!if_is_loopback(oi->interface))
2011 thread_add_event(master, ospf6_hello_send, oi, 0,
2012 &oi->thread_send_hello);
2013
2014 return CMD_SUCCESS;
2015 }
2016
2017 DEFUN (ipv6_ospf6_mtu_ignore,
2018 ipv6_ospf6_mtu_ignore_cmd,
2019 "ipv6 ospf6 mtu-ignore",
2020 IP6_STR
2021 OSPF6_STR
2022 "Disable MTU mismatch detection on this interface\n"
2023 )
2024 {
2025 VTY_DECLVAR_CONTEXT(interface, ifp);
2026 struct ospf6_interface *oi;
2027 assert(ifp);
2028
2029 oi = (struct ospf6_interface *)ifp->info;
2030 if (oi == NULL)
2031 oi = ospf6_interface_create(ifp);
2032 assert(oi);
2033
2034 oi->mtu_ignore = 1;
2035
2036 return CMD_SUCCESS;
2037 }
2038
2039 DEFUN (no_ipv6_ospf6_mtu_ignore,
2040 no_ipv6_ospf6_mtu_ignore_cmd,
2041 "no ipv6 ospf6 mtu-ignore",
2042 NO_STR
2043 IP6_STR
2044 OSPF6_STR
2045 "Disable MTU mismatch detection on this interface\n"
2046 )
2047 {
2048 VTY_DECLVAR_CONTEXT(interface, ifp);
2049 struct ospf6_interface *oi;
2050 assert(ifp);
2051
2052 oi = (struct ospf6_interface *)ifp->info;
2053 if (oi == NULL)
2054 oi = ospf6_interface_create(ifp);
2055 assert(oi);
2056
2057 oi->mtu_ignore = 0;
2058
2059 return CMD_SUCCESS;
2060 }
2061
2062 DEFUN (ipv6_ospf6_advertise_prefix_list,
2063 ipv6_ospf6_advertise_prefix_list_cmd,
2064 "ipv6 ospf6 advertise prefix-list WORD",
2065 IP6_STR
2066 OSPF6_STR
2067 "Advertising options\n"
2068 "Filter prefix using prefix-list\n"
2069 "Prefix list name\n"
2070 )
2071 {
2072 VTY_DECLVAR_CONTEXT(interface, ifp);
2073 int idx_word = 4;
2074 struct ospf6_interface *oi;
2075 assert(ifp);
2076
2077 oi = (struct ospf6_interface *)ifp->info;
2078 if (oi == NULL)
2079 oi = ospf6_interface_create(ifp);
2080 assert(oi);
2081
2082 if (oi->plist_name)
2083 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
2084 oi->plist_name = XSTRDUP(MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg);
2085
2086 ospf6_interface_connected_route_update(oi->interface);
2087
2088 if (oi->area) {
2089 OSPF6_LINK_LSA_SCHEDULE(oi);
2090 if (oi->state == OSPF6_INTERFACE_DR) {
2091 OSPF6_NETWORK_LSA_SCHEDULE(oi);
2092 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
2093 }
2094 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
2095 }
2096
2097 return CMD_SUCCESS;
2098 }
2099
2100 DEFUN (no_ipv6_ospf6_advertise_prefix_list,
2101 no_ipv6_ospf6_advertise_prefix_list_cmd,
2102 "no ipv6 ospf6 advertise prefix-list [WORD]",
2103 NO_STR
2104 IP6_STR
2105 OSPF6_STR
2106 "Advertising options\n"
2107 "Filter prefix using prefix-list\n"
2108 "Prefix list name\n")
2109 {
2110 VTY_DECLVAR_CONTEXT(interface, ifp);
2111 struct ospf6_interface *oi;
2112 assert(ifp);
2113
2114 oi = (struct ospf6_interface *)ifp->info;
2115 if (oi == NULL)
2116 oi = ospf6_interface_create(ifp);
2117 assert(oi);
2118
2119 if (oi->plist_name)
2120 XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name);
2121
2122 ospf6_interface_connected_route_update(oi->interface);
2123
2124 if (oi->area) {
2125 OSPF6_LINK_LSA_SCHEDULE(oi);
2126 if (oi->state == OSPF6_INTERFACE_DR) {
2127 OSPF6_NETWORK_LSA_SCHEDULE(oi);
2128 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
2129 }
2130 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
2131 }
2132
2133 return CMD_SUCCESS;
2134 }
2135
2136 DEFUN (ipv6_ospf6_network,
2137 ipv6_ospf6_network_cmd,
2138 "ipv6 ospf6 network <broadcast|point-to-point>",
2139 IP6_STR
2140 OSPF6_STR
2141 "Network type\n"
2142 "Specify OSPF6 broadcast network\n"
2143 "Specify OSPF6 point-to-point network\n"
2144 )
2145 {
2146 VTY_DECLVAR_CONTEXT(interface, ifp);
2147 int idx_network = 3;
2148 struct ospf6_interface *oi;
2149 assert(ifp);
2150
2151 oi = (struct ospf6_interface *)ifp->info;
2152 if (oi == NULL) {
2153 oi = ospf6_interface_create(ifp);
2154 }
2155 assert(oi);
2156
2157 oi->type_cfg = true;
2158
2159 if (strncmp(argv[idx_network]->arg, "b", 1) == 0) {
2160 if (oi->type == OSPF_IFTYPE_BROADCAST)
2161 return CMD_SUCCESS;
2162
2163 oi->type = OSPF_IFTYPE_BROADCAST;
2164 } else if (strncmp(argv[idx_network]->arg, "point-to-p", 10) == 0) {
2165 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
2166 return CMD_SUCCESS;
2167 }
2168 oi->type = OSPF_IFTYPE_POINTOPOINT;
2169 }
2170
2171 /* Reset the interface */
2172 thread_execute(master, interface_down, oi, 0);
2173 thread_execute(master, interface_up, oi, 0);
2174
2175 return CMD_SUCCESS;
2176 }
2177
2178 DEFUN (no_ipv6_ospf6_network,
2179 no_ipv6_ospf6_network_cmd,
2180 "no ipv6 ospf6 network [<broadcast|point-to-point>]",
2181 NO_STR
2182 IP6_STR
2183 OSPF6_STR
2184 "Set default network type\n"
2185 "Specify OSPF6 broadcast network\n"
2186 "Specify OSPF6 point-to-point network\n")
2187 {
2188 VTY_DECLVAR_CONTEXT(interface, ifp);
2189 struct ospf6_interface *oi;
2190 int type;
2191
2192 assert(ifp);
2193
2194 oi = (struct ospf6_interface *)ifp->info;
2195 if (oi == NULL) {
2196 return CMD_SUCCESS;
2197 }
2198
2199 oi->type_cfg = false;
2200
2201 type = ospf6_default_iftype(ifp);
2202 if (oi->type == type) {
2203 return CMD_SUCCESS;
2204 }
2205 oi->type = type;
2206
2207 /* Reset the interface */
2208 thread_execute(master, interface_down, oi, 0);
2209 thread_execute(master, interface_up, oi, 0);
2210
2211 return CMD_SUCCESS;
2212 }
2213
2214 static int config_write_ospf6_interface(struct vty *vty)
2215 {
2216 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
2217 struct ospf6_interface *oi;
2218 struct interface *ifp;
2219
2220 FOR_ALL_INTERFACES (vrf, ifp) {
2221 oi = (struct ospf6_interface *)ifp->info;
2222 if (oi == NULL)
2223 continue;
2224
2225 vty_frame(vty, "interface %s\n", oi->interface->name);
2226
2227 if (ifp->desc)
2228 vty_out(vty, " description %s\n", ifp->desc);
2229 if (oi->c_ifmtu)
2230 vty_out(vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu);
2231
2232 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
2233 vty_out(vty, " ipv6 ospf6 cost %d\n", oi->cost);
2234
2235 if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
2236 vty_out(vty, " ipv6 ospf6 hello-interval %d\n",
2237 oi->hello_interval);
2238
2239 if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
2240 vty_out(vty, " ipv6 ospf6 dead-interval %d\n",
2241 oi->dead_interval);
2242
2243 if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
2244 vty_out(vty, " ipv6 ospf6 retransmit-interval %d\n",
2245 oi->rxmt_interval);
2246
2247 if (oi->priority != OSPF6_INTERFACE_PRIORITY)
2248 vty_out(vty, " ipv6 ospf6 priority %d\n", oi->priority);
2249
2250 if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
2251 vty_out(vty, " ipv6 ospf6 transmit-delay %d\n",
2252 oi->transdelay);
2253
2254 if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
2255 vty_out(vty, " ipv6 ospf6 instance-id %d\n",
2256 oi->instance_id);
2257
2258 if (oi->plist_name)
2259 vty_out(vty, " ipv6 ospf6 advertise prefix-list %s\n",
2260 oi->plist_name);
2261
2262 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE))
2263 vty_out(vty, " ipv6 ospf6 passive\n");
2264
2265 if (oi->mtu_ignore)
2266 vty_out(vty, " ipv6 ospf6 mtu-ignore\n");
2267
2268 if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT)
2269 vty_out(vty, " ipv6 ospf6 network point-to-point\n");
2270 else if (oi->type_cfg && oi->type == OSPF_IFTYPE_BROADCAST)
2271 vty_out(vty, " ipv6 ospf6 network broadcast\n");
2272
2273 ospf6_bfd_write_config(vty, oi);
2274
2275 vty_endframe(vty, "!\n");
2276 }
2277 return 0;
2278 }
2279
2280 static int config_write_ospf6_interface(struct vty *vty);
2281 static struct cmd_node interface_node = {
2282 .name = "interface",
2283 .node = INTERFACE_NODE,
2284 .parent_node = CONFIG_NODE,
2285 .prompt = "%s(config-if)# ",
2286 .config_write = config_write_ospf6_interface,
2287 };
2288
2289 static int ospf6_ifp_create(struct interface *ifp)
2290 {
2291 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2292 zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp->name,
2293 ifp->ifindex, ifp->mtu6);
2294 ospf6_interface_if_add(ifp);
2295
2296 return 0;
2297 }
2298
2299 static int ospf6_ifp_up(struct interface *ifp)
2300 {
2301 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2302 zlog_debug(
2303 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2304 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
2305 ifp->metric, ifp->mtu6, ifp->bandwidth);
2306
2307 ospf6_interface_state_update(ifp);
2308
2309 return 0;
2310 }
2311
2312 static int ospf6_ifp_down(struct interface *ifp)
2313 {
2314 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2315 zlog_debug(
2316 "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
2317 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
2318 ifp->metric, ifp->mtu6, ifp->bandwidth);
2319
2320 ospf6_interface_state_update(ifp);
2321
2322 return 0;
2323 }
2324
2325 static int ospf6_ifp_destroy(struct interface *ifp)
2326 {
2327 if (if_is_up(ifp))
2328 zlog_warn("Zebra: got delete of %s, but interface is still up",
2329 ifp->name);
2330
2331 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
2332 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
2333 ifp->name, ifp->ifindex, ifp->mtu6);
2334
2335 return 0;
2336 }
2337
2338 void ospf6_interface_init(void)
2339 {
2340 /* Install interface node. */
2341 install_node(&interface_node);
2342 if_cmd_init();
2343 if_zapi_callbacks(ospf6_ifp_create, ospf6_ifp_up,
2344 ospf6_ifp_down, ospf6_ifp_destroy);
2345
2346 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
2347 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
2348 install_element(VIEW_NODE,
2349 &show_ipv6_ospf6_interface_ifname_prefix_cmd);
2350 install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd);
2351
2352 install_element(INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
2353 install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
2354 install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
2355 install_element(INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
2356
2357 install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
2358 install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
2359 install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
2360 install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
2361 install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
2362 install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
2363 install_element(INTERFACE_NODE, &no_ipv6_ospf6_deadinterval_cmd);
2364 install_element(INTERFACE_NODE, &no_ipv6_ospf6_hellointerval_cmd);
2365 install_element(INTERFACE_NODE, &no_ipv6_ospf6_priority_cmd);
2366 install_element(INTERFACE_NODE, &no_ipv6_ospf6_retransmitinterval_cmd);
2367 install_element(INTERFACE_NODE, &no_ipv6_ospf6_transmitdelay_cmd);
2368 install_element(INTERFACE_NODE, &no_ipv6_ospf6_instance_cmd);
2369
2370 install_element(INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
2371 install_element(INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
2372
2373 install_element(INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
2374 install_element(INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
2375
2376 install_element(INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
2377 install_element(INTERFACE_NODE,
2378 &no_ipv6_ospf6_advertise_prefix_list_cmd);
2379
2380 install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd);
2381 install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
2382
2383 /* reference bandwidth commands */
2384 install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
2385 install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
2386 }
2387
2388 /* Clear the specified interface structure */
2389 static void ospf6_interface_clear(struct vty *vty, struct interface *ifp)
2390 {
2391 struct ospf6_interface *oi;
2392
2393 if (!if_is_operative(ifp))
2394 return;
2395
2396 if (ifp->info == NULL)
2397 return;
2398
2399 oi = (struct ospf6_interface *)ifp->info;
2400
2401 if (IS_OSPF6_DEBUG_INTERFACE)
2402 zlog_debug("Interface %s: clear by reset", ifp->name);
2403
2404 /* Reset the interface */
2405 thread_execute(master, interface_down, oi, 0);
2406 thread_execute(master, interface_up, oi, 0);
2407 }
2408
2409 /* Clear interface */
2410 DEFUN (clear_ipv6_ospf6_interface,
2411 clear_ipv6_ospf6_interface_cmd,
2412 "clear ipv6 ospf6 interface [IFNAME]",
2413 CLEAR_STR
2414 IP6_STR
2415 OSPF6_STR
2416 INTERFACE_STR
2417 IFNAME_STR
2418 )
2419 {
2420 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
2421 int idx_ifname = 4;
2422 struct interface *ifp;
2423
2424 if (argc == 4) /* Clear all the ospfv3 interfaces. */
2425 {
2426 FOR_ALL_INTERFACES (vrf, ifp)
2427 ospf6_interface_clear(vty, ifp);
2428 } else /* Interface name is specified. */
2429 {
2430 if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
2431 VRF_DEFAULT))
2432 == NULL) {
2433 vty_out(vty, "No such Interface: %s\n",
2434 argv[idx_ifname]->arg);
2435 return CMD_WARNING;
2436 }
2437 ospf6_interface_clear(vty, ifp);
2438 }
2439
2440 return CMD_SUCCESS;
2441 }
2442
2443 void install_element_ospf6_clear_interface(void)
2444 {
2445 install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
2446 }
2447
2448 DEFUN (debug_ospf6_interface,
2449 debug_ospf6_interface_cmd,
2450 "debug ospf6 interface",
2451 DEBUG_STR
2452 OSPF6_STR
2453 "Debug OSPFv3 Interface\n"
2454 )
2455 {
2456 OSPF6_DEBUG_INTERFACE_ON();
2457 return CMD_SUCCESS;
2458 }
2459
2460 DEFUN (no_debug_ospf6_interface,
2461 no_debug_ospf6_interface_cmd,
2462 "no debug ospf6 interface",
2463 NO_STR
2464 DEBUG_STR
2465 OSPF6_STR
2466 "Debug OSPFv3 Interface\n"
2467 )
2468 {
2469 OSPF6_DEBUG_INTERFACE_OFF();
2470 return CMD_SUCCESS;
2471 }
2472
2473 int config_write_ospf6_debug_interface(struct vty *vty)
2474 {
2475 if (IS_OSPF6_DEBUG_INTERFACE)
2476 vty_out(vty, "debug ospf6 interface\n");
2477 return 0;
2478 }
2479
2480 void install_element_ospf6_debug_interface(void)
2481 {
2482 install_element(ENABLE_NODE, &debug_ospf6_interface_cmd);
2483 install_element(ENABLE_NODE, &no_debug_ospf6_interface_cmd);
2484 install_element(CONFIG_NODE, &debug_ospf6_interface_cmd);
2485 install_element(CONFIG_NODE, &no_debug_ospf6_interface_cmd);
2486 }