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