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