]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_interface.c
Merge pull request #101 from LabNConsulting/working/master/patch-set/3-vrf
[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
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22 #include <zebra.h>
23
24 #include "memory.h"
25 #include "if.h"
26 #include "log.h"
27 #include "command.h"
28 #include "thread.h"
29 #include "prefix.h"
30 #include "plist.h"
31 #include "zclient.h"
32
33 #include "ospf6_lsa.h"
34 #include "ospf6_lsdb.h"
35 #include "ospf6_network.h"
36 #include "ospf6_message.h"
37 #include "ospf6_route.h"
38 #include "ospf6_top.h"
39 #include "ospf6_area.h"
40 #include "ospf6_interface.h"
41 #include "ospf6_neighbor.h"
42 #include "ospf6_intra.h"
43 #include "ospf6_spf.h"
44 #include "ospf6_snmp.h"
45 #include "ospf6d.h"
46 #include "ospf6_bfd.h"
47
48 DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names")
49 DEFINE_QOBJ_TYPE(ospf6_interface)
50
51 unsigned char conf_debug_ospf6_interface = 0;
52
53 const char *ospf6_interface_state_str[] =
54 {
55 "None",
56 "Down",
57 "Loopback",
58 "Waiting",
59 "PointToPoint",
60 "DROther",
61 "BDR",
62 "DR",
63 NULL
64 };
65
66 struct ospf6_interface *
67 ospf6_interface_lookup_by_ifindex (ifindex_t ifindex)
68 {
69 struct ospf6_interface *oi;
70 struct interface *ifp;
71
72 ifp = if_lookup_by_index (ifindex);
73 if (ifp == NULL)
74 return (struct ospf6_interface *) NULL;
75
76 oi = (struct ospf6_interface *) ifp->info;
77 return oi;
78 }
79
80 /* schedule routing table recalculation */
81 static void
82 ospf6_interface_lsdb_hook (struct ospf6_lsa *lsa, unsigned int reason)
83 {
84 struct ospf6_interface *oi;
85
86 if (lsa == NULL)
87 return;
88
89 oi = lsa->lsdb->data;
90 switch (ntohs (lsa->header->type))
91 {
92 case OSPF6_LSTYPE_LINK:
93 if (oi->state == OSPF6_INTERFACE_DR)
94 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
95 if (oi->area)
96 ospf6_spf_schedule (oi->area->ospf6, reason);
97 break;
98
99 default:
100 break;
101 }
102 }
103
104 static void
105 ospf6_interface_lsdb_hook_add (struct ospf6_lsa *lsa)
106 {
107 ospf6_interface_lsdb_hook(lsa, ospf6_lsadd_to_spf_reason(lsa));
108 }
109
110 static void
111 ospf6_interface_lsdb_hook_remove (struct ospf6_lsa *lsa)
112 {
113 ospf6_interface_lsdb_hook(lsa, ospf6_lsremove_to_spf_reason(lsa));
114 }
115
116 static u_char
117 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 u_int32_t
128 ospf6_interface_get_cost (struct ospf6_interface *oi)
129 {
130 /* If all else fails, use default OSPF cost */
131 u_int32_t cost;
132 u_int32_t bw, refbw;
133
134 bw = oi->interface->bandwidth ? oi->interface->bandwidth : OSPF6_INTERFACE_BANDWIDTH;
135 refbw = ospf6 ? ospf6->ref_bandwidth : OSPF6_REFERENCE_BANDWIDTH;
136
137 /* A specifed ip ospf cost overrides a calculated one. */
138 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
139 cost = oi->cost;
140 else
141 {
142 cost = (u_int32_t) ((double)refbw / (double)bw + (double)0.5);
143 if (cost < 1) cost = 1;
144 else if (cost > UINT32_MAX) cost = UINT32_MAX;
145 }
146
147 return cost;
148 }
149
150 static void
151 ospf6_interface_recalculate_cost (struct ospf6_interface *oi)
152 {
153 u_int32_t newcost;
154
155 newcost = ospf6_interface_get_cost (oi);
156 if (newcost == oi->cost) return;
157 oi->cost = newcost;
158
159 /* update cost held in route_connected list in ospf6_interface */
160 ospf6_interface_connected_route_update (oi->interface);
161
162 /* execute LSA hooks */
163 if (oi->area)
164 {
165 OSPF6_LINK_LSA_SCHEDULE (oi);
166 OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
167 OSPF6_NETWORK_LSA_SCHEDULE (oi);
168 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
169 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
170 }
171 }
172
173 /* Create new ospf6 interface structure */
174 struct ospf6_interface *
175 ospf6_interface_create (struct interface *ifp)
176 {
177 struct ospf6_interface *oi;
178 unsigned int iobuflen;
179
180 oi = (struct ospf6_interface *)
181 XCALLOC (MTYPE_OSPF6_IF, sizeof (struct ospf6_interface));
182
183 if (!oi)
184 {
185 zlog_err ("Can't malloc ospf6_interface for ifindex %d", ifp->ifindex);
186 return (struct ospf6_interface *) NULL;
187 }
188
189 oi->area = (struct ospf6_area *) NULL;
190 oi->neighbor_list = list_new ();
191 oi->neighbor_list->cmp = ospf6_neighbor_cmp;
192 oi->linklocal_addr = (struct in6_addr *) NULL;
193 oi->instance_id = OSPF6_INTERFACE_INSTANCE_ID;
194 oi->transdelay = OSPF6_INTERFACE_TRANSDELAY;
195 oi->priority = OSPF6_INTERFACE_PRIORITY;
196
197 oi->hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
198 oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
199 oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
200 oi->type = ospf6_default_iftype (ifp);
201 oi->state = OSPF6_INTERFACE_DOWN;
202 oi->flag = 0;
203 oi->mtu_ignore = 0;
204
205 /* Try to adjust I/O buffer size with IfMtu */
206 oi->ifmtu = ifp->mtu6;
207 iobuflen = ospf6_iobuf_size (ifp->mtu6);
208 if (oi->ifmtu > iobuflen)
209 {
210 if (IS_OSPF6_DEBUG_INTERFACE)
211 zlog_debug ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
212 ifp->name, iobuflen);
213 oi->ifmtu = iobuflen;
214 }
215
216 QOBJ_REG (oi, ospf6_interface);
217
218 oi->lsupdate_list = ospf6_lsdb_create (oi);
219 oi->lsack_list = ospf6_lsdb_create (oi);
220 oi->lsdb = ospf6_lsdb_create (oi);
221 oi->lsdb->hook_add = ospf6_interface_lsdb_hook_add;
222 oi->lsdb->hook_remove = ospf6_interface_lsdb_hook_remove;
223 oi->lsdb_self = ospf6_lsdb_create (oi);
224
225 oi->route_connected = 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
239 ospf6_interface_delete (struct ospf6_interface *oi)
240 {
241 struct listnode *node, *nnode;
242 struct ospf6_neighbor *on;
243
244 QOBJ_UNREG (oi);
245
246 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
247 ospf6_neighbor_delete (on);
248
249 list_delete (oi->neighbor_list);
250
251 THREAD_OFF (oi->thread_send_hello);
252 THREAD_OFF (oi->thread_send_lsupdate);
253 THREAD_OFF (oi->thread_send_lsack);
254
255 ospf6_lsdb_remove_all (oi->lsdb);
256 ospf6_lsdb_remove_all (oi->lsupdate_list);
257 ospf6_lsdb_remove_all (oi->lsack_list);
258
259 ospf6_lsdb_delete (oi->lsdb);
260 ospf6_lsdb_delete (oi->lsdb_self);
261
262 ospf6_lsdb_delete (oi->lsupdate_list);
263 ospf6_lsdb_delete (oi->lsack_list);
264
265 ospf6_route_table_delete (oi->route_connected);
266
267 /* cut link */
268 oi->interface->info = NULL;
269
270 /* plist_name */
271 if (oi->plist_name)
272 XFREE (MTYPE_CFG_PLIST_NAME, oi->plist_name);
273
274 ospf6_bfd_info_free(&(oi->bfd_info));
275
276 XFREE (MTYPE_OSPF6_IF, oi);
277 }
278
279 void
280 ospf6_interface_enable (struct ospf6_interface *oi)
281 {
282 UNSET_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE);
283 ospf6_interface_state_update (oi->interface);
284 }
285
286 void
287 ospf6_interface_disable (struct ospf6_interface *oi)
288 {
289 SET_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE);
290
291 thread_execute (master, interface_down, oi, 0);
292
293 ospf6_lsdb_remove_all (oi->lsdb);
294 ospf6_lsdb_remove_all (oi->lsdb_self);
295 ospf6_lsdb_remove_all (oi->lsupdate_list);
296 ospf6_lsdb_remove_all (oi->lsack_list);
297
298 THREAD_OFF (oi->thread_send_hello);
299 THREAD_OFF (oi->thread_send_lsupdate);
300 THREAD_OFF (oi->thread_send_lsack);
301
302 THREAD_OFF (oi->thread_network_lsa);
303 THREAD_OFF (oi->thread_link_lsa);
304 THREAD_OFF (oi->thread_intra_prefix_lsa);
305 }
306
307 static struct in6_addr *
308 ospf6_interface_get_linklocal_address (struct interface *ifp)
309 {
310 struct listnode *n;
311 struct connected *c;
312 struct in6_addr *l = (struct in6_addr *) NULL;
313
314 /* for each connected address */
315 for (ALL_LIST_ELEMENTS_RO (ifp->connected, n, c))
316 {
317 /* if family not AF_INET6, ignore */
318 if (c->address->family != AF_INET6)
319 continue;
320
321 /* linklocal scope check */
322 if (IN6_IS_ADDR_LINKLOCAL (&c->address->u.prefix6))
323 l = &c->address->u.prefix6;
324 }
325 return l;
326 }
327
328 void
329 ospf6_interface_if_add (struct interface *ifp)
330 {
331 struct ospf6_interface *oi;
332 unsigned int iobuflen;
333
334 oi = (struct ospf6_interface *) ifp->info;
335 if (oi == NULL)
336 return;
337
338 /* Try to adjust I/O buffer size with IfMtu */
339 if (oi->ifmtu == 0)
340 oi->ifmtu = ifp->mtu6;
341 iobuflen = ospf6_iobuf_size (ifp->mtu6);
342 if (oi->ifmtu > iobuflen)
343 {
344 if (IS_OSPF6_DEBUG_INTERFACE)
345 zlog_debug ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
346 ifp->name, iobuflen);
347 oi->ifmtu = iobuflen;
348 }
349
350 /* interface start */
351 ospf6_interface_state_update(oi->interface);
352 }
353
354 void
355 ospf6_interface_if_del (struct interface *ifp)
356 {
357 struct ospf6_interface *oi;
358
359 oi = (struct ospf6_interface *) ifp->info;
360 if (oi == NULL)
361 return;
362
363 /* interface stop */
364 if (oi->area)
365 thread_execute (master, interface_down, oi, 0);
366
367 listnode_delete (oi->area->if_list, oi);
368 oi->area = (struct ospf6_area *) NULL;
369
370 /* cut link */
371 oi->interface = NULL;
372 ifp->info = NULL;
373
374 ospf6_interface_delete (oi);
375 }
376
377 void
378 ospf6_interface_state_update (struct interface *ifp)
379 {
380 struct ospf6_interface *oi;
381
382 oi = (struct ospf6_interface *) ifp->info;
383 if (oi == NULL)
384 return;
385 if (oi->area == NULL)
386 return;
387 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
388 return;
389
390 if (if_is_operative (ifp)
391 && (ospf6_interface_get_linklocal_address(oi->interface)
392 || if_is_loopback(oi->interface)))
393 thread_add_event (master, interface_up, oi, 0);
394 else
395 thread_add_event (master, interface_down, oi, 0);
396
397 return;
398 }
399
400 void
401 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 {
428 if (c->address->family != AF_INET6)
429 continue;
430
431 CONTINUE_IF_ADDRESS_LINKLOCAL (IS_OSPF6_DEBUG_INTERFACE, c->address);
432 CONTINUE_IF_ADDRESS_UNSPECIFIED (IS_OSPF6_DEBUG_INTERFACE, c->address);
433 CONTINUE_IF_ADDRESS_LOOPBACK (IS_OSPF6_DEBUG_INTERFACE, c->address);
434 CONTINUE_IF_ADDRESS_V4COMPAT (IS_OSPF6_DEBUG_INTERFACE, c->address);
435 CONTINUE_IF_ADDRESS_V4MAPPED (IS_OSPF6_DEBUG_INTERFACE, c->address);
436
437 /* apply filter */
438 if (oi->plist_name)
439 {
440 struct prefix_list *plist;
441 enum prefix_list_type ret;
442 char buf[PREFIX2STR_BUFFER];
443
444 prefix2str (c->address, buf, sizeof (buf));
445 plist = prefix_list_lookup (AFI_IP6, oi->plist_name);
446 ret = prefix_list_apply (plist, (void *) c->address);
447 if (ret == PREFIX_DENY)
448 {
449 if (IS_OSPF6_DEBUG_INTERFACE)
450 zlog_debug ("%s on %s filtered by prefix-list %s ",
451 buf, oi->interface->name, oi->plist_name);
452 continue;
453 }
454 }
455
456 route = ospf6_route_create ();
457 memcpy (&route->prefix, c->address, sizeof (struct prefix));
458 apply_mask (&route->prefix);
459 route->type = OSPF6_DEST_TYPE_NETWORK;
460 route->path.area_id = oi->area->area_id;
461 route->path.type = OSPF6_PATH_TYPE_INTRA;
462 route->path.cost = oi->cost;
463 inet_pton (AF_INET6, "::1", &nh_addr);
464 ospf6_route_add_nexthop (route, oi->interface->ifindex, &nh_addr);
465 ospf6_route_add (route, oi->route_connected);
466 }
467
468 /* create new Link-LSA */
469 OSPF6_LINK_LSA_SCHEDULE (oi);
470 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
471 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
472 }
473
474 static void
475 ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi)
476 {
477 u_char prev_state;
478
479 prev_state = oi->state;
480 oi->state = next_state;
481
482 if (prev_state == next_state)
483 return;
484
485 /* log */
486 if (IS_OSPF6_DEBUG_INTERFACE)
487 {
488 zlog_debug ("Interface state change %s: %s -> %s", oi->interface->name,
489 ospf6_interface_state_str[prev_state],
490 ospf6_interface_state_str[next_state]);
491 }
492 oi->state_change++;
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, IPV6_LEAVE_GROUP);
499
500 if ((prev_state != OSPF6_INTERFACE_DR &&
501 prev_state != OSPF6_INTERFACE_BDR) &&
502 (next_state == OSPF6_INTERFACE_DR ||
503 next_state == OSPF6_INTERFACE_BDR))
504 ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_JOIN_GROUP);
505
506 OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
507 if (next_state == OSPF6_INTERFACE_DOWN)
508 {
509 OSPF6_NETWORK_LSA_EXECUTE (oi);
510 OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT (oi);
511 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
512 }
513 else if (prev_state == OSPF6_INTERFACE_DR ||
514 next_state == OSPF6_INTERFACE_DR)
515 {
516 OSPF6_NETWORK_LSA_SCHEDULE (oi);
517 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
518 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
519 }
520
521 #ifdef HAVE_SNMP
522 /* Terminal state or regression */
523 if ((next_state == OSPF6_INTERFACE_POINTTOPOINT) ||
524 (next_state == OSPF6_INTERFACE_DROTHER) ||
525 (next_state == OSPF6_INTERFACE_BDR) ||
526 (next_state == OSPF6_INTERFACE_DR) ||
527 (next_state < prev_state))
528 ospf6TrapIfStateChange (oi);
529 #endif
530
531 }
532
533
534 /* DR Election, RFC2328 section 9.4 */
535
536 #define IS_ELIGIBLE(n) \
537 ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
538
539 static struct ospf6_neighbor *
540 better_bdrouter (struct ospf6_neighbor *a, struct ospf6_neighbor *b)
541 {
542 if ((a == NULL || ! IS_ELIGIBLE (a) || a->drouter == a->router_id) &&
543 (b == NULL || ! IS_ELIGIBLE (b) || b->drouter == b->router_id))
544 return NULL;
545 else if (a == NULL || ! IS_ELIGIBLE (a) || a->drouter == a->router_id)
546 return b;
547 else if (b == NULL || ! IS_ELIGIBLE (b) || b->drouter == b->router_id)
548 return a;
549
550 if (a->bdrouter == a->router_id && b->bdrouter != b->router_id)
551 return a;
552 if (a->bdrouter != a->router_id && b->bdrouter == b->router_id)
553 return b;
554
555 if (a->priority > b->priority)
556 return a;
557 if (a->priority < b->priority)
558 return b;
559
560 if (ntohl (a->router_id) > ntohl (b->router_id))
561 return a;
562 if (ntohl (a->router_id) < ntohl (b->router_id))
563 return b;
564
565 zlog_warn ("Router-ID duplicate ?");
566 return a;
567 }
568
569 static struct ospf6_neighbor *
570 better_drouter (struct ospf6_neighbor *a, struct ospf6_neighbor *b)
571 {
572 if ((a == NULL || ! IS_ELIGIBLE (a) || a->drouter != a->router_id) &&
573 (b == NULL || ! IS_ELIGIBLE (b) || b->drouter != b->router_id))
574 return NULL;
575 else if (a == NULL || ! IS_ELIGIBLE (a) || a->drouter != a->router_id)
576 return b;
577 else if (b == NULL || ! IS_ELIGIBLE (b) || b->drouter != b->router_id)
578 return a;
579
580 if (a->drouter == a->router_id && b->drouter != b->router_id)
581 return a;
582 if (a->drouter != a->router_id && b->drouter == b->router_id)
583 return b;
584
585 if (a->priority > b->priority)
586 return a;
587 if (a->priority < b->priority)
588 return b;
589
590 if (ntohl (a->router_id) > ntohl (b->router_id))
591 return a;
592 if (ntohl (a->router_id) < ntohl (b->router_id))
593 return b;
594
595 zlog_warn ("Router-ID duplicate ?");
596 return a;
597 }
598
599 static u_char
600 dr_election (struct ospf6_interface *oi)
601 {
602 struct listnode *node, *nnode;
603 struct ospf6_neighbor *on, *drouter, *bdrouter, myself;
604 struct ospf6_neighbor *best_drouter, *best_bdrouter;
605 u_char next_state = 0;
606
607 drouter = bdrouter = NULL;
608 best_drouter = best_bdrouter = NULL;
609
610 /* pseudo neighbor myself, including noting current DR/BDR (1) */
611 memset (&myself, 0, sizeof (myself));
612 inet_ntop (AF_INET, &oi->area->ospf6->router_id, myself.name,
613 sizeof (myself.name));
614 myself.state = OSPF6_NEIGHBOR_TWOWAY;
615 myself.drouter = oi->drouter;
616 myself.bdrouter = oi->bdrouter;
617 myself.priority = oi->priority;
618 myself.router_id = oi->area->ospf6->router_id;
619
620 /* Electing BDR (2) */
621 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
622 bdrouter = better_bdrouter (bdrouter, on);
623
624 best_bdrouter = bdrouter;
625 bdrouter = better_bdrouter (best_bdrouter, &myself);
626
627 /* Electing DR (3) */
628 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
629 drouter = better_drouter (drouter, on);
630
631 best_drouter = drouter;
632 drouter = better_drouter (best_drouter, &myself);
633 if (drouter == NULL)
634 drouter = bdrouter;
635
636 /* the router itself is newly/no longer DR/BDR (4) */
637 if ((drouter == &myself && myself.drouter != myself.router_id) ||
638 (drouter != &myself && myself.drouter == myself.router_id) ||
639 (bdrouter == &myself && myself.bdrouter != myself.router_id) ||
640 (bdrouter != &myself && myself.bdrouter == myself.router_id))
641 {
642 myself.drouter = (drouter ? drouter->router_id : htonl (0));
643 myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl (0));
644
645 /* compatible to Electing BDR (2) */
646 bdrouter = better_bdrouter (best_bdrouter, &myself);
647
648 /* compatible to Electing DR (3) */
649 drouter = better_drouter (best_drouter, &myself);
650 if (drouter == NULL)
651 drouter = bdrouter;
652 }
653
654 /* Set interface state accordingly (5) */
655 if (drouter && drouter == &myself)
656 next_state = OSPF6_INTERFACE_DR;
657 else if (bdrouter && bdrouter == &myself)
658 next_state = OSPF6_INTERFACE_BDR;
659 else
660 next_state = OSPF6_INTERFACE_DROTHER;
661
662 /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
663 /* XXX */
664
665 /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
666 /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
667 accordingly after AdjOK */
668 if (oi->drouter != (drouter ? drouter->router_id : htonl (0)) ||
669 oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl (0)))
670 {
671 if (IS_OSPF6_DEBUG_INTERFACE)
672 zlog_debug ("DR Election on %s: DR: %s BDR: %s", oi->interface->name,
673 (drouter ? drouter->name : "0.0.0.0"),
674 (bdrouter ? bdrouter->name : "0.0.0.0"));
675
676 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, node, on))
677 {
678 if (on->state < OSPF6_NEIGHBOR_TWOWAY)
679 continue;
680 /* Schedule AdjOK. */
681 thread_add_event (master, adj_ok, on, 0);
682 }
683 }
684
685 oi->drouter = (drouter ? drouter->router_id : htonl (0));
686 oi->bdrouter = (bdrouter ? bdrouter->router_id : htonl (0));
687 return next_state;
688 }
689
690
691 /* Interface State Machine */
692 int
693 interface_up (struct thread *thread)
694 {
695 struct ospf6_interface *oi;
696
697 oi = (struct ospf6_interface *) THREAD_ARG (thread);
698 assert (oi && oi->interface);
699
700 if (IS_OSPF6_DEBUG_INTERFACE)
701 zlog_debug ("Interface Event %s: [InterfaceUp]",
702 oi->interface->name);
703
704 /* check physical interface is up */
705 if (! if_is_operative (oi->interface))
706 {
707 if (IS_OSPF6_DEBUG_INTERFACE)
708 zlog_debug ("Interface %s is down, can't execute [InterfaceUp]",
709 oi->interface->name);
710 return 0;
711 }
712
713 /* check interface has a link-local address */
714 if (! (ospf6_interface_get_linklocal_address(oi->interface)
715 || if_is_loopback(oi->interface)))
716 {
717 if (IS_OSPF6_DEBUG_INTERFACE)
718 zlog_debug ("Interface %s has no link local address, can't execute [InterfaceUp]",
719 oi->interface->name);
720 return 0;
721 }
722
723 /* Recompute cost */
724 ospf6_interface_recalculate_cost (oi);
725
726 /* if already enabled, do nothing */
727 if (oi->state > OSPF6_INTERFACE_DOWN)
728 {
729 if (IS_OSPF6_DEBUG_INTERFACE)
730 zlog_debug ("Interface %s already enabled",
731 oi->interface->name);
732 return 0;
733 }
734
735 /* If no area assigned, return */
736 if (oi->area == NULL)
737 {
738 zlog_debug ("%s: Not scheduleing Hello for %s as there is no area assigned yet", __func__,
739 oi->interface->name);
740 return 0;
741 }
742
743 /* Join AllSPFRouters */
744 if (ospf6_sso (oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP) < 0)
745 {
746 if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX)
747 {
748 zlog_info("Scheduling %s for sso retry, trial count: %d",
749 oi->interface->name, oi->sso_try_cnt);
750 thread_add_timer (master, interface_up, oi,
751 OSPF6_INTERFACE_SSO_RETRY_INT);
752 }
753 return 0;
754 }
755 oi->sso_try_cnt = 0; /* Reset on success */
756
757 /* Update interface route */
758 ospf6_interface_connected_route_update (oi->interface);
759
760 /* Schedule Hello */
761 if (! CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE) &&
762 !if_is_loopback (oi->interface))
763 oi->thread_send_hello = thread_add_event (master, ospf6_hello_send, oi, 0);
764
765 /* decide next interface state */
766 if ((if_is_pointopoint (oi->interface)) ||
767 (oi->type == OSPF_IFTYPE_POINTOPOINT)) {
768 ospf6_interface_state_change (OSPF6_INTERFACE_POINTTOPOINT, oi);
769 }
770 else if (oi->priority == 0)
771 ospf6_interface_state_change (OSPF6_INTERFACE_DROTHER, oi);
772 else
773 {
774 ospf6_interface_state_change (OSPF6_INTERFACE_WAITING, oi);
775 thread_add_timer (master, wait_timer, oi, oi->dead_interval);
776 }
777
778 return 0;
779 }
780
781 int
782 wait_timer (struct thread *thread)
783 {
784 struct ospf6_interface *oi;
785
786 oi = (struct ospf6_interface *) THREAD_ARG (thread);
787 assert (oi && oi->interface);
788
789 if (IS_OSPF6_DEBUG_INTERFACE)
790 zlog_debug ("Interface Event %s: [WaitTimer]",
791 oi->interface->name);
792
793 if (oi->state == OSPF6_INTERFACE_WAITING)
794 ospf6_interface_state_change (dr_election (oi), oi);
795
796 return 0;
797 }
798
799 int
800 backup_seen (struct thread *thread)
801 {
802 struct ospf6_interface *oi;
803
804 oi = (struct ospf6_interface *) THREAD_ARG (thread);
805 assert (oi && oi->interface);
806
807 if (IS_OSPF6_DEBUG_INTERFACE)
808 zlog_debug ("Interface Event %s: [BackupSeen]",
809 oi->interface->name);
810
811 if (oi->state == OSPF6_INTERFACE_WAITING)
812 ospf6_interface_state_change (dr_election (oi), oi);
813
814 return 0;
815 }
816
817 int
818 neighbor_change (struct thread *thread)
819 {
820 struct ospf6_interface *oi;
821
822 oi = (struct ospf6_interface *) THREAD_ARG (thread);
823 assert (oi && oi->interface);
824
825 if (IS_OSPF6_DEBUG_INTERFACE)
826 zlog_debug ("Interface Event %s: [NeighborChange]",
827 oi->interface->name);
828
829 if (oi->state == OSPF6_INTERFACE_DROTHER ||
830 oi->state == OSPF6_INTERFACE_BDR ||
831 oi->state == OSPF6_INTERFACE_DR)
832 ospf6_interface_state_change (dr_election (oi), oi);
833
834 return 0;
835 }
836
837 int
838 interface_down (struct thread *thread)
839 {
840 struct ospf6_interface *oi;
841 struct listnode *node, *nnode;
842 struct ospf6_neighbor *on;
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: [InterfaceDown]",
849 oi->interface->name);
850
851 /* Stop Hellos */
852 THREAD_OFF (oi->thread_send_hello);
853
854 /* Leave AllSPFRouters */
855 if (oi->state > OSPF6_INTERFACE_DOWN)
856 ospf6_sso (oi->interface->ifindex, &allspfrouters6, IPV6_LEAVE_GROUP);
857
858 ospf6_interface_state_change (OSPF6_INTERFACE_DOWN, oi);
859
860 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
861 ospf6_neighbor_delete (on);
862
863 list_delete_all_node (oi->neighbor_list);
864
865 /* When interface state is reset, also reset information about
866 * DR election, as it is no longer valid. */
867 oi->drouter = oi->prev_drouter = htonl(0);
868 oi->bdrouter = oi->prev_bdrouter = htonl(0);
869 return 0;
870 }
871
872
873 /* show specified interface structure */
874 static int
875 ospf6_interface_show (struct vty *vty, struct interface *ifp)
876 {
877 struct ospf6_interface *oi;
878 struct connected *c;
879 struct prefix *p;
880 struct listnode *i;
881 char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32];
882 const char *updown[3] = {"down", "up", NULL};
883 const char *type;
884 struct timeval res, now;
885 char duration[32];
886 struct ospf6_lsa *lsa;
887
888 /* check physical interface type */
889 if (if_is_loopback (ifp))
890 type = "LOOPBACK";
891 else if (if_is_broadcast (ifp))
892 type = "BROADCAST";
893 else if (if_is_pointopoint (ifp))
894 type = "POINTOPOINT";
895 else
896 type = "UNKNOWN";
897
898 vty_out (vty, "%s is %s, type %s%s",
899 ifp->name, updown[if_is_operative (ifp)], type,
900 VNL);
901 vty_out (vty, " Interface ID: %d%s", ifp->ifindex, VNL);
902
903 if (ifp->info == NULL)
904 {
905 vty_out (vty, " OSPF not enabled on this interface%s", VNL);
906 return 0;
907 }
908 else
909 oi = (struct ospf6_interface *) ifp->info;
910
911 vty_out (vty, " Internet Address:%s", VNL);
912
913 for (ALL_LIST_ELEMENTS_RO (ifp->connected, i, c))
914 {
915 p = c->address;
916 prefix2str (p, strbuf, sizeof (strbuf));
917 switch (p->family)
918 {
919 case AF_INET:
920 vty_out (vty, " inet : %s%s", strbuf,
921 VNL);
922 break;
923 case AF_INET6:
924 vty_out (vty, " inet6: %s%s", strbuf,
925 VNL);
926 break;
927 default:
928 vty_out (vty, " ??? : %s%s", strbuf,
929 VNL);
930 break;
931 }
932 }
933
934 if (oi->area)
935 {
936 vty_out (vty, " Instance ID %d, Interface MTU %d (autodetect: %d)%s",
937 oi->instance_id, oi->ifmtu, ifp->mtu6, VNL);
938 vty_out (vty, " MTU mismatch detection: %s%s", oi->mtu_ignore ?
939 "disabled" : "enabled", VNL);
940 inet_ntop (AF_INET, &oi->area->area_id,
941 strbuf, sizeof (strbuf));
942 vty_out (vty, " Area ID %s, Cost %u%s", strbuf, oi->cost,
943 VNL);
944 }
945 else
946 vty_out (vty, " Not Attached to Area%s", VNL);
947
948 vty_out (vty, " State %s, Transmit Delay %d sec, Priority %d%s",
949 ospf6_interface_state_str[oi->state],
950 oi->transdelay, oi->priority,
951 VNL);
952 vty_out (vty, " Timer intervals configured:%s", VNL);
953 vty_out (vty, " Hello %d, Dead %d, Retransmit %d%s",
954 oi->hello_interval, oi->dead_interval, oi->rxmt_interval,
955 VNL);
956
957 inet_ntop (AF_INET, &oi->drouter, drouter, sizeof (drouter));
958 inet_ntop (AF_INET, &oi->bdrouter, bdrouter, sizeof (bdrouter));
959 vty_out (vty, " DR: %s BDR: %s%s", drouter, bdrouter, VNL);
960
961 vty_out (vty, " Number of I/F scoped LSAs is %u%s",
962 oi->lsdb->count, VNL);
963
964 monotime(&now);
965
966 timerclear (&res);
967 if (oi->thread_send_lsupdate)
968 timersub (&oi->thread_send_lsupdate->u.sands, &now, &res);
969 timerstring (&res, duration, sizeof (duration));
970 vty_out (vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
971 oi->lsupdate_list->count, duration,
972 (oi->thread_send_lsupdate ? "on" : "off"),
973 VNL);
974 for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
975 lsa = ospf6_lsdb_next (lsa))
976 vty_out (vty, " %s%s", lsa->name, VNL);
977
978 timerclear (&res);
979 if (oi->thread_send_lsack)
980 timersub (&oi->thread_send_lsack->u.sands, &now, &res);
981 timerstring (&res, duration, sizeof (duration));
982 vty_out (vty, " %d Pending LSAs for LSAck in Time %s [thread %s]%s",
983 oi->lsack_list->count, duration,
984 (oi->thread_send_lsack ? "on" : "off"),
985 VNL);
986 for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
987 lsa = ospf6_lsdb_next (lsa))
988 vty_out (vty, " %s%s", lsa->name, VNL);
989 ospf6_bfd_show_info(vty, oi->bfd_info, 1);
990 return 0;
991 }
992
993 /* show interface */
994 DEFUN (show_ipv6_ospf6_interface,
995 show_ipv6_ospf6_interface_ifname_cmd,
996 "show ipv6 ospf6 interface [IFNAME]",
997 SHOW_STR
998 IP6_STR
999 OSPF6_STR
1000 INTERFACE_STR
1001 IFNAME_STR)
1002 {
1003 int idx_ifname = 4;
1004 struct interface *ifp;
1005 struct listnode *i;
1006
1007 if (argc == 5)
1008 {
1009 ifp = if_lookup_by_name (argv[idx_ifname]->arg);
1010 if (ifp == NULL)
1011 {
1012 vty_out (vty, "No such Interface: %s%s", argv[idx_ifname]->arg,
1013 VNL);
1014 return CMD_WARNING;
1015 }
1016 ospf6_interface_show (vty, ifp);
1017 }
1018 else
1019 {
1020 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), i, ifp))
1021 ospf6_interface_show (vty, ifp);
1022 }
1023
1024 return CMD_SUCCESS;
1025 }
1026
1027 DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
1028 show_ipv6_ospf6_interface_ifname_prefix_cmd,
1029 "show ipv6 ospf6 interface IFNAME prefix [<X:X::X:X|X:X::X:X/M>] [<match|detail>]",
1030 SHOW_STR
1031 IP6_STR
1032 OSPF6_STR
1033 INTERFACE_STR
1034 IFNAME_STR
1035 "Display connected prefixes to advertise\n"
1036 OSPF6_ROUTE_ADDRESS_STR
1037 OSPF6_ROUTE_PREFIX_STR
1038 OSPF6_ROUTE_MATCH_STR
1039 "Display details of the prefixes\n")
1040 {
1041 int idx_ifname = 4;
1042 int idx_prefix = 6;
1043 struct interface *ifp;
1044 struct ospf6_interface *oi;
1045
1046 ifp = if_lookup_by_name (argv[idx_ifname]->arg);
1047 if (ifp == NULL)
1048 {
1049 vty_out (vty, "No such Interface: %s%s", argv[idx_ifname]->arg, VNL);
1050 return CMD_WARNING;
1051 }
1052
1053 oi = ifp->info;
1054 if (oi == NULL)
1055 {
1056 vty_out (vty, "OSPFv3 is not enabled on %s%s", argv[idx_ifname]->arg, VNL);
1057 return CMD_WARNING;
1058 }
1059
1060 ospf6_route_table_show (vty, idx_prefix, argc, argv, oi->route_connected);
1061
1062 return CMD_SUCCESS;
1063 }
1064
1065 DEFUN (show_ipv6_ospf6_interface_prefix,
1066 show_ipv6_ospf6_interface_prefix_cmd,
1067 "show ipv6 ospf6 interface prefix [<X:X::X:X|X:X::X:X/M>] [<match|detail>]",
1068 SHOW_STR
1069 IP6_STR
1070 OSPF6_STR
1071 INTERFACE_STR
1072 "Display connected prefixes to advertise\n"
1073 OSPF6_ROUTE_ADDRESS_STR
1074 OSPF6_ROUTE_PREFIX_STR
1075 OSPF6_ROUTE_MATCH_STR
1076 "Display details of the prefixes\n")
1077 {
1078 int idx_prefix = 5;
1079 struct listnode *i;
1080 struct ospf6_interface *oi;
1081 struct interface *ifp;
1082
1083 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), i, ifp))
1084 {
1085 oi = (struct ospf6_interface *) ifp->info;
1086 if (oi == NULL)
1087 continue;
1088
1089 ospf6_route_table_show (vty, idx_prefix, argc, argv, oi->route_connected);
1090 }
1091
1092 return CMD_SUCCESS;
1093 }
1094
1095 /* interface variable set command */
1096 DEFUN (ipv6_ospf6_ifmtu,
1097 ipv6_ospf6_ifmtu_cmd,
1098 "ipv6 ospf6 ifmtu (1-65535)",
1099 IP6_STR
1100 OSPF6_STR
1101 "Interface MTU\n"
1102 "OSPFv3 Interface MTU\n"
1103 )
1104 {
1105 VTY_DECLVAR_CONTEXT(interface, ifp);
1106 int idx_number = 3;
1107 struct ospf6_interface *oi;
1108 unsigned int ifmtu, iobuflen;
1109 struct listnode *node, *nnode;
1110 struct ospf6_neighbor *on;
1111
1112 assert (ifp);
1113
1114 oi = (struct ospf6_interface *) ifp->info;
1115 if (oi == NULL)
1116 oi = ospf6_interface_create (ifp);
1117 assert (oi);
1118
1119 ifmtu = strtol (argv[idx_number]->arg, NULL, 10);
1120
1121 if (oi->ifmtu == ifmtu)
1122 return CMD_SUCCESS;
1123
1124 if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu)
1125 {
1126 vty_out (vty, "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)%s",
1127 ifp->name, ifp->mtu6, VNL);
1128 return CMD_WARNING;
1129 }
1130
1131 if (oi->ifmtu < ifmtu)
1132 {
1133 iobuflen = ospf6_iobuf_size (ifmtu);
1134 if (iobuflen < ifmtu)
1135 {
1136 vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
1137 ifp->name, iobuflen, VNL);
1138 oi->ifmtu = iobuflen;
1139 }
1140 else
1141 oi->ifmtu = ifmtu;
1142 }
1143 else
1144 oi->ifmtu = ifmtu;
1145
1146 /* re-establish adjacencies */
1147 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
1148 {
1149 THREAD_OFF (on->inactivity_timer);
1150 thread_add_event (master, inactivity_timer, on, 0);
1151 }
1152
1153 return CMD_SUCCESS;
1154 }
1155
1156 DEFUN (no_ipv6_ospf6_ifmtu,
1157 no_ipv6_ospf6_ifmtu_cmd,
1158 "no ipv6 ospf6 ifmtu",
1159 NO_STR
1160 IP6_STR
1161 OSPF6_STR
1162 "Interface MTU\n"
1163 )
1164 {
1165 VTY_DECLVAR_CONTEXT(interface, ifp);
1166 struct ospf6_interface *oi;
1167 unsigned int iobuflen;
1168 struct listnode *node, *nnode;
1169 struct ospf6_neighbor *on;
1170
1171 assert (ifp);
1172
1173 oi = (struct ospf6_interface *) ifp->info;
1174 if (oi == NULL)
1175 oi = ospf6_interface_create (ifp);
1176 assert (oi);
1177
1178 if (oi->ifmtu < ifp->mtu)
1179 {
1180 iobuflen = ospf6_iobuf_size (ifp->mtu);
1181 if (iobuflen < ifp->mtu)
1182 {
1183 vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
1184 ifp->name, iobuflen, VNL);
1185 oi->ifmtu = iobuflen;
1186 }
1187 else
1188 oi->ifmtu = ifp->mtu;
1189 }
1190 else
1191 oi->ifmtu = ifp->mtu;
1192
1193 /* re-establish adjacencies */
1194 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
1195 {
1196 THREAD_OFF (on->inactivity_timer);
1197 thread_add_event (master, inactivity_timer, on, 0);
1198 }
1199
1200 return CMD_SUCCESS;
1201 }
1202
1203 DEFUN (ipv6_ospf6_cost,
1204 ipv6_ospf6_cost_cmd,
1205 "ipv6 ospf6 cost (1-65535)",
1206 IP6_STR
1207 OSPF6_STR
1208 "Interface cost\n"
1209 "Outgoing metric of this interface\n"
1210 )
1211 {
1212 VTY_DECLVAR_CONTEXT(interface, ifp);
1213 int idx_number = 3;
1214 struct ospf6_interface *oi;
1215 unsigned long int lcost;
1216
1217 assert (ifp);
1218
1219 oi = (struct ospf6_interface *) ifp->info;
1220 if (oi == NULL)
1221 oi = ospf6_interface_create (ifp);
1222 assert (oi);
1223
1224 lcost = strtol (argv[idx_number]->arg, NULL, 10);
1225
1226 if (lcost > UINT32_MAX)
1227 {
1228 vty_out (vty, "Cost %ld is out of range%s", lcost, VNL);
1229 return CMD_WARNING;
1230 }
1231
1232 if (oi->cost == lcost)
1233 return CMD_SUCCESS;
1234
1235 oi->cost = lcost;
1236 SET_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1237
1238 ospf6_interface_recalculate_cost(oi);
1239
1240 return CMD_SUCCESS;
1241 }
1242
1243 DEFUN (no_ipv6_ospf6_cost,
1244 no_ipv6_ospf6_cost_cmd,
1245 "no ipv6 ospf6 cost",
1246 NO_STR
1247 IP6_STR
1248 OSPF6_STR
1249 "Calculate interface cost from bandwidth\n"
1250 )
1251 {
1252 VTY_DECLVAR_CONTEXT(interface, ifp);
1253 struct ospf6_interface *oi;
1254 assert (ifp);
1255
1256 oi = (struct ospf6_interface *) ifp->info;
1257 if (oi == NULL)
1258 oi = ospf6_interface_create (ifp);
1259 assert (oi);
1260
1261 UNSET_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
1262
1263 ospf6_interface_recalculate_cost(oi);
1264
1265 return CMD_SUCCESS;
1266 }
1267
1268 DEFUN (auto_cost_reference_bandwidth,
1269 auto_cost_reference_bandwidth_cmd,
1270 "auto-cost reference-bandwidth (1-4294967)",
1271 "Calculate OSPF interface cost according to bandwidth\n"
1272 "Use reference bandwidth method to assign OSPF cost\n"
1273 "The reference bandwidth in terms of Mbits per second\n")
1274 {
1275 VTY_DECLVAR_CONTEXT(ospf6, o);
1276 int idx_number = 2;
1277 struct ospf6_area *oa;
1278 struct ospf6_interface *oi;
1279 struct listnode *i, *j;
1280 u_int32_t refbw;
1281
1282 refbw = strtol (argv[idx_number]->arg, NULL, 10);
1283 if (refbw < 1 || refbw > 4294967)
1284 {
1285 vty_out (vty, "reference-bandwidth value is invalid%s", VTY_NEWLINE);
1286 return CMD_WARNING;
1287 }
1288
1289 /* If reference bandwidth is changed. */
1290 if ((refbw) == o->ref_bandwidth)
1291 return CMD_SUCCESS;
1292
1293 o->ref_bandwidth = refbw;
1294 for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa))
1295 for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
1296 ospf6_interface_recalculate_cost (oi);
1297
1298 return CMD_SUCCESS;
1299 }
1300
1301 DEFUN (no_auto_cost_reference_bandwidth,
1302 no_auto_cost_reference_bandwidth_cmd,
1303 "no auto-cost reference-bandwidth [(1-4294967)]",
1304 NO_STR
1305 "Calculate OSPF interface cost according to bandwidth\n"
1306 "Use reference bandwidth method to assign OSPF cost\n"
1307 "The reference bandwidth in terms of Mbits per second\n")
1308 {
1309 VTY_DECLVAR_CONTEXT(ospf6, o);
1310 struct ospf6_area *oa;
1311 struct ospf6_interface *oi;
1312 struct listnode *i, *j;
1313
1314 if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH)
1315 return CMD_SUCCESS;
1316
1317 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
1318 for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa))
1319 for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
1320 ospf6_interface_recalculate_cost (oi);
1321
1322 return CMD_SUCCESS;
1323 }
1324
1325
1326 DEFUN (ipv6_ospf6_hellointerval,
1327 ipv6_ospf6_hellointerval_cmd,
1328 "ipv6 ospf6 hello-interval (1-65535)",
1329 IP6_STR
1330 OSPF6_STR
1331 "Time between HELLO packets\n"
1332 SECONDS_STR
1333 )
1334 {
1335 VTY_DECLVAR_CONTEXT(interface, ifp);
1336 int idx_number = 3;
1337 struct ospf6_interface *oi;
1338 assert (ifp);
1339
1340 oi = (struct ospf6_interface *) ifp->info;
1341 if (oi == NULL)
1342 oi = ospf6_interface_create (ifp);
1343 assert (oi);
1344
1345 oi->hello_interval = strtol (argv[idx_number]->arg, NULL, 10);
1346 return CMD_SUCCESS;
1347 }
1348
1349 /* interface variable set command */
1350 DEFUN (ipv6_ospf6_deadinterval,
1351 ipv6_ospf6_deadinterval_cmd,
1352 "ipv6 ospf6 dead-interval (1-65535)",
1353 IP6_STR
1354 OSPF6_STR
1355 "Interval time after which a neighbor is declared down\n"
1356 SECONDS_STR
1357 )
1358 {
1359 VTY_DECLVAR_CONTEXT(interface, ifp);
1360 int idx_number = 3;
1361 struct ospf6_interface *oi;
1362 assert (ifp);
1363
1364 oi = (struct ospf6_interface *) ifp->info;
1365 if (oi == NULL)
1366 oi = ospf6_interface_create (ifp);
1367 assert (oi);
1368
1369 oi->dead_interval = strtol (argv[idx_number]->arg, NULL, 10);
1370 return CMD_SUCCESS;
1371 }
1372
1373 /* interface variable set command */
1374 DEFUN (ipv6_ospf6_transmitdelay,
1375 ipv6_ospf6_transmitdelay_cmd,
1376 "ipv6 ospf6 transmit-delay (1-3600)",
1377 IP6_STR
1378 OSPF6_STR
1379 "Link state transmit delay\n"
1380 SECONDS_STR)
1381 {
1382 VTY_DECLVAR_CONTEXT(interface, ifp);
1383 int idx_number = 3;
1384 struct ospf6_interface *oi;
1385 assert (ifp);
1386
1387 oi = (struct ospf6_interface *) ifp->info;
1388 if (oi == NULL)
1389 oi = ospf6_interface_create (ifp);
1390 assert (oi);
1391
1392 oi->transdelay = strtol (argv[idx_number]->arg, NULL, 10);
1393 return CMD_SUCCESS;
1394 }
1395
1396 /* interface variable set command */
1397 DEFUN (ipv6_ospf6_retransmitinterval,
1398 ipv6_ospf6_retransmitinterval_cmd,
1399 "ipv6 ospf6 retransmit-interval (1-65535)",
1400 IP6_STR
1401 OSPF6_STR
1402 "Time between retransmitting lost link state advertisements\n"
1403 SECONDS_STR
1404 )
1405 {
1406 VTY_DECLVAR_CONTEXT(interface, ifp);
1407 int idx_number = 3;
1408 struct ospf6_interface *oi;
1409 assert (ifp);
1410
1411 oi = (struct ospf6_interface *) ifp->info;
1412 if (oi == NULL)
1413 oi = ospf6_interface_create (ifp);
1414 assert (oi);
1415
1416 oi->rxmt_interval = strtol (argv[idx_number]->arg, NULL, 10);
1417 return CMD_SUCCESS;
1418 }
1419
1420 /* interface variable set command */
1421 DEFUN (ipv6_ospf6_priority,
1422 ipv6_ospf6_priority_cmd,
1423 "ipv6 ospf6 priority (0-255)",
1424 IP6_STR
1425 OSPF6_STR
1426 "Router priority\n"
1427 "Priority value\n"
1428 )
1429 {
1430 VTY_DECLVAR_CONTEXT(interface, ifp);
1431 int idx_number = 3;
1432 struct ospf6_interface *oi;
1433 assert (ifp);
1434
1435 oi = (struct ospf6_interface *) ifp->info;
1436 if (oi == NULL)
1437 oi = ospf6_interface_create (ifp);
1438 assert (oi);
1439
1440 oi->priority = strtol (argv[idx_number]->arg, NULL, 10);
1441
1442 if (oi->area &&
1443 (oi->state == OSPF6_INTERFACE_DROTHER ||
1444 oi->state == OSPF6_INTERFACE_BDR ||
1445 oi->state == OSPF6_INTERFACE_DR))
1446 ospf6_interface_state_change (dr_election (oi), oi);
1447
1448 return CMD_SUCCESS;
1449 }
1450
1451 DEFUN (ipv6_ospf6_instance,
1452 ipv6_ospf6_instance_cmd,
1453 "ipv6 ospf6 instance-id (0-255)",
1454 IP6_STR
1455 OSPF6_STR
1456 "Instance ID for this interface\n"
1457 "Instance ID value\n"
1458 )
1459 {
1460 VTY_DECLVAR_CONTEXT(interface, ifp);
1461 int idx_number = 3;
1462 struct ospf6_interface *oi;
1463 assert (ifp);
1464
1465 oi = (struct ospf6_interface *)ifp->info;
1466 if (oi == NULL)
1467 oi = ospf6_interface_create (ifp);
1468 assert (oi);
1469
1470 oi->instance_id = strtol (argv[idx_number]->arg, NULL, 10);
1471 return CMD_SUCCESS;
1472 }
1473
1474 DEFUN (ipv6_ospf6_passive,
1475 ipv6_ospf6_passive_cmd,
1476 "ipv6 ospf6 passive",
1477 IP6_STR
1478 OSPF6_STR
1479 "Passive interface; no adjacency will be formed on this interface\n"
1480 )
1481 {
1482 VTY_DECLVAR_CONTEXT(interface, ifp);
1483 struct ospf6_interface *oi;
1484 struct listnode *node, *nnode;
1485 struct ospf6_neighbor *on;
1486
1487 assert (ifp);
1488
1489 oi = (struct ospf6_interface *) ifp->info;
1490 if (oi == NULL)
1491 oi = ospf6_interface_create (ifp);
1492 assert (oi);
1493
1494 SET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE);
1495 THREAD_OFF (oi->thread_send_hello);
1496
1497 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
1498 {
1499 THREAD_OFF (on->inactivity_timer);
1500 thread_add_event (master, inactivity_timer, on, 0);
1501 }
1502
1503 return CMD_SUCCESS;
1504 }
1505
1506 DEFUN (no_ipv6_ospf6_passive,
1507 no_ipv6_ospf6_passive_cmd,
1508 "no ipv6 ospf6 passive",
1509 NO_STR
1510 IP6_STR
1511 OSPF6_STR
1512 "passive interface: No Adjacency will be formed on this I/F\n"
1513 )
1514 {
1515 VTY_DECLVAR_CONTEXT(interface, ifp);
1516 struct ospf6_interface *oi;
1517 assert (ifp);
1518
1519 oi = (struct ospf6_interface *) ifp->info;
1520 if (oi == NULL)
1521 oi = ospf6_interface_create (ifp);
1522 assert (oi);
1523
1524 UNSET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE);
1525 THREAD_OFF (oi->thread_send_hello);
1526 oi->thread_send_hello =
1527 thread_add_event (master, ospf6_hello_send, oi, 0);
1528
1529 return CMD_SUCCESS;
1530 }
1531
1532 DEFUN (ipv6_ospf6_mtu_ignore,
1533 ipv6_ospf6_mtu_ignore_cmd,
1534 "ipv6 ospf6 mtu-ignore",
1535 IP6_STR
1536 OSPF6_STR
1537 "Disable MTU mismatch detection on this interface\n"
1538 )
1539 {
1540 VTY_DECLVAR_CONTEXT(interface, ifp);
1541 struct ospf6_interface *oi;
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 oi->mtu_ignore = 1;
1550
1551 return CMD_SUCCESS;
1552 }
1553
1554 DEFUN (no_ipv6_ospf6_mtu_ignore,
1555 no_ipv6_ospf6_mtu_ignore_cmd,
1556 "no ipv6 ospf6 mtu-ignore",
1557 NO_STR
1558 IP6_STR
1559 OSPF6_STR
1560 "Disable MTU mismatch detection on this interface\n"
1561 )
1562 {
1563 VTY_DECLVAR_CONTEXT(interface, ifp);
1564 struct ospf6_interface *oi;
1565 assert (ifp);
1566
1567 oi = (struct ospf6_interface *) ifp->info;
1568 if (oi == NULL)
1569 oi = ospf6_interface_create (ifp);
1570 assert (oi);
1571
1572 oi->mtu_ignore = 0;
1573
1574 return CMD_SUCCESS;
1575 }
1576
1577 DEFUN (ipv6_ospf6_advertise_prefix_list,
1578 ipv6_ospf6_advertise_prefix_list_cmd,
1579 "ipv6 ospf6 advertise prefix-list WORD",
1580 IP6_STR
1581 OSPF6_STR
1582 "Advertising options\n"
1583 "Filter prefix using prefix-list\n"
1584 "Prefix list name\n"
1585 )
1586 {
1587 VTY_DECLVAR_CONTEXT(interface, ifp);
1588 int idx_word = 4;
1589 struct ospf6_interface *oi;
1590 assert (ifp);
1591
1592 oi = (struct ospf6_interface *) ifp->info;
1593 if (oi == NULL)
1594 oi = ospf6_interface_create (ifp);
1595 assert (oi);
1596
1597 if (oi->plist_name)
1598 XFREE (MTYPE_CFG_PLIST_NAME, oi->plist_name);
1599 oi->plist_name = XSTRDUP (MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg);
1600
1601 ospf6_interface_connected_route_update (oi->interface);
1602
1603 if (oi->area)
1604 {
1605 OSPF6_LINK_LSA_SCHEDULE (oi);
1606 if (oi->state == OSPF6_INTERFACE_DR)
1607 {
1608 OSPF6_NETWORK_LSA_SCHEDULE (oi);
1609 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
1610 }
1611 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
1612 }
1613
1614 return CMD_SUCCESS;
1615 }
1616
1617 DEFUN (no_ipv6_ospf6_advertise_prefix_list,
1618 no_ipv6_ospf6_advertise_prefix_list_cmd,
1619 "no ipv6 ospf6 advertise prefix-list",
1620 NO_STR
1621 IP6_STR
1622 OSPF6_STR
1623 "Advertising options\n"
1624 "Filter prefix using prefix-list\n"
1625 )
1626 {
1627 VTY_DECLVAR_CONTEXT(interface, ifp);
1628 struct ospf6_interface *oi;
1629 assert (ifp);
1630
1631 oi = (struct ospf6_interface *) ifp->info;
1632 if (oi == NULL)
1633 oi = ospf6_interface_create (ifp);
1634 assert (oi);
1635
1636 if (oi->plist_name)
1637 {
1638 XFREE (MTYPE_CFG_PLIST_NAME, oi->plist_name);
1639 oi->plist_name = NULL;
1640 }
1641
1642 ospf6_interface_connected_route_update (oi->interface);
1643
1644 if (oi->area)
1645 {
1646 OSPF6_LINK_LSA_SCHEDULE (oi);
1647 if (oi->state == OSPF6_INTERFACE_DR)
1648 {
1649 OSPF6_NETWORK_LSA_SCHEDULE (oi);
1650 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
1651 }
1652 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
1653 }
1654
1655 return CMD_SUCCESS;
1656 }
1657
1658 DEFUN (ipv6_ospf6_network,
1659 ipv6_ospf6_network_cmd,
1660 "ipv6 ospf6 network <broadcast|point-to-point>",
1661 IP6_STR
1662 OSPF6_STR
1663 "Network type\n"
1664 "Specify OSPF6 broadcast network\n"
1665 "Specify OSPF6 point-to-point network\n"
1666 )
1667 {
1668 VTY_DECLVAR_CONTEXT(interface, ifp);
1669 int idx_network = 3;
1670 struct ospf6_interface *oi;
1671 assert (ifp);
1672
1673 oi = (struct ospf6_interface *) ifp->info;
1674 if (oi == NULL) {
1675 oi = ospf6_interface_create (ifp);
1676 }
1677 assert (oi);
1678
1679 if (strncmp (argv[idx_network]->arg, "b", 1) == 0)
1680 {
1681 if (oi->type == OSPF_IFTYPE_BROADCAST)
1682 return CMD_SUCCESS;
1683
1684 oi->type = OSPF_IFTYPE_BROADCAST;
1685 }
1686 else if (strncmp (argv[idx_network]->arg, "point-to-p", 10) == 0)
1687 {
1688 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
1689 return CMD_SUCCESS;
1690 }
1691 oi->type = OSPF_IFTYPE_POINTOPOINT;
1692 }
1693
1694 /* Reset the interface */
1695 thread_add_event (master, interface_down, oi, 0);
1696 thread_add_event (master, interface_up, oi, 0);
1697
1698 return CMD_SUCCESS;
1699 }
1700
1701 DEFUN (no_ipv6_ospf6_network,
1702 no_ipv6_ospf6_network_cmd,
1703 "no ipv6 ospf6 network",
1704 NO_STR
1705 IP6_STR
1706 OSPF6_STR
1707 "Network type\n"
1708 "Default to whatever interface type system specifies"
1709 )
1710 {
1711 VTY_DECLVAR_CONTEXT(interface, ifp);
1712 struct ospf6_interface *oi;
1713 int type;
1714
1715 assert (ifp);
1716
1717 oi = (struct ospf6_interface *) ifp->info;
1718 if (oi == NULL) {
1719 return CMD_SUCCESS;
1720 }
1721
1722 type = ospf6_default_iftype (ifp);
1723 if (oi->type == type)
1724 {
1725 return CMD_SUCCESS;
1726 }
1727 oi->type = type;
1728
1729 /* Reset the interface */
1730 thread_add_event (master, interface_down, oi, 0);
1731 thread_add_event (master, interface_up, oi, 0);
1732
1733 return CMD_SUCCESS;
1734 }
1735
1736 static int
1737 config_write_ospf6_interface (struct vty *vty)
1738 {
1739 struct listnode *i;
1740 struct ospf6_interface *oi;
1741 struct interface *ifp;
1742
1743 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), i, ifp))
1744 {
1745 oi = (struct ospf6_interface *) ifp->info;
1746 if (oi == NULL)
1747 continue;
1748
1749 vty_out (vty, "interface %s%s",
1750 oi->interface->name, VNL);
1751
1752 if (ifp->desc)
1753 vty_out (vty, " description %s%s", ifp->desc, VNL);
1754 if (ifp->mtu6 != oi->ifmtu)
1755 vty_out (vty, " ipv6 ospf6 ifmtu %d%s", oi->ifmtu, VNL);
1756
1757 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
1758 vty_out (vty, " ipv6 ospf6 cost %d%s",
1759 oi->cost, VNL);
1760
1761 if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL)
1762 vty_out (vty, " ipv6 ospf6 hello-interval %d%s",
1763 oi->hello_interval, VNL);
1764
1765 if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL)
1766 vty_out (vty, " ipv6 ospf6 dead-interval %d%s",
1767 oi->dead_interval, VNL);
1768
1769 if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL)
1770 vty_out (vty, " ipv6 ospf6 retransmit-interval %d%s",
1771 oi->rxmt_interval, VNL);
1772
1773 if (oi->priority != OSPF6_INTERFACE_PRIORITY)
1774 vty_out (vty, " ipv6 ospf6 priority %d%s",
1775 oi->priority, VNL);
1776
1777 if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY)
1778 vty_out (vty, " ipv6 ospf6 transmit-delay %d%s",
1779 oi->transdelay, VNL);
1780
1781 if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID)
1782 vty_out (vty, " ipv6 ospf6 instance-id %d%s",
1783 oi->instance_id, VNL);
1784
1785 if (oi->plist_name)
1786 vty_out (vty, " ipv6 ospf6 advertise prefix-list %s%s",
1787 oi->plist_name, VNL);
1788
1789 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
1790 vty_out (vty, " ipv6 ospf6 passive%s", VNL);
1791
1792 if (oi->mtu_ignore)
1793 vty_out (vty, " ipv6 ospf6 mtu-ignore%s", VNL);
1794
1795 if (oi->type != ospf6_default_iftype(ifp))
1796 {
1797 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
1798 vty_out (vty, " ipv6 ospf6 network point-to-point%s", VNL);
1799 else if (oi->type == OSPF_IFTYPE_BROADCAST)
1800 vty_out (vty, " ipv6 ospf6 network broadcast%s", VNL);
1801 }
1802
1803 ospf6_bfd_write_config(vty, oi);
1804
1805 vty_out (vty, "!%s", VNL);
1806 }
1807 return 0;
1808 }
1809
1810 static struct cmd_node interface_node =
1811 {
1812 INTERFACE_NODE,
1813 "%s(config-if)# ",
1814 1 /* VTYSH */
1815 };
1816
1817 void
1818 ospf6_interface_init (void)
1819 {
1820 /* Install interface node. */
1821 install_node (&interface_node, config_write_ospf6_interface);
1822 if_cmd_init ();
1823
1824 install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
1825 install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
1826 install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd);
1827
1828 install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
1829 install_element (INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
1830 install_element (INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
1831 install_element (INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
1832 install_element (INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
1833 install_element (INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
1834 install_element (INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
1835 install_element (INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
1836 install_element (INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
1837 install_element (INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
1838
1839 install_element (INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
1840 install_element (INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
1841
1842 install_element (INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
1843 install_element (INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
1844
1845 install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
1846 install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_prefix_list_cmd);
1847
1848 install_element (INTERFACE_NODE, &ipv6_ospf6_network_cmd);
1849 install_element (INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
1850
1851 /* reference bandwidth commands */
1852 install_element (OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
1853 install_element (OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
1854 }
1855
1856 /* Clear the specified interface structure */
1857 static void
1858 ospf6_interface_clear (struct vty *vty, struct interface *ifp)
1859 {
1860 struct ospf6_interface *oi;
1861
1862 if (!if_is_operative (ifp))
1863 return;
1864
1865 if (ifp->info == NULL)
1866 return;
1867
1868 oi = (struct ospf6_interface *) ifp->info;
1869
1870 if (IS_OSPF6_DEBUG_INTERFACE)
1871 zlog_debug ("Interface %s: clear by reset", ifp->name);
1872
1873 /* Reset the interface */
1874 thread_add_event (master, interface_down, oi, 0);
1875 thread_add_event (master, interface_up, oi, 0);
1876 }
1877
1878 /* Clear interface */
1879 DEFUN (clear_ipv6_ospf6_interface,
1880 clear_ipv6_ospf6_interface_cmd,
1881 "clear ipv6 ospf6 interface [IFNAME]",
1882 CLEAR_STR
1883 IP6_STR
1884 OSPF6_STR
1885 INTERFACE_STR
1886 IFNAME_STR
1887 )
1888 {
1889 int idx_ifname = 4;
1890 struct interface *ifp;
1891 struct listnode *node;
1892
1893 if (argc == 4) /* Clear all the ospfv3 interfaces. */
1894 {
1895 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
1896 ospf6_interface_clear (vty, ifp);
1897 }
1898 else /* Interface name is specified. */
1899 {
1900 if ((ifp = if_lookup_by_name (argv[idx_ifname]->arg)) == NULL)
1901 {
1902 vty_out (vty, "No such Interface: %s%s", argv[idx_ifname]->arg, VNL);
1903 return CMD_WARNING;
1904 }
1905 ospf6_interface_clear (vty, ifp);
1906 }
1907
1908 return CMD_SUCCESS;
1909 }
1910
1911 void
1912 install_element_ospf6_clear_interface (void)
1913 {
1914 install_element (ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
1915 }
1916
1917 DEFUN (debug_ospf6_interface,
1918 debug_ospf6_interface_cmd,
1919 "debug ospf6 interface",
1920 DEBUG_STR
1921 OSPF6_STR
1922 "Debug OSPFv3 Interface\n"
1923 )
1924 {
1925 OSPF6_DEBUG_INTERFACE_ON ();
1926 return CMD_SUCCESS;
1927 }
1928
1929 DEFUN (no_debug_ospf6_interface,
1930 no_debug_ospf6_interface_cmd,
1931 "no debug ospf6 interface",
1932 NO_STR
1933 DEBUG_STR
1934 OSPF6_STR
1935 "Debug OSPFv3 Interface\n"
1936 )
1937 {
1938 OSPF6_DEBUG_INTERFACE_OFF ();
1939 return CMD_SUCCESS;
1940 }
1941
1942 int
1943 config_write_ospf6_debug_interface (struct vty *vty)
1944 {
1945 if (IS_OSPF6_DEBUG_INTERFACE)
1946 vty_out (vty, "debug ospf6 interface%s", VNL);
1947 return 0;
1948 }
1949
1950 void
1951 install_element_ospf6_debug_interface (void)
1952 {
1953 install_element (ENABLE_NODE, &debug_ospf6_interface_cmd);
1954 install_element (ENABLE_NODE, &no_debug_ospf6_interface_cmd);
1955 install_element (CONFIG_NODE, &debug_ospf6_interface_cmd);
1956 install_element (CONFIG_NODE, &no_debug_ospf6_interface_cmd);
1957 }
1958
1959