ospfd: Tighten up the connected check for redistribution
[jleu-quagga.git] / ripd / ripd.c
blob2d5a85600aabd74fe90995935c278a4725aad2e7
1 /* RIP version 1 and 2.
2 * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
3 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro <kunihiro@zebra.org>
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
23 #include <zebra.h>
25 #include "if.h"
26 #include "command.h"
27 #include "prefix.h"
28 #include "table.h"
29 #include "thread.h"
30 #include "memory.h"
31 #include "log.h"
32 #include "stream.h"
33 #include "filter.h"
34 #include "sockunion.h"
35 #include "sockopt.h"
36 #include "routemap.h"
37 #include "if_rmap.h"
38 #include "plist.h"
39 #include "distribute.h"
40 #include "md5.h"
41 #include "keychain.h"
42 #include "privs.h"
44 #include "ripd/ripd.h"
45 #include "ripd/rip_debug.h"
47 /* UDP receive buffer size */
48 #define RIP_UDP_RCV_BUF 41600
50 /* privileges global */
51 extern struct zebra_privs_t ripd_privs;
53 /* RIP Structure. */
54 struct rip *rip = NULL;
56 /* RIP neighbor address table. */
57 struct route_table *rip_neighbor_table;
59 /* RIP route changes. */
60 long rip_global_route_changes = 0;
62 /* RIP queries. */
63 long rip_global_queries = 0;
65 /* Prototypes. */
66 static void rip_event (enum rip_event, int);
67 static void rip_output_process (struct connected *, struct sockaddr_in *, int, u_char);
68 static int rip_triggered_update (struct thread *);
69 static int rip_update_jitter (unsigned long);
71 /* RIP output routes type. */
72 enum
74 rip_all_route,
75 rip_changed_route
78 /* RIP command strings. */
79 static const struct message rip_msg[] =
81 {RIP_REQUEST, "REQUEST"},
82 {RIP_RESPONSE, "RESPONSE"},
83 {RIP_TRACEON, "TRACEON"},
84 {RIP_TRACEOFF, "TRACEOFF"},
85 {RIP_POLL, "POLL"},
86 {RIP_POLL_ENTRY, "POLL ENTRY"},
87 {0, NULL},
90 /* Utility function to set boradcast option to the socket. */
91 static int
92 sockopt_broadcast (int sock)
94 int ret;
95 int on = 1;
97 ret = setsockopt (sock, SOL_SOCKET, SO_BROADCAST, (char *) &on, sizeof on);
98 if (ret < 0)
100 zlog_warn ("can't set sockopt SO_BROADCAST to socket %d", sock);
101 return -1;
103 return 0;
106 static int
107 rip_route_rte (struct rip_info *rinfo)
109 return (rinfo->type == ZEBRA_ROUTE_RIP && rinfo->sub_type == RIP_ROUTE_RTE);
112 static struct rip_info *
113 rip_info_new (void)
115 return XCALLOC (MTYPE_RIP_INFO, sizeof (struct rip_info));
118 void
119 rip_info_free (struct rip_info *rinfo)
121 XFREE (MTYPE_RIP_INFO, rinfo);
124 /* RIP route garbage collect timer. */
125 static int
126 rip_garbage_collect (struct thread *t)
128 struct rip_info *rinfo;
129 struct route_node *rp;
131 rinfo = THREAD_ARG (t);
132 rinfo->t_garbage_collect = NULL;
134 /* Off timeout timer. */
135 RIP_TIMER_OFF (rinfo->t_timeout);
137 /* Get route_node pointer. */
138 rp = rinfo->rp;
140 /* Unlock route_node. */
141 rp->info = NULL;
142 route_unlock_node (rp);
144 /* Free RIP routing information. */
145 rip_info_free (rinfo);
147 return 0;
150 /* Timeout RIP routes. */
151 static int
152 rip_timeout (struct thread *t)
154 struct rip_info *rinfo;
155 struct route_node *rn;
157 rinfo = THREAD_ARG (t);
158 rinfo->t_timeout = NULL;
160 rn = rinfo->rp;
162 /* - The garbage-collection timer is set for 120 seconds. */
163 RIP_TIMER_ON (rinfo->t_garbage_collect, rip_garbage_collect,
164 rip->garbage_time);
166 rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rn->p, &rinfo->nexthop,
167 rinfo->metric);
168 /* - The metric for the route is set to 16 (infinity). This causes
169 the route to be removed from service. */
170 rinfo->metric = RIP_METRIC_INFINITY;
171 rinfo->flags &= ~RIP_RTF_FIB;
173 /* - The route change flag is to indicate that this entry has been
174 changed. */
175 rinfo->flags |= RIP_RTF_CHANGED;
177 /* - The output process is signalled to trigger a response. */
178 rip_event (RIP_TRIGGERED_UPDATE, 0);
180 return 0;
183 static void
184 rip_timeout_update (struct rip_info *rinfo)
186 if (rinfo->metric != RIP_METRIC_INFINITY)
188 RIP_TIMER_OFF (rinfo->t_timeout);
189 RIP_TIMER_ON (rinfo->t_timeout, rip_timeout, rip->timeout_time);
193 static int
194 rip_incoming_filter (struct prefix_ipv4 *p, struct rip_interface *ri)
196 struct distribute *dist;
197 struct access_list *alist;
198 struct prefix_list *plist;
200 /* Input distribute-list filtering. */
201 if (ri->list[RIP_FILTER_IN])
203 if (access_list_apply (ri->list[RIP_FILTER_IN],
204 (struct prefix *) p) == FILTER_DENY)
206 if (IS_RIP_DEBUG_PACKET)
207 zlog_debug ("%s/%d filtered by distribute in",
208 inet_ntoa (p->prefix), p->prefixlen);
209 return -1;
212 if (ri->prefix[RIP_FILTER_IN])
214 if (prefix_list_apply (ri->prefix[RIP_FILTER_IN],
215 (struct prefix *) p) == PREFIX_DENY)
217 if (IS_RIP_DEBUG_PACKET)
218 zlog_debug ("%s/%d filtered by prefix-list in",
219 inet_ntoa (p->prefix), p->prefixlen);
220 return -1;
224 /* All interface filter check. */
225 dist = distribute_lookup (NULL);
226 if (dist)
228 if (dist->list[DISTRIBUTE_IN])
230 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_IN]);
232 if (alist)
234 if (access_list_apply (alist,
235 (struct prefix *) p) == FILTER_DENY)
237 if (IS_RIP_DEBUG_PACKET)
238 zlog_debug ("%s/%d filtered by distribute in",
239 inet_ntoa (p->prefix), p->prefixlen);
240 return -1;
244 if (dist->prefix[DISTRIBUTE_IN])
246 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_IN]);
248 if (plist)
250 if (prefix_list_apply (plist,
251 (struct prefix *) p) == PREFIX_DENY)
253 if (IS_RIP_DEBUG_PACKET)
254 zlog_debug ("%s/%d filtered by prefix-list in",
255 inet_ntoa (p->prefix), p->prefixlen);
256 return -1;
261 return 0;
264 static int
265 rip_outgoing_filter (struct prefix_ipv4 *p, struct rip_interface *ri)
267 struct distribute *dist;
268 struct access_list *alist;
269 struct prefix_list *plist;
271 if (ri->list[RIP_FILTER_OUT])
273 if (access_list_apply (ri->list[RIP_FILTER_OUT],
274 (struct prefix *) p) == FILTER_DENY)
276 if (IS_RIP_DEBUG_PACKET)
277 zlog_debug ("%s/%d is filtered by distribute out",
278 inet_ntoa (p->prefix), p->prefixlen);
279 return -1;
282 if (ri->prefix[RIP_FILTER_OUT])
284 if (prefix_list_apply (ri->prefix[RIP_FILTER_OUT],
285 (struct prefix *) p) == PREFIX_DENY)
287 if (IS_RIP_DEBUG_PACKET)
288 zlog_debug ("%s/%d is filtered by prefix-list out",
289 inet_ntoa (p->prefix), p->prefixlen);
290 return -1;
294 /* All interface filter check. */
295 dist = distribute_lookup (NULL);
296 if (dist)
298 if (dist->list[DISTRIBUTE_OUT])
300 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_OUT]);
302 if (alist)
304 if (access_list_apply (alist,
305 (struct prefix *) p) == FILTER_DENY)
307 if (IS_RIP_DEBUG_PACKET)
308 zlog_debug ("%s/%d filtered by distribute out",
309 inet_ntoa (p->prefix), p->prefixlen);
310 return -1;
314 if (dist->prefix[DISTRIBUTE_OUT])
316 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_OUT]);
318 if (plist)
320 if (prefix_list_apply (plist,
321 (struct prefix *) p) == PREFIX_DENY)
323 if (IS_RIP_DEBUG_PACKET)
324 zlog_debug ("%s/%d filtered by prefix-list out",
325 inet_ntoa (p->prefix), p->prefixlen);
326 return -1;
331 return 0;
334 /* Check nexthop address validity. */
335 static int
336 rip_nexthop_check (struct in_addr *addr)
338 struct listnode *node;
339 struct listnode *cnode;
340 struct interface *ifp;
341 struct connected *ifc;
342 struct prefix *p;
344 /* If nexthop address matches local configured address then it is
345 invalid nexthop. */
346 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
348 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
350 p = ifc->address;
352 if (p->family == AF_INET
353 && IPV4_ADDR_SAME (&p->u.prefix4, addr))
354 return -1;
357 return 0;
360 /* RIP add route to routing table. */
361 static void
362 rip_rte_process (struct rte *rte, struct sockaddr_in *from,
363 struct interface *ifp)
365 int ret;
366 struct prefix_ipv4 p;
367 struct route_node *rp;
368 struct rip_info *rinfo, rinfotmp;
369 struct rip_interface *ri;
370 struct in_addr *nexthop;
371 u_char oldmetric;
372 int same = 0;
373 int route_reuse = 0;
374 unsigned char old_dist, new_dist;
376 /* Make prefix structure. */
377 memset (&p, 0, sizeof (struct prefix_ipv4));
378 p.family = AF_INET;
379 p.prefix = rte->prefix;
380 p.prefixlen = ip_masklen (rte->mask);
382 /* Make sure mask is applied. */
383 apply_mask_ipv4 (&p);
385 /* Apply input filters. */
386 ri = ifp->info;
388 ret = rip_incoming_filter (&p, ri);
389 if (ret < 0)
390 return;
392 /* Modify entry according to the interface routemap. */
393 if (ri->routemap[RIP_FILTER_IN])
395 int ret;
396 struct rip_info newinfo;
398 memset (&newinfo, 0, sizeof (newinfo));
399 newinfo.type = ZEBRA_ROUTE_RIP;
400 newinfo.sub_type = RIP_ROUTE_RTE;
401 newinfo.nexthop = rte->nexthop;
402 newinfo.from = from->sin_addr;
403 newinfo.ifindex = ifp->ifindex;
404 newinfo.metric = rte->metric;
405 newinfo.metric_out = rte->metric; /* XXX */
406 newinfo.tag = ntohs (rte->tag); /* XXX */
408 /* The object should be of the type of rip_info */
409 ret = route_map_apply (ri->routemap[RIP_FILTER_IN],
410 (struct prefix *) &p, RMAP_RIP, &newinfo);
412 if (ret == RMAP_DENYMATCH)
414 if (IS_RIP_DEBUG_PACKET)
415 zlog_debug ("RIP %s/%d is filtered by route-map in",
416 inet_ntoa (p.prefix), p.prefixlen);
417 return;
420 /* Get back the object */
421 rte->nexthop = newinfo.nexthop_out;
422 rte->tag = htons (newinfo.tag_out); /* XXX */
423 rte->metric = newinfo.metric_out; /* XXX: the routemap uses the metric_out field */
426 /* Once the entry has been validated, update the metric by
427 adding the cost of the network on wich the message
428 arrived. If the result is greater than infinity, use infinity
429 (RFC2453 Sec. 3.9.2) */
430 /* Zebra ripd can handle offset-list in. */
431 ret = rip_offset_list_apply_in (&p, ifp, &rte->metric);
433 /* If offset-list does not modify the metric use interface's
434 metric. */
435 if (!ret)
436 rte->metric += ifp->metric;
438 if (rte->metric > RIP_METRIC_INFINITY)
439 rte->metric = RIP_METRIC_INFINITY;
441 /* Set nexthop pointer. */
442 if (rte->nexthop.s_addr == 0)
443 nexthop = &from->sin_addr;
444 else
445 nexthop = &rte->nexthop;
447 /* Check if nexthop address is myself, then do nothing. */
448 if (rip_nexthop_check (nexthop) < 0)
450 if (IS_RIP_DEBUG_PACKET)
451 zlog_debug ("Nexthop address %s is myself", inet_ntoa (*nexthop));
452 return;
455 /* Get index for the prefix. */
456 rp = route_node_get (rip->table, (struct prefix *) &p);
458 /* Check to see whether there is already RIP route on the table. */
459 rinfo = rp->info;
461 if (rinfo)
463 /* Local static route. */
464 if (rinfo->type == ZEBRA_ROUTE_RIP
465 && ((rinfo->sub_type == RIP_ROUTE_STATIC) ||
466 (rinfo->sub_type == RIP_ROUTE_DEFAULT))
467 && rinfo->metric != RIP_METRIC_INFINITY)
469 route_unlock_node (rp);
470 return;
473 /* Redistributed route check. */
474 if (rinfo->type != ZEBRA_ROUTE_RIP
475 && rinfo->metric != RIP_METRIC_INFINITY)
477 /* Fill in a minimaly temporary rip_info structure, for a future
478 rip_distance_apply() use) */
479 memset (&rinfotmp, 0, sizeof (rinfotmp));
480 IPV4_ADDR_COPY (&rinfotmp.from, &from->sin_addr);
481 rinfotmp.rp = rinfo->rp;
482 new_dist = rip_distance_apply (&rinfotmp);
483 new_dist = new_dist ? new_dist : ZEBRA_RIP_DISTANCE_DEFAULT;
484 old_dist = rinfo->distance;
485 /* Only connected routes may have a valid NULL distance */
486 if (rinfo->type != ZEBRA_ROUTE_CONNECT)
487 old_dist = old_dist ? old_dist : ZEBRA_RIP_DISTANCE_DEFAULT;
488 /* If imported route does not have STRICT precedence,
489 mark it as a ghost */
490 if (new_dist > old_dist
491 || rte->metric == RIP_METRIC_INFINITY)
493 route_unlock_node (rp);
494 return;
496 else
498 RIP_TIMER_OFF (rinfo->t_timeout);
499 RIP_TIMER_OFF (rinfo->t_garbage_collect);
501 rp->info = NULL;
502 if (rip_route_rte (rinfo))
503 rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p,
504 &rinfo->nexthop, rinfo->metric);
505 rip_info_free (rinfo);
506 rinfo = NULL;
507 route_reuse = 1;
512 if (!rinfo)
514 /* Now, check to see whether there is already an explicit route
515 for the destination prefix. If there is no such route, add
516 this route to the routing table, unless the metric is
517 infinity (there is no point in adding a route which
518 unusable). */
519 if (rte->metric != RIP_METRIC_INFINITY)
521 rinfo = rip_info_new ();
523 /* - Setting the destination prefix and length to those in
524 the RTE. */
525 rinfo->rp = rp;
527 /* - Setting the metric to the newly calculated metric (as
528 described above). */
529 rinfo->metric = rte->metric;
530 rinfo->tag = ntohs (rte->tag);
532 /* - Set the next hop address to be the address of the router
533 from which the datagram came or the next hop address
534 specified by a next hop RTE. */
535 IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);
536 IPV4_ADDR_COPY (&rinfo->from, &from->sin_addr);
537 rinfo->ifindex = ifp->ifindex;
539 /* - Initialize the timeout for the route. If the
540 garbage-collection timer is running for this route, stop it
541 (see section 2.3 for a discussion of the timers). */
542 rip_timeout_update (rinfo);
544 /* - Set the route change flag. */
545 rinfo->flags |= RIP_RTF_CHANGED;
547 /* - Signal the output process to trigger an update (see section
548 2.5). */
549 rip_event (RIP_TRIGGERED_UPDATE, 0);
551 /* Finally, route goes into the kernel. */
552 rinfo->type = ZEBRA_ROUTE_RIP;
553 rinfo->sub_type = RIP_ROUTE_RTE;
555 /* Set distance value. */
556 rinfo->distance = rip_distance_apply (rinfo);
558 rp->info = rinfo;
559 rip_zebra_ipv4_add (&p, &rinfo->nexthop, rinfo->metric,
560 rinfo->distance);
561 rinfo->flags |= RIP_RTF_FIB;
564 /* Unlock temporary lock, i.e. same behaviour */
565 if (route_reuse)
566 route_unlock_node (rp);
568 else
570 /* Route is there but we are not sure the route is RIP or not. */
571 rinfo = rp->info;
573 /* If there is an existing route, compare the next hop address
574 to the address of the router from which the datagram came.
575 If this datagram is from the same router as the existing
576 route, reinitialize the timeout. */
577 same = (IPV4_ADDR_SAME (&rinfo->from, &from->sin_addr)
578 && (rinfo->ifindex == ifp->ifindex));
580 if (same)
581 rip_timeout_update (rinfo);
584 /* Fill in a minimaly temporary rip_info structure, for a future
585 rip_distance_apply() use) */
586 memset (&rinfotmp, 0, sizeof (rinfotmp));
587 IPV4_ADDR_COPY (&rinfotmp.from, &from->sin_addr);
588 rinfotmp.rp = rinfo->rp;
591 /* Next, compare the metrics. If the datagram is from the same
592 router as the existing route, and the new metric is different
593 than the old one; or, if the new metric is lower than the old
594 one, or if the tag has been changed; or if there is a route
595 with a lower administrave distance; or an update of the
596 distance on the actual route; do the following actions: */
597 if ((same && rinfo->metric != rte->metric)
598 || (rte->metric < rinfo->metric)
599 || ((same)
600 && (rinfo->metric == rte->metric)
601 && ntohs (rte->tag) != rinfo->tag)
602 || (rinfo->distance > rip_distance_apply (&rinfotmp))
603 || ((rinfo->distance != rip_distance_apply (rinfo)) && same))
605 /* - Adopt the route from the datagram. That is, put the
606 new metric in, and adjust the next hop address (if
607 necessary). */
608 oldmetric = rinfo->metric;
609 rinfo->metric = rte->metric;
610 rinfo->tag = ntohs (rte->tag);
611 IPV4_ADDR_COPY (&rinfo->from, &from->sin_addr);
612 rinfo->ifindex = ifp->ifindex;
613 rinfo->distance = rip_distance_apply (rinfo);
615 /* Should a new route to this network be established
616 while the garbage-collection timer is running, the
617 new route will replace the one that is about to be
618 deleted. In this case the garbage-collection timer
619 must be cleared. */
621 if (oldmetric == RIP_METRIC_INFINITY &&
622 rinfo->metric < RIP_METRIC_INFINITY)
624 rinfo->type = ZEBRA_ROUTE_RIP;
625 rinfo->sub_type = RIP_ROUTE_RTE;
627 RIP_TIMER_OFF (rinfo->t_garbage_collect);
629 if (!IPV4_ADDR_SAME (&rinfo->nexthop, nexthop))
630 IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);
632 rip_zebra_ipv4_add (&p, nexthop, rinfo->metric,
633 rinfo->distance);
634 rinfo->flags |= RIP_RTF_FIB;
637 /* Update nexthop and/or metric value. */
638 if (oldmetric != RIP_METRIC_INFINITY)
640 rip_zebra_ipv4_delete (&p, &rinfo->nexthop, oldmetric);
641 rip_zebra_ipv4_add (&p, nexthop, rinfo->metric,
642 rinfo->distance);
643 rinfo->flags |= RIP_RTF_FIB;
645 if (!IPV4_ADDR_SAME (&rinfo->nexthop, nexthop))
646 IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);
649 /* - Set the route change flag and signal the output process
650 to trigger an update. */
651 rinfo->flags |= RIP_RTF_CHANGED;
652 rip_event (RIP_TRIGGERED_UPDATE, 0);
654 /* - If the new metric is infinity, start the deletion
655 process (described above); */
656 if (rinfo->metric == RIP_METRIC_INFINITY)
658 /* If the new metric is infinity, the deletion process
659 begins for the route, which is no longer used for
660 routing packets. Note that the deletion process is
661 started only when the metric is first set to
662 infinity. If the metric was already infinity, then a
663 new deletion process is not started. */
664 if (oldmetric != RIP_METRIC_INFINITY)
666 /* - The garbage-collection timer is set for 120 seconds. */
667 RIP_TIMER_ON (rinfo->t_garbage_collect,
668 rip_garbage_collect, rip->garbage_time);
669 RIP_TIMER_OFF (rinfo->t_timeout);
671 /* - The metric for the route is set to 16
672 (infinity). This causes the route to be removed
673 from service. */
674 rip_zebra_ipv4_delete (&p, &rinfo->nexthop, oldmetric);
675 rinfo->flags &= ~RIP_RTF_FIB;
677 /* - The route change flag is to indicate that this
678 entry has been changed. */
679 /* - The output process is signalled to trigger a
680 response. */
681 ; /* Above processes are already done previously. */
684 else
686 /* otherwise, re-initialize the timeout. */
687 rip_timeout_update (rinfo);
690 /* Unlock tempolary lock of the route. */
691 route_unlock_node (rp);
695 /* Dump RIP packet */
696 static void
697 rip_packet_dump (struct rip_packet *packet, int size, const char *sndrcv)
699 caddr_t lim;
700 struct rte *rte;
701 const char *command_str;
702 char pbuf[BUFSIZ], nbuf[BUFSIZ];
703 u_char netmask = 0;
704 u_char *p;
706 /* Set command string. */
707 if (packet->command > 0 && packet->command < RIP_COMMAND_MAX)
708 command_str = lookup (rip_msg, packet->command);
709 else
710 command_str = "unknown";
712 /* Dump packet header. */
713 zlog_debug ("%s %s version %d packet size %d",
714 sndrcv, command_str, packet->version, size);
716 /* Dump each routing table entry. */
717 rte = packet->rte;
719 for (lim = (caddr_t) packet + size; (caddr_t) rte < lim; rte++)
721 if (packet->version == RIPv2)
723 netmask = ip_masklen (rte->mask);
725 if (rte->family == htons (RIP_FAMILY_AUTH))
727 if (rte->tag == htons (RIP_AUTH_SIMPLE_PASSWORD))
729 p = (u_char *)&rte->prefix;
731 zlog_debug (" family 0x%X type %d auth string: %s",
732 ntohs (rte->family), ntohs (rte->tag), p);
734 else if (rte->tag == htons (RIP_AUTH_MD5))
736 struct rip_md5_info *md5;
738 md5 = (struct rip_md5_info *) &packet->rte;
740 zlog_debug (" family 0x%X type %d (MD5 authentication)",
741 ntohs (md5->family), ntohs (md5->type));
742 zlog_debug (" RIP-2 packet len %d Key ID %d"
743 " Auth Data len %d",
744 ntohs (md5->packet_len), md5->keyid,
745 md5->auth_len);
746 zlog_debug (" Sequence Number %ld",
747 (u_long) ntohl (md5->sequence));
749 else if (rte->tag == htons (RIP_AUTH_DATA))
751 p = (u_char *)&rte->prefix;
753 zlog_debug (" family 0x%X type %d (MD5 data)",
754 ntohs (rte->family), ntohs (rte->tag));
755 zlog_debug (" MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
756 "%02X%02X%02X%02X%02X%02X%02X",
757 p[0], p[1], p[2], p[3], p[4], p[5], p[6],
758 p[7], p[9], p[10], p[11], p[12], p[13],
759 p[14], p[15]);
761 else
763 zlog_debug (" family 0x%X type %d (Unknown auth type)",
764 ntohs (rte->family), ntohs (rte->tag));
767 else
768 zlog_debug (" %s/%d -> %s family %d tag %d metric %ld",
769 inet_ntop (AF_INET, &rte->prefix, pbuf, BUFSIZ),
770 netmask, inet_ntop (AF_INET, &rte->nexthop, nbuf,
771 BUFSIZ), ntohs (rte->family),
772 ntohs (rte->tag), (u_long) ntohl (rte->metric));
774 else
776 zlog_debug (" %s family %d tag %d metric %ld",
777 inet_ntop (AF_INET, &rte->prefix, pbuf, BUFSIZ),
778 ntohs (rte->family), ntohs (rte->tag),
779 (u_long)ntohl (rte->metric));
784 /* Check if the destination address is valid (unicast; not net 0
785 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
786 check net 0 because we accept default route. */
787 static int
788 rip_destination_check (struct in_addr addr)
790 u_int32_t destination;
792 /* Convert to host byte order. */
793 destination = ntohl (addr.s_addr);
795 if (IPV4_NET127 (destination))
796 return 0;
798 /* Net 0 may match to the default route. */
799 if (IPV4_NET0 (destination) && destination != 0)
800 return 0;
802 /* Unicast address must belong to class A, B, C. */
803 if (IN_CLASSA (destination))
804 return 1;
805 if (IN_CLASSB (destination))
806 return 1;
807 if (IN_CLASSC (destination))
808 return 1;
810 return 0;
813 /* RIP version 2 authentication. */
814 static int
815 rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from,
816 struct interface *ifp)
818 struct rip_interface *ri;
819 char *auth_str;
821 if (IS_RIP_DEBUG_EVENT)
822 zlog_debug ("RIPv2 simple password authentication from %s",
823 inet_ntoa (from->sin_addr));
825 ri = ifp->info;
827 if (ri->auth_type != RIP_AUTH_SIMPLE_PASSWORD
828 || rte->tag != htons(RIP_AUTH_SIMPLE_PASSWORD))
829 return 0;
831 /* Simple password authentication. */
832 if (ri->auth_str)
834 auth_str = (char *) &rte->prefix;
836 if (strncmp (auth_str, ri->auth_str, 16) == 0)
837 return 1;
839 if (ri->key_chain)
841 struct keychain *keychain;
842 struct key *key;
844 keychain = keychain_lookup (ri->key_chain);
845 if (keychain == NULL)
846 return 0;
848 key = key_match_for_accept (keychain, (char *) &rte->prefix);
849 if (key)
850 return 1;
852 return 0;
855 /* RIP version 2 authentication with MD5. */
856 static int
857 rip_auth_md5 (struct rip_packet *packet, struct sockaddr_in *from,
858 int length, struct interface *ifp)
860 struct rip_interface *ri;
861 struct rip_md5_info *md5;
862 struct rip_md5_data *md5data;
863 struct keychain *keychain;
864 struct key *key;
865 MD5_CTX ctx;
866 u_char digest[RIP_AUTH_MD5_SIZE];
867 u_int16_t packet_len;
868 char auth_str[RIP_AUTH_MD5_SIZE];
870 if (IS_RIP_DEBUG_EVENT)
871 zlog_debug ("RIPv2 MD5 authentication from %s",
872 inet_ntoa (from->sin_addr));
874 ri = ifp->info;
875 md5 = (struct rip_md5_info *) &packet->rte;
877 /* Check auth type. */
878 if (ri->auth_type != RIP_AUTH_MD5 || md5->type != htons(RIP_AUTH_MD5))
879 return 0;
881 /* If the authentication length is less than 16, then it must be wrong for
882 * any interpretation of rfc2082. Some implementations also interpret
883 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka RIP_AUTH_MD5_COMPAT_SIZE.
885 if ( !((md5->auth_len == RIP_AUTH_MD5_SIZE)
886 || (md5->auth_len == RIP_AUTH_MD5_COMPAT_SIZE)))
888 if (IS_RIP_DEBUG_EVENT)
889 zlog_debug ("RIPv2 MD5 authentication, strange authentication "
890 "length field %d", md5->auth_len);
891 return 0;
894 /* grab and verify check packet length */
895 packet_len = ntohs (md5->packet_len);
897 if (packet_len > (length - RIP_HEADER_SIZE - RIP_AUTH_MD5_SIZE))
899 if (IS_RIP_DEBUG_EVENT)
900 zlog_debug ("RIPv2 MD5 authentication, packet length field %d "
901 "greater than received length %d!",
902 md5->packet_len, length);
903 return 0;
906 /* retrieve authentication data */
907 md5data = (struct rip_md5_data *) (((u_char *) packet) + packet_len);
909 memset (auth_str, 0, RIP_AUTH_MD5_SIZE);
911 if (ri->key_chain)
913 keychain = keychain_lookup (ri->key_chain);
914 if (keychain == NULL)
915 return 0;
917 key = key_lookup_for_accept (keychain, md5->keyid);
918 if (key == NULL)
919 return 0;
921 strncpy (auth_str, key->string, RIP_AUTH_MD5_SIZE);
923 else if (ri->auth_str)
924 strncpy (auth_str, ri->auth_str, RIP_AUTH_MD5_SIZE);
926 if (auth_str[0] == 0)
927 return 0;
929 /* MD5 digest authentication. */
930 memset (&ctx, 0, sizeof(ctx));
931 MD5Init(&ctx);
932 MD5Update(&ctx, packet, packet_len + RIP_HEADER_SIZE);
933 MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE);
934 MD5Final(digest, &ctx);
936 if (memcmp (md5data->digest, digest, RIP_AUTH_MD5_SIZE) == 0)
937 return packet_len;
938 else
939 return 0;
942 /* Pick correct auth string for sends, prepare auth_str buffer for use.
943 * (left justified and padded).
945 * presumes one of ri or key is valid, and that the auth strings they point
946 * to are nul terminated. If neither are present, auth_str will be fully
947 * zero padded.
950 static void
951 rip_auth_prepare_str_send (struct rip_interface *ri, struct key *key,
952 char *auth_str, int len)
954 assert (ri || key);
956 memset (auth_str, 0, len);
957 if (key && key->string)
958 strncpy (auth_str, key->string, len);
959 else if (ri->auth_str)
960 strncpy (auth_str, ri->auth_str, len);
962 return;
965 /* Write RIPv2 simple password authentication information
967 * auth_str is presumed to be 2 bytes and correctly prepared
968 * (left justified and zero padded).
970 static void
971 rip_auth_simple_write (struct stream *s, char *auth_str, int len)
973 assert (s && len == RIP_AUTH_SIMPLE_SIZE);
975 stream_putw (s, RIP_FAMILY_AUTH);
976 stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD);
977 stream_put (s, auth_str, RIP_AUTH_SIMPLE_SIZE);
979 return;
982 /* write RIPv2 MD5 "authentication header"
983 * (uses the auth key data field)
985 * Digest offset field is set to 0.
987 * returns: offset of the digest offset field, which must be set when
988 * length to the auth-data MD5 digest is known.
990 static size_t
991 rip_auth_md5_ah_write (struct stream *s, struct rip_interface *ri,
992 struct key *key)
994 size_t doff = 0;
996 assert (s && ri && ri->auth_type == RIP_AUTH_MD5);
998 /* MD5 authentication. */
999 stream_putw (s, RIP_FAMILY_AUTH);
1000 stream_putw (s, RIP_AUTH_MD5);
1002 /* MD5 AH digest offset field.
1004 * Set to placeholder value here, to true value when RIP-2 Packet length
1005 * is known. Actual value is set in .....().
1007 doff = stream_get_endp(s);
1008 stream_putw (s, 0);
1010 /* Key ID. */
1011 if (key)
1012 stream_putc (s, key->index % 256);
1013 else
1014 stream_putc (s, 1);
1016 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
1017 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for this
1018 * to be configurable.
1020 stream_putc (s, ri->md5_auth_len);
1022 /* Sequence Number (non-decreasing). */
1023 /* RFC2080: The value used in the sequence number is
1024 arbitrary, but two suggestions are the time of the
1025 message's creation or a simple message counter. */
1026 stream_putl (s, time (NULL));
1028 /* Reserved field must be zero. */
1029 stream_putl (s, 0);
1030 stream_putl (s, 0);
1032 return doff;
1035 /* If authentication is in used, write the appropriate header
1036 * returns stream offset to which length must later be written
1037 * or 0 if this is not required
1039 static size_t
1040 rip_auth_header_write (struct stream *s, struct rip_interface *ri,
1041 struct key *key, char *auth_str, int len)
1043 assert (ri->auth_type != RIP_NO_AUTH);
1045 switch (ri->auth_type)
1047 case RIP_AUTH_SIMPLE_PASSWORD:
1048 rip_auth_prepare_str_send (ri, key, auth_str, len);
1049 rip_auth_simple_write (s, auth_str, len);
1050 return 0;
1051 case RIP_AUTH_MD5:
1052 return rip_auth_md5_ah_write (s, ri, key);
1054 assert (1);
1055 return 0;
1058 /* Write RIPv2 MD5 authentication data trailer */
1059 static void
1060 rip_auth_md5_set (struct stream *s, struct rip_interface *ri, size_t doff,
1061 char *auth_str, int authlen)
1063 unsigned long len;
1064 MD5_CTX ctx;
1065 unsigned char digest[RIP_AUTH_MD5_SIZE];
1067 /* Make it sure this interface is configured as MD5
1068 authentication. */
1069 assert ((ri->auth_type == RIP_AUTH_MD5) && (authlen == RIP_AUTH_MD5_SIZE));
1070 assert (doff > 0);
1072 /* Get packet length. */
1073 len = stream_get_endp(s);
1075 /* Check packet length. */
1076 if (len < (RIP_HEADER_SIZE + RIP_RTE_SIZE))
1078 zlog_err ("rip_auth_md5_set(): packet length %ld is less than minimum length.", len);
1079 return;
1082 /* Set the digest offset length in the header */
1083 stream_putw_at (s, doff, len);
1085 /* Set authentication data. */
1086 stream_putw (s, RIP_FAMILY_AUTH);
1087 stream_putw (s, RIP_AUTH_DATA);
1089 /* Generate a digest for the RIP packet. */
1090 memset(&ctx, 0, sizeof(ctx));
1091 MD5Init(&ctx);
1092 MD5Update(&ctx, STREAM_DATA (s), stream_get_endp (s));
1093 MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE);
1094 MD5Final(digest, &ctx);
1096 /* Copy the digest to the packet. */
1097 stream_write (s, digest, RIP_AUTH_MD5_SIZE);
1100 /* RIP routing information. */
1101 static void
1102 rip_response_process (struct rip_packet *packet, int size,
1103 struct sockaddr_in *from, struct connected *ifc)
1105 caddr_t lim;
1106 struct rte *rte;
1107 struct prefix_ipv4 ifaddr;
1108 struct prefix_ipv4 ifaddrclass;
1109 int subnetted;
1111 /* We don't know yet. */
1112 subnetted = -1;
1114 /* The Response must be ignored if it is not from the RIP
1115 port. (RFC2453 - Sec. 3.9.2)*/
1116 if (from->sin_port != htons(RIP_PORT_DEFAULT))
1118 zlog_info ("response doesn't come from RIP port: %d",
1119 from->sin_port);
1120 rip_peer_bad_packet (from);
1121 return;
1124 /* The datagram's IPv4 source address should be checked to see
1125 whether the datagram is from a valid neighbor; the source of the
1126 datagram must be on a directly connected network (RFC2453 - Sec. 3.9.2) */
1127 if (if_lookup_address(from->sin_addr) == NULL)
1129 zlog_info ("This datagram doesn't came from a valid neighbor: %s",
1130 inet_ntoa (from->sin_addr));
1131 rip_peer_bad_packet (from);
1132 return;
1135 /* It is also worth checking to see whether the response is from one
1136 of the router's own addresses. */
1138 ; /* Alredy done in rip_read () */
1140 /* Update RIP peer. */
1141 rip_peer_update (from, packet->version);
1143 /* Set RTE pointer. */
1144 rte = packet->rte;
1146 for (lim = (caddr_t) packet + size; (caddr_t) rte < lim; rte++)
1148 /* RIPv2 authentication check. */
1149 /* If the Address Family Identifier of the first (and only the
1150 first) entry in the message is 0xFFFF, then the remainder of
1151 the entry contains the authentication. */
1152 /* If the packet gets here it means authentication enabled */
1153 /* Check is done in rip_read(). So, just skipping it */
1154 if (packet->version == RIPv2 &&
1155 rte == packet->rte &&
1156 rte->family == htons(RIP_FAMILY_AUTH))
1157 continue;
1159 if (rte->family != htons(AF_INET))
1161 /* Address family check. RIP only supports AF_INET. */
1162 zlog_info ("Unsupported family %d from %s.",
1163 ntohs (rte->family), inet_ntoa (from->sin_addr));
1164 continue;
1167 /* - is the destination address valid (e.g., unicast; not net 0
1168 or 127) */
1169 if (! rip_destination_check (rte->prefix))
1171 zlog_info ("Network is net 0 or net 127 or it is not unicast network");
1172 rip_peer_bad_route (from);
1173 continue;
1176 /* Convert metric value to host byte order. */
1177 rte->metric = ntohl (rte->metric);
1179 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1180 if (! (rte->metric >= 1 && rte->metric <= 16))
1182 zlog_info ("Route's metric is not in the 1-16 range.");
1183 rip_peer_bad_route (from);
1184 continue;
1187 /* RIPv1 does not have nexthop value. */
1188 if (packet->version == RIPv1 && rte->nexthop.s_addr != 0)
1190 zlog_info ("RIPv1 packet with nexthop value %s",
1191 inet_ntoa (rte->nexthop));
1192 rip_peer_bad_route (from);
1193 continue;
1196 /* That is, if the provided information is ignored, a possibly
1197 sub-optimal, but absolutely valid, route may be taken. If
1198 the received Next Hop is not directly reachable, it should be
1199 treated as 0.0.0.0. */
1200 if (packet->version == RIPv2 && rte->nexthop.s_addr != 0)
1202 u_int32_t addrval;
1204 /* Multicast address check. */
1205 addrval = ntohl (rte->nexthop.s_addr);
1206 if (IN_CLASSD (addrval))
1208 zlog_info ("Nexthop %s is multicast address, skip this rte",
1209 inet_ntoa (rte->nexthop));
1210 continue;
1213 if (! if_lookup_address (rte->nexthop))
1215 struct route_node *rn;
1216 struct rip_info *rinfo;
1218 rn = route_node_match_ipv4 (rip->table, &rte->nexthop);
1220 if (rn)
1222 rinfo = rn->info;
1224 if (rinfo->type == ZEBRA_ROUTE_RIP
1225 && rinfo->sub_type == RIP_ROUTE_RTE)
1227 if (IS_RIP_DEBUG_EVENT)
1228 zlog_debug ("Next hop %s is on RIP network. Set nexthop to the packet's originator", inet_ntoa (rte->nexthop));
1229 rte->nexthop = rinfo->from;
1231 else
1233 if (IS_RIP_DEBUG_EVENT)
1234 zlog_debug ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte->nexthop));
1235 rte->nexthop.s_addr = 0;
1238 route_unlock_node (rn);
1240 else
1242 if (IS_RIP_DEBUG_EVENT)
1243 zlog_debug ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte->nexthop));
1244 rte->nexthop.s_addr = 0;
1250 /* For RIPv1, there won't be a valid netmask.
1252 This is a best guess at the masks. If everyone was using old
1253 Ciscos before the 'ip subnet zero' option, it would be almost
1254 right too :-)
1256 Cisco summarize ripv1 advertisments to the classful boundary
1257 (/16 for class B's) except when the RIP packet does to inside
1258 the classful network in question. */
1260 if ((packet->version == RIPv1 && rte->prefix.s_addr != 0)
1261 || (packet->version == RIPv2
1262 && (rte->prefix.s_addr != 0 && rte->mask.s_addr == 0)))
1264 u_int32_t destination;
1266 if (subnetted == -1)
1268 memcpy (&ifaddr, ifc->address, sizeof (struct prefix_ipv4));
1269 memcpy (&ifaddrclass, &ifaddr, sizeof (struct prefix_ipv4));
1270 apply_classful_mask_ipv4 (&ifaddrclass);
1271 subnetted = 0;
1272 if (ifaddr.prefixlen > ifaddrclass.prefixlen)
1273 subnetted = 1;
1276 destination = ntohl (rte->prefix.s_addr);
1278 if (IN_CLASSA (destination))
1279 masklen2ip (8, &rte->mask);
1280 else if (IN_CLASSB (destination))
1281 masklen2ip (16, &rte->mask);
1282 else if (IN_CLASSC (destination))
1283 masklen2ip (24, &rte->mask);
1285 if (subnetted == 1)
1286 masklen2ip (ifaddrclass.prefixlen,
1287 (struct in_addr *) &destination);
1288 if ((subnetted == 1) && ((rte->prefix.s_addr & destination) ==
1289 ifaddrclass.prefix.s_addr))
1291 masklen2ip (ifaddr.prefixlen, &rte->mask);
1292 if ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr)
1293 masklen2ip (32, &rte->mask);
1294 if (IS_RIP_DEBUG_EVENT)
1295 zlog_debug ("Subnetted route %s", inet_ntoa (rte->prefix));
1297 else
1299 if ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr)
1300 continue;
1303 if (IS_RIP_DEBUG_EVENT)
1305 zlog_debug ("Resultant route %s", inet_ntoa (rte->prefix));
1306 zlog_debug ("Resultant mask %s", inet_ntoa (rte->mask));
1310 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1311 ignore the entry. */
1312 if ((packet->version == RIPv2)
1313 && (rte->mask.s_addr != 0)
1314 && ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr))
1316 zlog_warn ("RIPv2 address %s is not mask /%d applied one",
1317 inet_ntoa (rte->prefix), ip_masklen (rte->mask));
1318 rip_peer_bad_route (from);
1319 continue;
1322 /* Default route's netmask is ignored. */
1323 if (packet->version == RIPv2
1324 && (rte->prefix.s_addr == 0)
1325 && (rte->mask.s_addr != 0))
1327 if (IS_RIP_DEBUG_EVENT)
1328 zlog_debug ("Default route with non-zero netmask. Set zero to netmask");
1329 rte->mask.s_addr = 0;
1332 /* Routing table updates. */
1333 rip_rte_process (rte, from, ifc->ifp);
1337 /* Make socket for RIP protocol. */
1338 static int
1339 rip_create_socket (struct sockaddr_in *from)
1341 int ret;
1342 int sock;
1343 struct sockaddr_in addr;
1345 memset (&addr, 0, sizeof (struct sockaddr_in));
1347 if (!from)
1349 addr.sin_family = AF_INET;
1350 addr.sin_addr.s_addr = INADDR_ANY;
1351 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1352 addr.sin_len = sizeof (struct sockaddr_in);
1353 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1354 } else {
1355 memcpy(&addr, from, sizeof(addr));
1358 /* sending port must always be the RIP port */
1359 addr.sin_port = htons (RIP_PORT_DEFAULT);
1361 /* Make datagram socket. */
1362 sock = socket (AF_INET, SOCK_DGRAM, 0);
1363 if (sock < 0)
1365 zlog_err("Cannot create UDP socket: %s", safe_strerror(errno));
1366 exit (1);
1369 sockopt_broadcast (sock);
1370 sockopt_reuseaddr (sock);
1371 sockopt_reuseport (sock);
1372 #ifdef RIP_RECVMSG
1373 setsockopt_pktinfo (sock);
1374 #endif /* RIP_RECVMSG */
1375 #ifdef IPTOS_PREC_INTERNETCONTROL
1376 setsockopt_ipv4_tos (sock, IPTOS_PREC_INTERNETCONTROL);
1377 #endif
1379 if (ripd_privs.change (ZPRIVS_RAISE))
1380 zlog_err ("rip_create_socket: could not raise privs");
1381 setsockopt_so_recvbuf (sock, RIP_UDP_RCV_BUF);
1382 if ( (ret = bind (sock, (struct sockaddr *) & addr, sizeof (addr))) < 0)
1385 int save_errno = errno;
1386 if (ripd_privs.change (ZPRIVS_LOWER))
1387 zlog_err ("rip_create_socket: could not lower privs");
1389 zlog_err("%s: Can't bind socket %d to %s port %d: %s", __func__,
1390 sock, inet_ntoa(addr.sin_addr),
1391 (int) ntohs(addr.sin_port),
1392 safe_strerror(save_errno));
1394 close (sock);
1395 return ret;
1398 if (ripd_privs.change (ZPRIVS_LOWER))
1399 zlog_err ("rip_create_socket: could not lower privs");
1401 return sock;
1404 /* RIP packet send to destination address, on interface denoted by
1405 * by connected argument. NULL to argument denotes destination should be
1406 * should be RIP multicast group
1408 static int
1409 rip_send_packet (u_char * buf, int size, struct sockaddr_in *to,
1410 struct connected *ifc)
1412 int ret, send_sock;
1413 struct sockaddr_in sin;
1415 assert (ifc != NULL);
1417 if (IS_RIP_DEBUG_PACKET)
1419 #define ADDRESS_SIZE 20
1420 char dst[ADDRESS_SIZE];
1421 dst[ADDRESS_SIZE - 1] = '\0';
1423 if (to)
1425 strncpy (dst, inet_ntoa(to->sin_addr), ADDRESS_SIZE - 1);
1427 else
1429 sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP);
1430 strncpy (dst, inet_ntoa(sin.sin_addr), ADDRESS_SIZE - 1);
1432 #undef ADDRESS_SIZE
1433 zlog_debug("rip_send_packet %s > %s (%s)",
1434 inet_ntoa(ifc->address->u.prefix4),
1435 dst, ifc->ifp->name);
1438 if ( CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY) )
1441 * ZEBRA_IFA_SECONDARY is set on linux when an interface is configured
1442 * with multiple addresses on the same subnet: the first address
1443 * on the subnet is configured "primary", and all subsequent addresses
1444 * on that subnet are treated as "secondary" addresses.
1445 * In order to avoid routing-table bloat on other rip listeners,
1446 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY source addrs.
1447 * XXX Since Linux is the only system for which the ZEBRA_IFA_SECONDARY
1448 * flag is set, we would end up sending a packet for a "secondary"
1449 * source address on non-linux systems.
1451 if (IS_RIP_DEBUG_PACKET)
1452 zlog_debug("duplicate dropped");
1453 return 0;
1456 /* Make destination address. */
1457 memset (&sin, 0, sizeof (struct sockaddr_in));
1458 sin.sin_family = AF_INET;
1459 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1460 sin.sin_len = sizeof (struct sockaddr_in);
1461 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1463 /* When destination is specified, use it's port and address. */
1464 if (to)
1466 sin.sin_port = to->sin_port;
1467 sin.sin_addr = to->sin_addr;
1468 send_sock = rip->sock;
1470 else
1472 struct sockaddr_in from;
1474 sin.sin_port = htons (RIP_PORT_DEFAULT);
1475 sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP);
1477 /* multicast send should bind to local interface address */
1478 from.sin_family = AF_INET;
1479 from.sin_port = htons (RIP_PORT_DEFAULT);
1480 from.sin_addr = ifc->address->u.prefix4;
1481 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1482 from.sin_len = sizeof (struct sockaddr_in);
1483 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1486 * we have to open a new socket for each packet because this
1487 * is the most portable way to bind to a different source
1488 * ipv4 address for each packet.
1490 if ( (send_sock = rip_create_socket (&from)) < 0)
1492 zlog_warn("rip_send_packet could not create socket.");
1493 return -1;
1495 rip_interface_multicast_set (send_sock, ifc);
1498 ret = sendto (send_sock, buf, size, 0, (struct sockaddr *)&sin,
1499 sizeof (struct sockaddr_in));
1501 if (IS_RIP_DEBUG_EVENT)
1502 zlog_debug ("SEND to %s.%d", inet_ntoa(sin.sin_addr),
1503 ntohs (sin.sin_port));
1505 if (ret < 0)
1506 zlog_warn ("can't send packet : %s", safe_strerror (errno));
1508 if (!to)
1509 close(send_sock);
1511 return ret;
1514 /* Add redistributed route to RIP table. */
1515 void
1516 rip_redistribute_add (int type, int sub_type, struct prefix_ipv4 *p,
1517 unsigned int ifindex, struct in_addr *nexthop,
1518 unsigned int metric, unsigned char distance)
1520 int ret;
1521 struct route_node *rp;
1522 struct rip_info *rinfo;
1524 /* Redistribute route */
1525 ret = rip_destination_check (p->prefix);
1526 if (! ret)
1527 return;
1529 rp = route_node_get (rip->table, (struct prefix *) p);
1531 rinfo = rp->info;
1533 if (rinfo)
1535 if (rinfo->type == ZEBRA_ROUTE_CONNECT
1536 && rinfo->sub_type == RIP_ROUTE_INTERFACE
1537 && rinfo->metric != RIP_METRIC_INFINITY)
1539 route_unlock_node (rp);
1540 return;
1543 /* Manually configured RIP route check. */
1544 if (rinfo->type == ZEBRA_ROUTE_RIP
1545 && ((rinfo->sub_type == RIP_ROUTE_STATIC) ||
1546 (rinfo->sub_type == RIP_ROUTE_DEFAULT)) )
1548 if (type != ZEBRA_ROUTE_RIP || ((sub_type != RIP_ROUTE_STATIC) &&
1549 (sub_type != RIP_ROUTE_DEFAULT)))
1551 route_unlock_node (rp);
1552 return;
1556 RIP_TIMER_OFF (rinfo->t_timeout);
1557 RIP_TIMER_OFF (rinfo->t_garbage_collect);
1559 if (rip_route_rte (rinfo))
1560 rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p, &rinfo->nexthop,
1561 rinfo->metric);
1562 rp->info = NULL;
1563 rip_info_free (rinfo);
1565 route_unlock_node (rp);
1568 rinfo = rip_info_new ();
1570 rinfo->type = type;
1571 rinfo->sub_type = sub_type;
1572 rinfo->ifindex = ifindex;
1573 rinfo->metric = 1;
1574 rinfo->external_metric = metric;
1575 rinfo->distance = distance;
1576 rinfo->rp = rp;
1578 if (nexthop)
1579 rinfo->nexthop = *nexthop;
1581 rinfo->flags |= RIP_RTF_FIB;
1582 rp->info = rinfo;
1584 rinfo->flags |= RIP_RTF_CHANGED;
1586 if (IS_RIP_DEBUG_EVENT) {
1587 if (!nexthop)
1588 zlog_debug ("Redistribute new prefix %s/%d on the interface %s",
1589 inet_ntoa(p->prefix), p->prefixlen,
1590 ifindex2ifname(ifindex));
1591 else
1592 zlog_debug ("Redistribute new prefix %s/%d with nexthop %s on the interface %s",
1593 inet_ntoa(p->prefix), p->prefixlen, inet_ntoa(rinfo->nexthop),
1594 ifindex2ifname(ifindex));
1598 rip_event (RIP_TRIGGERED_UPDATE, 0);
1601 /* Delete redistributed route from RIP table. */
1602 void
1603 rip_redistribute_delete (int type, int sub_type, struct prefix_ipv4 *p,
1604 unsigned int ifindex)
1606 int ret;
1607 struct route_node *rp;
1608 struct rip_info *rinfo;
1610 ret = rip_destination_check (p->prefix);
1611 if (! ret)
1612 return;
1614 rp = route_node_lookup (rip->table, (struct prefix *) p);
1615 if (rp)
1617 rinfo = rp->info;
1619 if (rinfo != NULL
1620 && rinfo->type == type
1621 && rinfo->sub_type == sub_type
1622 && rinfo->ifindex == ifindex)
1624 /* Perform poisoned reverse. */
1625 rinfo->metric = RIP_METRIC_INFINITY;
1626 RIP_TIMER_ON (rinfo->t_garbage_collect,
1627 rip_garbage_collect, rip->garbage_time);
1628 RIP_TIMER_OFF (rinfo->t_timeout);
1629 rinfo->flags |= RIP_RTF_CHANGED;
1631 if (IS_RIP_DEBUG_EVENT)
1632 zlog_debug ("Poisone %s/%d on the interface %s with an infinity metric [delete]",
1633 inet_ntoa(p->prefix), p->prefixlen,
1634 ifindex2ifname(ifindex));
1636 rip_event (RIP_TRIGGERED_UPDATE, 0);
1641 /* Response to request called from rip_read ().*/
1642 static void
1643 rip_request_process (struct rip_packet *packet, int size,
1644 struct sockaddr_in *from, struct connected *ifc)
1646 caddr_t lim;
1647 struct rte *rte;
1648 struct prefix_ipv4 p;
1649 struct route_node *rp;
1650 struct rip_info *rinfo;
1651 struct rip_interface *ri;
1653 /* Does not reponse to the requests on the loopback interfaces */
1654 if (if_is_loopback (ifc->ifp))
1655 return;
1657 /* Check RIP process is enabled on this interface. */
1658 ri = ifc->ifp->info;
1659 if (! ri->running)
1660 return;
1662 /* When passive interface is specified, suppress responses */
1663 if (ri->passive)
1664 return;
1666 /* RIP peer update. */
1667 rip_peer_update (from, packet->version);
1669 lim = ((caddr_t) packet) + size;
1670 rte = packet->rte;
1672 /* The Request is processed entry by entry. If there are no
1673 entries, no response is given. */
1674 if (lim == (caddr_t) rte)
1675 return;
1677 /* There is one special case. If there is exactly one entry in the
1678 request, and it has an address family identifier of zero and a
1679 metric of infinity (i.e., 16), then this is a request to send the
1680 entire routing table. */
1681 if (lim == ((caddr_t) (rte + 1)) &&
1682 ntohs (rte->family) == 0 &&
1683 ntohl (rte->metric) == RIP_METRIC_INFINITY)
1685 struct prefix_ipv4 saddr;
1687 /* saddr will be used for determining which routes to split-horizon.
1688 Since the source address we'll pick will be on the same subnet as the
1689 destination, for the purpose of split-horizoning, we'll
1690 pretend that "from" is our source address. */
1691 saddr.family = AF_INET;
1692 saddr.prefixlen = IPV4_MAX_BITLEN;
1693 saddr.prefix = from->sin_addr;
1695 /* All route with split horizon */
1696 rip_output_process (ifc, from, rip_all_route, packet->version);
1698 else
1700 /* Examine the list of RTEs in the Request one by one. For each
1701 entry, look up the destination in the router's routing
1702 database and, if there is a route, put that route's metric in
1703 the metric field of the RTE. If there is no explicit route
1704 to the specified destination, put infinity in the metric
1705 field. Once all the entries have been filled in, change the
1706 command from Request to Response and send the datagram back
1707 to the requestor. */
1708 p.family = AF_INET;
1710 for (; ((caddr_t) rte) < lim; rte++)
1712 p.prefix = rte->prefix;
1713 p.prefixlen = ip_masklen (rte->mask);
1714 apply_mask_ipv4 (&p);
1716 rp = route_node_lookup (rip->table, (struct prefix *) &p);
1717 if (rp)
1719 rinfo = rp->info;
1720 rte->metric = htonl (rinfo->metric);
1721 route_unlock_node (rp);
1723 else
1724 rte->metric = htonl (RIP_METRIC_INFINITY);
1726 packet->command = RIP_RESPONSE;
1728 rip_send_packet ((u_char *)packet, size, from, ifc);
1730 rip_global_queries++;
1733 #if RIP_RECVMSG
1734 /* Set IPv6 packet info to the socket. */
1735 static int
1736 setsockopt_pktinfo (int sock)
1738 int ret;
1739 int val = 1;
1741 ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val));
1742 if (ret < 0)
1743 zlog_warn ("Can't setsockopt IP_PKTINFO : %s", safe_strerror (errno));
1744 return ret;
1747 /* Read RIP packet by recvmsg function. */
1749 rip_recvmsg (int sock, u_char *buf, int size, struct sockaddr_in *from,
1750 int *ifindex)
1752 int ret;
1753 struct msghdr msg;
1754 struct iovec iov;
1755 struct cmsghdr *ptr;
1756 char adata[1024];
1758 msg.msg_name = (void *) from;
1759 msg.msg_namelen = sizeof (struct sockaddr_in);
1760 msg.msg_iov = &iov;
1761 msg.msg_iovlen = 1;
1762 msg.msg_control = (void *) adata;
1763 msg.msg_controllen = sizeof adata;
1764 iov.iov_base = buf;
1765 iov.iov_len = size;
1767 ret = recvmsg (sock, &msg, 0);
1768 if (ret < 0)
1769 return ret;
1771 for (ptr = ZCMSG_FIRSTHDR(&msg); ptr != NULL; ptr = CMSG_NXTHDR(&msg, ptr))
1772 if (ptr->cmsg_level == IPPROTO_IP && ptr->cmsg_type == IP_PKTINFO)
1774 struct in_pktinfo *pktinfo;
1775 int i;
1777 pktinfo = (struct in_pktinfo *) CMSG_DATA (ptr);
1778 i = pktinfo->ipi_ifindex;
1780 return ret;
1783 /* RIP packet read function. */
1785 rip_read_new (struct thread *t)
1787 int ret;
1788 int sock;
1789 char buf[RIP_PACKET_MAXSIZ];
1790 struct sockaddr_in from;
1791 unsigned int ifindex;
1793 /* Fetch socket then register myself. */
1794 sock = THREAD_FD (t);
1795 rip_event (RIP_READ, sock);
1797 /* Read RIP packet. */
1798 ret = rip_recvmsg (sock, buf, RIP_PACKET_MAXSIZ, &from, (int *)&ifindex);
1799 if (ret < 0)
1801 zlog_warn ("Can't read RIP packet: %s", safe_strerror (errno));
1802 return ret;
1805 return ret;
1807 #endif /* RIP_RECVMSG */
1809 /* First entry point of RIP packet. */
1810 static int
1811 rip_read (struct thread *t)
1813 int sock;
1814 int ret;
1815 int rtenum;
1816 union rip_buf rip_buf;
1817 struct rip_packet *packet;
1818 struct sockaddr_in from;
1819 int len;
1820 int vrecv;
1821 socklen_t fromlen;
1822 struct interface *ifp;
1823 struct connected *ifc;
1824 struct rip_interface *ri;
1826 /* Fetch socket then register myself. */
1827 sock = THREAD_FD (t);
1828 rip->t_read = NULL;
1830 /* Add myself to tne next event */
1831 rip_event (RIP_READ, sock);
1833 /* RIPd manages only IPv4. */
1834 memset (&from, 0, sizeof (struct sockaddr_in));
1835 fromlen = sizeof (struct sockaddr_in);
1837 len = recvfrom (sock, (char *)&rip_buf.buf, sizeof (rip_buf.buf), 0,
1838 (struct sockaddr *) &from, &fromlen);
1839 if (len < 0)
1841 zlog_info ("recvfrom failed: %s", safe_strerror (errno));
1842 return len;
1845 /* Check is this packet comming from myself? */
1846 if (if_check_address (from.sin_addr))
1848 if (IS_RIP_DEBUG_PACKET)
1849 zlog_debug ("ignore packet comes from myself");
1850 return -1;
1853 /* Which interface is this packet comes from. */
1854 ifp = if_lookup_address (from.sin_addr);
1856 /* RIP packet received */
1857 if (IS_RIP_DEBUG_EVENT)
1858 zlog_debug ("RECV packet from %s port %d on %s",
1859 inet_ntoa (from.sin_addr), ntohs (from.sin_port),
1860 ifp ? ifp->name : "unknown");
1862 /* If this packet come from unknown interface, ignore it. */
1863 if (ifp == NULL)
1865 zlog_info ("rip_read: cannot find interface for packet from %s port %d",
1866 inet_ntoa(from.sin_addr), ntohs (from.sin_port));
1867 return -1;
1870 ifc = connected_lookup_address (ifp, from.sin_addr);
1872 if (ifc == NULL)
1874 zlog_info ("rip_read: cannot find connected address for packet from %s "
1875 "port %d on interface %s",
1876 inet_ntoa(from.sin_addr), ntohs (from.sin_port), ifp->name);
1877 return -1;
1880 /* Packet length check. */
1881 if (len < RIP_PACKET_MINSIZ)
1883 zlog_warn ("packet size %d is smaller than minimum size %d",
1884 len, RIP_PACKET_MINSIZ);
1885 rip_peer_bad_packet (&from);
1886 return len;
1888 if (len > RIP_PACKET_MAXSIZ)
1890 zlog_warn ("packet size %d is larger than max size %d",
1891 len, RIP_PACKET_MAXSIZ);
1892 rip_peer_bad_packet (&from);
1893 return len;
1896 /* Packet alignment check. */
1897 if ((len - RIP_PACKET_MINSIZ) % 20)
1899 zlog_warn ("packet size %d is wrong for RIP packet alignment", len);
1900 rip_peer_bad_packet (&from);
1901 return len;
1904 /* Set RTE number. */
1905 rtenum = ((len - RIP_PACKET_MINSIZ) / 20);
1907 /* For easy to handle. */
1908 packet = &rip_buf.rip_packet;
1910 /* RIP version check. */
1911 if (packet->version == 0)
1913 zlog_info ("version 0 with command %d received.", packet->command);
1914 rip_peer_bad_packet (&from);
1915 return -1;
1918 /* Dump RIP packet. */
1919 if (IS_RIP_DEBUG_RECV)
1920 rip_packet_dump (packet, len, "RECV");
1922 /* RIP version adjust. This code should rethink now. RFC1058 says
1923 that "Version 1 implementations are to ignore this extra data and
1924 process only the fields specified in this document.". So RIPv3
1925 packet should be treated as RIPv1 ignoring must be zero field. */
1926 if (packet->version > RIPv2)
1927 packet->version = RIPv2;
1929 /* Is RIP running or is this RIP neighbor ?*/
1930 ri = ifp->info;
1931 if (! ri->running && ! rip_neighbor_lookup (&from))
1933 if (IS_RIP_DEBUG_EVENT)
1934 zlog_debug ("RIP is not enabled on interface %s.", ifp->name);
1935 rip_peer_bad_packet (&from);
1936 return -1;
1939 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1940 vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ?
1941 rip->version_recv : ri->ri_receive);
1942 if ((packet->version == RIPv1) && !(vrecv & RIPv1))
1944 if (IS_RIP_DEBUG_PACKET)
1945 zlog_debug (" packet's v%d doesn't fit to if version spec",
1946 packet->version);
1947 rip_peer_bad_packet (&from);
1948 return -1;
1950 if ((packet->version == RIPv2) && !(vrecv & RIPv2))
1952 if (IS_RIP_DEBUG_PACKET)
1953 zlog_debug (" packet's v%d doesn't fit to if version spec",
1954 packet->version);
1955 rip_peer_bad_packet (&from);
1956 return -1;
1959 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1960 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1961 accepted; authenticated RIP-2 messages shall be discarded. */
1962 if ((ri->auth_type == RIP_NO_AUTH)
1963 && rtenum
1964 && (packet->version == RIPv2)
1965 && (packet->rte->family == htons(RIP_FAMILY_AUTH)))
1967 if (IS_RIP_DEBUG_EVENT)
1968 zlog_debug ("packet RIPv%d is dropped because authentication disabled",
1969 packet->version);
1970 rip_peer_bad_packet (&from);
1971 return -1;
1974 /* RFC:
1975 If the router is configured to authenticate RIP-2 messages, then
1976 RIP-1 messages and RIP-2 messages which pass authentication
1977 testing shall be accepted; unauthenticated and failed
1978 authentication RIP-2 messages shall be discarded. For maximum
1979 security, RIP-1 messages should be ignored when authentication is
1980 in use (see section 4.1); otherwise, the routing information from
1981 authenticated messages will be propagated by RIP-1 routers in an
1982 unauthenticated manner.
1984 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1985 * always reply regardless of authentication settings, because:
1987 * - if there other authorised routers on-link, the REQUESTor can
1988 * passively obtain the routing updates anyway
1989 * - if there are no other authorised routers on-link, RIP can
1990 * easily be disabled for the link to prevent giving out information
1991 * on state of this routers RIP routing table..
1993 * I.e. if RIPv1 has any place anymore these days, it's as a very
1994 * simple way to distribute routing information (e.g. to embedded
1995 * hosts / appliances) and the ability to give out RIPv1
1996 * routing-information freely, while still requiring RIPv2
1997 * authentication for any RESPONSEs might be vaguely useful.
1999 if (ri->auth_type != RIP_NO_AUTH
2000 && packet->version == RIPv1)
2002 /* Discard RIPv1 messages other than REQUESTs */
2003 if (packet->command != RIP_REQUEST)
2005 if (IS_RIP_DEBUG_PACKET)
2006 zlog_debug ("RIPv1" " dropped because authentication enabled");
2007 rip_peer_bad_packet (&from);
2008 return -1;
2011 else if (ri->auth_type != RIP_NO_AUTH)
2013 const char *auth_desc;
2015 if (rtenum == 0)
2017 /* There definitely is no authentication in the packet. */
2018 if (IS_RIP_DEBUG_PACKET)
2019 zlog_debug ("RIPv2 authentication failed: no auth RTE in packet");
2020 rip_peer_bad_packet (&from);
2021 return -1;
2024 /* First RTE must be an Authentication Family RTE */
2025 if (packet->rte->family != htons(RIP_FAMILY_AUTH))
2027 if (IS_RIP_DEBUG_PACKET)
2028 zlog_debug ("RIPv2" " dropped because authentication enabled");
2029 rip_peer_bad_packet (&from);
2030 return -1;
2033 /* Check RIPv2 authentication. */
2034 switch (ntohs(packet->rte->tag))
2036 case RIP_AUTH_SIMPLE_PASSWORD:
2037 auth_desc = "simple";
2038 ret = rip_auth_simple_password (packet->rte, &from, ifp);
2039 break;
2041 case RIP_AUTH_MD5:
2042 auth_desc = "MD5";
2043 ret = rip_auth_md5 (packet, &from, len, ifp);
2044 /* Reset RIP packet length to trim MD5 data. */
2045 len = ret;
2046 break;
2048 default:
2049 ret = 0;
2050 auth_desc = "unknown type";
2051 if (IS_RIP_DEBUG_PACKET)
2052 zlog_debug ("RIPv2 Unknown authentication type %d",
2053 ntohs (packet->rte->tag));
2056 if (ret)
2058 if (IS_RIP_DEBUG_PACKET)
2059 zlog_debug ("RIPv2 %s authentication success", auth_desc);
2061 else
2063 if (IS_RIP_DEBUG_PACKET)
2064 zlog_debug ("RIPv2 %s authentication failure", auth_desc);
2065 rip_peer_bad_packet (&from);
2066 return -1;
2070 /* Process each command. */
2071 switch (packet->command)
2073 case RIP_RESPONSE:
2074 rip_response_process (packet, len, &from, ifc);
2075 break;
2076 case RIP_REQUEST:
2077 case RIP_POLL:
2078 rip_request_process (packet, len, &from, ifc);
2079 break;
2080 case RIP_TRACEON:
2081 case RIP_TRACEOFF:
2082 zlog_info ("Obsolete command %s received, please sent it to routed",
2083 lookup (rip_msg, packet->command));
2084 rip_peer_bad_packet (&from);
2085 break;
2086 case RIP_POLL_ENTRY:
2087 zlog_info ("Obsolete command %s received",
2088 lookup (rip_msg, packet->command));
2089 rip_peer_bad_packet (&from);
2090 break;
2091 default:
2092 zlog_info ("Unknown RIP command %d received", packet->command);
2093 rip_peer_bad_packet (&from);
2094 break;
2097 return len;
2100 /* Write routing table entry to the stream and return next index of
2101 the routing table entry in the stream. */
2102 static int
2103 rip_write_rte (int num, struct stream *s, struct prefix_ipv4 *p,
2104 u_char version, struct rip_info *rinfo)
2106 struct in_addr mask;
2108 /* Write routing table entry. */
2109 if (version == RIPv1)
2111 stream_putw (s, AF_INET);
2112 stream_putw (s, 0);
2113 stream_put_ipv4 (s, p->prefix.s_addr);
2114 stream_put_ipv4 (s, 0);
2115 stream_put_ipv4 (s, 0);
2116 stream_putl (s, rinfo->metric_out);
2118 else
2120 masklen2ip (p->prefixlen, &mask);
2122 stream_putw (s, AF_INET);
2123 stream_putw (s, rinfo->tag_out);
2124 stream_put_ipv4 (s, p->prefix.s_addr);
2125 stream_put_ipv4 (s, mask.s_addr);
2126 stream_put_ipv4 (s, rinfo->nexthop_out.s_addr);
2127 stream_putl (s, rinfo->metric_out);
2130 return ++num;
2133 /* Send update to the ifp or spcified neighbor. */
2134 void
2135 rip_output_process (struct connected *ifc, struct sockaddr_in *to,
2136 int route_type, u_char version)
2138 int ret;
2139 struct stream *s;
2140 struct route_node *rp;
2141 struct rip_info *rinfo;
2142 struct rip_interface *ri;
2143 struct prefix_ipv4 *p;
2144 struct prefix_ipv4 classfull;
2145 struct prefix_ipv4 ifaddrclass;
2146 struct key *key = NULL;
2147 /* this might need to made dynamic if RIP ever supported auth methods
2148 with larger key string sizes */
2149 char auth_str[RIP_AUTH_SIMPLE_SIZE];
2150 size_t doff = 0; /* offset of digest offset field */
2151 int num = 0;
2152 int rtemax;
2153 int subnetted = 0;
2155 /* Logging output event. */
2156 if (IS_RIP_DEBUG_EVENT)
2158 if (to)
2159 zlog_debug ("update routes to neighbor %s", inet_ntoa (to->sin_addr));
2160 else
2161 zlog_debug ("update routes on interface %s ifindex %d",
2162 ifc->ifp->name, ifc->ifp->ifindex);
2165 /* Set output stream. */
2166 s = rip->obuf;
2168 /* Reset stream and RTE counter. */
2169 stream_reset (s);
2170 rtemax = (RIP_PACKET_MAXSIZ - 4) / 20;
2172 /* Get RIP interface. */
2173 ri = ifc->ifp->info;
2175 /* If output interface is in simple password authentication mode, we
2176 need space for authentication data. */
2177 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2178 rtemax -= 1;
2180 /* If output interface is in MD5 authentication mode, we need space
2181 for authentication header and data. */
2182 if (ri->auth_type == RIP_AUTH_MD5)
2183 rtemax -= 2;
2185 /* If output interface is in simple password authentication mode
2186 and string or keychain is specified we need space for auth. data */
2187 if (ri->auth_type != RIP_NO_AUTH)
2189 if (ri->key_chain)
2191 struct keychain *keychain;
2193 keychain = keychain_lookup (ri->key_chain);
2194 if (keychain)
2195 key = key_lookup_for_send (keychain);
2197 /* to be passed to auth functions later */
2198 rip_auth_prepare_str_send (ri, key, auth_str, RIP_AUTH_SIMPLE_SIZE);
2201 if (version == RIPv1)
2203 memcpy (&ifaddrclass, ifc->address, sizeof (struct prefix_ipv4));
2204 apply_classful_mask_ipv4 (&ifaddrclass);
2205 subnetted = 0;
2206 if (ifc->address->prefixlen > ifaddrclass.prefixlen)
2207 subnetted = 1;
2210 for (rp = route_top (rip->table); rp; rp = route_next (rp))
2211 if ((rinfo = rp->info) != NULL)
2213 /* For RIPv1, if we are subnetted, output subnets in our network */
2214 /* that have the same mask as the output "interface". For other */
2215 /* networks, only the classfull version is output. */
2217 if (version == RIPv1)
2219 p = (struct prefix_ipv4 *) &rp->p;
2221 if (IS_RIP_DEBUG_PACKET)
2222 zlog_debug("RIPv1 mask check, %s/%d considered for output",
2223 inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen);
2225 if (subnetted &&
2226 prefix_match ((struct prefix *) &ifaddrclass, &rp->p))
2228 if ((ifc->address->prefixlen != rp->p.prefixlen) &&
2229 (rp->p.prefixlen != 32))
2230 continue;
2232 else
2234 memcpy (&classfull, &rp->p, sizeof(struct prefix_ipv4));
2235 apply_classful_mask_ipv4(&classfull);
2236 if (rp->p.u.prefix4.s_addr != 0 &&
2237 classfull.prefixlen != rp->p.prefixlen)
2238 continue;
2240 if (IS_RIP_DEBUG_PACKET)
2241 zlog_debug("RIPv1 mask check, %s/%d made it through",
2242 inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen);
2244 else
2245 p = (struct prefix_ipv4 *) &rp->p;
2247 /* Apply output filters. */
2248 ret = rip_outgoing_filter (p, ri);
2249 if (ret < 0)
2250 continue;
2252 /* Changed route only output. */
2253 if (route_type == rip_changed_route &&
2254 (! (rinfo->flags & RIP_RTF_CHANGED)))
2255 continue;
2257 /* Split horizon. */
2258 /* if (split_horizon == rip_split_horizon) */
2259 if (ri->split_horizon == RIP_SPLIT_HORIZON)
2262 * We perform split horizon for RIP and connected route.
2263 * For rip routes, we want to suppress the route if we would
2264 * end up sending the route back on the interface that we
2265 * learned it from, with a higher metric. For connected routes,
2266 * we suppress the route if the prefix is a subset of the
2267 * source address that we are going to use for the packet
2268 * (in order to handle the case when multiple subnets are
2269 * configured on the same interface).
2271 if (rinfo->type == ZEBRA_ROUTE_RIP &&
2272 rinfo->ifindex == ifc->ifp->ifindex)
2273 continue;
2274 if (rinfo->type == ZEBRA_ROUTE_CONNECT &&
2275 prefix_match((struct prefix *)p, ifc->address))
2276 continue;
2279 /* Preparation for route-map. */
2280 rinfo->metric_set = 0;
2281 rinfo->nexthop_out.s_addr = 0;
2282 rinfo->metric_out = rinfo->metric;
2283 rinfo->tag_out = rinfo->tag;
2284 rinfo->ifindex_out = ifc->ifp->ifindex;
2286 /* In order to avoid some local loops,
2287 * if the RIP route has a nexthop via this interface, keep the nexthop,
2288 * otherwise set it to 0. The nexthop should not be propagated
2289 * beyond the local broadcast/multicast area in order
2290 * to avoid an IGP multi-level recursive look-up.
2291 * see (4.4)
2293 if (rinfo->ifindex == ifc->ifp->ifindex)
2294 rinfo->nexthop_out = rinfo->nexthop;
2296 /* Interface route-map */
2297 if (ri->routemap[RIP_FILTER_OUT])
2299 ret = route_map_apply (ri->routemap[RIP_FILTER_OUT],
2300 (struct prefix *) p, RMAP_RIP,
2301 rinfo);
2303 if (ret == RMAP_DENYMATCH)
2305 if (IS_RIP_DEBUG_PACKET)
2306 zlog_debug ("RIP %s/%d is filtered by route-map out",
2307 inet_ntoa (p->prefix), p->prefixlen);
2308 continue;
2312 /* Apply redistribute route map - continue, if deny */
2313 if (rip->route_map[rinfo->type].name
2314 && rinfo->sub_type != RIP_ROUTE_INTERFACE)
2316 ret = route_map_apply (rip->route_map[rinfo->type].map,
2317 (struct prefix *)p, RMAP_RIP, rinfo);
2319 if (ret == RMAP_DENYMATCH)
2321 if (IS_RIP_DEBUG_PACKET)
2322 zlog_debug ("%s/%d is filtered by route-map",
2323 inet_ntoa (p->prefix), p->prefixlen);
2324 continue;
2328 /* When route-map does not set metric. */
2329 if (! rinfo->metric_set)
2331 /* If redistribute metric is set. */
2332 if (rip->route_map[rinfo->type].metric_config
2333 && rinfo->metric != RIP_METRIC_INFINITY)
2335 rinfo->metric_out = rip->route_map[rinfo->type].metric;
2337 else
2339 /* If the route is not connected or localy generated
2340 one, use default-metric value*/
2341 if (rinfo->type != ZEBRA_ROUTE_RIP
2342 && rinfo->type != ZEBRA_ROUTE_CONNECT
2343 && rinfo->metric != RIP_METRIC_INFINITY)
2344 rinfo->metric_out = rip->default_metric;
2348 /* Apply offset-list */
2349 if (rinfo->metric != RIP_METRIC_INFINITY)
2350 rip_offset_list_apply_out (p, ifc->ifp, &rinfo->metric_out);
2352 if (rinfo->metric_out > RIP_METRIC_INFINITY)
2353 rinfo->metric_out = RIP_METRIC_INFINITY;
2355 /* Perform split-horizon with poisoned reverse
2356 * for RIP and connected routes.
2358 if (ri->split_horizon == RIP_SPLIT_HORIZON_POISONED_REVERSE) {
2360 * We perform split horizon for RIP and connected route.
2361 * For rip routes, we want to suppress the route if we would
2362 * end up sending the route back on the interface that we
2363 * learned it from, with a higher metric. For connected routes,
2364 * we suppress the route if the prefix is a subset of the
2365 * source address that we are going to use for the packet
2366 * (in order to handle the case when multiple subnets are
2367 * configured on the same interface).
2369 if (rinfo->type == ZEBRA_ROUTE_RIP &&
2370 rinfo->ifindex == ifc->ifp->ifindex)
2371 rinfo->metric_out = RIP_METRIC_INFINITY;
2372 if (rinfo->type == ZEBRA_ROUTE_CONNECT &&
2373 prefix_match((struct prefix *)p, ifc->address))
2374 rinfo->metric_out = RIP_METRIC_INFINITY;
2377 /* Prepare preamble, auth headers, if needs be */
2378 if (num == 0)
2380 stream_putc (s, RIP_RESPONSE);
2381 stream_putc (s, version);
2382 stream_putw (s, 0);
2384 /* auth header for !v1 && !no_auth */
2385 if ( (ri->auth_type != RIP_NO_AUTH) && (version != RIPv1) )
2386 doff = rip_auth_header_write (s, ri, key, auth_str,
2387 RIP_AUTH_SIMPLE_SIZE);
2390 /* Write RTE to the stream. */
2391 num = rip_write_rte (num, s, p, version, rinfo);
2392 if (num == rtemax)
2394 if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
2395 rip_auth_md5_set (s, ri, doff, auth_str, RIP_AUTH_SIMPLE_SIZE);
2397 ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s),
2398 to, ifc);
2400 if (ret >= 0 && IS_RIP_DEBUG_SEND)
2401 rip_packet_dump ((struct rip_packet *)STREAM_DATA (s),
2402 stream_get_endp(s), "SEND");
2403 num = 0;
2404 stream_reset (s);
2408 /* Flush unwritten RTE. */
2409 if (num != 0)
2411 if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
2412 rip_auth_md5_set (s, ri, doff, auth_str, RIP_AUTH_SIMPLE_SIZE);
2414 ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s), to, ifc);
2416 if (ret >= 0 && IS_RIP_DEBUG_SEND)
2417 rip_packet_dump ((struct rip_packet *)STREAM_DATA (s),
2418 stream_get_endp (s), "SEND");
2419 num = 0;
2420 stream_reset (s);
2423 /* Statistics updates. */
2424 ri->sent_updates++;
2427 /* Send RIP packet to the interface. */
2428 static void
2429 rip_update_interface (struct connected *ifc, u_char version, int route_type)
2431 struct sockaddr_in to;
2433 /* When RIP version is 2 and multicast enable interface. */
2434 if (version == RIPv2 && if_is_multicast (ifc->ifp))
2436 if (IS_RIP_DEBUG_EVENT)
2437 zlog_debug ("multicast announce on %s ", ifc->ifp->name);
2439 rip_output_process (ifc, NULL, route_type, version);
2440 return;
2443 /* If we can't send multicast packet, send it with unicast. */
2444 if (if_is_broadcast (ifc->ifp) || if_is_pointopoint (ifc->ifp))
2446 if (ifc->address->family == AF_INET)
2448 /* Destination address and port setting. */
2449 memset (&to, 0, sizeof (struct sockaddr_in));
2450 if (ifc->destination)
2451 /* use specified broadcast or peer destination addr */
2452 to.sin_addr = ifc->destination->u.prefix4;
2453 else if (ifc->address->prefixlen < IPV4_MAX_PREFIXLEN)
2454 /* calculate the appropriate broadcast address */
2455 to.sin_addr.s_addr =
2456 ipv4_broadcast_addr(ifc->address->u.prefix4.s_addr,
2457 ifc->address->prefixlen);
2458 else
2459 /* do not know where to send the packet */
2460 return;
2461 to.sin_port = htons (RIP_PORT_DEFAULT);
2463 if (IS_RIP_DEBUG_EVENT)
2464 zlog_debug("%s announce to %s on %s",
2465 CONNECTED_PEER(ifc) ? "unicast" : "broadcast",
2466 inet_ntoa (to.sin_addr), ifc->ifp->name);
2468 rip_output_process (ifc, &to, route_type, version);
2473 /* Update send to all interface and neighbor. */
2474 static void
2475 rip_update_process (int route_type)
2477 struct listnode *node;
2478 struct listnode *ifnode, *ifnnode;
2479 struct connected *connected;
2480 struct interface *ifp;
2481 struct rip_interface *ri;
2482 struct route_node *rp;
2483 struct sockaddr_in to;
2484 struct prefix_ipv4 *p;
2486 /* Send RIP update to each interface. */
2487 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
2489 if (if_is_loopback (ifp))
2490 continue;
2492 if (! if_is_operative (ifp))
2493 continue;
2495 /* Fetch RIP interface information. */
2496 ri = ifp->info;
2498 /* When passive interface is specified, suppress announce to the
2499 interface. */
2500 if (ri->passive)
2501 continue;
2503 if (ri->running)
2506 * If there is no version configuration in the interface,
2507 * use rip's version setting.
2509 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
2510 rip->version_send : ri->ri_send);
2512 if (IS_RIP_DEBUG_EVENT)
2513 zlog_debug("SEND UPDATE to %s ifindex %d",
2514 (ifp->name ? ifp->name : "_unknown_"), ifp->ifindex);
2516 /* send update on each connected network */
2517 for (ALL_LIST_ELEMENTS (ifp->connected, ifnode, ifnnode, connected))
2519 if (connected->address->family == AF_INET)
2521 if (vsend & RIPv1)
2522 rip_update_interface (connected, RIPv1, route_type);
2523 if ((vsend & RIPv2) && if_is_multicast(ifp))
2524 rip_update_interface (connected, RIPv2, route_type);
2530 /* RIP send updates to each neighbor. */
2531 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
2532 if (rp->info != NULL)
2534 p = (struct prefix_ipv4 *) &rp->p;
2536 ifp = if_lookup_address (p->prefix);
2537 if (! ifp)
2539 zlog_warn ("Neighbor %s doesnt have connected interface!",
2540 inet_ntoa (p->prefix));
2541 continue;
2544 if ( (connected = connected_lookup_address (ifp, p->prefix)) == NULL)
2546 zlog_warn ("Neighbor %s doesnt have connected network",
2547 inet_ntoa (p->prefix));
2548 continue;
2551 /* Set destination address and port */
2552 memset (&to, 0, sizeof (struct sockaddr_in));
2553 to.sin_addr = p->prefix;
2554 to.sin_port = htons (RIP_PORT_DEFAULT);
2556 /* RIP version is rip's configuration. */
2557 rip_output_process (connected, &to, route_type, rip->version_send);
2561 /* RIP's periodical timer. */
2562 static int
2563 rip_update (struct thread *t)
2565 /* Clear timer pointer. */
2566 rip->t_update = NULL;
2568 if (IS_RIP_DEBUG_EVENT)
2569 zlog_debug ("update timer fire!");
2571 /* Process update output. */
2572 rip_update_process (rip_all_route);
2574 /* Triggered updates may be suppressed if a regular update is due by
2575 the time the triggered update would be sent. */
2576 if (rip->t_triggered_interval)
2578 thread_cancel (rip->t_triggered_interval);
2579 rip->t_triggered_interval = NULL;
2581 rip->trigger = 0;
2583 /* Register myself. */
2584 rip_event (RIP_UPDATE_EVENT, 0);
2586 return 0;
2589 /* Walk down the RIP routing table then clear changed flag. */
2590 static void
2591 rip_clear_changed_flag (void)
2593 struct route_node *rp;
2594 struct rip_info *rinfo;
2596 for (rp = route_top (rip->table); rp; rp = route_next (rp))
2597 if ((rinfo = rp->info) != NULL)
2598 if (rinfo->flags & RIP_RTF_CHANGED)
2599 rinfo->flags &= ~RIP_RTF_CHANGED;
2602 /* Triggered update interval timer. */
2603 static int
2604 rip_triggered_interval (struct thread *t)
2606 int rip_triggered_update (struct thread *);
2608 rip->t_triggered_interval = NULL;
2610 if (rip->trigger)
2612 rip->trigger = 0;
2613 rip_triggered_update (t);
2615 return 0;
2618 /* Execute triggered update. */
2619 static int
2620 rip_triggered_update (struct thread *t)
2622 int interval;
2624 /* Clear thred pointer. */
2625 rip->t_triggered_update = NULL;
2627 /* Cancel interval timer. */
2628 if (rip->t_triggered_interval)
2630 thread_cancel (rip->t_triggered_interval);
2631 rip->t_triggered_interval = NULL;
2633 rip->trigger = 0;
2635 /* Logging triggered update. */
2636 if (IS_RIP_DEBUG_EVENT)
2637 zlog_debug ("triggered update!");
2639 /* Split Horizon processing is done when generating triggered
2640 updates as well as normal updates (see section 2.6). */
2641 rip_update_process (rip_changed_route);
2643 /* Once all of the triggered updates have been generated, the route
2644 change flags should be cleared. */
2645 rip_clear_changed_flag ();
2647 /* After a triggered update is sent, a timer should be set for a
2648 random interval between 1 and 5 seconds. If other changes that
2649 would trigger updates occur before the timer expires, a single
2650 update is triggered when the timer expires. */
2651 interval = (random () % 5) + 1;
2653 rip->t_triggered_interval =
2654 thread_add_timer (master, rip_triggered_interval, NULL, interval);
2656 return 0;
2659 /* Withdraw redistributed route. */
2660 void
2661 rip_redistribute_withdraw (int type)
2663 struct route_node *rp;
2664 struct rip_info *rinfo;
2666 if (!rip)
2667 return;
2669 for (rp = route_top (rip->table); rp; rp = route_next (rp))
2670 if ((rinfo = rp->info) != NULL)
2672 if (rinfo->type == type
2673 && rinfo->sub_type != RIP_ROUTE_INTERFACE)
2675 /* Perform poisoned reverse. */
2676 rinfo->metric = RIP_METRIC_INFINITY;
2677 RIP_TIMER_ON (rinfo->t_garbage_collect,
2678 rip_garbage_collect, rip->garbage_time);
2679 RIP_TIMER_OFF (rinfo->t_timeout);
2680 rinfo->flags |= RIP_RTF_CHANGED;
2682 if (IS_RIP_DEBUG_EVENT) {
2683 struct prefix_ipv4 *p = (struct prefix_ipv4 *) &rp->p;
2685 zlog_debug ("Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2686 inet_ntoa(p->prefix), p->prefixlen,
2687 ifindex2ifname(rinfo->ifindex));
2690 rip_event (RIP_TRIGGERED_UPDATE, 0);
2695 /* Create new RIP instance and set it to global variable. */
2696 static int
2697 rip_create (void)
2699 rip = XCALLOC (MTYPE_RIP, sizeof (struct rip));
2701 /* Set initial value. */
2702 rip->version_send = RI_RIP_VERSION_2;
2703 rip->version_recv = RI_RIP_VERSION_1_AND_2;
2704 rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
2705 rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
2706 rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
2707 rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
2709 /* Initialize RIP routig table. */
2710 rip->table = route_table_init ();
2711 rip->route = route_table_init ();
2712 rip->neighbor = route_table_init ();
2714 /* Make output stream. */
2715 rip->obuf = stream_new (1500);
2717 /* Make socket. */
2718 rip->sock = rip_create_socket (NULL);
2719 if (rip->sock < 0)
2720 return rip->sock;
2722 /* Create read and timer thread. */
2723 rip_event (RIP_READ, rip->sock);
2724 rip_event (RIP_UPDATE_EVENT, 1);
2726 return 0;
2729 /* Sned RIP request to the destination. */
2731 rip_request_send (struct sockaddr_in *to, struct interface *ifp,
2732 u_char version, struct connected *connected)
2734 struct rte *rte;
2735 struct rip_packet rip_packet;
2736 struct listnode *node, *nnode;
2738 memset (&rip_packet, 0, sizeof (rip_packet));
2740 rip_packet.command = RIP_REQUEST;
2741 rip_packet.version = version;
2742 rte = rip_packet.rte;
2743 rte->metric = htonl (RIP_METRIC_INFINITY);
2745 if (connected)
2748 * connected is only sent for ripv1 case, or when
2749 * interface does not support multicast. Caller loops
2750 * over each connected address for this case.
2752 if (rip_send_packet ((u_char *) &rip_packet, sizeof (rip_packet),
2753 to, connected) != sizeof (rip_packet))
2754 return -1;
2755 else
2756 return sizeof (rip_packet);
2759 /* send request on each connected network */
2760 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
2762 struct prefix_ipv4 *p;
2764 p = (struct prefix_ipv4 *) connected->address;
2766 if (p->family != AF_INET)
2767 continue;
2769 if (rip_send_packet ((u_char *) &rip_packet, sizeof (rip_packet),
2770 to, connected) != sizeof (rip_packet))
2771 return -1;
2773 return sizeof (rip_packet);
2776 static int
2777 rip_update_jitter (unsigned long time)
2779 #define JITTER_BOUND 4
2780 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2781 Given that, we cannot let time be less than JITTER_BOUND seconds.
2782 The RIPv2 RFC says jitter should be small compared to
2783 update_time. We consider 1/JITTER_BOUND to be small.
2786 int jitter_input = time;
2787 int jitter;
2789 if (jitter_input < JITTER_BOUND)
2790 jitter_input = JITTER_BOUND;
2792 jitter = (((rand () % ((jitter_input * 2) + 1)) - jitter_input));
2794 return jitter/JITTER_BOUND;
2797 void
2798 rip_event (enum rip_event event, int sock)
2800 int jitter = 0;
2802 switch (event)
2804 case RIP_READ:
2805 rip->t_read = thread_add_read (master, rip_read, NULL, sock);
2806 break;
2807 case RIP_UPDATE_EVENT:
2808 if (rip->t_update)
2810 thread_cancel (rip->t_update);
2811 rip->t_update = NULL;
2813 jitter = rip_update_jitter (rip->update_time);
2814 rip->t_update =
2815 thread_add_timer (master, rip_update, NULL,
2816 sock ? 2 : rip->update_time + jitter);
2817 break;
2818 case RIP_TRIGGERED_UPDATE:
2819 if (rip->t_triggered_interval)
2820 rip->trigger = 1;
2821 else if (! rip->t_triggered_update)
2822 rip->t_triggered_update =
2823 thread_add_event (master, rip_triggered_update, NULL, 0);
2824 break;
2825 default:
2826 break;
2830 DEFUN (router_rip,
2831 router_rip_cmd,
2832 "router rip",
2833 "Enable a routing process\n"
2834 "Routing Information Protocol (RIP)\n")
2836 int ret;
2838 /* If rip is not enabled before. */
2839 if (! rip)
2841 ret = rip_create ();
2842 if (ret < 0)
2844 zlog_info ("Can't create RIP");
2845 return CMD_WARNING;
2848 vty->node = RIP_NODE;
2849 vty->index = rip;
2851 return CMD_SUCCESS;
2854 DEFUN (no_router_rip,
2855 no_router_rip_cmd,
2856 "no router rip",
2857 NO_STR
2858 "Enable a routing process\n"
2859 "Routing Information Protocol (RIP)\n")
2861 if (rip)
2862 rip_clean ();
2863 return CMD_SUCCESS;
2866 DEFUN (rip_version,
2867 rip_version_cmd,
2868 "version <1-2>",
2869 "Set routing protocol version\n"
2870 "version\n")
2872 int version;
2874 version = atoi (argv[0]);
2875 if (version != RIPv1 && version != RIPv2)
2877 vty_out (vty, "invalid rip version %d%s", version,
2878 VTY_NEWLINE);
2879 return CMD_WARNING;
2881 rip->version_send = version;
2882 rip->version_recv = version;
2884 return CMD_SUCCESS;
2887 DEFUN (no_rip_version,
2888 no_rip_version_cmd,
2889 "no version",
2890 NO_STR
2891 "Set routing protocol version\n")
2893 /* Set RIP version to the default. */
2894 rip->version_send = RI_RIP_VERSION_2;
2895 rip->version_recv = RI_RIP_VERSION_1_AND_2;
2897 return CMD_SUCCESS;
2900 ALIAS (no_rip_version,
2901 no_rip_version_val_cmd,
2902 "no version <1-2>",
2903 NO_STR
2904 "Set routing protocol version\n"
2905 "version\n")
2907 DEFUN (rip_route,
2908 rip_route_cmd,
2909 "route A.B.C.D/M",
2910 "RIP static route configuration\n"
2911 "IP prefix <network>/<length>\n")
2913 int ret;
2914 struct prefix_ipv4 p;
2915 struct route_node *node;
2917 ret = str2prefix_ipv4 (argv[0], &p);
2918 if (ret < 0)
2920 vty_out (vty, "Malformed address%s", VTY_NEWLINE);
2921 return CMD_WARNING;
2923 apply_mask_ipv4 (&p);
2925 /* For router rip configuration. */
2926 node = route_node_get (rip->route, (struct prefix *) &p);
2928 if (node->info)
2930 vty_out (vty, "There is already same static route.%s", VTY_NEWLINE);
2931 route_unlock_node (node);
2932 return CMD_WARNING;
2935 node->info = (char *)"static";
2937 rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0, NULL, 0, 0);
2939 return CMD_SUCCESS;
2942 DEFUN (no_rip_route,
2943 no_rip_route_cmd,
2944 "no route A.B.C.D/M",
2945 NO_STR
2946 "RIP static route configuration\n"
2947 "IP prefix <network>/<length>\n")
2949 int ret;
2950 struct prefix_ipv4 p;
2951 struct route_node *node;
2953 ret = str2prefix_ipv4 (argv[0], &p);
2954 if (ret < 0)
2956 vty_out (vty, "Malformed address%s", VTY_NEWLINE);
2957 return CMD_WARNING;
2959 apply_mask_ipv4 (&p);
2961 /* For router rip configuration. */
2962 node = route_node_lookup (rip->route, (struct prefix *) &p);
2963 if (! node)
2965 vty_out (vty, "Can't find route %s.%s", argv[0],
2966 VTY_NEWLINE);
2967 return CMD_WARNING;
2970 rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
2971 route_unlock_node (node);
2973 node->info = NULL;
2974 route_unlock_node (node);
2976 return CMD_SUCCESS;
2979 static void
2980 rip_update_default_metric (void)
2982 struct route_node *np;
2983 struct rip_info *rinfo;
2985 for (np = route_top (rip->table); np; np = route_next (np))
2986 if ((rinfo = np->info) != NULL)
2987 if (rinfo->type != ZEBRA_ROUTE_RIP && rinfo->type != ZEBRA_ROUTE_CONNECT)
2988 rinfo->metric = rip->default_metric;
2991 DEFUN (rip_default_metric,
2992 rip_default_metric_cmd,
2993 "default-metric <1-16>",
2994 "Set a metric of redistribute routes\n"
2995 "Default metric\n")
2997 if (rip)
2999 rip->default_metric = atoi (argv[0]);
3000 /* rip_update_default_metric (); */
3002 return CMD_SUCCESS;
3005 DEFUN (no_rip_default_metric,
3006 no_rip_default_metric_cmd,
3007 "no default-metric",
3008 NO_STR
3009 "Set a metric of redistribute routes\n"
3010 "Default metric\n")
3012 if (rip)
3014 rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
3015 /* rip_update_default_metric (); */
3017 return CMD_SUCCESS;
3020 ALIAS (no_rip_default_metric,
3021 no_rip_default_metric_val_cmd,
3022 "no default-metric <1-16>",
3023 NO_STR
3024 "Set a metric of redistribute routes\n"
3025 "Default metric\n")
3027 DEFUN (rip_timers,
3028 rip_timers_cmd,
3029 "timers basic <5-2147483647> <5-2147483647> <5-2147483647>",
3030 "Adjust routing timers\n"
3031 "Basic routing protocol update timers\n"
3032 "Routing table update timer value in second. Default is 30.\n"
3033 "Routing information timeout timer. Default is 180.\n"
3034 "Garbage collection timer. Default is 120.\n")
3036 unsigned long update;
3037 unsigned long timeout;
3038 unsigned long garbage;
3039 char *endptr = NULL;
3040 unsigned long RIP_TIMER_MAX = 2147483647;
3041 unsigned long RIP_TIMER_MIN = 5;
3043 update = strtoul (argv[0], &endptr, 10);
3044 if (update > RIP_TIMER_MAX || update < RIP_TIMER_MIN || *endptr != '\0')
3046 vty_out (vty, "update timer value error%s", VTY_NEWLINE);
3047 return CMD_WARNING;
3050 timeout = strtoul (argv[1], &endptr, 10);
3051 if (timeout > RIP_TIMER_MAX || timeout < RIP_TIMER_MIN || *endptr != '\0')
3053 vty_out (vty, "timeout timer value error%s", VTY_NEWLINE);
3054 return CMD_WARNING;
3057 garbage = strtoul (argv[2], &endptr, 10);
3058 if (garbage > RIP_TIMER_MAX || garbage < RIP_TIMER_MIN || *endptr != '\0')
3060 vty_out (vty, "garbage timer value error%s", VTY_NEWLINE);
3061 return CMD_WARNING;
3064 /* Set each timer value. */
3065 rip->update_time = update;
3066 rip->timeout_time = timeout;
3067 rip->garbage_time = garbage;
3069 /* Reset update timer thread. */
3070 rip_event (RIP_UPDATE_EVENT, 0);
3072 return CMD_SUCCESS;
3075 DEFUN (no_rip_timers,
3076 no_rip_timers_cmd,
3077 "no timers basic",
3078 NO_STR
3079 "Adjust routing timers\n"
3080 "Basic routing protocol update timers\n")
3082 /* Set each timer value to the default. */
3083 rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
3084 rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
3085 rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
3087 /* Reset update timer thread. */
3088 rip_event (RIP_UPDATE_EVENT, 0);
3090 return CMD_SUCCESS;
3093 ALIAS (no_rip_timers,
3094 no_rip_timers_val_cmd,
3095 "no timers basic <0-65535> <0-65535> <0-65535>",
3096 NO_STR
3097 "Adjust routing timers\n"
3098 "Basic routing protocol update timers\n"
3099 "Routing table update timer value in second. Default is 30.\n"
3100 "Routing information timeout timer. Default is 180.\n"
3101 "Garbage collection timer. Default is 120.\n")
3104 struct route_table *rip_distance_table;
3106 struct rip_distance
3108 /* Distance value for the IP source prefix. */
3109 u_char distance;
3111 /* Name of the access-list to be matched. */
3112 char *access_list;
3115 static struct rip_distance *
3116 rip_distance_new (void)
3118 return XCALLOC (MTYPE_RIP_DISTANCE, sizeof (struct rip_distance));
3121 static void
3122 rip_distance_free (struct rip_distance *rdistance)
3124 XFREE (MTYPE_RIP_DISTANCE, rdistance);
3127 static int
3128 rip_distance_set (struct vty *vty, const char *distance_str, const char *ip_str,
3129 const char *access_list_str)
3131 int ret;
3132 struct prefix_ipv4 p;
3133 u_char distance;
3134 struct route_node *rn;
3135 struct rip_distance *rdistance;
3137 ret = str2prefix_ipv4 (ip_str, &p);
3138 if (ret == 0)
3140 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
3141 return CMD_WARNING;
3144 distance = atoi (distance_str);
3146 /* Get RIP distance node. */
3147 rn = route_node_get (rip_distance_table, (struct prefix *) &p);
3148 if (rn->info)
3150 rdistance = rn->info;
3151 route_unlock_node (rn);
3153 else
3155 rdistance = rip_distance_new ();
3156 rn->info = rdistance;
3159 /* Set distance value. */
3160 rdistance->distance = distance;
3162 /* Reset access-list configuration. */
3163 if (rdistance->access_list)
3165 free (rdistance->access_list);
3166 rdistance->access_list = NULL;
3168 if (access_list_str)
3169 rdistance->access_list = strdup (access_list_str);
3171 return CMD_SUCCESS;
3174 static int
3175 rip_distance_unset (struct vty *vty, const char *distance_str,
3176 const char *ip_str, const char *access_list_str)
3178 int ret;
3179 struct prefix_ipv4 p;
3180 u_char distance;
3181 struct route_node *rn;
3182 struct rip_distance *rdistance;
3184 ret = str2prefix_ipv4 (ip_str, &p);
3185 if (ret == 0)
3187 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
3188 return CMD_WARNING;
3191 distance = atoi (distance_str);
3193 rn = route_node_lookup (rip_distance_table, (struct prefix *)&p);
3194 if (! rn)
3196 vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
3197 return CMD_WARNING;
3200 rdistance = rn->info;
3202 if (rdistance->access_list)
3203 free (rdistance->access_list);
3204 rip_distance_free (rdistance);
3206 rn->info = NULL;
3207 route_unlock_node (rn);
3208 route_unlock_node (rn);
3210 return CMD_SUCCESS;
3213 static void
3214 rip_distance_reset (void)
3216 struct route_node *rn;
3217 struct rip_distance *rdistance;
3219 for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
3220 if ((rdistance = rn->info) != NULL)
3222 if (rdistance->access_list)
3223 free (rdistance->access_list);
3224 rip_distance_free (rdistance);
3225 rn->info = NULL;
3226 route_unlock_node (rn);
3230 /* Apply RIP information to distance method. */
3231 u_char
3232 rip_distance_apply (struct rip_info *rinfo)
3234 struct route_node *rn;
3235 struct prefix_ipv4 p;
3236 struct rip_distance *rdistance;
3237 struct access_list *alist;
3239 if (! rip)
3240 return 0;
3242 memset (&p, 0, sizeof (struct prefix_ipv4));
3243 p.family = AF_INET;
3244 p.prefix = rinfo->from;
3245 p.prefixlen = IPV4_MAX_BITLEN;
3247 /* Check source address. */
3248 rn = route_node_match (rip_distance_table, (struct prefix *) &p);
3249 if (rn)
3251 rdistance = rn->info;
3252 route_unlock_node (rn);
3254 if (rdistance->access_list)
3256 alist = access_list_lookup (AFI_IP, rdistance->access_list);
3257 if (alist == NULL)
3258 return 0;
3259 if (access_list_apply (alist, &rinfo->rp->p) == FILTER_DENY)
3260 return 0;
3262 return rdistance->distance;
3264 else
3265 return rdistance->distance;
3268 if (rip->distance)
3269 return rip->distance;
3271 return 0;
3274 static void
3275 rip_distance_show (struct vty *vty)
3277 struct route_node *rn;
3278 struct rip_distance *rdistance;
3279 int header = 1;
3280 char buf[BUFSIZ];
3282 vty_out (vty, " Distance: (default is %d)%s",
3283 rip->distance ? rip->distance :ZEBRA_RIP_DISTANCE_DEFAULT,
3284 VTY_NEWLINE);
3286 for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
3287 if ((rdistance = rn->info) != NULL)
3289 if (header)
3291 vty_out (vty, " Address Distance List%s",
3292 VTY_NEWLINE);
3293 header = 0;
3295 sprintf (buf, "%s/%d", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
3296 vty_out (vty, " %-20s %4d %s%s",
3297 buf, rdistance->distance,
3298 rdistance->access_list ? rdistance->access_list : "",
3299 VTY_NEWLINE);
3303 DEFUN (rip_distance,
3304 rip_distance_cmd,
3305 "distance <1-255>",
3306 "Administrative distance\n"
3307 "Distance value\n")
3309 rip->distance = atoi (argv[0]);
3310 return CMD_SUCCESS;
3313 DEFUN (no_rip_distance,
3314 no_rip_distance_cmd,
3315 "no distance <1-255>",
3316 NO_STR
3317 "Administrative distance\n"
3318 "Distance value\n")
3320 rip->distance = 0;
3321 return CMD_SUCCESS;
3324 DEFUN (rip_distance_source,
3325 rip_distance_source_cmd,
3326 "distance <1-255> A.B.C.D/M",
3327 "Administrative distance\n"
3328 "Distance value\n"
3329 "IP source prefix\n")
3331 rip_distance_set (vty, argv[0], argv[1], NULL);
3332 return CMD_SUCCESS;
3335 DEFUN (no_rip_distance_source,
3336 no_rip_distance_source_cmd,
3337 "no distance <1-255> A.B.C.D/M",
3338 NO_STR
3339 "Administrative distance\n"
3340 "Distance value\n"
3341 "IP source prefix\n")
3343 rip_distance_unset (vty, argv[0], argv[1], NULL);
3344 return CMD_SUCCESS;
3347 DEFUN (rip_distance_source_access_list,
3348 rip_distance_source_access_list_cmd,
3349 "distance <1-255> A.B.C.D/M WORD",
3350 "Administrative distance\n"
3351 "Distance value\n"
3352 "IP source prefix\n"
3353 "Access list name\n")
3355 rip_distance_set (vty, argv[0], argv[1], argv[2]);
3356 return CMD_SUCCESS;
3359 DEFUN (no_rip_distance_source_access_list,
3360 no_rip_distance_source_access_list_cmd,
3361 "no distance <1-255> A.B.C.D/M WORD",
3362 NO_STR
3363 "Administrative distance\n"
3364 "Distance value\n"
3365 "IP source prefix\n"
3366 "Access list name\n")
3368 rip_distance_unset (vty, argv[0], argv[1], argv[2]);
3369 return CMD_SUCCESS;
3372 /* Print out routes update time. */
3373 static void
3374 rip_vty_out_uptime (struct vty *vty, struct rip_info *rinfo)
3376 time_t clock;
3377 struct tm *tm;
3378 #define TIME_BUF 25
3379 char timebuf [TIME_BUF];
3380 struct thread *thread;
3382 if ((thread = rinfo->t_timeout) != NULL)
3384 clock = thread_timer_remain_second (thread);
3385 tm = gmtime (&clock);
3386 strftime (timebuf, TIME_BUF, "%M:%S", tm);
3387 vty_out (vty, "%5s", timebuf);
3389 else if ((thread = rinfo->t_garbage_collect) != NULL)
3391 clock = thread_timer_remain_second (thread);
3392 tm = gmtime (&clock);
3393 strftime (timebuf, TIME_BUF, "%M:%S", tm);
3394 vty_out (vty, "%5s", timebuf);
3398 static const char *
3399 rip_route_type_print (int sub_type)
3401 switch (sub_type)
3403 case RIP_ROUTE_RTE:
3404 return "n";
3405 case RIP_ROUTE_STATIC:
3406 return "s";
3407 case RIP_ROUTE_DEFAULT:
3408 return "d";
3409 case RIP_ROUTE_REDISTRIBUTE:
3410 return "r";
3411 case RIP_ROUTE_INTERFACE:
3412 return "i";
3413 default:
3414 return "?";
3418 DEFUN (show_ip_rip,
3419 show_ip_rip_cmd,
3420 "show ip rip",
3421 SHOW_STR
3422 IP_STR
3423 "Show RIP routes\n")
3425 struct route_node *np;
3426 struct rip_info *rinfo;
3428 if (! rip)
3429 return CMD_SUCCESS;
3431 vty_out (vty, "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP%s"
3432 "Sub-codes:%s"
3433 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,%s"
3434 " (i) - interface%s%s"
3435 " Network Next Hop Metric From Tag Time%s",
3436 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
3438 for (np = route_top (rip->table); np; np = route_next (np))
3439 if ((rinfo = np->info) != NULL)
3441 int len;
3443 len = vty_out (vty, "%c(%s) %s/%d",
3444 /* np->lock, For debugging. */
3445 zebra_route_char(rinfo->type),
3446 rip_route_type_print (rinfo->sub_type),
3447 inet_ntoa (np->p.u.prefix4), np->p.prefixlen);
3449 len = 24 - len;
3451 if (len > 0)
3452 vty_out (vty, "%*s", len, " ");
3454 if (rinfo->nexthop.s_addr)
3455 vty_out (vty, "%-20s %2d ", inet_ntoa (rinfo->nexthop),
3456 rinfo->metric);
3457 else
3458 vty_out (vty, "0.0.0.0 %2d ", rinfo->metric);
3460 /* Route which exist in kernel routing table. */
3461 if ((rinfo->type == ZEBRA_ROUTE_RIP) &&
3462 (rinfo->sub_type == RIP_ROUTE_RTE))
3464 vty_out (vty, "%-15s ", inet_ntoa (rinfo->from));
3465 vty_out (vty, "%3d ", rinfo->tag);
3466 rip_vty_out_uptime (vty, rinfo);
3468 else if (rinfo->metric == RIP_METRIC_INFINITY)
3470 vty_out (vty, "self ");
3471 vty_out (vty, "%3d ", rinfo->tag);
3472 rip_vty_out_uptime (vty, rinfo);
3474 else
3476 if (rinfo->external_metric)
3478 len = vty_out (vty, "self (%s:%d)",
3479 zebra_route_string(rinfo->type),
3480 rinfo->external_metric);
3481 len = 16 - len;
3482 if (len > 0)
3483 vty_out (vty, "%*s", len, " ");
3485 else
3486 vty_out (vty, "self ");
3487 vty_out (vty, "%3d", rinfo->tag);
3490 vty_out (vty, "%s", VTY_NEWLINE);
3492 return CMD_SUCCESS;
3495 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3496 DEFUN (show_ip_rip_status,
3497 show_ip_rip_status_cmd,
3498 "show ip rip status",
3499 SHOW_STR
3500 IP_STR
3501 "Show RIP routes\n"
3502 "IP routing protocol process parameters and statistics\n")
3504 struct listnode *node;
3505 struct interface *ifp;
3506 struct rip_interface *ri;
3507 extern const struct message ri_version_msg[];
3508 const char *send_version;
3509 const char *receive_version;
3511 if (! rip)
3512 return CMD_SUCCESS;
3514 vty_out (vty, "Routing Protocol is \"rip\"%s", VTY_NEWLINE);
3515 vty_out (vty, " Sending updates every %ld seconds with +/-50%%,",
3516 rip->update_time);
3517 vty_out (vty, " next due in %lu seconds%s",
3518 thread_timer_remain_second(rip->t_update),
3519 VTY_NEWLINE);
3520 vty_out (vty, " Timeout after %ld seconds,", rip->timeout_time);
3521 vty_out (vty, " garbage collect after %ld seconds%s", rip->garbage_time,
3522 VTY_NEWLINE);
3524 /* Filtering status show. */
3525 config_show_distribute (vty);
3527 /* Default metric information. */
3528 vty_out (vty, " Default redistribution metric is %d%s",
3529 rip->default_metric, VTY_NEWLINE);
3531 /* Redistribute information. */
3532 vty_out (vty, " Redistributing:");
3533 config_write_rip_redistribute (vty, 0);
3534 vty_out (vty, "%s", VTY_NEWLINE);
3536 vty_out (vty, " Default version control: send version %s,",
3537 lookup(ri_version_msg,rip->version_send));
3538 if (rip->version_recv == RI_RIP_VERSION_1_AND_2)
3539 vty_out (vty, " receive any version %s", VTY_NEWLINE);
3540 else
3541 vty_out (vty, " receive version %s %s",
3542 lookup(ri_version_msg,rip->version_recv), VTY_NEWLINE);
3544 vty_out (vty, " Interface Send Recv Key-chain%s", VTY_NEWLINE);
3546 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
3548 ri = ifp->info;
3550 if (!ri->running)
3551 continue;
3553 if (ri->enable_network || ri->enable_interface)
3555 if (ri->ri_send == RI_RIP_UNSPEC)
3556 send_version = lookup (ri_version_msg, rip->version_send);
3557 else
3558 send_version = lookup (ri_version_msg, ri->ri_send);
3560 if (ri->ri_receive == RI_RIP_UNSPEC)
3561 receive_version = lookup (ri_version_msg, rip->version_recv);
3562 else
3563 receive_version = lookup (ri_version_msg, ri->ri_receive);
3565 vty_out (vty, " %-17s%-3s %-3s %s%s", ifp->name,
3566 send_version,
3567 receive_version,
3568 ri->key_chain ? ri->key_chain : "",
3569 VTY_NEWLINE);
3573 vty_out (vty, " Routing for Networks:%s", VTY_NEWLINE);
3574 config_write_rip_network (vty, 0);
3577 int found_passive = 0;
3578 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
3580 ri = ifp->info;
3582 if ((ri->enable_network || ri->enable_interface) && ri->passive)
3584 if (!found_passive)
3586 vty_out (vty, " Passive Interface(s):%s", VTY_NEWLINE);
3587 found_passive = 1;
3589 vty_out (vty, " %s%s", ifp->name, VTY_NEWLINE);
3594 vty_out (vty, " Routing Information Sources:%s", VTY_NEWLINE);
3595 vty_out (vty, " Gateway BadPackets BadRoutes Distance Last Update%s", VTY_NEWLINE);
3596 rip_peer_display (vty);
3598 rip_distance_show (vty);
3600 return CMD_SUCCESS;
3603 /* RIP configuration write function. */
3604 static int
3605 config_write_rip (struct vty *vty)
3607 int write = 0;
3608 struct route_node *rn;
3609 struct rip_distance *rdistance;
3611 if (rip)
3613 /* Router RIP statement. */
3614 vty_out (vty, "router rip%s", VTY_NEWLINE);
3615 write++;
3617 /* RIP version statement. Default is RIP version 2. */
3618 if (rip->version_send != RI_RIP_VERSION_2
3619 || rip->version_recv != RI_RIP_VERSION_1_AND_2)
3620 vty_out (vty, " version %d%s", rip->version_send,
3621 VTY_NEWLINE);
3623 /* RIP timer configuration. */
3624 if (rip->update_time != RIP_UPDATE_TIMER_DEFAULT
3625 || rip->timeout_time != RIP_TIMEOUT_TIMER_DEFAULT
3626 || rip->garbage_time != RIP_GARBAGE_TIMER_DEFAULT)
3627 vty_out (vty, " timers basic %lu %lu %lu%s",
3628 rip->update_time,
3629 rip->timeout_time,
3630 rip->garbage_time,
3631 VTY_NEWLINE);
3633 /* Default information configuration. */
3634 if (rip->default_information)
3636 if (rip->default_information_route_map)
3637 vty_out (vty, " default-information originate route-map %s%s",
3638 rip->default_information_route_map, VTY_NEWLINE);
3639 else
3640 vty_out (vty, " default-information originate%s",
3641 VTY_NEWLINE);
3644 /* Redistribute configuration. */
3645 config_write_rip_redistribute (vty, 1);
3647 /* RIP offset-list configuration. */
3648 config_write_rip_offset_list (vty);
3650 /* RIP enabled network and interface configuration. */
3651 config_write_rip_network (vty, 1);
3653 /* RIP default metric configuration */
3654 if (rip->default_metric != RIP_DEFAULT_METRIC_DEFAULT)
3655 vty_out (vty, " default-metric %d%s",
3656 rip->default_metric, VTY_NEWLINE);
3658 /* Distribute configuration. */
3659 write += config_write_distribute (vty);
3661 /* Interface routemap configuration */
3662 write += config_write_if_rmap (vty);
3664 /* Distance configuration. */
3665 if (rip->distance)
3666 vty_out (vty, " distance %d%s", rip->distance, VTY_NEWLINE);
3668 /* RIP source IP prefix distance configuration. */
3669 for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
3670 if ((rdistance = rn->info) != NULL)
3671 vty_out (vty, " distance %d %s/%d %s%s", rdistance->distance,
3672 inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
3673 rdistance->access_list ? rdistance->access_list : "",
3674 VTY_NEWLINE);
3676 /* RIP static route configuration. */
3677 for (rn = route_top (rip->route); rn; rn = route_next (rn))
3678 if (rn->info)
3679 vty_out (vty, " route %s/%d%s",
3680 inet_ntoa (rn->p.u.prefix4),
3681 rn->p.prefixlen,
3682 VTY_NEWLINE);
3685 return write;
3688 /* RIP node structure. */
3689 static struct cmd_node rip_node =
3691 RIP_NODE,
3692 "%s(config-router)# ",
3696 /* Distribute-list update functions. */
3697 static void
3698 rip_distribute_update (struct distribute *dist)
3700 struct interface *ifp;
3701 struct rip_interface *ri;
3702 struct access_list *alist;
3703 struct prefix_list *plist;
3705 if (! dist->ifname)
3706 return;
3708 ifp = if_lookup_by_name (dist->ifname);
3709 if (ifp == NULL)
3710 return;
3712 ri = ifp->info;
3714 if (dist->list[DISTRIBUTE_IN])
3716 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_IN]);
3717 if (alist)
3718 ri->list[RIP_FILTER_IN] = alist;
3719 else
3720 ri->list[RIP_FILTER_IN] = NULL;
3722 else
3723 ri->list[RIP_FILTER_IN] = NULL;
3725 if (dist->list[DISTRIBUTE_OUT])
3727 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_OUT]);
3728 if (alist)
3729 ri->list[RIP_FILTER_OUT] = alist;
3730 else
3731 ri->list[RIP_FILTER_OUT] = NULL;
3733 else
3734 ri->list[RIP_FILTER_OUT] = NULL;
3736 if (dist->prefix[DISTRIBUTE_IN])
3738 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_IN]);
3739 if (plist)
3740 ri->prefix[RIP_FILTER_IN] = plist;
3741 else
3742 ri->prefix[RIP_FILTER_IN] = NULL;
3744 else
3745 ri->prefix[RIP_FILTER_IN] = NULL;
3747 if (dist->prefix[DISTRIBUTE_OUT])
3749 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_OUT]);
3750 if (plist)
3751 ri->prefix[RIP_FILTER_OUT] = plist;
3752 else
3753 ri->prefix[RIP_FILTER_OUT] = NULL;
3755 else
3756 ri->prefix[RIP_FILTER_OUT] = NULL;
3759 void
3760 rip_distribute_update_interface (struct interface *ifp)
3762 struct distribute *dist;
3764 dist = distribute_lookup (ifp->name);
3765 if (dist)
3766 rip_distribute_update (dist);
3769 /* Update all interface's distribute list. */
3770 /* ARGSUSED */
3771 static void
3772 rip_distribute_update_all (struct prefix_list *notused)
3774 struct interface *ifp;
3775 struct listnode *node, *nnode;
3777 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
3778 rip_distribute_update_interface (ifp);
3780 /* ARGSUSED */
3781 static void
3782 rip_distribute_update_all_wrapper(struct access_list *notused)
3784 rip_distribute_update_all(NULL);
3787 /* Delete all added rip route. */
3788 void
3789 rip_clean (void)
3791 int i;
3792 struct route_node *rp;
3793 struct rip_info *rinfo;
3795 if (rip)
3797 /* Clear RIP routes */
3798 for (rp = route_top (rip->table); rp; rp = route_next (rp))
3799 if ((rinfo = rp->info) != NULL)
3801 if (rinfo->type == ZEBRA_ROUTE_RIP &&
3802 rinfo->sub_type == RIP_ROUTE_RTE)
3803 rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p,
3804 &rinfo->nexthop, rinfo->metric);
3806 RIP_TIMER_OFF (rinfo->t_timeout);
3807 RIP_TIMER_OFF (rinfo->t_garbage_collect);
3809 rp->info = NULL;
3810 route_unlock_node (rp);
3812 rip_info_free (rinfo);
3815 /* Cancel RIP related timers. */
3816 RIP_TIMER_OFF (rip->t_update);
3817 RIP_TIMER_OFF (rip->t_triggered_update);
3818 RIP_TIMER_OFF (rip->t_triggered_interval);
3820 /* Cancel read thread. */
3821 if (rip->t_read)
3823 thread_cancel (rip->t_read);
3824 rip->t_read = NULL;
3827 /* Close RIP socket. */
3828 if (rip->sock >= 0)
3830 close (rip->sock);
3831 rip->sock = -1;
3834 /* Static RIP route configuration. */
3835 for (rp = route_top (rip->route); rp; rp = route_next (rp))
3836 if (rp->info)
3838 rp->info = NULL;
3839 route_unlock_node (rp);
3842 /* RIP neighbor configuration. */
3843 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
3844 if (rp->info)
3846 rp->info = NULL;
3847 route_unlock_node (rp);
3850 /* Redistribute related clear. */
3851 if (rip->default_information_route_map)
3852 free (rip->default_information_route_map);
3854 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
3855 if (rip->route_map[i].name)
3856 free (rip->route_map[i].name);
3858 XFREE (MTYPE_ROUTE_TABLE, rip->table);
3859 XFREE (MTYPE_ROUTE_TABLE, rip->route);
3860 XFREE (MTYPE_ROUTE_TABLE, rip->neighbor);
3862 XFREE (MTYPE_RIP, rip);
3863 rip = NULL;
3866 rip_clean_network ();
3867 rip_passive_nondefault_clean ();
3868 rip_offset_clean ();
3869 rip_interface_clean ();
3870 rip_distance_reset ();
3871 rip_redistribute_clean ();
3874 /* Reset all values to the default settings. */
3875 void
3876 rip_reset (void)
3878 /* Reset global counters. */
3879 rip_global_route_changes = 0;
3880 rip_global_queries = 0;
3882 /* Call ripd related reset functions. */
3883 rip_debug_reset ();
3884 rip_route_map_reset ();
3886 /* Call library reset functions. */
3887 vty_reset ();
3888 access_list_reset ();
3889 prefix_list_reset ();
3891 distribute_list_reset ();
3893 rip_interface_reset ();
3894 rip_distance_reset ();
3896 rip_zclient_reset ();
3899 static void
3900 rip_if_rmap_update (struct if_rmap *if_rmap)
3902 struct interface *ifp;
3903 struct rip_interface *ri;
3904 struct route_map *rmap;
3906 ifp = if_lookup_by_name (if_rmap->ifname);
3907 if (ifp == NULL)
3908 return;
3910 ri = ifp->info;
3912 if (if_rmap->routemap[IF_RMAP_IN])
3914 rmap = route_map_lookup_by_name (if_rmap->routemap[IF_RMAP_IN]);
3915 if (rmap)
3916 ri->routemap[IF_RMAP_IN] = rmap;
3917 else
3918 ri->routemap[IF_RMAP_IN] = NULL;
3920 else
3921 ri->routemap[RIP_FILTER_IN] = NULL;
3923 if (if_rmap->routemap[IF_RMAP_OUT])
3925 rmap = route_map_lookup_by_name (if_rmap->routemap[IF_RMAP_OUT]);
3926 if (rmap)
3927 ri->routemap[IF_RMAP_OUT] = rmap;
3928 else
3929 ri->routemap[IF_RMAP_OUT] = NULL;
3931 else
3932 ri->routemap[RIP_FILTER_OUT] = NULL;
3935 void
3936 rip_if_rmap_update_interface (struct interface *ifp)
3938 struct if_rmap *if_rmap;
3940 if_rmap = if_rmap_lookup (ifp->name);
3941 if (if_rmap)
3942 rip_if_rmap_update (if_rmap);
3945 static void
3946 rip_routemap_update_redistribute (void)
3948 int i;
3950 if (rip)
3952 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
3954 if (rip->route_map[i].name)
3955 rip->route_map[i].map =
3956 route_map_lookup_by_name (rip->route_map[i].name);
3961 /* ARGSUSED */
3962 static void
3963 rip_routemap_update (const char *notused)
3965 struct interface *ifp;
3966 struct listnode *node, *nnode;
3968 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
3969 rip_if_rmap_update_interface (ifp);
3971 rip_routemap_update_redistribute ();
3974 /* Allocate new rip structure and set default value. */
3975 void
3976 rip_init (void)
3978 /* Randomize for triggered update random(). */
3979 srand (time (NULL));
3981 /* Install top nodes. */
3982 install_node (&rip_node, config_write_rip);
3984 /* Install rip commands. */
3985 install_element (VIEW_NODE, &show_ip_rip_cmd);
3986 install_element (VIEW_NODE, &show_ip_rip_status_cmd);
3987 install_element (ENABLE_NODE, &show_ip_rip_cmd);
3988 install_element (ENABLE_NODE, &show_ip_rip_status_cmd);
3989 install_element (CONFIG_NODE, &router_rip_cmd);
3990 install_element (CONFIG_NODE, &no_router_rip_cmd);
3992 install_default (RIP_NODE);
3993 install_element (RIP_NODE, &rip_version_cmd);
3994 install_element (RIP_NODE, &no_rip_version_cmd);
3995 install_element (RIP_NODE, &no_rip_version_val_cmd);
3996 install_element (RIP_NODE, &rip_default_metric_cmd);
3997 install_element (RIP_NODE, &no_rip_default_metric_cmd);
3998 install_element (RIP_NODE, &no_rip_default_metric_val_cmd);
3999 install_element (RIP_NODE, &rip_timers_cmd);
4000 install_element (RIP_NODE, &no_rip_timers_cmd);
4001 install_element (RIP_NODE, &no_rip_timers_val_cmd);
4002 install_element (RIP_NODE, &rip_route_cmd);
4003 install_element (RIP_NODE, &no_rip_route_cmd);
4004 install_element (RIP_NODE, &rip_distance_cmd);
4005 install_element (RIP_NODE, &no_rip_distance_cmd);
4006 install_element (RIP_NODE, &rip_distance_source_cmd);
4007 install_element (RIP_NODE, &no_rip_distance_source_cmd);
4008 install_element (RIP_NODE, &rip_distance_source_access_list_cmd);
4009 install_element (RIP_NODE, &no_rip_distance_source_access_list_cmd);
4011 /* Debug related init. */
4012 rip_debug_init ();
4014 /* SNMP init. */
4015 #ifdef HAVE_SNMP
4016 rip_snmp_init ();
4017 #endif /* HAVE_SNMP */
4019 /* Access list install. */
4020 access_list_init ();
4021 access_list_add_hook (rip_distribute_update_all_wrapper);
4022 access_list_delete_hook (rip_distribute_update_all_wrapper);
4024 /* Prefix list initialize.*/
4025 prefix_list_init ();
4026 prefix_list_add_hook (rip_distribute_update_all);
4027 prefix_list_delete_hook (rip_distribute_update_all);
4029 /* Distribute list install. */
4030 distribute_list_init (RIP_NODE);
4031 distribute_list_add_hook (rip_distribute_update);
4032 distribute_list_delete_hook (rip_distribute_update);
4034 /* Route-map */
4035 rip_route_map_init ();
4036 rip_offset_init ();
4038 route_map_add_hook (rip_routemap_update);
4039 route_map_delete_hook (rip_routemap_update);
4041 if_rmap_init (RIP_NODE);
4042 if_rmap_hook_add (rip_if_rmap_update);
4043 if_rmap_hook_delete (rip_if_rmap_update);
4045 /* Distance control. */
4046 rip_distance_table = route_table_init ();