blob: accac5e9c5836d658d13bbda2410e84bd4ca032a [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* RIP version 1 and 2.
2 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro <kunihiro@zebra.org>
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "if.h"
25#include "command.h"
26#include "prefix.h"
27#include "table.h"
28#include "thread.h"
29#include "memory.h"
30#include "log.h"
31#include "stream.h"
32#include "filter.h"
33#include "sockunion.h"
34#include "routemap.h"
hasso16705132003-05-25 14:49:19 +000035#include "if_rmap.h"
paul718e3742002-12-13 20:15:29 +000036#include "plist.h"
37#include "distribute.h"
38#include "md5-gnu.h"
39#include "keychain.h"
pauledd7c242003-06-04 13:59:38 +000040#include "privs.h"
paul718e3742002-12-13 20:15:29 +000041
42#include "ripd/ripd.h"
43#include "ripd/rip_debug.h"
44
pauledd7c242003-06-04 13:59:38 +000045extern struct zebra_privs_t ripd_privs;
46
paul718e3742002-12-13 20:15:29 +000047/* RIP Structure. */
48struct rip *rip = NULL;
49
50/* RIP neighbor address table. */
51struct route_table *rip_neighbor_table;
52
53/* RIP route changes. */
54long rip_global_route_changes = 0;
55
56/* RIP queries. */
57long rip_global_queries = 0;
58
59/* Prototypes. */
60void rip_event (enum rip_event, int);
61
paul727d1042002-12-13 20:50:29 +000062void rip_output_process (struct interface *, struct prefix *,
paulcc1131a2003-10-15 23:20:17 +000063 struct sockaddr_in *, int, u_char,
64 struct prefix_ipv4 *);
paul718e3742002-12-13 20:15:29 +000065
66/* RIP output routes type. */
67enum
68{
69 rip_all_route,
70 rip_changed_route
71};
72
73/* RIP command strings. */
74struct message rip_msg[] =
75{
76 {RIP_REQUEST, "REQUEST"},
77 {RIP_RESPONSE, "RESPONSE"},
78 {RIP_TRACEON, "TRACEON"},
79 {RIP_TRACEOFF, "TRACEOFF"},
80 {RIP_POLL, "POLL"},
81 {RIP_POLL_ENTRY, "POLL ENTRY"},
82 {0, NULL}
83};
84
85/* Each route type's strings and default preference. */
86struct
87{
88 int key;
89 char *str;
90 char *str_long;
91} route_info[] =
92{
93 { ZEBRA_ROUTE_SYSTEM, "X", "system"},
94 { ZEBRA_ROUTE_KERNEL, "K", "kernel"},
95 { ZEBRA_ROUTE_CONNECT, "C", "connected"},
96 { ZEBRA_ROUTE_STATIC, "S", "static"},
97 { ZEBRA_ROUTE_RIP, "R", "rip"},
98 { ZEBRA_ROUTE_RIPNG, "R", "ripng"},
99 { ZEBRA_ROUTE_OSPF, "O", "ospf"},
100 { ZEBRA_ROUTE_OSPF6, "O", "ospf6"},
101 { ZEBRA_ROUTE_BGP, "B", "bgp"}
102};
103
104/* Utility function to set boradcast option to the socket. */
105int
106sockopt_broadcast (int sock)
107{
108 int ret;
109 int on = 1;
110
111 ret = setsockopt (sock, SOL_SOCKET, SO_BROADCAST, (char *) &on, sizeof on);
112 if (ret < 0)
113 {
114 zlog_warn ("can't set sockopt SO_BROADCAST to socket %d", sock);
115 return -1;
116 }
117 return 0;
118}
119
120int
121rip_route_rte (struct rip_info *rinfo)
122{
123 return (rinfo->type == ZEBRA_ROUTE_RIP && rinfo->sub_type == RIP_ROUTE_RTE);
124}
125
126struct rip_info *
127rip_info_new ()
128{
129 struct rip_info *new;
130
131 new = XMALLOC (MTYPE_RIP_INFO, sizeof (struct rip_info));
132 memset (new, 0, sizeof (struct rip_info));
133 return new;
134}
135
136void
137rip_info_free (struct rip_info *rinfo)
138{
139 XFREE (MTYPE_RIP_INFO, rinfo);
140}
141
142/* RIP route garbage collect timer. */
143int
144rip_garbage_collect (struct thread *t)
145{
146 struct rip_info *rinfo;
147 struct route_node *rp;
148
149 rinfo = THREAD_ARG (t);
150 rinfo->t_garbage_collect = NULL;
151
152 /* Off timeout timer. */
153 RIP_TIMER_OFF (rinfo->t_timeout);
154
155 /* Get route_node pointer. */
156 rp = rinfo->rp;
157
158 /* Unlock route_node. */
159 rp->info = NULL;
160 route_unlock_node (rp);
161
162 /* Free RIP routing information. */
163 rip_info_free (rinfo);
164
165 return 0;
166}
167
168/* Timeout RIP routes. */
169int
170rip_timeout (struct thread *t)
171{
172 struct rip_info *rinfo;
173 struct route_node *rn;
174
175 rinfo = THREAD_ARG (t);
176 rinfo->t_timeout = NULL;
177
178 rn = rinfo->rp;
179
180 /* - The garbage-collection timer is set for 120 seconds. */
181 RIP_TIMER_ON (rinfo->t_garbage_collect, rip_garbage_collect,
182 rip->garbage_time);
183
184 rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rn->p, &rinfo->nexthop,
185 rinfo->metric);
186 /* - The metric for the route is set to 16 (infinity). This causes
187 the route to be removed from service. */
188 rinfo->metric = RIP_METRIC_INFINITY;
189 rinfo->flags &= ~RIP_RTF_FIB;
190
191 /* - The route change flag is to indicate that this entry has been
192 changed. */
193 rinfo->flags |= RIP_RTF_CHANGED;
194
195 /* - The output process is signalled to trigger a response. */
196 rip_event (RIP_TRIGGERED_UPDATE, 0);
197
198 return 0;
199}
200
201void
202rip_timeout_update (struct rip_info *rinfo)
203{
204 if (rinfo->metric != RIP_METRIC_INFINITY)
205 {
206 RIP_TIMER_OFF (rinfo->t_timeout);
207 RIP_TIMER_ON (rinfo->t_timeout, rip_timeout, rip->timeout_time);
208 }
209}
210
211int
212rip_incoming_filter (struct prefix_ipv4 *p, struct rip_interface *ri)
213{
214 struct distribute *dist;
215 struct access_list *alist;
216 struct prefix_list *plist;
217
218 /* Input distribute-list filtering. */
219 if (ri->list[RIP_FILTER_IN])
220 {
221 if (access_list_apply (ri->list[RIP_FILTER_IN],
222 (struct prefix *) p) == FILTER_DENY)
223 {
224 if (IS_RIP_DEBUG_PACKET)
225 zlog_info ("%s/%d filtered by distribute in",
226 inet_ntoa (p->prefix), p->prefixlen);
227 return -1;
228 }
229 }
230 if (ri->prefix[RIP_FILTER_IN])
231 {
232 if (prefix_list_apply (ri->prefix[RIP_FILTER_IN],
233 (struct prefix *) p) == PREFIX_DENY)
234 {
235 if (IS_RIP_DEBUG_PACKET)
236 zlog_info ("%s/%d filtered by prefix-list in",
237 inet_ntoa (p->prefix), p->prefixlen);
238 return -1;
239 }
240 }
241
242 /* All interface filter check. */
243 dist = distribute_lookup (NULL);
244 if (dist)
245 {
246 if (dist->list[DISTRIBUTE_IN])
247 {
248 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_IN]);
249
250 if (alist)
251 {
252 if (access_list_apply (alist,
253 (struct prefix *) p) == FILTER_DENY)
254 {
255 if (IS_RIP_DEBUG_PACKET)
256 zlog_info ("%s/%d filtered by distribute in",
257 inet_ntoa (p->prefix), p->prefixlen);
258 return -1;
259 }
260 }
261 }
262 if (dist->prefix[DISTRIBUTE_IN])
263 {
264 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_IN]);
265
266 if (plist)
267 {
268 if (prefix_list_apply (plist,
269 (struct prefix *) p) == PREFIX_DENY)
270 {
271 if (IS_RIP_DEBUG_PACKET)
272 zlog_info ("%s/%d filtered by prefix-list in",
273 inet_ntoa (p->prefix), p->prefixlen);
274 return -1;
275 }
276 }
277 }
278 }
279 return 0;
280}
281
282int
283rip_outgoing_filter (struct prefix_ipv4 *p, struct rip_interface *ri)
284{
285 struct distribute *dist;
286 struct access_list *alist;
287 struct prefix_list *plist;
288
289 if (ri->list[RIP_FILTER_OUT])
290 {
291 if (access_list_apply (ri->list[RIP_FILTER_OUT],
292 (struct prefix *) p) == FILTER_DENY)
293 {
294 if (IS_RIP_DEBUG_PACKET)
295 zlog_info ("%s/%d is filtered by distribute out",
296 inet_ntoa (p->prefix), p->prefixlen);
297 return -1;
298 }
299 }
300 if (ri->prefix[RIP_FILTER_OUT])
301 {
302 if (prefix_list_apply (ri->prefix[RIP_FILTER_OUT],
303 (struct prefix *) p) == PREFIX_DENY)
304 {
305 if (IS_RIP_DEBUG_PACKET)
306 zlog_info ("%s/%d is filtered by prefix-list out",
307 inet_ntoa (p->prefix), p->prefixlen);
308 return -1;
309 }
310 }
311
312 /* All interface filter check. */
313 dist = distribute_lookup (NULL);
314 if (dist)
315 {
316 if (dist->list[DISTRIBUTE_OUT])
317 {
318 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_OUT]);
319
320 if (alist)
321 {
322 if (access_list_apply (alist,
323 (struct prefix *) p) == FILTER_DENY)
324 {
325 if (IS_RIP_DEBUG_PACKET)
326 zlog_info ("%s/%d filtered by distribute out",
327 inet_ntoa (p->prefix), p->prefixlen);
328 return -1;
329 }
330 }
331 }
332 if (dist->prefix[DISTRIBUTE_OUT])
333 {
334 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_OUT]);
335
336 if (plist)
337 {
338 if (prefix_list_apply (plist,
339 (struct prefix *) p) == PREFIX_DENY)
340 {
341 if (IS_RIP_DEBUG_PACKET)
342 zlog_info ("%s/%d filtered by prefix-list out",
343 inet_ntoa (p->prefix), p->prefixlen);
344 return -1;
345 }
346 }
347 }
348 }
349 return 0;
350}
351
352/* Check nexthop address validity. */
353static int
354rip_nexthop_check (struct in_addr *addr)
355{
356 listnode node;
357 listnode cnode;
358 struct interface *ifp;
359 struct connected *ifc;
360 struct prefix *p;
361
362 /* If nexthop address matches local configured address then it is
363 invalid nexthop. */
364 for (node = listhead (iflist); node; nextnode (node))
365 {
366 ifp = getdata (node);
367
368 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
369 {
370 ifc = getdata (cnode);
371 p = ifc->address;
372
373 if (p->family == AF_INET
374 && IPV4_ADDR_SAME (&p->u.prefix4, addr))
375 return -1;
376 }
377 }
378 return 0;
379}
380
381/* RIP add route to routing table. */
382void
383rip_rte_process (struct rte *rte, struct sockaddr_in *from,
384 struct interface *ifp)
385
386{
387 int ret;
388 struct prefix_ipv4 p;
389 struct route_node *rp;
390 struct rip_info *rinfo;
391 struct rip_interface *ri;
392 struct in_addr *nexthop;
393 u_char oldmetric;
394 int same = 0;
395
396 /* Make prefix structure. */
397 memset (&p, 0, sizeof (struct prefix_ipv4));
398 p.family = AF_INET;
399 p.prefix = rte->prefix;
400 p.prefixlen = ip_masklen (rte->mask);
401
402 /* Make sure mask is applied. */
403 apply_mask_ipv4 (&p);
404
405 /* Apply input filters. */
406 ri = ifp->info;
407
408 ret = rip_incoming_filter (&p, ri);
409 if (ret < 0)
410 return;
411
hasso16705132003-05-25 14:49:19 +0000412 /* Modify entry according to the interface routemap. */
413 if (ri->routemap[RIP_FILTER_IN])
414 {
415 int ret;
416 struct rip_info newinfo;
417
418 memset (&newinfo, 0, sizeof (newinfo));
419 newinfo.type = ZEBRA_ROUTE_RIP;
420 newinfo.sub_type = RIP_ROUTE_RTE;
421 newinfo.nexthop= rte->nexthop;
422 newinfo.from = from->sin_addr;
423 newinfo.ifindex= ifp->ifindex;
424 newinfo.metric = rte->metric;
425 newinfo.metric_out = rte->metric; /* XXX */
426 newinfo.tag = ntohs(rte->tag); /* XXX */
427
428 /* The object should be of the type of rip_info */
429 ret = route_map_apply (ri->routemap[RIP_FILTER_IN],
430 (struct prefix *)&p, RMAP_RIP, &newinfo);
431
432 if (ret == RMAP_DENYMATCH)
433 {
434 if (IS_RIP_DEBUG_PACKET)
435 zlog_info ("RIP %s/%d is filtered by route-map in",
436 inet_ntoa (p.prefix), p.prefixlen);
437 return;
438 }
439
440 /* Get back the object */
441 rte->nexthop = newinfo.nexthop_out;
442 rte->tag = htons(newinfo.tag_out); /* XXX */
443 rte->metric = newinfo.metric_out; /* XXX: the routemap uses the metric_out field */
444 }
445
paul718e3742002-12-13 20:15:29 +0000446 /* Once the entry has been validated, update the metric by
447 adding the cost of the network on wich the message
448 arrived. If the result is greater than infinity, use infinity
449 (RFC2453 Sec. 3.9.2) */
450 /* Zebra ripd can handle offset-list in. */
451 ret = rip_offset_list_apply_in (&p, ifp, &rte->metric);
452
453 /* If offset-list does not modify the metric use interface's
454 metric. */
455 if (! ret)
456 rte->metric += ifp->metric;
457
458 if (rte->metric > RIP_METRIC_INFINITY)
459 rte->metric = RIP_METRIC_INFINITY;
460
461 /* Set nexthop pointer. */
462 if (rte->nexthop.s_addr == 0)
463 nexthop = &from->sin_addr;
464 else
465 nexthop = &rte->nexthop;
466
hasso16705132003-05-25 14:49:19 +0000467 /* Check if nexthop address is myself, then do nothing. */
paul718e3742002-12-13 20:15:29 +0000468 if (rip_nexthop_check (nexthop) < 0)
469 {
470 if (IS_RIP_DEBUG_PACKET)
hasso16705132003-05-25 14:49:19 +0000471 zlog_info ("Nexthop address %s is myself", inet_ntoa (*nexthop));
paul718e3742002-12-13 20:15:29 +0000472 return;
473 }
474
475 /* Get index for the prefix. */
476 rp = route_node_get (rip->table, (struct prefix *) &p);
477
478 /* Check to see whether there is already RIP route on the table. */
479 rinfo = rp->info;
480
481 if (rinfo)
482 {
483 /* Redistributed route check. */
484 if (rinfo->type != ZEBRA_ROUTE_RIP
485 && rinfo->metric != RIP_METRIC_INFINITY)
486 return;
487
488 /* Local static route. */
489 if (rinfo->type == ZEBRA_ROUTE_RIP
hasso16705132003-05-25 14:49:19 +0000490 && ((rinfo->sub_type == RIP_ROUTE_STATIC) ||
491 (rinfo->sub_type == RIP_ROUTE_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000492 && rinfo->metric != RIP_METRIC_INFINITY)
493 return;
494 }
495
496 if (! rinfo)
497 {
498 /* Now, check to see whether there is already an explicit route
499 for the destination prefix. If there is no such route, add
500 this route to the routing table, unless the metric is
501 infinity (there is no point in adding a route which
502 unusable). */
503 if (rte->metric != RIP_METRIC_INFINITY)
504 {
505 rinfo = rip_info_new ();
506
507 /* - Setting the destination prefix and length to those in
508 the RTE. */
509 rinfo->rp = rp;
510
511 /* - Setting the metric to the newly calculated metric (as
512 described above). */
513 rinfo->metric = rte->metric;
514 rinfo->tag = ntohs (rte->tag);
515
516 /* - Set the next hop address to be the address of the router
517 from which the datagram came or the next hop address
518 specified by a next hop RTE. */
519 IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);
520 IPV4_ADDR_COPY (&rinfo->from, &from->sin_addr);
521 rinfo->ifindex = ifp->ifindex;
522
523 /* - Initialize the timeout for the route. If the
524 garbage-collection timer is running for this route, stop it
525 (see section 2.3 for a discussion of the timers). */
526 rip_timeout_update (rinfo);
527
528 /* - Set the route change flag. */
529 rinfo->flags |= RIP_RTF_CHANGED;
530
531 /* - Signal the output process to trigger an update (see section
532 2.5). */
533 rip_event (RIP_TRIGGERED_UPDATE, 0);
534
535 /* Finally, route goes into the kernel. */
536 rinfo->type = ZEBRA_ROUTE_RIP;
537 rinfo->sub_type = RIP_ROUTE_RTE;
538
539 /* Set distance value. */
540 rinfo->distance = rip_distance_apply (rinfo);
541
542 rp->info = rinfo;
543 rip_zebra_ipv4_add (&p, &rinfo->nexthop, rinfo->metric,
544 rinfo->distance);
545 rinfo->flags |= RIP_RTF_FIB;
546 }
547 }
548 else
549 {
550 /* Route is there but we are not sure the route is RIP or not. */
551 rinfo = rp->info;
552
553 /* If there is an existing route, compare the next hop address
554 to the address of the router from which the datagram came.
555 If this datagram is from the same router as the existing
556 route, reinitialize the timeout. */
hasso16705132003-05-25 14:49:19 +0000557 same = (IPV4_ADDR_SAME (&rinfo->from, &from->sin_addr)
558 && (rinfo->ifindex == ifp->ifindex));
paul718e3742002-12-13 20:15:29 +0000559
560 if (same)
561 rip_timeout_update (rinfo);
562
563 /* Next, compare the metrics. If the datagram is from the same
564 router as the existing route, and the new metric is different
565 than the old one; or, if the new metric is lower than the old
hasso16705132003-05-25 14:49:19 +0000566 one, or if the tag has been changed; do the following actions: */
paul718e3742002-12-13 20:15:29 +0000567 if ((same && rinfo->metric != rte->metric) ||
hasso16705132003-05-25 14:49:19 +0000568 (rte->metric < rinfo->metric) ||
569 (same && (rinfo->metric == rte->metric) && ntohs(rte->tag) != rinfo->tag))
paul718e3742002-12-13 20:15:29 +0000570 {
571 /* - Adopt the route from the datagram. That is, put the
572 new metric in, and adjust the next hop address (if
573 necessary). */
574 oldmetric = rinfo->metric;
575 rinfo->metric = rte->metric;
576 rinfo->tag = ntohs (rte->tag);
577 IPV4_ADDR_COPY (&rinfo->from, &from->sin_addr);
578 rinfo->ifindex = ifp->ifindex;
579 rinfo->distance = rip_distance_apply (rinfo);
580
581 /* Should a new route to this network be established
582 while the garbage-collection timer is running, the
583 new route will replace the one that is about to be
584 deleted. In this case the garbage-collection timer
585 must be cleared. */
586
587 if (oldmetric == RIP_METRIC_INFINITY &&
588 rinfo->metric < RIP_METRIC_INFINITY)
589 {
590 rinfo->type = ZEBRA_ROUTE_RIP;
591 rinfo->sub_type = RIP_ROUTE_RTE;
592
593 RIP_TIMER_OFF (rinfo->t_garbage_collect);
594
595 if (! IPV4_ADDR_SAME (&rinfo->nexthop, nexthop))
596 IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);
597
598 rip_zebra_ipv4_add (&p, nexthop, rinfo->metric,
599 rinfo->distance);
600 rinfo->flags |= RIP_RTF_FIB;
601 }
602
603 /* Update nexthop and/or metric value. */
604 if (oldmetric != RIP_METRIC_INFINITY)
605 {
606 rip_zebra_ipv4_delete (&p, &rinfo->nexthop, oldmetric);
607 rip_zebra_ipv4_add (&p, nexthop, rinfo->metric,
608 rinfo->distance);
609 rinfo->flags |= RIP_RTF_FIB;
610
611 if (! IPV4_ADDR_SAME (&rinfo->nexthop, nexthop))
612 IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);
613 }
614
615 /* - Set the route change flag and signal the output process
616 to trigger an update. */
617 rinfo->flags |= RIP_RTF_CHANGED;
618 rip_event (RIP_TRIGGERED_UPDATE, 0);
619
620 /* - If the new metric is infinity, start the deletion
621 process (described above); */
622 if (rinfo->metric == RIP_METRIC_INFINITY)
623 {
624 /* If the new metric is infinity, the deletion process
625 begins for the route, which is no longer used for
626 routing packets. Note that the deletion process is
627 started only when the metric is first set to
628 infinity. If the metric was already infinity, then a
629 new deletion process is not started. */
630 if (oldmetric != RIP_METRIC_INFINITY)
631 {
632 /* - The garbage-collection timer is set for 120 seconds. */
633 RIP_TIMER_ON (rinfo->t_garbage_collect,
634 rip_garbage_collect, rip->garbage_time);
635 RIP_TIMER_OFF (rinfo->t_timeout);
636
637 /* - The metric for the route is set to 16
638 (infinity). This causes the route to be removed
639 from service.*/
640 rip_zebra_ipv4_delete (&p, &rinfo->nexthop, oldmetric);
641 rinfo->flags &= ~RIP_RTF_FIB;
642
643 /* - The route change flag is to indicate that this
644 entry has been changed. */
645 /* - The output process is signalled to trigger a
646 response. */
647 ; /* Above processes are already done previously. */
648 }
649 }
650 else
651 {
652 /* otherwise, re-initialize the timeout. */
653 rip_timeout_update (rinfo);
654 }
655 }
656 /* Unlock tempolary lock of the route. */
657 route_unlock_node (rp);
658 }
659}
660
661/* Dump RIP packet */
662void
663rip_packet_dump (struct rip_packet *packet, int size, char *sndrcv)
664{
665 caddr_t lim;
666 struct rte *rte;
667 char *command_str;
668 char pbuf[BUFSIZ], nbuf[BUFSIZ];
669 u_char netmask = 0;
670 u_char *p;
671
672 /* Set command string. */
673 if (packet->command > 0 && packet->command < RIP_COMMAND_MAX)
674 command_str = lookup (rip_msg, packet->command);
675 else
676 command_str = "unknown";
677
678 /* Dump packet header. */
679 zlog_info ("%s %s version %d packet size %d",
680 sndrcv, command_str, packet->version, size);
681
682 /* Dump each routing table entry. */
683 rte = packet->rte;
684
685 for (lim = (caddr_t) packet + size; (caddr_t) rte < lim; rte++)
686 {
687 if (packet->version == RIPv2)
688 {
689 netmask = ip_masklen (rte->mask);
690
691 if (ntohs (rte->family) == 0xffff)
692 {
693 if (ntohs (rte->tag) == RIP_AUTH_SIMPLE_PASSWORD)
694 {
695 p = (u_char *)&rte->prefix;
696
697 zlog_info (" family 0x%X type %d auth string: %s",
698 ntohs (rte->family), ntohs (rte->tag), p);
699 }
700 else if (ntohs (rte->tag) == RIP_AUTH_MD5)
701 {
702 struct rip_md5_info *md5;
703
704 md5 = (struct rip_md5_info *) &packet->rte;
705
706 zlog_info (" family 0x%X type %d (MD5 authentication)",
707 ntohs (md5->family), ntohs (md5->type));
708 zlog_info (" RIP-2 packet len %d Key ID %d"
709 " Auth Data len %d", ntohs (md5->packet_len),
710 md5->keyid, md5->auth_len);
711 zlog_info (" Sequence Number %ld", (u_long)ntohl (md5->sequence));
712 }
713 else if (ntohs (rte->tag) == RIP_AUTH_DATA)
714 {
715 p = (u_char *)&rte->prefix;
716
717 zlog_info (" family 0x%X type %d (MD5 data)",
718 ntohs (rte->family), ntohs (rte->tag));
719 zlog_info (" MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
720 "%02X%02X%02X%02X%02X%02X%02X",
721 p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],
722 p[9],p[10],p[11],p[12],p[13],p[14],p[15]);
723 }
724 else
725 {
726 zlog_info (" family 0x%X type %d (Unknown auth type)",
727 ntohs (rte->family), ntohs (rte->tag));
728 }
729 }
730 else
731 zlog_info (" %s/%d -> %s family %d tag %d metric %ld",
732 inet_ntop (AF_INET, &rte->prefix, pbuf, BUFSIZ),netmask,
733 inet_ntop (AF_INET, &rte->nexthop, nbuf, BUFSIZ),
734 ntohs (rte->family), ntohs (rte->tag),
735 (u_long)ntohl (rte->metric));
736 }
737 else
738 {
739 zlog_info (" %s family %d tag %d metric %ld",
740 inet_ntop (AF_INET, &rte->prefix, pbuf, BUFSIZ),
741 ntohs (rte->family), ntohs (rte->tag),
742 (u_long)ntohl (rte->metric));
743 }
744 }
745}
746
747/* Check if the destination address is valid (unicast; not net 0
748 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
749 check net 0 because we accept default route. */
750int
751rip_destination_check (struct in_addr addr)
752{
753 u_int32_t destination;
754
755 /* Convert to host byte order. */
756 destination = ntohl (addr.s_addr);
757
758 if (IPV4_NET127 (destination))
759 return 0;
760
761 /* Net 0 may match to the default route. */
762 if (IPV4_NET0 (destination) && destination != 0)
763 return 0;
764
765 /* Unicast address must belong to class A, B, C. */
766 if (IN_CLASSA (destination))
767 return 1;
768 if (IN_CLASSB (destination))
769 return 1;
770 if (IN_CLASSC (destination))
771 return 1;
772
773 return 0;
774}
775
776/* RIP version 2 authentication. */
777int
778rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from,
779 struct interface *ifp)
780{
781 struct rip_interface *ri;
782 char *auth_str;
783
784 if (IS_RIP_DEBUG_EVENT)
785 zlog_info ("RIPv2 simple password authentication from %s",
786 inet_ntoa (from->sin_addr));
787
788 ri = ifp->info;
789
790 if (ri->auth_type != RIP_AUTH_SIMPLE_PASSWORD
791 || ntohs (rte->tag) != RIP_AUTH_SIMPLE_PASSWORD)
792 return 0;
793
794 /* Simple password authentication. */
795 if (ri->auth_str)
796 {
797 auth_str = (char *) &rte->prefix;
798
799 if (strncmp (auth_str, ri->auth_str, 16) == 0)
800 return 1;
801 }
802 if (ri->key_chain)
803 {
804 struct keychain *keychain;
805 struct key *key;
806
807 keychain = keychain_lookup (ri->key_chain);
808 if (keychain == NULL)
809 return 0;
810
811 key = key_match_for_accept (keychain, (char *) &rte->prefix);
812 if (key)
813 return 1;
814 }
815 return 0;
816}
817
818/* RIP version 2 authentication with MD5. */
819int
820rip_auth_md5 (struct rip_packet *packet, struct sockaddr_in *from,
821 struct interface *ifp)
822{
823 struct rip_interface *ri;
824 struct rip_md5_info *md5;
825 struct rip_md5_data *md5data;
826 struct keychain *keychain;
827 struct key *key;
828 struct md5_ctx ctx;
829 u_char pdigest[RIP_AUTH_MD5_SIZE];
830 u_char digest[RIP_AUTH_MD5_SIZE];
831 u_int16_t packet_len;
832 char *auth_str = NULL;
833
834 if (IS_RIP_DEBUG_EVENT)
835 zlog_info ("RIPv2 MD5 authentication from %s", inet_ntoa (from->sin_addr));
836
837 ri = ifp->info;
838 md5 = (struct rip_md5_info *) &packet->rte;
839
840 /* Check auth type. */
841 if (ri->auth_type != RIP_AUTH_MD5 || ntohs (md5->type) != RIP_AUTH_MD5)
842 return 0;
843
844 if (md5->auth_len != RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE)
845 return 0;
846
847 if (ri->key_chain)
848 {
849 keychain = keychain_lookup (ri->key_chain);
850 if (keychain == NULL)
851 return 0;
852
853 key = key_lookup_for_accept (keychain, md5->keyid);
854 if (key == NULL)
855 return 0;
856
857 auth_str = key->string;
858 }
859
860 if (ri->auth_str)
861 auth_str = ri->auth_str;
862
863 if (! auth_str)
864 return 0;
865
866 /* MD5 digest authentication. */
867 packet_len = ntohs (md5->packet_len);
868 md5data = (struct rip_md5_data *)(((u_char *) packet) + packet_len);
869
870 /* Save digest to pdigest. */
871 memcpy (pdigest, md5data->digest, RIP_AUTH_MD5_SIZE);
872
873 /* Overwrite digest by my secret. */
874 memset (md5data->digest, 0, RIP_AUTH_MD5_SIZE);
875 strncpy (md5data->digest, auth_str, RIP_AUTH_MD5_SIZE);
876
877 md5_init_ctx (&ctx);
878 md5_process_bytes (packet, packet_len + md5->auth_len, &ctx);
879 md5_finish_ctx (&ctx, digest);
880
881 if (memcmp (pdigest, digest, RIP_AUTH_MD5_SIZE) == 0)
882 return packet_len;
883 else
884 return 0;
885}
886
887void
888rip_auth_md5_set (struct stream *s, struct interface *ifp)
889{
890 struct rip_interface *ri;
891 struct keychain *keychain = NULL;
892 struct key *key = NULL;
893 unsigned long len;
894 struct md5_ctx ctx;
895 unsigned char secret[RIP_AUTH_MD5_SIZE];
896 unsigned char digest[RIP_AUTH_MD5_SIZE];
897 char *auth_str = NULL;
898
899 ri = ifp->info;
900
901 /* Make it sure this interface is configured as MD5
902 authentication. */
903 if (ri->auth_type != RIP_AUTH_MD5)
904 return;
905
906 /* Lookup key chain. */
907 if (ri->key_chain)
908 {
909 keychain = keychain_lookup (ri->key_chain);
910 if (keychain == NULL)
911 return;
912
913 /* Lookup key. */
914 key = key_lookup_for_send (keychain);
915 if (key == NULL)
916 return;
917
918 auth_str = key->string;
919 }
920
921 if (ri->auth_str)
922 auth_str = ri->auth_str;
923
924 if (! auth_str)
925 return;
926
927 /* Get packet length. */
928 len = s->putp;
929
930 /* Check packet length. */
931 if (len < (RIP_HEADER_SIZE + RIP_RTE_SIZE))
932 {
933 zlog_err ("rip_auth_md5_set(): packet length %ld is less than minimum length.", len);
934 return;
935 }
936
937 /* Move RTE. */
938 memmove (s->data + RIP_HEADER_SIZE + RIP_RTE_SIZE,
939 s->data + RIP_HEADER_SIZE,
940 len - RIP_HEADER_SIZE);
941
942 /* Set pointer to authentication header. */
943 stream_set_putp (s, RIP_HEADER_SIZE);
944 len += RIP_RTE_SIZE;
945
946 /* MD5 authentication. */
947 stream_putw (s, 0xffff);
948 stream_putw (s, RIP_AUTH_MD5);
949
950 /* RIP-2 Packet length. Actual value is filled in
951 rip_auth_md5_set(). */
952 stream_putw (s, len);
953
954 /* Key ID. */
955 if (key)
956 stream_putc (s, key->index % 256);
957 else
958 stream_putc (s, 1);
959
960 /* Auth Data Len. Set 16 for MD5 authentication
961 data. */
962 stream_putc (s, RIP_AUTH_MD5_SIZE + RIP_HEADER_SIZE);
963
964 /* Sequence Number (non-decreasing). */
965 /* RFC2080: The value used in the sequence number is
966 arbitrary, but two suggestions are the time of the
967 message's creation or a simple message counter. */
968 stream_putl (s, time (NULL));
969
970 /* Reserved field must be zero. */
971 stream_putl (s, 0);
972 stream_putl (s, 0);
973
974 /* Set pointer to authentication data. */
975 stream_set_putp (s, len);
976
977 /* Set authentication data. */
978 stream_putw (s, 0xffff);
979 stream_putw (s, 0x01);
980
981 /* Generate a digest for the RIP packet. */
982 memset (secret, 0, RIP_AUTH_MD5_SIZE);
983 strncpy (secret, auth_str, RIP_AUTH_MD5_SIZE);
984 md5_init_ctx (&ctx);
985 md5_process_bytes (s->data, s->endp, &ctx);
986 md5_process_bytes (secret, RIP_AUTH_MD5_SIZE, &ctx);
987 md5_finish_ctx (&ctx, digest);
988
989 /* Copy the digest to the packet. */
990 stream_write (s, digest, RIP_AUTH_MD5_SIZE);
991}
992
993/* RIP routing information. */
994void
995rip_response_process (struct rip_packet *packet, int size,
996 struct sockaddr_in *from, struct interface *ifp)
997{
998 caddr_t lim;
999 struct rte *rte;
paul727d1042002-12-13 20:50:29 +00001000 struct prefix_ipv4 ifaddr;
1001 struct prefix_ipv4 ifaddrclass;
1002 struct connected *c;
1003 int subnetted;
paul718e3742002-12-13 20:15:29 +00001004
paul727d1042002-12-13 20:50:29 +00001005 /* We don't know yet. */
1006 subnetted = -1;
1007
paul718e3742002-12-13 20:15:29 +00001008 /* The Response must be ignored if it is not from the RIP
1009 port. (RFC2453 - Sec. 3.9.2)*/
1010 if (ntohs (from->sin_port) != RIP_PORT_DEFAULT)
1011 {
1012 zlog_info ("response doesn't come from RIP port: %d",
1013 from->sin_port);
1014 rip_peer_bad_packet (from);
1015 return;
1016 }
1017
1018 /* The datagram's IPv4 source address should be checked to see
1019 whether the datagram is from a valid neighbor; the source of the
1020 datagram must be on a directly connected network */
paul31a476c2003-09-29 19:54:53 +00001021 if (! if_valid_neighbor (from->sin_addr))
paul718e3742002-12-13 20:15:29 +00001022 {
1023 zlog_info ("This datagram doesn't came from a valid neighbor: %s",
1024 inet_ntoa (from->sin_addr));
1025 rip_peer_bad_packet (from);
1026 return;
1027 }
1028
1029 /* It is also worth checking to see whether the response is from one
1030 of the router's own addresses. */
1031
1032 ; /* Alredy done in rip_read () */
1033
1034 /* Update RIP peer. */
1035 rip_peer_update (from, packet->version);
1036
1037 /* Set RTE pointer. */
1038 rte = packet->rte;
1039
1040 for (lim = (caddr_t) packet + size; (caddr_t) rte < lim; rte++)
1041 {
1042 /* RIPv2 authentication check. */
1043 /* If the Address Family Identifier of the first (and only the
1044 first) entry in the message is 0xFFFF, then the remainder of
1045 the entry contains the authentication. */
1046 /* If the packet gets here it means authentication enabled */
1047 /* Check is done in rip_read(). So, just skipping it */
1048 if (packet->version == RIPv2 &&
1049 rte == packet->rte &&
1050 rte->family == 0xffff)
1051 continue;
1052
1053 if (ntohs (rte->family) != AF_INET)
1054 {
1055 /* Address family check. RIP only supports AF_INET. */
1056 zlog_info ("Unsupported family %d from %s.",
1057 ntohs (rte->family), inet_ntoa (from->sin_addr));
1058 continue;
1059 }
1060
1061 /* - is the destination address valid (e.g., unicast; not net 0
1062 or 127) */
1063 if (! rip_destination_check (rte->prefix))
1064 {
1065 zlog_info ("Network is net 0 or net 127 or it is not unicast network");
1066 rip_peer_bad_route (from);
1067 continue;
1068 }
1069
1070 /* Convert metric value to host byte order. */
1071 rte->metric = ntohl (rte->metric);
1072
1073 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1074 if (! (rte->metric >= 1 && rte->metric <= 16))
1075 {
1076 zlog_info ("Route's metric is not in the 1-16 range.");
1077 rip_peer_bad_route (from);
1078 continue;
1079 }
1080
1081 /* RIPv1 does not have nexthop value. */
1082 if (packet->version == RIPv1 && rte->nexthop.s_addr != 0)
1083 {
1084 zlog_info ("RIPv1 packet with nexthop value %s",
1085 inet_ntoa (rte->nexthop));
1086 rip_peer_bad_route (from);
1087 continue;
1088 }
1089
1090 /* That is, if the provided information is ignored, a possibly
1091 sub-optimal, but absolutely valid, route may be taken. If
1092 the received Next Hop is not directly reachable, it should be
1093 treated as 0.0.0.0. */
1094 if (packet->version == RIPv2 && rte->nexthop.s_addr != 0)
1095 {
1096 u_int32_t addrval;
1097
1098 /* Multicast address check. */
1099 addrval = ntohl (rte->nexthop.s_addr);
1100 if (IN_CLASSD (addrval))
1101 {
1102 zlog_info ("Nexthop %s is multicast address, skip this rte",
1103 inet_ntoa (rte->nexthop));
1104 continue;
1105 }
1106
1107 if (! if_lookup_address (rte->nexthop))
1108 {
1109 struct route_node *rn;
1110 struct rip_info *rinfo;
1111
1112 rn = route_node_match_ipv4 (rip->table, &rte->nexthop);
1113
1114 if (rn)
1115 {
1116 rinfo = rn->info;
1117
1118 if (rinfo->type == ZEBRA_ROUTE_RIP
1119 && rinfo->sub_type == RIP_ROUTE_RTE)
1120 {
1121 if (IS_RIP_DEBUG_EVENT)
1122 zlog_info ("Next hop %s is on RIP network. Set nexthop to the packet's originator", inet_ntoa (rte->nexthop));
1123 rte->nexthop = rinfo->from;
1124 }
1125 else
1126 {
1127 if (IS_RIP_DEBUG_EVENT)
1128 zlog_info ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte->nexthop));
1129 rte->nexthop.s_addr = 0;
1130 }
1131
1132 route_unlock_node (rn);
1133 }
1134 else
1135 {
1136 if (IS_RIP_DEBUG_EVENT)
1137 zlog_info ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte->nexthop));
1138 rte->nexthop.s_addr = 0;
1139 }
1140
1141 }
1142 }
1143
1144 /* For RIPv1, there won't be a valid netmask.
1145
1146 This is a best guess at the masks. If everyone was using old
1147 Ciscos before the 'ip subnet zero' option, it would be almost
1148 right too :-)
1149
1150 Cisco summarize ripv1 advertisments to the classful boundary
1151 (/16 for class B's) except when the RIP packet does to inside
1152 the classful network in question. */
1153
1154 if ((packet->version == RIPv1 && rte->prefix.s_addr != 0)
1155 || (packet->version == RIPv2
1156 && (rte->prefix.s_addr != 0 && rte->mask.s_addr == 0)))
1157 {
1158 u_int32_t destination;
1159
paul727d1042002-12-13 20:50:29 +00001160 if (subnetted == -1)
1161 {
1162 c = connected_lookup_address (ifp, from->sin_addr);
1163 if (c != NULL)
1164 {
1165 memcpy (&ifaddr, c->address, sizeof (struct prefix_ipv4));
1166 memcpy (&ifaddrclass, &ifaddr, sizeof (struct prefix_ipv4));
1167 apply_classful_mask_ipv4 (&ifaddrclass);
1168 subnetted = 0;
1169 if (ifaddr.prefixlen > ifaddrclass.prefixlen)
1170 subnetted = 1;
1171 }
1172 }
1173
paul718e3742002-12-13 20:15:29 +00001174 destination = ntohl (rte->prefix.s_addr);
1175
paul727d1042002-12-13 20:50:29 +00001176 if (IN_CLASSA (destination))
paul718e3742002-12-13 20:15:29 +00001177 masklen2ip (8, &rte->mask);
paul727d1042002-12-13 20:50:29 +00001178 else if (IN_CLASSB (destination))
1179 masklen2ip (16, &rte->mask);
1180 else if (IN_CLASSC (destination))
1181 masklen2ip (24, &rte->mask);
1182
1183 if (subnetted == 1)
1184 masklen2ip (ifaddrclass.prefixlen,
1185 (struct in_addr *) &destination);
1186 if ((subnetted == 1) && ((rte->prefix.s_addr & destination) ==
1187 ifaddrclass.prefix.s_addr))
1188 {
1189 masklen2ip (ifaddr.prefixlen, &rte->mask);
1190 if ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr)
1191 masklen2ip (32, &rte->mask);
1192 if (IS_RIP_DEBUG_EVENT)
1193 zlog_info ("Subnetted route %s", inet_ntoa (rte->prefix));
1194 }
1195 else
1196 {
1197 if ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr)
1198 continue;
1199 }
1200
1201 if (IS_RIP_DEBUG_EVENT)
1202 {
1203 zlog_info ("Resultant route %s", inet_ntoa (rte->prefix));
1204 zlog_info ("Resultant mask %s", inet_ntoa (rte->mask));
paul718e3742002-12-13 20:15:29 +00001205 }
1206 }
1207
1208 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1209 ignore the entry. */
1210 if ((packet->version == RIPv2)
1211 && (rte->mask.s_addr != 0)
1212 && ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr))
1213 {
1214 zlog_warn ("RIPv2 address %s is not mask /%d applied one",
1215 inet_ntoa (rte->prefix), ip_masklen (rte->mask));
1216 rip_peer_bad_route (from);
1217 continue;
1218 }
1219
1220 /* Default route's netmask is ignored. */
1221 if (packet->version == RIPv2
1222 && (rte->prefix.s_addr == 0)
1223 && (rte->mask.s_addr != 0))
1224 {
1225 if (IS_RIP_DEBUG_EVENT)
1226 zlog_info ("Default route with non-zero netmask. Set zero to netmask");
1227 rte->mask.s_addr = 0;
1228 }
1229
1230 /* Routing table updates. */
1231 rip_rte_process (rte, from, ifp);
1232 }
1233}
1234
1235/* RIP packet send to destination address. */
1236int
1237rip_send_packet (caddr_t buf, int size, struct sockaddr_in *to,
1238 struct interface *ifp)
1239{
1240 int ret;
1241 struct sockaddr_in sin;
paul718e3742002-12-13 20:15:29 +00001242
1243 /* Make destination address. */
1244 memset (&sin, 0, sizeof (struct sockaddr_in));
1245 sin.sin_family = AF_INET;
1246#ifdef HAVE_SIN_LEN
1247 sin.sin_len = sizeof (struct sockaddr_in);
1248#endif /* HAVE_SIN_LEN */
1249
1250 /* When destination is specified, use it's port and address. */
1251 if (to)
1252 {
paul718e3742002-12-13 20:15:29 +00001253 sin.sin_port = to->sin_port;
1254 sin.sin_addr = to->sin_addr;
1255 }
1256 else
1257 {
paul718e3742002-12-13 20:15:29 +00001258
1259 sin.sin_port = htons (RIP_PORT_DEFAULT);
1260 sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP);
1261
paulcc1131a2003-10-15 23:20:17 +00001262 /* caller has set multicast interface */
1263
paul718e3742002-12-13 20:15:29 +00001264 }
1265
paulcc1131a2003-10-15 23:20:17 +00001266 ret = sendto (rip->sock, buf, size, 0, (struct sockaddr *)&sin,
paul718e3742002-12-13 20:15:29 +00001267 sizeof (struct sockaddr_in));
1268
1269 if (IS_RIP_DEBUG_EVENT)
paulcc1131a2003-10-15 23:20:17 +00001270 zlog_info ("SEND to %s.%d", inet_ntoa(sin.sin_addr),
1271 ntohs (sin.sin_port));
paul718e3742002-12-13 20:15:29 +00001272
1273 if (ret < 0)
1274 zlog_warn ("can't send packet : %s", strerror (errno));
1275
paul718e3742002-12-13 20:15:29 +00001276 return ret;
1277}
1278
1279/* Add redistributed route to RIP table. */
1280void
1281rip_redistribute_add (int type, int sub_type, struct prefix_ipv4 *p,
1282 unsigned int ifindex, struct in_addr *nexthop)
1283{
1284 int ret;
1285 struct route_node *rp;
1286 struct rip_info *rinfo;
1287
1288 /* Redistribute route */
1289 ret = rip_destination_check (p->prefix);
1290 if (! ret)
1291 return;
1292
1293 rp = route_node_get (rip->table, (struct prefix *) p);
1294
1295 rinfo = rp->info;
1296
1297 if (rinfo)
1298 {
1299 if (rinfo->type == ZEBRA_ROUTE_CONNECT
1300 && rinfo->sub_type == RIP_ROUTE_INTERFACE
1301 && rinfo->metric != RIP_METRIC_INFINITY)
1302 {
1303 route_unlock_node (rp);
1304 return;
1305 }
1306
1307 /* Manually configured RIP route check. */
1308 if (rinfo->type == ZEBRA_ROUTE_RIP
hasso16705132003-05-25 14:49:19 +00001309 && ((rinfo->sub_type == RIP_ROUTE_STATIC) ||
1310 (rinfo->sub_type == RIP_ROUTE_DEFAULT)) )
paul718e3742002-12-13 20:15:29 +00001311 {
hasso16705132003-05-25 14:49:19 +00001312 if (type != ZEBRA_ROUTE_RIP || ((sub_type != RIP_ROUTE_STATIC) &&
1313 (sub_type != RIP_ROUTE_DEFAULT)))
paul718e3742002-12-13 20:15:29 +00001314 {
1315 route_unlock_node (rp);
1316 return;
1317 }
1318 }
1319
1320 RIP_TIMER_OFF (rinfo->t_timeout);
1321 RIP_TIMER_OFF (rinfo->t_garbage_collect);
1322
1323 if (rip_route_rte (rinfo))
1324 rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p, &rinfo->nexthop,
1325 rinfo->metric);
1326 rp->info = NULL;
1327 rip_info_free (rinfo);
1328
1329 route_unlock_node (rp);
1330 }
1331
1332 rinfo = rip_info_new ();
1333
1334 rinfo->type = type;
1335 rinfo->sub_type = sub_type;
1336 rinfo->ifindex = ifindex;
1337 rinfo->metric = 1;
1338 rinfo->rp = rp;
1339
1340 if (nexthop)
1341 rinfo->nexthop = *nexthop;
1342
1343 rinfo->flags |= RIP_RTF_FIB;
1344 rp->info = rinfo;
1345
1346 rinfo->flags |= RIP_RTF_CHANGED;
1347
hasso16705132003-05-25 14:49:19 +00001348 if (IS_RIP_DEBUG_EVENT) {
1349 if (!nexthop)
1350 zlog_info ("Redistribute new prefix %s/%d on the interface %s",
1351 inet_ntoa(p->prefix), p->prefixlen,
1352 ifindex2ifname(ifindex));
1353 else
1354 zlog_info ("Redistribute new prefix %s/%d with nexthop %s on the interface %s",
1355 inet_ntoa(p->prefix), p->prefixlen, inet_ntoa(rinfo->nexthop),
1356 ifindex2ifname(ifindex));
1357 }
1358
1359
paul718e3742002-12-13 20:15:29 +00001360 rip_event (RIP_TRIGGERED_UPDATE, 0);
1361}
1362
1363/* Delete redistributed route from RIP table. */
1364void
1365rip_redistribute_delete (int type, int sub_type, struct prefix_ipv4 *p,
1366 unsigned int ifindex)
1367{
1368 int ret;
1369 struct route_node *rp;
1370 struct rip_info *rinfo;
1371
1372 ret = rip_destination_check (p->prefix);
1373 if (! ret)
1374 return;
1375
1376 rp = route_node_lookup (rip->table, (struct prefix *) p);
1377 if (rp)
1378 {
1379 rinfo = rp->info;
1380
1381 if (rinfo != NULL
1382 && rinfo->type == type
1383 && rinfo->sub_type == sub_type
1384 && rinfo->ifindex == ifindex)
1385 {
1386 /* Perform poisoned reverse. */
1387 rinfo->metric = RIP_METRIC_INFINITY;
1388 RIP_TIMER_ON (rinfo->t_garbage_collect,
1389 rip_garbage_collect, rip->garbage_time);
1390 RIP_TIMER_OFF (rinfo->t_timeout);
1391 rinfo->flags |= RIP_RTF_CHANGED;
1392
hasso16705132003-05-25 14:49:19 +00001393 if (IS_RIP_DEBUG_EVENT)
1394 zlog_info ("Poisone %s/%d on the interface %s with an infinity metric [delete]",
1395 inet_ntoa(p->prefix), p->prefixlen,
1396 ifindex2ifname(ifindex));
1397
paul718e3742002-12-13 20:15:29 +00001398 rip_event (RIP_TRIGGERED_UPDATE, 0);
1399 }
1400 }
1401}
1402
1403/* Response to request called from rip_read ().*/
1404void
1405rip_request_process (struct rip_packet *packet, int size,
1406 struct sockaddr_in *from, struct interface *ifp)
1407{
1408 caddr_t lim;
1409 struct rte *rte;
1410 struct prefix_ipv4 p;
1411 struct route_node *rp;
1412 struct rip_info *rinfo;
1413 struct rip_interface *ri;
1414
hasso16705132003-05-25 14:49:19 +00001415 /* Does not reponse to the requests on the loopback interfaces */
1416 if (if_is_loopback (ifp))
1417 return;
1418
1419 /* Check RIPng process is enabled on this interface. */
paul718e3742002-12-13 20:15:29 +00001420 ri = ifp->info;
hasso16705132003-05-25 14:49:19 +00001421 if (! ri->running)
1422 return;
paul718e3742002-12-13 20:15:29 +00001423
1424 /* When passive interface is specified, suppress responses */
1425 if (ri->passive)
1426 return;
1427
1428 /* RIP peer update. */
1429 rip_peer_update (from, packet->version);
1430
1431 lim = ((caddr_t) packet) + size;
1432 rte = packet->rte;
1433
1434 /* The Request is processed entry by entry. If there are no
1435 entries, no response is given. */
1436 if (lim == (caddr_t) rte)
1437 return;
1438
1439 /* There is one special case. If there is exactly one entry in the
1440 request, and it has an address family identifier of zero and a
1441 metric of infinity (i.e., 16), then this is a request to send the
1442 entire routing table. */
1443 if (lim == ((caddr_t) (rte + 1)) &&
1444 ntohs (rte->family) == 0 &&
1445 ntohl (rte->metric) == RIP_METRIC_INFINITY)
1446 {
paulcc1131a2003-10-15 23:20:17 +00001447 struct prefix_ipv4 saddr;
1448
1449 /* saddr will be used for determining which routes to split-horizon.
1450 Since the source address we'll pick will be on the same subnet as the
1451 destination, for the purpose of split-horizoning, we'll
1452 pretend that "from" is our source address. */
1453 saddr.family = AF_INET;
1454 saddr.prefixlen = IPV4_MAX_BITLEN;
1455 saddr.prefix = from->sin_addr;
1456
paul718e3742002-12-13 20:15:29 +00001457 /* All route with split horizon */
paulcc1131a2003-10-15 23:20:17 +00001458 rip_output_process (ifp, NULL, from, rip_all_route, packet->version,
1459 &saddr);
paul718e3742002-12-13 20:15:29 +00001460 }
1461 else
1462 {
1463 /* Examine the list of RTEs in the Request one by one. For each
1464 entry, look up the destination in the router's routing
1465 database and, if there is a route, put that route's metric in
1466 the metric field of the RTE. If there is no explicit route
1467 to the specified destination, put infinity in the metric
1468 field. Once all the entries have been filled in, change the
1469 command from Request to Response and send the datagram back
1470 to the requestor. */
1471 p.family = AF_INET;
1472
1473 for (; ((caddr_t) rte) < lim; rte++)
1474 {
1475 p.prefix = rte->prefix;
1476 p.prefixlen = ip_masklen (rte->mask);
1477 apply_mask_ipv4 (&p);
1478
1479 rp = route_node_lookup (rip->table, (struct prefix *) &p);
1480 if (rp)
1481 {
1482 rinfo = rp->info;
1483 rte->metric = htonl (rinfo->metric);
1484 route_unlock_node (rp);
1485 }
1486 else
1487 rte->metric = htonl (RIP_METRIC_INFINITY);
1488 }
1489 packet->command = RIP_RESPONSE;
1490
1491 rip_send_packet ((caddr_t) packet, size, from, ifp);
1492 }
1493 rip_global_queries++;
1494}
1495
1496#if RIP_RECVMSG
1497/* Set IPv6 packet info to the socket. */
1498static int
1499setsockopt_pktinfo (int sock)
1500{
1501 int ret;
1502 int val = 1;
1503
1504 ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val));
1505 if (ret < 0)
1506 zlog_warn ("Can't setsockopt IP_PKTINFO : %s", strerror (errno));
1507 return ret;
1508}
1509
1510/* Read RIP packet by recvmsg function. */
1511int
1512rip_recvmsg (int sock, u_char *buf, int size, struct sockaddr_in *from,
1513 int *ifindex)
1514{
1515 int ret;
1516 struct msghdr msg;
1517 struct iovec iov;
1518 struct cmsghdr *ptr;
1519 char adata[1024];
1520
1521 msg.msg_name = (void *) from;
1522 msg.msg_namelen = sizeof (struct sockaddr_in);
1523 msg.msg_iov = &iov;
1524 msg.msg_iovlen = 1;
1525 msg.msg_control = (void *) adata;
1526 msg.msg_controllen = sizeof adata;
1527 iov.iov_base = buf;
1528 iov.iov_len = size;
1529
1530 ret = recvmsg (sock, &msg, 0);
1531 if (ret < 0)
1532 return ret;
1533
1534 for (ptr = CMSG_FIRSTHDR(&msg); ptr != NULL; ptr = CMSG_NXTHDR(&msg, ptr))
1535 if (ptr->cmsg_level == IPPROTO_IP && ptr->cmsg_type == IP_PKTINFO)
1536 {
1537 struct in_pktinfo *pktinfo;
1538 int i;
1539
1540 pktinfo = (struct in_pktinfo *) CMSG_DATA (ptr);
1541 i = pktinfo->ipi_ifindex;
1542 }
1543 return ret;
1544}
1545
1546/* RIP packet read function. */
1547int
1548rip_read_new (struct thread *t)
1549{
1550 int ret;
1551 int sock;
1552 char buf[RIP_PACKET_MAXSIZ];
1553 struct sockaddr_in from;
1554 unsigned int ifindex;
1555
1556 /* Fetch socket then register myself. */
1557 sock = THREAD_FD (t);
1558 rip_event (RIP_READ, sock);
1559
1560 /* Read RIP packet. */
1561 ret = rip_recvmsg (sock, buf, RIP_PACKET_MAXSIZ, &from, (int *)&ifindex);
1562 if (ret < 0)
1563 {
1564 zlog_warn ("Can't read RIP packet: %s", strerror (errno));
1565 return ret;
1566 }
1567
1568 return ret;
1569}
1570#endif /* RIP_RECVMSG */
1571
1572/* First entry point of RIP packet. */
1573int
1574rip_read (struct thread *t)
1575{
1576 int sock;
1577 int ret;
1578 int rtenum;
1579 union rip_buf rip_buf;
1580 struct rip_packet *packet;
1581 struct sockaddr_in from;
1582 int fromlen, len;
1583 struct interface *ifp;
1584 struct rip_interface *ri;
1585
1586 /* Fetch socket then register myself. */
1587 sock = THREAD_FD (t);
1588 rip->t_read = NULL;
1589
1590 /* Add myself to tne next event */
1591 rip_event (RIP_READ, sock);
1592
1593 /* RIPd manages only IPv4. */
1594 memset (&from, 0, sizeof (struct sockaddr_in));
1595 fromlen = sizeof (struct sockaddr_in);
1596
1597 len = recvfrom (sock, (char *)&rip_buf.buf, sizeof (rip_buf.buf), 0,
1598 (struct sockaddr *) &from, &fromlen);
1599 if (len < 0)
1600 {
1601 zlog_info ("recvfrom failed: %s", strerror (errno));
1602 return len;
1603 }
1604
1605 /* Check is this packet comming from myself? */
paul31a476c2003-09-29 19:54:53 +00001606 if (if_check_address (from.sin_addr))
paul718e3742002-12-13 20:15:29 +00001607 {
1608 if (IS_RIP_DEBUG_PACKET)
1609 zlog_warn ("ignore packet comes from myself");
1610 return -1;
1611 }
1612
1613 /* Which interface is this packet comes from. */
1614 ifp = if_lookup_address (from.sin_addr);
1615
1616 /* RIP packet received */
1617 if (IS_RIP_DEBUG_EVENT)
1618 zlog_info ("RECV packet from %s port %d on %s",
1619 inet_ntoa (from.sin_addr), ntohs (from.sin_port),
1620 ifp ? ifp->name : "unknown");
1621
1622 /* If this packet come from unknown interface, ignore it. */
1623 if (ifp == NULL)
1624 {
1625 zlog_info ("packet comes from unknown interface");
1626 return -1;
1627 }
1628
1629 /* Packet length check. */
1630 if (len < RIP_PACKET_MINSIZ)
1631 {
1632 zlog_warn ("packet size %d is smaller than minimum size %d",
1633 len, RIP_PACKET_MINSIZ);
1634 rip_peer_bad_packet (&from);
1635 return len;
1636 }
1637 if (len > RIP_PACKET_MAXSIZ)
1638 {
1639 zlog_warn ("packet size %d is larger than max size %d",
1640 len, RIP_PACKET_MAXSIZ);
1641 rip_peer_bad_packet (&from);
1642 return len;
1643 }
1644
1645 /* Packet alignment check. */
1646 if ((len - RIP_PACKET_MINSIZ) % 20)
1647 {
1648 zlog_warn ("packet size %d is wrong for RIP packet alignment", len);
1649 rip_peer_bad_packet (&from);
1650 return len;
1651 }
1652
1653 /* Set RTE number. */
1654 rtenum = ((len - RIP_PACKET_MINSIZ) / 20);
1655
1656 /* For easy to handle. */
1657 packet = &rip_buf.rip_packet;
1658
1659 /* RIP version check. */
1660 if (packet->version == 0)
1661 {
1662 zlog_info ("version 0 with command %d received.", packet->command);
1663 rip_peer_bad_packet (&from);
1664 return -1;
1665 }
1666
1667 /* Dump RIP packet. */
1668 if (IS_RIP_DEBUG_RECV)
1669 rip_packet_dump (packet, len, "RECV");
1670
1671 /* RIP version adjust. This code should rethink now. RFC1058 says
1672 that "Version 1 implementations are to ignore this extra data and
1673 process only the fields specified in this document.". So RIPv3
1674 packet should be treated as RIPv1 ignoring must be zero field. */
1675 if (packet->version > RIPv2)
1676 packet->version = RIPv2;
1677
1678 /* Is RIP running or is this RIP neighbor ?*/
1679 ri = ifp->info;
1680 if (! ri->running && ! rip_neighbor_lookup (&from))
1681 {
1682 if (IS_RIP_DEBUG_EVENT)
1683 zlog_info ("RIP is not enabled on interface %s.", ifp->name);
1684 rip_peer_bad_packet (&from);
1685 return -1;
1686 }
1687
1688 /* RIP Version check. */
1689 if (packet->command == RIP_RESPONSE)
1690 {
paulf38a4712003-06-07 01:10:00 +00001691 int vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ?
1692 rip->version_recv : ri->ri_receive);
paul718e3742002-12-13 20:15:29 +00001693 if (packet->version == RIPv1)
paulf38a4712003-06-07 01:10:00 +00001694 if (! (vrecv & RIPv1))
paul718e3742002-12-13 20:15:29 +00001695 {
1696 if (IS_RIP_DEBUG_PACKET)
1697 zlog_warn (" packet's v%d doesn't fit to if version spec",
1698 packet->version);
1699 rip_peer_bad_packet (&from);
1700 return -1;
1701 }
1702 if (packet->version == RIPv2)
paulf38a4712003-06-07 01:10:00 +00001703 if (! (vrecv & RIPv2))
paul718e3742002-12-13 20:15:29 +00001704 {
1705 if (IS_RIP_DEBUG_PACKET)
1706 zlog_warn (" packet's v%d doesn't fit to if version spec",
1707 packet->version);
1708 rip_peer_bad_packet (&from);
1709 return -1;
1710 }
paul718e3742002-12-13 20:15:29 +00001711 }
1712
1713 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1714 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1715 accepted; authenticated RIP-2 messages shall be discarded. */
1716
1717 if ((ri->auth_type == RIP_NO_AUTH)
1718 && rtenum
1719 && (packet->version == RIPv2) && (packet->rte->family == 0xffff))
1720 {
1721 if (IS_RIP_DEBUG_EVENT)
1722 zlog_warn ("packet RIPv%d is dropped because authentication disabled",
1723 packet->version);
1724 rip_peer_bad_packet (&from);
1725 return -1;
1726 }
1727
1728 /* If the router is configured to authenticate RIP-2 messages, then
1729 RIP-1 messages and RIP-2 messages which pass authentication
1730 testing shall be accepted; unauthenticated and failed
1731 authentication RIP-2 messages shall be discarded. For maximum
1732 security, RIP-1 messages should be ignored when authentication is
1733 in use (see section 4.1); otherwise, the routing information from
1734 authenticated messages will be propagated by RIP-1 routers in an
1735 unauthenticated manner. */
1736
1737 if ((ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD
1738 || ri->auth_type == RIP_AUTH_MD5)
1739 && rtenum)
1740 {
1741 /* We follow maximum security. */
1742 if (packet->version == RIPv1 && packet->rte->family == 0xffff)
1743 {
1744 if (IS_RIP_DEBUG_PACKET)
1745 zlog_warn ("packet RIPv%d is dropped because authentication enabled", packet->version);
1746 rip_peer_bad_packet (&from);
1747 return -1;
1748 }
1749
1750 /* Check RIPv2 authentication. */
1751 if (packet->version == RIPv2)
1752 {
1753 if (packet->rte->family == 0xffff)
1754 {
1755 if (ntohs (packet->rte->tag) == RIP_AUTH_SIMPLE_PASSWORD)
1756 {
1757 ret = rip_auth_simple_password (packet->rte, &from, ifp);
1758 if (! ret)
1759 {
1760 if (IS_RIP_DEBUG_EVENT)
1761 zlog_warn ("RIPv2 simple password authentication failed");
1762 rip_peer_bad_packet (&from);
1763 return -1;
1764 }
1765 else
1766 {
1767 if (IS_RIP_DEBUG_EVENT)
1768 zlog_info ("RIPv2 simple password authentication success");
1769 }
1770 }
1771 else if (ntohs (packet->rte->tag) == RIP_AUTH_MD5)
1772 {
1773 ret = rip_auth_md5 (packet, &from, ifp);
1774 if (! ret)
1775 {
1776 if (IS_RIP_DEBUG_EVENT)
1777 zlog_warn ("RIPv2 MD5 authentication failed");
1778 rip_peer_bad_packet (&from);
1779 return -1;
1780 }
1781 else
1782 {
1783 if (IS_RIP_DEBUG_EVENT)
1784 zlog_info ("RIPv2 MD5 authentication success");
1785 }
1786 /* Reset RIP packet length to trim MD5 data. */
1787 len = ret;
1788 }
1789 else
1790 {
1791 if (IS_RIP_DEBUG_EVENT)
1792 zlog_warn ("Unknown authentication type %d",
1793 ntohs (packet->rte->tag));
1794 rip_peer_bad_packet (&from);
1795 return -1;
1796 }
1797 }
1798 else
1799 {
1800 /* There is no authentication in the packet. */
1801 if (ri->auth_str || ri->key_chain)
1802 {
1803 if (IS_RIP_DEBUG_EVENT)
1804 zlog_warn ("RIPv2 authentication failed: no authentication in packet");
1805 rip_peer_bad_packet (&from);
1806 return -1;
1807 }
1808 }
1809 }
1810 }
1811
1812 /* Process each command. */
1813 switch (packet->command)
1814 {
1815 case RIP_RESPONSE:
1816 rip_response_process (packet, len, &from, ifp);
1817 break;
1818 case RIP_REQUEST:
1819 case RIP_POLL:
1820 rip_request_process (packet, len, &from, ifp);
1821 break;
1822 case RIP_TRACEON:
1823 case RIP_TRACEOFF:
1824 zlog_info ("Obsolete command %s received, please sent it to routed",
1825 lookup (rip_msg, packet->command));
1826 rip_peer_bad_packet (&from);
1827 break;
1828 case RIP_POLL_ENTRY:
1829 zlog_info ("Obsolete command %s received",
1830 lookup (rip_msg, packet->command));
1831 rip_peer_bad_packet (&from);
1832 break;
1833 default:
1834 zlog_info ("Unknown RIP command %d received", packet->command);
1835 rip_peer_bad_packet (&from);
1836 break;
1837 }
1838
1839 return len;
1840}
1841
1842/* Make socket for RIP protocol. */
1843int
1844rip_create_socket ()
1845{
1846 int ret;
1847 int sock;
1848 struct sockaddr_in addr;
1849 struct servent *sp;
1850
1851 memset (&addr, 0, sizeof (struct sockaddr_in));
1852
1853 /* Set RIP port. */
1854 sp = getservbyname ("router", "udp");
1855 if (sp)
1856 addr.sin_port = sp->s_port;
1857 else
1858 addr.sin_port = htons (RIP_PORT_DEFAULT);
1859
1860 /* Address shoud be any address. */
1861 addr.sin_family = AF_INET;
1862 addr.sin_addr.s_addr = INADDR_ANY;
1863
1864 /* Make datagram socket. */
1865 sock = socket (AF_INET, SOCK_DGRAM, 0);
1866 if (sock < 0)
1867 {
1868 perror ("socket");
1869 exit (1);
1870 }
1871
1872 sockopt_broadcast (sock);
1873 sockopt_reuseaddr (sock);
1874 sockopt_reuseport (sock);
1875#ifdef RIP_RECVMSG
1876 setsockopt_pktinfo (sock);
1877#endif /* RIP_RECVMSG */
1878
pauledd7c242003-06-04 13:59:38 +00001879 if (ripd_privs.change (ZPRIVS_RAISE))
1880 zlog_err ("rip_create_socket: could not raise privs");
paul718e3742002-12-13 20:15:29 +00001881 ret = bind (sock, (struct sockaddr *) & addr, sizeof (addr));
1882 if (ret < 0)
1883 {
1884 perror ("bind");
1885 return ret;
1886 }
pauledd7c242003-06-04 13:59:38 +00001887 if (ripd_privs.change (ZPRIVS_LOWER))
1888 zlog_err ("rip_create_socket: could not lower privs");
1889
paul718e3742002-12-13 20:15:29 +00001890 return sock;
1891}
1892
1893/* Write routing table entry to the stream and return next index of
1894 the routing table entry in the stream. */
1895int
1896rip_write_rte (int num, struct stream *s, struct prefix_ipv4 *p,
1897 u_char version, struct rip_info *rinfo, struct interface *ifp)
1898{
1899 struct in_addr mask;
1900 struct rip_interface *ri;
1901
1902 /* RIP packet header. */
1903 if (num == 0)
1904 {
1905 stream_putc (s, RIP_RESPONSE);
1906 stream_putc (s, version);
1907 stream_putw (s, 0);
1908
1909 /* In case of we need RIPv2 authentication. */
1910 if (version == RIPv2 && ifp)
1911 {
1912 ri = ifp->info;
1913
1914 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1915 {
1916 if (ri->auth_str)
1917 {
1918 stream_putw (s, 0xffff);
1919 stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD);
1920
1921 memset ((s->data + s->putp), 0, 16);
1922 strncpy ((s->data + s->putp), ri->auth_str, 16);
1923 stream_set_putp (s, s->putp + 16);
1924
1925 num++;
1926 }
1927 if (ri->key_chain)
1928 {
1929 struct keychain *keychain;
1930 struct key *key;
1931
1932 keychain = keychain_lookup (ri->key_chain);
1933
1934 if (keychain)
1935 {
1936 key = key_lookup_for_send (keychain);
1937
1938 if (key)
1939 {
1940 stream_putw (s, 0xffff);
1941 stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD);
1942
1943 memset ((s->data + s->putp), 0, 16);
1944 strncpy ((s->data + s->putp), key->string, 16);
1945 stream_set_putp (s, s->putp + 16);
1946
1947 num++;
1948 }
1949 }
1950 }
1951 }
1952 }
1953 }
1954
1955 /* Write routing table entry. */
1956 if (version == RIPv1)
1957 {
1958 stream_putw (s, AF_INET);
1959 stream_putw (s, 0);
1960 stream_put_ipv4 (s, p->prefix.s_addr);
1961 stream_put_ipv4 (s, 0);
1962 stream_put_ipv4 (s, 0);
1963 stream_putl (s, rinfo->metric_out);
1964 }
1965 else
1966 {
1967 masklen2ip (p->prefixlen, &mask);
1968
1969 stream_putw (s, AF_INET);
hasso16705132003-05-25 14:49:19 +00001970 stream_putw (s, rinfo->tag_out);
paul718e3742002-12-13 20:15:29 +00001971 stream_put_ipv4 (s, p->prefix.s_addr);
1972 stream_put_ipv4 (s, mask.s_addr);
1973 stream_put_ipv4 (s, rinfo->nexthop_out.s_addr);
1974 stream_putl (s, rinfo->metric_out);
1975 }
1976
1977 return ++num;
1978}
1979
1980/* Send update to the ifp or spcified neighbor. */
1981void
paul727d1042002-12-13 20:50:29 +00001982rip_output_process (struct interface *ifp, struct prefix *ifaddr,
paulcc1131a2003-10-15 23:20:17 +00001983 struct sockaddr_in *to, int route_type, u_char version,
1984 struct prefix_ipv4 *saddr)
paul718e3742002-12-13 20:15:29 +00001985{
1986 int ret;
1987 struct stream *s;
1988 struct route_node *rp;
1989 struct rip_info *rinfo;
1990 struct rip_interface *ri;
1991 struct prefix_ipv4 *p;
1992 struct prefix_ipv4 classfull;
paul727d1042002-12-13 20:50:29 +00001993 struct prefix_ipv4 ifaddrclass;
1994 struct connected *c;
paul718e3742002-12-13 20:15:29 +00001995 int num;
1996 int rtemax;
paul01d09082003-06-08 21:22:18 +00001997 int subnetted = 0;
paul718e3742002-12-13 20:15:29 +00001998
1999 /* Logging output event. */
2000 if (IS_RIP_DEBUG_EVENT)
2001 {
2002 if (to)
2003 zlog_info ("update routes to neighbor %s", inet_ntoa (to->sin_addr));
2004 else
2005 zlog_info ("update routes on interface %s ifindex %d",
2006 ifp->name, ifp->ifindex);
2007 }
2008
2009 /* Set output stream. */
2010 s = rip->obuf;
2011
2012 /* Reset stream and RTE counter. */
2013 stream_reset (s);
2014 num = 0;
2015 rtemax = (RIP_PACKET_MAXSIZ - 4) / 20;
2016
2017 /* Get RIP interface. */
2018 ri = ifp->info;
2019
2020 /* If output interface is in simple password authentication mode, we
2021 need space for authentication data. */
2022 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2023 rtemax -= 1;
2024
2025 /* If output interface is in MD5 authentication mode, we need space
2026 for authentication header and data. */
2027 if (ri->auth_type == RIP_AUTH_MD5)
2028 rtemax -= 2;
2029
2030 /* If output interface is in simple password authentication mode
2031 and string or keychain is specified we need space for auth. data */
2032 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2033 {
2034 if (ri->key_chain)
2035 {
2036 struct keychain *keychain;
2037
2038 keychain = keychain_lookup (ri->key_chain);
2039 if (keychain)
2040 if (key_lookup_for_send (keychain))
2041 rtemax -=1;
2042 }
2043 else
2044 if (ri->auth_str)
2045 rtemax -=1;
2046 }
2047
paul727d1042002-12-13 20:50:29 +00002048 if (version == RIPv1)
2049 {
2050 if (ifaddr == NULL)
2051 {
2052 c = connected_lookup_address (ifp, to->sin_addr);
2053 if (c != NULL)
2054 ifaddr = c->address;
2055 }
2056 if (ifaddr == NULL)
2057 {
2058 zlog_warn ("cannot find source address for packets to neighbor %s",
2059 inet_ntoa (to->sin_addr));
2060 return;
2061 }
2062 memcpy (&ifaddrclass, ifaddr, sizeof (struct prefix_ipv4));
2063 apply_classful_mask_ipv4 (&ifaddrclass);
2064 subnetted = 0;
2065 if (ifaddr->prefixlen > ifaddrclass.prefixlen)
paul01d09082003-06-08 21:22:18 +00002066 subnetted = 1;
paul727d1042002-12-13 20:50:29 +00002067 }
2068
paul718e3742002-12-13 20:15:29 +00002069 for (rp = route_top (rip->table); rp; rp = route_next (rp))
2070 if ((rinfo = rp->info) != NULL)
2071 {
paul727d1042002-12-13 20:50:29 +00002072 /* For RIPv1, if we are subnetted, output subnets in our network */
2073 /* that have the same mask as the output "interface". For other */
2074 /* networks, only the classfull version is output. */
paul718e3742002-12-13 20:15:29 +00002075
2076 if (version == RIPv1)
2077 {
paul727d1042002-12-13 20:50:29 +00002078 p = (struct prefix_ipv4 *) &rp->p;
paul718e3742002-12-13 20:15:29 +00002079
2080 if (IS_RIP_DEBUG_PACKET)
paul727d1042002-12-13 20:50:29 +00002081 zlog_info("RIPv1 mask check, %s/%d considered for output",
2082 inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen);
paul718e3742002-12-13 20:15:29 +00002083
paul727d1042002-12-13 20:50:29 +00002084 if (subnetted &&
2085 prefix_match ((struct prefix *) &ifaddrclass, &rp->p))
2086 {
2087 if ((ifaddr->prefixlen != rp->p.prefixlen) &&
2088 (rp->p.prefixlen != 32))
2089 continue;
2090 }
2091 else
2092 {
2093 memcpy (&classfull, &rp->p, sizeof(struct prefix_ipv4));
2094 apply_classful_mask_ipv4(&classfull);
2095 if (rp->p.u.prefix4.s_addr != 0 &&
2096 classfull.prefixlen != rp->p.prefixlen)
2097 continue;
2098 }
paul718e3742002-12-13 20:15:29 +00002099 if (IS_RIP_DEBUG_PACKET)
paul727d1042002-12-13 20:50:29 +00002100 zlog_info("RIPv1 mask check, %s/%d made it through",
2101 inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen);
paul718e3742002-12-13 20:15:29 +00002102 }
2103 else
2104 p = (struct prefix_ipv4 *) &rp->p;
2105
2106 /* Apply output filters. */
2107 ret = rip_outgoing_filter (p, ri);
2108 if (ret < 0)
2109 continue;
2110
2111 /* Changed route only output. */
2112 if (route_type == rip_changed_route &&
2113 (! (rinfo->flags & RIP_RTF_CHANGED)))
2114 continue;
2115
2116 /* Split horizon. */
2117 /* if (split_horizon == rip_split_horizon) */
hasso16705132003-05-25 14:49:19 +00002118 if (ri->split_horizon == RIP_SPLIT_HORIZON)
paul718e3742002-12-13 20:15:29 +00002119 {
2120 /* We perform split horizon for RIP and connected route. */
2121 if ((rinfo->type == ZEBRA_ROUTE_RIP ||
2122 rinfo->type == ZEBRA_ROUTE_CONNECT) &&
paulcc1131a2003-10-15 23:20:17 +00002123 prefix_match((struct prefix *)p, (struct prefix *)saddr))
paul718e3742002-12-13 20:15:29 +00002124 continue;
2125 }
2126
2127 /* Preparation for route-map. */
2128 rinfo->metric_set = 0;
2129 rinfo->nexthop_out.s_addr = 0;
2130 rinfo->metric_out = rinfo->metric;
hasso16705132003-05-25 14:49:19 +00002131 rinfo->tag_out = rinfo->tag;
paul718e3742002-12-13 20:15:29 +00002132 rinfo->ifindex_out = ifp->ifindex;
2133
hasso16705132003-05-25 14:49:19 +00002134 /* In order to avoid some local loops,
2135 * if the RIP route has a nexthop via this interface, keep the nexthop,
2136 * otherwise set it to 0. The nexthop should not be propagated
2137 * beyond the local broadcast/multicast area in order
2138 * to avoid an IGP multi-level recursive look-up.
2139 * see (4.4)
2140 */
2141 if (rinfo->ifindex == ifp->ifindex)
paul718e3742002-12-13 20:15:29 +00002142 rinfo->nexthop_out = rinfo->nexthop;
hasso16705132003-05-25 14:49:19 +00002143
2144 /* Interface route-map */
2145 if (ri->routemap[RIP_FILTER_OUT])
2146 {
2147 ret = route_map_apply (ri->routemap[RIP_FILTER_OUT],
2148 (struct prefix *) p, RMAP_RIP,
2149 rinfo);
2150
2151 if (ret == RMAP_DENYMATCH)
2152 {
2153 if (IS_RIP_DEBUG_PACKET)
2154 zlog_info ("RIP %s/%d is filtered by route-map out",
2155 inet_ntoa (p->prefix), p->prefixlen);
2156 continue;
2157 }
2158 }
paul718e3742002-12-13 20:15:29 +00002159
hasso16705132003-05-25 14:49:19 +00002160 /* Apply redistribute route map - continue, if deny */
paul718e3742002-12-13 20:15:29 +00002161 if (rip->route_map[rinfo->type].name
2162 && rinfo->sub_type != RIP_ROUTE_INTERFACE)
2163 {
2164 ret = route_map_apply (rip->route_map[rinfo->type].map,
2165 (struct prefix *)p, RMAP_RIP, rinfo);
2166
2167 if (ret == RMAP_DENYMATCH)
2168 {
2169 if (IS_RIP_DEBUG_PACKET)
2170 zlog_info ("%s/%d is filtered by route-map",
2171 inet_ntoa (p->prefix), p->prefixlen);
2172 continue;
2173 }
2174 }
2175
2176 /* When route-map does not set metric. */
2177 if (! rinfo->metric_set)
2178 {
2179 /* If redistribute metric is set. */
2180 if (rip->route_map[rinfo->type].metric_config
2181 && rinfo->metric != RIP_METRIC_INFINITY)
2182 {
2183 rinfo->metric_out = rip->route_map[rinfo->type].metric;
2184 }
2185 else
2186 {
2187 /* If the route is not connected or localy generated
2188 one, use default-metric value*/
2189 if (rinfo->type != ZEBRA_ROUTE_RIP
2190 && rinfo->type != ZEBRA_ROUTE_CONNECT
2191 && rinfo->metric != RIP_METRIC_INFINITY)
2192 rinfo->metric_out = rip->default_metric;
2193 }
2194 }
2195
2196 /* Apply offset-list */
2197 if (rinfo->metric != RIP_METRIC_INFINITY)
2198 rip_offset_list_apply_out (p, ifp, &rinfo->metric_out);
2199
2200 if (rinfo->metric_out > RIP_METRIC_INFINITY)
2201 rinfo->metric_out = RIP_METRIC_INFINITY;
hasso16705132003-05-25 14:49:19 +00002202
2203 /* Perform split-horizon with poisoned reverse
2204 * for RIP and connected routes.
2205 **/
2206 if (ri->split_horizon == RIP_SPLIT_HORIZON_POISONED_REVERSE) {
2207 if ((rinfo->type == ZEBRA_ROUTE_RIP ||
2208 rinfo->type == ZEBRA_ROUTE_CONNECT) &&
2209 rinfo->ifindex == ifp->ifindex)
2210 rinfo->metric_out = RIP_METRIC_INFINITY;
2211 }
2212
paul718e3742002-12-13 20:15:29 +00002213 /* Write RTE to the stream. */
2214 num = rip_write_rte (num, s, p, version, rinfo, to ? NULL : ifp);
2215 if (num == rtemax)
2216 {
2217 if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
2218 rip_auth_md5_set (s, ifp);
2219
2220 ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s),
2221 to, ifp);
2222
2223 if (ret >= 0 && IS_RIP_DEBUG_SEND)
2224 rip_packet_dump ((struct rip_packet *)STREAM_DATA (s),
2225 stream_get_endp(s), "SEND");
2226 num = 0;
2227 stream_reset (s);
2228 }
2229 }
2230
2231 /* Flush unwritten RTE. */
2232 if (num != 0)
2233 {
2234 if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
2235 rip_auth_md5_set (s, ifp);
2236
2237 ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s), to, ifp);
2238
2239 if (ret >= 0 && IS_RIP_DEBUG_SEND)
2240 rip_packet_dump ((struct rip_packet *)STREAM_DATA (s),
2241 stream_get_endp (s), "SEND");
2242 num = 0;
2243 stream_reset (s);
2244 }
2245
2246 /* Statistics updates. */
2247 ri->sent_updates++;
2248}
2249
2250/* Send RIP packet to the interface. */
2251void
paulcc1131a2003-10-15 23:20:17 +00002252rip_update_interface (struct interface *ifp, u_char version, int route_type,
2253 struct prefix_ipv4 *saddr)
paul718e3742002-12-13 20:15:29 +00002254{
2255 struct prefix_ipv4 *p;
2256 struct connected *connected;
2257 listnode node;
2258 struct sockaddr_in to;
2259
2260 /* When RIP version is 2 and multicast enable interface. */
2261 if (version == RIPv2 && if_is_multicast (ifp))
2262 {
2263 if (IS_RIP_DEBUG_EVENT)
2264 zlog_info ("multicast announce on %s ", ifp->name);
2265
paulcc1131a2003-10-15 23:20:17 +00002266 rip_output_process (ifp, NULL, NULL, route_type, rip->version_send,
2267 saddr);
paul718e3742002-12-13 20:15:29 +00002268 return;
2269 }
2270
2271 /* If we can't send multicast packet, send it with unicast. */
2272 if (if_is_broadcast (ifp) || if_is_pointopoint (ifp))
2273 {
2274 for (node = listhead (ifp->connected); node; nextnode (node))
2275 {
2276 connected = getdata (node);
2277
2278 /* Fetch broadcast address or poin-to-point destination
2279 address . */
2280 p = (struct prefix_ipv4 *) connected->destination;
2281
2282 if (p->family == AF_INET)
2283 {
2284 /* Destination address and port setting. */
2285 memset (&to, 0, sizeof (struct sockaddr_in));
2286 to.sin_addr = p->prefix;
2287 to.sin_port = htons (RIP_PORT_DEFAULT);
2288
2289 if (IS_RIP_DEBUG_EVENT)
2290 zlog_info ("%s announce to %s on %s",
2291 if_is_pointopoint (ifp) ? "unicast" : "broadcast",
2292 inet_ntoa (to.sin_addr), ifp->name);
2293
paul727d1042002-12-13 20:50:29 +00002294 rip_output_process (ifp, connected->address, &to, route_type,
paulcc1131a2003-10-15 23:20:17 +00002295 rip->version_send, saddr);
paul718e3742002-12-13 20:15:29 +00002296 }
2297 }
2298 }
2299}
2300
2301/* Update send to all interface and neighbor. */
2302void
2303rip_update_process (int route_type)
2304{
paulcc1131a2003-10-15 23:20:17 +00002305 listnode node, ifnode;
2306 struct connected *connected;
paul718e3742002-12-13 20:15:29 +00002307 struct interface *ifp;
2308 struct rip_interface *ri;
2309 struct route_node *rp;
2310 struct sockaddr_in to;
2311 struct prefix_ipv4 *p;
2312
2313 /* Send RIP update to each interface. */
2314 for (node = listhead (iflist); node; nextnode (node))
2315 {
2316 ifp = getdata (node);
2317
2318 if (if_is_loopback (ifp))
2319 continue;
2320
paul2e3b2e42002-12-13 21:03:13 +00002321 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00002322 continue;
2323
2324 /* Fetch RIP interface information. */
2325 ri = ifp->info;
2326
2327 /* When passive interface is specified, suppress announce to the
2328 interface. */
2329 if (ri->passive)
2330 continue;
2331
2332 if (ri->running)
2333 {
2334 if (IS_RIP_DEBUG_EVENT)
2335 {
2336 if (ifp->name)
2337 zlog_info ("SEND UPDATE to %s ifindex %d",
2338 ifp->name, ifp->ifindex);
2339 else
2340 zlog_info ("SEND UPDATE to _unknown_ ifindex %d",
2341 ifp->ifindex);
2342 }
2343
paulcc1131a2003-10-15 23:20:17 +00002344 /* send update on each connected network */
2345
2346 LIST_LOOP(ifp->connected, connected, ifnode)
2347 {
2348 struct prefix_ipv4 *ifaddr;
2349
2350
paul718e3742002-12-13 20:15:29 +00002351 /* If there is no version configuration in the interface,
2352 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +00002353 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
2354 rip->version_send : ri->ri_send);
paulcc1131a2003-10-15 23:20:17 +00002355
2356 ifaddr = (struct prefix_ipv4 *) connected->address;
2357
2358 if (ifaddr->family != AF_INET)
2359 continue;
2360
2361 rip_interface_multicast_set(rip->sock, connected,
2362 if_is_pointopoint(ifp));
paulf38a4712003-06-07 01:10:00 +00002363 if (vsend & RIPv1)
paulcc1131a2003-10-15 23:20:17 +00002364 rip_update_interface (ifp, RIPv1, route_type, ifaddr);
paulf38a4712003-06-07 01:10:00 +00002365 if (vsend & RIPv2)
paulcc1131a2003-10-15 23:20:17 +00002366 rip_update_interface (ifp, RIPv2, route_type, ifaddr);
paulf38a4712003-06-07 01:10:00 +00002367 }
paul718e3742002-12-13 20:15:29 +00002368 }
2369 }
2370
2371 /* RIP send updates to each neighbor. */
2372 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
2373 if (rp->info != NULL)
2374 {
2375 p = (struct prefix_ipv4 *) &rp->p;
2376
2377 ifp = if_lookup_address (p->prefix);
2378 if (! ifp)
2379 {
2380 zlog_warn ("Neighbor %s doesn't exist direct connected network",
2381 inet_ntoa (p->prefix));
2382 continue;
2383 }
2384
2385 /* Set destination address and port */
2386 memset (&to, 0, sizeof (struct sockaddr_in));
2387 to.sin_addr = p->prefix;
2388 to.sin_port = htons (RIP_PORT_DEFAULT);
2389
2390 /* RIP version is rip's configuration. */
paulcc1131a2003-10-15 23:20:17 +00002391 rip_output_process (ifp, NULL, &to, route_type, rip->version_send, p);
paul718e3742002-12-13 20:15:29 +00002392 }
2393}
2394
2395/* RIP's periodical timer. */
2396int
2397rip_update (struct thread *t)
2398{
2399 /* Clear timer pointer. */
2400 rip->t_update = NULL;
2401
2402 if (IS_RIP_DEBUG_EVENT)
2403 zlog_info ("update timer fire!");
2404
2405 /* Process update output. */
2406 rip_update_process (rip_all_route);
2407
2408 /* Triggered updates may be suppressed if a regular update is due by
2409 the time the triggered update would be sent. */
2410 if (rip->t_triggered_interval)
2411 {
2412 thread_cancel (rip->t_triggered_interval);
2413 rip->t_triggered_interval = NULL;
2414 }
2415 rip->trigger = 0;
2416
2417 /* Register myself. */
2418 rip_event (RIP_UPDATE_EVENT, 0);
2419
2420 return 0;
2421}
2422
2423/* Walk down the RIP routing table then clear changed flag. */
2424void
2425rip_clear_changed_flag ()
2426{
2427 struct route_node *rp;
2428 struct rip_info *rinfo;
2429
2430 for (rp = route_top (rip->table); rp; rp = route_next (rp))
2431 if ((rinfo = rp->info) != NULL)
2432 if (rinfo->flags & RIP_RTF_CHANGED)
2433 rinfo->flags &= ~RIP_RTF_CHANGED;
2434}
2435
2436/* Triggered update interval timer. */
2437int
2438rip_triggered_interval (struct thread *t)
2439{
2440 int rip_triggered_update (struct thread *);
2441
2442 rip->t_triggered_interval = NULL;
2443
2444 if (rip->trigger)
2445 {
2446 rip->trigger = 0;
2447 rip_triggered_update (t);
2448 }
2449 return 0;
2450}
2451
2452/* Execute triggered update. */
2453int
2454rip_triggered_update (struct thread *t)
2455{
2456 int interval;
2457
2458 /* Clear thred pointer. */
2459 rip->t_triggered_update = NULL;
2460
2461 /* Cancel interval timer. */
2462 if (rip->t_triggered_interval)
2463 {
2464 thread_cancel (rip->t_triggered_interval);
2465 rip->t_triggered_interval = NULL;
2466 }
2467 rip->trigger = 0;
2468
2469 /* Logging triggered update. */
2470 if (IS_RIP_DEBUG_EVENT)
2471 zlog_info ("triggered update!");
2472
2473 /* Split Horizon processing is done when generating triggered
2474 updates as well as normal updates (see section 2.6). */
2475 rip_update_process (rip_changed_route);
2476
2477 /* Once all of the triggered updates have been generated, the route
2478 change flags should be cleared. */
2479 rip_clear_changed_flag ();
2480
2481 /* After a triggered update is sent, a timer should be set for a
2482 random interval between 1 and 5 seconds. If other changes that
2483 would trigger updates occur before the timer expires, a single
2484 update is triggered when the timer expires. */
2485 interval = (random () % 5) + 1;
2486
2487 rip->t_triggered_interval =
2488 thread_add_timer (master, rip_triggered_interval, NULL, interval);
2489
2490 return 0;
2491}
2492
2493/* Withdraw redistributed route. */
2494void
2495rip_redistribute_withdraw (int type)
2496{
2497 struct route_node *rp;
2498 struct rip_info *rinfo;
2499
2500 if (!rip)
2501 return;
2502
2503 for (rp = route_top (rip->table); rp; rp = route_next (rp))
2504 if ((rinfo = rp->info) != NULL)
2505 {
2506 if (rinfo->type == type
2507 && rinfo->sub_type != RIP_ROUTE_INTERFACE)
2508 {
2509 /* Perform poisoned reverse. */
2510 rinfo->metric = RIP_METRIC_INFINITY;
2511 RIP_TIMER_ON (rinfo->t_garbage_collect,
2512 rip_garbage_collect, rip->garbage_time);
2513 RIP_TIMER_OFF (rinfo->t_timeout);
2514 rinfo->flags |= RIP_RTF_CHANGED;
2515
hasso16705132003-05-25 14:49:19 +00002516 if (IS_RIP_DEBUG_EVENT) {
2517 struct prefix_ipv4 *p = (struct prefix_ipv4 *) &rp->p;
2518
2519 zlog_info ("Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2520 inet_ntoa(p->prefix), p->prefixlen,
2521 ifindex2ifname(rinfo->ifindex));
2522 }
2523
paul718e3742002-12-13 20:15:29 +00002524 rip_event (RIP_TRIGGERED_UPDATE, 0);
2525 }
2526 }
2527}
2528
2529/* Create new RIP instance and set it to global variable. */
2530int
2531rip_create ()
2532{
2533 rip = XMALLOC (MTYPE_RIP, sizeof (struct rip));
2534 memset (rip, 0, sizeof (struct rip));
2535
2536 /* Set initial value. */
paulf38a4712003-06-07 01:10:00 +00002537 rip->version_send = RI_RIP_VERSION_2;
2538 rip->version_recv = RI_RIP_VERSION_1_AND_2;
paul718e3742002-12-13 20:15:29 +00002539 rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
2540 rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
2541 rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
2542 rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
2543
2544 /* Initialize RIP routig table. */
2545 rip->table = route_table_init ();
2546 rip->route = route_table_init ();
2547 rip->neighbor = route_table_init ();
2548
2549 /* Make output stream. */
2550 rip->obuf = stream_new (1500);
2551
2552 /* Make socket. */
2553 rip->sock = rip_create_socket ();
2554 if (rip->sock < 0)
2555 return rip->sock;
2556
2557 /* Create read and timer thread. */
2558 rip_event (RIP_READ, rip->sock);
2559 rip_event (RIP_UPDATE_EVENT, 1);
2560
2561 return 0;
2562}
2563
2564/* Sned RIP request to the destination. */
2565int
2566rip_request_send (struct sockaddr_in *to, struct interface *ifp,
2567 u_char version)
2568{
2569 struct rte *rte;
2570 struct rip_packet rip_packet;
paulcc1131a2003-10-15 23:20:17 +00002571 listnode node;
2572 struct connected *connected;
paul718e3742002-12-13 20:15:29 +00002573
2574 memset (&rip_packet, 0, sizeof (rip_packet));
2575
2576 rip_packet.command = RIP_REQUEST;
2577 rip_packet.version = version;
2578 rte = rip_packet.rte;
2579 rte->metric = htonl (RIP_METRIC_INFINITY);
2580
paulcc1131a2003-10-15 23:20:17 +00002581 /* send request on each connected network */
2582 LIST_LOOP(ifp->connected, connected, node)
2583 {
2584 struct prefix_ipv4 *p;
2585
2586 p = (struct prefix_ipv4 *) connected->address;
2587
2588 if (p->family != AF_INET)
2589 continue;
2590
2591 rip_interface_multicast_set(rip->sock, connected,
2592 if_is_pointopoint(ifp));
2593 if (rip_send_packet ((caddr_t) &rip_packet, sizeof (rip_packet),
2594 to, ifp) != sizeof (rip_packet))
2595 return -1;
2596 }
2597 return sizeof (rip_packet);
paul718e3742002-12-13 20:15:29 +00002598}
2599
2600int
2601rip_update_jitter (unsigned long time)
2602{
2603 return ((rand () % (time + 1)) - (time / 2));
2604}
2605
2606void
2607rip_event (enum rip_event event, int sock)
2608{
2609 int jitter = 0;
2610
2611 switch (event)
2612 {
2613 case RIP_READ:
2614 rip->t_read = thread_add_read (master, rip_read, NULL, sock);
2615 break;
2616 case RIP_UPDATE_EVENT:
2617 if (rip->t_update)
2618 {
2619 thread_cancel (rip->t_update);
2620 rip->t_update = NULL;
2621 }
2622 jitter = rip_update_jitter (rip->update_time);
2623 rip->t_update =
2624 thread_add_timer (master, rip_update, NULL,
2625 sock ? 2 : rip->update_time + jitter);
2626 break;
2627 case RIP_TRIGGERED_UPDATE:
2628 if (rip->t_triggered_interval)
2629 rip->trigger = 1;
2630 else if (! rip->t_triggered_update)
2631 rip->t_triggered_update =
2632 thread_add_event (master, rip_triggered_update, NULL, 0);
2633 break;
2634 default:
2635 break;
2636 }
2637}
2638
2639DEFUN (router_rip,
2640 router_rip_cmd,
2641 "router rip",
2642 "Enable a routing process\n"
2643 "Routing Information Protocol (RIP)\n")
2644{
2645 int ret;
2646
2647 /* If rip is not enabled before. */
2648 if (! rip)
2649 {
2650 ret = rip_create ();
2651 if (ret < 0)
2652 {
2653 zlog_info ("Can't create RIP");
2654 return CMD_WARNING;
2655 }
2656 }
2657 vty->node = RIP_NODE;
2658 vty->index = rip;
2659
2660 return CMD_SUCCESS;
2661}
2662
2663DEFUN (no_router_rip,
2664 no_router_rip_cmd,
2665 "no router rip",
2666 NO_STR
2667 "Enable a routing process\n"
2668 "Routing Information Protocol (RIP)\n")
2669{
2670 if (rip)
2671 rip_clean ();
2672 return CMD_SUCCESS;
2673}
2674
2675DEFUN (rip_version,
2676 rip_version_cmd,
2677 "version <1-2>",
2678 "Set routing protocol version\n"
2679 "version\n")
2680{
2681 int version;
2682
2683 version = atoi (argv[0]);
2684 if (version != RIPv1 && version != RIPv2)
2685 {
2686 vty_out (vty, "invalid rip version %d%s", version,
2687 VTY_NEWLINE);
2688 return CMD_WARNING;
2689 }
paulf38a4712003-06-07 01:10:00 +00002690 rip->version_send = version;
2691 rip->version_recv = version;
paul718e3742002-12-13 20:15:29 +00002692
2693 return CMD_SUCCESS;
2694}
2695
2696DEFUN (no_rip_version,
2697 no_rip_version_cmd,
2698 "no version",
2699 NO_STR
2700 "Set routing protocol version\n")
2701{
2702 /* Set RIP version to the default. */
paulf38a4712003-06-07 01:10:00 +00002703 rip->version_send = RI_RIP_VERSION_2;
2704 rip->version_recv = RI_RIP_VERSION_1_AND_2;
paul718e3742002-12-13 20:15:29 +00002705
2706 return CMD_SUCCESS;
2707}
2708
2709ALIAS (no_rip_version,
2710 no_rip_version_val_cmd,
2711 "no version <1-2>",
2712 NO_STR
2713 "Set routing protocol version\n"
2714 "version\n")
2715
2716DEFUN (rip_route,
2717 rip_route_cmd,
2718 "route A.B.C.D/M",
2719 "RIP static route configuration\n"
2720 "IP prefix <network>/<length>\n")
2721{
2722 int ret;
2723 struct prefix_ipv4 p;
2724 struct route_node *node;
2725
2726 ret = str2prefix_ipv4 (argv[0], &p);
2727 if (ret < 0)
2728 {
2729 vty_out (vty, "Malformed address%s", VTY_NEWLINE);
2730 return CMD_WARNING;
2731 }
2732 apply_mask_ipv4 (&p);
2733
2734 /* For router rip configuration. */
2735 node = route_node_get (rip->route, (struct prefix *) &p);
2736
2737 if (node->info)
2738 {
2739 vty_out (vty, "There is already same static route.%s", VTY_NEWLINE);
2740 route_unlock_node (node);
2741 return CMD_WARNING;
2742 }
2743
2744 node->info = "static";
2745
2746 rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0, NULL);
2747
2748 return CMD_SUCCESS;
2749}
2750
2751DEFUN (no_rip_route,
2752 no_rip_route_cmd,
2753 "no route A.B.C.D/M",
2754 NO_STR
2755 "RIP static route configuration\n"
2756 "IP prefix <network>/<length>\n")
2757{
2758 int ret;
2759 struct prefix_ipv4 p;
2760 struct route_node *node;
2761
2762 ret = str2prefix_ipv4 (argv[0], &p);
2763 if (ret < 0)
2764 {
2765 vty_out (vty, "Malformed address%s", VTY_NEWLINE);
2766 return CMD_WARNING;
2767 }
2768 apply_mask_ipv4 (&p);
2769
2770 /* For router rip configuration. */
2771 node = route_node_lookup (rip->route, (struct prefix *) &p);
2772 if (! node)
2773 {
2774 vty_out (vty, "Can't find route %s.%s", argv[0],
2775 VTY_NEWLINE);
2776 return CMD_WARNING;
2777 }
2778
2779 rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
2780 route_unlock_node (node);
2781
2782 node->info = NULL;
2783 route_unlock_node (node);
2784
2785 return CMD_SUCCESS;
2786}
2787
2788void
2789rip_update_default_metric ()
2790{
2791 struct route_node *np;
2792 struct rip_info *rinfo;
2793
2794 for (np = route_top (rip->table); np; np = route_next (np))
2795 if ((rinfo = np->info) != NULL)
2796 if (rinfo->type != ZEBRA_ROUTE_RIP && rinfo->type != ZEBRA_ROUTE_CONNECT)
2797 rinfo->metric = rip->default_metric;
2798}
2799
2800DEFUN (rip_default_metric,
2801 rip_default_metric_cmd,
2802 "default-metric <1-16>",
2803 "Set a metric of redistribute routes\n"
2804 "Default metric\n")
2805{
2806 if (rip)
2807 {
2808 rip->default_metric = atoi (argv[0]);
2809 /* rip_update_default_metric (); */
2810 }
2811 return CMD_SUCCESS;
2812}
2813
2814DEFUN (no_rip_default_metric,
2815 no_rip_default_metric_cmd,
2816 "no default-metric",
2817 NO_STR
2818 "Set a metric of redistribute routes\n"
2819 "Default metric\n")
2820{
2821 if (rip)
2822 {
2823 rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
2824 /* rip_update_default_metric (); */
2825 }
2826 return CMD_SUCCESS;
2827}
2828
2829ALIAS (no_rip_default_metric,
2830 no_rip_default_metric_val_cmd,
2831 "no default-metric <1-16>",
2832 NO_STR
2833 "Set a metric of redistribute routes\n"
2834 "Default metric\n")
2835
2836DEFUN (rip_timers,
2837 rip_timers_cmd,
2838 "timers basic <5-2147483647> <5-2147483647> <5-2147483647>",
2839 "Adjust routing timers\n"
2840 "Basic routing protocol update timers\n"
2841 "Routing table update timer value in second. Default is 30.\n"
2842 "Routing information timeout timer. Default is 180.\n"
2843 "Garbage collection timer. Default is 120.\n")
2844{
2845 unsigned long update;
2846 unsigned long timeout;
2847 unsigned long garbage;
2848 char *endptr = NULL;
2849 unsigned long RIP_TIMER_MAX = 2147483647;
2850 unsigned long RIP_TIMER_MIN = 5;
2851
2852 update = strtoul (argv[0], &endptr, 10);
2853 if (update > RIP_TIMER_MAX || update < RIP_TIMER_MIN || *endptr != '\0')
2854 {
2855 vty_out (vty, "update timer value error%s", VTY_NEWLINE);
2856 return CMD_WARNING;
2857 }
2858
2859 timeout = strtoul (argv[1], &endptr, 10);
2860 if (timeout > RIP_TIMER_MAX || timeout < RIP_TIMER_MIN || *endptr != '\0')
2861 {
2862 vty_out (vty, "timeout timer value error%s", VTY_NEWLINE);
2863 return CMD_WARNING;
2864 }
2865
2866 garbage = strtoul (argv[2], &endptr, 10);
2867 if (garbage > RIP_TIMER_MAX || garbage < RIP_TIMER_MIN || *endptr != '\0')
2868 {
2869 vty_out (vty, "garbage timer value error%s", VTY_NEWLINE);
2870 return CMD_WARNING;
2871 }
2872
2873 /* Set each timer value. */
2874 rip->update_time = update;
2875 rip->timeout_time = timeout;
2876 rip->garbage_time = garbage;
2877
2878 /* Reset update timer thread. */
2879 rip_event (RIP_UPDATE_EVENT, 0);
2880
2881 return CMD_SUCCESS;
2882}
2883
2884DEFUN (no_rip_timers,
2885 no_rip_timers_cmd,
2886 "no timers basic",
2887 NO_STR
2888 "Adjust routing timers\n"
2889 "Basic routing protocol update timers\n")
2890{
2891 /* Set each timer value to the default. */
2892 rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
2893 rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
2894 rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
2895
2896 /* Reset update timer thread. */
2897 rip_event (RIP_UPDATE_EVENT, 0);
2898
2899 return CMD_SUCCESS;
2900}
hasso16705132003-05-25 14:49:19 +00002901
2902ALIAS (no_rip_timers,
2903 no_rip_timers_val_cmd,
2904 "no timers basic <0-65535> <0-65535> <0-65535>",
2905 NO_STR
2906 "Adjust routing timers\n"
2907 "Basic routing protocol update timers\n"
2908 "Routing table update timer value in second. Default is 30.\n"
2909 "Routing information timeout timer. Default is 180.\n"
2910 "Garbage collection timer. Default is 120.\n")
2911
paul718e3742002-12-13 20:15:29 +00002912
2913struct route_table *rip_distance_table;
2914
2915struct rip_distance
2916{
2917 /* Distance value for the IP source prefix. */
2918 u_char distance;
2919
2920 /* Name of the access-list to be matched. */
2921 char *access_list;
2922};
2923
2924struct rip_distance *
2925rip_distance_new ()
2926{
2927 struct rip_distance *new;
2928 new = XMALLOC (MTYPE_RIP_DISTANCE, sizeof (struct rip_distance));
2929 memset (new, 0, sizeof (struct rip_distance));
2930 return new;
2931}
2932
2933void
2934rip_distance_free (struct rip_distance *rdistance)
2935{
2936 XFREE (MTYPE_RIP_DISTANCE, rdistance);
2937}
2938
2939int
2940rip_distance_set (struct vty *vty, char *distance_str, char *ip_str,
2941 char *access_list_str)
2942{
2943 int ret;
2944 struct prefix_ipv4 p;
2945 u_char distance;
2946 struct route_node *rn;
2947 struct rip_distance *rdistance;
2948
2949 ret = str2prefix_ipv4 (ip_str, &p);
2950 if (ret == 0)
2951 {
2952 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
2953 return CMD_WARNING;
2954 }
2955
2956 distance = atoi (distance_str);
2957
2958 /* Get RIP distance node. */
2959 rn = route_node_get (rip_distance_table, (struct prefix *) &p);
2960 if (rn->info)
2961 {
2962 rdistance = rn->info;
2963 route_unlock_node (rn);
2964 }
2965 else
2966 {
2967 rdistance = rip_distance_new ();
2968 rn->info = rdistance;
2969 }
2970
2971 /* Set distance value. */
2972 rdistance->distance = distance;
2973
2974 /* Reset access-list configuration. */
2975 if (rdistance->access_list)
2976 {
2977 free (rdistance->access_list);
2978 rdistance->access_list = NULL;
2979 }
2980 if (access_list_str)
2981 rdistance->access_list = strdup (access_list_str);
2982
2983 return CMD_SUCCESS;
2984}
2985
2986int
2987rip_distance_unset (struct vty *vty, char *distance_str, char *ip_str,
2988 char *access_list_str)
2989{
2990 int ret;
2991 struct prefix_ipv4 p;
2992 u_char distance;
2993 struct route_node *rn;
2994 struct rip_distance *rdistance;
2995
2996 ret = str2prefix_ipv4 (ip_str, &p);
2997 if (ret == 0)
2998 {
2999 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
3000 return CMD_WARNING;
3001 }
3002
3003 distance = atoi (distance_str);
3004
3005 rn = route_node_lookup (rip_distance_table, (struct prefix *)&p);
3006 if (! rn)
3007 {
3008 vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
3009 return CMD_WARNING;
3010 }
3011
3012 rdistance = rn->info;
3013
3014 if (rdistance->access_list)
3015 free (rdistance->access_list);
3016 rip_distance_free (rdistance);
3017
3018 rn->info = NULL;
3019 route_unlock_node (rn);
3020 route_unlock_node (rn);
3021
3022 return CMD_SUCCESS;
3023}
3024
3025void
3026rip_distance_reset ()
3027{
3028 struct route_node *rn;
3029 struct rip_distance *rdistance;
3030
3031 for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
3032 if ((rdistance = rn->info) != NULL)
3033 {
3034 if (rdistance->access_list)
3035 free (rdistance->access_list);
3036 rip_distance_free (rdistance);
3037 rn->info = NULL;
3038 route_unlock_node (rn);
3039 }
3040}
3041
3042/* Apply RIP information to distance method. */
3043u_char
3044rip_distance_apply (struct rip_info *rinfo)
3045{
3046 struct route_node *rn;
3047 struct prefix_ipv4 p;
3048 struct rip_distance *rdistance;
3049 struct access_list *alist;
3050
3051 if (! rip)
3052 return 0;
3053
3054 memset (&p, 0, sizeof (struct prefix_ipv4));
3055 p.family = AF_INET;
3056 p.prefix = rinfo->from;
3057 p.prefixlen = IPV4_MAX_BITLEN;
3058
3059 /* Check source address. */
3060 rn = route_node_match (rip_distance_table, (struct prefix *) &p);
3061 if (rn)
3062 {
3063 rdistance = rn->info;
3064 route_unlock_node (rn);
3065
3066 if (rdistance->access_list)
3067 {
3068 alist = access_list_lookup (AFI_IP, rdistance->access_list);
3069 if (alist == NULL)
3070 return 0;
3071 if (access_list_apply (alist, &rinfo->rp->p) == FILTER_DENY)
3072 return 0;
3073
3074 return rdistance->distance;
3075 }
3076 else
3077 return rdistance->distance;
3078 }
3079
3080 if (rip->distance)
3081 return rip->distance;
3082
3083 return 0;
3084}
3085
3086void
3087rip_distance_show (struct vty *vty)
3088{
3089 struct route_node *rn;
3090 struct rip_distance *rdistance;
3091 int header = 1;
3092 char buf[BUFSIZ];
3093
3094 vty_out (vty, " Distance: (default is %d)%s",
3095 rip->distance ? rip->distance :ZEBRA_RIP_DISTANCE_DEFAULT,
3096 VTY_NEWLINE);
3097
3098 for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
3099 if ((rdistance = rn->info) != NULL)
3100 {
3101 if (header)
3102 {
3103 vty_out (vty, " Address Distance List%s",
3104 VTY_NEWLINE);
3105 header = 0;
3106 }
3107 sprintf (buf, "%s/%d", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
3108 vty_out (vty, " %-20s %4d %s%s",
3109 buf, rdistance->distance,
3110 rdistance->access_list ? rdistance->access_list : "",
3111 VTY_NEWLINE);
3112 }
3113}
3114
3115DEFUN (rip_distance,
3116 rip_distance_cmd,
3117 "distance <1-255>",
3118 "Administrative distance\n"
3119 "Distance value\n")
3120{
3121 rip->distance = atoi (argv[0]);
3122 return CMD_SUCCESS;
3123}
3124
3125DEFUN (no_rip_distance,
3126 no_rip_distance_cmd,
3127 "no distance <1-255>",
3128 NO_STR
3129 "Administrative distance\n"
3130 "Distance value\n")
3131{
3132 rip->distance = 0;
3133 return CMD_SUCCESS;
3134}
3135
3136DEFUN (rip_distance_source,
3137 rip_distance_source_cmd,
3138 "distance <1-255> A.B.C.D/M",
3139 "Administrative distance\n"
3140 "Distance value\n"
3141 "IP source prefix\n")
3142{
3143 rip_distance_set (vty, argv[0], argv[1], NULL);
3144 return CMD_SUCCESS;
3145}
3146
3147DEFUN (no_rip_distance_source,
3148 no_rip_distance_source_cmd,
3149 "no distance <1-255> A.B.C.D/M",
3150 NO_STR
3151 "Administrative distance\n"
3152 "Distance value\n"
3153 "IP source prefix\n")
3154{
3155 rip_distance_unset (vty, argv[0], argv[1], NULL);
3156 return CMD_SUCCESS;
3157}
3158
3159DEFUN (rip_distance_source_access_list,
3160 rip_distance_source_access_list_cmd,
3161 "distance <1-255> A.B.C.D/M WORD",
3162 "Administrative distance\n"
3163 "Distance value\n"
3164 "IP source prefix\n"
3165 "Access list name\n")
3166{
3167 rip_distance_set (vty, argv[0], argv[1], argv[2]);
3168 return CMD_SUCCESS;
3169}
3170
3171DEFUN (no_rip_distance_source_access_list,
3172 no_rip_distance_source_access_list_cmd,
3173 "no distance <1-255> A.B.C.D/M WORD",
3174 NO_STR
3175 "Administrative distance\n"
3176 "Distance value\n"
3177 "IP source prefix\n"
3178 "Access list name\n")
3179{
3180 rip_distance_unset (vty, argv[0], argv[1], argv[2]);
3181 return CMD_SUCCESS;
3182}
3183
3184/* Print out routes update time. */
3185void
3186rip_vty_out_uptime (struct vty *vty, struct rip_info *rinfo)
3187{
3188 struct timeval timer_now;
3189 time_t clock;
3190 struct tm *tm;
3191#define TIME_BUF 25
3192 char timebuf [TIME_BUF];
3193 struct thread *thread;
3194
3195 gettimeofday (&timer_now, NULL);
3196
3197 if ((thread = rinfo->t_timeout) != NULL)
3198 {
3199 clock = thread->u.sands.tv_sec - timer_now.tv_sec;
3200 tm = gmtime (&clock);
3201 strftime (timebuf, TIME_BUF, "%M:%S", tm);
3202 vty_out (vty, "%5s", timebuf);
3203 }
3204 else if ((thread = rinfo->t_garbage_collect) != NULL)
3205 {
3206 clock = thread->u.sands.tv_sec - timer_now.tv_sec;
3207 tm = gmtime (&clock);
3208 strftime (timebuf, TIME_BUF, "%M:%S", tm);
3209 vty_out (vty, "%5s", timebuf);
3210 }
3211}
3212
3213char *
3214rip_route_type_print (int sub_type)
3215{
3216 switch (sub_type)
3217 {
3218 case RIP_ROUTE_RTE:
3219 return "n";
3220 case RIP_ROUTE_STATIC:
3221 return "s";
3222 case RIP_ROUTE_DEFAULT:
3223 return "d";
3224 case RIP_ROUTE_REDISTRIBUTE:
3225 return "r";
3226 case RIP_ROUTE_INTERFACE:
3227 return "i";
3228 default:
3229 return "?";
3230 }
3231}
3232
3233DEFUN (show_ip_rip,
3234 show_ip_rip_cmd,
3235 "show ip rip",
3236 SHOW_STR
3237 IP_STR
3238 "Show RIP routes\n")
3239{
3240 struct route_node *np;
3241 struct rip_info *rinfo;
3242
3243 if (! rip)
3244 return CMD_SUCCESS;
3245
hasso16705132003-05-25 14:49:19 +00003246 vty_out (vty, "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP%s"
3247 "Sub-codes:%s"
3248 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,%s"
paul718e3742002-12-13 20:15:29 +00003249 " (i) - interface%s%s"
hasso16705132003-05-25 14:49:19 +00003250 " Network Next Hop Metric From Tag Time%s",
3251 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00003252
3253 for (np = route_top (rip->table); np; np = route_next (np))
3254 if ((rinfo = np->info) != NULL)
3255 {
3256 int len;
3257
3258 len = vty_out (vty, "%s(%s) %s/%d",
3259 /* np->lock, For debugging. */
3260 route_info[rinfo->type].str,
3261 rip_route_type_print (rinfo->sub_type),
3262 inet_ntoa (np->p.u.prefix4), np->p.prefixlen);
3263
hasso16705132003-05-25 14:49:19 +00003264 len = 21 - len;
paul718e3742002-12-13 20:15:29 +00003265
3266 if (len > 0)
3267 vty_out (vty, "%*s", len, " ");
3268
3269 if (rinfo->nexthop.s_addr)
3270 vty_out (vty, "%-20s %2d ", inet_ntoa (rinfo->nexthop),
3271 rinfo->metric);
3272 else
3273 vty_out (vty, "0.0.0.0 %2d ", rinfo->metric);
3274
3275 /* Route which exist in kernel routing table. */
3276 if ((rinfo->type == ZEBRA_ROUTE_RIP) &&
3277 (rinfo->sub_type == RIP_ROUTE_RTE))
3278 {
3279 vty_out (vty, "%-15s ", inet_ntoa (rinfo->from));
hasso16705132003-05-25 14:49:19 +00003280 vty_out (vty, "%3d ", rinfo->tag);
paul718e3742002-12-13 20:15:29 +00003281 rip_vty_out_uptime (vty, rinfo);
3282 }
3283 else if (rinfo->metric == RIP_METRIC_INFINITY)
3284 {
3285 vty_out (vty, "self ");
hasso16705132003-05-25 14:49:19 +00003286 vty_out (vty, "%3d ", rinfo->tag);
paul718e3742002-12-13 20:15:29 +00003287 rip_vty_out_uptime (vty, rinfo);
3288 }
3289 else
hasso16705132003-05-25 14:49:19 +00003290 {
3291 vty_out (vty, "self ");
3292 vty_out (vty, "%3d", rinfo->tag);
3293 }
paul718e3742002-12-13 20:15:29 +00003294
3295 vty_out (vty, "%s", VTY_NEWLINE);
3296 }
3297 return CMD_SUCCESS;
3298}
3299
3300/* Return next event time. */
3301int
3302rip_next_thread_timer (struct thread *thread)
3303{
3304 struct timeval timer_now;
3305
3306 gettimeofday (&timer_now, NULL);
3307
3308 return thread->u.sands.tv_sec - timer_now.tv_sec;
3309}
3310
hasso16705132003-05-25 14:49:19 +00003311/* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3312DEFUN (show_ip_rip_status,
3313 show_ip_rip_status_cmd,
3314 "show ip rip status",
paul718e3742002-12-13 20:15:29 +00003315 SHOW_STR
3316 IP_STR
hasso16705132003-05-25 14:49:19 +00003317 "Show RIP routes\n"
paul718e3742002-12-13 20:15:29 +00003318 "IP routing protocol process parameters and statistics\n")
3319{
3320 listnode node;
3321 struct interface *ifp;
3322 struct rip_interface *ri;
3323 extern struct message ri_version_msg[];
3324 char *send_version;
3325 char *receive_version;
3326
3327 if (! rip)
3328 return CMD_SUCCESS;
3329
3330 vty_out (vty, "Routing Protocol is \"rip\"%s", VTY_NEWLINE);
3331 vty_out (vty, " Sending updates every %ld seconds with +/-50%%,",
3332 rip->update_time);
3333 vty_out (vty, " next due in %d seconds%s",
3334 rip_next_thread_timer (rip->t_update),
3335 VTY_NEWLINE);
3336 vty_out (vty, " Timeout after %ld seconds,", rip->timeout_time);
3337 vty_out (vty, " garbage collect after %ld seconds%s", rip->garbage_time,
3338 VTY_NEWLINE);
3339
3340 /* Filtering status show. */
3341 config_show_distribute (vty);
3342
3343 /* Default metric information. */
3344 vty_out (vty, " Default redistribution metric is %d%s",
3345 rip->default_metric, VTY_NEWLINE);
3346
3347 /* Redistribute information. */
3348 vty_out (vty, " Redistributing:");
3349 config_write_rip_redistribute (vty, 0);
3350 vty_out (vty, "%s", VTY_NEWLINE);
3351
paulf38a4712003-06-07 01:10:00 +00003352 vty_out (vty, " Default version control: send version %s,",
3353 lookup(ri_version_msg,rip->version_send));
3354 if (rip->version_recv == RI_RIP_VERSION_1_AND_2)
3355 vty_out (vty, " receive any version %s", VTY_NEWLINE);
3356 else
3357 vty_out (vty, " receive version %s %s",
3358 lookup(ri_version_msg,rip->version_recv), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00003359
3360 vty_out (vty, " Interface Send Recv Key-chain%s", VTY_NEWLINE);
3361
3362 for (node = listhead (iflist); node; node = nextnode (node))
3363 {
3364 ifp = getdata (node);
3365 ri = ifp->info;
3366
3367 if (ri->enable_network || ri->enable_interface)
3368 {
3369 if (ri->ri_send == RI_RIP_UNSPEC)
paulf38a4712003-06-07 01:10:00 +00003370 send_version = lookup (ri_version_msg, rip->version_send);
paul718e3742002-12-13 20:15:29 +00003371 else
3372 send_version = lookup (ri_version_msg, ri->ri_send);
3373
3374 if (ri->ri_receive == RI_RIP_UNSPEC)
paulf38a4712003-06-07 01:10:00 +00003375 receive_version = lookup (ri_version_msg, rip->version_recv);
paul718e3742002-12-13 20:15:29 +00003376 else
3377 receive_version = lookup (ri_version_msg, ri->ri_receive);
3378
3379 vty_out (vty, " %-17s%-3s %-3s %s%s", ifp->name,
3380 send_version,
3381 receive_version,
3382 ri->key_chain ? ri->key_chain : "",
3383 VTY_NEWLINE);
3384 }
3385 }
3386
3387 vty_out (vty, " Routing for Networks:%s", VTY_NEWLINE);
3388 config_write_rip_network (vty, 0);
3389
paul4aaff3f2003-06-07 01:04:45 +00003390 {
3391 int found_passive = 0;
3392 for (node = listhead (iflist); node; node = nextnode (node))
3393 {
3394 ifp = getdata (node);
3395 ri = ifp->info;
3396
3397 if ((ri->enable_network || ri->enable_interface) && ri->passive)
3398 {
3399 if (!found_passive)
3400 {
3401 vty_out (vty, " Passive Interface(s):%s", VTY_NEWLINE);
3402 found_passive = 1;
3403 }
3404 vty_out (vty, " %s%s", ifp->name, VTY_NEWLINE);
3405 }
3406 }
3407 }
3408
paul718e3742002-12-13 20:15:29 +00003409 vty_out (vty, " Routing Information Sources:%s", VTY_NEWLINE);
3410 vty_out (vty, " Gateway BadPackets BadRoutes Distance Last Update%s", VTY_NEWLINE);
3411 rip_peer_display (vty);
3412
3413 rip_distance_show (vty);
3414
3415 return CMD_SUCCESS;
3416}
3417
3418/* RIP configuration write function. */
3419int
3420config_write_rip (struct vty *vty)
3421{
3422 int write = 0;
3423 struct route_node *rn;
3424 struct rip_distance *rdistance;
3425
3426 if (rip)
3427 {
3428 /* Router RIP statement. */
3429 vty_out (vty, "router rip%s", VTY_NEWLINE);
3430 write++;
3431
3432 /* RIP version statement. Default is RIP version 2. */
paulf38a4712003-06-07 01:10:00 +00003433 if (rip->version_send != RI_RIP_VERSION_2
3434 || rip->version_recv != RI_RIP_VERSION_1_AND_2)
3435 vty_out (vty, " version %d%s", rip->version_send,
paul718e3742002-12-13 20:15:29 +00003436 VTY_NEWLINE);
3437
3438 /* RIP timer configuration. */
3439 if (rip->update_time != RIP_UPDATE_TIMER_DEFAULT
3440 || rip->timeout_time != RIP_TIMEOUT_TIMER_DEFAULT
3441 || rip->garbage_time != RIP_GARBAGE_TIMER_DEFAULT)
3442 vty_out (vty, " timers basic %lu %lu %lu%s",
3443 rip->update_time,
3444 rip->timeout_time,
3445 rip->garbage_time,
3446 VTY_NEWLINE);
3447
3448 /* Default information configuration. */
3449 if (rip->default_information)
3450 {
3451 if (rip->default_information_route_map)
3452 vty_out (vty, " default-information originate route-map %s%s",
3453 rip->default_information_route_map, VTY_NEWLINE);
3454 else
3455 vty_out (vty, " default-information originate%s",
3456 VTY_NEWLINE);
3457 }
3458
3459 /* Redistribute configuration. */
3460 config_write_rip_redistribute (vty, 1);
3461
3462 /* RIP offset-list configuration. */
3463 config_write_rip_offset_list (vty);
3464
3465 /* RIP enabled network and interface configuration. */
3466 config_write_rip_network (vty, 1);
3467
3468 /* RIP default metric configuration */
3469 if (rip->default_metric != RIP_DEFAULT_METRIC_DEFAULT)
3470 vty_out (vty, " default-metric %d%s",
3471 rip->default_metric, VTY_NEWLINE);
3472
3473 /* Distribute configuration. */
3474 write += config_write_distribute (vty);
3475
hasso16705132003-05-25 14:49:19 +00003476 /* Interface routemap configuration */
3477 write += config_write_if_rmap (vty);
3478
paul718e3742002-12-13 20:15:29 +00003479 /* Distance configuration. */
3480 if (rip->distance)
3481 vty_out (vty, " distance %d%s", rip->distance, VTY_NEWLINE);
3482
3483 /* RIP source IP prefix distance configuration. */
3484 for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
3485 if ((rdistance = rn->info) != NULL)
3486 vty_out (vty, " distance %d %s/%d %s%s", rdistance->distance,
3487 inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
3488 rdistance->access_list ? rdistance->access_list : "",
3489 VTY_NEWLINE);
3490
3491 /* RIP static route configuration. */
3492 for (rn = route_top (rip->route); rn; rn = route_next (rn))
3493 if (rn->info)
3494 vty_out (vty, " route %s/%d%s",
3495 inet_ntoa (rn->p.u.prefix4),
3496 rn->p.prefixlen,
3497 VTY_NEWLINE);
3498
3499 }
3500 return write;
3501}
3502
3503/* RIP node structure. */
3504struct cmd_node rip_node =
3505{
3506 RIP_NODE,
3507 "%s(config-router)# ",
3508 1
3509};
3510
3511/* Distribute-list update functions. */
3512void
3513rip_distribute_update (struct distribute *dist)
3514{
3515 struct interface *ifp;
3516 struct rip_interface *ri;
3517 struct access_list *alist;
3518 struct prefix_list *plist;
3519
3520 if (! dist->ifname)
3521 return;
3522
3523 ifp = if_lookup_by_name (dist->ifname);
3524 if (ifp == NULL)
3525 return;
3526
3527 ri = ifp->info;
3528
3529 if (dist->list[DISTRIBUTE_IN])
3530 {
3531 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_IN]);
3532 if (alist)
3533 ri->list[RIP_FILTER_IN] = alist;
3534 else
3535 ri->list[RIP_FILTER_IN] = NULL;
3536 }
3537 else
3538 ri->list[RIP_FILTER_IN] = NULL;
3539
3540 if (dist->list[DISTRIBUTE_OUT])
3541 {
3542 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_OUT]);
3543 if (alist)
3544 ri->list[RIP_FILTER_OUT] = alist;
3545 else
3546 ri->list[RIP_FILTER_OUT] = NULL;
3547 }
3548 else
3549 ri->list[RIP_FILTER_OUT] = NULL;
3550
3551 if (dist->prefix[DISTRIBUTE_IN])
3552 {
3553 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_IN]);
3554 if (plist)
3555 ri->prefix[RIP_FILTER_IN] = plist;
3556 else
3557 ri->prefix[RIP_FILTER_IN] = NULL;
3558 }
3559 else
3560 ri->prefix[RIP_FILTER_IN] = NULL;
3561
3562 if (dist->prefix[DISTRIBUTE_OUT])
3563 {
3564 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_OUT]);
3565 if (plist)
3566 ri->prefix[RIP_FILTER_OUT] = plist;
3567 else
3568 ri->prefix[RIP_FILTER_OUT] = NULL;
3569 }
3570 else
3571 ri->prefix[RIP_FILTER_OUT] = NULL;
3572}
3573
3574void
3575rip_distribute_update_interface (struct interface *ifp)
3576{
3577 struct distribute *dist;
3578
3579 dist = distribute_lookup (ifp->name);
3580 if (dist)
3581 rip_distribute_update (dist);
3582}
3583
3584/* Update all interface's distribute list. */
3585void
3586rip_distribute_update_all ()
3587{
3588 struct interface *ifp;
3589 listnode node;
3590
3591 for (node = listhead (iflist); node; nextnode (node))
3592 {
3593 ifp = getdata (node);
3594 rip_distribute_update_interface (ifp);
3595 }
3596}
3597
3598/* Delete all added rip route. */
3599void
3600rip_clean ()
3601{
3602 int i;
3603 struct route_node *rp;
3604 struct rip_info *rinfo;
3605
3606 if (rip)
3607 {
3608 /* Clear RIP routes */
3609 for (rp = route_top (rip->table); rp; rp = route_next (rp))
3610 if ((rinfo = rp->info) != NULL)
3611 {
3612 if (rinfo->type == ZEBRA_ROUTE_RIP &&
3613 rinfo->sub_type == RIP_ROUTE_RTE)
3614 rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p,
3615 &rinfo->nexthop, rinfo->metric);
3616
3617 RIP_TIMER_OFF (rinfo->t_timeout);
3618 RIP_TIMER_OFF (rinfo->t_garbage_collect);
3619
3620 rp->info = NULL;
3621 route_unlock_node (rp);
3622
3623 rip_info_free (rinfo);
3624 }
3625
3626 /* Cancel RIP related timers. */
3627 RIP_TIMER_OFF (rip->t_update);
3628 RIP_TIMER_OFF (rip->t_triggered_update);
3629 RIP_TIMER_OFF (rip->t_triggered_interval);
3630
3631 /* Cancel read thread. */
3632 if (rip->t_read)
3633 {
3634 thread_cancel (rip->t_read);
3635 rip->t_read = NULL;
3636 }
3637
3638 /* Close RIP socket. */
3639 if (rip->sock >= 0)
3640 {
3641 close (rip->sock);
3642 rip->sock = -1;
3643 }
3644
3645 /* Static RIP route configuration. */
3646 for (rp = route_top (rip->route); rp; rp = route_next (rp))
3647 if (rp->info)
3648 {
3649 rp->info = NULL;
3650 route_unlock_node (rp);
3651 }
3652
3653 /* RIP neighbor configuration. */
3654 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
3655 if (rp->info)
3656 {
3657 rp->info = NULL;
3658 route_unlock_node (rp);
3659 }
3660
3661 /* Redistribute related clear. */
3662 if (rip->default_information_route_map)
3663 free (rip->default_information_route_map);
3664
3665 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
3666 if (rip->route_map[i].name)
3667 free (rip->route_map[i].name);
3668
3669 XFREE (MTYPE_ROUTE_TABLE, rip->table);
3670 XFREE (MTYPE_ROUTE_TABLE, rip->route);
3671 XFREE (MTYPE_ROUTE_TABLE, rip->neighbor);
3672
3673 XFREE (MTYPE_RIP, rip);
3674 rip = NULL;
3675 }
3676
3677 rip_clean_network ();
paul4aaff3f2003-06-07 01:04:45 +00003678 rip_passive_nondefault_clean ();
paul718e3742002-12-13 20:15:29 +00003679 rip_offset_clean ();
3680 rip_interface_clean ();
3681 rip_distance_reset ();
3682 rip_redistribute_clean ();
3683}
3684
3685/* Reset all values to the default settings. */
3686void
3687rip_reset ()
3688{
3689 /* Reset global counters. */
3690 rip_global_route_changes = 0;
3691 rip_global_queries = 0;
3692
3693 /* Call ripd related reset functions. */
3694 rip_debug_reset ();
3695 rip_route_map_reset ();
3696
3697 /* Call library reset functions. */
3698 vty_reset ();
3699 access_list_reset ();
3700 prefix_list_reset ();
3701
3702 distribute_list_reset ();
3703
3704 rip_interface_reset ();
3705 rip_distance_reset ();
3706
3707 rip_zclient_reset ();
3708}
3709
hasso16705132003-05-25 14:49:19 +00003710void
3711rip_if_rmap_update (struct if_rmap *if_rmap)
3712{
3713 struct interface *ifp;
3714 struct rip_interface *ri;
3715 struct route_map *rmap;
3716
3717 ifp = if_lookup_by_name (if_rmap->ifname);
3718 if (ifp == NULL)
3719 return;
3720
3721 ri = ifp->info;
3722
3723 if (if_rmap->routemap[IF_RMAP_IN])
3724 {
3725 rmap = route_map_lookup_by_name (if_rmap->routemap[IF_RMAP_IN]);
3726 if (rmap)
3727 ri->routemap[IF_RMAP_IN] = rmap;
3728 else
3729 ri->routemap[IF_RMAP_IN] = NULL;
3730 }
3731 else
3732 ri->routemap[RIP_FILTER_IN] = NULL;
3733
3734 if (if_rmap->routemap[IF_RMAP_OUT])
3735 {
3736 rmap = route_map_lookup_by_name (if_rmap->routemap[IF_RMAP_OUT]);
3737 if (rmap)
3738 ri->routemap[IF_RMAP_OUT] = rmap;
3739 else
3740 ri->routemap[IF_RMAP_OUT] = NULL;
3741 }
3742 else
3743 ri->routemap[RIP_FILTER_OUT] = NULL;
3744}
3745
3746void
3747rip_if_rmap_update_interface (struct interface *ifp)
3748{
3749 struct if_rmap *if_rmap;
3750
3751 if_rmap = if_rmap_lookup (ifp->name);
3752 if (if_rmap)
3753 rip_if_rmap_update (if_rmap);
3754}
3755
3756void
3757rip_routemap_update_redistribute (void)
3758{
3759 int i;
3760
3761 if (rip)
3762 {
3763 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
3764 {
3765 if (rip->route_map[i].name)
3766 rip->route_map[i].map =
3767 route_map_lookup_by_name (rip->route_map[i].name);
3768 }
3769 }
3770}
3771
3772void
3773rip_routemap_update ()
3774{
3775 struct interface *ifp;
3776 listnode node;
3777
3778 for (node = listhead (iflist); node; nextnode (node))
3779 {
3780 ifp = getdata (node);
3781 rip_if_rmap_update_interface (ifp);
3782 }
3783
3784 rip_routemap_update_redistribute ();
3785}
3786
paul718e3742002-12-13 20:15:29 +00003787/* Allocate new rip structure and set default value. */
3788void
3789rip_init ()
3790{
3791 /* Randomize for triggered update random(). */
3792 srand (time (NULL));
3793
3794 /* Install top nodes. */
3795 install_node (&rip_node, config_write_rip);
3796
3797 /* Install rip commands. */
3798 install_element (VIEW_NODE, &show_ip_rip_cmd);
hasso16705132003-05-25 14:49:19 +00003799 install_element (VIEW_NODE, &show_ip_rip_status_cmd);
paul718e3742002-12-13 20:15:29 +00003800 install_element (ENABLE_NODE, &show_ip_rip_cmd);
hasso16705132003-05-25 14:49:19 +00003801 install_element (ENABLE_NODE, &show_ip_rip_status_cmd);
paul718e3742002-12-13 20:15:29 +00003802 install_element (CONFIG_NODE, &router_rip_cmd);
3803 install_element (CONFIG_NODE, &no_router_rip_cmd);
3804
3805 install_default (RIP_NODE);
3806 install_element (RIP_NODE, &rip_version_cmd);
3807 install_element (RIP_NODE, &no_rip_version_cmd);
3808 install_element (RIP_NODE, &no_rip_version_val_cmd);
3809 install_element (RIP_NODE, &rip_default_metric_cmd);
3810 install_element (RIP_NODE, &no_rip_default_metric_cmd);
3811 install_element (RIP_NODE, &no_rip_default_metric_val_cmd);
3812 install_element (RIP_NODE, &rip_timers_cmd);
3813 install_element (RIP_NODE, &no_rip_timers_cmd);
hasso16705132003-05-25 14:49:19 +00003814 install_element (RIP_NODE, &no_rip_timers_val_cmd);
paul718e3742002-12-13 20:15:29 +00003815 install_element (RIP_NODE, &rip_route_cmd);
3816 install_element (RIP_NODE, &no_rip_route_cmd);
3817 install_element (RIP_NODE, &rip_distance_cmd);
3818 install_element (RIP_NODE, &no_rip_distance_cmd);
3819 install_element (RIP_NODE, &rip_distance_source_cmd);
3820 install_element (RIP_NODE, &no_rip_distance_source_cmd);
3821 install_element (RIP_NODE, &rip_distance_source_access_list_cmd);
3822 install_element (RIP_NODE, &no_rip_distance_source_access_list_cmd);
3823
3824 /* Debug related init. */
3825 rip_debug_init ();
3826
paul718e3742002-12-13 20:15:29 +00003827 /* SNMP init. */
3828#ifdef HAVE_SNMP
3829 rip_snmp_init ();
3830#endif /* HAVE_SNMP */
3831
3832 /* Access list install. */
3833 access_list_init ();
3834 access_list_add_hook (rip_distribute_update_all);
3835 access_list_delete_hook (rip_distribute_update_all);
3836
3837 /* Prefix list initialize.*/
3838 prefix_list_init ();
3839 prefix_list_add_hook (rip_distribute_update_all);
3840 prefix_list_delete_hook (rip_distribute_update_all);
3841
3842 /* Distribute list install. */
3843 distribute_list_init (RIP_NODE);
3844 distribute_list_add_hook (rip_distribute_update);
3845 distribute_list_delete_hook (rip_distribute_update);
3846
hasso16705132003-05-25 14:49:19 +00003847 /* Route-map */
3848 rip_route_map_init ();
3849 rip_offset_init ();
3850
3851 route_map_add_hook (rip_routemap_update);
3852 route_map_delete_hook (rip_routemap_update);
3853
3854 if_rmap_init (RIP_NODE);
3855 if_rmap_hook_add (rip_if_rmap_update);
3856 if_rmap_hook_delete (rip_if_rmap_update);
3857
paul718e3742002-12-13 20:15:29 +00003858 /* Distance control. */
3859 rip_distance_table = route_table_init ();
3860}