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