Annotation of embedaddon/quagga/zebra/interface.c, revision 1.1.1.4

1.1       misho       1: /*
                      2:  * Interface function.
                      3:  * Copyright (C) 1997, 1999 Kunihiro Ishiguro
                      4:  *
                      5:  * This file is part of GNU Zebra.
                      6:  *
                      7:  * GNU Zebra is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2, or (at your option) any
                     10:  * later version.
                     11:  *
                     12:  * GNU Zebra is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     15:  * General Public License for more details.
                     16:  *
                     17:  * You should have received a copy of the GNU General Public License
                     18:  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
                     19:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
                     20:  * 02111-1307, USA.  
                     21:  */
                     22: 
                     23: #include <zebra.h>
                     24: 
                     25: #include "if.h"
                     26: #include "vty.h"
                     27: #include "sockunion.h"
                     28: #include "prefix.h"
                     29: #include "command.h"
                     30: #include "memory.h"
                     31: #include "ioctl.h"
                     32: #include "connected.h"
                     33: #include "log.h"
                     34: #include "zclient.h"
1.1.1.4 ! misho      35: #include "vrf.h"
1.1       misho      36: 
                     37: #include "zebra/interface.h"
                     38: #include "zebra/rtadv.h"
                     39: #include "zebra/rib.h"
                     40: #include "zebra/zserv.h"
                     41: #include "zebra/redistribute.h"
                     42: #include "zebra/debug.h"
                     43: #include "zebra/irdp.h"
                     44: 
1.1.1.4 ! misho      45: #if defined (HAVE_RTADV)
1.1       misho      46: /* Order is intentional.  Matches RFC4191.  This array is also used for
                     47:    command matching, so only modify with care. */
                     48: const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
1.1.1.4 ! misho      49: #endif /* HAVE_RTADV */
1.1       misho      50: 
                     51: /* Called when new interface is added. */
                     52: static int
                     53: if_zebra_new_hook (struct interface *ifp)
                     54: {
                     55:   struct zebra_if *zebra_if;
                     56: 
                     57:   zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
                     58: 
                     59:   zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
1.1.1.4 ! misho      60:   zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1.1       misho      61: 
1.1.1.4 ! misho      62: #if defined (HAVE_RTADV)
1.1       misho      63:   {
                     64:     /* Set default router advertise values. */
                     65:     struct rtadvconf *rtadv;
                     66: 
                     67:     rtadv = &zebra_if->rtadv;
                     68: 
                     69:     rtadv->AdvSendAdvertisements = 0;
                     70:     rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
                     71:     rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
                     72:     rtadv->AdvIntervalTimer = 0;
                     73:     rtadv->AdvManagedFlag = 0;
                     74:     rtadv->AdvOtherConfigFlag = 0;
                     75:     rtadv->AdvHomeAgentFlag = 0;
                     76:     rtadv->AdvLinkMTU = 0;
                     77:     rtadv->AdvReachableTime = 0;
                     78:     rtadv->AdvRetransTimer = 0;
                     79:     rtadv->AdvCurHopLimit = 0;
1.1.1.2   misho      80:     rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
1.1       misho      81:     rtadv->HomeAgentPreference = 0;
1.1.1.2   misho      82:     rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
1.1       misho      83:     rtadv->AdvIntervalOption = 0;
                     84:     rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
                     85: 
                     86:     rtadv->AdvPrefixList = list_new ();
                     87:   }    
1.1.1.4 ! misho      88: #endif /* HAVE_RTADV */
1.1       misho      89: 
                     90:   /* Initialize installed address chains tree. */
                     91:   zebra_if->ipv4_subnets = route_table_init ();
                     92: 
                     93:   ifp->info = zebra_if;
                     94:   return 0;
                     95: }
                     96: 
                     97: /* Called when interface is deleted. */
                     98: static int
                     99: if_zebra_delete_hook (struct interface *ifp)
                    100: {
                    101:   struct zebra_if *zebra_if;
                    102:   
                    103:   if (ifp->info)
                    104:     {
                    105:       zebra_if = ifp->info;
                    106: 
                    107:       /* Free installed address chains tree. */
                    108:       if (zebra_if->ipv4_subnets)
                    109:        route_table_finish (zebra_if->ipv4_subnets);
                    110: 
                    111:       XFREE (MTYPE_TMP, zebra_if);
                    112:     }
                    113: 
                    114:   return 0;
                    115: }
                    116: 
                    117: /* Tie an interface address to its derived subnet list of addresses. */
                    118: int
                    119: if_subnet_add (struct interface *ifp, struct connected *ifc)
                    120: {
                    121:   struct route_node *rn;
                    122:   struct zebra_if *zebra_if;
                    123:   struct prefix cp;
                    124:   struct list *addr_list;
                    125: 
                    126:   assert (ifp && ifp->info && ifc);
                    127:   zebra_if = ifp->info;
                    128: 
                    129:   /* Get address derived subnet node and associated address list, while marking
                    130:      address secondary attribute appropriately. */
                    131:   cp = *ifc->address;
                    132:   apply_mask (&cp);
                    133:   rn = route_node_get (zebra_if->ipv4_subnets, &cp);
                    134: 
                    135:   if ((addr_list = rn->info))
                    136:     SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
                    137:   else
                    138:     {
                    139:       UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
                    140:       rn->info = addr_list = list_new ();
                    141:       route_lock_node (rn);
                    142:     }
                    143: 
                    144:   /* Tie address at the tail of address list. */
                    145:   listnode_add (addr_list, ifc);
                    146:   
                    147:   /* Return list element count. */
                    148:   return (addr_list->count);
                    149: }
                    150: 
                    151: /* Untie an interface address from its derived subnet list of addresses. */
                    152: int
                    153: if_subnet_delete (struct interface *ifp, struct connected *ifc)
                    154: {
                    155:   struct route_node *rn;
                    156:   struct zebra_if *zebra_if;
                    157:   struct list *addr_list;
                    158: 
                    159:   assert (ifp && ifp->info && ifc);
                    160:   zebra_if = ifp->info;
                    161: 
                    162:   /* Get address derived subnet node. */
                    163:   rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
                    164:   if (! (rn && rn->info))
1.1.1.4 ! misho     165:     {
        !           166:       zlog_warn("Trying to remove an address from an unknown subnet."
        !           167:                 " (please report this bug)");
        !           168:       return -1;
        !           169:     }
1.1       misho     170:   route_unlock_node (rn);
                    171:   
                    172:   /* Untie address from subnet's address list. */
                    173:   addr_list = rn->info;
1.1.1.4 ! misho     174: 
        !           175:   /* Deleting an address that is not registered is a bug.
        !           176:    * In any case, we shouldn't decrement the lock counter if the address
        !           177:    * is unknown. */
        !           178:   if (!listnode_lookup(addr_list, ifc))
        !           179:     {
        !           180:       zlog_warn("Trying to remove an address from a subnet where it is not"
        !           181:                 " currently registered. (please report this bug)");
        !           182:       return -1;
        !           183:     }
        !           184: 
1.1       misho     185:   listnode_delete (addr_list, ifc);
                    186:   route_unlock_node (rn);
                    187: 
                    188:   /* Return list element count, if not empty. */
                    189:   if (addr_list->count)
                    190:     {
                    191:       /* If deleted address is primary, mark subsequent one as such and distribute. */
                    192:       if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
                    193:        {
                    194:          ifc = listgetdata (listhead (addr_list));
                    195:          zebra_interface_address_delete_update (ifp, ifc);
                    196:          UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1.1.1.4 ! misho     197:          /* XXX: Linux kernel removes all the secondary addresses when the primary
        !           198:           * address is removed. We could try to work around that, though this is
        !           199:           * non-trivial. */
1.1       misho     200:          zebra_interface_address_add_update (ifp, ifc);
                    201:        }
                    202:       
                    203:       return addr_list->count;
                    204:     }
                    205:   
                    206:   /* Otherwise, free list and route node. */
                    207:   list_free (addr_list);
                    208:   rn->info = NULL;
                    209:   route_unlock_node (rn);
                    210: 
                    211:   return 0;
                    212: }
                    213: 
                    214: /* if_flags_mangle: A place for hacks that require mangling
                    215:  * or tweaking the interface flags.
                    216:  *
                    217:  * ******************** Solaris flags hacks **************************
                    218:  *
                    219:  * Solaris IFF_UP flag reflects only the primary interface as the
                    220:  * routing socket only sends IFINFO for the primary interface.  Hence  
                    221:  * ~IFF_UP does not per se imply all the logical interfaces are also   
                    222:  * down - which we only know of as addresses. Instead we must determine
                    223:  * whether the interface really is up or not according to how many   
                    224:  * addresses are still attached. (Solaris always sends RTM_DELADDR if
                    225:  * an interface, logical or not, goes ~IFF_UP).
                    226:  *
                    227:  * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
                    228:  * are addresses left in struct connected, not just the actual underlying
                    229:  * IFF_UP flag.
                    230:  *
                    231:  * We must hence remember the real state of IFF_UP, which we do in
                    232:  * struct zebra_if.primary_state.
                    233:  *
                    234:  * Setting IFF_UP within zebra to administratively shutdown the
                    235:  * interface will affect only the primary interface/address on Solaris.
                    236:  ************************End Solaris flags hacks ***********************
                    237:  */
