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