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