Annotation of embedaddon/quagga/ripd/rip_interface.c, revision 1.1
1.1 ! misho 1: /* Interface related function for RIP.
! 2: * Copyright (C) 1997, 98 Kunihiro Ishiguro <kunihiro@zebra.org>
! 3: *
! 4: * This file is part of GNU Zebra.
! 5: *
! 6: * GNU Zebra is free software; you can redistribute it and/or modify it
! 7: * under the terms of the GNU General Public License as published by the
! 8: * Free Software Foundation; either version 2, or (at your option) any
! 9: * later version.
! 10: *
! 11: * GNU Zebra is distributed in the hope that it will be useful, but
! 12: * WITHOUT ANY WARRANTY; without even the implied warranty of
! 13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
! 14: * General Public License for more details.
! 15: *
! 16: * You should have received a copy of the GNU General Public License
! 17: * along with GNU Zebra; see the file COPYING. If not, write to the Free
! 18: * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
! 19: * 02111-1307, USA.
! 20: */
! 21:
! 22: #include <zebra.h>
! 23:
! 24: #include "command.h"
! 25: #include "if.h"
! 26: #include "sockunion.h"
! 27: #include "prefix.h"
! 28: #include "memory.h"
! 29: #include "network.h"
! 30: #include "table.h"
! 31: #include "log.h"
! 32: #include "stream.h"
! 33: #include "thread.h"
! 34: #include "zclient.h"
! 35: #include "filter.h"
! 36: #include "sockopt.h"
! 37: #include "privs.h"
! 38:
! 39: #include "zebra/connected.h"
! 40:
! 41: #include "ripd/ripd.h"
! 42: #include "ripd/rip_debug.h"
! 43: #include "ripd/rip_interface.h"
! 44:
! 45: /* static prototypes */
! 46: static void rip_enable_apply (struct interface *);
! 47: static void rip_passive_interface_apply (struct interface *);
! 48: static int rip_if_down(struct interface *ifp);
! 49: static int rip_enable_if_lookup (const char *ifname);
! 50: static int rip_enable_network_lookup2 (struct connected *connected);
! 51: static void rip_enable_apply_all (void);
! 52:
! 53: struct message ri_version_msg[] =
! 54: {
! 55: {RI_RIP_VERSION_1, "1"},
! 56: {RI_RIP_VERSION_2, "2"},
! 57: {RI_RIP_VERSION_1_AND_2, "1 2"},
! 58: };
! 59:
! 60: extern struct zebra_privs_t ripd_privs;
! 61:
! 62: /* RIP enabled network vector. */
! 63: vector rip_enable_interface;
! 64:
! 65: /* RIP enabled interface table. */
! 66: struct route_table *rip_enable_network;
! 67:
! 68: /* Vector to store passive-interface name. */
! 69: static int passive_default; /* are we in passive-interface default mode? */
! 70: vector Vrip_passive_nondefault;
! 71:
! 72: /* Join to the RIP version 2 multicast group. */
! 73: static int
! 74: ipv4_multicast_join (int sock,
! 75: struct in_addr group,
! 76: struct in_addr ifa,
! 77: unsigned int ifindex)
! 78: {
! 79: int ret;
! 80:
! 81: ret = setsockopt_ipv4_multicast (sock,
! 82: IP_ADD_MEMBERSHIP,
! 83: group.s_addr,
! 84: ifindex);
! 85:
! 86: if (ret < 0)
! 87: zlog (NULL, LOG_INFO, "can't setsockopt IP_ADD_MEMBERSHIP %s",
! 88: safe_strerror (errno));
! 89:
! 90: return ret;
! 91: }
! 92:
! 93: /* Leave from the RIP version 2 multicast group. */
! 94: static int
! 95: ipv4_multicast_leave (int sock,
! 96: struct in_addr group,
! 97: struct in_addr ifa,
! 98: unsigned int ifindex)
! 99: {
! 100: int ret;
! 101:
! 102: ret = setsockopt_ipv4_multicast (sock,
! 103: IP_DROP_MEMBERSHIP,
! 104: group.s_addr,
! 105: ifindex);
! 106:
! 107: if (ret < 0)
! 108: zlog (NULL, LOG_INFO, "can't setsockopt IP_DROP_MEMBERSHIP");
! 109:
! 110: return ret;
! 111: }
! 112:
! 113: /* Allocate new RIP's interface configuration. */
! 114: static struct rip_interface *
! 115: rip_interface_new (void)
! 116: {
! 117: struct rip_interface *ri;
! 118:
! 119: ri = XCALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
! 120:
! 121: /* Default authentication type is simple password for Cisco
! 122: compatibility. */
! 123: ri->auth_type = RIP_NO_AUTH;
! 124: ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
! 125:
! 126: /* Set default split-horizon behavior. If the interface is Frame
! 127: Relay or SMDS is enabled, the default value for split-horizon is
! 128: off. But currently Zebra does detect Frame Relay or SMDS
! 129: interface. So all interface is set to split horizon. */
! 130: ri->split_horizon_default = RIP_SPLIT_HORIZON;
! 131: ri->split_horizon = ri->split_horizon_default;
! 132:
! 133: return ri;
! 134: }
! 135:
! 136: void
! 137: rip_interface_multicast_set (int sock, struct connected *connected)
! 138: {
! 139: assert (connected != NULL);
! 140:
! 141: if (setsockopt_ipv4_multicast_if (sock, connected->ifp->ifindex) < 0)
! 142: {
! 143: zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
! 144: "ifindex %d for interface %s",
! 145: sock, connected->ifp->ifindex,
! 146: connected->ifp->name);
! 147: }
! 148:
! 149: return;
! 150: }
! 151:
! 152: /* Send RIP request packet to specified interface. */
! 153: static void
! 154: rip_request_interface_send (struct interface *ifp, u_char version)
! 155: {
! 156: struct sockaddr_in to;
! 157:
! 158: /* RIPv2 support multicast. */
! 159: if (version == RIPv2 && if_is_multicast (ifp))
! 160: {
! 161:
! 162: if (IS_RIP_DEBUG_EVENT)
! 163: zlog_debug ("multicast request on %s", ifp->name);
! 164:
! 165: rip_request_send (NULL, ifp, version, NULL);
! 166: return;
! 167: }
! 168:
! 169: /* RIPv1 and non multicast interface. */
! 170: if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
! 171: {
! 172: struct listnode *cnode, *cnnode;
! 173: struct connected *connected;
! 174:
! 175: if (IS_RIP_DEBUG_EVENT)
! 176: zlog_debug ("broadcast request to %s", ifp->name);
! 177:
! 178: for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
! 179: {
! 180: if (connected->address->family == AF_INET)
! 181: {
! 182: memset (&to, 0, sizeof (struct sockaddr_in));
! 183: to.sin_port = htons (RIP_PORT_DEFAULT);
! 184: if (connected->destination)
! 185: /* use specified broadcast or peer destination addr */
! 186: to.sin_addr = connected->destination->u.prefix4;
! 187: else if (connected->address->prefixlen < IPV4_MAX_PREFIXLEN)
! 188: /* calculate the appropriate broadcast address */
! 189: to.sin_addr.s_addr =
! 190: ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
! 191: connected->address->prefixlen);
! 192: else
! 193: /* do not know where to send the packet */
! 194: continue;
! 195:
! 196: if (IS_RIP_DEBUG_EVENT)
! 197: zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
! 198:
! 199: rip_request_send (&to, ifp, version, connected);
! 200: }
! 201: }
! 202: }
! 203: }
! 204:
! 205: /* This will be executed when interface goes up. */
! 206: static void
! 207: rip_request_interface (struct interface *ifp)
! 208: {
! 209: struct rip_interface *ri;
! 210:
! 211: /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
! 212: if (if_is_loopback (ifp))
! 213: return;
! 214:
! 215: /* If interface is down, don't send RIP packet. */
! 216: if (! if_is_operative (ifp))
! 217: return;
! 218:
! 219: /* Fetch RIP interface information. */
! 220: ri = ifp->info;
! 221:
! 222:
! 223: /* If there is no version configuration in the interface,
! 224: use rip's version setting. */
! 225: {
! 226: int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
! 227: rip->version_send : ri->ri_send);
! 228: if (vsend & RIPv1)
! 229: rip_request_interface_send (ifp, RIPv1);
! 230: if (vsend & RIPv2)
! 231: rip_request_interface_send (ifp, RIPv2);
! 232: }
! 233: }
! 234:
! 235: #if 0
! 236: /* Send RIP request to the neighbor. */
! 237: static void
! 238: rip_request_neighbor (struct in_addr addr)
! 239: {
! 240: struct sockaddr_in to;
! 241:
! 242: memset (&to, 0, sizeof (struct sockaddr_in));
! 243: to.sin_port = htons (RIP_PORT_DEFAULT);
! 244: to.sin_addr = addr;
! 245:
! 246: rip_request_send (&to, NULL, rip->version_send, NULL);
! 247: }
! 248:
! 249: /* Request routes at all interfaces. */
! 250: static void
! 251: rip_request_neighbor_all (void)
! 252: {
! 253: struct route_node *rp;
! 254:
! 255: if (! rip)
! 256: return;
! 257:
! 258: if (IS_RIP_DEBUG_EVENT)
! 259: zlog_debug ("request to the all neighbor");
! 260:
! 261: /* Send request to all neighbor. */
! 262: for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
! 263: if (rp->info)
! 264: rip_request_neighbor (rp->p.u.prefix4);
! 265: }
! 266: #endif
! 267:
! 268: /* Multicast packet receive socket. */
! 269: static int
! 270: rip_multicast_join (struct interface *ifp, int sock)
! 271: {
! 272: struct listnode *cnode;
! 273: struct connected *ifc;
! 274:
! 275: if (if_is_operative (ifp) && if_is_multicast (ifp))
! 276: {
! 277: if (IS_RIP_DEBUG_EVENT)
! 278: zlog_debug ("multicast join at %s", ifp->name);
! 279:
! 280: for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
! 281: {
! 282: struct prefix_ipv4 *p;
! 283: struct in_addr group;
! 284:
! 285: p = (struct prefix_ipv4 *) ifc->address;
! 286:
! 287: if (p->family != AF_INET)
! 288: continue;
! 289:
! 290: group.s_addr = htonl (INADDR_RIP_GROUP);
! 291: if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
! 292: return -1;
! 293: else
! 294: return 0;
! 295: }
! 296: }
! 297: return 0;
! 298: }
! 299:
! 300: /* Leave from multicast group. */
! 301: static void
! 302: rip_multicast_leave (struct interface *ifp, int sock)
! 303: {
! 304: struct listnode *cnode;
! 305: struct connected *connected;
! 306:
! 307: if (if_is_up (ifp) && if_is_multicast (ifp))
! 308: {
! 309: if (IS_RIP_DEBUG_EVENT)
! 310: zlog_debug ("multicast leave from %s", ifp->name);
! 311:
! 312: for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
! 313: {
! 314: struct prefix_ipv4 *p;
! 315: struct in_addr group;
! 316:
! 317: p = (struct prefix_ipv4 *) connected->address;
! 318:
! 319: if (p->family != AF_INET)
! 320: continue;
! 321:
! 322: group.s_addr = htonl (INADDR_RIP_GROUP);
! 323: if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
! 324: return;
! 325: }
! 326: }
! 327: }
! 328:
! 329: /* Is there and address on interface that I could use ? */
! 330: static int
! 331: rip_if_ipv4_address_check (struct interface *ifp)
! 332: {
! 333: struct listnode *nn;
! 334: struct connected *connected;
! 335: int count = 0;
! 336:
! 337: for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected))
! 338: {
! 339: struct prefix *p;
! 340:
! 341: p = connected->address;
! 342:
! 343: if (p->family == AF_INET)
! 344: count++;
! 345: }
! 346:
! 347: return count;
! 348: }
! 349:
! 350:
! 351:
! 352:
! 353: /* Does this address belongs to me ? */
! 354: int
! 355: if_check_address (struct in_addr addr)
! 356: {
! 357: struct listnode *node;
! 358: struct interface *ifp;
! 359:
! 360: for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
! 361: {
! 362: struct listnode *cnode;
! 363: struct connected *connected;
! 364:
! 365: for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
! 366: {
! 367: struct prefix_ipv4 *p;
! 368:
! 369: p = (struct prefix_ipv4 *) connected->address;
! 370:
! 371: if (p->family != AF_INET)
! 372: continue;
! 373:
! 374: if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
! 375: return 1;
! 376: }
! 377: }
! 378: return 0;
! 379: }
! 380:
! 381: /* Inteface link down message processing. */
! 382: int
! 383: rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
! 384: {
! 385: struct interface *ifp;
! 386: struct stream *s;
! 387:
! 388: s = zclient->ibuf;
! 389:
! 390: /* zebra_interface_state_read() updates interface structure in
! 391: iflist. */
! 392: ifp = zebra_interface_state_read(s);
! 393:
! 394: if (ifp == NULL)
! 395: return 0;
! 396:
! 397: rip_if_down(ifp);
! 398:
! 399: if (IS_RIP_DEBUG_ZEBRA)
! 400: zlog_debug ("interface %s index %d flags %llx metric %d mtu %d is down",
! 401: ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
! 402: ifp->metric, ifp->mtu);
! 403:
! 404: return 0;
! 405: }
! 406:
! 407: /* Inteface link up message processing */
! 408: int
! 409: rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
! 410: {
! 411: struct interface *ifp;
! 412:
! 413: /* zebra_interface_state_read () updates interface structure in
! 414: iflist. */
! 415: ifp = zebra_interface_state_read (zclient->ibuf);
! 416:
! 417: if (ifp == NULL)
! 418: return 0;
! 419:
! 420: if (IS_RIP_DEBUG_ZEBRA)
! 421: zlog_debug ("interface %s index %d flags %#llx metric %d mtu %d is up",
! 422: ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
! 423: ifp->metric, ifp->mtu);
! 424:
! 425: /* Check if this interface is RIP enabled or not.*/
! 426: rip_enable_apply (ifp);
! 427:
! 428: /* Check for a passive interface */
! 429: rip_passive_interface_apply (ifp);
! 430:
! 431: /* Apply distribute list to the all interface. */
! 432: rip_distribute_update_interface (ifp);
! 433:
! 434: return 0;
! 435: }
! 436:
! 437: /* Inteface addition message from zebra. */
! 438: int
! 439: rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
! 440: {
! 441: struct interface *ifp;
! 442:
! 443: ifp = zebra_interface_add_read (zclient->ibuf);
! 444:
! 445: if (IS_RIP_DEBUG_ZEBRA)
! 446: zlog_debug ("interface add %s index %d flags %#llx metric %d mtu %d",
! 447: ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
! 448: ifp->metric, ifp->mtu);
! 449:
! 450: /* Check if this interface is RIP enabled or not.*/
! 451: rip_enable_apply (ifp);
! 452:
! 453: /* Check for a passive interface */
! 454: rip_passive_interface_apply (ifp);
! 455:
! 456: /* Apply distribute list to the all interface. */
! 457: rip_distribute_update_interface (ifp);
! 458:
! 459: /* rip_request_neighbor_all (); */
! 460:
! 461: /* Check interface routemap. */
! 462: rip_if_rmap_update_interface (ifp);
! 463:
! 464: return 0;
! 465: }
! 466:
! 467: int
! 468: rip_interface_delete (int command, struct zclient *zclient,
! 469: zebra_size_t length)
! 470: {
! 471: struct interface *ifp;
! 472: struct stream *s;
! 473:
! 474:
! 475: s = zclient->ibuf;
! 476: /* zebra_interface_state_read() updates interface structure in iflist */
! 477: ifp = zebra_interface_state_read(s);
! 478:
! 479: if (ifp == NULL)
! 480: return 0;
! 481:
! 482: if (if_is_up (ifp)) {
! 483: rip_if_down(ifp);
! 484: }
! 485:
! 486: zlog_info("interface delete %s index %d flags %#llx metric %d mtu %d",
! 487: ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
! 488: ifp->metric, ifp->mtu);
! 489:
! 490: /* To support pseudo interface do not free interface structure. */
! 491: /* if_delete(ifp); */
! 492: ifp->ifindex = IFINDEX_INTERNAL;
! 493:
! 494: return 0;
! 495: }
! 496:
! 497: void
! 498: rip_interface_clean (void)
! 499: {
! 500: struct listnode *node;
! 501: struct interface *ifp;
! 502: struct rip_interface *ri;
! 503:
! 504: for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
! 505: {
! 506: ri = ifp->info;
! 507:
! 508: ri->enable_network = 0;
! 509: ri->enable_interface = 0;
! 510: ri->running = 0;
! 511:
! 512: if (ri->t_wakeup)
! 513: {
! 514: thread_cancel (ri->t_wakeup);
! 515: ri->t_wakeup = NULL;
! 516: }
! 517: }
! 518: }
! 519:
! 520: void
! 521: rip_interface_reset (void)
! 522: {
! 523: struct listnode *node;
! 524: struct interface *ifp;
! 525: struct rip_interface *ri;
! 526:
! 527: for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
! 528: {
! 529: ri = ifp->info;
! 530:
! 531: ri->enable_network = 0;
! 532: ri->enable_interface = 0;
! 533: ri->running = 0;
! 534:
! 535: ri->ri_send = RI_RIP_UNSPEC;
! 536: ri->ri_receive = RI_RIP_UNSPEC;
! 537:
! 538: ri->auth_type = RIP_NO_AUTH;
! 539:
! 540: if (ri->auth_str)
! 541: {
! 542: free (ri->auth_str);
! 543: ri->auth_str = NULL;
! 544: }
! 545: if (ri->key_chain)
! 546: {
! 547: free (ri->key_chain);
! 548: ri->key_chain = NULL;
! 549: }
! 550:
! 551: ri->split_horizon = RIP_NO_SPLIT_HORIZON;
! 552: ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
! 553:
! 554: ri->list[RIP_FILTER_IN] = NULL;
! 555: ri->list[RIP_FILTER_OUT] = NULL;
! 556:
! 557: ri->prefix[RIP_FILTER_IN] = NULL;
! 558: ri->prefix[RIP_FILTER_OUT] = NULL;
! 559:
! 560: if (ri->t_wakeup)
! 561: {
! 562: thread_cancel (ri->t_wakeup);
! 563: ri->t_wakeup = NULL;
! 564: }
! 565:
! 566: ri->recv_badpackets = 0;
! 567: ri->recv_badroutes = 0;
! 568: ri->sent_updates = 0;
! 569:
! 570: ri->passive = 0;
! 571: }
! 572: }
! 573:
! 574: int
! 575: rip_if_down(struct interface *ifp)
! 576: {
! 577: struct route_node *rp;
! 578: struct rip_info *rinfo;
! 579: struct rip_interface *ri = NULL;
! 580: if (rip)
! 581: {
! 582: for (rp = route_top (rip->table); rp; rp = route_next (rp))
! 583: if ((rinfo = rp->info) != NULL)
! 584: {
! 585: /* Routes got through this interface. */
! 586: if (rinfo->ifindex == ifp->ifindex &&
! 587: rinfo->type == ZEBRA_ROUTE_RIP &&
! 588: rinfo->sub_type == RIP_ROUTE_RTE)
! 589: {
! 590: rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
! 591: &rinfo->nexthop,
! 592: rinfo->metric);
! 593:
! 594: rip_redistribute_delete (rinfo->type,rinfo->sub_type,
! 595: (struct prefix_ipv4 *)&rp->p,
! 596: rinfo->ifindex);
! 597: }
! 598: else
! 599: {
! 600: /* All redistributed routes but static and system */
! 601: if ((rinfo->ifindex == ifp->ifindex) &&
! 602: /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
! 603: (rinfo->type != ZEBRA_ROUTE_SYSTEM))
! 604: rip_redistribute_delete (rinfo->type,rinfo->sub_type,
! 605: (struct prefix_ipv4 *)&rp->p,
! 606: rinfo->ifindex);
! 607: }
! 608: }
! 609: }
! 610:
! 611: ri = ifp->info;
! 612:
! 613: if (ri->running)
! 614: {
! 615: if (IS_RIP_DEBUG_EVENT)
! 616: zlog_debug ("turn off %s", ifp->name);
! 617:
! 618: /* Leave from multicast group. */
! 619: rip_multicast_leave (ifp, rip->sock);
! 620:
! 621: ri->running = 0;
! 622: }
! 623:
! 624: return 0;
! 625: }
! 626:
! 627: /* Needed for stop RIP process. */
! 628: void
! 629: rip_if_down_all ()
! 630: {
! 631: struct interface *ifp;
! 632: struct listnode *node, *nnode;
! 633:
! 634: for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
! 635: rip_if_down (ifp);
! 636: }
! 637:
! 638: static void
! 639: rip_apply_address_add (struct connected *ifc)
! 640: {
! 641: struct prefix_ipv4 address;
! 642: struct prefix *p;
! 643:
! 644: if (!rip)
! 645: return;
! 646:
! 647: if (! if_is_up(ifc->ifp))
! 648: return;
! 649:
! 650: p = ifc->address;
! 651:
! 652: memset (&address, 0, sizeof (address));
! 653: address.family = p->family;
! 654: address.prefix = p->u.prefix4;
! 655: address.prefixlen = p->prefixlen;
! 656: apply_mask_ipv4(&address);
! 657:
! 658: /* Check if this interface is RIP enabled or not
! 659: or Check if this address's prefix is RIP enabled */
! 660: if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
! 661: (rip_enable_network_lookup2(ifc) >= 0))
! 662: rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
! 663: &address, ifc->ifp->ifindex, NULL, 0, 0);
! 664:
! 665: }
! 666:
! 667: int
! 668: rip_interface_address_add (int command, struct zclient *zclient,
! 669: zebra_size_t length)
! 670: {
! 671: struct connected *ifc;
! 672: struct prefix *p;
! 673:
! 674: ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
! 675: zclient->ibuf);
! 676:
! 677: if (ifc == NULL)
! 678: return 0;
! 679:
! 680: p = ifc->address;
! 681:
! 682: if (p->family == AF_INET)
! 683: {
! 684: if (IS_RIP_DEBUG_ZEBRA)
! 685: zlog_debug ("connected address %s/%d is added",
! 686: inet_ntoa (p->u.prefix4), p->prefixlen);
! 687:
! 688: rip_enable_apply(ifc->ifp);
! 689: /* Check if this prefix needs to be redistributed */
! 690: rip_apply_address_add(ifc);
! 691:
! 692: #ifdef HAVE_SNMP
! 693: rip_ifaddr_add (ifc->ifp, ifc);
! 694: #endif /* HAVE_SNMP */
! 695: }
! 696:
! 697: return 0;
! 698: }
! 699:
! 700: static void
! 701: rip_apply_address_del (struct connected *ifc) {
! 702: struct prefix_ipv4 address;
! 703: struct prefix *p;
! 704:
! 705: if (!rip)
! 706: return;
! 707:
! 708: if (! if_is_up(ifc->ifp))
! 709: return;
! 710:
! 711: p = ifc->address;
! 712:
! 713: memset (&address, 0, sizeof (address));
! 714: address.family = p->family;
! 715: address.prefix = p->u.prefix4;
! 716: address.prefixlen = p->prefixlen;
! 717: apply_mask_ipv4(&address);
! 718:
! 719: rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
! 720: &address, ifc->ifp->ifindex);
! 721: }
! 722:
! 723: int
! 724: rip_interface_address_delete (int command, struct zclient *zclient,
! 725: zebra_size_t length)
! 726: {
! 727: struct connected *ifc;
! 728: struct prefix *p;
! 729:
! 730: ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
! 731: zclient->ibuf);
! 732:
! 733: if (ifc)
! 734: {
! 735: p = ifc->address;
! 736: if (p->family == AF_INET)
! 737: {
! 738: if (IS_RIP_DEBUG_ZEBRA)
! 739: zlog_debug ("connected address %s/%d is deleted",
! 740: inet_ntoa (p->u.prefix4), p->prefixlen);
! 741:
! 742: #ifdef HAVE_SNMP
! 743: rip_ifaddr_delete (ifc->ifp, ifc);
! 744: #endif /* HAVE_SNMP */
! 745:
! 746: /* Chech wether this prefix needs to be removed */
! 747: rip_apply_address_del(ifc);
! 748:
! 749: }
! 750:
! 751: connected_free (ifc);
! 752:
! 753: }
! 754:
! 755: return 0;
! 756: }
! 757:
! 758: /* Check interface is enabled by network statement. */
! 759: /* Check wether the interface has at least a connected prefix that
! 760: * is within the ripng_enable_network table. */
! 761: static int
! 762: rip_enable_network_lookup_if (struct interface *ifp)
! 763: {
! 764: struct listnode *node, *nnode;
! 765: struct connected *connected;
! 766: struct prefix_ipv4 address;
! 767:
! 768: for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
! 769: {
! 770: struct prefix *p;
! 771: struct route_node *node;
! 772:
! 773: p = connected->address;
! 774:
! 775: if (p->family == AF_INET)
! 776: {
! 777: address.family = AF_INET;
! 778: address.prefix = p->u.prefix4;
! 779: address.prefixlen = IPV4_MAX_BITLEN;
! 780:
! 781: node = route_node_match (rip_enable_network,
! 782: (struct prefix *)&address);
! 783: if (node)
! 784: {
! 785: route_unlock_node (node);
! 786: return 1;
! 787: }
! 788: }
! 789: }
! 790: return -1;
! 791: }
! 792:
! 793: /* Check wether connected is within the ripng_enable_network table. */
! 794: int
! 795: rip_enable_network_lookup2 (struct connected *connected)
! 796: {
! 797: struct prefix_ipv4 address;
! 798: struct prefix *p;
! 799:
! 800: p = connected->address;
! 801:
! 802: if (p->family == AF_INET) {
! 803: struct route_node *node;
! 804:
! 805: address.family = p->family;
! 806: address.prefix = p->u.prefix4;
! 807: address.prefixlen = IPV4_MAX_BITLEN;
! 808:
! 809: /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
! 810: node = route_node_match (rip_enable_network,
! 811: (struct prefix *)&address);
! 812:
! 813: if (node) {
! 814: route_unlock_node (node);
! 815: return 1;
! 816: }
! 817: }
! 818:
! 819: return -1;
! 820: }
! 821: /* Add RIP enable network. */
! 822: static int
! 823: rip_enable_network_add (struct prefix *p)
! 824: {
! 825: struct route_node *node;
! 826:
! 827: node = route_node_get (rip_enable_network, p);
! 828:
! 829: if (node->info)
! 830: {
! 831: route_unlock_node (node);
! 832: return -1;
! 833: }
! 834: else
! 835: node->info = (char *) "enabled";
! 836:
! 837: /* XXX: One should find a better solution than a generic one */
! 838: rip_enable_apply_all();
! 839:
! 840: return 1;
! 841: }
! 842:
! 843: /* Delete RIP enable network. */
! 844: static int
! 845: rip_enable_network_delete (struct prefix *p)
! 846: {
! 847: struct route_node *node;
! 848:
! 849: node = route_node_lookup (rip_enable_network, p);
! 850: if (node)
! 851: {
! 852: node->info = NULL;
! 853:
! 854: /* Unlock info lock. */
! 855: route_unlock_node (node);
! 856:
! 857: /* Unlock lookup lock. */
! 858: route_unlock_node (node);
! 859:
! 860: /* XXX: One should find a better solution than a generic one */
! 861: rip_enable_apply_all ();
! 862:
! 863: return 1;
! 864: }
! 865: return -1;
! 866: }
! 867:
! 868: /* Check interface is enabled by ifname statement. */
! 869: static int
! 870: rip_enable_if_lookup (const char *ifname)
! 871: {
! 872: unsigned int i;
! 873: char *str;
! 874:
! 875: for (i = 0; i < vector_active (rip_enable_interface); i++)
! 876: if ((str = vector_slot (rip_enable_interface, i)) != NULL)
! 877: if (strcmp (str, ifname) == 0)
! 878: return i;
! 879: return -1;
! 880: }
! 881:
! 882: /* Add interface to rip_enable_if. */
! 883: static int
! 884: rip_enable_if_add (const char *ifname)
! 885: {
! 886: int ret;
! 887:
! 888: ret = rip_enable_if_lookup (ifname);
! 889: if (ret >= 0)
! 890: return -1;
! 891:
! 892: vector_set (rip_enable_interface, strdup (ifname));
! 893:
! 894: rip_enable_apply_all(); /* TODOVJ */
! 895:
! 896: return 1;
! 897: }
! 898:
! 899: /* Delete interface from rip_enable_if. */
! 900: static int
! 901: rip_enable_if_delete (const char *ifname)
! 902: {
! 903: int index;
! 904: char *str;
! 905:
! 906: index = rip_enable_if_lookup (ifname);
! 907: if (index < 0)
! 908: return -1;
! 909:
! 910: str = vector_slot (rip_enable_interface, index);
! 911: free (str);
! 912: vector_unset (rip_enable_interface, index);
! 913:
! 914: rip_enable_apply_all(); /* TODOVJ */
! 915:
! 916: return 1;
! 917: }
! 918:
! 919: /* Join to multicast group and send request to the interface. */
! 920: static int
! 921: rip_interface_wakeup (struct thread *t)
! 922: {
! 923: struct interface *ifp;
! 924: struct rip_interface *ri;
! 925:
! 926: /* Get interface. */
! 927: ifp = THREAD_ARG (t);
! 928:
! 929: ri = ifp->info;
! 930: ri->t_wakeup = NULL;
! 931:
! 932: /* Join to multicast group. */
! 933: if (rip_multicast_join (ifp, rip->sock) < 0)
! 934: {
! 935: zlog_err ("multicast join failed, interface %s not running", ifp->name);
! 936: return 0;
! 937: }
! 938:
! 939: /* Set running flag. */
! 940: ri->running = 1;
! 941:
! 942: /* Send RIP request to the interface. */
! 943: rip_request_interface (ifp);
! 944:
! 945: return 0;
! 946: }
! 947:
! 948: static void
! 949: rip_connect_set (struct interface *ifp, int set)
! 950: {
! 951: struct listnode *node, *nnode;
! 952: struct connected *connected;
! 953: struct prefix_ipv4 address;
! 954:
! 955: for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
! 956: {
! 957: struct prefix *p;
! 958: p = connected->address;
! 959:
! 960: if (p->family != AF_INET)
! 961: continue;
! 962:
! 963: address.family = AF_INET;
! 964: address.prefix = p->u.prefix4;
! 965: address.prefixlen = p->prefixlen;
! 966: apply_mask_ipv4 (&address);
! 967:
! 968: if (set) {
! 969: /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
! 970: if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
! 971: (rip_enable_network_lookup2(connected) >= 0))
! 972: rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
! 973: &address, connected->ifp->ifindex,
! 974: NULL, 0, 0);
! 975: } else
! 976: {
! 977: rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
! 978: &address, connected->ifp->ifindex);
! 979: if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
! 980: rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
! 981: &address, connected->ifp->ifindex,
! 982: NULL, 0, 0);
! 983: }
! 984: }
! 985: }
! 986:
! 987: /* Update interface status. */
! 988: void
! 989: rip_enable_apply (struct interface *ifp)
! 990: {
! 991: int ret;
! 992: struct rip_interface *ri = NULL;
! 993:
! 994: /* Check interface. */
! 995: if (! if_is_operative (ifp))
! 996: return;
! 997:
! 998: ri = ifp->info;
! 999:
! 1000: /* Check network configuration. */
! 1001: ret = rip_enable_network_lookup_if (ifp);
! 1002:
! 1003: /* If the interface is matched. */
! 1004: if (ret > 0)
! 1005: ri->enable_network = 1;
! 1006: else
! 1007: ri->enable_network = 0;
! 1008:
! 1009: /* Check interface name configuration. */
! 1010: ret = rip_enable_if_lookup (ifp->name);
! 1011: if (ret >= 0)
! 1012: ri->enable_interface = 1;
! 1013: else
! 1014: ri->enable_interface = 0;
! 1015:
! 1016: /* any interface MUST have an IPv4 address */
! 1017: if ( ! rip_if_ipv4_address_check (ifp) )
! 1018: {
! 1019: ri->enable_network = 0;
! 1020: ri->enable_interface = 0;
! 1021: }
! 1022:
! 1023: /* Update running status of the interface. */
! 1024: if (ri->enable_network || ri->enable_interface)
! 1025: {
! 1026: {
! 1027: if (IS_RIP_DEBUG_EVENT)
! 1028: zlog_debug ("turn on %s", ifp->name);
! 1029:
! 1030: /* Add interface wake up thread. */
! 1031: if (! ri->t_wakeup)
! 1032: ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
! 1033: ifp, 1);
! 1034: rip_connect_set (ifp, 1);
! 1035: }
! 1036: }
! 1037: else
! 1038: {
! 1039: if (ri->running)
! 1040: {
! 1041: /* Might as well clean up the route table as well
! 1042: * rip_if_down sets to 0 ri->running, and displays "turn off %s"
! 1043: **/
! 1044: rip_if_down(ifp);
! 1045:
! 1046: rip_connect_set (ifp, 0);
! 1047: }
! 1048: }
! 1049: }
! 1050:
! 1051: /* Apply network configuration to all interface. */
! 1052: void
! 1053: rip_enable_apply_all ()
! 1054: {
! 1055: struct interface *ifp;
! 1056: struct listnode *node, *nnode;
! 1057:
! 1058: /* Check each interface. */
! 1059: for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
! 1060: rip_enable_apply (ifp);
! 1061: }
! 1062:
! 1063: int
! 1064: rip_neighbor_lookup (struct sockaddr_in *from)
! 1065: {
! 1066: struct prefix_ipv4 p;
! 1067: struct route_node *node;
! 1068:
! 1069: memset (&p, 0, sizeof (struct prefix_ipv4));
! 1070: p.family = AF_INET;
! 1071: p.prefix = from->sin_addr;
! 1072: p.prefixlen = IPV4_MAX_BITLEN;
! 1073:
! 1074: node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
! 1075: if (node)
! 1076: {
! 1077: route_unlock_node (node);
! 1078: return 1;
! 1079: }
! 1080: return 0;
! 1081: }
! 1082:
! 1083: /* Add new RIP neighbor to the neighbor tree. */
! 1084: static int
! 1085: rip_neighbor_add (struct prefix_ipv4 *p)
! 1086: {
! 1087: struct route_node *node;
! 1088:
! 1089: node = route_node_get (rip->neighbor, (struct prefix *) p);
! 1090:
! 1091: if (node->info)
! 1092: return -1;
! 1093:
! 1094: node->info = rip->neighbor;
! 1095:
! 1096: return 0;
! 1097: }
! 1098:
! 1099: /* Delete RIP neighbor from the neighbor tree. */
! 1100: static int
! 1101: rip_neighbor_delete (struct prefix_ipv4 *p)
! 1102: {
! 1103: struct route_node *node;
! 1104:
! 1105: /* Lock for look up. */
! 1106: node = route_node_lookup (rip->neighbor, (struct prefix *) p);
! 1107: if (! node)
! 1108: return -1;
! 1109:
! 1110: node->info = NULL;
! 1111:
! 1112: /* Unlock lookup lock. */
! 1113: route_unlock_node (node);
! 1114:
! 1115: /* Unlock real neighbor information lock. */
! 1116: route_unlock_node (node);
! 1117:
! 1118: return 0;
! 1119: }
! 1120:
! 1121: /* Clear all network and neighbor configuration. */
! 1122: void
! 1123: rip_clean_network ()
! 1124: {
! 1125: unsigned int i;
! 1126: char *str;
! 1127: struct route_node *rn;
! 1128:
! 1129: /* rip_enable_network. */
! 1130: for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
! 1131: if (rn->info)
! 1132: {
! 1133: rn->info = NULL;
! 1134: route_unlock_node (rn);
! 1135: }
! 1136:
! 1137: /* rip_enable_interface. */
! 1138: for (i = 0; i < vector_active (rip_enable_interface); i++)
! 1139: if ((str = vector_slot (rip_enable_interface, i)) != NULL)
! 1140: {
! 1141: free (str);
! 1142: vector_slot (rip_enable_interface, i) = NULL;
! 1143: }
! 1144: }
! 1145:
! 1146: /* Utility function for looking up passive interface settings. */
! 1147: static int
! 1148: rip_passive_nondefault_lookup (const char *ifname)
! 1149: {
! 1150: unsigned int i;
! 1151: char *str;
! 1152:
! 1153: for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
! 1154: if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
! 1155: if (strcmp (str, ifname) == 0)
! 1156: return i;
! 1157: return -1;
! 1158: }
! 1159:
! 1160: void
! 1161: rip_passive_interface_apply (struct interface *ifp)
! 1162: {
! 1163: struct rip_interface *ri;
! 1164:
! 1165: ri = ifp->info;
! 1166:
! 1167: ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
! 1168: passive_default : !passive_default);
! 1169:
! 1170: if (IS_RIP_DEBUG_ZEBRA)
! 1171: zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
! 1172: }
! 1173:
! 1174: static void
! 1175: rip_passive_interface_apply_all (void)
! 1176: {
! 1177: struct interface *ifp;
! 1178: struct listnode *node, *nnode;
! 1179:
! 1180: for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
! 1181: rip_passive_interface_apply (ifp);
! 1182: }
! 1183:
! 1184: /* Passive interface. */
! 1185: static int
! 1186: rip_passive_nondefault_set (struct vty *vty, const char *ifname)
! 1187: {
! 1188: if (rip_passive_nondefault_lookup (ifname) >= 0)
! 1189: return CMD_WARNING;
! 1190:
! 1191: vector_set (Vrip_passive_nondefault, strdup (ifname));
! 1192:
! 1193: rip_passive_interface_apply_all ();
! 1194:
! 1195: return CMD_SUCCESS;
! 1196: }
! 1197:
! 1198: static int
! 1199: rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
! 1200: {
! 1201: int i;
! 1202: char *str;
! 1203:
! 1204: i = rip_passive_nondefault_lookup (ifname);
! 1205: if (i < 0)
! 1206: return CMD_WARNING;
! 1207:
! 1208: str = vector_slot (Vrip_passive_nondefault, i);
! 1209: free (str);
! 1210: vector_unset (Vrip_passive_nondefault, i);
! 1211:
! 1212: rip_passive_interface_apply_all ();
! 1213:
! 1214: return CMD_SUCCESS;
! 1215: }
! 1216:
! 1217: /* Free all configured RIP passive-interface settings. */
! 1218: void
! 1219: rip_passive_nondefault_clean (void)
! 1220: {
! 1221: unsigned int i;
! 1222: char *str;
! 1223:
! 1224: for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
! 1225: if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
! 1226: {
! 1227: free (str);
! 1228: vector_slot (Vrip_passive_nondefault, i) = NULL;
! 1229: }
! 1230: rip_passive_interface_apply_all ();
! 1231: }
! 1232:
! 1233: /* RIP enable network or interface configuration. */
! 1234: DEFUN (rip_network,
! 1235: rip_network_cmd,
! 1236: "network (A.B.C.D/M|WORD)",
! 1237: "Enable routing on an IP network\n"
! 1238: "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
! 1239: "Interface name\n")
! 1240: {
! 1241: int ret;
! 1242: struct prefix_ipv4 p;
! 1243:
! 1244: ret = str2prefix_ipv4 (argv[0], &p);
! 1245:
! 1246: if (ret)
! 1247: ret = rip_enable_network_add ((struct prefix *) &p);
! 1248: else
! 1249: ret = rip_enable_if_add (argv[0]);
! 1250:
! 1251: if (ret < 0)
! 1252: {
! 1253: vty_out (vty, "There is a same network configuration %s%s", argv[0],
! 1254: VTY_NEWLINE);
! 1255: return CMD_WARNING;
! 1256: }
! 1257:
! 1258: return CMD_SUCCESS;
! 1259: }
! 1260:
! 1261: /* RIP enable network or interface configuration. */
! 1262: DEFUN (no_rip_network,
! 1263: no_rip_network_cmd,
! 1264: "no network (A.B.C.D/M|WORD)",
! 1265: NO_STR
! 1266: "Enable routing on an IP network\n"
! 1267: "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
! 1268: "Interface name\n")
! 1269: {
! 1270: int ret;
! 1271: struct prefix_ipv4 p;
! 1272:
! 1273: ret = str2prefix_ipv4 (argv[0], &p);
! 1274:
! 1275: if (ret)
! 1276: ret = rip_enable_network_delete ((struct prefix *) &p);
! 1277: else
! 1278: ret = rip_enable_if_delete (argv[0]);
! 1279:
! 1280: if (ret < 0)
! 1281: {
! 1282: vty_out (vty, "Can't find network configuration %s%s", argv[0],
! 1283: VTY_NEWLINE);
! 1284: return CMD_WARNING;
! 1285: }
! 1286:
! 1287: return CMD_SUCCESS;
! 1288: }
! 1289:
! 1290: /* RIP neighbor configuration set. */
! 1291: DEFUN (rip_neighbor,
! 1292: rip_neighbor_cmd,
! 1293: "neighbor A.B.C.D",
! 1294: "Specify a neighbor router\n"
! 1295: "Neighbor address\n")
! 1296: {
! 1297: int ret;
! 1298: struct prefix_ipv4 p;
! 1299:
! 1300: ret = str2prefix_ipv4 (argv[0], &p);
! 1301:
! 1302: if (ret <= 0)
! 1303: {
! 1304: vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
! 1305: return CMD_WARNING;
! 1306: }
! 1307:
! 1308: rip_neighbor_add (&p);
! 1309:
! 1310: return CMD_SUCCESS;
! 1311: }
! 1312:
! 1313: /* RIP neighbor configuration unset. */
! 1314: DEFUN (no_rip_neighbor,
! 1315: no_rip_neighbor_cmd,
! 1316: "no neighbor A.B.C.D",
! 1317: NO_STR
! 1318: "Specify a neighbor router\n"
! 1319: "Neighbor address\n")
! 1320: {
! 1321: int ret;
! 1322: struct prefix_ipv4 p;
! 1323:
! 1324: ret = str2prefix_ipv4 (argv[0], &p);
! 1325:
! 1326: if (ret <= 0)
! 1327: {
! 1328: vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
! 1329: return CMD_WARNING;
! 1330: }
! 1331:
! 1332: rip_neighbor_delete (&p);
! 1333:
! 1334: return CMD_SUCCESS;
! 1335: }
! 1336:
! 1337: DEFUN (ip_rip_receive_version,
! 1338: ip_rip_receive_version_cmd,
! 1339: "ip rip receive version (1|2)",
! 1340: IP_STR
! 1341: "Routing Information Protocol\n"
! 1342: "Advertisement reception\n"
! 1343: "Version control\n"
! 1344: "RIP version 1\n"
! 1345: "RIP version 2\n")
! 1346: {
! 1347: struct interface *ifp;
! 1348: struct rip_interface *ri;
! 1349:
! 1350: ifp = (struct interface *)vty->index;
! 1351: ri = ifp->info;
! 1352:
! 1353: /* Version 1. */
! 1354: if (atoi (argv[0]) == 1)
! 1355: {
! 1356: ri->ri_receive = RI_RIP_VERSION_1;
! 1357: return CMD_SUCCESS;
! 1358: }
! 1359: if (atoi (argv[0]) == 2)
! 1360: {
! 1361: ri->ri_receive = RI_RIP_VERSION_2;
! 1362: return CMD_SUCCESS;
! 1363: }
! 1364: return CMD_WARNING;
! 1365: }
! 1366:
! 1367: DEFUN (ip_rip_receive_version_1,
! 1368: ip_rip_receive_version_1_cmd,
! 1369: "ip rip receive version 1 2",
! 1370: IP_STR
! 1371: "Routing Information Protocol\n"
! 1372: "Advertisement reception\n"
! 1373: "Version control\n"
! 1374: "RIP version 1\n"
! 1375: "RIP version 2\n")
! 1376: {
! 1377: struct interface *ifp;
! 1378: struct rip_interface *ri;
! 1379:
! 1380: ifp = (struct interface *)vty->index;
! 1381: ri = ifp->info;
! 1382:
! 1383: /* Version 1 and 2. */
! 1384: ri->ri_receive = RI_RIP_VERSION_1_AND_2;
! 1385: return CMD_SUCCESS;
! 1386: }
! 1387:
! 1388: DEFUN (ip_rip_receive_version_2,
! 1389: ip_rip_receive_version_2_cmd,
! 1390: "ip rip receive version 2 1",
! 1391: IP_STR
! 1392: "Routing Information Protocol\n"
! 1393: "Advertisement reception\n"
! 1394: "Version control\n"
! 1395: "RIP version 2\n"
! 1396: "RIP version 1\n")
! 1397: {
! 1398: struct interface *ifp;
! 1399: struct rip_interface *ri;
! 1400:
! 1401: ifp = (struct interface *)vty->index;
! 1402: ri = ifp->info;
! 1403:
! 1404: /* Version 1 and 2. */
! 1405: ri->ri_receive = RI_RIP_VERSION_1_AND_2;
! 1406: return CMD_SUCCESS;
! 1407: }
! 1408:
! 1409: DEFUN (no_ip_rip_receive_version,
! 1410: no_ip_rip_receive_version_cmd,
! 1411: "no ip rip receive version",
! 1412: NO_STR
! 1413: IP_STR
! 1414: "Routing Information Protocol\n"
! 1415: "Advertisement reception\n"
! 1416: "Version control\n")
! 1417: {
! 1418: struct interface *ifp;
! 1419: struct rip_interface *ri;
! 1420:
! 1421: ifp = (struct interface *)vty->index;
! 1422: ri = ifp->info;
! 1423:
! 1424: ri->ri_receive = RI_RIP_UNSPEC;
! 1425: return CMD_SUCCESS;
! 1426: }
! 1427:
! 1428: ALIAS (no_ip_rip_receive_version,
! 1429: no_ip_rip_receive_version_num_cmd,
! 1430: "no ip rip receive version (1|2)",
! 1431: NO_STR
! 1432: IP_STR
! 1433: "Routing Information Protocol\n"
! 1434: "Advertisement reception\n"
! 1435: "Version control\n"
! 1436: "Version 1\n"
! 1437: "Version 2\n")
! 1438:
! 1439: DEFUN (ip_rip_send_version,
! 1440: ip_rip_send_version_cmd,
! 1441: "ip rip send version (1|2)",
! 1442: IP_STR
! 1443: "Routing Information Protocol\n"
! 1444: "Advertisement transmission\n"
! 1445: "Version control\n"
! 1446: "RIP version 1\n"
! 1447: "RIP version 2\n")
! 1448: {
! 1449: struct interface *ifp;
! 1450: struct rip_interface *ri;
! 1451:
! 1452: ifp = (struct interface *)vty->index;
! 1453: ri = ifp->info;
! 1454:
! 1455: /* Version 1. */
! 1456: if (atoi (argv[0]) == 1)
! 1457: {
! 1458: ri->ri_send = RI_RIP_VERSION_1;
! 1459: return CMD_SUCCESS;
! 1460: }
! 1461: if (atoi (argv[0]) == 2)
! 1462: {
! 1463: ri->ri_send = RI_RIP_VERSION_2;
! 1464: return CMD_SUCCESS;
! 1465: }
! 1466: return CMD_WARNING;
! 1467: }
! 1468:
! 1469: DEFUN (ip_rip_send_version_1,
! 1470: ip_rip_send_version_1_cmd,
! 1471: "ip rip send version 1 2",
! 1472: IP_STR
! 1473: "Routing Information Protocol\n"
! 1474: "Advertisement transmission\n"
! 1475: "Version control\n"
! 1476: "RIP version 1\n"
! 1477: "RIP version 2\n")
! 1478: {
! 1479: struct interface *ifp;
! 1480: struct rip_interface *ri;
! 1481:
! 1482: ifp = (struct interface *)vty->index;
! 1483: ri = ifp->info;
! 1484:
! 1485: /* Version 1 and 2. */
! 1486: ri->ri_send = RI_RIP_VERSION_1_AND_2;
! 1487: return CMD_SUCCESS;
! 1488: }
! 1489:
! 1490: DEFUN (ip_rip_send_version_2,
! 1491: ip_rip_send_version_2_cmd,
! 1492: "ip rip send version 2 1",
! 1493: IP_STR
! 1494: "Routing Information Protocol\n"
! 1495: "Advertisement transmission\n"
! 1496: "Version control\n"
! 1497: "RIP version 2\n"
! 1498: "RIP version 1\n")
! 1499: {
! 1500: struct interface *ifp;
! 1501: struct rip_interface *ri;
! 1502:
! 1503: ifp = (struct interface *)vty->index;
! 1504: ri = ifp->info;
! 1505:
! 1506: /* Version 1 and 2. */
! 1507: ri->ri_send = RI_RIP_VERSION_1_AND_2;
! 1508: return CMD_SUCCESS;
! 1509: }
! 1510:
! 1511: DEFUN (no_ip_rip_send_version,
! 1512: no_ip_rip_send_version_cmd,
! 1513: "no ip rip send version",
! 1514: NO_STR
! 1515: IP_STR
! 1516: "Routing Information Protocol\n"
! 1517: "Advertisement transmission\n"
! 1518: "Version control\n")
! 1519: {
! 1520: struct interface *ifp;
! 1521: struct rip_interface *ri;
! 1522:
! 1523: ifp = (struct interface *)vty->index;
! 1524: ri = ifp->info;
! 1525:
! 1526: ri->ri_send = RI_RIP_UNSPEC;
! 1527: return CMD_SUCCESS;
! 1528: }
! 1529:
! 1530: ALIAS (no_ip_rip_send_version,
! 1531: no_ip_rip_send_version_num_cmd,
! 1532: "no ip rip send version (1|2)",
! 1533: NO_STR
! 1534: IP_STR
! 1535: "Routing Information Protocol\n"
! 1536: "Advertisement transmission\n"
! 1537: "Version control\n"
! 1538: "Version 1\n"
! 1539: "Version 2\n")
! 1540:
! 1541: DEFUN (ip_rip_authentication_mode,
! 1542: ip_rip_authentication_mode_cmd,
! 1543: "ip rip authentication mode (md5|text)",
! 1544: IP_STR
! 1545: "Routing Information Protocol\n"
! 1546: "Authentication control\n"
! 1547: "Authentication mode\n"
! 1548: "Keyed message digest\n"
! 1549: "Clear text authentication\n")
! 1550: {
! 1551: struct interface *ifp;
! 1552: struct rip_interface *ri;
! 1553: int auth_type;
! 1554:
! 1555: ifp = (struct interface *)vty->index;
! 1556: ri = ifp->info;
! 1557:
! 1558: if ( (argc < 1) || (argc > 2) )
! 1559: {
! 1560: vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
! 1561: return CMD_WARNING;
! 1562: }
! 1563:
! 1564: if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
! 1565: auth_type = RIP_AUTH_MD5;
! 1566: else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
! 1567: auth_type = RIP_AUTH_SIMPLE_PASSWORD;
! 1568: else
! 1569: {
! 1570: vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
! 1571: return CMD_WARNING;
! 1572: }
! 1573:
! 1574: if (argc == 1)
! 1575: {
! 1576: ri->auth_type = auth_type;
! 1577: return CMD_SUCCESS;
! 1578: }
! 1579:
! 1580: if ( (argc == 2) && (auth_type != RIP_AUTH_MD5) )
! 1581: {
! 1582: vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
! 1583: return CMD_WARNING;
! 1584: }
! 1585:
! 1586: if (strncmp ("r", argv[1], 1) == 0)
! 1587: ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
! 1588: else if (strncmp ("o", argv[1], 1) == 0)
! 1589: ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
! 1590: else
! 1591: return CMD_WARNING;
! 1592:
! 1593: ri->auth_type = auth_type;
! 1594:
! 1595: return CMD_SUCCESS;
! 1596: }
! 1597:
! 1598: ALIAS (ip_rip_authentication_mode,
! 1599: ip_rip_authentication_mode_authlen_cmd,
! 1600: "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
! 1601: IP_STR
! 1602: "Routing Information Protocol\n"
! 1603: "Authentication control\n"
! 1604: "Authentication mode\n"
! 1605: "Keyed message digest\n"
! 1606: "Clear text authentication\n"
! 1607: "MD5 authentication data length\n"
! 1608: "RFC compatible\n"
! 1609: "Old ripd compatible\n")
! 1610:
! 1611: DEFUN (no_ip_rip_authentication_mode,
! 1612: no_ip_rip_authentication_mode_cmd,
! 1613: "no ip rip authentication mode",
! 1614: NO_STR
! 1615: IP_STR
! 1616: "Routing Information Protocol\n"
! 1617: "Authentication control\n"
! 1618: "Authentication mode\n")
! 1619: {
! 1620: struct interface *ifp;
! 1621: struct rip_interface *ri;
! 1622:
! 1623: ifp = (struct interface *)vty->index;
! 1624: ri = ifp->info;
! 1625:
! 1626: ri->auth_type = RIP_NO_AUTH;
! 1627: ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
! 1628:
! 1629: return CMD_SUCCESS;
! 1630: }
! 1631:
! 1632: ALIAS (no_ip_rip_authentication_mode,
! 1633: no_ip_rip_authentication_mode_type_cmd,
! 1634: "no ip rip authentication mode (md5|text)",
! 1635: NO_STR
! 1636: IP_STR
! 1637: "Routing Information Protocol\n"
! 1638: "Authentication control\n"
! 1639: "Authentication mode\n"
! 1640: "Keyed message digest\n"
! 1641: "Clear text authentication\n")
! 1642:
! 1643: ALIAS (no_ip_rip_authentication_mode,
! 1644: no_ip_rip_authentication_mode_type_authlen_cmd,
! 1645: "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
! 1646: NO_STR
! 1647: IP_STR
! 1648: "Routing Information Protocol\n"
! 1649: "Authentication control\n"
! 1650: "Authentication mode\n"
! 1651: "Keyed message digest\n"
! 1652: "Clear text authentication\n"
! 1653: "MD5 authentication data length\n"
! 1654: "RFC compatible\n"
! 1655: "Old ripd compatible\n")
! 1656:
! 1657: DEFUN (ip_rip_authentication_string,
! 1658: ip_rip_authentication_string_cmd,
! 1659: "ip rip authentication string LINE",
! 1660: IP_STR
! 1661: "Routing Information Protocol\n"
! 1662: "Authentication control\n"
! 1663: "Authentication string\n"
! 1664: "Authentication string\n")
! 1665: {
! 1666: struct interface *ifp;
! 1667: struct rip_interface *ri;
! 1668:
! 1669: ifp = (struct interface *)vty->index;
! 1670: ri = ifp->info;
! 1671:
! 1672: if (strlen (argv[0]) > 16)
! 1673: {
! 1674: vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
! 1675: VTY_NEWLINE);
! 1676: return CMD_WARNING;
! 1677: }
! 1678:
! 1679: if (ri->key_chain)
! 1680: {
! 1681: vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
! 1682: return CMD_WARNING;
! 1683: }
! 1684:
! 1685: if (ri->auth_str)
! 1686: free (ri->auth_str);
! 1687:
! 1688: ri->auth_str = strdup (argv[0]);
! 1689:
! 1690: return CMD_SUCCESS;
! 1691: }
! 1692:
! 1693: DEFUN (no_ip_rip_authentication_string,
! 1694: no_ip_rip_authentication_string_cmd,
! 1695: "no ip rip authentication string",
! 1696: NO_STR
! 1697: IP_STR
! 1698: "Routing Information Protocol\n"
! 1699: "Authentication control\n"
! 1700: "Authentication string\n")
! 1701: {
! 1702: struct interface *ifp;
! 1703: struct rip_interface *ri;
! 1704:
! 1705: ifp = (struct interface *)vty->index;
! 1706: ri = ifp->info;
! 1707:
! 1708: if (ri->auth_str)
! 1709: free (ri->auth_str);
! 1710:
! 1711: ri->auth_str = NULL;
! 1712:
! 1713: return CMD_SUCCESS;
! 1714: }
! 1715:
! 1716: ALIAS (no_ip_rip_authentication_string,
! 1717: no_ip_rip_authentication_string2_cmd,
! 1718: "no ip rip authentication string LINE",
! 1719: NO_STR
! 1720: IP_STR
! 1721: "Routing Information Protocol\n"
! 1722: "Authentication control\n"
! 1723: "Authentication string\n"
! 1724: "Authentication string\n")
! 1725:
! 1726: DEFUN (ip_rip_authentication_key_chain,
! 1727: ip_rip_authentication_key_chain_cmd,
! 1728: "ip rip authentication key-chain LINE",
! 1729: IP_STR
! 1730: "Routing Information Protocol\n"
! 1731: "Authentication control\n"
! 1732: "Authentication key-chain\n"
! 1733: "name of key-chain\n")
! 1734: {
! 1735: struct interface *ifp;
! 1736: struct rip_interface *ri;
! 1737:
! 1738: ifp = (struct interface *) vty->index;
! 1739: ri = ifp->info;
! 1740:
! 1741: if (ri->auth_str)
! 1742: {
! 1743: vty_out (vty, "%% authentication string configuration exists%s",
! 1744: VTY_NEWLINE);
! 1745: return CMD_WARNING;
! 1746: }
! 1747:
! 1748: if (ri->key_chain)
! 1749: free (ri->key_chain);
! 1750:
! 1751: ri->key_chain = strdup (argv[0]);
! 1752:
! 1753: return CMD_SUCCESS;
! 1754: }
! 1755:
! 1756: DEFUN (no_ip_rip_authentication_key_chain,
! 1757: no_ip_rip_authentication_key_chain_cmd,
! 1758: "no ip rip authentication key-chain",
! 1759: NO_STR
! 1760: IP_STR
! 1761: "Routing Information Protocol\n"
! 1762: "Authentication control\n"
! 1763: "Authentication key-chain\n")
! 1764: {
! 1765: struct interface *ifp;
! 1766: struct rip_interface *ri;
! 1767:
! 1768: ifp = (struct interface *) vty->index;
! 1769: ri = ifp->info;
! 1770:
! 1771: if (ri->key_chain)
! 1772: free (ri->key_chain);
! 1773:
! 1774: ri->key_chain = NULL;
! 1775:
! 1776: return CMD_SUCCESS;
! 1777: }
! 1778:
! 1779: ALIAS (no_ip_rip_authentication_key_chain,
! 1780: no_ip_rip_authentication_key_chain2_cmd,
! 1781: "no ip rip authentication key-chain LINE",
! 1782: NO_STR
! 1783: IP_STR
! 1784: "Routing Information Protocol\n"
! 1785: "Authentication control\n"
! 1786: "Authentication key-chain\n"
! 1787: "name of key-chain\n")
! 1788:
! 1789: /* CHANGED: ip rip split-horizon
! 1790: Cisco and Zebra's command is
! 1791: ip split-horizon
! 1792: */
! 1793: DEFUN (ip_rip_split_horizon,
! 1794: ip_rip_split_horizon_cmd,
! 1795: "ip rip split-horizon",
! 1796: IP_STR
! 1797: "Routing Information Protocol\n"
! 1798: "Perform split horizon\n")
! 1799: {
! 1800: struct interface *ifp;
! 1801: struct rip_interface *ri;
! 1802:
! 1803: ifp = vty->index;
! 1804: ri = ifp->info;
! 1805:
! 1806: ri->split_horizon = RIP_SPLIT_HORIZON;
! 1807: return CMD_SUCCESS;
! 1808: }
! 1809:
! 1810: DEFUN (ip_rip_split_horizon_poisoned_reverse,
! 1811: ip_rip_split_horizon_poisoned_reverse_cmd,
! 1812: "ip rip split-horizon poisoned-reverse",
! 1813: IP_STR
! 1814: "Routing Information Protocol\n"
! 1815: "Perform split horizon\n"
! 1816: "With poisoned-reverse\n")
! 1817: {
! 1818: struct interface *ifp;
! 1819: struct rip_interface *ri;
! 1820:
! 1821: ifp = vty->index;
! 1822: ri = ifp->info;
! 1823:
! 1824: ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
! 1825: return CMD_SUCCESS;
! 1826: }
! 1827:
! 1828: /* CHANGED: no ip rip split-horizon
! 1829: Cisco and Zebra's command is
! 1830: no ip split-horizon
! 1831: */
! 1832: DEFUN (no_ip_rip_split_horizon,
! 1833: no_ip_rip_split_horizon_cmd,
! 1834: "no ip rip split-horizon",
! 1835: NO_STR
! 1836: IP_STR
! 1837: "Routing Information Protocol\n"
! 1838: "Perform split horizon\n")
! 1839: {
! 1840: struct interface *ifp;
! 1841: struct rip_interface *ri;
! 1842:
! 1843: ifp = vty->index;
! 1844: ri = ifp->info;
! 1845:
! 1846: ri->split_horizon = RIP_NO_SPLIT_HORIZON;
! 1847: return CMD_SUCCESS;
! 1848: }
! 1849:
! 1850: DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
! 1851: no_ip_rip_split_horizon_poisoned_reverse_cmd,
! 1852: "no ip rip split-horizon poisoned-reverse",
! 1853: NO_STR
! 1854: IP_STR
! 1855: "Routing Information Protocol\n"
! 1856: "Perform split horizon\n"
! 1857: "With poisoned-reverse\n")
! 1858: {
! 1859: struct interface *ifp;
! 1860: struct rip_interface *ri;
! 1861:
! 1862: ifp = vty->index;
! 1863: ri = ifp->info;
! 1864:
! 1865: switch( ri->split_horizon )
! 1866: {
! 1867: case RIP_SPLIT_HORIZON_POISONED_REVERSE:
! 1868: ri->split_horizon = RIP_SPLIT_HORIZON;
! 1869: default:
! 1870: break;
! 1871: }
! 1872:
! 1873: return CMD_SUCCESS;
! 1874: }
! 1875:
! 1876: DEFUN (rip_passive_interface,
! 1877: rip_passive_interface_cmd,
! 1878: "passive-interface (IFNAME|default)",
! 1879: "Suppress routing updates on an interface\n"
! 1880: "Interface name\n"
! 1881: "default for all interfaces\n")
! 1882: {
! 1883: const char *ifname = argv[0];
! 1884:
! 1885: if (!strcmp(ifname,"default")) {
! 1886: passive_default = 1;
! 1887: rip_passive_nondefault_clean();
! 1888: return CMD_SUCCESS;
! 1889: }
! 1890: if (passive_default)
! 1891: return rip_passive_nondefault_unset (vty, ifname);
! 1892: else
! 1893: return rip_passive_nondefault_set (vty, ifname);
! 1894: }
! 1895:
! 1896: DEFUN (no_rip_passive_interface,
! 1897: no_rip_passive_interface_cmd,
! 1898: "no passive-interface (IFNAME|default)",
! 1899: NO_STR
! 1900: "Suppress routing updates on an interface\n"
! 1901: "Interface name\n"
! 1902: "default for all interfaces\n")
! 1903: {
! 1904: const char *ifname = argv[0];
! 1905:
! 1906: if (!strcmp(ifname,"default")) {
! 1907: passive_default = 0;
! 1908: rip_passive_nondefault_clean();
! 1909: return CMD_SUCCESS;
! 1910: }
! 1911: if (passive_default)
! 1912: return rip_passive_nondefault_set (vty, ifname);
! 1913: else
! 1914: return rip_passive_nondefault_unset (vty, ifname);
! 1915: }
! 1916:
! 1917: /* Write rip configuration of each interface. */
! 1918: static int
! 1919: rip_interface_config_write (struct vty *vty)
! 1920: {
! 1921: struct listnode *node;
! 1922: struct interface *ifp;
! 1923:
! 1924: for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
! 1925: {
! 1926: struct rip_interface *ri;
! 1927:
! 1928: ri = ifp->info;
! 1929:
! 1930: /* Do not display the interface if there is no
! 1931: * configuration about it.
! 1932: **/
! 1933: if ((!ifp->desc) &&
! 1934: (ri->split_horizon == ri->split_horizon_default) &&
! 1935: (ri->ri_send == RI_RIP_UNSPEC) &&
! 1936: (ri->ri_receive == RI_RIP_UNSPEC) &&
! 1937: (ri->auth_type != RIP_AUTH_MD5) &&
! 1938: (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
! 1939: (!ri->auth_str) &&
! 1940: (!ri->key_chain) )
! 1941: continue;
! 1942:
! 1943: vty_out (vty, "interface %s%s", ifp->name,
! 1944: VTY_NEWLINE);
! 1945:
! 1946: if (ifp->desc)
! 1947: vty_out (vty, " description %s%s", ifp->desc,
! 1948: VTY_NEWLINE);
! 1949:
! 1950: /* Split horizon. */
! 1951: if (ri->split_horizon != ri->split_horizon_default)
! 1952: {
! 1953: switch (ri->split_horizon) {
! 1954: case RIP_SPLIT_HORIZON:
! 1955: vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
! 1956: break;
! 1957: case RIP_SPLIT_HORIZON_POISONED_REVERSE:
! 1958: vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
! 1959: VTY_NEWLINE);
! 1960: break;
! 1961: case RIP_NO_SPLIT_HORIZON:
! 1962: default:
! 1963: vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
! 1964: break;
! 1965: }
! 1966: }
! 1967:
! 1968: /* RIP version setting. */
! 1969: if (ri->ri_send != RI_RIP_UNSPEC)
! 1970: vty_out (vty, " ip rip send version %s%s",
! 1971: lookup (ri_version_msg, ri->ri_send),
! 1972: VTY_NEWLINE);
! 1973:
! 1974: if (ri->ri_receive != RI_RIP_UNSPEC)
! 1975: vty_out (vty, " ip rip receive version %s%s",
! 1976: lookup (ri_version_msg, ri->ri_receive),
! 1977: VTY_NEWLINE);
! 1978:
! 1979: /* RIP authentication. */
! 1980: if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
! 1981: vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
! 1982:
! 1983: if (ri->auth_type == RIP_AUTH_MD5)
! 1984: {
! 1985: vty_out (vty, " ip rip authentication mode md5");
! 1986: if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
! 1987: vty_out (vty, " auth-length old-ripd");
! 1988: else
! 1989: vty_out (vty, " auth-length rfc");
! 1990: vty_out (vty, "%s", VTY_NEWLINE);
! 1991: }
! 1992:
! 1993: if (ri->auth_str)
! 1994: vty_out (vty, " ip rip authentication string %s%s",
! 1995: ri->auth_str, VTY_NEWLINE);
! 1996:
! 1997: if (ri->key_chain)
! 1998: vty_out (vty, " ip rip authentication key-chain %s%s",
! 1999: ri->key_chain, VTY_NEWLINE);
! 2000:
! 2001: vty_out (vty, "!%s", VTY_NEWLINE);
! 2002: }
! 2003: return 0;
! 2004: }
! 2005:
! 2006: int
! 2007: config_write_rip_network (struct vty *vty, int config_mode)
! 2008: {
! 2009: unsigned int i;
! 2010: char *ifname;
! 2011: struct route_node *node;
! 2012:
! 2013: /* Network type RIP enable interface statement. */
! 2014: for (node = route_top (rip_enable_network); node; node = route_next (node))
! 2015: if (node->info)
! 2016: vty_out (vty, "%s%s/%d%s",
! 2017: config_mode ? " network " : " ",
! 2018: inet_ntoa (node->p.u.prefix4),
! 2019: node->p.prefixlen,
! 2020: VTY_NEWLINE);
! 2021:
! 2022: /* Interface name RIP enable statement. */
! 2023: for (i = 0; i < vector_active (rip_enable_interface); i++)
! 2024: if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
! 2025: vty_out (vty, "%s%s%s",
! 2026: config_mode ? " network " : " ",
! 2027: ifname,
! 2028: VTY_NEWLINE);
! 2029:
! 2030: /* RIP neighbors listing. */
! 2031: for (node = route_top (rip->neighbor); node; node = route_next (node))
! 2032: if (node->info)
! 2033: vty_out (vty, "%s%s%s",
! 2034: config_mode ? " neighbor " : " ",
! 2035: inet_ntoa (node->p.u.prefix4),
! 2036: VTY_NEWLINE);
! 2037:
! 2038: /* RIP passive interface listing. */
! 2039: if (config_mode) {
! 2040: if (passive_default)
! 2041: vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
! 2042: for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
! 2043: if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
! 2044: vty_out (vty, " %spassive-interface %s%s",
! 2045: (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
! 2046: }
! 2047:
! 2048: return 0;
! 2049: }
! 2050:
! 2051: static struct cmd_node interface_node =
! 2052: {
! 2053: INTERFACE_NODE,
! 2054: "%s(config-if)# ",
! 2055: 1,
! 2056: };
! 2057:
! 2058: /* Called when interface structure allocated. */
! 2059: static int
! 2060: rip_interface_new_hook (struct interface *ifp)
! 2061: {
! 2062: ifp->info = rip_interface_new ();
! 2063: return 0;
! 2064: }
! 2065:
! 2066: /* Called when interface structure deleted. */
! 2067: static int
! 2068: rip_interface_delete_hook (struct interface *ifp)
! 2069: {
! 2070: XFREE (MTYPE_RIP_INTERFACE, ifp->info);
! 2071: ifp->info = NULL;
! 2072: return 0;
! 2073: }
! 2074:
! 2075: /* Allocate and initialize interface vector. */
! 2076: void
! 2077: rip_if_init (void)
! 2078: {
! 2079: /* Default initial size of interface vector. */
! 2080: if_init();
! 2081: if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
! 2082: if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
! 2083:
! 2084: /* RIP network init. */
! 2085: rip_enable_interface = vector_init (1);
! 2086: rip_enable_network = route_table_init ();
! 2087:
! 2088: /* RIP passive interface. */
! 2089: Vrip_passive_nondefault = vector_init (1);
! 2090:
! 2091: /* Install interface node. */
! 2092: install_node (&interface_node, rip_interface_config_write);
! 2093:
! 2094: /* Install commands. */
! 2095: install_element (CONFIG_NODE, &interface_cmd);
! 2096: install_element (CONFIG_NODE, &no_interface_cmd);
! 2097: install_default (INTERFACE_NODE);
! 2098: install_element (INTERFACE_NODE, &interface_desc_cmd);
! 2099: install_element (INTERFACE_NODE, &no_interface_desc_cmd);
! 2100: install_element (RIP_NODE, &rip_network_cmd);
! 2101: install_element (RIP_NODE, &no_rip_network_cmd);
! 2102: install_element (RIP_NODE, &rip_neighbor_cmd);
! 2103: install_element (RIP_NODE, &no_rip_neighbor_cmd);
! 2104:
! 2105: install_element (RIP_NODE, &rip_passive_interface_cmd);
! 2106: install_element (RIP_NODE, &no_rip_passive_interface_cmd);
! 2107:
! 2108: install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
! 2109: install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
! 2110: install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
! 2111: install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
! 2112: install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
! 2113:
! 2114: install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
! 2115: install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
! 2116: install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
! 2117: install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
! 2118: install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
! 2119:
! 2120: install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
! 2121: install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
! 2122: install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
! 2123: install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
! 2124: install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
! 2125:
! 2126: install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
! 2127: install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
! 2128: install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
! 2129:
! 2130: install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
! 2131: install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
! 2132: install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
! 2133:
! 2134: install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
! 2135: install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
! 2136: install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
! 2137: install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
! 2138: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>