1.1.1.2   misho     238: static void
1.1       misho     239: if_flags_mangle (struct interface *ifp, uint64_t *newflags)
                    240: {
                    241: #ifdef SUNOS_5
                    242:   struct zebra_if *zif = ifp->info;
                    243:   
                    244:   zif->primary_state = *newflags & (IFF_UP & 0xff);
                    245:   
                    246:   if (CHECK_FLAG (zif->primary_state, IFF_UP)
                    247:       || listcount(ifp->connected) > 0)
                    248:     SET_FLAG (*newflags, IFF_UP);
                    249:   else
                    250:     UNSET_FLAG (*newflags, IFF_UP);
                    251: #endif /* SUNOS_5 */
                    252: }
                    253: 
                    254: /* Update the flags field of the ifp with the new flag set provided.
                    255:  * Take whatever actions are required for any changes in flags we care
                    256:  * about.
                    257:  *
                    258:  * newflags should be the raw value, as obtained from the OS.
                    259:  */
                    260: void
                    261: if_flags_update (struct interface *ifp, uint64_t newflags)
                    262: {
                    263:   if_flags_mangle (ifp, &newflags);
                    264:     
                    265:   if (if_is_operative (ifp))
                    266:     {
                    267:       /* operative -> inoperative? */
                    268:       ifp->flags = newflags;
                    269:       if (!if_is_operative (ifp))
                    270:         if_down (ifp);
                    271:     }
                    272:   else
                    273:     {
                    274:       /* inoperative -> operative? */
                    275:       ifp->flags = newflags;
                    276:       if (if_is_operative (ifp))
                    277:         if_up (ifp);
                    278:     }
                    279: }
                    280: 
                    281: /* Wake up configured address if it is not in current kernel
                    282:    address. */
                    283: static void
                    284: if_addr_wakeup (struct interface *ifp)
                    285: {
                    286:   struct listnode *node, *nnode;
                    287:   struct connected *ifc;
                    288:   struct prefix *p;
                    289:   int ret;
                    290: 
                    291:   for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
                    292:     {
                    293:       p = ifc->address;
                    294:        
                    295:       if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
1.1.1.4 ! misho     296:          && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED))
1.1       misho     297:        {
                    298:          /* Address check. */
                    299:          if (p->family == AF_INET)
                    300:            {
                    301:              if (! if_is_up (ifp))
                    302:                {
1.1.1.4 ! misho     303:                  /* Assume zebra is configured like following:
        !           304:                   *
        !           305:                   *   interface gre0
        !           306:                   *    ip addr 192.0.2.1/24
        !           307:                   *   !
        !           308:                   *
        !           309:                   * As soon as zebra becomes first aware that gre0 exists in the
        !           310:                   * kernel, it will set gre0 up and configure its addresses.
        !           311:                   *
        !           312:                   * (This may happen at startup when the interface already exists
        !           313:                   * or during runtime when the interface is added to the kernel)
        !           314:                   *
        !           315:                   * XXX: IRDP code is calling here via if_add_update - this seems
        !           316:                   * somewhat weird.
        !           317:                   * XXX: RUNNING is not a settable flag on any system
        !           318:                   * I (paulj) am aware of.
        !           319:                  */
1.1       misho     320:                  if_set_flags (ifp, IFF_UP | IFF_RUNNING);
                    321:                  if_refresh (ifp);
                    322:                }
                    323: 
                    324:              ret = if_set_prefix (ifp, ifc);
                    325:              if (ret < 0)
                    326:                {
                    327:                  zlog_warn ("Can't set interface's address: %s", 
                    328:                             safe_strerror(errno));
                    329:                  continue;
                    330:                }
                    331: 
1.1.1.4 ! misho     332:              SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
        !           333:              /* The address will be advertised to zebra clients when the notification
        !           334:               * from the kernel has been received.
        !           335:               * It will also be added to the interface's subnet list then. */
1.1       misho     336:            }
                    337: #ifdef HAVE_IPV6
                    338:          if (p->family == AF_INET6)
                    339:            {
                    340:              if (! if_is_up (ifp))
                    341:                {
1.1.1.4 ! misho     342:                  /* See long comment above */
1.1       misho     343:                  if_set_flags (ifp, IFF_UP | IFF_RUNNING);
                    344:                  if_refresh (ifp);
                    345:                }
                    346: 
                    347:              ret = if_prefix_add_ipv6 (ifp, ifc);
                    348:              if (ret < 0)
                    349:                {
                    350:                  zlog_warn ("Can't set interface's address: %s", 
                    351:                             safe_strerror(errno));
                    352:                  continue;
                    353:                }
                    354: 
1.1.1.4 ! misho     355:              SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
        !           356:              /* The address will be advertised to zebra clients when the notification
        !           357:               * from the kernel has been received. */
1.1       misho     358:            }
                    359: #endif /* HAVE_IPV6 */
                    360:        }
                    361:     }
                    362: }
                    363: 
                    364: /* Handle interface addition */
                    365: void
                    366: if_add_update (struct interface *ifp)
                    367: {
                    368:   struct zebra_if *if_data;
                    369: 
                    370:   if_data = ifp->info;
1.1.1.4 ! misho     371:   assert(if_data);
        !           372: 
1.1       misho     373:   if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
                    374:     if_set_flags (ifp, IFF_MULTICAST);
                    375:   else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
                    376:     if_unset_flags (ifp, IFF_MULTICAST);
                    377: 
                    378:   zebra_interface_add_update (ifp);
                    379: 
                    380:   if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
                    381:     {
                    382:       SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
                    383: 
1.1.1.4 ! misho     384:       if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
        !           385:        {
        !           386:          if (IS_ZEBRA_DEBUG_KERNEL)
        !           387:            zlog_debug ("interface %s vrf %u index %d is shutdown. "
        !           388:                        "Won't wake it up.",
        !           389:                        ifp->name, ifp->vrf_id, ifp->ifindex);
        !           390:          return;
        !           391:        }
        !           392: 
1.1       misho     393:       if_addr_wakeup (ifp);
                    394: 
                    395:       if (IS_ZEBRA_DEBUG_KERNEL)
1.1.1.4 ! misho     396:        zlog_debug ("interface %s vrf %u index %d becomes active.",
        !           397:                    ifp->name, ifp->vrf_id, ifp->ifindex);
1.1       misho     398:     }
                    399:   else
                    400:     {
                    401:       if (IS_ZEBRA_DEBUG_KERNEL)
1.1.1.4 ! misho     402:        zlog_debug ("interface %s vrf %u index %d is added.",
        !           403:                    ifp->name, ifp->vrf_id, ifp->ifindex);
1.1       misho     404:     }
                    405: }
                    406: 
                    407: /* Handle an interface delete event */
                    408: void 
                    409: if_delete_update (struct interface *ifp)
                    410: {
                    411:   struct connected *ifc;
                    412:   struct prefix *p;
                    413:   struct route_node *rn;
                    414:   struct zebra_if *zebra_if;
                    415: 
                    416:   zebra_if = ifp->info;
                    417: 
                    418:   if (if_is_up(ifp))
                    419:     {
1.1.1.4 ! misho     420:       zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
        !           421:                 ifp->name, ifp->vrf_id, ifp->ifindex);
1.1       misho     422:       return;
                    423:     }
                    424: 
                    425:   /* Mark interface as inactive */
                    426:   UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
                    427:   
                    428:   if (IS_ZEBRA_DEBUG_KERNEL)
1.1.1.4 ! misho     429:     zlog_debug ("interface %s vrf %u index %d is now inactive.",
        !           430:                 ifp->name, ifp->vrf_id, ifp->ifindex);
