File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospf6d / ospf6_interface.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:12 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>