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