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