1.1       misho     431: 
                    432:   /* Delete connected routes from the kernel. */
                    433:   if (ifp->connected)
                    434:     {
                    435:       struct listnode *node;
                    436:       struct listnode *last = NULL;
                    437: 
                    438:       while ((node = (last ? last->next : listhead (ifp->connected))))
                    439:        {
                    440:          ifc = listgetdata (node);
                    441:          p = ifc->address;
                    442:          
                    443:          if (p->family == AF_INET
                    444:              && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
                    445:            {
                    446:              struct listnode *anode;
                    447:              struct listnode *next;
                    448:              struct listnode *first;
                    449:              struct list *addr_list;
                    450:              
                    451:              route_unlock_node (rn);
                    452:              addr_list = (struct list *) rn->info;
                    453:              
                    454:              /* Remove addresses, secondaries first. */
                    455:              first = listhead (addr_list);
                    456:              for (anode = first->next; anode || first; anode = next)
                    457:                {
                    458:                  if (!anode)
                    459:                    {
                    460:                      anode = first;
                    461:                      first = NULL;
                    462:                    }
                    463:                  next = anode->next;
                    464: 
                    465:                  ifc = listgetdata (anode);
                    466:                  p = ifc->address;
                    467:                  connected_down_ipv4 (ifp, ifc);
                    468: 
1.1.1.4 ! misho     469:                  /* XXX: We have to send notifications here explicitly, because we destroy
        !           470:                   * the ifc before receiving the notification about the address being deleted.
        !           471:                   */
1.1       misho     472:                  zebra_interface_address_delete_update (ifp, ifc);
                    473: 
                    474:                  UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1.1.1.4 ! misho     475:                  UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
1.1       misho     476: 
                    477:                  /* Remove from subnet chain. */
                    478:                  list_delete_node (addr_list, anode);
                    479:                  route_unlock_node (rn);
                    480:                  
                    481:                  /* Remove from interface address list (unconditionally). */
                    482:                  if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
                    483:                    {
                    484:                      listnode_delete (ifp->connected, ifc);
                    485:                      connected_free (ifc);
                    486:                     }
                    487:                   else
                    488:                     last = node;
                    489:                }
                    490: 
                    491:              /* Free chain list and respective route node. */
                    492:              list_delete (addr_list);
                    493:              rn->info = NULL;
                    494:              route_unlock_node (rn);
                    495:            }
                    496: #ifdef HAVE_IPV6
                    497:          else if (p->family == AF_INET6)
                    498:            {
                    499:              connected_down_ipv6 (ifp, ifc);
                    500: 
                    501:              zebra_interface_address_delete_update (ifp, ifc);
                    502: 
                    503:              UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1.1.1.4 ! misho     504:              UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
1.1       misho     505: 
                    506:              if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
                    507:                last = node;
                    508:              else
                    509:                {
                    510:                  listnode_delete (ifp->connected, ifc);
                    511:                  connected_free (ifc);
                    512:                }
                    513:            }
                    514: #endif /* HAVE_IPV6 */
                    515:          else
                    516:            {
                    517:              last = node;
                    518:            }
                    519:        }
                    520:     }
                    521:   zebra_interface_delete_update (ifp);
                    522: 
                    523:   /* Update ifindex after distributing the delete message.  This is in
                    524:      case any client needs to have the old value of ifindex available
                    525:      while processing the deletion.  Each client daemon is responsible
                    526:      for setting ifindex to IFINDEX_INTERNAL after processing the
                    527:      interface deletion message. */
                    528:   ifp->ifindex = IFINDEX_INTERNAL;
                    529: }
                    530: 
                    531: /* Interface is up. */
                    532: void
                    533: if_up (struct interface *ifp)
                    534: {
                    535:   struct listnode *node;
                    536:   struct listnode *next;
                    537:   struct connected *ifc;
                    538:   struct prefix *p;
                    539: 
                    540:   /* Notify the protocol daemons. */
                    541:   zebra_interface_up_update (ifp);
                    542: 
                    543:   /* Install connected routes to the kernel. */
                    544:   if (ifp->connected)
                    545:     {
                    546:       for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
                    547:        {
                    548:          p = ifc->address;
                    549: 
                    550:          if (p->family == AF_INET)
                    551:            connected_up_ipv4 (ifp, ifc);
                    552: #ifdef HAVE_IPV6
                    553:          else if (p->family == AF_INET6)
                    554:            connected_up_ipv6 (ifp, ifc);
                    555: #endif /* HAVE_IPV6 */
                    556:        }
                    557:     }
                    558: 
                    559:   /* Examine all static routes. */
1.1.1.4 ! misho     560:   rib_update (ifp->vrf_id);
1.1       misho     561: }
                    562: 
                    563: /* Interface goes down.  We have to manage different behavior of based
                    564:    OS. */
                    565: void
                    566: if_down (struct interface *ifp)
                    567: {
                    568:   struct listnode *node;
                    569:   struct listnode *next;
                    570:   struct connected *ifc;
                    571:   struct prefix *p;
                    572: 
                    573:   /* Notify to the protocol daemons. */
                    574:   zebra_interface_down_update (ifp);
                    575: 
                    576:   /* Delete connected routes from the kernel. */
                    577:   if (ifp->connected)
                    578:     {
                    579:       for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
                    580:        {
                    581:          p = ifc->address;
                    582: 
                    583:          if (p->family == AF_INET)
                    584:            connected_down_ipv4 (ifp, ifc);
                    585: #ifdef HAVE_IPV6
                    586:          else if (p->family == AF_INET6)
                    587:            connected_down_ipv6 (ifp, ifc);
                    588: #endif /* HAVE_IPV6 */
                    589:        }
                    590:     }
                    591: 
                    592:   /* Examine all static routes which direct to the interface. */
1.1.1.4 ! misho     593:   rib_update (ifp->vrf_id);
1.1       misho     594: }
                    595: 
                    596: void
                    597: if_refresh (struct interface *ifp)
                    598: {
                    599:   if_get_flags (ifp);
                    600: }
                    601: 
                    602: /* Output prefix string to vty. */
                    603: static int
                    604: prefix_vty_out (struct vty *vty, struct prefix *p)
                    605: {
                    606:   char str[INET6_ADDRSTRLEN];
                    607: 
                    608:   inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
                    609:   vty_out (vty, "%s", str);
                    610:   return strlen (str);
                    611: }
                    612: 
                    613: /* Dump if address information to vty. */
                    614: static void
                    615: connected_dump_vty (struct vty *vty, struct connected *connected)
                    616: {
                    617:   struct prefix *p;
                    618: 
                    619:   /* Print interface address. */
                    620:   p = connected->address;
                    621:   vty_out (vty, "  %s ", prefix_family_str (p));
                    622:   prefix_vty_out (vty, p);
                    623:   vty_out (vty, "/%d", p->prefixlen);
                    624: 
                    625:   /* If there is destination address, print it. */
                    626:   if (connected->destination)
                    627:     {
                    628:       vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
                    629:       prefix_vty_out (vty, connected->destination);
                    630:     }
                    631: 
                    632:   if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
                    633:     vty_out (vty, " secondary");
                    634: 
                    635:   if (connected->label)
                    636:     vty_out (vty, " %s", connected->label);
                    637: 
                    638:   vty_out (vty, "%s", VTY_NEWLINE);
                    639: }
                    640: 
1.1.1.4 ! misho     641: #if defined (HAVE_RTADV)
1.1       misho     642: /* Dump interface ND information to vty. */
                    643: static void
                    644: nd_dump_vty (struct vty *vty, struct interface *ifp)
                    645: {
                    646:   struct zebra_if *zif;
                    647:   struct rtadvconf *rtadv;
                    648:   int interval;
                    649: 
                    650:   zif = (struct zebra_if *) ifp->info;
                    651:   rtadv = &zif->rtadv;
                    652: 
                    653:   if (rtadv->AdvSendAdvertisements)
                    654:     {
                    655:       vty_out (vty, "  ND advertised reachable time is %d milliseconds%s",
                    656:               rtadv->AdvReachableTime, VTY_NEWLINE);
                    657:       vty_out (vty, "  ND advertised retransmit interval is %d milliseconds%s",
                    658:               rtadv->AdvRetransTimer, VTY_NEWLINE);
                    659:       interval = rtadv->MaxRtrAdvInterval;
                    660:       if (interval % 1000)
                    661:         vty_out (vty, "  ND router advertisements are sent every "
                    662:                        "%d milliseconds%s", interval,
                    663:                 VTY_NEWLINE);
                    664:       else
                    665:         vty_out (vty, "  ND router advertisements are sent every "
                    666:                        "%d seconds%s", interval / 1000,
                    667:                 VTY_NEWLINE);
1.1.1.2   misho     668:       if (rtadv->AdvDefaultLifetime != -1)
                    669:        vty_out (vty, "  ND router advertisements live for %d seconds%s",
                    670:                 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
                    671:       else
                    672:        vty_out (vty, "  ND router advertisements lifetime tracks ra-interval%s",
                    673:                 VTY_NEWLINE);
1.1       misho     674:       vty_out (vty, "  ND router advertisement default router preference is "
                    675:                        "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
                    676:                 VTY_NEWLINE);
                    677:       if (rtadv->AdvManagedFlag)
                    678:        vty_out (vty, "  Hosts use DHCP to obtain routable addresses.%s",
                    679:                 VTY_NEWLINE);
                    680:       else
                    681:        vty_out (vty, "  Hosts use stateless autoconfig for addresses.%s",
                    682:                 VTY_NEWLINE);
                    683:       if (rtadv->AdvHomeAgentFlag)
1.1.1.2   misho     684:       {
1.1       misho     685:        vty_out (vty, "  ND router advertisements with "
                    686:                                "Home Agent flag bit set.%s",
                    687:                 VTY_NEWLINE);
1.1.1.2   misho     688:        if (rtadv->HomeAgentLifetime != -1)
                    689:          vty_out (vty, "  Home Agent lifetime is %u seconds%s",
                    690:                   rtadv->HomeAgentLifetime, VTY_NEWLINE);
                    691:        else
                    692:          vty_out (vty, "  Home Agent lifetime tracks ra-lifetime%s",
                    693:                   VTY_NEWLINE);
                    694:        vty_out (vty, "  Home Agent preference is %u%s",
                    695:                 rtadv->HomeAgentPreference, VTY_NEWLINE);
                    696:       }
1.1       misho     697:       if (rtadv->AdvIntervalOption)
                    698:        vty_out (vty, "  ND router advertisements with Adv. Interval option.%s",
                    699:                 VTY_NEWLINE);
                    700:     }
                    701: }
1.1.1.4 ! misho     702: #endif /* HAVE_RTADV */
1.1       misho     703: 
                    704: /* Interface's information print out to vty interface. */
                    705: static void
                    706: if_dump_vty (struct vty *vty, struct interface *ifp)
                    707: {
                    708:   struct connected *connected;
                    709:   struct listnode *node;
                    710:   struct route_node *rn;
                    711:   struct zebra_if *zebra_if;
                    712: 
                    713:   zebra_if = ifp->info;
                    714: 
                    715:   vty_out (vty, "Interface %s is ", ifp->name);
                    716:   if (if_is_up(ifp)) {
                    717:     vty_out (vty, "up, line protocol ");
                    718:     
                    719:     if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
                    720:       if (if_is_running(ifp))
                    721:        vty_out (vty, "is up%s", VTY_NEWLINE);
                    722:       else
                    723:        vty_out (vty, "is down%s", VTY_NEWLINE);
                    724:     } else {
                    725:       vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
                    726:     }
                    727:   } else {
                    728:     vty_out (vty, "down%s", VTY_NEWLINE);
                    729:   }
                    730: 
1.1.1.4 ! misho     731:   vty_out (vty, "  vrf: %u%s", ifp->vrf_id, VTY_NEWLINE);
        !           732: 
1.1       misho     733:   if (ifp->desc)
                    734:     vty_out (vty, "  Description: %s%s", ifp->desc,
                    735:             VTY_NEWLINE);
                    736:   if (ifp->ifindex == IFINDEX_INTERNAL)
                    737:     {
                    738:       vty_out(vty, "  pseudo interface%s", VTY_NEWLINE);
                    739:       return;
                    740:     }
                    741:   else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
                    742:     {
                    743:       vty_out(vty, "  index %d inactive interface%s", 
                    744:              ifp->ifindex, 
                    745:              VTY_NEWLINE);
                    746:       return;
                    747:     }
                    748: 
                    749:   vty_out (vty, "  index %d metric %d mtu %d ",
                    750:           ifp->ifindex, ifp->metric, ifp->mtu);
                    751: #ifdef HAVE_IPV6
                    752:   if (ifp->mtu6 != ifp->mtu)
                    753:     vty_out (vty, "mtu6 %d ", ifp->mtu6);
                    754: #endif 
                    755:   vty_out (vty, "%s  flags: %s%s", VTY_NEWLINE,
                    756:            if_flag_dump (ifp->flags), VTY_NEWLINE);
                    757:   
                    758:   /* Hardware address. */
1.1.1.4 ! misho     759:   vty_out (vty, "  Type: %s%s", if_link_type_str (ifp->ll_type), VTY_NEWLINE);
1.1       misho     760:   if (ifp->hw_addr_len != 0)
                    761:     {
                    762:       int i;
                    763: 
                    764:       vty_out (vty, "  HWaddr: ");
                    765:       for (i = 0; i < ifp->hw_addr_len; i++)
                    766:        vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
                    767:       vty_out (vty, "%s", VTY_NEWLINE);
                    768:     }
                    769:   
                    770:   /* Bandwidth in kbps */
                    771:   if (ifp->bandwidth != 0)
                    772:     {
                    773:       vty_out(vty, "  bandwidth %u kbps", ifp->bandwidth);
                    774:       vty_out(vty, "%s", VTY_NEWLINE);
                    775:     }
                    776: 
                    777:   for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
                    778:     {
                    779:       if (! rn->info)
                    780:        continue;
                    781:       
                    782:       for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
                    783:         connected_dump_vty (vty, connected);
                    784:     }
                    785: 
                    786:   for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
                    787:     {
                    788:       if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
                    789:          (connected->address->family == AF_INET6))
                    790:        connected_dump_vty (vty, connected);
                    791:     }
                    792: 
