blob: d394f21bc3c875ee138a8e17e1554f8c5b2ec04d [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * Copyright (C) 1999 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 "ospf6d.h"
23
24#include "if.h"
25#include "log.h"
26#include "command.h"
27
28#include "ospf6_lsdb.h"
29
30#include "ospf6_top.h"
31#include "ospf6_area.h"
32#include "ospf6_interface.h"
33
34char *ospf6_interface_state_string[] =
35{
36 "None", "Down", "Loopback", "Waiting", "PointToPoint",
37 "DROther", "BDR", "DR", NULL
38};
39
40static void
41ospf6_interface_foreach_neighbor (struct ospf6_interface *o6i,
42 void *arg, int val,
43 void (*func) (void *, int, void *))
44{
45 listnode node;
46 struct ospf6_neighbor *nei;
47
48 for (node = listhead (o6i->neighbor_list); node; nextnode (node))
49 {
50 nei = (struct ospf6_neighbor *) getdata (node);
51 (*func) (arg, val, nei);
52 }
53}
54
55static int
56ospf6_interface_maxage_remover (struct thread *t)
57{
58 int count;
59 struct ospf6_interface *o6i = (struct ospf6_interface *) THREAD_ARG (t);
60
61 o6i->maxage_remover = (struct thread *) NULL;
62
63 count = 0;
64 o6i->foreach_nei (o6i, &count, NBS_EXCHANGE, ospf6_count_state);
65 o6i->foreach_nei (o6i, &count, NBS_LOADING, ospf6_count_state);
66 if (count != 0)
67 return 0;
68
69 ospf6_lsdb_remove_maxage (o6i->lsdb);
70 return 0;
71}
72
73void
74ospf6_interface_schedule_maxage_remover (void *arg, int val, void *obj)
75{
76 struct ospf6_interface *o6i = (struct ospf6_interface *) obj;
77
78 if (o6i->maxage_remover != NULL)
79 return;
80
81 o6i->maxage_remover =
82 thread_add_event (master, ospf6_interface_maxage_remover, o6i, 0);
83}
84
85/* Create new ospf6 interface structure */
86struct ospf6_interface *
87ospf6_interface_create (struct interface *ifp)
88{
89 struct ospf6_interface *o6i;
90
91 o6i = (struct ospf6_interface *)
92 XMALLOC (MTYPE_OSPF6_IF, sizeof (struct ospf6_interface));
93
94 if (o6i)
95 memset (o6i, 0, sizeof (struct ospf6_interface));
96 else
97 {
98 zlog_err ("Can't malloc ospf6_interface for ifindex %d", ifp->ifindex);
99 return (struct ospf6_interface *) NULL;
100 }
101
102 o6i->instance_id = 0;
103 o6i->if_id = ifp->ifindex;
104 o6i->lladdr = (struct in6_addr *) NULL;
105 o6i->area = (struct ospf6_area *) NULL;
106 o6i->state = IFS_DOWN;
107 o6i->flag = 0;
108 o6i->neighbor_list = list_new ();
109
110 o6i->ack_list = ospf6_lsdb_create ();
111 o6i->lsdb = ospf6_lsdb_create ();
112
113 o6i->transdelay = 1;
114 o6i->priority = 1;
115 o6i->hello_interval = 10;
116 o6i->dead_interval = 40;
117 o6i->rxmt_interval = 5;
118 o6i->cost = 1;
119 o6i->ifmtu = 1280;
120
121 o6i->foreach_nei = ospf6_interface_foreach_neighbor;
122
123 /* link both */
124 o6i->interface = ifp;
125 ifp->info = o6i;
126
127 CALL_ADD_HOOK (&interface_hook, o6i);
128
129 /* Get the interface's link-local if any */
130 ospf6_interface_address_update(ifp);
131
132 return o6i;
133}
134
135void
136ospf6_interface_delete (struct ospf6_interface *o6i)
137{
138 listnode n;
139 struct ospf6_neighbor *o6n;
140
141 CALL_REMOVE_HOOK (&interface_hook, o6i);
142
143 for (n = listhead (o6i->neighbor_list); n; nextnode (n))
144 {
145 o6n = (struct ospf6_neighbor *) getdata (n);
146 ospf6_neighbor_delete (o6n);
147 }
148 list_delete (o6i->neighbor_list);
149
150 if (o6i->thread_send_hello)
151 {
152 thread_cancel (o6i->thread_send_hello);
153 o6i->thread_send_hello = NULL;
154 }
155 if (o6i->thread_send_lsack_delayed)
156 {
157 thread_cancel (o6i->thread_send_lsack_delayed);
158 o6i->thread_send_lsack_delayed = NULL;
159 }
160
161 ospf6_lsdb_delete (o6i->ack_list);
162 ospf6_lsdb_remove_all (o6i->lsdb);
163 ospf6_lsdb_delete (o6i->lsdb);
164
165 /* cut link */
166 o6i->interface->info = NULL;
167
168 /* plist_name */
169 if (o6i->plist_name)
170 XFREE (MTYPE_PREFIX_LIST_STR, o6i->plist_name);
171
172 XFREE (MTYPE_OSPF6_IF, o6i);
173}
174
175static struct in6_addr *
176ospf6_interface_update_linklocal_address (struct interface *ifp)
177{
178 listnode n;
179 struct connected *c;
180 struct in6_addr *l = (struct in6_addr *) NULL;
181
182 /* for each connected address */
183 for (n = listhead (ifp->connected); n; nextnode (n))
184 {
185 c = (struct connected *) getdata (n);
186
187 /* if family not AF_INET6, ignore */
188 if (c->address->family != AF_INET6)
189 continue;
190
191 /* linklocal scope check */
192 if (IN6_IS_ADDR_LINKLOCAL (&c->address->u.prefix6))
193 l = &c->address->u.prefix6;
194 }
195 return l;
196}
197
198void
199ospf6_interface_if_add (struct interface *ifp)
200{
201 struct ospf6_interface *o6i;
202
203 o6i = (struct ospf6_interface *) ifp->info;
204 if (!o6i)
205 return;
206
207 o6i->if_id = ifp->ifindex;
208
209 ospf6_interface_address_update (ifp);
210
211 /* interface start */
212 if (o6i->area)
213 thread_add_event (master, interface_up, o6i, 0);
214}
215
216void
217ospf6_interface_if_del (struct interface *ifp)
218{
219 struct ospf6_interface *o6i;
220
221 o6i = (struct ospf6_interface *) ifp->info;
222 if (!o6i)
223 return;
224
225 /* interface stop */
226 if (o6i->area)
227 thread_execute (master, interface_down, o6i, 0);
228
229 listnode_delete (o6i->area->if_list, o6i);
230 o6i->area = (struct ospf6_area *) NULL;
231
232 /* cut link */
233 o6i->interface = NULL;
234 ifp->info = NULL;
235
236 ospf6_interface_delete (o6i);
237}
238
239void
240ospf6_interface_state_update (struct interface *ifp)
241{
242 struct ospf6_interface *o6i;
243
244 o6i = (struct ospf6_interface *) ifp->info;
245 if (! o6i)
246 return;
247 if (! o6i->area)
248 return;
249
250 if (if_is_up (ifp))
251 thread_add_event (master, interface_up, o6i, 0);
252 else
253 thread_add_event (master, interface_down, o6i, 0);
254
255 return;
256}
257
258void
259ospf6_interface_address_update (struct interface *ifp)
260{
261 struct ospf6_interface *o6i;
262
263 o6i = (struct ospf6_interface *) ifp->info;
264 if (! o6i)
265 return;
266
267 /* reset linklocal pointer */
268 o6i->lladdr = ospf6_interface_update_linklocal_address (ifp);
269
270 /* if area is null, can't make link-lsa */
271 if (! o6i->area)
272 return;
273
274 /* create new Link-LSA */
275 CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i);
276
277 CALL_CHANGE_HOOK (&interface_hook, o6i);
278}
279
280struct ospf6_interface *
281ospf6_interface_lookup_by_index (int ifindex)
282{
283 struct ospf6_interface *o6i;
284 struct interface *ifp;
285
286 ifp = if_lookup_by_index (ifindex);
287
288 if (! ifp)
289 return (struct ospf6_interface *) NULL;
290
291 o6i = (struct ospf6_interface *) ifp->info;
292 return o6i;
293}
294
295struct ospf6_interface *
296ospf6_interface_lookup_by_name (char *ifname)
297{
298 struct ospf6_interface *o6i;
299 struct interface *ifp;
300
301 ifp = if_lookup_by_name (ifname);
302
303 if (! ifp)
304 return (struct ospf6_interface *) NULL;
305
306 o6i = (struct ospf6_interface *) ifp->info;
307 return o6i;
308}
309
310int
311ospf6_interface_count_neighbor_in_state (u_char state,
312 struct ospf6_interface *o6i)
313{
314 listnode n;
315 struct ospf6_neighbor *o6n;
316 int count = 0;
317
318 for (n = listhead (o6i->neighbor_list); n; nextnode (n))
319 {
320 o6n = (struct ospf6_neighbor *) getdata (n);
321 if (o6n->state == state)
322 count++;
323 }
324 return count;
325}
326
327int
328ospf6_interface_count_full_neighbor (struct ospf6_interface *o6i)
329{
330 listnode n;
331 struct ospf6_neighbor *o6n;
332 int count = 0;
333
334 for (n = listhead (o6i->neighbor_list); n; nextnode (n))
335 {
336 o6n = (struct ospf6_neighbor *) getdata (n);
337 if (o6n->state == NBS_FULL)
338 count++;
339 }
340 return count;
341}
342
343int
344ospf6_interface_is_enabled (unsigned int ifindex)
345{
346 struct ospf6_interface *o6i;
347
348 o6i = ospf6_interface_lookup_by_index (ifindex);
349 if (! o6i)
350 return 0;
351
352 if (! o6i->area)
353 return 0;
354
355 if (o6i->state <= IFS_DOWN)
356 return 0;
357
358 return 1;
359}
360
361void
362ospf6_interface_delayed_ack_add (struct ospf6_lsa *lsa,
363 struct ospf6_interface *o6i)
364{
365 struct ospf6_lsa *summary;
366 summary = ospf6_lsa_summary_create (lsa->header);
367 ospf6_lsdb_add (summary, o6i->ack_list);
368}
369
370void
371ospf6_interface_delayed_ack_remove (struct ospf6_lsa *lsa,
372 struct ospf6_interface *o6i)
373{
374 struct ospf6_lsa *summary;
375 summary = ospf6_lsdb_lookup_lsdb (lsa->header->type, lsa->header->id,
376 lsa->header->adv_router, o6i->ack_list);
377 ospf6_lsdb_remove (summary, o6i->ack_list);
378}
379
380/* show specified interface structure */
381int
382ospf6_interface_show (struct vty *vty, struct interface *iface)
383{
384 struct ospf6_interface *ospf6_interface;
385 struct connected *c;
386 struct prefix *p;
387 listnode i;
388 char strbuf[64], dr[32], bdr[32];
389 char *updown[3] = {"down", "up", NULL};
390 char *type;
391
392 /* check physical interface type */
393 if (if_is_loopback (iface))
394 type = "LOOPBACK";
395 else if (if_is_broadcast (iface))
396 type = "BROADCAST";
397 else if (if_is_pointopoint (iface))
398 type = "POINTOPOINT";
399 else
400 type = "UNKNOWN";
401
402 vty_out (vty, "%s is %s, type %s%s",
403 iface->name, updown[if_is_up (iface)], type,
404 VTY_NEWLINE);
405 vty_out (vty, " Interface ID: %d%s", iface->ifindex, VTY_NEWLINE);
406
407 if (iface->info == NULL)
408 {
409 vty_out (vty, " OSPF not enabled on this interface%s", VTY_NEWLINE);
410 return 0;
411 }
412 else
413 ospf6_interface = (struct ospf6_interface *) iface->info;
414
415 vty_out (vty, " Internet Address:%s", VTY_NEWLINE);
416 for (i = listhead (iface->connected); i; nextnode (i))
417 {
418 c = (struct connected *)getdata (i);
419 p = c->address;
420 prefix2str (p, strbuf, sizeof (strbuf));
421 switch (p->family)
422 {
423 case AF_INET:
424 vty_out (vty, " inet : %s%s", strbuf,
425 VTY_NEWLINE);
426 break;
427 case AF_INET6:
428 vty_out (vty, " inet6: %s%s", strbuf,
429 VTY_NEWLINE);
430 break;
431 default:
432 vty_out (vty, " ??? : %s%s", strbuf,
433 VTY_NEWLINE);
434 break;
435 }
436 }
437
438 if (ospf6_interface->area)
439 {
440 inet_ntop (AF_INET, &ospf6_interface->area->ospf6->router_id,
441 strbuf, sizeof (strbuf));
442 vty_out (vty, " Instance ID %d, Router ID %s%s",
443 ospf6_interface->instance_id, strbuf,
444 VTY_NEWLINE);
445 inet_ntop (AF_INET, &ospf6_interface->area->area_id,
446 strbuf, sizeof (strbuf));
447 vty_out (vty, " Area ID %s, Cost %hu%s", strbuf,
448 ospf6_interface->cost, VTY_NEWLINE);
449 }
450 else
451 vty_out (vty, " Not Attached to Area%s", VTY_NEWLINE);
452
453 vty_out (vty, " State %s, Transmit Delay %d sec, Priority %d%s",
454 ospf6_interface_state_string[ospf6_interface->state],
455 ospf6_interface->transdelay,
456 ospf6_interface->priority,
457 VTY_NEWLINE);
458 vty_out (vty, " Timer intervals configured:%s", VTY_NEWLINE);
459 vty_out (vty, " Hello %d, Dead %d, Retransmit %d%s",
460 ospf6_interface->hello_interval,
461 ospf6_interface->dead_interval,
462 ospf6_interface->rxmt_interval,
463 VTY_NEWLINE);
464
465 inet_ntop (AF_INET, &ospf6_interface->dr, dr, sizeof (dr));
466 inet_ntop (AF_INET, &ospf6_interface->bdr, bdr, sizeof (bdr));
467 vty_out (vty, " DR:%s BDR:%s%s", dr, bdr, VTY_NEWLINE);
468
469 vty_out (vty, " Number of I/F scoped LSAs is %u%s",
470 ospf6_interface->lsdb->count, VTY_NEWLINE);
471 vty_out (vty, " %-16s %5d times, %-16s %5d times%s",
472 "DRElection", ospf6_interface->ospf6_stat_dr_election,
473 "DelayedLSAck", ospf6_interface->ospf6_stat_delayed_lsack,
474 VTY_NEWLINE);
475
476 return 0;
477}
478
479void
480ospf6_interface_statistics_show (struct vty *vty, struct ospf6_interface *o6i)
481{
482 struct timeval now, uptime;
483 u_long recv_total, send_total;
484 u_long bps_total_avg, bps_tx_avg, bps_rx_avg;
485 int i;
486
487 gettimeofday (&now, (struct timezone *) NULL);
488 ospf6_timeval_sub (&now, &ospf6->starttime, &uptime);
489
490 recv_total = send_total = 0;
491 for (i = 0; i < OSPF6_MESSAGE_TYPE_MAX; i++)
492 {
493 recv_total += o6i->message_stat[i].recv_octet;
494 send_total += o6i->message_stat[i].send_octet;
495 }
496 bps_total_avg = (recv_total + send_total) * 8 / uptime.tv_sec;
497 bps_tx_avg = send_total * 8 / uptime.tv_sec;
498 bps_rx_avg = recv_total * 8 / uptime.tv_sec;
499
500 vty_out (vty, " Statistics of interface %s%s",
501 o6i->interface->name, VTY_NEWLINE);
502 vty_out (vty, " Number of Neighbor: %d%s",
503 listcount (o6i->neighbor_list), VTY_NEWLINE);
504
505 vty_out (vty, " %-8s %6s %6s %8s %8s%s",
506 "Type", "tx", "rx", "tx-byte", "rx-byte", VTY_NEWLINE);
507 for (i = 0; i < OSPF6_MESSAGE_TYPE_MAX; i++)
508 {
509 vty_out (vty, " %-8s %6d %6d %8d %8d%s",
510 ospf6_message_type_string[i],
511 o6i->message_stat[i].send,
512 o6i->message_stat[i].recv,
513 o6i->message_stat[i].send_octet,
514 o6i->message_stat[i].recv_octet,
515 VTY_NEWLINE);
516 }
517
518 vty_out (vty, " Average Link bandwidth: %ldbps"
519 " (Tx: %ldbps Rx: %ldbps)%s",
520 bps_total_avg, bps_tx_avg, bps_rx_avg, VTY_NEWLINE);
521}
522
523/* show interface */
524DEFUN (show_ipv6_ospf6_interface,
525 show_ipv6_ospf6_interface_ifname_cmd,
526 "show ipv6 ospf6 interface IFNAME",
527 SHOW_STR
528 IP6_STR
529 OSPF6_STR
530 INTERFACE_STR
531 IFNAME_STR
532 )
533{
534 struct interface *ifp;
535 listnode i;
536
537 if (argc)
538 {
539 ifp = if_lookup_by_name (argv[0]);
540 if (!ifp)
541 {
542 vty_out (vty, "No such Interface: %s%s", argv[0],
543 VTY_NEWLINE);
544 return CMD_WARNING;
545 }
546 ospf6_interface_show (vty, ifp);
547 }
548 else
549 {
550 for (i = listhead (iflist); i; nextnode (i))
551 {
552 ifp = (struct interface *)getdata (i);
553 ospf6_interface_show (vty, ifp);
554 }
555 }
556 return CMD_SUCCESS;
557}
558
559ALIAS (show_ipv6_ospf6_interface,
560 show_ipv6_ospf6_interface_cmd,
561 "show ipv6 ospf6 interface",
562 SHOW_STR
563 IP6_STR
564 OSPF6_STR
565 INTERFACE_STR
566 )
567
568/* interface variable set command */
569DEFUN (ipv6_ospf6_cost,
570 ipv6_ospf6_cost_cmd,
571 "ipv6 ospf6 cost COST",
572 IP6_STR
573 OSPF6_STR
574 "Interface cost\n"
575 "<1-65535> Cost\n"
576 )
577{
578 struct ospf6_interface *o6i;
579 struct interface *ifp;
580
581 ifp = (struct interface *)vty->index;
582 assert (ifp);
583
584 o6i = (struct ospf6_interface *)ifp->info;
585 if (!o6i)
586 o6i = ospf6_interface_create (ifp);
587 assert (o6i);
588
589 if (o6i->cost == strtol (argv[0], NULL, 10))
590 return CMD_SUCCESS;
591
592 o6i->cost = strtol (argv[0], NULL, 10);
593
594 /* execute LSA hooks */
595 CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i);
596
597 CALL_CHANGE_HOOK (&interface_hook, o6i);
598
599 return CMD_SUCCESS;
600}
601
602/* interface variable set command */
603DEFUN (ipv6_ospf6_hellointerval,
604 ipv6_ospf6_hellointerval_cmd,
605 "ipv6 ospf6 hello-interval HELLO_INTERVAL",
606 IP6_STR
607 OSPF6_STR
608 "Time between HELLO packets\n"
609 SECONDS_STR
610 )
611{
612 struct ospf6_interface *ospf6_interface;
613 struct interface *ifp;
614
615 ifp = (struct interface *) vty->index;
616 assert (ifp);
617 ospf6_interface = (struct ospf6_interface *) ifp->info;
618 if (!ospf6_interface)
619 ospf6_interface = ospf6_interface_create (ifp);
620 assert (ospf6_interface);
621
622 ospf6_interface->hello_interval = strtol (argv[0], NULL, 10);
623 return CMD_SUCCESS;
624}
625
626/* interface variable set command */
627DEFUN (ipv6_ospf6_deadinterval,
628 ipv6_ospf6_deadinterval_cmd,
629 "ipv6 ospf6 dead-interval ROUTER_DEAD_INTERVAL",
630 IP6_STR
631 OSPF6_STR
632 "Interval after which a neighbor is declared dead\n"
633 SECONDS_STR
634 )
635{
636 struct ospf6_interface *ospf6_interface;
637 struct interface *ifp;
638
639 ifp = (struct interface *) vty->index;
640 assert (ifp);
641 ospf6_interface = (struct ospf6_interface *) ifp->info;
642 if (!ospf6_interface)
643 ospf6_interface = ospf6_interface_create (ifp);
644 assert (ospf6_interface);
645
646 ospf6_interface->dead_interval = strtol (argv[0], NULL, 10);
647 return CMD_SUCCESS;
648}
649
650/* interface variable set command */
651DEFUN (ipv6_ospf6_transmitdelay,
652 ipv6_ospf6_transmitdelay_cmd,
653 "ipv6 ospf6 transmit-delay TRANSMITDELAY",
654 IP6_STR
655 OSPF6_STR
656 "Link state transmit delay\n"
657 SECONDS_STR
658 )
659{
660 struct ospf6_interface *ospf6_interface;
661 struct interface *ifp;
662
663 ifp = (struct interface *) vty->index;
664 assert (ifp);
665 ospf6_interface = (struct ospf6_interface *) ifp->info;
666 if (!ospf6_interface)
667 ospf6_interface = ospf6_interface_create (ifp);
668 assert (ospf6_interface);
669
670 ospf6_interface->transdelay = strtol (argv[0], NULL, 10);
671 return CMD_SUCCESS;
672}
673
674/* interface variable set command */
675DEFUN (ipv6_ospf6_retransmitinterval,
676 ipv6_ospf6_retransmitinterval_cmd,
677 "ipv6 ospf6 retransmit-interval RXMTINTERVAL",
678 IP6_STR
679 OSPF6_STR
680 "Time between retransmitting lost link state advertisements\n"
681 SECONDS_STR
682 )
683{
684 struct ospf6_interface *ospf6_interface;
685 struct interface *ifp;
686
687 ifp = (struct interface *) vty->index;
688 assert (ifp);
689 ospf6_interface = (struct ospf6_interface *) ifp->info;
690 if (!ospf6_interface)
691 ospf6_interface = ospf6_interface_create (ifp);
692 assert (ospf6_interface);
693
694 ospf6_interface->rxmt_interval = strtol (argv[0], NULL, 10);
695 return CMD_SUCCESS;
696}
697
698/* interface variable set command */
699DEFUN (ipv6_ospf6_priority,
700 ipv6_ospf6_priority_cmd,
701 "ipv6 ospf6 priority PRIORITY",
702 IP6_STR
703 OSPF6_STR
704 "Router priority\n"
705 "<0-255> Priority\n"
706 )
707{
708 struct ospf6_interface *ospf6_interface;
709 struct interface *ifp;
710
711 ifp = (struct interface *) vty->index;
712 assert (ifp);
713 ospf6_interface = (struct ospf6_interface *) ifp->info;
714 if (!ospf6_interface)
715 ospf6_interface = ospf6_interface_create (ifp);
716 assert (ospf6_interface);
717
718 ospf6_interface->priority = strtol (argv[0], NULL, 10);
719
720 if (ospf6_interface->area)
721 ifs_change (dr_election (ospf6_interface), "Priority reconfigured",
722 ospf6_interface);
723
724 return CMD_SUCCESS;
725}
726
727DEFUN (ipv6_ospf6_instance,
728 ipv6_ospf6_instance_cmd,
729 "ipv6 ospf6 instance-id INSTANCE",
730 IP6_STR
731 OSPF6_STR
732 "Instance ID\n"
733 "<0-255> Instance ID\n"
734 )
735{
736 struct ospf6_interface *ospf6_interface;
737 struct interface *ifp;
738
739 ifp = (struct interface *)vty->index;
740 assert (ifp);
741
742 ospf6_interface = (struct ospf6_interface *)ifp->info;
743 if (!ospf6_interface)
744 ospf6_interface = ospf6_interface_create (ifp);
745 assert (ospf6_interface);
746
747 ospf6_interface->instance_id = strtol (argv[0], NULL, 10);
748 return CMD_SUCCESS;
749}
750
751DEFUN (ipv6_ospf6_passive,
752 ipv6_ospf6_passive_cmd,
753 "ipv6 ospf6 passive",
754 IP6_STR
755 OSPF6_STR
756 "passive interface: No Adjacency will be formed on this I/F\n"
757 )
758{
759 struct ospf6_interface *o6i;
760 struct interface *ifp;
761 listnode node;
762 struct ospf6_neighbor *o6n;
763
764 ifp = (struct interface *) vty->index;
765 assert (ifp);
766 o6i = (struct ospf6_interface *) ifp->info;
767 if (! o6i)
768 o6i = ospf6_interface_create (ifp);
769 assert (o6i);
770
771 SET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE);
772 if (o6i->thread_send_hello)
773 {
774 thread_cancel (o6i->thread_send_hello);
775 o6i->thread_send_hello = (struct thread *) NULL;
776 }
777
778 for (node = listhead (o6i->neighbor_list); node; nextnode (node))
779 {
780 o6n = getdata (node);
781 if (o6n->inactivity_timer)
782 thread_cancel (o6n->inactivity_timer);
783 thread_execute (master, inactivity_timer, o6n, 0);
784 }
785
786 return CMD_SUCCESS;
787}
788
789DEFUN (no_ipv6_ospf6_passive,
790 no_ipv6_ospf6_passive_cmd,
791 "no ipv6 ospf6 passive",
792 NO_STR
793 IP6_STR
794 OSPF6_STR
795 "passive interface: No Adjacency will be formed on this I/F\n"
796 )
797{
798 struct ospf6_interface *o6i;
799 struct interface *ifp;
800
801 ifp = (struct interface *) vty->index;
802 assert (ifp);
803 o6i = (struct ospf6_interface *) ifp->info;
804 if (! o6i)
805 o6i = ospf6_interface_create (ifp);
806 assert (o6i);
807
808 UNSET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE);
809 if (o6i->thread_send_hello == NULL)
810 thread_add_event (master, ospf6_send_hello, o6i, 0);
811
812 return CMD_SUCCESS;
813}
814
815
816DEFUN (ipv6_ospf6_advertise_force_prefix,
817 ipv6_ospf6_advertise_force_prefix_cmd,
818 "ipv6 ospf6 advertise force-prefix",
819 IP6_STR
820 OSPF6_STR
821 "Advertising options\n"
822 "Force advertising prefix, applicable if Loopback or P-to-P\n"
823 )
824{
825 struct ospf6_interface *o6i;
826 struct interface *ifp;
827
828 ifp = (struct interface *) vty->index;
829 assert (ifp);
830 o6i = (struct ospf6_interface *) ifp->info;
831 if (! o6i)
832 o6i = ospf6_interface_create (ifp);
833 assert (o6i);
834
835 if (! if_is_loopback (ifp) && ! if_is_pointopoint (ifp))
836 {
837 vty_out (vty, "Interface not Loopback nor PointToPoint%s",
838 VTY_NEWLINE);
839 return CMD_ERR_NOTHING_TODO;
840 }
841
842 SET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_FORCE_PREFIX);
843
844 /* execute LSA hooks */
845 CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i);
846
847 CALL_CHANGE_HOOK (&interface_hook, o6i);
848
849 return CMD_SUCCESS;
850}
851
852DEFUN (no_ipv6_ospf6_advertise_force_prefix,
853 no_ipv6_ospf6_advertise_force_prefix_cmd,
854 "no ipv6 ospf6 advertise force-prefix",
855 NO_STR
856 IP6_STR
857 OSPF6_STR
858 "Advertising options\n"
859 "Force to advertise prefix, applicable if Loopback or P-to-P\n"
860 )
861{
862 struct ospf6_interface *o6i;
863 struct interface *ifp;
864
865 ifp = (struct interface *) vty->index;
866 assert (ifp);
867 o6i = (struct ospf6_interface *) ifp->info;
868 if (! o6i)
869 o6i = ospf6_interface_create (ifp);
870 assert (o6i);
871
872 UNSET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_FORCE_PREFIX);
873
874 /* execute LSA hooks */
875 CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i);
876
877 CALL_CHANGE_HOOK (&interface_hook, o6i);
878
879 return CMD_SUCCESS;
880}
881
882DEFUN (ipv6_ospf6_advertise_prefix_list,
883 ipv6_ospf6_advertise_prefix_list_cmd,
884 "ipv6 ospf6 advertise prefix-list WORD",
885 IP6_STR
886 OSPF6_STR
887 "Advertising options\n"
888 "Filter prefix using prefix-list\n"
889 "Prefix list name\n"
890 )
891{
892 struct ospf6_interface *o6i;
893 struct interface *ifp;
894
895 ifp = (struct interface *) vty->index;
896 assert (ifp);
897 o6i = (struct ospf6_interface *) ifp->info;
898 if (! o6i)
899 o6i = ospf6_interface_create (ifp);
900 assert (o6i);
901
902 if (o6i->plist_name)
903 XFREE (MTYPE_PREFIX_LIST_STR, o6i->plist_name);
904 o6i->plist_name = XSTRDUP (MTYPE_PREFIX_LIST_STR, argv[0]);
905
906 /* execute LSA hooks */
907 CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i);
908
909 CALL_CHANGE_HOOK (&interface_hook, o6i);
910
911 return CMD_SUCCESS;
912}
913
914DEFUN (no_ipv6_ospf6_advertise_prefix_list,
915 no_ipv6_ospf6_advertise_prefix_list_cmd,
916 "no ipv6 ospf6 advertise prefix-list",
917 NO_STR
918 IP6_STR
919 OSPF6_STR
920 "Advertising options\n"
921 "Filter prefix using prefix-list\n"
922 )
923{
924 struct ospf6_interface *o6i;
925 struct interface *ifp;
926
927 ifp = (struct interface *) vty->index;
928 assert (ifp);
929 o6i = (struct ospf6_interface *) ifp->info;
930 if (! o6i)
931 o6i = ospf6_interface_create (ifp);
932 assert (o6i);
933
934 if (o6i->plist_name)
935 {
936 XFREE (MTYPE_PREFIX_LIST_STR, o6i->plist_name);
937 o6i->plist_name = NULL;
938 }
939
940 /* execute LSA hooks */
941 CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i);
942
943 CALL_CHANGE_HOOK (&interface_hook, o6i);
944
945 return CMD_SUCCESS;
946}
947
948int
949ospf6_interface_config_write (struct vty *vty)
950{
951 listnode i;
952 struct ospf6_interface *o6i;
953 struct interface *ifp;
954
955 for (i = listhead (iflist); i; nextnode (i))
956 {
957 ifp = (struct interface *) getdata (i);
958 o6i = (struct ospf6_interface *) ifp->info;
959 if (! o6i)
960 continue;
961
962 vty_out (vty, "interface %s%s",
963 o6i->interface->name, VTY_NEWLINE);
964 vty_out (vty, " ipv6 ospf6 cost %d%s",
965 o6i->cost, VTY_NEWLINE);
966 vty_out (vty, " ipv6 ospf6 hello-interval %d%s",
967 o6i->hello_interval, VTY_NEWLINE);
968 vty_out (vty, " ipv6 ospf6 dead-interval %d%s",
969 o6i->dead_interval, VTY_NEWLINE);
970 vty_out (vty, " ipv6 ospf6 retransmit-interval %d%s",
971 o6i->rxmt_interval, VTY_NEWLINE);
972 vty_out (vty, " ipv6 ospf6 priority %d%s",
973 o6i->priority, VTY_NEWLINE);
974 vty_out (vty, " ipv6 ospf6 transmit-delay %d%s",
975 o6i->transdelay, VTY_NEWLINE);
976 vty_out (vty, " ipv6 ospf6 instance-id %d%s",
977 o6i->instance_id, VTY_NEWLINE);
978
979 if (CHECK_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_FORCE_PREFIX))
980 vty_out (vty, " ipv6 ospf6 advertise force-prefix%s", VTY_NEWLINE);
981 if (o6i->plist_name)
982 vty_out (vty, " ipv6 ospf6 advertise prefix-list %s%s",
983 o6i->plist_name, VTY_NEWLINE);
984
985 if (CHECK_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE))
986 vty_out (vty, " ipv6 ospf6 passive%s", VTY_NEWLINE);
987
988 vty_out (vty, "!%s", VTY_NEWLINE);
989 }
990 return 0;
991}
992
993struct cmd_node interface_node =
994{
995 INTERFACE_NODE,
996 "%s(config-if)# ",
997};
998
999void
1000ospf6_interface_init ()
1001{
1002 /* Install interface node. */
1003 install_node (&interface_node, ospf6_interface_config_write);
1004
1005 install_element (VIEW_NODE, &show_ipv6_ospf6_interface_cmd);
1006 install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
1007 install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_cmd);
1008 install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
1009
1010 install_default (INTERFACE_NODE);
1011 install_element (INTERFACE_NODE, &interface_desc_cmd);
1012 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1013 install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
1014 install_element (INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
1015 install_element (INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
1016 install_element (INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
1017 install_element (INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
1018 install_element (INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
1019 install_element (INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
1020 install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_force_prefix_cmd);
1021 install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_force_prefix_cmd);
1022 install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
1023 install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_prefix_list_cmd);
1024 install_element (INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
1025 install_element (INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
1026}
1027
1028