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