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