ospf6_interface.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:42k
源码类别:

网络

开发平台:

Unix_Linux

  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. #include <zebra.h>
  22. #include "memory.h"
  23. #include "if.h"
  24. #include "log.h"
  25. #include "command.h"
  26. #include "thread.h"
  27. #include "prefix.h"
  28. #include "plist.h"
  29. #include "ospf6_lsa.h"
  30. #include "ospf6_lsdb.h"
  31. #include "ospf6_network.h"
  32. #include "ospf6_message.h"
  33. #include "ospf6_route.h"
  34. #include "ospf6_top.h"
  35. #include "ospf6_area.h"
  36. #include "ospf6_interface.h"
  37. #include "ospf6_neighbor.h"
  38. #include "ospf6_intra.h"
  39. #include "ospf6_spf.h"
  40. #include "ospf6d.h"
  41. unsigned char conf_debug_ospf6_interface = 0;
  42. char *ospf6_interface_state_str[] =
  43. {
  44.   "None",
  45.   "Down",
  46.   "Loopback",
  47.   "Waiting",
  48.   "PointToPoint",
  49.   "DROther",
  50.   "BDR",
  51.   "DR",
  52.   NULL
  53. };
  54. struct ospf6_interface *
  55. ospf6_interface_lookup_by_ifindex (int ifindex)
  56. {
  57.   struct ospf6_interface *oi;
  58.   struct interface *ifp;
  59.   ifp = if_lookup_by_index (ifindex);
  60.   if (ifp == NULL)
  61.     return (struct ospf6_interface *) NULL;
  62.   oi = (struct ospf6_interface *) ifp->info;
  63.   return oi;
  64. }
  65. struct ospf6_interface *
  66. ospf6_interface_lookup_by_name (char *ifname)
  67. {
  68.   struct ospf6_interface *oi;
  69.   struct interface *ifp;
  70.   ifp = if_lookup_by_name (ifname);
  71.   if (ifp == NULL)
  72.     return (struct ospf6_interface *) NULL;
  73.   oi = (struct ospf6_interface *) ifp->info;
  74.   return oi;
  75. }
  76. /* schedule routing table recalculation */
  77. void
  78. ospf6_interface_lsdb_hook (struct ospf6_lsa *lsa)
  79. {
  80.   switch (ntohs (lsa->header->type))
  81.     {
  82.       case OSPF6_LSTYPE_LINK:
  83.         if (OSPF6_INTERFACE (lsa->lsdb->data)->state == OSPF6_INTERFACE_DR)
  84.           OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (OSPF6_INTERFACE (lsa->lsdb->data));
  85.         ospf6_spf_schedule (OSPF6_INTERFACE (lsa->lsdb->data)->area);
  86.         break;
  87.       default:
  88.         break;
  89.     }
  90. }
  91. /* Create new ospf6 interface structure */
  92. struct ospf6_interface *
  93. ospf6_interface_create (struct interface *ifp)
  94. {
  95.   struct ospf6_interface *oi;
  96.   int iobuflen;
  97.   oi = (struct ospf6_interface *)
  98.     XMALLOC (MTYPE_OSPF6_IF, sizeof (struct ospf6_interface));
  99.   if (oi)
  100.     memset (oi, 0, sizeof (struct ospf6_interface));
  101.   else
  102.     {
  103.       zlog_err ("Can't malloc ospf6_interface for ifindex %d", ifp->ifindex);
  104.       return (struct ospf6_interface *) NULL;
  105.     }
  106.   oi->area = (struct ospf6_area *) NULL;
  107.   oi->neighbor_list = list_new ();
  108.   oi->neighbor_list->cmp = ospf6_neighbor_cmp;
  109.   oi->linklocal_addr = (struct in6_addr *) NULL;
  110.   oi->instance_id = 0;
  111.   oi->transdelay = 1;
  112.   oi->priority = 1;
  113.   oi->hello_interval = 10;
  114.   oi->dead_interval = 40;
  115.   oi->rxmt_interval = 5;
  116.   oi->cost = 1;
  117.   oi->state = OSPF6_INTERFACE_DOWN;
  118.   oi->flag = 0;
  119.   /* Try to adjust I/O buffer size with IfMtu */
  120.   oi->ifmtu = ifp->mtu;
  121.   iobuflen = ospf6_iobuf_size (ifp->mtu);
  122.   if (oi->ifmtu > iobuflen)
  123.     {
  124.       if (IS_OSPF6_DEBUG_INTERFACE)
  125.         zlog_info ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
  126.                    ifp->name, iobuflen);
  127.       oi->ifmtu = iobuflen;
  128.     }
  129.   oi->lsupdate_list = ospf6_lsdb_create (oi);
  130.   oi->lsack_list = ospf6_lsdb_create (oi);
  131.   oi->lsdb = ospf6_lsdb_create (oi);
  132.   oi->lsdb->hook_add = ospf6_interface_lsdb_hook;
  133.   oi->lsdb->hook_remove = ospf6_interface_lsdb_hook;
  134.   oi->lsdb_self = ospf6_lsdb_create (oi);
  135.   oi->route_connected = ospf6_route_table_create ();
  136.   /* link both */
  137.   oi->interface = ifp;
  138.   ifp->info = oi;
  139.   return oi;
  140. }
  141. void
  142. ospf6_interface_delete (struct ospf6_interface *oi)
  143. {
  144.   listnode n;
  145.   struct ospf6_neighbor *on;
  146.   for (n = listhead (oi->neighbor_list); n; nextnode (n))
  147.     {
  148.       on = (struct ospf6_neighbor *) getdata (n);
  149.       ospf6_neighbor_delete (on);
  150.     }
  151.   list_delete (oi->neighbor_list);
  152.   THREAD_OFF (oi->thread_send_hello);
  153.   THREAD_OFF (oi->thread_send_lsupdate);
  154.   THREAD_OFF (oi->thread_send_lsack);
  155.   ospf6_lsdb_remove_all (oi->lsdb);
  156.   ospf6_lsdb_remove_all (oi->lsupdate_list);
  157.   ospf6_lsdb_remove_all (oi->lsack_list);
  158.   ospf6_lsdb_delete (oi->lsdb);
  159.   ospf6_lsdb_delete (oi->lsdb_self);
  160.   ospf6_lsdb_delete (oi->lsupdate_list);
  161.   ospf6_lsdb_delete (oi->lsack_list);
  162.   ospf6_route_table_delete (oi->route_connected);
  163.   /* cut link */
  164.   oi->interface->info = NULL;
  165.   /* plist_name */
  166.   if (oi->plist_name)
  167.     XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name);
  168.   XFREE (MTYPE_OSPF6_IF, oi);
  169. }
  170. void
  171. ospf6_interface_enable (struct ospf6_interface *oi)
  172. {
  173.   UNSET_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE);
  174.   oi->thread_send_hello =
  175.     thread_add_event (master, ospf6_hello_send, oi, 0);
  176. }
  177. void
  178. ospf6_interface_disable (struct ospf6_interface *oi)
  179. {
  180.   listnode i;
  181.   struct ospf6_neighbor *on;
  182.   SET_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE);
  183.   for (i = listhead (oi->neighbor_list); i; nextnode (i))
  184.     {
  185.       on = (struct ospf6_neighbor *) getdata (i);
  186.       ospf6_neighbor_delete (on);
  187.     }
  188.   list_delete_all_node (oi->neighbor_list);
  189.   ospf6_lsdb_remove_all (oi->lsdb);
  190.   ospf6_lsdb_remove_all (oi->lsupdate_list);
  191.   ospf6_lsdb_remove_all (oi->lsack_list);
  192.   THREAD_OFF (oi->thread_send_hello);
  193.   THREAD_OFF (oi->thread_send_lsupdate);
  194.   THREAD_OFF (oi->thread_send_lsack);
  195. }
  196. static struct in6_addr *
  197. ospf6_interface_get_linklocal_address (struct interface *ifp)
  198. {
  199.   listnode n;
  200.   struct connected *c;
  201.   struct in6_addr *l = (struct in6_addr *) NULL;
  202.   /* for each connected address */
  203.   for (n = listhead (ifp->connected); n; nextnode (n))
  204.     {
  205.       c = (struct connected *) getdata (n);
  206.       /* if family not AF_INET6, ignore */
  207.       if (c->address->family != AF_INET6)
  208.         continue;
  209.       /* linklocal scope check */
  210.       if (IN6_IS_ADDR_LINKLOCAL (&c->address->u.prefix6))
  211.         l = &c->address->u.prefix6;
  212.     }
  213.   return l;
  214. }
  215. void
  216. ospf6_interface_if_add (struct interface *ifp)
  217. {
  218.   struct ospf6_interface *oi;
  219.   int iobuflen;
  220.   oi = (struct ospf6_interface *) ifp->info;
  221.   if (oi == NULL)
  222.     return;
  223.   /* Try to adjust I/O buffer size with IfMtu */
  224.   if (oi->ifmtu == 0)
  225.     oi->ifmtu = ifp->mtu;
  226.   iobuflen = ospf6_iobuf_size (ifp->mtu);
  227.   if (oi->ifmtu > iobuflen)
  228.     {
  229.       if (IS_OSPF6_DEBUG_INTERFACE)
  230.         zlog_info ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
  231.                    ifp->name, iobuflen);
  232.       oi->ifmtu = iobuflen;
  233.     }
  234.   /* interface start */
  235.   if (oi->area)
  236.     thread_add_event (master, interface_up, oi, 0);
  237. }
  238. void
  239. ospf6_interface_if_del (struct interface *ifp)
  240. {
  241.   struct ospf6_interface *oi;
  242.   oi = (struct ospf6_interface *) ifp->info;
  243.   if (oi == NULL)
  244.     return;
  245.   /* interface stop */
  246.   if (oi->area)
  247.     thread_execute (master, interface_down, oi, 0);
  248.   listnode_delete (oi->area->if_list, oi);
  249.   oi->area = (struct ospf6_area *) NULL;
  250.   /* cut link */
  251.   oi->interface = NULL;
  252.   ifp->info = NULL;
  253.   ospf6_interface_delete (oi);
  254. }
  255. void
  256. ospf6_interface_state_update (struct interface *ifp)
  257. {
  258.   struct ospf6_interface *oi;
  259.   oi = (struct ospf6_interface *) ifp->info;
  260.   if (oi == NULL)
  261.     return;
  262.   if (oi->area == NULL)
  263.     return;
  264.   if (if_is_up (ifp))
  265.     thread_add_event (master, interface_up, oi, 0);
  266.   else
  267.     thread_add_event (master, interface_down, oi, 0);
  268.   return;
  269. }
  270. void
  271. ospf6_interface_connected_route_update (struct interface *ifp)
  272. {
  273.   struct ospf6_interface *oi;
  274.   struct ospf6_route *route;
  275.   struct connected *c;
  276.   listnode i;
  277.   oi = (struct ospf6_interface *) ifp->info;
  278.   if (oi == NULL)
  279.     return;
  280.   /* reset linklocal pointer */
  281.   oi->linklocal_addr = ospf6_interface_get_linklocal_address (ifp);
  282.   /* if area is null, do not make connected-route list */
  283.   if (oi->area == NULL)
  284.     return;
  285.   /* update "route to advertise" interface route table */
  286.   ospf6_route_remove_all (oi->route_connected);
  287.   for (i = listhead (oi->interface->connected); i; nextnode (i))
  288.     {
  289.       c = (struct connected *) getdata (i);
  290.       if (c->address->family != AF_INET6)
  291.         continue;
  292.       CONTINUE_IF_ADDRESS_LINKLOCAL (IS_OSPF6_DEBUG_INTERFACE, c->address);
  293.       CONTINUE_IF_ADDRESS_UNSPECIFIED (IS_OSPF6_DEBUG_INTERFACE, c->address);
  294.       CONTINUE_IF_ADDRESS_LOOPBACK (IS_OSPF6_DEBUG_INTERFACE, c->address);
  295.       CONTINUE_IF_ADDRESS_V4COMPAT (IS_OSPF6_DEBUG_INTERFACE, c->address);
  296.       CONTINUE_IF_ADDRESS_V4MAPPED (IS_OSPF6_DEBUG_INTERFACE, c->address);
  297.       /* apply filter */
  298.       if (oi->plist_name)
  299.         {
  300.           struct prefix_list *plist;
  301.           enum prefix_list_type ret;
  302.           char buf[128];
  303.           prefix2str (c->address, buf, sizeof (buf));
  304.           plist = prefix_list_lookup (AFI_IP6, oi->plist_name);
  305.           ret = prefix_list_apply (plist, (void *) c->address);
  306.           if (ret == PREFIX_DENY)
  307.             {
  308.               if (IS_OSPF6_DEBUG_INTERFACE)
  309.                 zlog_info ("%s on %s filtered by prefix-list %s ",
  310.                            buf, oi->interface->name, oi->plist_name);
  311.               continue;
  312.             }
  313.         }
  314.       route = ospf6_route_create ();
  315.       memcpy (&route->prefix, c->address, sizeof (struct prefix));
  316.       apply_mask (&route->prefix);
  317.       route->type = OSPF6_DEST_TYPE_NETWORK;
  318.       route->path.area_id = oi->area->area_id;
  319.       route->path.type = OSPF6_PATH_TYPE_INTRA;
  320.       route->path.cost = oi->cost;
  321.       route->nexthop[0].ifindex = oi->interface->ifindex;
  322.       inet_pton (AF_INET6, "::1", &route->nexthop[0].address);
  323.       ospf6_route_add (route, oi->route_connected);
  324.     }
  325.   /* create new Link-LSA */
  326.   OSPF6_LINK_LSA_SCHEDULE (oi);
  327.   OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
  328.   OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
  329. }
  330. static void
  331. ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi)
  332. {
  333.   u_char prev_state;
  334.   prev_state = oi->state;
  335.   oi->state = next_state;
  336.   if (prev_state == next_state)
  337.     return;
  338.   /* log */
  339.   if (IS_OSPF6_DEBUG_INTERFACE)
  340.     {
  341.       zlog_info ("Interface state change %s: %s -> %s", oi->interface->name,
  342.                  ospf6_interface_state_str[prev_state],
  343.                  ospf6_interface_state_str[next_state]);
  344.     }
  345.   if ((prev_state == OSPF6_INTERFACE_DR ||
  346.        prev_state == OSPF6_INTERFACE_BDR) &&
  347.       (next_state != OSPF6_INTERFACE_DR &&
  348.        next_state != OSPF6_INTERFACE_BDR))
  349.     ospf6_leave_alldrouters (oi->interface->ifindex);
  350.   if ((prev_state != OSPF6_INTERFACE_DR &&
  351.        prev_state != OSPF6_INTERFACE_BDR) &&
  352.       (next_state == OSPF6_INTERFACE_DR ||
  353.        next_state == OSPF6_INTERFACE_BDR))
  354.     ospf6_join_alldrouters (oi->interface->ifindex);
  355.   OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
  356.   if (next_state == OSPF6_INTERFACE_DOWN)
  357.     {
  358.       OSPF6_NETWORK_LSA_EXECUTE (oi);
  359.       OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT (oi);
  360.       OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
  361.     }
  362.   else if (prev_state == OSPF6_INTERFACE_DR ||
  363.            next_state == OSPF6_INTERFACE_DR)
  364.     {
  365.       OSPF6_NETWORK_LSA_SCHEDULE (oi);
  366.       OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
  367.       OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
  368.     }
  369. }
  370. /* DR Election, RFC2328 section 9.4 */
  371. #define IS_ELIGIBLE(n) 
  372.   ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
  373. static struct ospf6_neighbor *
  374. better_bdrouter (struct ospf6_neighbor *a, struct ospf6_neighbor *b)
  375. {
  376.   if ((a == NULL || ! IS_ELIGIBLE (a) || a->drouter == a->router_id) &&
  377.       (b == NULL || ! IS_ELIGIBLE (b) || b->drouter == b->router_id))
  378.     return NULL;
  379.   else if (a == NULL || ! IS_ELIGIBLE (a) || a->drouter == a->router_id)
  380.     return b;
  381.   else if (b == NULL || ! IS_ELIGIBLE (b) || b->drouter == b->router_id)
  382.     return a;
  383.   if (a->bdrouter == a->router_id && b->bdrouter != b->router_id)
  384.     return a;
  385.   if (a->bdrouter != a->router_id && b->bdrouter == b->router_id)
  386.     return b;
  387.   if (a->priority > b->priority)
  388.     return a;
  389.   if (a->priority < b->priority)
  390.     return b;
  391.   if (ntohl (a->router_id) > ntohl (b->router_id))
  392.     return a;
  393.   if (ntohl (a->router_id) < ntohl (b->router_id))
  394.     return b;
  395.   zlog_warn ("Router-ID duplicate ?");
  396.   return a;
  397. }
  398. static struct ospf6_neighbor *
  399. better_drouter (struct ospf6_neighbor *a, struct ospf6_neighbor *b)
  400. {
  401.   if ((a == NULL || ! IS_ELIGIBLE (a) || a->drouter != a->router_id) &&
  402.       (b == NULL || ! IS_ELIGIBLE (b) || b->drouter != b->router_id))
  403.     return NULL;
  404.   else if (a == NULL || ! IS_ELIGIBLE (a) || a->drouter != a->router_id)
  405.     return b;
  406.   else if (b == NULL || ! IS_ELIGIBLE (b) || b->drouter != b->router_id)
  407.     return a;
  408.   if (a->drouter == a->router_id && b->drouter != b->router_id)
  409.     return a;
  410.   if (a->drouter != a->router_id && b->drouter == b->router_id)
  411.     return b;
  412.   if (a->priority > b->priority)
  413.     return a;
  414.   if (a->priority < b->priority)
  415.     return b;
  416.   if (ntohl (a->router_id) > ntohl (b->router_id))
  417.     return a;
  418.   if (ntohl (a->router_id) < ntohl (b->router_id))
  419.     return b;
  420.   zlog_warn ("Router-ID duplicate ?");
  421.   return a;
  422. }
  423. static u_char
  424. dr_election (struct ospf6_interface *oi)
  425. {
  426.   listnode i;
  427.   struct ospf6_neighbor *on, *drouter, *bdrouter, myself;
  428.   struct ospf6_neighbor *best_drouter, *best_bdrouter;
  429.   u_char next_state = 0;
  430.   drouter = bdrouter = NULL;
  431.   best_drouter = best_bdrouter = NULL;
  432.   /* pseudo neighbor myself, including noting current DR/BDR (1) */
  433.   memset (&myself, 0, sizeof (myself));
  434.   inet_ntop (AF_INET, &oi->area->ospf6->router_id, myself.name,
  435.              sizeof (myself.name));
  436.   myself.state = OSPF6_NEIGHBOR_TWOWAY;
  437.   myself.drouter = oi->drouter;
  438.   myself.bdrouter = oi->bdrouter;
  439.   myself.priority = oi->priority;
  440.   myself.router_id = oi->area->ospf6->router_id;
  441.   /* Electing BDR (2) */
  442.   for (i = listhead (oi->neighbor_list); i; nextnode (i))
  443.     {
  444.       on = (struct ospf6_neighbor *) getdata (i);
  445.       bdrouter = better_bdrouter (bdrouter, on);
  446.     }
  447.   best_bdrouter = bdrouter;
  448.   bdrouter = better_bdrouter (best_bdrouter, &myself);
  449.   /* Electing DR (3) */
  450.   for (i = listhead (oi->neighbor_list); i; nextnode (i))
  451.     {
  452.       on = (struct ospf6_neighbor *) getdata (i);
  453.       drouter = better_drouter (drouter, on);
  454.     }
  455.   best_drouter = drouter;
  456.   drouter = better_drouter (best_drouter, &myself);
  457.   if (drouter == NULL)
  458.     drouter = bdrouter;
  459.   /* the router itself is newly/no longer DR/BDR (4) */
  460.   if ((drouter == &myself && myself.drouter != myself.router_id) ||
  461.       (drouter != &myself && myself.drouter == myself.router_id) ||
  462.       (bdrouter == &myself && myself.bdrouter != myself.router_id) ||
  463.       (bdrouter != &myself && myself.bdrouter == myself.router_id))
  464.     {
  465.       myself.drouter = (drouter ? drouter->router_id : htonl (0));
  466.       myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl (0));
  467.       /* compatible to Electing BDR (2) */
  468.       bdrouter = better_bdrouter (best_bdrouter, &myself);
  469.       /* compatible to Electing DR (3) */
  470.       drouter = better_drouter (best_drouter, &myself);
  471.       if (drouter == NULL)
  472.         drouter = bdrouter;
  473.     }
  474.   /* Set interface state accordingly (5) */
  475.   if (drouter && drouter == &myself)
  476.     next_state = OSPF6_INTERFACE_DR;
  477.   else if (bdrouter && bdrouter == &myself)
  478.     next_state = OSPF6_INTERFACE_BDR;
  479.   else
  480.     next_state = OSPF6_INTERFACE_DROTHER;
  481.   /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
  482.   /* XXX */
  483.   /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
  484.   /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
  485.      accordingly after AdjOK */
  486.   if (oi->drouter != (drouter ? drouter->router_id : htonl (0)) ||
  487.       oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl (0)))
  488.     {
  489.       if (IS_OSPF6_DEBUG_INTERFACE)
  490.         zlog_info ("DR Election on %s: DR: %s BDR: %s", oi->interface->name,
  491.                    (drouter ? drouter->name : "0.0.0.0"),
  492.                    (bdrouter ? bdrouter->name : "0.0.0.0"));
  493.       for (i = listhead (oi->neighbor_list); i; nextnode (i))
  494.         {
  495.           on = (struct ospf6_neighbor *) getdata (i);
  496.           if (on->state < OSPF6_NEIGHBOR_TWOWAY)
  497.             continue;
  498.           /* Schedule AdjOK. */
  499.           thread_add_event (master, adj_ok, on, 0);
  500.         }
  501.     }
  502.   oi->drouter = (drouter ? drouter->router_id : htonl (0));
  503.   oi->bdrouter = (bdrouter ? bdrouter->router_id : htonl (0));
  504.   return next_state;
  505. }
  506. /* Interface State Machine */
  507. int
  508. interface_up (struct thread *thread)
  509. {
  510.   struct ospf6_interface *oi;
  511.   oi = (struct ospf6_interface *) THREAD_ARG (thread);
  512.   assert (oi && oi->interface);
  513.   if (IS_OSPF6_DEBUG_INTERFACE)
  514.     zlog_info ("Interface Event %s: [InterfaceUp]",
  515.                oi->interface->name);
  516.   /* check physical interface is up */
  517.   if (! if_is_up (oi->interface))
  518.     {
  519.       if (IS_OSPF6_DEBUG_INTERFACE)
  520.         zlog_info ("Interface %s is down, can't execute [InterfaceUp]",
  521.                    oi->interface->name);
  522.       return 0;
  523.     }
  524.   /* if already enabled, do nothing */
  525.   if (oi->state > OSPF6_INTERFACE_DOWN)
  526.     {
  527.       if (IS_OSPF6_DEBUG_INTERFACE)
  528.         zlog_info ("Interface %s already enabled",
  529.                    oi->interface->name);
  530.       return 0;
  531.     }
  532.   /* Join AllSPFRouters */
  533.   ospf6_join_allspfrouters (oi->interface->ifindex);
  534.   /* Update interface route */
  535.   ospf6_interface_connected_route_update (oi->interface);
  536.   /* Schedule Hello */
  537.   if (! CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
  538.     thread_add_event (master, ospf6_hello_send, oi, 0);
  539.   /* decide next interface state */
  540.   if (if_is_pointopoint (oi->interface))
  541.     ospf6_interface_state_change (OSPF6_INTERFACE_POINTTOPOINT, oi);
  542.   else if (oi->priority == 0)
  543.     ospf6_interface_state_change (OSPF6_INTERFACE_DROTHER, oi);
  544.   else
  545.     {
  546.       ospf6_interface_state_change (OSPF6_INTERFACE_WAITING, oi);
  547.       thread_add_timer (master, wait_timer, oi, oi->dead_interval);
  548.     }
  549.   return 0;
  550. }
  551. int
  552. wait_timer (struct thread *thread)
  553. {
  554.   struct ospf6_interface *oi;
  555.   oi = (struct ospf6_interface *) THREAD_ARG (thread);
  556.   assert (oi && oi->interface);
  557.   if (IS_OSPF6_DEBUG_INTERFACE)
  558.     zlog_info ("Interface Event %s: [WaitTimer]",
  559.                oi->interface->name);
  560.   if (oi->state == OSPF6_INTERFACE_WAITING)
  561.     ospf6_interface_state_change (dr_election (oi), oi);
  562.   return 0;
  563. }
  564. int
  565. backup_seen (struct thread *thread)
  566. {
  567.   struct ospf6_interface *oi;
  568.   oi = (struct ospf6_interface *) THREAD_ARG (thread);
  569.   assert (oi && oi->interface);
  570.   if (IS_OSPF6_DEBUG_INTERFACE)
  571.     zlog_info ("Interface Event %s: [BackupSeen]",
  572.                oi->interface->name);
  573.   if (oi->state == OSPF6_INTERFACE_WAITING)
  574.     ospf6_interface_state_change (dr_election (oi), oi);
  575.   return 0;
  576. }
  577. int
  578. neighbor_change (struct thread *thread)
  579. {
  580.   struct ospf6_interface *oi;
  581.   oi = (struct ospf6_interface *) THREAD_ARG (thread);
  582.   assert (oi && oi->interface);
  583.   if (IS_OSPF6_DEBUG_INTERFACE)
  584.     zlog_info ("Interface Event %s: [NeighborChange]",
  585.                oi->interface->name);
  586.   if (oi->state == OSPF6_INTERFACE_DROTHER ||
  587.       oi->state == OSPF6_INTERFACE_BDR ||
  588.       oi->state == OSPF6_INTERFACE_DR)
  589.     ospf6_interface_state_change (dr_election (oi), oi);
  590.   return 0;
  591. }
  592. int
  593. loopind (struct thread *thread)
  594. {
  595.   struct ospf6_interface *oi;
  596.   oi = (struct ospf6_interface *) THREAD_ARG (thread);
  597.   assert (oi && oi->interface);
  598.   if (IS_OSPF6_DEBUG_INTERFACE)
  599.     zlog_info ("Interface Event %s: [LoopInd]",
  600.                oi->interface->name);
  601.   /* XXX not yet */
  602.   return 0;
  603. }
  604. int
  605. interface_down (struct thread *thread)
  606. {
  607.   struct ospf6_interface *oi;
  608.   listnode n;
  609.   struct ospf6_neighbor *on;
  610.   oi = (struct ospf6_interface *) THREAD_ARG (thread);
  611.   assert (oi && oi->interface);
  612.   if (IS_OSPF6_DEBUG_INTERFACE)
  613.     zlog_info ("Interface Event %s: [InterfaceDown]",
  614.                oi->interface->name);
  615.   /* Leave AllSPFRouters */
  616.   if (oi->state > OSPF6_INTERFACE_DOWN)
  617.     ospf6_leave_allspfrouters (oi->interface->ifindex);
  618.   ospf6_interface_state_change (OSPF6_INTERFACE_DOWN, oi);
  619.   for (n = listhead (oi->neighbor_list); n; nextnode (n))
  620.     {
  621.       on = (struct ospf6_neighbor *) getdata (n);
  622.       ospf6_neighbor_delete (on);
  623.     }
  624.   list_delete_all_node (oi->neighbor_list);
  625.   return 0;
  626. }
  627. /* show specified interface structure */
  628. int
  629. ospf6_interface_show (struct vty *vty, struct interface *ifp)
  630. {
  631.   struct ospf6_interface *oi;
  632.   struct connected *c;
  633.   struct prefix *p;
  634.   listnode i;
  635.   char strbuf[64], drouter[32], bdrouter[32];
  636.   char *updown[3] = {"down", "up", NULL};
  637.   char *type;
  638.   struct timeval res, now;
  639.   char duration[32];
  640.   struct ospf6_lsa *lsa;
  641.   /* check physical interface type */
  642.   if (if_is_loopback (ifp))
  643.     type = "LOOPBACK";
  644.   else if (if_is_broadcast (ifp))
  645.     type = "BROADCAST";
  646.   else if (if_is_pointopoint (ifp))
  647.     type = "POINTOPOINT";
  648.   else
  649.     type = "UNKNOWN";
  650.   vty_out (vty, "%s is %s, type %s%s",
  651.            ifp->name, updown[if_is_up (ifp)], type,
  652.    VNL);
  653.   vty_out (vty, "  Interface ID: %d%s", ifp->ifindex, VNL);
  654.   if (ifp->info == NULL)
  655.     {
  656.       vty_out (vty, "   OSPF not enabled on this interface%s", VNL);
  657.       return 0;
  658.     }
  659.   else
  660.     oi = (struct ospf6_interface *) ifp->info;
  661.   vty_out (vty, "  Internet Address:%s", VNL);
  662.   for (i = listhead (ifp->connected); i; nextnode (i))
  663.     {
  664.       c = (struct connected *)getdata (i);
  665.       p = c->address;
  666.       prefix2str (p, strbuf, sizeof (strbuf));
  667.       switch (p->family)
  668.         {
  669.         case AF_INET:
  670.           vty_out (vty, "    inet : %s%s", strbuf,
  671.    VNL);
  672.           break;
  673.         case AF_INET6:
  674.           vty_out (vty, "    inet6: %s%s", strbuf,
  675.    VNL);
  676.           break;
  677.         default:
  678.           vty_out (vty, "    ???  : %s%s", strbuf,
  679.    VNL);
  680.           break;
  681.         }
  682.     }
  683.   if (oi->area)
  684.     {
  685.       vty_out (vty, "  Instance ID %d, Interface MTU %d (autodetect: %d)%s",
  686.        oi->instance_id, oi->ifmtu, ifp->mtu, VNL);
  687.       inet_ntop (AF_INET, &oi->area->area_id,
  688.                  strbuf, sizeof (strbuf));
  689.       vty_out (vty, "  Area ID %s, Cost %hu%s", strbuf, oi->cost,
  690.        VNL);
  691.     }
  692.   else
  693.     vty_out (vty, "  Not Attached to Area%s", VNL);
  694.   vty_out (vty, "  State %s, Transmit Delay %d sec, Priority %d%s",
  695.            ospf6_interface_state_str[oi->state],
  696.            oi->transdelay, oi->priority,
  697.    VNL);
  698.   vty_out (vty, "  Timer intervals configured:%s", VNL);
  699.   vty_out (vty, "   Hello %d, Dead %d, Retransmit %d%s",
  700.            oi->hello_interval, oi->dead_interval, oi->rxmt_interval,
  701.    VNL);
  702.   inet_ntop (AF_INET, &oi->drouter, drouter, sizeof (drouter));
  703.   inet_ntop (AF_INET, &oi->bdrouter, bdrouter, sizeof (bdrouter));
  704.   vty_out (vty, "  DR: %s BDR: %s%s", drouter, bdrouter, VNL);
  705.   vty_out (vty, "  Number of I/F scoped LSAs is %u%s",
  706.            oi->lsdb->count, VNL);
  707.   gettimeofday (&now, (struct timezone *) NULL);
  708.   timerclear (&res);
  709.   if (oi->thread_send_lsupdate)
  710.     timersub (&oi->thread_send_lsupdate->u.sands, &now, &res);
  711.   timerstring (&res, duration, sizeof (duration));
  712.   vty_out (vty, "    %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
  713.            oi->lsupdate_list->count, duration,
  714.            (oi->thread_send_lsupdate ? "on" : "off"),
  715.            VNL);
  716.   for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
  717.        lsa = ospf6_lsdb_next (lsa))
  718.     vty_out (vty, "      %s%s", lsa->name, VNL);
  719.   timerclear (&res);
  720.   if (oi->thread_send_lsack)
  721.     timersub (&oi->thread_send_lsack->u.sands, &now, &res);
  722.   timerstring (&res, duration, sizeof (duration));
  723.   vty_out (vty, "    %d Pending LSAs for LSAck in Time %s [thread %s]%s",
  724.            oi->lsack_list->count, duration,
  725.            (oi->thread_send_lsack ? "on" : "off"),
  726.            VNL);
  727.   for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
  728.        lsa = ospf6_lsdb_next (lsa))
  729.     vty_out (vty, "      %s%s", lsa->name, VNL);
  730.   return 0;
  731. }
  732. /* show interface */
  733. DEFUN (show_ipv6_ospf6_interface,
  734.        show_ipv6_ospf6_interface_ifname_cmd,
  735.        "show ipv6 ospf6 interface IFNAME",
  736.        SHOW_STR
  737.        IP6_STR
  738.        OSPF6_STR
  739.        INTERFACE_STR
  740.        IFNAME_STR
  741.        )
  742. {
  743.   struct interface *ifp;
  744.   listnode i;
  745.   if (argc)
  746.     {
  747.       ifp = if_lookup_by_name (argv[0]);
  748.       if (ifp == NULL)
  749.         {
  750.           vty_out (vty, "No such Interface: %s%s", argv[0],
  751.                    VNL);
  752.           return CMD_WARNING;
  753.         }
  754.       ospf6_interface_show (vty, ifp);
  755.     }
  756.   else
  757.     {
  758.       for (i = listhead (iflist); i; nextnode (i))
  759.         {
  760.           ifp = (struct interface *) getdata (i);
  761.           ospf6_interface_show (vty, ifp);
  762.         }
  763.     }
  764.   return CMD_SUCCESS;
  765. }
  766. ALIAS (show_ipv6_ospf6_interface,
  767.        show_ipv6_ospf6_interface_cmd,
  768.        "show ipv6 ospf6 interface",
  769.        SHOW_STR
  770.        IP6_STR
  771.        OSPF6_STR
  772.        INTERFACE_STR
  773.        );
  774. DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
  775.        show_ipv6_ospf6_interface_ifname_prefix_cmd,
  776.        "show ipv6 ospf6 interface IFNAME prefix",
  777.        SHOW_STR
  778.        IP6_STR
  779.        OSPF6_STR
  780.        INTERFACE_STR
  781.        IFNAME_STR
  782.        "Display connected prefixes to advertisen"
  783.        )
  784. {
  785.   struct interface *ifp;
  786.   struct ospf6_interface *oi;
  787.   ifp = if_lookup_by_name (argv[0]);
  788.   if (ifp == NULL)
  789.     {
  790.       vty_out (vty, "No such Interface: %s%s", argv[0], VNL);
  791.       return CMD_WARNING;
  792.     }
  793.   oi = ifp->info;
  794.   if (oi == NULL)
  795.     {
  796.       vty_out (vty, "OSPFv3 is not enabled on %s%s", argv[0], VNL);
  797.       return CMD_WARNING;
  798.     }
  799.   argc--;
  800.   argv++;
  801.   ospf6_route_table_show (vty, argc, argv, oi->route_connected);
  802.   return CMD_SUCCESS;
  803. }
  804. ALIAS (show_ipv6_ospf6_interface_ifname_prefix,
  805.        show_ipv6_ospf6_interface_ifname_prefix_detail_cmd,
  806.        "show ipv6 ospf6 interface IFNAME prefix (X:X::X:X|X:X::X:X/M|detail)",
  807.        SHOW_STR
  808.        IP6_STR
  809.        OSPF6_STR
  810.        INTERFACE_STR
  811.        IFNAME_STR
  812.        "Display connected prefixes to advertisen"
  813.        OSPF6_ROUTE_ADDRESS_STR
  814.        OSPF6_ROUTE_PREFIX_STR
  815.        "Dispaly details of the prefixesn"
  816.        );
  817. ALIAS (show_ipv6_ospf6_interface_ifname_prefix,
  818.        show_ipv6_ospf6_interface_ifname_prefix_match_cmd,
  819.        "show ipv6 ospf6 interface IFNAME prefix X:X::X:X/M (match|detail)",
  820.        SHOW_STR
  821.        IP6_STR
  822.        OSPF6_STR
  823.        INTERFACE_STR
  824.        IFNAME_STR
  825.        "Display connected prefixes to advertisen"
  826.        OSPF6_ROUTE_PREFIX_STR
  827.        OSPF6_ROUTE_MATCH_STR
  828.        "Dispaly details of the prefixesn"
  829.        );
  830. DEFUN (show_ipv6_ospf6_interface_prefix,
  831.        show_ipv6_ospf6_interface_prefix_cmd,
  832.        "show ipv6 ospf6 interface prefix",
  833.        SHOW_STR
  834.        IP6_STR
  835.        OSPF6_STR
  836.        INTERFACE_STR
  837.        "Display connected prefixes to advertisen"
  838.        )
  839. {
  840.   listnode i;
  841.   struct ospf6_interface *oi;
  842.   struct interface *ifp;
  843.   for (i = listhead (iflist); i; nextnode (i))
  844.     {
  845.       ifp = (struct interface *) getdata (i);
  846.       oi = (struct ospf6_interface *) ifp->info;
  847.       if (oi == NULL)
  848.         continue;
  849.       ospf6_route_table_show (vty, argc, argv, oi->route_connected);
  850.     }
  851.   return CMD_SUCCESS;
  852. }
  853. ALIAS (show_ipv6_ospf6_interface_prefix,
  854.        show_ipv6_ospf6_interface_prefix_detail_cmd,
  855.        "show ipv6 ospf6 interface prefix (X:X::X:X|X:X::X:X/M|detail)",
  856.        SHOW_STR
  857.        IP6_STR
  858.        OSPF6_STR
  859.        INTERFACE_STR
  860.        "Display connected prefixes to advertisen"
  861.        OSPF6_ROUTE_ADDRESS_STR
  862.        OSPF6_ROUTE_PREFIX_STR
  863.        "Dispaly details of the prefixesn"
  864.        );
  865. ALIAS (show_ipv6_ospf6_interface_prefix,
  866.        show_ipv6_ospf6_interface_prefix_match_cmd,
  867.        "show ipv6 ospf6 interface prefix X:X::X:X/M (match|detail)",
  868.        SHOW_STR
  869.        IP6_STR
  870.        OSPF6_STR
  871.        INTERFACE_STR
  872.        "Display connected prefixes to advertisen"
  873.        OSPF6_ROUTE_PREFIX_STR
  874.        OSPF6_ROUTE_MATCH_STR
  875.        "Dispaly details of the prefixesn"
  876.        );
  877. /* interface variable set command */
  878. DEFUN (ipv6_ospf6_ifmtu,
  879.        ipv6_ospf6_ifmtu_cmd,
  880.        "ipv6 ospf6 ifmtu <1-65535>",
  881.        IP6_STR
  882.        OSPF6_STR
  883.        "Interface MTUn"
  884.        "OSPFv3 Interface MTUn"
  885.        )
  886. {
  887.   struct ospf6_interface *oi;
  888.   struct interface *ifp;
  889.   int ifmtu, iobuflen;
  890.   listnode node;
  891.   struct ospf6_neighbor *on;
  892.   ifp = (struct interface *) vty->index;
  893.   assert (ifp);
  894.   oi = (struct ospf6_interface *) ifp->info;
  895.   if (oi == NULL)
  896.     oi = ospf6_interface_create (ifp);
  897.   assert (oi);
  898.   ifmtu = strtol (argv[0], NULL, 10);
  899.   if (oi->ifmtu == ifmtu)
  900.     return CMD_SUCCESS;
  901.   if (ifp->mtu != 0 && ifp->mtu < ifmtu)
  902.     {
  903.       vty_out (vty, "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)%s",
  904.                ifp->name, ifp->mtu, VNL);
  905.       return CMD_WARNING;
  906.     }
  907.   if (oi->ifmtu < ifmtu)
  908.     {
  909.       iobuflen = ospf6_iobuf_size (ifmtu);
  910.       if (iobuflen < ifmtu)
  911.         {
  912.           vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
  913.                    ifp->name, iobuflen, VNL);
  914.           oi->ifmtu = iobuflen;
  915.         }
  916.       else
  917.         oi->ifmtu = ifmtu;
  918.     }
  919.   else
  920.     oi->ifmtu = ifmtu;
  921.   /* re-establish adjacencies */
  922.   for (node = listhead (oi->neighbor_list); node; nextnode (node))
  923.     {
  924.       on = (struct ospf6_neighbor *) getdata (node);
  925.       THREAD_OFF (on->inactivity_timer);
  926.       thread_add_event (master, inactivity_timer, on, 0);
  927.     }
  928.   return CMD_SUCCESS;
  929. }
  930. DEFUN (no_ipv6_ospf6_ifmtu,
  931.        no_ipv6_ospf6_ifmtu_cmd,
  932.        "no ipv6 ospf6 ifmtu",
  933.        NO_STR
  934.        IP6_STR
  935.        OSPF6_STR
  936.        "Interface MTUn"
  937.        )
  938. {
  939.   struct ospf6_interface *oi;
  940.   struct interface *ifp;
  941.   int iobuflen;
  942.   listnode node;
  943.   struct ospf6_neighbor *on;
  944.   ifp = (struct interface *) vty->index;
  945.   assert (ifp);
  946.   oi = (struct ospf6_interface *) ifp->info;
  947.   if (oi == NULL)
  948.     oi = ospf6_interface_create (ifp);
  949.   assert (oi);
  950.   if (oi->ifmtu < ifp->mtu)
  951.     {
  952.       iobuflen = ospf6_iobuf_size (ifp->mtu);
  953.       if (iobuflen < ifp->mtu)
  954.         {
  955.           vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
  956.                    ifp->name, iobuflen, VNL);
  957.           oi->ifmtu = iobuflen;
  958.         }
  959.       else
  960.         oi->ifmtu = ifp->mtu;
  961.     }
  962.   else
  963.     oi->ifmtu = ifp->mtu;
  964.   /* re-establish adjacencies */
  965.   for (node = listhead (oi->neighbor_list); node; nextnode (node))
  966.     {
  967.       on = (struct ospf6_neighbor *) getdata (node);
  968.       THREAD_OFF (on->inactivity_timer);
  969.       thread_add_event (master, inactivity_timer, on, 0);
  970.     }
  971.   return CMD_SUCCESS;
  972. }
  973. DEFUN (ipv6_ospf6_cost,
  974.        ipv6_ospf6_cost_cmd,
  975.        "ipv6 ospf6 cost <1-65535>",
  976.        IP6_STR
  977.        OSPF6_STR
  978.        "Interface costn"
  979.        "Outgoing metric of this interfacen"
  980.        )
  981. {
  982.   struct ospf6_interface *oi;
  983.   struct interface *ifp;
  984.   ifp = (struct interface *) vty->index;
  985.   assert (ifp);
  986.   oi = (struct ospf6_interface *) ifp->info;
  987.   if (oi == NULL)
  988.     oi = ospf6_interface_create (ifp);
  989.   assert (oi);
  990.   if (oi->cost == strtol (argv[0], NULL, 10))
  991.     return CMD_SUCCESS;
  992.   oi->cost = strtol (argv[0], NULL, 10);
  993.   /* update cost held in route_connected list in ospf6_interface */
  994.   ospf6_interface_connected_route_update (oi->interface);
  995.   /* execute LSA hooks */
  996.   if (oi->area)
  997.     {
  998.       OSPF6_LINK_LSA_SCHEDULE (oi);
  999.       OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
  1000.       OSPF6_NETWORK_LSA_SCHEDULE (oi);
  1001.       OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
  1002.       OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
  1003.     }
  1004.   return CMD_SUCCESS;
  1005. }
  1006. DEFUN (ipv6_ospf6_hellointerval,
  1007.        ipv6_ospf6_hellointerval_cmd,
  1008.        "ipv6 ospf6 hello-interval <1-65535>",
  1009.        IP6_STR
  1010.        OSPF6_STR
  1011.        "Interval time of Hello packetsn"
  1012.        SECONDS_STR
  1013.        )
  1014. {
  1015.   struct ospf6_interface *oi;
  1016.   struct interface *ifp;
  1017.   ifp = (struct interface *) vty->index;
  1018.   assert (ifp);
  1019.   oi = (struct ospf6_interface *) ifp->info;
  1020.   if (oi == NULL)
  1021.     oi = ospf6_interface_create (ifp);
  1022.   assert (oi);
  1023.   oi->hello_interval = strtol (argv[0], NULL, 10);
  1024.   return CMD_SUCCESS;
  1025. }
  1026. /* interface variable set command */
  1027. DEFUN (ipv6_ospf6_deadinterval,
  1028.        ipv6_ospf6_deadinterval_cmd,
  1029.        "ipv6 ospf6 dead-interval <1-65535>",
  1030.        IP6_STR
  1031.        OSPF6_STR
  1032.        "Interval time after which a neighbor is declared downn"
  1033.        SECONDS_STR
  1034.        )
  1035. {
  1036.   struct ospf6_interface *oi;
  1037.   struct interface *ifp;
  1038.   ifp = (struct interface *) vty->index;
  1039.   assert (ifp);
  1040.   oi = (struct ospf6_interface *) ifp->info;
  1041.   if (oi == NULL)
  1042.     oi = ospf6_interface_create (ifp);
  1043.   assert (oi);
  1044.   oi->dead_interval = strtol (argv[0], NULL, 10);
  1045.   return CMD_SUCCESS;
  1046. }
  1047. /* interface variable set command */
  1048. DEFUN (ipv6_ospf6_transmitdelay,
  1049.        ipv6_ospf6_transmitdelay_cmd,
  1050.        "ipv6 ospf6 transmit-delay <1-3600>",
  1051.        IP6_STR
  1052.        OSPF6_STR
  1053.        "Transmit delay of this interfacen"
  1054.        SECONDS_STR
  1055.        )
  1056. {
  1057.   struct ospf6_interface *oi;
  1058.   struct interface *ifp;
  1059.   ifp = (struct interface *) vty->index;
  1060.   assert (ifp);
  1061.   oi = (struct ospf6_interface *) ifp->info;
  1062.   if (oi == NULL)
  1063.     oi = ospf6_interface_create (ifp);
  1064.   assert (oi);
  1065.   oi->transdelay = strtol (argv[0], NULL, 10);
  1066.   return CMD_SUCCESS;
  1067. }
  1068. /* interface variable set command */
  1069. DEFUN (ipv6_ospf6_retransmitinterval,
  1070.        ipv6_ospf6_retransmitinterval_cmd,
  1071.        "ipv6 ospf6 retransmit-interval <1-65535>",
  1072.        IP6_STR
  1073.        OSPF6_STR
  1074.        "Time between retransmitting lost link state advertisementsn"
  1075.        SECONDS_STR
  1076.        )
  1077. {
  1078.   struct ospf6_interface *oi;
  1079.   struct interface *ifp;
  1080.   ifp = (struct interface *) vty->index;
  1081.   assert (ifp);
  1082.   oi = (struct ospf6_interface *) ifp->info;
  1083.   if (oi == NULL)
  1084.     oi = ospf6_interface_create (ifp);
  1085.   assert (oi);
  1086.   oi->rxmt_interval = strtol (argv[0], NULL, 10);
  1087.   return CMD_SUCCESS;
  1088. }
  1089. /* interface variable set command */
  1090. DEFUN (ipv6_ospf6_priority,
  1091.        ipv6_ospf6_priority_cmd,
  1092.        "ipv6 ospf6 priority <0-255>",
  1093.        IP6_STR
  1094.        OSPF6_STR
  1095.        "Router priorityn"
  1096.        "Priority valuen"
  1097.        )
  1098. {
  1099.   struct ospf6_interface *oi;
  1100.   struct interface *ifp;
  1101.   ifp = (struct interface *) vty->index;
  1102.   assert (ifp);
  1103.   oi = (struct ospf6_interface *) ifp->info;
  1104.   if (oi == NULL)
  1105.     oi = ospf6_interface_create (ifp);
  1106.   assert (oi);
  1107.   oi->priority = strtol (argv[0], NULL, 10);
  1108.   if (oi->area)
  1109.     ospf6_interface_state_change (dr_election (oi), oi);
  1110.   return CMD_SUCCESS;
  1111. }
  1112. DEFUN (ipv6_ospf6_instance,
  1113.        ipv6_ospf6_instance_cmd,
  1114.        "ipv6 ospf6 instance-id <0-255>",
  1115.        IP6_STR
  1116.        OSPF6_STR
  1117.        "Instance ID for this interfacen"
  1118.        "Instance ID valuen"
  1119.        )
  1120. {
  1121.   struct ospf6_interface *oi;
  1122.   struct interface *ifp;
  1123.   ifp = (struct interface *)vty->index;
  1124.   assert (ifp);
  1125.   oi = (struct ospf6_interface *)ifp->info;
  1126.   if (oi == NULL)
  1127.     oi = ospf6_interface_create (ifp);
  1128.   assert (oi);
  1129.   oi->instance_id = strtol (argv[0], NULL, 10);
  1130.   return CMD_SUCCESS;
  1131. }
  1132. DEFUN (ipv6_ospf6_passive,
  1133.        ipv6_ospf6_passive_cmd,
  1134.        "ipv6 ospf6 passive",
  1135.        IP6_STR
  1136.        OSPF6_STR
  1137.        "passive interface, No adjacency will be formed on this interfacen"
  1138.        )
  1139. {
  1140.   struct ospf6_interface *oi;
  1141.   struct interface *ifp;
  1142.   listnode node;
  1143.   struct ospf6_neighbor *on;
  1144.   ifp = (struct interface *) vty->index;
  1145.   assert (ifp);
  1146.   oi = (struct ospf6_interface *) ifp->info;
  1147.   if (oi == NULL)
  1148.     oi = ospf6_interface_create (ifp);
  1149.   assert (oi);
  1150.   SET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE);
  1151.   THREAD_OFF (oi->thread_send_hello);
  1152.   for (node = listhead (oi->neighbor_list); node; nextnode (node))
  1153.     {
  1154.       on = (struct ospf6_neighbor *) getdata (node);
  1155.       THREAD_OFF (on->inactivity_timer);
  1156.       thread_add_event (master, inactivity_timer, on, 0);
  1157.     }
  1158.   return CMD_SUCCESS;
  1159. }
  1160. DEFUN (no_ipv6_ospf6_passive,
  1161.        no_ipv6_ospf6_passive_cmd,
  1162.        "no ipv6 ospf6 passive",
  1163.        NO_STR
  1164.        IP6_STR
  1165.        OSPF6_STR
  1166.        "passive interface: No Adjacency will be formed on this I/Fn"
  1167.        )
  1168. {
  1169.   struct ospf6_interface *oi;
  1170.   struct interface *ifp;
  1171.   ifp = (struct interface *) vty->index;
  1172.   assert (ifp);
  1173.   oi = (struct ospf6_interface *) ifp->info;
  1174.   if (oi == NULL)
  1175.     oi = ospf6_interface_create (ifp);
  1176.   assert (oi);
  1177.   UNSET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE);
  1178.   THREAD_OFF (oi->thread_send_hello);
  1179.   oi->thread_send_hello =
  1180.     thread_add_event (master, ospf6_hello_send, oi, 0);
  1181.   return CMD_SUCCESS;
  1182. }
  1183. DEFUN (ipv6_ospf6_advertise_prefix_list,
  1184.        ipv6_ospf6_advertise_prefix_list_cmd,
  1185.        "ipv6 ospf6 advertise prefix-list WORD",
  1186.        IP6_STR
  1187.        OSPF6_STR
  1188.        "Advertising optionsn"
  1189.        "Filter prefix using prefix-listn"
  1190.        "Prefix list namen"
  1191.        )
  1192. {
  1193.   struct ospf6_interface *oi;
  1194.   struct interface *ifp;
  1195.   ifp = (struct interface *) vty->index;
  1196.   assert (ifp);
  1197.   oi = (struct ospf6_interface *) ifp->info;
  1198.   if (oi == NULL)
  1199.     oi = ospf6_interface_create (ifp);
  1200.   assert (oi);
  1201.   if (oi->plist_name)
  1202.     XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name);
  1203.   oi->plist_name = XSTRDUP (MTYPE_PREFIX_LIST_STR, argv[0]);
  1204.   ospf6_interface_connected_route_update (oi->interface);
  1205.   OSPF6_LINK_LSA_SCHEDULE (oi);
  1206.   if (oi->state == OSPF6_INTERFACE_DR)
  1207.     {
  1208.       OSPF6_NETWORK_LSA_SCHEDULE (oi);
  1209.       OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
  1210.     }
  1211.   OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
  1212.   return CMD_SUCCESS;
  1213. }
  1214. DEFUN (no_ipv6_ospf6_advertise_prefix_list,
  1215.        no_ipv6_ospf6_advertise_prefix_list_cmd,
  1216.        "no ipv6 ospf6 advertise prefix-list",
  1217.        NO_STR
  1218.        IP6_STR
  1219.        OSPF6_STR
  1220.        "Advertising optionsn"
  1221.        "Filter prefix using prefix-listn"
  1222.        )
  1223. {
  1224.   struct ospf6_interface *oi;
  1225.   struct interface *ifp;
  1226.   ifp = (struct interface *) vty->index;
  1227.   assert (ifp);
  1228.   oi = (struct ospf6_interface *) ifp->info;
  1229.   if (oi == NULL)
  1230.     oi = ospf6_interface_create (ifp);
  1231.   assert (oi);
  1232.   if (oi->plist_name)
  1233.     {
  1234.       XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name);
  1235.       oi->plist_name = NULL;
  1236.     }
  1237.   ospf6_interface_connected_route_update (oi->interface);
  1238.   OSPF6_LINK_LSA_SCHEDULE (oi);
  1239.   if (oi->state == OSPF6_INTERFACE_DR)
  1240.     {
  1241.       OSPF6_NETWORK_LSA_SCHEDULE (oi);
  1242.       OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
  1243.     }
  1244.   OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
  1245.   return CMD_SUCCESS;
  1246. }
  1247. int
  1248. config_write_ospf6_interface (struct vty *vty)
  1249. {
  1250.   listnode i;
  1251.   struct ospf6_interface *oi;
  1252.   struct interface *ifp;
  1253.   for (i = listhead (iflist); i; nextnode (i))
  1254.     {
  1255.       ifp = (struct interface *) getdata (i);
  1256.       oi = (struct ospf6_interface *) ifp->info;
  1257.       if (oi == NULL)
  1258.         continue;
  1259.       vty_out (vty, "interface %s%s",
  1260.                oi->interface->name, VNL);
  1261.       if (ifp->desc)
  1262.         vty_out (vty, " description %s%s", ifp->desc, VNL);
  1263.       if (ifp->mtu != oi->ifmtu)
  1264.         vty_out (vty, " ipv6 ospf6 ifmtu %d%s", oi->ifmtu, VNL);
  1265.       vty_out (vty, " ipv6 ospf6 cost %d%s",
  1266.                oi->cost, VNL);
  1267.       vty_out (vty, " ipv6 ospf6 hello-interval %d%s",
  1268.                oi->hello_interval, VNL);
  1269.       vty_out (vty, " ipv6 ospf6 dead-interval %d%s",
  1270.                oi->dead_interval, VNL);
  1271.       vty_out (vty, " ipv6 ospf6 retransmit-interval %d%s",
  1272.                oi->rxmt_interval, VNL);
  1273.       vty_out (vty, " ipv6 ospf6 priority %d%s",
  1274.                oi->priority, VNL);
  1275.       vty_out (vty, " ipv6 ospf6 transmit-delay %d%s",
  1276.                oi->transdelay, VNL);
  1277.       vty_out (vty, " ipv6 ospf6 instance-id %d%s",
  1278.                oi->instance_id, VNL);
  1279.       if (oi->plist_name)
  1280.         vty_out (vty, " ipv6 ospf6 advertise prefix-list %s%s",
  1281.                  oi->plist_name, VNL);
  1282.       if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
  1283.         vty_out (vty, " ipv6 ospf6 passive%s", VNL);
  1284.       vty_out (vty, "!%s", VNL);
  1285.     }
  1286.   return 0;
  1287. }
  1288. struct cmd_node interface_node =
  1289. {
  1290.   INTERFACE_NODE,
  1291.   "%s(config-if)# ",
  1292.   1 /* VTYSH */
  1293. };
  1294. void
  1295. ospf6_interface_init ()
  1296. {
  1297.   /* Install interface node. */
  1298.   install_node (&interface_node, config_write_ospf6_interface);
  1299.   install_element (VIEW_NODE, &show_ipv6_ospf6_interface_cmd);
  1300.   install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
  1301.   install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_detail_cmd);
  1302.   install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_match_cmd);
  1303.   install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
  1304.   install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd);
  1305.   install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_detail_cmd);
  1306.   install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_match_cmd);
  1307.   install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_cmd);
  1308.   install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
  1309.   install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_detail_cmd);
  1310.   install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_match_cmd);
  1311.   install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
  1312.   install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd);
  1313.   install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_prefix_detail_cmd);
  1314.   install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_prefix_match_cmd);
  1315.   install_element (CONFIG_NODE, &interface_cmd);
  1316.   install_default (INTERFACE_NODE);
  1317.   install_element (INTERFACE_NODE, &interface_desc_cmd);
  1318.   install_element (INTERFACE_NODE, &no_interface_desc_cmd);
  1319.   install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
  1320.   install_element (INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
  1321.   install_element (INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
  1322.   install_element (INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
  1323.   install_element (INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
  1324.   install_element (INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
  1325.   install_element (INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
  1326.   install_element (INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
  1327.   install_element (INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
  1328.   install_element (INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
  1329.   install_element (INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
  1330.   install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
  1331.   install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_prefix_list_cmd);
  1332. }
  1333. DEFUN (debug_ospf6_interface,
  1334.        debug_ospf6_interface_cmd,
  1335.        "debug ospf6 interface",
  1336.        DEBUG_STR
  1337.        OSPF6_STR
  1338.        "Debug OSPFv3 Interfacen"
  1339.       )
  1340. {
  1341.   OSPF6_DEBUG_INTERFACE_ON ();
  1342.   return CMD_SUCCESS;
  1343. }
  1344. DEFUN (no_debug_ospf6_interface,
  1345.        no_debug_ospf6_interface_cmd,
  1346.        "no debug ospf6 interface",
  1347.        NO_STR
  1348.        DEBUG_STR
  1349.        OSPF6_STR
  1350.        "Debug OSPFv3 Interfacen"
  1351.       )
  1352. {
  1353.   OSPF6_DEBUG_INTERFACE_OFF ();
  1354.   return CMD_SUCCESS;
  1355. }
  1356. int
  1357. config_write_ospf6_debug_interface (struct vty *vty)
  1358. {
  1359.   if (IS_OSPF6_DEBUG_INTERFACE)
  1360.     vty_out (vty, "debug ospf6 interface%s", VNL);
  1361.   return 0;
  1362. }
  1363. void
  1364. install_element_ospf6_debug_interface ()
  1365. {
  1366.   install_element (ENABLE_NODE, &debug_ospf6_interface_cmd);
  1367.   install_element (ENABLE_NODE, &no_debug_ospf6_interface_cmd);
  1368.   install_element (CONFIG_NODE, &debug_ospf6_interface_cmd);
  1369.   install_element (CONFIG_NODE, &no_debug_ospf6_interface_cmd);
  1370. }