1.1.1.4 ! misho     793: #if defined (HAVE_RTADV)
1.1       misho     794:   nd_dump_vty (vty, ifp);
1.1.1.4 ! misho     795: #endif /* HAVE_RTADV */
1.1       misho     796: 
                    797: #ifdef HAVE_PROC_NET_DEV
                    798:   /* Statistics print out using proc file system. */
                    799:   vty_out (vty, "    %lu input packets (%lu multicast), %lu bytes, "
                    800:           "%lu dropped%s",
                    801:           ifp->stats.rx_packets, ifp->stats.rx_multicast,
                    802:           ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
                    803: 
                    804:   vty_out (vty, "    %lu input errors, %lu length, %lu overrun,"
                    805:           " %lu CRC, %lu frame%s",
                    806:           ifp->stats.rx_errors, ifp->stats.rx_length_errors,
                    807:           ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
                    808:           ifp->stats.rx_frame_errors, VTY_NEWLINE);
                    809: 
                    810:   vty_out (vty, "    %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
                    811:           ifp->stats.rx_missed_errors, VTY_NEWLINE);
                    812: 
                    813:   vty_out (vty, "    %lu output packets, %lu bytes, %lu dropped%s",
                    814:           ifp->stats.tx_packets, ifp->stats.tx_bytes,
                    815:           ifp->stats.tx_dropped, VTY_NEWLINE);
                    816: 
                    817:   vty_out (vty, "    %lu output errors, %lu aborted, %lu carrier,"
                    818:           " %lu fifo, %lu heartbeat%s",
                    819:           ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
                    820:           ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
                    821:           ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
                    822: 
                    823:   vty_out (vty, "    %lu window, %lu collisions%s",
                    824:           ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
                    825: #endif /* HAVE_PROC_NET_DEV */
                    826: 
                    827: #ifdef HAVE_NET_RT_IFLIST
                    828: #if defined (__bsdi__) || defined (__NetBSD__)
                    829:   /* Statistics print out using sysctl (). */
1.1.1.4 ! misho     830:   vty_out (vty, "    input packets %llu, bytes %llu, dropped %llu,"
        !           831:            " multicast packets %llu%s",
        !           832:            (unsigned long long)ifp->stats.ifi_ipackets,
        !           833:            (unsigned long long)ifp->stats.ifi_ibytes,
        !           834:            (unsigned long long)ifp->stats.ifi_iqdrops,
        !           835:            (unsigned long long)ifp->stats.ifi_imcasts,
        !           836:            VTY_NEWLINE);
        !           837: 
        !           838:   vty_out (vty, "    input errors %llu%s",
        !           839:            (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
        !           840: 
        !           841:   vty_out (vty, "    output packets %llu, bytes %llu,"
        !           842:            " multicast packets %llu%s",
        !           843:            (unsigned long long)ifp->stats.ifi_opackets,
        !           844:            (unsigned long long)ifp->stats.ifi_obytes,
        !           845:            (unsigned long long)ifp->stats.ifi_omcasts,
        !           846:            VTY_NEWLINE);
1.1       misho     847: 
1.1.1.4 ! misho     848:   vty_out (vty, "    output errors %llu%s",
        !           849:            (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
1.1       misho     850: 
1.1.1.4 ! misho     851:   vty_out (vty, "    collisions %llu%s",
        !           852:            (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
1.1       misho     853: #else
                    854:   /* Statistics print out using sysctl (). */
                    855:   vty_out (vty, "    input packets %lu, bytes %lu, dropped %lu,"
                    856:           " multicast packets %lu%s",
                    857:           ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
                    858:           ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
                    859:           VTY_NEWLINE);
                    860: 
                    861:   vty_out (vty, "    input errors %lu%s",
                    862:           ifp->stats.ifi_ierrors, VTY_NEWLINE);
                    863: 
                    864:   vty_out (vty, "    output packets %lu, bytes %lu, multicast packets %lu%s",
                    865:           ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
                    866:           ifp->stats.ifi_omcasts, VTY_NEWLINE);
                    867: 
                    868:   vty_out (vty, "    output errors %lu%s",
                    869:           ifp->stats.ifi_oerrors, VTY_NEWLINE);
                    870: 
                    871:   vty_out (vty, "    collisions %lu%s",
                    872:           ifp->stats.ifi_collisions, VTY_NEWLINE);
                    873: #endif /* __bsdi__ || __NetBSD__ */
                    874: #endif /* HAVE_NET_RT_IFLIST */
                    875: }
                    876: 
                    877: /* Wrapper hook point for zebra daemon so that ifindex can be set 
                    878:  * DEFUN macro not used as extract.pl HAS to ignore this
                    879:  * See also interface_cmd in lib/if.c
                    880:  */ 
                    881: DEFUN_NOSH (zebra_interface,
                    882:            zebra_interface_cmd,
                    883:            "interface IFNAME",
                    884:            "Select an interface to configure\n"
                    885:            "Interface's name\n")
                    886: {
                    887:   int ret;
                    888:   struct interface * ifp;
                    889:   
                    890:   /* Call lib interface() */
                    891:   if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
                    892:     return ret;
                    893: 
                    894:   ifp = vty->index;  
                    895: 
                    896:   if (ifp->ifindex == IFINDEX_INTERNAL)
                    897:     /* Is this really necessary?  Shouldn't status be initialized to 0
                    898:        in that case? */
                    899:     UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
                    900: 
                    901:   return ret;
                    902: }
                    903: 
1.1.1.4 ! misho     904: ALIAS (zebra_interface,
        !           905:        zebra_interface_vrf_cmd,
        !           906:        "interface IFNAME " VRF_CMD_STR,
        !           907:        "Select an interface to configure\n"
        !           908:        "Interface's name\n"
        !           909:        VRF_CMD_HELP_STR)
        !           910: 
1.1       misho     911: struct cmd_node interface_node =
                    912: {
                    913:   INTERFACE_NODE,
                    914:   "%s(config-if)# ",
                    915:   1
                    916: };
                    917: 
1.1.1.4 ! misho     918: /* Show all interfaces to vty. */
1.1       misho     919: DEFUN (show_interface, show_interface_cmd,
1.1.1.4 ! misho     920:        "show interface",
        !           921:        SHOW_STR
        !           922:        "Interface status and configuration\n")
        !           923: {
        !           924:   struct listnode *node;
        !           925:   struct interface *ifp;
        !           926:   vrf_id_t vrf_id = VRF_DEFAULT;
        !           927: 
        !           928: #ifdef HAVE_PROC_NET_DEV
        !           929:   /* If system has interface statistics via proc file system, update
        !           930:      statistics. */
        !           931:   ifstat_update_proc ();
        !           932: #endif /* HAVE_PROC_NET_DEV */
        !           933: #ifdef HAVE_NET_RT_IFLIST
        !           934:   ifstat_update_sysctl ();
        !           935: #endif /* HAVE_NET_RT_IFLIST */
        !           936: 
        !           937:   if (argc > 0)
        !           938:     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
        !           939: 
        !           940:   /* All interface print. */
        !           941:   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
        !           942:     if_dump_vty (vty, ifp);
        !           943: 
        !           944:   return CMD_SUCCESS;
        !           945: }
        !           946: 
        !           947: ALIAS (show_interface,
        !           948:        show_interface_vrf_cmd,
        !           949:        "show interface " VRF_CMD_STR,
1.1       misho     950:        SHOW_STR
                    951:        "Interface status and configuration\n"
1.1.1.4 ! misho     952:        VRF_CMD_HELP_STR)
        !           953: 
        !           954: /* Show all interfaces to vty. */
        !           955: DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd,
        !           956:        "show interface " VRF_ALL_CMD_STR,
        !           957:        SHOW_STR
        !           958:        "Interface status and configuration\n"
        !           959:        VRF_ALL_CMD_HELP_STR)
1.1       misho     960: {
                    961:   struct listnode *node;
                    962:   struct interface *ifp;
1.1.1.4 ! misho     963:   vrf_iter_t iter;
        !           964: 
        !           965: #ifdef HAVE_PROC_NET_DEV
        !           966:   /* If system has interface statistics via proc file system, update
        !           967:      statistics. */
        !           968:   ifstat_update_proc ();
        !           969: #endif /* HAVE_PROC_NET_DEV */
        !           970: #ifdef HAVE_NET_RT_IFLIST
        !           971:   ifstat_update_sysctl ();
        !           972: #endif /* HAVE_NET_RT_IFLIST */
        !           973: 
        !           974:   /* All interface print. */
        !           975:   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
        !           976:     for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
        !           977:       if_dump_vty (vty, ifp);
        !           978: 
        !           979:   return CMD_SUCCESS;
        !           980: }
        !           981: 
        !           982: /* Show specified interface to vty. */
        !           983: DEFUN (show_interface_name, show_interface_name_cmd,
        !           984:        "show interface IFNAME",
        !           985:        SHOW_STR
        !           986:        "Interface status and configuration\n"
        !           987:        "Inteface name\n")
        !           988: {
        !           989:   struct interface *ifp;
        !           990:   vrf_id_t vrf_id = VRF_DEFAULT;
        !           991: 
1.1       misho     992: #ifdef HAVE_PROC_NET_DEV
                    993:   /* If system has interface statistics via proc file system, update
                    994:      statistics. */
                    995:   ifstat_update_proc ();
                    996: #endif /* HAVE_PROC_NET_DEV */
                    997: #ifdef HAVE_NET_RT_IFLIST
                    998:   ifstat_update_sysctl ();
                    999: #endif /* HAVE_NET_RT_IFLIST */
                   1000: 
1.1.1.4 ! misho    1001:   if (argc > 1)
        !          1002:     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
        !          1003: 
1.1       misho    1004:   /* Specified interface print. */
1.1.1.4 ! misho    1005:   ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
        !          1006:   if (ifp == NULL)
1.1       misho    1007:     {
1.1.1.4 ! misho    1008:       vty_out (vty, "%% Can't find interface %s%s", argv[0],
        !          1009:                VTY_NEWLINE);
        !          1010:       return CMD_WARNING;
1.1       misho    1011:     }
1.1.1.4 ! misho    1012:   if_dump_vty (vty, ifp);
1.1       misho    1013: 
                   1014:   return CMD_SUCCESS;
                   1015: }
                   1016: 
1.1.1.4 ! misho    1017: ALIAS (show_interface_name,
        !          1018:        show_interface_name_vrf_cmd,
        !          1019:        "show interface IFNAME " VRF_CMD_STR,
1.1       misho    1020:        SHOW_STR
                   1021:        "Interface status and configuration\n"
1.1.1.4 ! misho    1022:        "Inteface name\n"
        !          1023:        VRF_CMD_HELP_STR)
        !          1024: 
        !          1025: /* Show specified interface to vty. */
        !          1026: DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
        !          1027:        "show interface IFNAME " VRF_ALL_CMD_STR,
        !          1028:        SHOW_STR
        !          1029:        "Interface status and configuration\n"
        !          1030:        "Inteface name\n"
        !          1031:        VRF_ALL_CMD_HELP_STR)
        !          1032: {
        !          1033:   struct interface *ifp;
        !          1034:   vrf_iter_t iter;
        !          1035:   int found = 0;
        !          1036: 
        !          1037: #ifdef HAVE_PROC_NET_DEV
        !          1038:   /* If system has interface statistics via proc file system, update
        !          1039:      statistics. */
        !          1040:   ifstat_update_proc ();
        !          1041: #endif /* HAVE_PROC_NET_DEV */
        !          1042: #ifdef HAVE_NET_RT_IFLIST
        !          1043:   ifstat_update_sysctl ();
        !          1044: #endif /* HAVE_NET_RT_IFLIST */
        !          1045: 
        !          1046:   /* All interface print. */
        !          1047:   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
        !          1048:     {
        !          1049:       /* Specified interface print. */
        !          1050:       ifp = if_lookup_by_name_vrf (argv[0], vrf_iter2id (iter));
        !          1051:       if (ifp)
        !          1052:         {
        !          1053:           if_dump_vty (vty, ifp);
        !          1054:           found++;
        !          1055:         }
        !          1056:     }
        !          1057: 
        !          1058:   if (!found)
        !          1059:     {
        !          1060:       vty_out (vty, "%% Can't find interface %s%s", argv[0], VTY_NEWLINE);
        !          1061:       return CMD_WARNING;
        !          1062:     }
        !          1063: 
        !          1064:   return CMD_SUCCESS;
        !          1065: }
        !          1066: 
        !          1067: static void
        !          1068: if_show_description (struct vty *vty, vrf_id_t vrf_id)
1.1       misho    1069: {
                   1070:   struct listnode *node;
                   1071:   struct interface *ifp;
                   1072: 
                   1073:   vty_out (vty, "Interface       Status  Protocol  Description%s", VTY_NEWLINE);
1.1.1.4 ! misho    1074:   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
1.1       misho    1075:     {
                   1076:       int len;
                   1077: 
                   1078:       len = vty_out (vty, "%s", ifp->name);
                   1079:       vty_out (vty, "%*s", (16 - len), " ");
                   1080:       
                   1081:       if (if_is_up(ifp))
                   1082:        {
                   1083:          vty_out (vty, "up      ");
                   1084:          if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
                   1085:            {
                   1086:              if (if_is_running(ifp))
                   1087:                vty_out (vty, "up        ");
                   1088:              else
                   1089:                vty_out (vty, "down      ");
                   1090:            }
                   1091:          else
                   1092:            {
                   1093:              vty_out (vty, "unknown   ");
                   1094:            }
                   1095:        }
                   1096:       else
                   1097:        {
                   1098:          vty_out (vty, "down    down      ");
                   1099:        }
                   1100: 
                   1101:       if (ifp->desc)
                   1102:        vty_out (vty, "%s", ifp->desc);
                   1103:       vty_out (vty, "%s", VTY_NEWLINE);
                   1104:     }
1.1.1.4 ! misho    1105: }
        !          1106: 
        !          1107: DEFUN (show_interface_desc,
        !          1108:        show_interface_desc_cmd,
        !          1109:        "show interface description",
        !          1110:        SHOW_STR
        !          1111:        "Interface status and configuration\n"
        !          1112:        "Interface description\n")
        !          1113: {
        !          1114:   vrf_id_t vrf_id = VRF_DEFAULT;
        !          1115: 
        !          1116:   if (argc > 0)
        !          1117:     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
        !          1118: 
        !          1119:   if_show_description (vty, vrf_id);
        !          1120: 
        !          1121:   return CMD_SUCCESS;
        !          1122: }
        !          1123: 
        !          1124: ALIAS (show_interface_desc,
        !          1125:        show_interface_desc_vrf_cmd,
        !          1126:        "show interface description " VRF_CMD_STR,
        !          1127:        SHOW_STR
        !          1128:        "Interface status and configuration\n"
        !          1129:        "Interface description\n"
        !          1130:        VRF_CMD_HELP_STR)
        !          1131: 
        !          1132: DEFUN (show_interface_desc_vrf_all,
        !          1133:        show_interface_desc_vrf_all_cmd,
        !          1134:        "show interface description " VRF_ALL_CMD_STR,
        !          1135:        SHOW_STR
        !          1136:        "Interface status and configuration\n"
        !          1137:        "Interface description\n"
        !          1138:        VRF_ALL_CMD_HELP_STR)
        !          1139: {
        !          1140:   vrf_iter_t iter;
        !          1141: 
        !          1142:   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
        !          1143:     if (!list_isempty (vrf_iter2iflist (iter)))
        !          1144:       {
        !          1145:         vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE,
        !          1146:                  vrf_iter2id (iter),
        !          1147:                  VTY_NEWLINE, VTY_NEWLINE);
        !          1148:         if_show_description (vty, vrf_iter2id (iter));
        !          1149:       }
        !          1150: 
1.1       misho    1151:   return CMD_SUCCESS;
                   1152: }
                   1153: 
                   1154: DEFUN (multicast,
                   1155:        multicast_cmd,
                   1156:        "multicast",
                   1157:        "Set multicast flag to interface\n")
                   1158: {
                   1159:   int ret;
                   1160:   struct interface *ifp;
                   1161:   struct zebra_if *if_data;
                   1162: 
                   1163:   ifp = (struct interface *) vty->index;
                   1164:   if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
                   1165:     {
                   1166:       ret = if_set_flags (ifp, IFF_MULTICAST);
                   1167:       if (ret < 0)
                   1168:        {
                   1169:          vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
                   1170:          return CMD_WARNING;
                   1171:        }
                   1172:       if_refresh (ifp);
                   1173:     }
                   1174:   if_data = ifp->info;
                   1175:   if_data->multicast = IF_ZEBRA_MULTICAST_ON;
                   1176: 
                   1177:   return CMD_SUCCESS;
                   1178: }
                   1179: 
                   1180: DEFUN (no_multicast,
                   1181:        no_multicast_cmd,
                   1182:        "no multicast",
                   1183:        NO_STR
                   1184:        "Unset multicast flag to interface\n")
                   1185: {
                   1186:   int ret;
                   1187:   struct interface *ifp;
                   1188:   struct zebra_if *if_data;
                   1189: 
                   1190:   ifp = (struct interface *) vty->index;
                   1191:   if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
                   1192:     {
                   1193:       ret = if_unset_flags (ifp, IFF_MULTICAST);
                   1194:       if (ret < 0)
                   1195:        {
                   1196:          vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
                   1197:          return CMD_WARNING;
                   1198:        }
                   1199:       if_refresh (ifp);
                   1200:     }
                   1201:   if_data = ifp->info;
                   1202:   if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
                   1203: 
                   1204:   return CMD_SUCCESS;
                   1205: }
                   1206: 
                   1207: DEFUN (linkdetect,
                   1208:        linkdetect_cmd,
                   1209:        "link-detect",
                   1210:        "Enable link detection on interface\n")
                   1211: {
                   1212:   struct interface *ifp;
                   1213:   int if_was_operative;
                   1214:   
                   1215:   ifp = (struct interface *) vty->index;
                   1216:   if_was_operative = if_is_operative(ifp);
                   1217:   SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
                   1218: 
                   1219:   /* When linkdetection is enabled, if might come down */
                   1220:   if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
                   1221: 
                   1222:   /* FIXME: Will defer status change forwarding if interface
                   1223:      does not come down! */
                   1224: 
                   1225:   return CMD_SUCCESS;
                   1226: }
                   1227: 
                   1228: 
                   1229: DEFUN (no_linkdetect,
                   1230:        no_linkdetect_cmd,
                   1231:        "no link-detect",
                   1232:        NO_STR
                   1233:        "Disable link detection on interface\n")
                   1234: {
                   1235:   struct interface *ifp;
                   1236:   int if_was_operative;
                   1237: 
                   1238:   ifp = (struct interface *) vty->index;
                   1239:   if_was_operative = if_is_operative(ifp);
                   1240:   UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
                   1241:   
                   1242:   /* Interface may come up after disabling link detection */
                   1243:   if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
                   1244: 
                   1245:   /* FIXME: see linkdetect_cmd */
                   1246: 
                   1247:   return CMD_SUCCESS;
                   1248: }
                   1249: 
                   1250: DEFUN (shutdown_if,
                   1251:        shutdown_if_cmd,
                   1252:        "shutdown",
                   1253:        "Shutdown the selected interface\n")
                   1254: {
                   1255:   int ret;
                   1256:   struct interface *ifp;
                   1257:   struct zebra_if *if_data;
                   1258: 
                   1259:   ifp = (struct interface *) vty->index;
1.1.1.4 ! misho    1260:   if (ifp->ifindex != IFINDEX_INTERNAL)
1.1       misho    1261:     {
1.1.1.4 ! misho    1262:         ret = if_unset_flags (ifp, IFF_UP);
        !          1263:         if (ret < 0)
        !          1264:           {
        !          1265:             vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
        !          1266:             return CMD_WARNING;
        !          1267:           }
        !          1268:         if_refresh (ifp);
1.1       misho    1269:     }
                   1270:   if_data = ifp->info;
                   1271:   if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
                   1272: 
                   1273:   return CMD_SUCCESS;
                   1274: }
                   1275: 
                   1276: DEFUN (no_shutdown_if,
                   1277:        no_shutdown_if_cmd,
                   1278:        "no shutdown",
                   1279:        NO_STR
                   1280:        "Shutdown the selected interface\n")
                   1281: {
                   1282:   int ret;
                   1283:   struct interface *ifp;
                   1284:   struct zebra_if *if_data;
                   1285: 
                   1286:   ifp = (struct interface *) vty->index;
1.1.1.4 ! misho    1287: 
        !          1288:   if (ifp->ifindex != IFINDEX_INTERNAL)
1.1       misho    1289:     {
1.1.1.4 ! misho    1290:       ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
        !          1291:       if (ret < 0)
        !          1292:        {
        !          1293:          vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
        !          1294:          return CMD_WARNING;
        !          1295:        }
        !          1296:       if_refresh (ifp);
        !          1297: 
        !          1298:       /* Some addresses (in particular, IPv6 addresses on Linux) get
        !          1299:        * removed when the interface goes down. They need to be readded.
        !          1300:        */
        !          1301:       if_addr_wakeup(ifp);
1.1       misho    1302:     }
1.1.1.4 ! misho    1303: 
1.1       misho    1304:   if_data = ifp->info;
                   1305:   if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
                   1306: 
                   1307:   return CMD_SUCCESS;
                   1308: }
                   1309: 
                   1310: DEFUN (bandwidth_if,
                   1311:        bandwidth_if_cmd,
                   1312:        "bandwidth <1-10000000>",
                   1313:        "Set bandwidth informational parameter\n"
                   1314:        "Bandwidth in kilobits\n")
                   1315: {
                   1316:   struct interface *ifp;   
                   1317:   unsigned int bandwidth;
                   1318:   
                   1319:   ifp = (struct interface *) vty->index;
                   1320:   bandwidth = strtol(argv[0], NULL, 10);
                   1321: 
                   1322:   /* bandwidth range is <1-10000000> */
                   1323:   if (bandwidth < 1 || bandwidth > 10000000)
                   1324:     {
                   1325:       vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
                   1326:       return CMD_WARNING;
                   1327:     }
                   1328:   
                   1329:   ifp->bandwidth = bandwidth;
                   1330: 
                   1331:   /* force protocols to recalculate routes due to cost change */
                   1332:   if (if_is_operative (ifp))
                   1333:     zebra_interface_up_update (ifp);
                   1334:   
                   1335:   return CMD_SUCCESS;
                   1336: }
                   1337: 
                   1338: DEFUN (no_bandwidth_if,
                   1339:        no_bandwidth_if_cmd,
                   1340:        "no bandwidth",
                   1341:        NO_STR
                   1342:        "Set bandwidth informational parameter\n")
                   1343: {
                   1344:   struct interface *ifp;   
                   1345:   
                   1346:   ifp = (struct interface *) vty->index;
                   1347: 
                   1348:   ifp->bandwidth = 0;
                   1349:   
                   1350:   /* force protocols to recalculate routes due to cost change */
                   1351:   if (if_is_operative (ifp))
                   1352:     zebra_interface_up_update (ifp);
                   1353: 
                   1354:   return CMD_SUCCESS;
                   1355: }
                   1356: 
                   1357: ALIAS (no_bandwidth_if,
                   1358:        no_bandwidth_if_val_cmd,
                   1359:        "no bandwidth <1-10000000>",
                   1360:        NO_STR
                   1361:        "Set bandwidth informational parameter\n"
                   1362:        "Bandwidth in kilobits\n")
1.1.1.4 ! misho    1363: 
1.1       misho    1364: static int
                   1365: ip_address_install (struct vty *vty, struct interface *ifp,
                   1366:                    const char *addr_str, const char *peer_str,
                   1367:                    const char *label)
                   1368: {
1.1.1.4 ! misho    1369:   struct zebra_if *if_data;
1.1       misho    1370:   struct prefix_ipv4 cp;
                   1371:   struct connected *ifc;
                   1372:   struct prefix_ipv4 *p;
                   1373:   int ret;
                   1374: 
1.1.1.4 ! misho    1375:   if_data = ifp->info;
        !          1376: 
1.1       misho    1377:   ret = str2prefix_ipv4 (addr_str, &cp);
                   1378:   if (ret <= 0)
                   1379:     {
                   1380:       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
                   1381:       return CMD_WARNING;
                   1382:     }
                   1383: 
                   1384:   ifc = connected_check (ifp, (struct prefix *) &cp);
                   1385:   if (! ifc)
                   1386:     {
                   1387:       ifc = connected_new ();
                   1388:       ifc->ifp = ifp;
                   1389: 
                   1390:       /* Address. */
                   1391:       p = prefix_ipv4_new ();
                   1392:       *p = cp;
                   1393:       ifc->address = (struct prefix *) p;
                   1394: 
                   1395:       /* Broadcast. */
                   1396:       if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
                   1397:        {
                   1398:          p = prefix_ipv4_new ();
                   1399:          *p = cp;
                   1400:          p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
                   1401:          ifc->destination = (struct prefix *) p;
                   1402:        }
                   1403: 
                   1404:       /* Label. */
                   1405:       if (label)
                   1406:        ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
                   1407: 
                   1408:       /* Add to linked list. */
                   1409:       listnode_add (ifp->connected, ifc);
                   1410:     }
                   1411: 
                   1412:   /* This address is configured from zebra. */
                   1413:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
                   1414:     SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
                   1415: 
                   1416:   /* In case of this route need to install kernel. */
1.1.1.4 ! misho    1417:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
        !          1418:       && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
        !          1419:       && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
1.1       misho    1420:     {
                   1421:       /* Some system need to up the interface to set IP address. */
                   1422:       if (! if_is_up (ifp))
                   1423:        {
                   1424:          if_set_flags (ifp, IFF_UP | IFF_RUNNING);
                   1425:          if_refresh (ifp);
                   1426:        }
                   1427: 
                   1428:       ret = if_set_prefix (ifp, ifc);
                   1429:       if (ret < 0)
                   1430:        {
                   1431:          vty_out (vty, "%% Can't set interface IP address: %s.%s", 
                   1432:                   safe_strerror(errno), VTY_NEWLINE);
                   1433:          return CMD_WARNING;
                   1434:        }
                   1435: 
1.1.1.4 ! misho    1436:       SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
        !          1437:       /* The address will be advertised to zebra clients when the notification
        !          1438:        * from the kernel has been received.
        !          1439:        * It will also be added to the subnet chain list, then. */
1.1       misho    1440:     }
                   1441: 
                   1442:   return CMD_SUCCESS;
                   1443: }
                   1444: 
                   1445: static int
                   1446: ip_address_uninstall (struct vty *vty, struct interface *ifp,
                   1447:                      const char *addr_str, const char *peer_str,
                   1448:                      const char *label)
                   1449: {
                   1450:   struct prefix_ipv4 cp;
                   1451:   struct connected *ifc;
                   1452:   int ret;
                   1453: 
                   1454:   /* Convert to prefix structure. */
                   1455:   ret = str2prefix_ipv4 (addr_str, &cp);
                   1456:   if (ret <= 0)
                   1457:     {
                   1458:       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
                   1459:       return CMD_WARNING;
                   1460:     }
                   1461: 
                   1462:   /* Check current interface address. */
                   1463:   ifc = connected_check (ifp, (struct prefix *) &cp);
                   1464:   if (! ifc)
                   1465:     {
                   1466:       vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
                   1467:       return CMD_WARNING;
                   1468:     }
                   1469: 
                   1470:   /* This is not configured address. */
                   1471:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
                   1472:     return CMD_WARNING;
                   1473: 
                   1474:   UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
                   1475:   
                   1476:   /* This is not real address or interface is not active. */
1.1.1.4 ! misho    1477:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
1.1       misho    1478:       || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
                   1479:     {
                   1480:       listnode_delete (ifp->connected, ifc);
                   1481:       connected_free (ifc);
                   1482:       return CMD_WARNING;
                   1483:     }
                   1484: 
                   1485:   /* This is real route. */
                   1486:   ret = if_unset_prefix (ifp, ifc);
                   1487:   if (ret < 0)
                   1488:     {
                   1489:       vty_out (vty, "%% Can't unset interface IP address: %s.%s", 
                   1490:               safe_strerror(errno), VTY_NEWLINE);
                   1491:       return CMD_WARNING;
                   1492:     }
1.1.1.4 ! misho    1493:   UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
        !          1494:   /* we will receive a kernel notification about this route being removed.
        !          1495:    * this will trigger its removal from the connected list. */
1.1       misho    1496:   return CMD_SUCCESS;
                   1497: }
                   1498: 
                   1499: DEFUN (ip_address,
                   1500:        ip_address_cmd,
                   1501:        "ip address A.B.C.D/M",
                   1502:        "Interface Internet Protocol config commands\n"
                   1503:        "Set the IP address of an interface\n"
                   1504:        "IP address (e.g. 10.0.0.1/8)\n")
                   1505: {
                   1506:   return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
                   1507: }
                   1508: 
                   1509: DEFUN (no_ip_address,
                   1510:        no_ip_address_cmd,
                   1511:        "no ip address A.B.C.D/M",
                   1512:        NO_STR
                   1513:        "Interface Internet Protocol config commands\n"
                   1514:        "Set the IP address of an interface\n"
                   1515:        "IP Address (e.g. 10.0.0.1/8)")
                   1516: {
                   1517:   return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
                   1518: }
                   1519: 
                   1520: #ifdef HAVE_NETLINK
                   1521: DEFUN (ip_address_label,
                   1522:        ip_address_label_cmd,
                   1523:        "ip address A.B.C.D/M label LINE",
                   1524:        "Interface Internet Protocol config commands\n"
                   1525:        "Set the IP address of an interface\n"
                   1526:        "IP address (e.g. 10.0.0.1/8)\n"
                   1527:        "Label of this address\n"
                   1528:        "Label\n")
                   1529: {
                   1530:   return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
                   1531: }
                   1532: 
                   1533: DEFUN (no_ip_address_label,
                   1534:        no_ip_address_label_cmd,
                   1535:        "no ip address A.B.C.D/M label LINE",
                   1536:        NO_STR
                   1537:        "Interface Internet Protocol config commands\n"
                   1538:        "Set the IP address of an interface\n"
                   1539:        "IP address (e.g. 10.0.0.1/8)\n"
                   1540:        "Label of this address\n"
                   1541:        "Label\n")
                   1542: {
                   1543:   return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
                   1544: }
                   1545: #endif /* HAVE_NETLINK */
                   1546: 
                   1547: #ifdef HAVE_IPV6
                   1548: static int
                   1549: ipv6_address_install (struct vty *vty, struct interface *ifp,
                   1550:                      const char *addr_str, const char *peer_str,
                   1551:                      const char *label, int secondary)
                   1552: {
1.1.1.4 ! misho    1553:   struct zebra_if *if_data;
1.1       misho    1554:   struct prefix_ipv6 cp;
                   1555:   struct connected *ifc;
                   1556:   struct prefix_ipv6 *p;
                   1557:   int ret;
                   1558: 
1.1.1.4 ! misho    1559:   if_data = ifp->info;
        !          1560: 
1.1       misho    1561:   ret = str2prefix_ipv6 (addr_str, &cp);
                   1562:   if (ret <= 0)
                   1563:     {
                   1564:       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
                   1565:       return CMD_WARNING;
                   1566:     }
                   1567: 
                   1568:   ifc = connected_check (ifp, (struct prefix *) &cp);
                   1569:   if (! ifc)
                   1570:     {
                   1571:       ifc = connected_new ();
                   1572:       ifc->ifp = ifp;
                   1573: 
                   1574:       /* Address. */
                   1575:       p = prefix_ipv6_new ();
                   1576:       *p = cp;
                   1577:       ifc->address = (struct prefix *) p;
                   1578: 
                   1579:       /* Secondary. */
                   1580:       if (secondary)
                   1581:        SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
                   1582: 
                   1583:       /* Label. */
                   1584:       if (label)
                   1585:        ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
                   1586: 
                   1587:       /* Add to linked list. */
                   1588:       listnode_add (ifp->connected, ifc);
                   1589:     }
                   1590: 
                   1591:   /* This address is configured from zebra. */
                   1592:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
                   1593:     SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
                   1594: 
                   1595:   /* In case of this route need to install kernel. */
1.1.1.4 ! misho    1596:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
        !          1597:       && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
        !          1598:       && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
1.1       misho    1599:     {
                   1600:       /* Some system need to up the interface to set IP address. */
                   1601:       if (! if_is_up (ifp))
                   1602:        {
                   1603:          if_set_flags (ifp, IFF_UP | IFF_RUNNING);
                   1604:          if_refresh (ifp);
                   1605:        }
                   1606: 
                   1607:       ret = if_prefix_add_ipv6 (ifp, ifc);
                   1608: 
                   1609:       if (ret < 0)
                   1610:        {
                   1611:          vty_out (vty, "%% Can't set interface IP address: %s.%s", 
                   1612:                   safe_strerror(errno), VTY_NEWLINE);
                   1613:          return CMD_WARNING;
                   1614:        }
                   1615: 
1.1.1.4 ! misho    1616:       SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
        !          1617:       /* The address will be advertised to zebra clients when the notification
        !          1618:        * from the kernel has been received. */
1.1       misho    1619:     }
                   1620: 
                   1621:   return CMD_SUCCESS;
                   1622: }
                   1623: 
                   1624: static int
                   1625: ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
                   1626:                        const char *addr_str, const char *peer_str,
                   1627:                        const char *label, int secondry)
                   1628: {
                   1629:   struct prefix_ipv6 cp;
                   1630:   struct connected *ifc;
                   1631:   int ret;
                   1632: 
                   1633:   /* Convert to prefix structure. */
                   1634:   ret = str2prefix_ipv6 (addr_str, &cp);
                   1635:   if (ret <= 0)
                   1636:     {
                   1637:       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
                   1638:       return CMD_WARNING;
                   1639:     }
                   1640: 
                   1641:   /* Check current interface address. */
                   1642:   ifc = connected_check (ifp, (struct prefix *) &cp);
                   1643:   if (! ifc)
                   1644:     {
                   1645:       vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
                   1646:       return CMD_WARNING;
                   1647:     }
                   1648: 
                   1649:   /* This is not configured address. */
                   1650:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
                   1651:     return CMD_WARNING;
                   1652: 
1.1.1.4 ! misho    1653:   UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
        !          1654: 
1.1       misho    1655:   /* This is not real address or interface is not active. */
1.1.1.4 ! misho    1656:   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
1.1       misho    1657:       || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
                   1658:     {
                   1659:       listnode_delete (ifp->connected, ifc);
                   1660:       connected_free (ifc);
                   1661:       return CMD_WARNING;
                   1662:     }
                   1663: 
                   1664:   /* This is real route. */
                   1665:   ret = if_prefix_delete_ipv6 (ifp, ifc);
                   1666:   if (ret < 0)
                   1667:     {
                   1668:       vty_out (vty, "%% Can't unset interface IP address: %s.%s", 
                   1669:               safe_strerror(errno), VTY_NEWLINE);
                   1670:       return CMD_WARNING;
                   1671:     }
                   1672: 
1.1.1.4 ! misho    1673:   UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
        !          1674:   /* This information will be propagated to the zclients when the
        !          1675:    * kernel notification is received. */
1.1       misho    1676:   return CMD_SUCCESS;
                   1677: }
                   1678: 
                   1679: DEFUN (ipv6_address,
                   1680:        ipv6_address_cmd,
                   1681:        "ipv6 address X:X::X:X/M",
                   1682:        "Interface IPv6 config commands\n"
                   1683:        "Set the IP address of an interface\n"
                   1684:        "IPv6 address (e.g. 3ffe:506::1/48)\n")
                   1685: {
                   1686:   return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
                   1687: }
                   1688: 
                   1689: DEFUN (no_ipv6_address,
                   1690:        no_ipv6_address_cmd,
                   1691:        "no ipv6 address X:X::X:X/M",
                   1692:        NO_STR
                   1693:        "Interface IPv6 config commands\n"
                   1694:        "Set the IP address of an interface\n"
                   1695:        "IPv6 address (e.g. 3ffe:506::1/48)\n")
                   1696: {
                   1697:   return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
                   1698: }
                   1699: #endif /* HAVE_IPV6 */
                   1700: 
                   1701: static int
                   1702: if_config_write (struct vty *vty)
                   1703: {
                   1704:   struct listnode *node;
                   1705:   struct interface *ifp;
1.1.1.4 ! misho    1706:   vrf_iter_t iter;
1.1       misho    1707: 
1.1.1.4 ! misho    1708:   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
        !          1709:   for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
1.1       misho    1710:     {
                   1711:       struct zebra_if *if_data;
                   1712:       struct listnode *addrnode;
                   1713:       struct connected *ifc;
                   1714:       struct prefix *p;
                   1715: 
                   1716:       if_data = ifp->info;
1.1.1.4 ! misho    1717: 
        !          1718:       if (ifp->vrf_id == VRF_DEFAULT)
        !          1719:         vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
        !          1720:       else
        !          1721:         vty_out (vty, "interface %s vrf %u%s", ifp->name, ifp->vrf_id,
        !          1722:                  VTY_NEWLINE);
        !          1723: 
        !          1724:       if (if_data)
        !          1725:        {
        !          1726:          if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
        !          1727:            vty_out (vty, " shutdown%s", VTY_NEWLINE);
        !          1728:        }
1.1       misho    1729: 
                   1730:       if (ifp->desc)
                   1731:        vty_out (vty, " description %s%s", ifp->desc,
                   1732:                 VTY_NEWLINE);
                   1733: 
                   1734:       /* Assign bandwidth here to avoid unnecessary interface flap
                   1735:         while processing config script */
                   1736:       if (ifp->bandwidth != 0)
                   1737:        vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE); 
                   1738: 
                   1739:       if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
                   1740:        vty_out(vty, " link-detect%s", VTY_NEWLINE);
1.1.1.4 ! misho    1741:       else
        !          1742:        vty_out(vty, " no link-detect%s", VTY_NEWLINE);
1.1       misho    1743: 
                   1744:       for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
                   1745:          {
                   1746:            if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
                   1747:              {
                   1748:                char buf[INET6_ADDRSTRLEN];
                   1749:                p = ifc->address;
1.1.1.4 ! misho    1750:                vty_out (vty, " ip%s address %s",
1.1       misho    1751:                         p->family == AF_INET ? "" : "v6",
1.1.1.4 ! misho    1752:                         prefix2str (p, buf, sizeof(buf)));
1.1       misho    1753: 
                   1754:                if (ifc->label)
                   1755:                  vty_out (vty, " label %s", ifc->label);
                   1756: 
                   1757:                vty_out (vty, "%s", VTY_NEWLINE);
                   1758:              }
                   1759:          }
                   1760: 
                   1761:       if (if_data)
                   1762:        {
                   1763:          if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
                   1764:            vty_out (vty, " %smulticast%s",
                   1765:                     if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
                   1766:                     VTY_NEWLINE);
                   1767:        }
                   1768: 
1.1.1.4 ! misho    1769: #if defined (HAVE_RTADV)
1.1       misho    1770:       rtadv_config_write (vty, ifp);
1.1.1.4 ! misho    1771: #endif /* HAVE_RTADV */
1.1       misho    1772: 
                   1773: #ifdef HAVE_IRDP
                   1774:       irdp_config_write (vty, ifp);
                   1775: #endif /* IRDP */
                   1776: 
                   1777:       vty_out (vty, "!%s", VTY_NEWLINE);
                   1778:     }
                   1779:   return 0;
                   1780: }
                   1781: 
                   1782: /* Allocate and initialize interface vector. */
                   1783: void
                   1784: zebra_if_init (void)
                   1785: {
                   1786:   /* Initialize interface and new hook. */
                   1787:   if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
                   1788:   if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
                   1789:   
                   1790:   /* Install configuration write function. */
                   1791:   install_node (&interface_node, if_config_write);
                   1792: 
                   1793:   install_element (VIEW_NODE, &show_interface_cmd);
1.1.1.4 ! misho    1794:   install_element (VIEW_NODE, &show_interface_vrf_cmd);
        !          1795:   install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
        !          1796:   install_element (VIEW_NODE, &show_interface_name_cmd);
        !          1797:   install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
        !          1798:   install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
1.1       misho    1799:   install_element (ENABLE_NODE, &show_interface_cmd);
1.1.1.4 ! misho    1800:   install_element (ENABLE_NODE, &show_interface_vrf_cmd);
        !          1801:   install_element (ENABLE_NODE, &show_interface_vrf_all_cmd);
        !          1802:   install_element (ENABLE_NODE, &show_interface_name_cmd);
        !          1803:   install_element (ENABLE_NODE, &show_interface_name_vrf_cmd);
        !          1804:   install_element (ENABLE_NODE, &show_interface_name_vrf_all_cmd);
1.1       misho    1805:   install_element (ENABLE_NODE, &show_interface_desc_cmd);
1.1.1.4 ! misho    1806:   install_element (ENABLE_NODE, &show_interface_desc_vrf_cmd);
        !          1807:   install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
1.1       misho    1808:   install_element (CONFIG_NODE, &zebra_interface_cmd);
1.1.1.4 ! misho    1809:   install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
1.1       misho    1810:   install_element (CONFIG_NODE, &no_interface_cmd);
1.1.1.4 ! misho    1811:   install_element (CONFIG_NODE, &no_interface_vrf_cmd);
1.1       misho    1812:   install_default (INTERFACE_NODE);
                   1813:   install_element (INTERFACE_NODE, &interface_desc_cmd);
                   1814:   install_element (INTERFACE_NODE, &no_interface_desc_cmd);
                   1815:   install_element (INTERFACE_NODE, &multicast_cmd);
                   1816:   install_element (INTERFACE_NODE, &no_multicast_cmd);
                   1817:   install_element (INTERFACE_NODE, &linkdetect_cmd);
                   1818:   install_element (INTERFACE_NODE, &no_linkdetect_cmd);
                   1819:   install_element (INTERFACE_NODE, &shutdown_if_cmd);
                   1820:   install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
                   1821:   install_element (INTERFACE_NODE, &bandwidth_if_cmd);
                   1822:   install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
                   1823:   install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
                   1824:   install_element (INTERFACE_NODE, &ip_address_cmd);
                   1825:   install_element (INTERFACE_NODE, &no_ip_address_cmd);
                   1826: #ifdef HAVE_IPV6
                   1827:   install_element (INTERFACE_NODE, &ipv6_address_cmd);
                   1828:   install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
                   1829: #endif /* HAVE_IPV6 */
                   1830: #ifdef HAVE_NETLINK
                   1831:   install_element (INTERFACE_NODE, &ip_address_label_cmd);
                   1832:   install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
                   1833: #endif /* HAVE_NETLINK */
                   1834: }

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