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