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