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