blob: c017fe56436a5cecb015847ed82c71eca2cff450 [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
58void rip_output_process (struct interface *, struct sockaddr_in *,
59 int, u_char);
60
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;
958
959 /* The Response must be ignored if it is not from the RIP
960 port. (RFC2453 - Sec. 3.9.2)*/
961 if (ntohs (from->sin_port) != RIP_PORT_DEFAULT)
962 {
963 zlog_info ("response doesn't come from RIP port: %d",
964 from->sin_port);
965 rip_peer_bad_packet (from);
966 return;
967 }
968
969 /* The datagram's IPv4 source address should be checked to see
970 whether the datagram is from a valid neighbor; the source of the
971 datagram must be on a directly connected network */
972 if (! if_valid_neighbor (from->sin_addr))
973 {
974 zlog_info ("This datagram doesn't came from a valid neighbor: %s",
975 inet_ntoa (from->sin_addr));
976 rip_peer_bad_packet (from);
977 return;
978 }
979
980 /* It is also worth checking to see whether the response is from one
981 of the router's own addresses. */
982
983 ; /* Alredy done in rip_read () */
984
985 /* Update RIP peer. */
986 rip_peer_update (from, packet->version);
987
988 /* Set RTE pointer. */
989 rte = packet->rte;
990
991 for (lim = (caddr_t) packet + size; (caddr_t) rte < lim; rte++)
992 {
993 /* RIPv2 authentication check. */
994 /* If the Address Family Identifier of the first (and only the
995 first) entry in the message is 0xFFFF, then the remainder of
996 the entry contains the authentication. */
997 /* If the packet gets here it means authentication enabled */
998 /* Check is done in rip_read(). So, just skipping it */
999 if (packet->version == RIPv2 &&
1000 rte == packet->rte &&
1001 rte->family == 0xffff)
1002 continue;
1003
1004 if (ntohs (rte->family) != AF_INET)
1005 {
1006 /* Address family check. RIP only supports AF_INET. */
1007 zlog_info ("Unsupported family %d from %s.",
1008 ntohs (rte->family), inet_ntoa (from->sin_addr));
1009 continue;
1010 }
1011
1012 /* - is the destination address valid (e.g., unicast; not net 0
1013 or 127) */
1014 if (! rip_destination_check (rte->prefix))
1015 {
1016 zlog_info ("Network is net 0 or net 127 or it is not unicast network");
1017 rip_peer_bad_route (from);
1018 continue;
1019 }
1020
1021 /* Convert metric value to host byte order. */
1022 rte->metric = ntohl (rte->metric);
1023
1024 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1025 if (! (rte->metric >= 1 && rte->metric <= 16))
1026 {
1027 zlog_info ("Route's metric is not in the 1-16 range.");
1028 rip_peer_bad_route (from);
1029 continue;
1030 }
1031
1032 /* RIPv1 does not have nexthop value. */
1033 if (packet->version == RIPv1 && rte->nexthop.s_addr != 0)
1034 {
1035 zlog_info ("RIPv1 packet with nexthop value %s",
1036 inet_ntoa (rte->nexthop));
1037 rip_peer_bad_route (from);
1038 continue;
1039 }
1040
1041 /* That is, if the provided information is ignored, a possibly
1042 sub-optimal, but absolutely valid, route may be taken. If
1043 the received Next Hop is not directly reachable, it should be
1044 treated as 0.0.0.0. */
1045 if (packet->version == RIPv2 && rte->nexthop.s_addr != 0)
1046 {
1047 u_int32_t addrval;
1048
1049 /* Multicast address check. */
1050 addrval = ntohl (rte->nexthop.s_addr);
1051 if (IN_CLASSD (addrval))
1052 {
1053 zlog_info ("Nexthop %s is multicast address, skip this rte",
1054 inet_ntoa (rte->nexthop));
1055 continue;
1056 }
1057
1058 if (! if_lookup_address (rte->nexthop))
1059 {
1060 struct route_node *rn;
1061 struct rip_info *rinfo;
1062
1063 rn = route_node_match_ipv4 (rip->table, &rte->nexthop);
1064
1065 if (rn)
1066 {
1067 rinfo = rn->info;
1068
1069 if (rinfo->type == ZEBRA_ROUTE_RIP
1070 && rinfo->sub_type == RIP_ROUTE_RTE)
1071 {
1072 if (IS_RIP_DEBUG_EVENT)
1073 zlog_info ("Next hop %s is on RIP network. Set nexthop to the packet's originator", inet_ntoa (rte->nexthop));
1074 rte->nexthop = rinfo->from;
1075 }
1076 else
1077 {
1078 if (IS_RIP_DEBUG_EVENT)
1079 zlog_info ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte->nexthop));
1080 rte->nexthop.s_addr = 0;
1081 }
1082
1083 route_unlock_node (rn);
1084 }
1085 else
1086 {
1087 if (IS_RIP_DEBUG_EVENT)
1088 zlog_info ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte->nexthop));
1089 rte->nexthop.s_addr = 0;
1090 }
1091
1092 }
1093 }
1094
1095 /* For RIPv1, there won't be a valid netmask.
1096
1097 This is a best guess at the masks. If everyone was using old
1098 Ciscos before the 'ip subnet zero' option, it would be almost
1099 right too :-)
1100
1101 Cisco summarize ripv1 advertisments to the classful boundary
1102 (/16 for class B's) except when the RIP packet does to inside
1103 the classful network in question. */
1104
1105 if ((packet->version == RIPv1 && rte->prefix.s_addr != 0)
1106 || (packet->version == RIPv2
1107 && (rte->prefix.s_addr != 0 && rte->mask.s_addr == 0)))
1108 {
1109 u_int32_t destination;
1110
1111 destination = ntohl (rte->prefix.s_addr);
1112
1113 if (destination & 0xff)
1114 {
1115 masklen2ip (32, &rte->mask);
1116 }
1117 else if ((destination & 0xff00) || IN_CLASSC (destination))
1118 {
1119 masklen2ip (24, &rte->mask);
1120 }
1121 else if ((destination & 0xff0000) || IN_CLASSB (destination))
1122 {
1123 masklen2ip (16, &rte->mask);
1124 }
1125 else
1126 {
1127 masklen2ip (8, &rte->mask);
1128 }
1129 }
1130
1131 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1132 ignore the entry. */
1133 if ((packet->version == RIPv2)
1134 && (rte->mask.s_addr != 0)
1135 && ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr))
1136 {
1137 zlog_warn ("RIPv2 address %s is not mask /%d applied one",
1138 inet_ntoa (rte->prefix), ip_masklen (rte->mask));
1139 rip_peer_bad_route (from);
1140 continue;
1141 }
1142
1143 /* Default route's netmask is ignored. */
1144 if (packet->version == RIPv2
1145 && (rte->prefix.s_addr == 0)
1146 && (rte->mask.s_addr != 0))
1147 {
1148 if (IS_RIP_DEBUG_EVENT)
1149 zlog_info ("Default route with non-zero netmask. Set zero to netmask");
1150 rte->mask.s_addr = 0;
1151 }
1152
1153 /* Routing table updates. */
1154 rip_rte_process (rte, from, ifp);
1155 }
1156}
1157
1158/* RIP packet send to destination address. */
1159int
1160rip_send_packet (caddr_t buf, int size, struct sockaddr_in *to,
1161 struct interface *ifp)
1162{
1163 int ret;
1164 struct sockaddr_in sin;
1165 int sock;
1166
1167 /* Make destination address. */
1168 memset (&sin, 0, sizeof (struct sockaddr_in));
1169 sin.sin_family = AF_INET;
1170#ifdef HAVE_SIN_LEN
1171 sin.sin_len = sizeof (struct sockaddr_in);
1172#endif /* HAVE_SIN_LEN */
1173
1174 /* When destination is specified, use it's port and address. */
1175 if (to)
1176 {
1177 sock = rip->sock;
1178
1179 sin.sin_port = to->sin_port;
1180 sin.sin_addr = to->sin_addr;
1181 }
1182 else
1183 {
1184 sock = socket (AF_INET, SOCK_DGRAM, 0);
1185
1186 sockopt_broadcast (sock);
1187 sockopt_reuseaddr (sock);
1188 sockopt_reuseport (sock);
1189
1190 sin.sin_port = htons (RIP_PORT_DEFAULT);
1191 sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP);
1192
1193 /* Set multicast interface. */
1194 rip_interface_multicast_set (sock, ifp);
1195 }
1196
1197 ret = sendto (sock, buf, size, 0, (struct sockaddr *)&sin,
1198 sizeof (struct sockaddr_in));
1199
1200 if (IS_RIP_DEBUG_EVENT)
1201 zlog_info ("SEND to socket %d port %d addr %s",
1202 sock, ntohs (sin.sin_port), inet_ntoa(sin.sin_addr));
1203
1204 if (ret < 0)
1205 zlog_warn ("can't send packet : %s", strerror (errno));
1206
1207 if (! to)
1208 close (sock);
1209
1210 return ret;
1211}
1212
1213/* Add redistributed route to RIP table. */
1214void
1215rip_redistribute_add (int type, int sub_type, struct prefix_ipv4 *p,
1216 unsigned int ifindex, struct in_addr *nexthop)
1217{
1218 int ret;
1219 struct route_node *rp;
1220 struct rip_info *rinfo;
1221
1222 /* Redistribute route */
1223 ret = rip_destination_check (p->prefix);
1224 if (! ret)
1225 return;
1226
1227 rp = route_node_get (rip->table, (struct prefix *) p);
1228
1229 rinfo = rp->info;
1230
1231 if (rinfo)
1232 {
1233 if (rinfo->type == ZEBRA_ROUTE_CONNECT
1234 && rinfo->sub_type == RIP_ROUTE_INTERFACE
1235 && rinfo->metric != RIP_METRIC_INFINITY)
1236 {
1237 route_unlock_node (rp);
1238 return;
1239 }
1240
1241 /* Manually configured RIP route check. */
1242 if (rinfo->type == ZEBRA_ROUTE_RIP
1243 && rinfo->sub_type == RIP_ROUTE_STATIC)
1244 {
1245 if (type != ZEBRA_ROUTE_RIP || sub_type != RIP_ROUTE_STATIC)
1246 {
1247 route_unlock_node (rp);
1248 return;
1249 }
1250 }
1251
1252 RIP_TIMER_OFF (rinfo->t_timeout);
1253 RIP_TIMER_OFF (rinfo->t_garbage_collect);
1254
1255 if (rip_route_rte (rinfo))
1256 rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p, &rinfo->nexthop,
1257 rinfo->metric);
1258 rp->info = NULL;
1259 rip_info_free (rinfo);
1260
1261 route_unlock_node (rp);
1262 }
1263
1264 rinfo = rip_info_new ();
1265
1266 rinfo->type = type;
1267 rinfo->sub_type = sub_type;
1268 rinfo->ifindex = ifindex;
1269 rinfo->metric = 1;
1270 rinfo->rp = rp;
1271
1272 if (nexthop)
1273 rinfo->nexthop = *nexthop;
1274
1275 rinfo->flags |= RIP_RTF_FIB;
1276 rp->info = rinfo;
1277
1278 rinfo->flags |= RIP_RTF_CHANGED;
1279
1280 rip_event (RIP_TRIGGERED_UPDATE, 0);
1281}
1282
1283/* Delete redistributed route from RIP table. */
1284void
1285rip_redistribute_delete (int type, int sub_type, struct prefix_ipv4 *p,
1286 unsigned int ifindex)
1287{
1288 int ret;
1289 struct route_node *rp;
1290 struct rip_info *rinfo;
1291
1292 ret = rip_destination_check (p->prefix);
1293 if (! ret)
1294 return;
1295
1296 rp = route_node_lookup (rip->table, (struct prefix *) p);
1297 if (rp)
1298 {
1299 rinfo = rp->info;
1300
1301 if (rinfo != NULL
1302 && rinfo->type == type
1303 && rinfo->sub_type == sub_type
1304 && rinfo->ifindex == ifindex)
1305 {
1306 /* Perform poisoned reverse. */
1307 rinfo->metric = RIP_METRIC_INFINITY;
1308 RIP_TIMER_ON (rinfo->t_garbage_collect,
1309 rip_garbage_collect, rip->garbage_time);
1310 RIP_TIMER_OFF (rinfo->t_timeout);
1311 rinfo->flags |= RIP_RTF_CHANGED;
1312
1313 rip_event (RIP_TRIGGERED_UPDATE, 0);
1314 }
1315 }
1316}
1317
1318/* Response to request called from rip_read ().*/
1319void
1320rip_request_process (struct rip_packet *packet, int size,
1321 struct sockaddr_in *from, struct interface *ifp)
1322{
1323 caddr_t lim;
1324 struct rte *rte;
1325 struct prefix_ipv4 p;
1326 struct route_node *rp;
1327 struct rip_info *rinfo;
1328 struct rip_interface *ri;
1329
1330 ri = ifp->info;
1331
1332 /* When passive interface is specified, suppress responses */
1333 if (ri->passive)
1334 return;
1335
1336 /* RIP peer update. */
1337 rip_peer_update (from, packet->version);
1338
1339 lim = ((caddr_t) packet) + size;
1340 rte = packet->rte;
1341
1342 /* The Request is processed entry by entry. If there are no
1343 entries, no response is given. */
1344 if (lim == (caddr_t) rte)
1345 return;
1346
1347 /* There is one special case. If there is exactly one entry in the
1348 request, and it has an address family identifier of zero and a
1349 metric of infinity (i.e., 16), then this is a request to send the
1350 entire routing table. */
1351 if (lim == ((caddr_t) (rte + 1)) &&
1352 ntohs (rte->family) == 0 &&
1353 ntohl (rte->metric) == RIP_METRIC_INFINITY)
1354 {
1355 /* All route with split horizon */
1356 rip_output_process (ifp, from, rip_all_route, packet->version);
1357 }
1358 else
1359 {
1360 /* Examine the list of RTEs in the Request one by one. For each
1361 entry, look up the destination in the router's routing
1362 database and, if there is a route, put that route's metric in
1363 the metric field of the RTE. If there is no explicit route
1364 to the specified destination, put infinity in the metric
1365 field. Once all the entries have been filled in, change the
1366 command from Request to Response and send the datagram back
1367 to the requestor. */
1368 p.family = AF_INET;
1369
1370 for (; ((caddr_t) rte) < lim; rte++)
1371 {
1372 p.prefix = rte->prefix;
1373 p.prefixlen = ip_masklen (rte->mask);
1374 apply_mask_ipv4 (&p);
1375
1376 rp = route_node_lookup (rip->table, (struct prefix *) &p);
1377 if (rp)
1378 {
1379 rinfo = rp->info;
1380 rte->metric = htonl (rinfo->metric);
1381 route_unlock_node (rp);
1382 }
1383 else
1384 rte->metric = htonl (RIP_METRIC_INFINITY);
1385 }
1386 packet->command = RIP_RESPONSE;
1387
1388 rip_send_packet ((caddr_t) packet, size, from, ifp);
1389 }
1390 rip_global_queries++;
1391}
1392
1393#if RIP_RECVMSG
1394/* Set IPv6 packet info to the socket. */
1395static int
1396setsockopt_pktinfo (int sock)
1397{
1398 int ret;
1399 int val = 1;
1400
1401 ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val));
1402 if (ret < 0)
1403 zlog_warn ("Can't setsockopt IP_PKTINFO : %s", strerror (errno));
1404 return ret;
1405}
1406
1407/* Read RIP packet by recvmsg function. */
1408int
1409rip_recvmsg (int sock, u_char *buf, int size, struct sockaddr_in *from,
1410 int *ifindex)
1411{
1412 int ret;
1413 struct msghdr msg;
1414 struct iovec iov;
1415 struct cmsghdr *ptr;
1416 char adata[1024];
1417
1418 msg.msg_name = (void *) from;
1419 msg.msg_namelen = sizeof (struct sockaddr_in);
1420 msg.msg_iov = &iov;
1421 msg.msg_iovlen = 1;
1422 msg.msg_control = (void *) adata;
1423 msg.msg_controllen = sizeof adata;
1424 iov.iov_base = buf;
1425 iov.iov_len = size;
1426
1427 ret = recvmsg (sock, &msg, 0);
1428 if (ret < 0)
1429 return ret;
1430
1431 for (ptr = CMSG_FIRSTHDR(&msg); ptr != NULL; ptr = CMSG_NXTHDR(&msg, ptr))
1432 if (ptr->cmsg_level == IPPROTO_IP && ptr->cmsg_type == IP_PKTINFO)
1433 {
1434 struct in_pktinfo *pktinfo;
1435 int i;
1436
1437 pktinfo = (struct in_pktinfo *) CMSG_DATA (ptr);
1438 i = pktinfo->ipi_ifindex;
1439 }
1440 return ret;
1441}
1442
1443/* RIP packet read function. */
1444int
1445rip_read_new (struct thread *t)
1446{
1447 int ret;
1448 int sock;
1449 char buf[RIP_PACKET_MAXSIZ];
1450 struct sockaddr_in from;
1451 unsigned int ifindex;
1452
1453 /* Fetch socket then register myself. */
1454 sock = THREAD_FD (t);
1455 rip_event (RIP_READ, sock);
1456
1457 /* Read RIP packet. */
1458 ret = rip_recvmsg (sock, buf, RIP_PACKET_MAXSIZ, &from, (int *)&ifindex);
1459 if (ret < 0)
1460 {
1461 zlog_warn ("Can't read RIP packet: %s", strerror (errno));
1462 return ret;
1463 }
1464
1465 return ret;
1466}
1467#endif /* RIP_RECVMSG */
1468
1469/* First entry point of RIP packet. */
1470int
1471rip_read (struct thread *t)
1472{
1473 int sock;
1474 int ret;
1475 int rtenum;
1476 union rip_buf rip_buf;
1477 struct rip_packet *packet;
1478 struct sockaddr_in from;
1479 int fromlen, len;
1480 struct interface *ifp;
1481 struct rip_interface *ri;
1482
1483 /* Fetch socket then register myself. */
1484 sock = THREAD_FD (t);
1485 rip->t_read = NULL;
1486
1487 /* Add myself to tne next event */
1488 rip_event (RIP_READ, sock);
1489
1490 /* RIPd manages only IPv4. */
1491 memset (&from, 0, sizeof (struct sockaddr_in));
1492 fromlen = sizeof (struct sockaddr_in);
1493
1494 len = recvfrom (sock, (char *)&rip_buf.buf, sizeof (rip_buf.buf), 0,
1495 (struct sockaddr *) &from, &fromlen);
1496 if (len < 0)
1497 {
1498 zlog_info ("recvfrom failed: %s", strerror (errno));
1499 return len;
1500 }
1501
1502 /* Check is this packet comming from myself? */
1503 if (if_check_address (from.sin_addr))
1504 {
1505 if (IS_RIP_DEBUG_PACKET)
1506 zlog_warn ("ignore packet comes from myself");
1507 return -1;
1508 }
1509
1510 /* Which interface is this packet comes from. */
1511 ifp = if_lookup_address (from.sin_addr);
1512
1513 /* RIP packet received */
1514 if (IS_RIP_DEBUG_EVENT)
1515 zlog_info ("RECV packet from %s port %d on %s",
1516 inet_ntoa (from.sin_addr), ntohs (from.sin_port),
1517 ifp ? ifp->name : "unknown");
1518
1519 /* If this packet come from unknown interface, ignore it. */
1520 if (ifp == NULL)
1521 {
1522 zlog_info ("packet comes from unknown interface");
1523 return -1;
1524 }
1525
1526 /* Packet length check. */
1527 if (len < RIP_PACKET_MINSIZ)
1528 {
1529 zlog_warn ("packet size %d is smaller than minimum size %d",
1530 len, RIP_PACKET_MINSIZ);
1531 rip_peer_bad_packet (&from);
1532 return len;
1533 }
1534 if (len > RIP_PACKET_MAXSIZ)
1535 {
1536 zlog_warn ("packet size %d is larger than max size %d",
1537 len, RIP_PACKET_MAXSIZ);
1538 rip_peer_bad_packet (&from);
1539 return len;
1540 }
1541
1542 /* Packet alignment check. */
1543 if ((len - RIP_PACKET_MINSIZ) % 20)
1544 {
1545 zlog_warn ("packet size %d is wrong for RIP packet alignment", len);
1546 rip_peer_bad_packet (&from);
1547 return len;
1548 }
1549
1550 /* Set RTE number. */
1551 rtenum = ((len - RIP_PACKET_MINSIZ) / 20);
1552
1553 /* For easy to handle. */
1554 packet = &rip_buf.rip_packet;
1555
1556 /* RIP version check. */
1557 if (packet->version == 0)
1558 {
1559 zlog_info ("version 0 with command %d received.", packet->command);
1560 rip_peer_bad_packet (&from);
1561 return -1;
1562 }
1563
1564 /* Dump RIP packet. */
1565 if (IS_RIP_DEBUG_RECV)
1566 rip_packet_dump (packet, len, "RECV");
1567
1568 /* RIP version adjust. This code should rethink now. RFC1058 says
1569 that "Version 1 implementations are to ignore this extra data and
1570 process only the fields specified in this document.". So RIPv3
1571 packet should be treated as RIPv1 ignoring must be zero field. */
1572 if (packet->version > RIPv2)
1573 packet->version = RIPv2;
1574
1575 /* Is RIP running or is this RIP neighbor ?*/
1576 ri = ifp->info;
1577 if (! ri->running && ! rip_neighbor_lookup (&from))
1578 {
1579 if (IS_RIP_DEBUG_EVENT)
1580 zlog_info ("RIP is not enabled on interface %s.", ifp->name);
1581 rip_peer_bad_packet (&from);
1582 return -1;
1583 }
1584
1585 /* RIP Version check. */
1586 if (packet->command == RIP_RESPONSE)
1587 {
1588 if (ri->ri_receive == RI_RIP_UNSPEC)
1589 {
1590 if (packet->version != rip->version)
1591 {
1592 if (IS_RIP_DEBUG_PACKET)
1593 zlog_warn (" packet's v%d doesn't fit to my version %d",
1594 packet->version, rip->version);
1595 rip_peer_bad_packet (&from);
1596 return -1;
1597 }
1598 }
1599 else
1600 {
1601 if (packet->version == RIPv1)
1602 if (! (ri->ri_receive & RIPv1))
1603 {
1604 if (IS_RIP_DEBUG_PACKET)
1605 zlog_warn (" packet's v%d doesn't fit to if version spec",
1606 packet->version);
1607 rip_peer_bad_packet (&from);
1608 return -1;
1609 }
1610 if (packet->version == RIPv2)
1611 if (! (ri->ri_receive & RIPv2))
1612 {
1613 if (IS_RIP_DEBUG_PACKET)
1614 zlog_warn (" packet's v%d doesn't fit to if version spec",
1615 packet->version);
1616 rip_peer_bad_packet (&from);
1617 return -1;
1618 }
1619 }
1620 }
1621
1622 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1623 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1624 accepted; authenticated RIP-2 messages shall be discarded. */
1625
1626 if ((ri->auth_type == RIP_NO_AUTH)
1627 && rtenum
1628 && (packet->version == RIPv2) && (packet->rte->family == 0xffff))
1629 {
1630 if (IS_RIP_DEBUG_EVENT)
1631 zlog_warn ("packet RIPv%d is dropped because authentication disabled",
1632 packet->version);
1633 rip_peer_bad_packet (&from);
1634 return -1;
1635 }
1636
1637 /* If the router is configured to authenticate RIP-2 messages, then
1638 RIP-1 messages and RIP-2 messages which pass authentication
1639 testing shall be accepted; unauthenticated and failed
1640 authentication RIP-2 messages shall be discarded. For maximum
1641 security, RIP-1 messages should be ignored when authentication is
1642 in use (see section 4.1); otherwise, the routing information from
1643 authenticated messages will be propagated by RIP-1 routers in an
1644 unauthenticated manner. */
1645
1646 if ((ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD
1647 || ri->auth_type == RIP_AUTH_MD5)
1648 && rtenum)
1649 {
1650 /* We follow maximum security. */
1651 if (packet->version == RIPv1 && packet->rte->family == 0xffff)
1652 {
1653 if (IS_RIP_DEBUG_PACKET)
1654 zlog_warn ("packet RIPv%d is dropped because authentication enabled", packet->version);
1655 rip_peer_bad_packet (&from);
1656 return -1;
1657 }
1658
1659 /* Check RIPv2 authentication. */
1660 if (packet->version == RIPv2)
1661 {
1662 if (packet->rte->family == 0xffff)
1663 {
1664 if (ntohs (packet->rte->tag) == RIP_AUTH_SIMPLE_PASSWORD)
1665 {
1666 ret = rip_auth_simple_password (packet->rte, &from, ifp);
1667 if (! ret)
1668 {
1669 if (IS_RIP_DEBUG_EVENT)
1670 zlog_warn ("RIPv2 simple password authentication failed");
1671 rip_peer_bad_packet (&from);
1672 return -1;
1673 }
1674 else
1675 {
1676 if (IS_RIP_DEBUG_EVENT)
1677 zlog_info ("RIPv2 simple password authentication success");
1678 }
1679 }
1680 else if (ntohs (packet->rte->tag) == RIP_AUTH_MD5)
1681 {
1682 ret = rip_auth_md5 (packet, &from, ifp);
1683 if (! ret)
1684 {
1685 if (IS_RIP_DEBUG_EVENT)
1686 zlog_warn ("RIPv2 MD5 authentication failed");
1687 rip_peer_bad_packet (&from);
1688 return -1;
1689 }
1690 else
1691 {
1692 if (IS_RIP_DEBUG_EVENT)
1693 zlog_info ("RIPv2 MD5 authentication success");
1694 }
1695 /* Reset RIP packet length to trim MD5 data. */
1696 len = ret;
1697 }
1698 else
1699 {
1700 if (IS_RIP_DEBUG_EVENT)
1701 zlog_warn ("Unknown authentication type %d",
1702 ntohs (packet->rte->tag));
1703 rip_peer_bad_packet (&from);
1704 return -1;
1705 }
1706 }
1707 else
1708 {
1709 /* There is no authentication in the packet. */
1710 if (ri->auth_str || ri->key_chain)
1711 {
1712 if (IS_RIP_DEBUG_EVENT)
1713 zlog_warn ("RIPv2 authentication failed: no authentication in packet");
1714 rip_peer_bad_packet (&from);
1715 return -1;
1716 }
1717 }
1718 }
1719 }
1720
1721 /* Process each command. */
1722 switch (packet->command)
1723 {
1724 case RIP_RESPONSE:
1725 rip_response_process (packet, len, &from, ifp);
1726 break;
1727 case RIP_REQUEST:
1728 case RIP_POLL:
1729 rip_request_process (packet, len, &from, ifp);
1730 break;
1731 case RIP_TRACEON:
1732 case RIP_TRACEOFF:
1733 zlog_info ("Obsolete command %s received, please sent it to routed",
1734 lookup (rip_msg, packet->command));
1735 rip_peer_bad_packet (&from);
1736 break;
1737 case RIP_POLL_ENTRY:
1738 zlog_info ("Obsolete command %s received",
1739 lookup (rip_msg, packet->command));
1740 rip_peer_bad_packet (&from);
1741 break;
1742 default:
1743 zlog_info ("Unknown RIP command %d received", packet->command);
1744 rip_peer_bad_packet (&from);
1745 break;
1746 }
1747
1748 return len;
1749}
1750
1751/* Make socket for RIP protocol. */
1752int
1753rip_create_socket ()
1754{
1755 int ret;
1756 int sock;
1757 struct sockaddr_in addr;
1758 struct servent *sp;
1759
1760 memset (&addr, 0, sizeof (struct sockaddr_in));
1761
1762 /* Set RIP port. */
1763 sp = getservbyname ("router", "udp");
1764 if (sp)
1765 addr.sin_port = sp->s_port;
1766 else
1767 addr.sin_port = htons (RIP_PORT_DEFAULT);
1768
1769 /* Address shoud be any address. */
1770 addr.sin_family = AF_INET;
1771 addr.sin_addr.s_addr = INADDR_ANY;
1772
1773 /* Make datagram socket. */
1774 sock = socket (AF_INET, SOCK_DGRAM, 0);
1775 if (sock < 0)
1776 {
1777 perror ("socket");
1778 exit (1);
1779 }
1780
1781 sockopt_broadcast (sock);
1782 sockopt_reuseaddr (sock);
1783 sockopt_reuseport (sock);
1784#ifdef RIP_RECVMSG
1785 setsockopt_pktinfo (sock);
1786#endif /* RIP_RECVMSG */
1787
1788 ret = bind (sock, (struct sockaddr *) & addr, sizeof (addr));
1789 if (ret < 0)
1790 {
1791 perror ("bind");
1792 return ret;
1793 }
1794
1795 return sock;
1796}
1797
1798/* Write routing table entry to the stream and return next index of
1799 the routing table entry in the stream. */
1800int
1801rip_write_rte (int num, struct stream *s, struct prefix_ipv4 *p,
1802 u_char version, struct rip_info *rinfo, struct interface *ifp)
1803{
1804 struct in_addr mask;
1805 struct rip_interface *ri;
1806
1807 /* RIP packet header. */
1808 if (num == 0)
1809 {
1810 stream_putc (s, RIP_RESPONSE);
1811 stream_putc (s, version);
1812 stream_putw (s, 0);
1813
1814 /* In case of we need RIPv2 authentication. */
1815 if (version == RIPv2 && ifp)
1816 {
1817 ri = ifp->info;
1818
1819 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1820 {
1821 if (ri->auth_str)
1822 {
1823 stream_putw (s, 0xffff);
1824 stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD);
1825
1826 memset ((s->data + s->putp), 0, 16);
1827 strncpy ((s->data + s->putp), ri->auth_str, 16);
1828 stream_set_putp (s, s->putp + 16);
1829
1830 num++;
1831 }
1832 if (ri->key_chain)
1833 {
1834 struct keychain *keychain;
1835 struct key *key;
1836
1837 keychain = keychain_lookup (ri->key_chain);
1838
1839 if (keychain)
1840 {
1841 key = key_lookup_for_send (keychain);
1842
1843 if (key)
1844 {
1845 stream_putw (s, 0xffff);
1846 stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD);
1847
1848 memset ((s->data + s->putp), 0, 16);
1849 strncpy ((s->data + s->putp), key->string, 16);
1850 stream_set_putp (s, s->putp + 16);
1851
1852 num++;
1853 }
1854 }
1855 }
1856 }
1857 }
1858 }
1859
1860 /* Write routing table entry. */
1861 if (version == RIPv1)
1862 {
1863 stream_putw (s, AF_INET);
1864 stream_putw (s, 0);
1865 stream_put_ipv4 (s, p->prefix.s_addr);
1866 stream_put_ipv4 (s, 0);
1867 stream_put_ipv4 (s, 0);
1868 stream_putl (s, rinfo->metric_out);
1869 }
1870 else
1871 {
1872 masklen2ip (p->prefixlen, &mask);
1873
1874 stream_putw (s, AF_INET);
1875 stream_putw (s, rinfo->tag);
1876 stream_put_ipv4 (s, p->prefix.s_addr);
1877 stream_put_ipv4 (s, mask.s_addr);
1878 stream_put_ipv4 (s, rinfo->nexthop_out.s_addr);
1879 stream_putl (s, rinfo->metric_out);
1880 }
1881
1882 return ++num;
1883}
1884
1885/* Send update to the ifp or spcified neighbor. */
1886void
1887rip_output_process (struct interface *ifp, struct sockaddr_in *to,
1888 int route_type, u_char version)
1889{
1890 int ret;
1891 struct stream *s;
1892 struct route_node *rp;
1893 struct rip_info *rinfo;
1894 struct rip_interface *ri;
1895 struct prefix_ipv4 *p;
1896 struct prefix_ipv4 classfull;
1897 int num;
1898 int rtemax;
1899
1900 /* Logging output event. */
1901 if (IS_RIP_DEBUG_EVENT)
1902 {
1903 if (to)
1904 zlog_info ("update routes to neighbor %s", inet_ntoa (to->sin_addr));
1905 else
1906 zlog_info ("update routes on interface %s ifindex %d",
1907 ifp->name, ifp->ifindex);
1908 }
1909
1910 /* Set output stream. */
1911 s = rip->obuf;
1912
1913 /* Reset stream and RTE counter. */
1914 stream_reset (s);
1915 num = 0;
1916 rtemax = (RIP_PACKET_MAXSIZ - 4) / 20;
1917
1918 /* Get RIP interface. */
1919 ri = ifp->info;
1920
1921 /* If output interface is in simple password authentication mode, we
1922 need space for authentication data. */
1923 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1924 rtemax -= 1;
1925
1926 /* If output interface is in MD5 authentication mode, we need space
1927 for authentication header and data. */
1928 if (ri->auth_type == RIP_AUTH_MD5)
1929 rtemax -= 2;
1930
1931 /* If output interface is in simple password authentication mode
1932 and string or keychain is specified we need space for auth. data */
1933 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1934 {
1935 if (ri->key_chain)
1936 {
1937 struct keychain *keychain;
1938
1939 keychain = keychain_lookup (ri->key_chain);
1940 if (keychain)
1941 if (key_lookup_for_send (keychain))
1942 rtemax -=1;
1943 }
1944 else
1945 if (ri->auth_str)
1946 rtemax -=1;
1947 }
1948
1949 for (rp = route_top (rip->table); rp; rp = route_next (rp))
1950 if ((rinfo = rp->info) != NULL)
1951 {
1952 /* Some inheritance stuff: */
1953 /* Before we process with ipv4 prefix we should mask it */
1954 /* with Classful mask if we send RIPv1 packet.That's because */
1955 /* user could set non-classful mask or we could get it by RIPv2 */
1956 /* or other protocol. checked with Cisco's way of life :) */
1957
1958 if (version == RIPv1)
1959 {
1960 memcpy (&classfull, &rp->p, sizeof (struct prefix_ipv4));
1961
1962 if (IS_RIP_DEBUG_PACKET)
1963 zlog_info("%s/%d before RIPv1 mask check ",
1964 inet_ntoa (classfull.prefix), classfull.prefixlen);
1965
1966 apply_classful_mask_ipv4 (&classfull);
1967 p = &classfull;
1968
1969 if (IS_RIP_DEBUG_PACKET)
1970 zlog_info("%s/%d after RIPv1 mask check",
1971 inet_ntoa (p->prefix), p->prefixlen);
1972 }
1973 else
1974 p = (struct prefix_ipv4 *) &rp->p;
1975
1976 /* Apply output filters. */
1977 ret = rip_outgoing_filter (p, ri);
1978 if (ret < 0)
1979 continue;
1980
1981 /* Changed route only output. */
1982 if (route_type == rip_changed_route &&
1983 (! (rinfo->flags & RIP_RTF_CHANGED)))
1984 continue;
1985
1986 /* Split horizon. */
1987 /* if (split_horizon == rip_split_horizon) */
1988 if (ri->split_horizon)
1989 {
1990 /* We perform split horizon for RIP and connected route. */
1991 if ((rinfo->type == ZEBRA_ROUTE_RIP ||
1992 rinfo->type == ZEBRA_ROUTE_CONNECT) &&
1993 rinfo->ifindex == ifp->ifindex)
1994 continue;
1995 }
1996
1997 /* Preparation for route-map. */
1998 rinfo->metric_set = 0;
1999 rinfo->nexthop_out.s_addr = 0;
2000 rinfo->metric_out = rinfo->metric;
2001 rinfo->ifindex_out = ifp->ifindex;
2002
2003 /* In order to avoid some local loops, if the RIP route has a
2004 nexthop via this interface, keep the nexthop, otherwise set
2005 it to 0. The nexthop should not be propagated beyond the
2006 local broadcast/multicast area in order to avoid an IGP
2007 multi-level recursive look-up. For RIP and connected
2008 route, we don't set next hop value automatically. For
2009 settting next hop to those routes, please use
2010 route-map. */
2011
2012 if (rinfo->type != ZEBRA_ROUTE_RIP
2013 && rinfo->type != ZEBRA_ROUTE_CONNECT
2014 && rinfo->ifindex == ifp->ifindex)
2015 rinfo->nexthop_out = rinfo->nexthop;
2016
2017 /* Apply route map - continue, if deny */
2018 if (rip->route_map[rinfo->type].name
2019 && rinfo->sub_type != RIP_ROUTE_INTERFACE)
2020 {
2021 ret = route_map_apply (rip->route_map[rinfo->type].map,
2022 (struct prefix *)p, RMAP_RIP, rinfo);
2023
2024 if (ret == RMAP_DENYMATCH)
2025 {
2026 if (IS_RIP_DEBUG_PACKET)
2027 zlog_info ("%s/%d is filtered by route-map",
2028 inet_ntoa (p->prefix), p->prefixlen);
2029 continue;
2030 }
2031 }
2032
2033 /* When route-map does not set metric. */
2034 if (! rinfo->metric_set)
2035 {
2036 /* If redistribute metric is set. */
2037 if (rip->route_map[rinfo->type].metric_config
2038 && rinfo->metric != RIP_METRIC_INFINITY)
2039 {
2040 rinfo->metric_out = rip->route_map[rinfo->type].metric;
2041 }
2042 else
2043 {
2044 /* If the route is not connected or localy generated
2045 one, use default-metric value*/
2046 if (rinfo->type != ZEBRA_ROUTE_RIP
2047 && rinfo->type != ZEBRA_ROUTE_CONNECT
2048 && rinfo->metric != RIP_METRIC_INFINITY)
2049 rinfo->metric_out = rip->default_metric;
2050 }
2051 }
2052
2053 /* Apply offset-list */
2054 if (rinfo->metric != RIP_METRIC_INFINITY)
2055 rip_offset_list_apply_out (p, ifp, &rinfo->metric_out);
2056
2057 if (rinfo->metric_out > RIP_METRIC_INFINITY)
2058 rinfo->metric_out = RIP_METRIC_INFINITY;
2059
2060 /* Write RTE to the stream. */
2061 num = rip_write_rte (num, s, p, version, rinfo, to ? NULL : ifp);
2062 if (num == rtemax)
2063 {
2064 if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
2065 rip_auth_md5_set (s, ifp);
2066
2067 ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s),
2068 to, ifp);
2069
2070 if (ret >= 0 && IS_RIP_DEBUG_SEND)
2071 rip_packet_dump ((struct rip_packet *)STREAM_DATA (s),
2072 stream_get_endp(s), "SEND");
2073 num = 0;
2074 stream_reset (s);
2075 }
2076 }
2077
2078 /* Flush unwritten RTE. */
2079 if (num != 0)
2080 {
2081 if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
2082 rip_auth_md5_set (s, ifp);
2083
2084 ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s), to, ifp);
2085
2086 if (ret >= 0 && IS_RIP_DEBUG_SEND)
2087 rip_packet_dump ((struct rip_packet *)STREAM_DATA (s),
2088 stream_get_endp (s), "SEND");
2089 num = 0;
2090 stream_reset (s);
2091 }
2092
2093 /* Statistics updates. */
2094 ri->sent_updates++;
2095}
2096
2097/* Send RIP packet to the interface. */
2098void
2099rip_update_interface (struct interface *ifp, u_char version, int route_type)
2100{
2101 struct prefix_ipv4 *p;
2102 struct connected *connected;
2103 listnode node;
2104 struct sockaddr_in to;
2105
2106 /* When RIP version is 2 and multicast enable interface. */
2107 if (version == RIPv2 && if_is_multicast (ifp))
2108 {
2109 if (IS_RIP_DEBUG_EVENT)
2110 zlog_info ("multicast announce on %s ", ifp->name);
2111
2112 rip_output_process (ifp, NULL, route_type, version);
2113 return;
2114 }
2115
2116 /* If we can't send multicast packet, send it with unicast. */
2117 if (if_is_broadcast (ifp) || if_is_pointopoint (ifp))
2118 {
2119 for (node = listhead (ifp->connected); node; nextnode (node))
2120 {
2121 connected = getdata (node);
2122
2123 /* Fetch broadcast address or poin-to-point destination
2124 address . */
2125 p = (struct prefix_ipv4 *) connected->destination;
2126
2127 if (p->family == AF_INET)
2128 {
2129 /* Destination address and port setting. */
2130 memset (&to, 0, sizeof (struct sockaddr_in));
2131 to.sin_addr = p->prefix;
2132 to.sin_port = htons (RIP_PORT_DEFAULT);
2133
2134 if (IS_RIP_DEBUG_EVENT)
2135 zlog_info ("%s announce to %s on %s",
2136 if_is_pointopoint (ifp) ? "unicast" : "broadcast",
2137 inet_ntoa (to.sin_addr), ifp->name);
2138
2139 rip_output_process (ifp, &to, route_type, version);
2140 }
2141 }
2142 }
2143}
2144
2145/* Update send to all interface and neighbor. */
2146void
2147rip_update_process (int route_type)
2148{
2149 listnode node;
2150 struct interface *ifp;
2151 struct rip_interface *ri;
2152 struct route_node *rp;
2153 struct sockaddr_in to;
2154 struct prefix_ipv4 *p;
2155
2156 /* Send RIP update to each interface. */
2157 for (node = listhead (iflist); node; nextnode (node))
2158 {
2159 ifp = getdata (node);
2160
2161 if (if_is_loopback (ifp))
2162 continue;
2163
2164 if (! if_is_up (ifp))
2165 continue;
2166
2167 /* Fetch RIP interface information. */
2168 ri = ifp->info;
2169
2170 /* When passive interface is specified, suppress announce to the
2171 interface. */
2172 if (ri->passive)
2173 continue;
2174
2175 if (ri->running)
2176 {
2177 if (IS_RIP_DEBUG_EVENT)
2178 {
2179 if (ifp->name)
2180 zlog_info ("SEND UPDATE to %s ifindex %d",
2181 ifp->name, ifp->ifindex);
2182 else
2183 zlog_info ("SEND UPDATE to _unknown_ ifindex %d",
2184 ifp->ifindex);
2185 }
2186
2187 /* If there is no version configuration in the interface,
2188 use rip's version setting. */
2189 if (ri->ri_send == RI_RIP_UNSPEC)
2190 {
2191 if (rip->version == RIPv1)
2192 rip_update_interface (ifp, RIPv1, route_type);
2193 else
2194 rip_update_interface (ifp, RIPv2, route_type);
2195 }
2196 /* If interface has RIP version configuration use it. */
2197 else
2198 {
2199 if (ri->ri_send & RIPv1)
2200 rip_update_interface (ifp, RIPv1, route_type);
2201 if (ri->ri_send & RIPv2)
2202 rip_update_interface (ifp, RIPv2, route_type);
2203 }
2204 }
2205 }
2206
2207 /* RIP send updates to each neighbor. */
2208 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
2209 if (rp->info != NULL)
2210 {
2211 p = (struct prefix_ipv4 *) &rp->p;
2212
2213 ifp = if_lookup_address (p->prefix);
2214 if (! ifp)
2215 {
2216 zlog_warn ("Neighbor %s doesn't exist direct connected network",
2217 inet_ntoa (p->prefix));
2218 continue;
2219 }
2220
2221 /* Set destination address and port */
2222 memset (&to, 0, sizeof (struct sockaddr_in));
2223 to.sin_addr = p->prefix;
2224 to.sin_port = htons (RIP_PORT_DEFAULT);
2225
2226 /* RIP version is rip's configuration. */
2227 rip_output_process (ifp, &to, route_type, rip->version);
2228 }
2229}
2230
2231/* RIP's periodical timer. */
2232int
2233rip_update (struct thread *t)
2234{
2235 /* Clear timer pointer. */
2236 rip->t_update = NULL;
2237
2238 if (IS_RIP_DEBUG_EVENT)
2239 zlog_info ("update timer fire!");
2240
2241 /* Process update output. */
2242 rip_update_process (rip_all_route);
2243
2244 /* Triggered updates may be suppressed if a regular update is due by
2245 the time the triggered update would be sent. */
2246 if (rip->t_triggered_interval)
2247 {
2248 thread_cancel (rip->t_triggered_interval);
2249 rip->t_triggered_interval = NULL;
2250 }
2251 rip->trigger = 0;
2252
2253 /* Register myself. */
2254 rip_event (RIP_UPDATE_EVENT, 0);
2255
2256 return 0;
2257}
2258
2259/* Walk down the RIP routing table then clear changed flag. */
2260void
2261rip_clear_changed_flag ()
2262{
2263 struct route_node *rp;
2264 struct rip_info *rinfo;
2265
2266 for (rp = route_top (rip->table); rp; rp = route_next (rp))
2267 if ((rinfo = rp->info) != NULL)
2268 if (rinfo->flags & RIP_RTF_CHANGED)
2269 rinfo->flags &= ~RIP_RTF_CHANGED;
2270}
2271
2272/* Triggered update interval timer. */
2273int
2274rip_triggered_interval (struct thread *t)
2275{
2276 int rip_triggered_update (struct thread *);
2277
2278 rip->t_triggered_interval = NULL;
2279
2280 if (rip->trigger)
2281 {
2282 rip->trigger = 0;
2283 rip_triggered_update (t);
2284 }
2285 return 0;
2286}
2287
2288/* Execute triggered update. */
2289int
2290rip_triggered_update (struct thread *t)
2291{
2292 int interval;
2293
2294 /* Clear thred pointer. */
2295 rip->t_triggered_update = NULL;
2296
2297 /* Cancel interval timer. */
2298 if (rip->t_triggered_interval)
2299 {
2300 thread_cancel (rip->t_triggered_interval);
2301 rip->t_triggered_interval = NULL;
2302 }
2303 rip->trigger = 0;
2304
2305 /* Logging triggered update. */
2306 if (IS_RIP_DEBUG_EVENT)
2307 zlog_info ("triggered update!");
2308
2309 /* Split Horizon processing is done when generating triggered
2310 updates as well as normal updates (see section 2.6). */
2311 rip_update_process (rip_changed_route);
2312
2313 /* Once all of the triggered updates have been generated, the route
2314 change flags should be cleared. */
2315 rip_clear_changed_flag ();
2316
2317 /* After a triggered update is sent, a timer should be set for a
2318 random interval between 1 and 5 seconds. If other changes that
2319 would trigger updates occur before the timer expires, a single
2320 update is triggered when the timer expires. */
2321 interval = (random () % 5) + 1;
2322
2323 rip->t_triggered_interval =
2324 thread_add_timer (master, rip_triggered_interval, NULL, interval);
2325
2326 return 0;
2327}
2328
2329/* Withdraw redistributed route. */
2330void
2331rip_redistribute_withdraw (int type)
2332{
2333 struct route_node *rp;
2334 struct rip_info *rinfo;
2335
2336 if (!rip)
2337 return;
2338
2339 for (rp = route_top (rip->table); rp; rp = route_next (rp))
2340 if ((rinfo = rp->info) != NULL)
2341 {
2342 if (rinfo->type == type
2343 && rinfo->sub_type != RIP_ROUTE_INTERFACE)
2344 {
2345 /* Perform poisoned reverse. */
2346 rinfo->metric = RIP_METRIC_INFINITY;
2347 RIP_TIMER_ON (rinfo->t_garbage_collect,
2348 rip_garbage_collect, rip->garbage_time);
2349 RIP_TIMER_OFF (rinfo->t_timeout);
2350 rinfo->flags |= RIP_RTF_CHANGED;
2351
2352 rip_event (RIP_TRIGGERED_UPDATE, 0);
2353 }
2354 }
2355}
2356
2357/* Create new RIP instance and set it to global variable. */
2358int
2359rip_create ()
2360{
2361 rip = XMALLOC (MTYPE_RIP, sizeof (struct rip));
2362 memset (rip, 0, sizeof (struct rip));
2363
2364 /* Set initial value. */
2365 rip->version = RIPv2;
2366 rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
2367 rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
2368 rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
2369 rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
2370
2371 /* Initialize RIP routig table. */
2372 rip->table = route_table_init ();
2373 rip->route = route_table_init ();
2374 rip->neighbor = route_table_init ();
2375
2376 /* Make output stream. */
2377 rip->obuf = stream_new (1500);
2378
2379 /* Make socket. */
2380 rip->sock = rip_create_socket ();
2381 if (rip->sock < 0)
2382 return rip->sock;
2383
2384 /* Create read and timer thread. */
2385 rip_event (RIP_READ, rip->sock);
2386 rip_event (RIP_UPDATE_EVENT, 1);
2387
2388 return 0;
2389}
2390
2391/* Sned RIP request to the destination. */
2392int
2393rip_request_send (struct sockaddr_in *to, struct interface *ifp,
2394 u_char version)
2395{
2396 struct rte *rte;
2397 struct rip_packet rip_packet;
2398
2399 memset (&rip_packet, 0, sizeof (rip_packet));
2400
2401 rip_packet.command = RIP_REQUEST;
2402 rip_packet.version = version;
2403 rte = rip_packet.rte;
2404 rte->metric = htonl (RIP_METRIC_INFINITY);
2405
2406 return rip_send_packet ((caddr_t) &rip_packet, sizeof (rip_packet), to, ifp);
2407}
2408
2409int
2410rip_update_jitter (unsigned long time)
2411{
2412 return ((rand () % (time + 1)) - (time / 2));
2413}
2414
2415void
2416rip_event (enum rip_event event, int sock)
2417{
2418 int jitter = 0;
2419
2420 switch (event)
2421 {
2422 case RIP_READ:
2423 rip->t_read = thread_add_read (master, rip_read, NULL, sock);
2424 break;
2425 case RIP_UPDATE_EVENT:
2426 if (rip->t_update)
2427 {
2428 thread_cancel (rip->t_update);
2429 rip->t_update = NULL;
2430 }
2431 jitter = rip_update_jitter (rip->update_time);
2432 rip->t_update =
2433 thread_add_timer (master, rip_update, NULL,
2434 sock ? 2 : rip->update_time + jitter);
2435 break;
2436 case RIP_TRIGGERED_UPDATE:
2437 if (rip->t_triggered_interval)
2438 rip->trigger = 1;
2439 else if (! rip->t_triggered_update)
2440 rip->t_triggered_update =
2441 thread_add_event (master, rip_triggered_update, NULL, 0);
2442 break;
2443 default:
2444 break;
2445 }
2446}
2447
2448DEFUN (router_rip,
2449 router_rip_cmd,
2450 "router rip",
2451 "Enable a routing process\n"
2452 "Routing Information Protocol (RIP)\n")
2453{
2454 int ret;
2455
2456 /* If rip is not enabled before. */
2457 if (! rip)
2458 {
2459 ret = rip_create ();
2460 if (ret < 0)
2461 {
2462 zlog_info ("Can't create RIP");
2463 return CMD_WARNING;
2464 }
2465 }
2466 vty->node = RIP_NODE;
2467 vty->index = rip;
2468
2469 return CMD_SUCCESS;
2470}
2471
2472DEFUN (no_router_rip,
2473 no_router_rip_cmd,
2474 "no router rip",
2475 NO_STR
2476 "Enable a routing process\n"
2477 "Routing Information Protocol (RIP)\n")
2478{
2479 if (rip)
2480 rip_clean ();
2481 return CMD_SUCCESS;
2482}
2483
2484DEFUN (rip_version,
2485 rip_version_cmd,
2486 "version <1-2>",
2487 "Set routing protocol version\n"
2488 "version\n")
2489{
2490 int version;
2491
2492 version = atoi (argv[0]);
2493 if (version != RIPv1 && version != RIPv2)
2494 {
2495 vty_out (vty, "invalid rip version %d%s", version,
2496 VTY_NEWLINE);
2497 return CMD_WARNING;
2498 }
2499 rip->version = version;
2500
2501 return CMD_SUCCESS;
2502}
2503
2504DEFUN (no_rip_version,
2505 no_rip_version_cmd,
2506 "no version",
2507 NO_STR
2508 "Set routing protocol version\n")
2509{
2510 /* Set RIP version to the default. */
2511 rip->version = RIPv2;
2512
2513 return CMD_SUCCESS;
2514}
2515
2516ALIAS (no_rip_version,
2517 no_rip_version_val_cmd,
2518 "no version <1-2>",
2519 NO_STR
2520 "Set routing protocol version\n"
2521 "version\n")
2522
2523DEFUN (rip_route,
2524 rip_route_cmd,
2525 "route A.B.C.D/M",
2526 "RIP static route configuration\n"
2527 "IP prefix <network>/<length>\n")
2528{
2529 int ret;
2530 struct prefix_ipv4 p;
2531 struct route_node *node;
2532
2533 ret = str2prefix_ipv4 (argv[0], &p);
2534 if (ret < 0)
2535 {
2536 vty_out (vty, "Malformed address%s", VTY_NEWLINE);
2537 return CMD_WARNING;
2538 }
2539 apply_mask_ipv4 (&p);
2540
2541 /* For router rip configuration. */
2542 node = route_node_get (rip->route, (struct prefix *) &p);
2543
2544 if (node->info)
2545 {
2546 vty_out (vty, "There is already same static route.%s", VTY_NEWLINE);
2547 route_unlock_node (node);
2548 return CMD_WARNING;
2549 }
2550
2551 node->info = "static";
2552
2553 rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0, NULL);
2554
2555 return CMD_SUCCESS;
2556}
2557
2558DEFUN (no_rip_route,
2559 no_rip_route_cmd,
2560 "no route A.B.C.D/M",
2561 NO_STR
2562 "RIP static route configuration\n"
2563 "IP prefix <network>/<length>\n")
2564{
2565 int ret;
2566 struct prefix_ipv4 p;
2567 struct route_node *node;
2568
2569 ret = str2prefix_ipv4 (argv[0], &p);
2570 if (ret < 0)
2571 {
2572 vty_out (vty, "Malformed address%s", VTY_NEWLINE);
2573 return CMD_WARNING;
2574 }
2575 apply_mask_ipv4 (&p);
2576
2577 /* For router rip configuration. */
2578 node = route_node_lookup (rip->route, (struct prefix *) &p);
2579 if (! node)
2580 {
2581 vty_out (vty, "Can't find route %s.%s", argv[0],
2582 VTY_NEWLINE);
2583 return CMD_WARNING;
2584 }
2585
2586 rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
2587 route_unlock_node (node);
2588
2589 node->info = NULL;
2590 route_unlock_node (node);
2591
2592 return CMD_SUCCESS;
2593}
2594
2595void
2596rip_update_default_metric ()
2597{
2598 struct route_node *np;
2599 struct rip_info *rinfo;
2600
2601 for (np = route_top (rip->table); np; np = route_next (np))
2602 if ((rinfo = np->info) != NULL)
2603 if (rinfo->type != ZEBRA_ROUTE_RIP && rinfo->type != ZEBRA_ROUTE_CONNECT)
2604 rinfo->metric = rip->default_metric;
2605}
2606
2607DEFUN (rip_default_metric,
2608 rip_default_metric_cmd,
2609 "default-metric <1-16>",
2610 "Set a metric of redistribute routes\n"
2611 "Default metric\n")
2612{
2613 if (rip)
2614 {
2615 rip->default_metric = atoi (argv[0]);
2616 /* rip_update_default_metric (); */
2617 }
2618 return CMD_SUCCESS;
2619}
2620
2621DEFUN (no_rip_default_metric,
2622 no_rip_default_metric_cmd,
2623 "no default-metric",
2624 NO_STR
2625 "Set a metric of redistribute routes\n"
2626 "Default metric\n")
2627{
2628 if (rip)
2629 {
2630 rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
2631 /* rip_update_default_metric (); */
2632 }
2633 return CMD_SUCCESS;
2634}
2635
2636ALIAS (no_rip_default_metric,
2637 no_rip_default_metric_val_cmd,
2638 "no default-metric <1-16>",
2639 NO_STR
2640 "Set a metric of redistribute routes\n"
2641 "Default metric\n")
2642
2643DEFUN (rip_timers,
2644 rip_timers_cmd,
2645 "timers basic <5-2147483647> <5-2147483647> <5-2147483647>",
2646 "Adjust routing timers\n"
2647 "Basic routing protocol update timers\n"
2648 "Routing table update timer value in second. Default is 30.\n"
2649 "Routing information timeout timer. Default is 180.\n"
2650 "Garbage collection timer. Default is 120.\n")
2651{
2652 unsigned long update;
2653 unsigned long timeout;
2654 unsigned long garbage;
2655 char *endptr = NULL;
2656 unsigned long RIP_TIMER_MAX = 2147483647;
2657 unsigned long RIP_TIMER_MIN = 5;
2658
2659 update = strtoul (argv[0], &endptr, 10);
2660 if (update > RIP_TIMER_MAX || update < RIP_TIMER_MIN || *endptr != '\0')
2661 {
2662 vty_out (vty, "update timer value error%s", VTY_NEWLINE);
2663 return CMD_WARNING;
2664 }
2665
2666 timeout = strtoul (argv[1], &endptr, 10);
2667 if (timeout > RIP_TIMER_MAX || timeout < RIP_TIMER_MIN || *endptr != '\0')
2668 {
2669 vty_out (vty, "timeout timer value error%s", VTY_NEWLINE);
2670 return CMD_WARNING;
2671 }
2672
2673 garbage = strtoul (argv[2], &endptr, 10);
2674 if (garbage > RIP_TIMER_MAX || garbage < RIP_TIMER_MIN || *endptr != '\0')
2675 {
2676 vty_out (vty, "garbage timer value error%s", VTY_NEWLINE);
2677 return CMD_WARNING;
2678 }
2679
2680 /* Set each timer value. */
2681 rip->update_time = update;
2682 rip->timeout_time = timeout;
2683 rip->garbage_time = garbage;
2684
2685 /* Reset update timer thread. */
2686 rip_event (RIP_UPDATE_EVENT, 0);
2687
2688 return CMD_SUCCESS;
2689}
2690
2691DEFUN (no_rip_timers,
2692 no_rip_timers_cmd,
2693 "no timers basic",
2694 NO_STR
2695 "Adjust routing timers\n"
2696 "Basic routing protocol update timers\n")
2697{
2698 /* Set each timer value to the default. */
2699 rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
2700 rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
2701 rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
2702
2703 /* Reset update timer thread. */
2704 rip_event (RIP_UPDATE_EVENT, 0);
2705
2706 return CMD_SUCCESS;
2707}
2708
2709struct route_table *rip_distance_table;
2710
2711struct rip_distance
2712{
2713 /* Distance value for the IP source prefix. */
2714 u_char distance;
2715
2716 /* Name of the access-list to be matched. */
2717 char *access_list;
2718};
2719
2720struct rip_distance *
2721rip_distance_new ()
2722{
2723 struct rip_distance *new;
2724 new = XMALLOC (MTYPE_RIP_DISTANCE, sizeof (struct rip_distance));
2725 memset (new, 0, sizeof (struct rip_distance));
2726 return new;
2727}
2728
2729void
2730rip_distance_free (struct rip_distance *rdistance)
2731{
2732 XFREE (MTYPE_RIP_DISTANCE, rdistance);
2733}
2734
2735int
2736rip_distance_set (struct vty *vty, char *distance_str, char *ip_str,
2737 char *access_list_str)
2738{
2739 int ret;
2740 struct prefix_ipv4 p;
2741 u_char distance;
2742 struct route_node *rn;
2743 struct rip_distance *rdistance;
2744
2745 ret = str2prefix_ipv4 (ip_str, &p);
2746 if (ret == 0)
2747 {
2748 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
2749 return CMD_WARNING;
2750 }
2751
2752 distance = atoi (distance_str);
2753
2754 /* Get RIP distance node. */
2755 rn = route_node_get (rip_distance_table, (struct prefix *) &p);
2756 if (rn->info)
2757 {
2758 rdistance = rn->info;
2759 route_unlock_node (rn);
2760 }
2761 else
2762 {
2763 rdistance = rip_distance_new ();
2764 rn->info = rdistance;
2765 }
2766
2767 /* Set distance value. */
2768 rdistance->distance = distance;
2769
2770 /* Reset access-list configuration. */
2771 if (rdistance->access_list)
2772 {
2773 free (rdistance->access_list);
2774 rdistance->access_list = NULL;
2775 }
2776 if (access_list_str)
2777 rdistance->access_list = strdup (access_list_str);
2778
2779 return CMD_SUCCESS;
2780}
2781
2782int
2783rip_distance_unset (struct vty *vty, char *distance_str, char *ip_str,
2784 char *access_list_str)
2785{
2786 int ret;
2787 struct prefix_ipv4 p;
2788 u_char distance;
2789 struct route_node *rn;
2790 struct rip_distance *rdistance;
2791
2792 ret = str2prefix_ipv4 (ip_str, &p);
2793 if (ret == 0)
2794 {
2795 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
2796 return CMD_WARNING;
2797 }
2798
2799 distance = atoi (distance_str);
2800
2801 rn = route_node_lookup (rip_distance_table, (struct prefix *)&p);
2802 if (! rn)
2803 {
2804 vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
2805 return CMD_WARNING;
2806 }
2807
2808 rdistance = rn->info;
2809
2810 if (rdistance->access_list)
2811 free (rdistance->access_list);
2812 rip_distance_free (rdistance);
2813
2814 rn->info = NULL;
2815 route_unlock_node (rn);
2816 route_unlock_node (rn);
2817
2818 return CMD_SUCCESS;
2819}
2820
2821void
2822rip_distance_reset ()
2823{
2824 struct route_node *rn;
2825 struct rip_distance *rdistance;
2826
2827 for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
2828 if ((rdistance = rn->info) != NULL)
2829 {
2830 if (rdistance->access_list)
2831 free (rdistance->access_list);
2832 rip_distance_free (rdistance);
2833 rn->info = NULL;
2834 route_unlock_node (rn);
2835 }
2836}
2837
2838/* Apply RIP information to distance method. */
2839u_char
2840rip_distance_apply (struct rip_info *rinfo)
2841{
2842 struct route_node *rn;
2843 struct prefix_ipv4 p;
2844 struct rip_distance *rdistance;
2845 struct access_list *alist;
2846
2847 if (! rip)
2848 return 0;
2849
2850 memset (&p, 0, sizeof (struct prefix_ipv4));
2851 p.family = AF_INET;
2852 p.prefix = rinfo->from;
2853 p.prefixlen = IPV4_MAX_BITLEN;
2854
2855 /* Check source address. */
2856 rn = route_node_match (rip_distance_table, (struct prefix *) &p);
2857 if (rn)
2858 {
2859 rdistance = rn->info;
2860 route_unlock_node (rn);
2861
2862 if (rdistance->access_list)
2863 {
2864 alist = access_list_lookup (AFI_IP, rdistance->access_list);
2865 if (alist == NULL)
2866 return 0;
2867 if (access_list_apply (alist, &rinfo->rp->p) == FILTER_DENY)
2868 return 0;
2869
2870 return rdistance->distance;
2871 }
2872 else
2873 return rdistance->distance;
2874 }
2875
2876 if (rip->distance)
2877 return rip->distance;
2878
2879 return 0;
2880}
2881
2882void
2883rip_distance_show (struct vty *vty)
2884{
2885 struct route_node *rn;
2886 struct rip_distance *rdistance;
2887 int header = 1;
2888 char buf[BUFSIZ];
2889
2890 vty_out (vty, " Distance: (default is %d)%s",
2891 rip->distance ? rip->distance :ZEBRA_RIP_DISTANCE_DEFAULT,
2892 VTY_NEWLINE);
2893
2894 for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
2895 if ((rdistance = rn->info) != NULL)
2896 {
2897 if (header)
2898 {
2899 vty_out (vty, " Address Distance List%s",
2900 VTY_NEWLINE);
2901 header = 0;
2902 }
2903 sprintf (buf, "%s/%d", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
2904 vty_out (vty, " %-20s %4d %s%s",
2905 buf, rdistance->distance,
2906 rdistance->access_list ? rdistance->access_list : "",
2907 VTY_NEWLINE);
2908 }
2909}
2910
2911DEFUN (rip_distance,
2912 rip_distance_cmd,
2913 "distance <1-255>",
2914 "Administrative distance\n"
2915 "Distance value\n")
2916{
2917 rip->distance = atoi (argv[0]);
2918 return CMD_SUCCESS;
2919}
2920
2921DEFUN (no_rip_distance,
2922 no_rip_distance_cmd,
2923 "no distance <1-255>",
2924 NO_STR
2925 "Administrative distance\n"
2926 "Distance value\n")
2927{
2928 rip->distance = 0;
2929 return CMD_SUCCESS;
2930}
2931
2932DEFUN (rip_distance_source,
2933 rip_distance_source_cmd,
2934 "distance <1-255> A.B.C.D/M",
2935 "Administrative distance\n"
2936 "Distance value\n"
2937 "IP source prefix\n")
2938{
2939 rip_distance_set (vty, argv[0], argv[1], NULL);
2940 return CMD_SUCCESS;
2941}
2942
2943DEFUN (no_rip_distance_source,
2944 no_rip_distance_source_cmd,
2945 "no distance <1-255> A.B.C.D/M",
2946 NO_STR
2947 "Administrative distance\n"
2948 "Distance value\n"
2949 "IP source prefix\n")
2950{
2951 rip_distance_unset (vty, argv[0], argv[1], NULL);
2952 return CMD_SUCCESS;
2953}
2954
2955DEFUN (rip_distance_source_access_list,
2956 rip_distance_source_access_list_cmd,
2957 "distance <1-255> A.B.C.D/M WORD",
2958 "Administrative distance\n"
2959 "Distance value\n"
2960 "IP source prefix\n"
2961 "Access list name\n")
2962{
2963 rip_distance_set (vty, argv[0], argv[1], argv[2]);
2964 return CMD_SUCCESS;
2965}
2966
2967DEFUN (no_rip_distance_source_access_list,
2968 no_rip_distance_source_access_list_cmd,
2969 "no distance <1-255> A.B.C.D/M WORD",
2970 NO_STR
2971 "Administrative distance\n"
2972 "Distance value\n"
2973 "IP source prefix\n"
2974 "Access list name\n")
2975{
2976 rip_distance_unset (vty, argv[0], argv[1], argv[2]);
2977 return CMD_SUCCESS;
2978}
2979
2980/* Print out routes update time. */
2981void
2982rip_vty_out_uptime (struct vty *vty, struct rip_info *rinfo)
2983{
2984 struct timeval timer_now;
2985 time_t clock;
2986 struct tm *tm;
2987#define TIME_BUF 25
2988 char timebuf [TIME_BUF];
2989 struct thread *thread;
2990
2991 gettimeofday (&timer_now, NULL);
2992
2993 if ((thread = rinfo->t_timeout) != NULL)
2994 {
2995 clock = thread->u.sands.tv_sec - timer_now.tv_sec;
2996 tm = gmtime (&clock);
2997 strftime (timebuf, TIME_BUF, "%M:%S", tm);
2998 vty_out (vty, "%5s", timebuf);
2999 }
3000 else if ((thread = rinfo->t_garbage_collect) != NULL)
3001 {
3002 clock = thread->u.sands.tv_sec - timer_now.tv_sec;
3003 tm = gmtime (&clock);
3004 strftime (timebuf, TIME_BUF, "%M:%S", tm);
3005 vty_out (vty, "%5s", timebuf);
3006 }
3007}
3008
3009char *
3010rip_route_type_print (int sub_type)
3011{
3012 switch (sub_type)
3013 {
3014 case RIP_ROUTE_RTE:
3015 return "n";
3016 case RIP_ROUTE_STATIC:
3017 return "s";
3018 case RIP_ROUTE_DEFAULT:
3019 return "d";
3020 case RIP_ROUTE_REDISTRIBUTE:
3021 return "r";
3022 case RIP_ROUTE_INTERFACE:
3023 return "i";
3024 default:
3025 return "?";
3026 }
3027}
3028
3029DEFUN (show_ip_rip,
3030 show_ip_rip_cmd,
3031 "show ip rip",
3032 SHOW_STR
3033 IP_STR
3034 "Show RIP routes\n")
3035{
3036 struct route_node *np;
3037 struct rip_info *rinfo;
3038
3039 if (! rip)
3040 return CMD_SUCCESS;
3041
3042 vty_out (vty, "Codes: R - RIP, C - connected, O - OSPF, B - BGP%s"
3043 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,%s"
3044 " (i) - interface%s%s"
3045 " Network Next Hop Metric From Time%s",
3046 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
3047
3048 for (np = route_top (rip->table); np; np = route_next (np))
3049 if ((rinfo = np->info) != NULL)
3050 {
3051 int len;
3052
3053 len = vty_out (vty, "%s(%s) %s/%d",
3054 /* np->lock, For debugging. */
3055 route_info[rinfo->type].str,
3056 rip_route_type_print (rinfo->sub_type),
3057 inet_ntoa (np->p.u.prefix4), np->p.prefixlen);
3058
3059 len = 24 - len;
3060
3061 if (len > 0)
3062 vty_out (vty, "%*s", len, " ");
3063
3064 if (rinfo->nexthop.s_addr)
3065 vty_out (vty, "%-20s %2d ", inet_ntoa (rinfo->nexthop),
3066 rinfo->metric);
3067 else
3068 vty_out (vty, "0.0.0.0 %2d ", rinfo->metric);
3069
3070 /* Route which exist in kernel routing table. */
3071 if ((rinfo->type == ZEBRA_ROUTE_RIP) &&
3072 (rinfo->sub_type == RIP_ROUTE_RTE))
3073 {
3074 vty_out (vty, "%-15s ", inet_ntoa (rinfo->from));
3075 rip_vty_out_uptime (vty, rinfo);
3076 }
3077 else if (rinfo->metric == RIP_METRIC_INFINITY)
3078 {
3079 vty_out (vty, "self ");
3080 rip_vty_out_uptime (vty, rinfo);
3081 }
3082 else
3083 vty_out (vty, "self");
3084
3085 vty_out (vty, "%s", VTY_NEWLINE);
3086 }
3087 return CMD_SUCCESS;
3088}
3089
3090/* Return next event time. */
3091int
3092rip_next_thread_timer (struct thread *thread)
3093{
3094 struct timeval timer_now;
3095
3096 gettimeofday (&timer_now, NULL);
3097
3098 return thread->u.sands.tv_sec - timer_now.tv_sec;
3099}
3100
3101DEFUN (show_ip_protocols_rip,
3102 show_ip_protocols_rip_cmd,
3103 "show ip protocols",
3104 SHOW_STR
3105 IP_STR
3106 "IP routing protocol process parameters and statistics\n")
3107{
3108 listnode node;
3109 struct interface *ifp;
3110 struct rip_interface *ri;
3111 extern struct message ri_version_msg[];
3112 char *send_version;
3113 char *receive_version;
3114
3115 if (! rip)
3116 return CMD_SUCCESS;
3117
3118 vty_out (vty, "Routing Protocol is \"rip\"%s", VTY_NEWLINE);
3119 vty_out (vty, " Sending updates every %ld seconds with +/-50%%,",
3120 rip->update_time);
3121 vty_out (vty, " next due in %d seconds%s",
3122 rip_next_thread_timer (rip->t_update),
3123 VTY_NEWLINE);
3124 vty_out (vty, " Timeout after %ld seconds,", rip->timeout_time);
3125 vty_out (vty, " garbage collect after %ld seconds%s", rip->garbage_time,
3126 VTY_NEWLINE);
3127
3128 /* Filtering status show. */
3129 config_show_distribute (vty);
3130
3131 /* Default metric information. */
3132 vty_out (vty, " Default redistribution metric is %d%s",
3133 rip->default_metric, VTY_NEWLINE);
3134
3135 /* Redistribute information. */
3136 vty_out (vty, " Redistributing:");
3137 config_write_rip_redistribute (vty, 0);
3138 vty_out (vty, "%s", VTY_NEWLINE);
3139
3140 vty_out (vty, " Default version control: send version %d,", rip->version);
3141 vty_out (vty, " receive version %d %s", rip->version,
3142 VTY_NEWLINE);
3143
3144 vty_out (vty, " Interface Send Recv Key-chain%s", VTY_NEWLINE);
3145
3146 for (node = listhead (iflist); node; node = nextnode (node))
3147 {
3148 ifp = getdata (node);
3149 ri = ifp->info;
3150
3151 if (ri->enable_network || ri->enable_interface)
3152 {
3153 if (ri->ri_send == RI_RIP_UNSPEC)
3154 send_version = lookup (ri_version_msg, rip->version);
3155 else
3156 send_version = lookup (ri_version_msg, ri->ri_send);
3157
3158 if (ri->ri_receive == RI_RIP_UNSPEC)
3159 receive_version = lookup (ri_version_msg, rip->version);
3160 else
3161 receive_version = lookup (ri_version_msg, ri->ri_receive);
3162
3163 vty_out (vty, " %-17s%-3s %-3s %s%s", ifp->name,
3164 send_version,
3165 receive_version,
3166 ri->key_chain ? ri->key_chain : "",
3167 VTY_NEWLINE);
3168 }
3169 }
3170
3171 vty_out (vty, " Routing for Networks:%s", VTY_NEWLINE);
3172 config_write_rip_network (vty, 0);
3173
3174 vty_out (vty, " Routing Information Sources:%s", VTY_NEWLINE);
3175 vty_out (vty, " Gateway BadPackets BadRoutes Distance Last Update%s", VTY_NEWLINE);
3176 rip_peer_display (vty);
3177
3178 rip_distance_show (vty);
3179
3180 return CMD_SUCCESS;
3181}
3182
3183/* RIP configuration write function. */
3184int
3185config_write_rip (struct vty *vty)
3186{
3187 int write = 0;
3188 struct route_node *rn;
3189 struct rip_distance *rdistance;
3190
3191 if (rip)
3192 {
3193 /* Router RIP statement. */
3194 vty_out (vty, "router rip%s", VTY_NEWLINE);
3195 write++;
3196
3197 /* RIP version statement. Default is RIP version 2. */
3198 if (rip->version != RIPv2)
3199 vty_out (vty, " version %d%s", rip->version,
3200 VTY_NEWLINE);
3201
3202 /* RIP timer configuration. */
3203 if (rip->update_time != RIP_UPDATE_TIMER_DEFAULT
3204 || rip->timeout_time != RIP_TIMEOUT_TIMER_DEFAULT
3205 || rip->garbage_time != RIP_GARBAGE_TIMER_DEFAULT)
3206 vty_out (vty, " timers basic %lu %lu %lu%s",
3207 rip->update_time,
3208 rip->timeout_time,
3209 rip->garbage_time,
3210 VTY_NEWLINE);
3211
3212 /* Default information configuration. */
3213 if (rip->default_information)
3214 {
3215 if (rip->default_information_route_map)
3216 vty_out (vty, " default-information originate route-map %s%s",
3217 rip->default_information_route_map, VTY_NEWLINE);
3218 else
3219 vty_out (vty, " default-information originate%s",
3220 VTY_NEWLINE);
3221 }
3222
3223 /* Redistribute configuration. */
3224 config_write_rip_redistribute (vty, 1);
3225
3226 /* RIP offset-list configuration. */
3227 config_write_rip_offset_list (vty);
3228
3229 /* RIP enabled network and interface configuration. */
3230 config_write_rip_network (vty, 1);
3231
3232 /* RIP default metric configuration */
3233 if (rip->default_metric != RIP_DEFAULT_METRIC_DEFAULT)
3234 vty_out (vty, " default-metric %d%s",
3235 rip->default_metric, VTY_NEWLINE);
3236
3237 /* Distribute configuration. */
3238 write += config_write_distribute (vty);
3239
3240 /* Distance configuration. */
3241 if (rip->distance)
3242 vty_out (vty, " distance %d%s", rip->distance, VTY_NEWLINE);
3243
3244 /* RIP source IP prefix distance configuration. */
3245 for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
3246 if ((rdistance = rn->info) != NULL)
3247 vty_out (vty, " distance %d %s/%d %s%s", rdistance->distance,
3248 inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
3249 rdistance->access_list ? rdistance->access_list : "",
3250 VTY_NEWLINE);
3251
3252 /* RIP static route configuration. */
3253 for (rn = route_top (rip->route); rn; rn = route_next (rn))
3254 if (rn->info)
3255 vty_out (vty, " route %s/%d%s",
3256 inet_ntoa (rn->p.u.prefix4),
3257 rn->p.prefixlen,
3258 VTY_NEWLINE);
3259
3260 }
3261 return write;
3262}
3263
3264/* RIP node structure. */
3265struct cmd_node rip_node =
3266{
3267 RIP_NODE,
3268 "%s(config-router)# ",
3269 1
3270};
3271
3272/* Distribute-list update functions. */
3273void
3274rip_distribute_update (struct distribute *dist)
3275{
3276 struct interface *ifp;
3277 struct rip_interface *ri;
3278 struct access_list *alist;
3279 struct prefix_list *plist;
3280
3281 if (! dist->ifname)
3282 return;
3283
3284 ifp = if_lookup_by_name (dist->ifname);
3285 if (ifp == NULL)
3286 return;
3287
3288 ri = ifp->info;
3289
3290 if (dist->list[DISTRIBUTE_IN])
3291 {
3292 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_IN]);
3293 if (alist)
3294 ri->list[RIP_FILTER_IN] = alist;
3295 else
3296 ri->list[RIP_FILTER_IN] = NULL;
3297 }
3298 else
3299 ri->list[RIP_FILTER_IN] = NULL;
3300
3301 if (dist->list[DISTRIBUTE_OUT])
3302 {
3303 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_OUT]);
3304 if (alist)
3305 ri->list[RIP_FILTER_OUT] = alist;
3306 else
3307 ri->list[RIP_FILTER_OUT] = NULL;
3308 }
3309 else
3310 ri->list[RIP_FILTER_OUT] = NULL;
3311
3312 if (dist->prefix[DISTRIBUTE_IN])
3313 {
3314 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_IN]);
3315 if (plist)
3316 ri->prefix[RIP_FILTER_IN] = plist;
3317 else
3318 ri->prefix[RIP_FILTER_IN] = NULL;
3319 }
3320 else
3321 ri->prefix[RIP_FILTER_IN] = NULL;
3322
3323 if (dist->prefix[DISTRIBUTE_OUT])
3324 {
3325 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_OUT]);
3326 if (plist)
3327 ri->prefix[RIP_FILTER_OUT] = plist;
3328 else
3329 ri->prefix[RIP_FILTER_OUT] = NULL;
3330 }
3331 else
3332 ri->prefix[RIP_FILTER_OUT] = NULL;
3333}
3334
3335void
3336rip_distribute_update_interface (struct interface *ifp)
3337{
3338 struct distribute *dist;
3339
3340 dist = distribute_lookup (ifp->name);
3341 if (dist)
3342 rip_distribute_update (dist);
3343}
3344
3345/* Update all interface's distribute list. */
3346void
3347rip_distribute_update_all ()
3348{
3349 struct interface *ifp;
3350 listnode node;
3351
3352 for (node = listhead (iflist); node; nextnode (node))
3353 {
3354 ifp = getdata (node);
3355 rip_distribute_update_interface (ifp);
3356 }
3357}
3358
3359/* Delete all added rip route. */
3360void
3361rip_clean ()
3362{
3363 int i;
3364 struct route_node *rp;
3365 struct rip_info *rinfo;
3366
3367 if (rip)
3368 {
3369 /* Clear RIP routes */
3370 for (rp = route_top (rip->table); rp; rp = route_next (rp))
3371 if ((rinfo = rp->info) != NULL)
3372 {
3373 if (rinfo->type == ZEBRA_ROUTE_RIP &&
3374 rinfo->sub_type == RIP_ROUTE_RTE)
3375 rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p,
3376 &rinfo->nexthop, rinfo->metric);
3377
3378 RIP_TIMER_OFF (rinfo->t_timeout);
3379 RIP_TIMER_OFF (rinfo->t_garbage_collect);
3380
3381 rp->info = NULL;
3382 route_unlock_node (rp);
3383
3384 rip_info_free (rinfo);
3385 }
3386
3387 /* Cancel RIP related timers. */
3388 RIP_TIMER_OFF (rip->t_update);
3389 RIP_TIMER_OFF (rip->t_triggered_update);
3390 RIP_TIMER_OFF (rip->t_triggered_interval);
3391
3392 /* Cancel read thread. */
3393 if (rip->t_read)
3394 {
3395 thread_cancel (rip->t_read);
3396 rip->t_read = NULL;
3397 }
3398
3399 /* Close RIP socket. */
3400 if (rip->sock >= 0)
3401 {
3402 close (rip->sock);
3403 rip->sock = -1;
3404 }
3405
3406 /* Static RIP route configuration. */
3407 for (rp = route_top (rip->route); rp; rp = route_next (rp))
3408 if (rp->info)
3409 {
3410 rp->info = NULL;
3411 route_unlock_node (rp);
3412 }
3413
3414 /* RIP neighbor configuration. */
3415 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
3416 if (rp->info)
3417 {
3418 rp->info = NULL;
3419 route_unlock_node (rp);
3420 }
3421
3422 /* Redistribute related clear. */
3423 if (rip->default_information_route_map)
3424 free (rip->default_information_route_map);
3425
3426 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
3427 if (rip->route_map[i].name)
3428 free (rip->route_map[i].name);
3429
3430 XFREE (MTYPE_ROUTE_TABLE, rip->table);
3431 XFREE (MTYPE_ROUTE_TABLE, rip->route);
3432 XFREE (MTYPE_ROUTE_TABLE, rip->neighbor);
3433
3434 XFREE (MTYPE_RIP, rip);
3435 rip = NULL;
3436 }
3437
3438 rip_clean_network ();
3439 rip_passive_interface_clean ();
3440 rip_offset_clean ();
3441 rip_interface_clean ();
3442 rip_distance_reset ();
3443 rip_redistribute_clean ();
3444}
3445
3446/* Reset all values to the default settings. */
3447void
3448rip_reset ()
3449{
3450 /* Reset global counters. */
3451 rip_global_route_changes = 0;
3452 rip_global_queries = 0;
3453
3454 /* Call ripd related reset functions. */
3455 rip_debug_reset ();
3456 rip_route_map_reset ();
3457
3458 /* Call library reset functions. */
3459 vty_reset ();
3460 access_list_reset ();
3461 prefix_list_reset ();
3462
3463 distribute_list_reset ();
3464
3465 rip_interface_reset ();
3466 rip_distance_reset ();
3467
3468 rip_zclient_reset ();
3469}
3470
3471/* Allocate new rip structure and set default value. */
3472void
3473rip_init ()
3474{
3475 /* Randomize for triggered update random(). */
3476 srand (time (NULL));
3477
3478 /* Install top nodes. */
3479 install_node (&rip_node, config_write_rip);
3480
3481 /* Install rip commands. */
3482 install_element (VIEW_NODE, &show_ip_rip_cmd);
3483 install_element (VIEW_NODE, &show_ip_protocols_rip_cmd);
3484 install_element (ENABLE_NODE, &show_ip_rip_cmd);
3485 install_element (ENABLE_NODE, &show_ip_protocols_rip_cmd);
3486 install_element (CONFIG_NODE, &router_rip_cmd);
3487 install_element (CONFIG_NODE, &no_router_rip_cmd);
3488
3489 install_default (RIP_NODE);
3490 install_element (RIP_NODE, &rip_version_cmd);
3491 install_element (RIP_NODE, &no_rip_version_cmd);
3492 install_element (RIP_NODE, &no_rip_version_val_cmd);
3493 install_element (RIP_NODE, &rip_default_metric_cmd);
3494 install_element (RIP_NODE, &no_rip_default_metric_cmd);
3495 install_element (RIP_NODE, &no_rip_default_metric_val_cmd);
3496 install_element (RIP_NODE, &rip_timers_cmd);
3497 install_element (RIP_NODE, &no_rip_timers_cmd);
3498 install_element (RIP_NODE, &rip_route_cmd);
3499 install_element (RIP_NODE, &no_rip_route_cmd);
3500 install_element (RIP_NODE, &rip_distance_cmd);
3501 install_element (RIP_NODE, &no_rip_distance_cmd);
3502 install_element (RIP_NODE, &rip_distance_source_cmd);
3503 install_element (RIP_NODE, &no_rip_distance_source_cmd);
3504 install_element (RIP_NODE, &rip_distance_source_access_list_cmd);
3505 install_element (RIP_NODE, &no_rip_distance_source_access_list_cmd);
3506
3507 /* Debug related init. */
3508 rip_debug_init ();
3509
3510 /* Filter related init. */
3511 rip_route_map_init ();
3512 rip_offset_init ();
3513
3514 /* SNMP init. */
3515#ifdef HAVE_SNMP
3516 rip_snmp_init ();
3517#endif /* HAVE_SNMP */
3518
3519 /* Access list install. */
3520 access_list_init ();
3521 access_list_add_hook (rip_distribute_update_all);
3522 access_list_delete_hook (rip_distribute_update_all);
3523
3524 /* Prefix list initialize.*/
3525 prefix_list_init ();
3526 prefix_list_add_hook (rip_distribute_update_all);
3527 prefix_list_delete_hook (rip_distribute_update_all);
3528
3529 /* Distribute list install. */
3530 distribute_list_init (RIP_NODE);
3531 distribute_list_add_hook (rip_distribute_update);
3532 distribute_list_delete_hook (rip_distribute_update);
3533
3534 /* Distance control. */
3535 rip_distance_table = route_table_init ();
3536}