1 /* RIP version 1 and 2.
2 * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
3 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro <kunihiro@zebra.org>
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
35 #include "sockunion.h"
40 #include "distribute.h"
45 #include "ripd/ripd.h"
46 #include "ripd/rip_debug.h"
48 /* UDP receive buffer size */
49 #define RIP_UDP_RCV_BUF 41600
51 /* privileges global */
52 extern struct zebra_privs_t ripd_privs
;
55 struct rip
*rip
= NULL
;
57 /* RIP neighbor address table. */
58 struct route_table
*rip_neighbor_table
;
60 /* RIP route changes. */
61 long rip_global_route_changes
= 0;
64 long rip_global_queries
= 0;
67 static void rip_event (enum rip_event
, int);
68 static void rip_output_process (struct connected
*, struct sockaddr_in
*, int, u_char
);
69 static int rip_triggered_update (struct thread
*);
70 static int rip_update_jitter (unsigned long);
72 /* RIP output routes type. */
79 /* RIP command strings. */
80 static const struct message rip_msg
[] =
82 {RIP_REQUEST
, "REQUEST"},
83 {RIP_RESPONSE
, "RESPONSE"},
84 {RIP_TRACEON
, "TRACEON"},
85 {RIP_TRACEOFF
, "TRACEOFF"},
87 {RIP_POLL_ENTRY
, "POLL ENTRY"},
91 /* Utility function to set boradcast option to the socket. */
93 sockopt_broadcast (int sock
)
98 ret
= setsockopt (sock
, SOL_SOCKET
, SO_BROADCAST
, (char *) &on
, sizeof on
);
101 zlog_warn ("can't set sockopt SO_BROADCAST to socket %d", sock
);
108 rip_route_rte (struct rip_info
*rinfo
)
110 return (rinfo
->type
== ZEBRA_ROUTE_RIP
&& rinfo
->sub_type
== RIP_ROUTE_RTE
);
113 static struct rip_info
*
116 return XCALLOC (MTYPE_RIP_INFO
, sizeof (struct rip_info
));
120 rip_info_free (struct rip_info
*rinfo
)
122 XFREE (MTYPE_RIP_INFO
, rinfo
);
125 /* RIP route garbage collect timer. */
127 rip_garbage_collect (struct thread
*t
)
129 struct rip_info
*rinfo
;
130 struct route_node
*rp
;
132 rinfo
= THREAD_ARG (t
);
133 rinfo
->t_garbage_collect
= NULL
;
135 /* Off timeout timer. */
136 RIP_TIMER_OFF (rinfo
->t_timeout
);
138 /* Get route_node pointer. */
141 /* Unlock route_node. */
142 listnode_delete (rp
->info
, rinfo
);
143 if (list_isempty ((struct list
*)rp
->info
))
145 list_free (rp
->info
);
147 route_unlock_node (rp
);
150 /* Free RIP routing information. */
151 rip_info_free (rinfo
);
156 static void rip_timeout_update (struct rip_info
*rinfo
);
158 /* Add new route to the ECMP list.
159 * RETURN: the new entry added in the list, or NULL if it is not the first
160 * entry and ECMP is not allowed.
163 rip_ecmp_add (struct rip_info
*rinfo_new
)
165 struct route_node
*rp
= rinfo_new
->rp
;
166 struct rip_info
*rinfo
= NULL
;
167 struct list
*list
= NULL
;
169 if (rp
->info
== NULL
)
170 rp
->info
= list_new ();
171 list
= (struct list
*)rp
->info
;
173 /* If ECMP is not allowed and some entry already exists in the list,
175 if (listcount (list
) && !rip
->ecmp
)
178 rinfo
= rip_info_new ();
179 memcpy (rinfo
, rinfo_new
, sizeof (struct rip_info
));
180 listnode_add (list
, rinfo
);
182 if (rip_route_rte (rinfo
))
184 rip_timeout_update (rinfo
);
185 rip_zebra_ipv4_add (rp
);
188 /* Set the route change flag on the first entry. */
189 rinfo
= listgetdata (listhead (list
));
190 SET_FLAG (rinfo
->flags
, RIP_RTF_CHANGED
);
192 /* Signal the output process to trigger an update (see section 2.5). */
193 rip_event (RIP_TRIGGERED_UPDATE
, 0);
198 /* Replace the ECMP list with the new route.
199 * RETURN: the new entry added in the list
202 rip_ecmp_replace (struct rip_info
*rinfo_new
)
204 struct route_node
*rp
= rinfo_new
->rp
;
205 struct list
*list
= (struct list
*)rp
->info
;
206 struct rip_info
*rinfo
= NULL
, *tmp_rinfo
= NULL
;
207 struct listnode
*node
= NULL
, *nextnode
= NULL
;
209 if (list
== NULL
|| listcount (list
) == 0)
210 return rip_ecmp_add (rinfo_new
);
212 /* Get the first entry */
213 rinfo
= listgetdata (listhead (list
));
215 /* Learnt route replaced by a local one. Delete it from zebra. */
216 if (rip_route_rte (rinfo
) && !rip_route_rte (rinfo_new
))
217 if (CHECK_FLAG (rinfo
->flags
, RIP_RTF_FIB
))
218 rip_zebra_ipv4_delete (rp
);
220 /* Re-use the first entry, and delete the others. */
221 for (ALL_LIST_ELEMENTS (list
, node
, nextnode
, tmp_rinfo
))
222 if (tmp_rinfo
!= rinfo
)
224 RIP_TIMER_OFF (tmp_rinfo
->t_timeout
);
225 RIP_TIMER_OFF (tmp_rinfo
->t_garbage_collect
);
226 list_delete_node (list
, node
);
227 rip_info_free (tmp_rinfo
);
230 RIP_TIMER_OFF (rinfo
->t_timeout
);
231 RIP_TIMER_OFF (rinfo
->t_garbage_collect
);
232 memcpy (rinfo
, rinfo_new
, sizeof (struct rip_info
));
234 if (rip_route_rte (rinfo
))
236 rip_timeout_update (rinfo
);
237 /* The ADD message implies an update. */
238 rip_zebra_ipv4_add (rp
);
241 /* Set the route change flag. */
242 SET_FLAG (rinfo
->flags
, RIP_RTF_CHANGED
);
244 /* Signal the output process to trigger an update (see section 2.5). */
245 rip_event (RIP_TRIGGERED_UPDATE
, 0);
250 /* Delete one route from the ECMP list.
252 * null - the entry is freed, and other entries exist in the list
253 * the entry - the entry is the last one in the list; its metric is set
254 * to INFINITY, and the garbage collector is started for it
257 rip_ecmp_delete (struct rip_info
*rinfo
)
259 struct route_node
*rp
= rinfo
->rp
;
260 struct list
*list
= (struct list
*)rp
->info
;
262 RIP_TIMER_OFF (rinfo
->t_timeout
);
264 if (listcount (list
) > 1)
266 /* Some other ECMP entries still exist. Just delete this entry. */
267 RIP_TIMER_OFF (rinfo
->t_garbage_collect
);
268 listnode_delete (list
, rinfo
);
269 if (rip_route_rte (rinfo
) && CHECK_FLAG (rinfo
->flags
, RIP_RTF_FIB
))
270 /* The ADD message implies the update. */
271 rip_zebra_ipv4_add (rp
);
272 rip_info_free (rinfo
);
277 assert (rinfo
== listgetdata (listhead (list
)));
279 /* This is the only entry left in the list. We must keep it in
280 * the list for garbage collection time, with INFINITY metric. */
282 rinfo
->metric
= RIP_METRIC_INFINITY
;
283 RIP_TIMER_ON (rinfo
->t_garbage_collect
,
284 rip_garbage_collect
, rip
->garbage_time
);
286 if (rip_route_rte (rinfo
) && CHECK_FLAG (rinfo
->flags
, RIP_RTF_FIB
))
287 rip_zebra_ipv4_delete (rp
);
290 /* Set the route change flag on the first entry. */
291 rinfo
= listgetdata (listhead (list
));
292 SET_FLAG (rinfo
->flags
, RIP_RTF_CHANGED
);
294 /* Signal the output process to trigger an update (see section 2.5). */
295 rip_event (RIP_TRIGGERED_UPDATE
, 0);
300 /* Timeout RIP routes. */
302 rip_timeout (struct thread
*t
)
304 rip_ecmp_delete ((struct rip_info
*)THREAD_ARG (t
));
309 rip_timeout_update (struct rip_info
*rinfo
)
311 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
313 RIP_TIMER_OFF (rinfo
->t_timeout
);
314 RIP_TIMER_ON (rinfo
->t_timeout
, rip_timeout
, rip
->timeout_time
);
319 rip_incoming_filter (struct prefix_ipv4
*p
, struct rip_interface
*ri
)
321 struct distribute
*dist
;
322 struct access_list
*alist
;
323 struct prefix_list
*plist
;
325 /* Input distribute-list filtering. */
326 if (ri
->list
[RIP_FILTER_IN
])
328 if (access_list_apply (ri
->list
[RIP_FILTER_IN
],
329 (struct prefix
*) p
) == FILTER_DENY
)
331 if (IS_RIP_DEBUG_PACKET
)
332 zlog_debug ("%s/%d filtered by distribute in",
333 inet_ntoa (p
->prefix
), p
->prefixlen
);
337 if (ri
->prefix
[RIP_FILTER_IN
])
339 if (prefix_list_apply (ri
->prefix
[RIP_FILTER_IN
],
340 (struct prefix
*) p
) == PREFIX_DENY
)
342 if (IS_RIP_DEBUG_PACKET
)
343 zlog_debug ("%s/%d filtered by prefix-list in",
344 inet_ntoa (p
->prefix
), p
->prefixlen
);
349 /* All interface filter check. */
350 dist
= distribute_lookup (NULL
);
353 if (dist
->list
[DISTRIBUTE_IN
])
355 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_IN
]);
359 if (access_list_apply (alist
,
360 (struct prefix
*) p
) == FILTER_DENY
)
362 if (IS_RIP_DEBUG_PACKET
)
363 zlog_debug ("%s/%d filtered by distribute in",
364 inet_ntoa (p
->prefix
), p
->prefixlen
);
369 if (dist
->prefix
[DISTRIBUTE_IN
])
371 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_IN
]);
375 if (prefix_list_apply (plist
,
376 (struct prefix
*) p
) == PREFIX_DENY
)
378 if (IS_RIP_DEBUG_PACKET
)
379 zlog_debug ("%s/%d filtered by prefix-list in",
380 inet_ntoa (p
->prefix
), p
->prefixlen
);
390 rip_outgoing_filter (struct prefix_ipv4
*p
, struct rip_interface
*ri
)
392 struct distribute
*dist
;
393 struct access_list
*alist
;
394 struct prefix_list
*plist
;
396 if (ri
->list
[RIP_FILTER_OUT
])
398 if (access_list_apply (ri
->list
[RIP_FILTER_OUT
],
399 (struct prefix
*) p
) == FILTER_DENY
)
401 if (IS_RIP_DEBUG_PACKET
)
402 zlog_debug ("%s/%d is filtered by distribute out",
403 inet_ntoa (p
->prefix
), p
->prefixlen
);
407 if (ri
->prefix
[RIP_FILTER_OUT
])
409 if (prefix_list_apply (ri
->prefix
[RIP_FILTER_OUT
],
410 (struct prefix
*) p
) == PREFIX_DENY
)
412 if (IS_RIP_DEBUG_PACKET
)
413 zlog_debug ("%s/%d is filtered by prefix-list out",
414 inet_ntoa (p
->prefix
), p
->prefixlen
);
419 /* All interface filter check. */
420 dist
= distribute_lookup (NULL
);
423 if (dist
->list
[DISTRIBUTE_OUT
])
425 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_OUT
]);
429 if (access_list_apply (alist
,
430 (struct prefix
*) p
) == FILTER_DENY
)
432 if (IS_RIP_DEBUG_PACKET
)
433 zlog_debug ("%s/%d filtered by distribute out",
434 inet_ntoa (p
->prefix
), p
->prefixlen
);
439 if (dist
->prefix
[DISTRIBUTE_OUT
])
441 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_OUT
]);
445 if (prefix_list_apply (plist
,
446 (struct prefix
*) p
) == PREFIX_DENY
)
448 if (IS_RIP_DEBUG_PACKET
)
449 zlog_debug ("%s/%d filtered by prefix-list out",
450 inet_ntoa (p
->prefix
), p
->prefixlen
);
459 /* Check nexthop address validity. */
461 rip_nexthop_check (struct in_addr
*addr
)
463 struct listnode
*node
;
464 struct listnode
*cnode
;
465 struct interface
*ifp
;
466 struct connected
*ifc
;
469 /* If nexthop address matches local configured address then it is
472 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
))
474 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, ifc
))
478 if (p
->family
== AF_INET
479 && IPV4_ADDR_SAME (&p
->u
.prefix4
, addr
))
486 /* RIP add route to routing table. */
488 rip_rte_process (struct rte
*rte
, struct sockaddr_in
*from
,
489 struct interface
*ifp
)
492 struct prefix_ipv4 p
;
493 struct route_node
*rp
;
494 struct rip_info
*rinfo
= NULL
, newinfo
;
495 struct rip_interface
*ri
;
496 struct in_addr
*nexthop
;
498 unsigned char old_dist
, new_dist
;
499 struct list
*list
= NULL
;
500 struct listnode
*node
= NULL
;
502 /* Make prefix structure. */
503 memset (&p
, 0, sizeof (struct prefix_ipv4
));
505 p
.prefix
= rte
->prefix
;
506 p
.prefixlen
= ip_masklen (rte
->mask
);
508 /* Make sure mask is applied. */
509 apply_mask_ipv4 (&p
);
511 /* Apply input filters. */
514 ret
= rip_incoming_filter (&p
, ri
);
518 memset (&newinfo
, 0, sizeof (newinfo
));
519 newinfo
.type
= ZEBRA_ROUTE_RIP
;
520 newinfo
.sub_type
= RIP_ROUTE_RTE
;
521 newinfo
.nexthop
= rte
->nexthop
;
522 newinfo
.from
= from
->sin_addr
;
523 newinfo
.ifindex
= ifp
->ifindex
;
524 newinfo
.metric
= rte
->metric
;
525 newinfo
.metric_out
= rte
->metric
; /* XXX */
526 newinfo
.tag
= ntohs (rte
->tag
); /* XXX */
528 /* Modify entry according to the interface routemap. */
529 if (ri
->routemap
[RIP_FILTER_IN
])
533 /* The object should be of the type of rip_info */
534 ret
= route_map_apply (ri
->routemap
[RIP_FILTER_IN
],
535 (struct prefix
*) &p
, RMAP_RIP
, &newinfo
);
537 if (ret
== RMAP_DENYMATCH
)
539 if (IS_RIP_DEBUG_PACKET
)
540 zlog_debug ("RIP %s/%d is filtered by route-map in",
541 inet_ntoa (p
.prefix
), p
.prefixlen
);
545 /* Get back the object */
546 rte
->nexthop
= newinfo
.nexthop_out
;
547 rte
->tag
= htons (newinfo
.tag_out
); /* XXX */
548 rte
->metric
= newinfo
.metric_out
; /* XXX: the routemap uses the metric_out field */
551 /* Once the entry has been validated, update the metric by
552 adding the cost of the network on wich the message
553 arrived. If the result is greater than infinity, use infinity
554 (RFC2453 Sec. 3.9.2) */
555 /* Zebra ripd can handle offset-list in. */
556 ret
= rip_offset_list_apply_in (&p
, ifp
, &rte
->metric
);
558 /* If offset-list does not modify the metric use interface's
561 rte
->metric
+= ifp
->metric
? ifp
->metric
: 1;
563 if (rte
->metric
> RIP_METRIC_INFINITY
)
564 rte
->metric
= RIP_METRIC_INFINITY
;
566 /* Set nexthop pointer. */
567 if (rte
->nexthop
.s_addr
== 0)
568 nexthop
= &from
->sin_addr
;
570 nexthop
= &rte
->nexthop
;
572 /* Check if nexthop address is myself, then do nothing. */
573 if (rip_nexthop_check (nexthop
) < 0)
575 if (IS_RIP_DEBUG_PACKET
)
576 zlog_debug ("Nexthop address %s is myself", inet_ntoa (*nexthop
));
580 /* Get index for the prefix. */
581 rp
= route_node_get (rip
->table
, (struct prefix
*) &p
);
584 newinfo
.nexthop
= *nexthop
;
585 newinfo
.metric
= rte
->metric
;
586 newinfo
.tag
= ntohs (rte
->tag
);
587 newinfo
.distance
= rip_distance_apply (&newinfo
);
589 new_dist
= newinfo
.distance
? newinfo
.distance
: ZEBRA_RIP_DISTANCE_DEFAULT
;
591 /* Check to see whether there is already RIP route on the table. */
592 if ((list
= rp
->info
) != NULL
)
593 for (ALL_LIST_ELEMENTS_RO (list
, node
, rinfo
))
595 /* Need to compare with redistributed entry or local entry */
596 if (!rip_route_rte (rinfo
))
599 if (IPV4_ADDR_SAME (&rinfo
->from
, &from
->sin_addr
) &&
600 IPV4_ADDR_SAME (&rinfo
->nexthop
, nexthop
))
603 if (!listnextnode (node
))
605 /* Not found in the list */
607 if (rte
->metric
> rinfo
->metric
)
609 /* New route has a greater metric. Discard it. */
610 route_unlock_node (rp
);
614 if (rte
->metric
< rinfo
->metric
)
615 /* New route has a smaller metric. Replace the ECMP list
616 * with the new one in below. */
619 /* Metrics are same. We compare the distances. */
620 old_dist
= rinfo
->distance
? \
621 rinfo
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
;
623 if (new_dist
> old_dist
)
625 /* New route has a greater distance. Discard it. */
626 route_unlock_node (rp
);
630 if (new_dist
< old_dist
)
631 /* New route has a smaller distance. Replace the ECMP list
632 * with the new one in below. */
635 /* Metrics and distances are both same. Keep "rinfo" null and
636 * the new route is added in the ECMP list in below. */
642 /* Local static route. */
643 if (rinfo
->type
== ZEBRA_ROUTE_RIP
644 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
) ||
645 (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))
646 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
648 route_unlock_node (rp
);
652 /* Redistributed route check. */
653 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
654 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
656 old_dist
= rinfo
->distance
;
657 /* Only routes directly connected to an interface (nexthop == 0)
658 * may have a valid NULL distance */
659 if (rinfo
->nexthop
.s_addr
!= 0)
660 old_dist
= old_dist
? old_dist
: ZEBRA_RIP_DISTANCE_DEFAULT
;
661 /* If imported route does not have STRICT precedence,
662 mark it as a ghost */
663 if (new_dist
<= old_dist
&& rte
->metric
!= RIP_METRIC_INFINITY
)
664 rip_ecmp_replace (&newinfo
);
666 route_unlock_node (rp
);
674 route_unlock_node (rp
);
676 /* Now, check to see whether there is already an explicit route
677 for the destination prefix. If there is no such route, add
678 this route to the routing table, unless the metric is
679 infinity (there is no point in adding a route which
681 if (rte
->metric
!= RIP_METRIC_INFINITY
)
682 rip_ecmp_add (&newinfo
);
686 /* Route is there but we are not sure the route is RIP or not. */
688 /* If there is an existing route, compare the next hop address
689 to the address of the router from which the datagram came.
690 If this datagram is from the same router as the existing
691 route, reinitialize the timeout. */
692 same
= (IPV4_ADDR_SAME (&rinfo
->from
, &from
->sin_addr
)
693 && (rinfo
->ifindex
== ifp
->ifindex
));
695 old_dist
= rinfo
->distance
? \
696 rinfo
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
;
698 /* Next, compare the metrics. If the datagram is from the same
699 router as the existing route, and the new metric is different
700 than the old one; or, if the new metric is lower than the old
701 one, or if the tag has been changed; or if there is a route
702 with a lower administrave distance; or an update of the
703 distance on the actual route; do the following actions: */
704 if ((same
&& rinfo
->metric
!= rte
->metric
)
705 || (rte
->metric
< rinfo
->metric
)
707 && (rinfo
->metric
== rte
->metric
)
708 && (newinfo
.tag
!= rinfo
->tag
))
709 || (old_dist
> new_dist
)
710 || ((old_dist
!= new_dist
) && same
))
712 if (listcount (list
) == 1)
714 if (newinfo
.metric
!= RIP_METRIC_INFINITY
)
715 rip_ecmp_replace (&newinfo
);
717 rip_ecmp_delete (rinfo
);
721 if (newinfo
.metric
< rinfo
->metric
)
722 rip_ecmp_replace (&newinfo
);
723 else if (newinfo
.metric
> rinfo
->metric
)
724 rip_ecmp_delete (rinfo
);
725 else if (new_dist
< old_dist
)
726 rip_ecmp_replace (&newinfo
);
727 else if (new_dist
> old_dist
)
728 rip_ecmp_delete (rinfo
);
731 int update
= CHECK_FLAG (rinfo
->flags
, RIP_RTF_FIB
) ? 1 : 0;
733 assert (newinfo
.metric
!= RIP_METRIC_INFINITY
);
735 RIP_TIMER_OFF (rinfo
->t_timeout
);
736 RIP_TIMER_OFF (rinfo
->t_garbage_collect
);
737 memcpy (rinfo
, &newinfo
, sizeof (struct rip_info
));
738 rip_timeout_update (rinfo
);
741 rip_zebra_ipv4_add (rp
);
743 /* - Set the route change flag on the first entry. */
744 rinfo
= listgetdata (listhead (list
));
745 SET_FLAG (rinfo
->flags
, RIP_RTF_CHANGED
);
746 rip_event (RIP_TRIGGERED_UPDATE
, 0);
750 else /* same & no change */
751 rip_timeout_update (rinfo
);
753 /* Unlock tempolary lock of the route. */
754 route_unlock_node (rp
);
758 /* Dump RIP packet */
760 rip_packet_dump (struct rip_packet
*packet
, int size
, const char *sndrcv
)
764 const char *command_str
;
765 char pbuf
[BUFSIZ
], nbuf
[BUFSIZ
];
769 /* Set command string. */
770 if (packet
->command
> 0 && packet
->command
< RIP_COMMAND_MAX
)
771 command_str
= lookup (rip_msg
, packet
->command
);
773 command_str
= "unknown";
775 /* Dump packet header. */
776 zlog_debug ("%s %s version %d packet size %d",
777 sndrcv
, command_str
, packet
->version
, size
);
779 /* Dump each routing table entry. */
782 for (lim
= (caddr_t
) packet
+ size
; (caddr_t
) rte
< lim
; rte
++)
784 if (packet
->version
== RIPv2
)
786 netmask
= ip_masklen (rte
->mask
);
788 if (rte
->family
== htons (RIP_FAMILY_AUTH
))
790 if (rte
->tag
== htons (RIP_AUTH_SIMPLE_PASSWORD
))
792 p
= (u_char
*)&rte
->prefix
;
794 zlog_debug (" family 0x%X type %d auth string: %s",
795 ntohs (rte
->family
), ntohs (rte
->tag
), p
);
797 else if (rte
->tag
== htons (RIP_AUTH_MD5
))
799 struct rip_md5_info
*md5
;
801 md5
= (struct rip_md5_info
*) &packet
->rte
;
803 zlog_debug (" family 0x%X type %d (MD5 authentication)",
804 ntohs (md5
->family
), ntohs (md5
->type
));
805 zlog_debug (" RIP-2 packet len %d Key ID %d"
807 ntohs (md5
->packet_len
), md5
->keyid
,
809 zlog_debug (" Sequence Number %ld",
810 (u_long
) ntohl (md5
->sequence
));
812 else if (rte
->tag
== htons (RIP_AUTH_DATA
))
814 p
= (u_char
*)&rte
->prefix
;
816 zlog_debug (" family 0x%X type %d (MD5 data)",
817 ntohs (rte
->family
), ntohs (rte
->tag
));
818 zlog_debug (" MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
819 "%02X%02X%02X%02X%02X%02X%02X",
820 p
[0], p
[1], p
[2], p
[3], p
[4], p
[5], p
[6],
821 p
[7], p
[9], p
[10], p
[11], p
[12], p
[13],
826 zlog_debug (" family 0x%X type %d (Unknown auth type)",
827 ntohs (rte
->family
), ntohs (rte
->tag
));
831 zlog_debug (" %s/%d -> %s family %d tag %d metric %ld",
832 inet_ntop (AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
833 netmask
, inet_ntop (AF_INET
, &rte
->nexthop
, nbuf
,
834 BUFSIZ
), ntohs (rte
->family
),
835 ntohs (rte
->tag
), (u_long
) ntohl (rte
->metric
));
839 zlog_debug (" %s family %d tag %d metric %ld",
840 inet_ntop (AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
841 ntohs (rte
->family
), ntohs (rte
->tag
),
842 (u_long
)ntohl (rte
->metric
));
847 /* Check if the destination address is valid (unicast; not net 0
848 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
849 check net 0 because we accept default route. */
851 rip_destination_check (struct in_addr addr
)
853 u_int32_t destination
;
855 /* Convert to host byte order. */
856 destination
= ntohl (addr
.s_addr
);
858 if (IPV4_NET127 (destination
))
861 /* Net 0 may match to the default route. */
862 if (IPV4_NET0 (destination
) && destination
!= 0)
865 /* Unicast address must belong to class A, B, C. */
866 if (IN_CLASSA (destination
))
868 if (IN_CLASSB (destination
))
870 if (IN_CLASSC (destination
))
876 /* RIP version 2 authentication. */
878 rip_auth_simple_password (struct rte
*rte
, struct sockaddr_in
*from
,
879 struct interface
*ifp
)
881 struct rip_interface
*ri
;
884 if (IS_RIP_DEBUG_EVENT
)
885 zlog_debug ("RIPv2 simple password authentication from %s",
886 inet_ntoa (from
->sin_addr
));
890 if (ri
->auth_type
!= RIP_AUTH_SIMPLE_PASSWORD
891 || rte
->tag
!= htons(RIP_AUTH_SIMPLE_PASSWORD
))
894 /* Simple password authentication. */
897 auth_str
= (char *) &rte
->prefix
;
899 if (strncmp (auth_str
, ri
->auth_str
, 16) == 0)
904 struct keychain
*keychain
;
907 keychain
= keychain_lookup (ri
->key_chain
);
908 if (keychain
== NULL
)
911 key
= key_match_for_accept (keychain
, (char *) &rte
->prefix
);
918 /* RIP version 2 authentication with MD5. */
920 rip_auth_md5 (struct rip_packet
*packet
, struct sockaddr_in
*from
,
921 int length
, struct interface
*ifp
)
923 struct rip_interface
*ri
;
924 struct rip_md5_info
*md5
;
925 struct rip_md5_data
*md5data
;
926 struct keychain
*keychain
;
929 u_char digest
[RIP_AUTH_MD5_SIZE
];
930 u_int16_t packet_len
;
931 char auth_str
[RIP_AUTH_MD5_SIZE
];
933 if (IS_RIP_DEBUG_EVENT
)
934 zlog_debug ("RIPv2 MD5 authentication from %s",
935 inet_ntoa (from
->sin_addr
));
938 md5
= (struct rip_md5_info
*) &packet
->rte
;
940 /* Check auth type. */
941 if (ri
->auth_type
!= RIP_AUTH_MD5
|| md5
->type
!= htons(RIP_AUTH_MD5
))
944 /* If the authentication length is less than 16, then it must be wrong for
945 * any interpretation of rfc2082. Some implementations also interpret
946 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka RIP_AUTH_MD5_COMPAT_SIZE.
948 if ( !((md5
->auth_len
== RIP_AUTH_MD5_SIZE
)
949 || (md5
->auth_len
== RIP_AUTH_MD5_COMPAT_SIZE
)))
951 if (IS_RIP_DEBUG_EVENT
)
952 zlog_debug ("RIPv2 MD5 authentication, strange authentication "
953 "length field %d", md5
->auth_len
);
957 /* grab and verify check packet length */
958 packet_len
= ntohs (md5
->packet_len
);
960 if (packet_len
> (length
- RIP_HEADER_SIZE
- RIP_AUTH_MD5_SIZE
))
962 if (IS_RIP_DEBUG_EVENT
)
963 zlog_debug ("RIPv2 MD5 authentication, packet length field %d "
964 "greater than received length %d!",
965 md5
->packet_len
, length
);
969 /* retrieve authentication data */
970 md5data
= (struct rip_md5_data
*) (((u_char
*) packet
) + packet_len
);
972 memset (auth_str
, 0, RIP_AUTH_MD5_SIZE
);
976 keychain
= keychain_lookup (ri
->key_chain
);
977 if (keychain
== NULL
)
980 key
= key_lookup_for_accept (keychain
, md5
->keyid
);
984 strncpy (auth_str
, key
->string
, RIP_AUTH_MD5_SIZE
);
986 else if (ri
->auth_str
)
987 strncpy (auth_str
, ri
->auth_str
, RIP_AUTH_MD5_SIZE
);
989 if (auth_str
[0] == 0)
992 /* MD5 digest authentication. */
993 memset (&ctx
, 0, sizeof(ctx
));
995 MD5Update(&ctx
, packet
, packet_len
+ RIP_HEADER_SIZE
);
996 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
997 MD5Final(digest
, &ctx
);
999 if (memcmp (md5data
->digest
, digest
, RIP_AUTH_MD5_SIZE
) == 0)
1005 /* Pick correct auth string for sends, prepare auth_str buffer for use.
1006 * (left justified and padded).
1008 * presumes one of ri or key is valid, and that the auth strings they point
1009 * to are nul terminated. If neither are present, auth_str will be fully
1014 rip_auth_prepare_str_send (struct rip_interface
*ri
, struct key
*key
,
1015 char *auth_str
, int len
)
1019 memset (auth_str
, 0, len
);
1020 if (key
&& key
->string
)
1021 strncpy (auth_str
, key
->string
, len
);
1022 else if (ri
->auth_str
)
1023 strncpy (auth_str
, ri
->auth_str
, len
);
1028 /* Write RIPv2 simple password authentication information
1030 * auth_str is presumed to be 2 bytes and correctly prepared
1031 * (left justified and zero padded).
1034 rip_auth_simple_write (struct stream
*s
, char *auth_str
, int len
)
1036 assert (s
&& len
== RIP_AUTH_SIMPLE_SIZE
);
1038 stream_putw (s
, RIP_FAMILY_AUTH
);
1039 stream_putw (s
, RIP_AUTH_SIMPLE_PASSWORD
);
1040 stream_put (s
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
1045 /* write RIPv2 MD5 "authentication header"
1046 * (uses the auth key data field)
1048 * Digest offset field is set to 0.
1050 * returns: offset of the digest offset field, which must be set when
1051 * length to the auth-data MD5 digest is known.
1054 rip_auth_md5_ah_write (struct stream
*s
, struct rip_interface
*ri
,
1059 assert (s
&& ri
&& ri
->auth_type
== RIP_AUTH_MD5
);
1061 /* MD5 authentication. */
1062 stream_putw (s
, RIP_FAMILY_AUTH
);
1063 stream_putw (s
, RIP_AUTH_MD5
);
1065 /* MD5 AH digest offset field.
1067 * Set to placeholder value here, to true value when RIP-2 Packet length
1068 * is known. Actual value is set in .....().
1070 doff
= stream_get_endp(s
);
1075 stream_putc (s
, key
->index
% 256);
1079 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
1080 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for this
1081 * to be configurable.
1083 stream_putc (s
, ri
->md5_auth_len
);
1085 /* Sequence Number (non-decreasing). */
1086 /* RFC2080: The value used in the sequence number is
1087 arbitrary, but two suggestions are the time of the
1088 message's creation or a simple message counter. */
1089 stream_putl (s
, time (NULL
));
1091 /* Reserved field must be zero. */
1098 /* If authentication is in used, write the appropriate header
1099 * returns stream offset to which length must later be written
1100 * or 0 if this is not required
1103 rip_auth_header_write (struct stream
*s
, struct rip_interface
*ri
,
1104 struct key
*key
, char *auth_str
, int len
)
1106 assert (ri
->auth_type
!= RIP_NO_AUTH
);
1108 switch (ri
->auth_type
)
1110 case RIP_AUTH_SIMPLE_PASSWORD
:
1111 rip_auth_prepare_str_send (ri
, key
, auth_str
, len
);
1112 rip_auth_simple_write (s
, auth_str
, len
);
1115 return rip_auth_md5_ah_write (s
, ri
, key
);
1121 /* Write RIPv2 MD5 authentication data trailer */
1123 rip_auth_md5_set (struct stream
*s
, struct rip_interface
*ri
, size_t doff
,
1124 char *auth_str
, int authlen
)
1128 unsigned char digest
[RIP_AUTH_MD5_SIZE
];
1130 /* Make it sure this interface is configured as MD5
1132 assert ((ri
->auth_type
== RIP_AUTH_MD5
) && (authlen
== RIP_AUTH_MD5_SIZE
));
1135 /* Get packet length. */
1136 len
= stream_get_endp(s
);
1138 /* Check packet length. */
1139 if (len
< (RIP_HEADER_SIZE
+ RIP_RTE_SIZE
))
1141 zlog_err ("rip_auth_md5_set(): packet length %ld is less than minimum length.", len
);
1145 /* Set the digest offset length in the header */
1146 stream_putw_at (s
, doff
, len
);
1148 /* Set authentication data. */
1149 stream_putw (s
, RIP_FAMILY_AUTH
);
1150 stream_putw (s
, RIP_AUTH_DATA
);
1152 /* Generate a digest for the RIP packet. */
1153 memset(&ctx
, 0, sizeof(ctx
));
1155 MD5Update(&ctx
, STREAM_DATA (s
), stream_get_endp (s
));
1156 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1157 MD5Final(digest
, &ctx
);
1159 /* Copy the digest to the packet. */
1160 stream_write (s
, digest
, RIP_AUTH_MD5_SIZE
);
1163 /* RIP routing information. */
1165 rip_response_process (struct rip_packet
*packet
, int size
,
1166 struct sockaddr_in
*from
, struct connected
*ifc
)
1170 struct prefix_ipv4 ifaddr
;
1171 struct prefix_ipv4 ifaddrclass
;
1174 memset(&ifaddr
, 0, sizeof(ifaddr
));
1175 /* We don't know yet. */
1178 /* The Response must be ignored if it is not from the RIP
1179 port. (RFC2453 - Sec. 3.9.2)*/
1180 if (from
->sin_port
!= htons(RIP_PORT_DEFAULT
))
1182 zlog_info ("response doesn't come from RIP port: %d",
1184 rip_peer_bad_packet (from
);
1188 /* The datagram's IPv4 source address should be checked to see
1189 whether the datagram is from a valid neighbor; the source of the
1190 datagram must be on a directly connected network (RFC2453 - Sec. 3.9.2) */
1191 if (if_lookup_address((void *)&from
->sin_addr
, AF_INET
) == NULL
)
1193 zlog_info ("This datagram doesn't came from a valid neighbor: %s",
1194 inet_ntoa (from
->sin_addr
));
1195 rip_peer_bad_packet (from
);
1199 /* It is also worth checking to see whether the response is from one
1200 of the router's own addresses. */
1202 ; /* Alredy done in rip_read () */
1204 /* Update RIP peer. */
1205 rip_peer_update (from
, packet
->version
);
1207 /* Set RTE pointer. */
1210 for (lim
= (caddr_t
) packet
+ size
; (caddr_t
) rte
< lim
; rte
++)
1212 /* RIPv2 authentication check. */
1213 /* If the Address Family Identifier of the first (and only the
1214 first) entry in the message is 0xFFFF, then the remainder of
1215 the entry contains the authentication. */
1216 /* If the packet gets here it means authentication enabled */
1217 /* Check is done in rip_read(). So, just skipping it */
1218 if (packet
->version
== RIPv2
&&
1219 rte
== packet
->rte
&&
1220 rte
->family
== htons(RIP_FAMILY_AUTH
))
1223 if (rte
->family
!= htons(AF_INET
))
1225 /* Address family check. RIP only supports AF_INET. */
1226 zlog_info ("Unsupported family %d from %s.",
1227 ntohs (rte
->family
), inet_ntoa (from
->sin_addr
));
1231 /* - is the destination address valid (e.g., unicast; not net 0
1233 if (! rip_destination_check (rte
->prefix
))
1235 zlog_info ("Network is net 0 or net 127 or it is not unicast network");
1236 rip_peer_bad_route (from
);
1240 /* Convert metric value to host byte order. */
1241 rte
->metric
= ntohl (rte
->metric
);
1243 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1244 if (! (rte
->metric
>= 1 && rte
->metric
<= 16))
1246 zlog_info ("Route's metric is not in the 1-16 range.");
1247 rip_peer_bad_route (from
);
1251 /* RIPv1 does not have nexthop value. */
1252 if (packet
->version
== RIPv1
&& rte
->nexthop
.s_addr
!= 0)
1254 zlog_info ("RIPv1 packet with nexthop value %s",
1255 inet_ntoa (rte
->nexthop
));
1256 rip_peer_bad_route (from
);
1260 /* That is, if the provided information is ignored, a possibly
1261 sub-optimal, but absolutely valid, route may be taken. If
1262 the received Next Hop is not directly reachable, it should be
1263 treated as 0.0.0.0. */
1264 if (packet
->version
== RIPv2
&& rte
->nexthop
.s_addr
!= 0)
1268 /* Multicast address check. */
1269 addrval
= ntohl (rte
->nexthop
.s_addr
);
1270 if (IN_CLASSD (addrval
))
1272 zlog_info ("Nexthop %s is multicast address, skip this rte",
1273 inet_ntoa (rte
->nexthop
));
1277 if (! if_lookup_address ((void *)&rte
->nexthop
, AF_INET
))
1279 struct route_node
*rn
;
1280 struct rip_info
*rinfo
;
1282 rn
= route_node_match_ipv4 (rip
->table
, &rte
->nexthop
);
1288 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1289 && rinfo
->sub_type
== RIP_ROUTE_RTE
)
1291 if (IS_RIP_DEBUG_EVENT
)
1292 zlog_debug ("Next hop %s is on RIP network. Set nexthop to the packet's originator", inet_ntoa (rte
->nexthop
));
1293 rte
->nexthop
= rinfo
->from
;
1297 if (IS_RIP_DEBUG_EVENT
)
1298 zlog_debug ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte
->nexthop
));
1299 rte
->nexthop
.s_addr
= 0;
1302 route_unlock_node (rn
);
1306 if (IS_RIP_DEBUG_EVENT
)
1307 zlog_debug ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte
->nexthop
));
1308 rte
->nexthop
.s_addr
= 0;
1314 /* For RIPv1, there won't be a valid netmask.
1316 This is a best guess at the masks. If everyone was using old
1317 Ciscos before the 'ip subnet zero' option, it would be almost
1320 Cisco summarize ripv1 advertisments to the classful boundary
1321 (/16 for class B's) except when the RIP packet does to inside
1322 the classful network in question. */
1324 if ((packet
->version
== RIPv1
&& rte
->prefix
.s_addr
!= 0)
1325 || (packet
->version
== RIPv2
1326 && (rte
->prefix
.s_addr
!= 0 && rte
->mask
.s_addr
== 0)))
1328 u_int32_t destination
;
1330 if (subnetted
== -1)
1332 memcpy (&ifaddr
, ifc
->address
, sizeof (struct prefix_ipv4
));
1333 memcpy (&ifaddrclass
, &ifaddr
, sizeof (struct prefix_ipv4
));
1334 apply_classful_mask_ipv4 (&ifaddrclass
);
1336 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1340 destination
= ntohl (rte
->prefix
.s_addr
);
1342 if (IN_CLASSA (destination
))
1343 masklen2ip (8, &rte
->mask
);
1344 else if (IN_CLASSB (destination
))
1345 masklen2ip (16, &rte
->mask
);
1346 else if (IN_CLASSC (destination
))
1347 masklen2ip (24, &rte
->mask
);
1350 masklen2ip (ifaddrclass
.prefixlen
,
1351 (struct in_addr
*) &destination
);
1352 if ((subnetted
== 1) && ((rte
->prefix
.s_addr
& destination
) ==
1353 ifaddrclass
.prefix
.s_addr
))
1355 masklen2ip (ifaddr
.prefixlen
, &rte
->mask
);
1356 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
) != rte
->prefix
.s_addr
)
1357 masklen2ip (32, &rte
->mask
);
1358 if (IS_RIP_DEBUG_EVENT
)
1359 zlog_debug ("Subnetted route %s", inet_ntoa (rte
->prefix
));
1363 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
) != rte
->prefix
.s_addr
)
1367 if (IS_RIP_DEBUG_EVENT
)
1369 zlog_debug ("Resultant route %s", inet_ntoa (rte
->prefix
));
1370 zlog_debug ("Resultant mask %s", inet_ntoa (rte
->mask
));
1374 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1375 ignore the entry. */
1376 if ((packet
->version
== RIPv2
)
1377 && (rte
->mask
.s_addr
!= 0)
1378 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
) != rte
->prefix
.s_addr
))
1380 zlog_warn ("RIPv2 address %s is not mask /%d applied one",
1381 inet_ntoa (rte
->prefix
), ip_masklen (rte
->mask
));
1382 rip_peer_bad_route (from
);
1386 /* Default route's netmask is ignored. */
1387 if (packet
->version
== RIPv2
1388 && (rte
->prefix
.s_addr
== 0)
1389 && (rte
->mask
.s_addr
!= 0))
1391 if (IS_RIP_DEBUG_EVENT
)
1392 zlog_debug ("Default route with non-zero netmask. Set zero to netmask");
1393 rte
->mask
.s_addr
= 0;
1396 /* Routing table updates. */
1397 rip_rte_process (rte
, from
, ifc
->ifp
);
1401 /* Make socket for RIP protocol. */
1403 rip_create_socket (struct sockaddr_in
*from
)
1407 struct sockaddr_in addr
;
1409 memset (&addr
, 0, sizeof (struct sockaddr_in
));
1413 addr
.sin_family
= AF_INET
;
1414 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1415 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1416 addr
.sin_len
= sizeof (struct sockaddr_in
);
1417 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1419 memcpy(&addr
, from
, sizeof(addr
));
1422 /* sending port must always be the RIP port */
1423 addr
.sin_port
= htons (RIP_PORT_DEFAULT
);
1425 /* Make datagram socket. */
1426 sock
= socket (AF_INET
, SOCK_DGRAM
, 0);
1429 zlog_err("Cannot create UDP socket: %s", safe_strerror(errno
));
1433 sockopt_broadcast (sock
);
1434 sockopt_reuseaddr (sock
);
1435 sockopt_reuseport (sock
);
1437 setsockopt_pktinfo (sock
);
1438 #endif /* RIP_RECVMSG */
1439 #ifdef IPTOS_PREC_INTERNETCONTROL
1440 setsockopt_ipv4_tos (sock
, IPTOS_PREC_INTERNETCONTROL
);
1443 if (ripd_privs
.change (ZPRIVS_RAISE
))
1444 zlog_err ("rip_create_socket: could not raise privs");
1445 setsockopt_so_recvbuf (sock
, RIP_UDP_RCV_BUF
);
1446 if ( (ret
= bind (sock
, (struct sockaddr
*) & addr
, sizeof (addr
))) < 0)
1449 int save_errno
= errno
;
1450 if (ripd_privs
.change (ZPRIVS_LOWER
))
1451 zlog_err ("rip_create_socket: could not lower privs");
1453 zlog_err("%s: Can't bind socket %d to %s port %d: %s", __func__
,
1454 sock
, inet_ntoa(addr
.sin_addr
),
1455 (int) ntohs(addr
.sin_port
),
1456 safe_strerror(save_errno
));
1462 if (ripd_privs
.change (ZPRIVS_LOWER
))
1463 zlog_err ("rip_create_socket: could not lower privs");
1468 /* RIP packet send to destination address, on interface denoted by
1469 * by connected argument. NULL to argument denotes destination should be
1470 * should be RIP multicast group
1473 rip_send_packet (u_char
* buf
, int size
, struct sockaddr_in
*to
,
1474 struct connected
*ifc
)
1477 struct sockaddr_in sin
;
1479 assert (ifc
!= NULL
);
1481 if (IS_RIP_DEBUG_PACKET
)
1483 #define ADDRESS_SIZE 20
1484 char dst
[ADDRESS_SIZE
];
1485 dst
[ADDRESS_SIZE
- 1] = '\0';
1489 strncpy (dst
, inet_ntoa(to
->sin_addr
), ADDRESS_SIZE
- 1);
1493 sin
.sin_addr
.s_addr
= htonl (INADDR_RIP_GROUP
);
1494 strncpy (dst
, inet_ntoa(sin
.sin_addr
), ADDRESS_SIZE
- 1);
1497 zlog_debug("rip_send_packet %s > %s (%s)",
1498 inet_ntoa(ifc
->address
->u
.prefix4
),
1499 dst
, ifc
->ifp
->name
);
1502 if ( CHECK_FLAG (ifc
->flags
, ZEBRA_IFA_SECONDARY
) )
1505 * ZEBRA_IFA_SECONDARY is set on linux when an interface is configured
1506 * with multiple addresses on the same subnet: the first address
1507 * on the subnet is configured "primary", and all subsequent addresses
1508 * on that subnet are treated as "secondary" addresses.
1509 * In order to avoid routing-table bloat on other rip listeners,
1510 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY source addrs.
1511 * XXX Since Linux is the only system for which the ZEBRA_IFA_SECONDARY
1512 * flag is set, we would end up sending a packet for a "secondary"
1513 * source address on non-linux systems.
1515 if (IS_RIP_DEBUG_PACKET
)
1516 zlog_debug("duplicate dropped");
1520 /* Make destination address. */
1521 memset (&sin
, 0, sizeof (struct sockaddr_in
));
1522 sin
.sin_family
= AF_INET
;
1523 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1524 sin
.sin_len
= sizeof (struct sockaddr_in
);
1525 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1527 /* When destination is specified, use it's port and address. */
1530 sin
.sin_port
= to
->sin_port
;
1531 sin
.sin_addr
= to
->sin_addr
;
1532 send_sock
= rip
->sock
;
1536 struct sockaddr_in from
;
1538 sin
.sin_port
= htons (RIP_PORT_DEFAULT
);
1539 sin
.sin_addr
.s_addr
= htonl (INADDR_RIP_GROUP
);
1541 /* multicast send should bind to local interface address */
1542 memset (&from
, 0, sizeof (from
));
1543 from
.sin_family
= AF_INET
;
1544 from
.sin_port
= htons (RIP_PORT_DEFAULT
);
1545 from
.sin_addr
= ifc
->address
->u
.prefix4
;
1546 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1547 from
.sin_len
= sizeof (struct sockaddr_in
);
1548 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1551 * we have to open a new socket for each packet because this
1552 * is the most portable way to bind to a different source
1553 * ipv4 address for each packet.
1555 if ( (send_sock
= rip_create_socket (&from
)) < 0)
1557 zlog_warn("rip_send_packet could not create socket.");
1560 rip_interface_multicast_set (send_sock
, ifc
);
1563 ret
= sendto (send_sock
, buf
, size
, 0, (struct sockaddr
*)&sin
,
1564 sizeof (struct sockaddr_in
));
1566 if (IS_RIP_DEBUG_EVENT
)
1567 zlog_debug ("SEND to %s.%d", inet_ntoa(sin
.sin_addr
),
1568 ntohs (sin
.sin_port
));
1571 zlog_warn ("can't send packet : %s", safe_strerror (errno
));
1579 /* Add redistributed route to RIP table. */
1581 rip_redistribute_add (int type
, int sub_type
, struct prefix_ipv4
*p
,
1582 ifindex_t ifindex
, struct in_addr
*nexthop
,
1583 unsigned int metric
, unsigned char distance
)
1586 struct route_node
*rp
= NULL
;
1587 struct rip_info
*rinfo
= NULL
, newinfo
;
1588 struct list
*list
= NULL
;
1590 /* Redistribute route */
1591 ret
= rip_destination_check (p
->prefix
);
1595 rp
= route_node_get (rip
->table
, (struct prefix
*) p
);
1597 memset (&newinfo
, 0, sizeof (struct rip_info
));
1598 newinfo
.type
= type
;
1599 newinfo
.sub_type
= sub_type
;
1600 newinfo
.ifindex
= ifindex
;
1602 newinfo
.external_metric
= metric
;
1603 newinfo
.distance
= distance
;
1606 newinfo
.nexthop
= *nexthop
;
1608 if ((list
= rp
->info
) != NULL
&& listcount (list
) != 0)
1610 rinfo
= listgetdata (listhead (list
));
1612 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
1613 && rinfo
->sub_type
== RIP_ROUTE_INTERFACE
1614 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
1616 route_unlock_node (rp
);
1620 /* Manually configured RIP route check. */
1621 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1622 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
) ||
1623 (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
)) )
1625 if (type
!= ZEBRA_ROUTE_RIP
|| ((sub_type
!= RIP_ROUTE_STATIC
) &&
1626 (sub_type
!= RIP_ROUTE_DEFAULT
)))
1628 route_unlock_node (rp
);
1633 rinfo
= rip_ecmp_replace (&newinfo
);
1634 route_unlock_node (rp
);
1637 rinfo
= rip_ecmp_add (&newinfo
);
1639 if (IS_RIP_DEBUG_EVENT
) {
1641 zlog_debug ("Redistribute new prefix %s/%d on the interface %s",
1642 inet_ntoa(p
->prefix
), p
->prefixlen
,
1643 ifindex2ifname(ifindex
));
1645 zlog_debug ("Redistribute new prefix %s/%d with nexthop %s on the interface %s",
1646 inet_ntoa(p
->prefix
), p
->prefixlen
, inet_ntoa(rinfo
->nexthop
),
1647 ifindex2ifname(ifindex
));
1650 rip_event (RIP_TRIGGERED_UPDATE
, 0);
1653 /* Delete redistributed route from RIP table. */
1655 rip_redistribute_delete (int type
, int sub_type
, struct prefix_ipv4
*p
,
1659 struct route_node
*rp
;
1660 struct rip_info
*rinfo
;
1662 ret
= rip_destination_check (p
->prefix
);
1666 rp
= route_node_lookup (rip
->table
, (struct prefix
*) p
);
1669 struct list
*list
= rp
->info
;
1671 if (list
!= NULL
&& listcount (list
) != 0)
1673 rinfo
= listgetdata (listhead (list
));
1675 && rinfo
->type
== type
1676 && rinfo
->sub_type
== sub_type
1677 && rinfo
->ifindex
== ifindex
)
1679 /* Perform poisoned reverse. */
1680 rinfo
->metric
= RIP_METRIC_INFINITY
;
1681 RIP_TIMER_ON (rinfo
->t_garbage_collect
,
1682 rip_garbage_collect
, rip
->garbage_time
);
1683 RIP_TIMER_OFF (rinfo
->t_timeout
);
1684 rinfo
->flags
|= RIP_RTF_CHANGED
;
1686 if (IS_RIP_DEBUG_EVENT
)
1687 zlog_debug ("Poisone %s/%d on the interface %s with an "
1688 "infinity metric [delete]",
1689 inet_ntoa(p
->prefix
), p
->prefixlen
,
1690 ifindex2ifname(ifindex
));
1692 rip_event (RIP_TRIGGERED_UPDATE
, 0);
1695 route_unlock_node (rp
);
1699 /* Response to request called from rip_read ().*/
1701 rip_request_process (struct rip_packet
*packet
, int size
,
1702 struct sockaddr_in
*from
, struct connected
*ifc
)
1706 struct prefix_ipv4 p
;
1707 struct route_node
*rp
;
1708 struct rip_info
*rinfo
;
1709 struct rip_interface
*ri
;
1711 /* Does not reponse to the requests on the loopback interfaces */
1712 if (if_is_loopback (ifc
->ifp
))
1715 /* Check RIP process is enabled on this interface. */
1716 ri
= ifc
->ifp
->info
;
1720 /* When passive interface is specified, suppress responses */
1724 /* RIP peer update. */
1725 rip_peer_update (from
, packet
->version
);
1727 lim
= ((caddr_t
) packet
) + size
;
1730 /* The Request is processed entry by entry. If there are no
1731 entries, no response is given. */
1732 if (lim
== (caddr_t
) rte
)
1735 /* There is one special case. If there is exactly one entry in the
1736 request, and it has an address family identifier of zero and a
1737 metric of infinity (i.e., 16), then this is a request to send the
1738 entire routing table. */
1739 if (lim
== ((caddr_t
) (rte
+ 1)) &&
1740 ntohs (rte
->family
) == 0 &&
1741 ntohl (rte
->metric
) == RIP_METRIC_INFINITY
)
1743 /* All route with split horizon */
1744 rip_output_process (ifc
, from
, rip_all_route
, packet
->version
);
1748 /* Examine the list of RTEs in the Request one by one. For each
1749 entry, look up the destination in the router's routing
1750 database and, if there is a route, put that route's metric in
1751 the metric field of the RTE. If there is no explicit route
1752 to the specified destination, put infinity in the metric
1753 field. Once all the entries have been filled in, change the
1754 command from Request to Response and send the datagram back
1755 to the requestor. */
1758 for (; ((caddr_t
) rte
) < lim
; rte
++)
1760 p
.prefix
= rte
->prefix
;
1761 p
.prefixlen
= ip_masklen (rte
->mask
);
1762 apply_mask_ipv4 (&p
);
1764 rp
= route_node_lookup (rip
->table
, (struct prefix
*) &p
);
1767 rinfo
= listgetdata (listhead ((struct list
*)rp
->info
));
1768 rte
->metric
= htonl (rinfo
->metric
);
1769 route_unlock_node (rp
);
1772 rte
->metric
= htonl (RIP_METRIC_INFINITY
);
1774 packet
->command
= RIP_RESPONSE
;
1776 rip_send_packet ((u_char
*)packet
, size
, from
, ifc
);
1778 rip_global_queries
++;
1782 /* Set IPv6 packet info to the socket. */
1784 setsockopt_pktinfo (int sock
)
1789 ret
= setsockopt(sock
, IPPROTO_IP
, IP_PKTINFO
, &val
, sizeof(val
));
1791 zlog_warn ("Can't setsockopt IP_PKTINFO : %s", safe_strerror (errno
));
1795 /* Read RIP packet by recvmsg function. */
1797 rip_recvmsg (int sock
, u_char
*buf
, int size
, struct sockaddr_in
*from
,
1803 struct cmsghdr
*ptr
;
1806 msg
.msg_name
= (void *) from
;
1807 msg
.msg_namelen
= sizeof (struct sockaddr_in
);
1810 msg
.msg_control
= (void *) adata
;
1811 msg
.msg_controllen
= sizeof adata
;
1815 ret
= recvmsg (sock
, &msg
, 0);
1819 for (ptr
= ZCMSG_FIRSTHDR(&msg
); ptr
!= NULL
; ptr
= CMSG_NXTHDR(&msg
, ptr
))
1820 if (ptr
->cmsg_level
== IPPROTO_IP
&& ptr
->cmsg_type
== IP_PKTINFO
)
1822 struct in_pktinfo
*pktinfo
;
1825 pktinfo
= (struct in_pktinfo
*) CMSG_DATA (ptr
);
1826 i
= pktinfo
->ipi_ifindex
;
1831 /* RIP packet read function. */
1833 rip_read_new (struct thread
*t
)
1837 char buf
[RIP_PACKET_MAXSIZ
];
1838 struct sockaddr_in from
;
1841 /* Fetch socket then register myself. */
1842 sock
= THREAD_FD (t
);
1843 rip_event (RIP_READ
, sock
);
1845 /* Read RIP packet. */
1846 ret
= rip_recvmsg (sock
, buf
, RIP_PACKET_MAXSIZ
, &from
, (int *)&ifindex
);
1849 zlog_warn ("Can't read RIP packet: %s", safe_strerror (errno
));
1855 #endif /* RIP_RECVMSG */
1857 /* First entry point of RIP packet. */
1859 rip_read (struct thread
*t
)
1864 union rip_buf rip_buf
;
1865 struct rip_packet
*packet
;
1866 struct sockaddr_in from
;
1870 struct interface
*ifp
;
1871 struct connected
*ifc
;
1872 struct rip_interface
*ri
;
1875 /* Fetch socket then register myself. */
1876 sock
= THREAD_FD (t
);
1879 /* Add myself to tne next event */
1880 rip_event (RIP_READ
, sock
);
1882 /* RIPd manages only IPv4. */
1883 memset (&from
, 0, sizeof (struct sockaddr_in
));
1884 fromlen
= sizeof (struct sockaddr_in
);
1886 len
= recvfrom (sock
, (char *)&rip_buf
.buf
, sizeof (rip_buf
.buf
), 0,
1887 (struct sockaddr
*) &from
, &fromlen
);
1890 zlog_info ("recvfrom failed: %s", safe_strerror (errno
));
1894 /* Check is this packet comming from myself? */
1895 if (if_check_address (from
.sin_addr
))
1897 if (IS_RIP_DEBUG_PACKET
)
1898 zlog_debug ("ignore packet comes from myself");
1902 /* Which interface is this packet comes from. */
1903 ifp
= if_lookup_address ((void *)&from
.sin_addr
, AF_INET
);
1905 /* RIP packet received */
1906 if (IS_RIP_DEBUG_EVENT
)
1907 zlog_debug ("RECV packet from %s port %d on %s",
1908 inet_ntoa (from
.sin_addr
), ntohs (from
.sin_port
),
1909 ifp
? ifp
->name
: "unknown");
1911 /* If this packet come from unknown interface, ignore it. */
1914 zlog_info ("rip_read: cannot find interface for packet from %s port %d",
1915 inet_ntoa(from
.sin_addr
), ntohs (from
.sin_port
));
1920 p
.u
.prefix4
= from
.sin_addr
;
1921 p
.prefixlen
= IPV4_MAX_BITLEN
;
1923 ifc
= connected_lookup_prefix (ifp
, &p
);
1927 zlog_info ("rip_read: cannot find connected address for packet from %s "
1928 "port %d on interface %s",
1929 inet_ntoa(from
.sin_addr
), ntohs (from
.sin_port
), ifp
->name
);
1933 /* Packet length check. */
1934 if (len
< RIP_PACKET_MINSIZ
)
1936 zlog_warn ("packet size %d is smaller than minimum size %d",
1937 len
, RIP_PACKET_MINSIZ
);
1938 rip_peer_bad_packet (&from
);
1941 if (len
> RIP_PACKET_MAXSIZ
)
1943 zlog_warn ("packet size %d is larger than max size %d",
1944 len
, RIP_PACKET_MAXSIZ
);
1945 rip_peer_bad_packet (&from
);
1949 /* Packet alignment check. */
1950 if ((len
- RIP_PACKET_MINSIZ
) % 20)
1952 zlog_warn ("packet size %d is wrong for RIP packet alignment", len
);
1953 rip_peer_bad_packet (&from
);
1957 /* Set RTE number. */
1958 rtenum
= ((len
- RIP_PACKET_MINSIZ
) / 20);
1960 /* For easy to handle. */
1961 packet
= &rip_buf
.rip_packet
;
1963 /* RIP version check. */
1964 if (packet
->version
== 0)
1966 zlog_info ("version 0 with command %d received.", packet
->command
);
1967 rip_peer_bad_packet (&from
);
1971 /* Dump RIP packet. */
1972 if (IS_RIP_DEBUG_RECV
)
1973 rip_packet_dump (packet
, len
, "RECV");
1975 /* RIP version adjust. This code should rethink now. RFC1058 says
1976 that "Version 1 implementations are to ignore this extra data and
1977 process only the fields specified in this document.". So RIPv3
1978 packet should be treated as RIPv1 ignoring must be zero field. */
1979 if (packet
->version
> RIPv2
)
1980 packet
->version
= RIPv2
;
1982 /* Is RIP running or is this RIP neighbor ?*/
1984 if (! ri
->running
&& ! rip_neighbor_lookup (&from
))
1986 if (IS_RIP_DEBUG_EVENT
)
1987 zlog_debug ("RIP is not enabled on interface %s.", ifp
->name
);
1988 rip_peer_bad_packet (&from
);
1992 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1993 vrecv
= ((ri
->ri_receive
== RI_RIP_UNSPEC
) ?
1994 rip
->version_recv
: ri
->ri_receive
);
1995 if ((packet
->version
== RIPv1
) && !(vrecv
& RIPv1
))
1997 if (IS_RIP_DEBUG_PACKET
)
1998 zlog_debug (" packet's v%d doesn't fit to if version spec",
2000 rip_peer_bad_packet (&from
);
2003 if ((packet
->version
== RIPv2
) && !(vrecv
& RIPv2
))
2005 if (IS_RIP_DEBUG_PACKET
)
2006 zlog_debug (" packet's v%d doesn't fit to if version spec",
2008 rip_peer_bad_packet (&from
);
2012 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
2013 messages, then RIP-1 and unauthenticated RIP-2 messages will be
2014 accepted; authenticated RIP-2 messages shall be discarded. */
2015 if ((ri
->auth_type
== RIP_NO_AUTH
)
2017 && (packet
->version
== RIPv2
)
2018 && (packet
->rte
->family
== htons(RIP_FAMILY_AUTH
)))
2020 if (IS_RIP_DEBUG_EVENT
)
2021 zlog_debug ("packet RIPv%d is dropped because authentication disabled",
2023 rip_peer_bad_packet (&from
);
2028 If the router is configured to authenticate RIP-2 messages, then
2029 RIP-1 messages and RIP-2 messages which pass authentication
2030 testing shall be accepted; unauthenticated and failed
2031 authentication RIP-2 messages shall be discarded. For maximum
2032 security, RIP-1 messages should be ignored when authentication is
2033 in use (see section 4.1); otherwise, the routing information from
2034 authenticated messages will be propagated by RIP-1 routers in an
2035 unauthenticated manner.
2037 /* We make an exception for RIPv1 REQUEST packets, to which we'll
2038 * always reply regardless of authentication settings, because:
2040 * - if there other authorised routers on-link, the REQUESTor can
2041 * passively obtain the routing updates anyway
2042 * - if there are no other authorised routers on-link, RIP can
2043 * easily be disabled for the link to prevent giving out information
2044 * on state of this routers RIP routing table..
2046 * I.e. if RIPv1 has any place anymore these days, it's as a very
2047 * simple way to distribute routing information (e.g. to embedded
2048 * hosts / appliances) and the ability to give out RIPv1
2049 * routing-information freely, while still requiring RIPv2
2050 * authentication for any RESPONSEs might be vaguely useful.
2052 if (ri
->auth_type
!= RIP_NO_AUTH
2053 && packet
->version
== RIPv1
)
2055 /* Discard RIPv1 messages other than REQUESTs */
2056 if (packet
->command
!= RIP_REQUEST
)
2058 if (IS_RIP_DEBUG_PACKET
)
2059 zlog_debug ("RIPv1" " dropped because authentication enabled");
2060 rip_peer_bad_packet (&from
);
2064 else if (ri
->auth_type
!= RIP_NO_AUTH
)
2066 const char *auth_desc
;
2070 /* There definitely is no authentication in the packet. */
2071 if (IS_RIP_DEBUG_PACKET
)
2072 zlog_debug ("RIPv2 authentication failed: no auth RTE in packet");
2073 rip_peer_bad_packet (&from
);
2077 /* First RTE must be an Authentication Family RTE */
2078 if (packet
->rte
->family
!= htons(RIP_FAMILY_AUTH
))
2080 if (IS_RIP_DEBUG_PACKET
)
2081 zlog_debug ("RIPv2" " dropped because authentication enabled");
2082 rip_peer_bad_packet (&from
);
2086 /* Check RIPv2 authentication. */
2087 switch (ntohs(packet
->rte
->tag
))
2089 case RIP_AUTH_SIMPLE_PASSWORD
:
2090 auth_desc
= "simple";
2091 ret
= rip_auth_simple_password (packet
->rte
, &from
, ifp
);
2096 ret
= rip_auth_md5 (packet
, &from
, len
, ifp
);
2097 /* Reset RIP packet length to trim MD5 data. */
2103 auth_desc
= "unknown type";
2104 if (IS_RIP_DEBUG_PACKET
)
2105 zlog_debug ("RIPv2 Unknown authentication type %d",
2106 ntohs (packet
->rte
->tag
));
2111 if (IS_RIP_DEBUG_PACKET
)
2112 zlog_debug ("RIPv2 %s authentication success", auth_desc
);
2116 if (IS_RIP_DEBUG_PACKET
)
2117 zlog_debug ("RIPv2 %s authentication failure", auth_desc
);
2118 rip_peer_bad_packet (&from
);
2123 /* Process each command. */
2124 switch (packet
->command
)
2127 rip_response_process (packet
, len
, &from
, ifc
);
2131 rip_request_process (packet
, len
, &from
, ifc
);
2135 zlog_info ("Obsolete command %s received, please sent it to routed",
2136 lookup (rip_msg
, packet
->command
));
2137 rip_peer_bad_packet (&from
);
2139 case RIP_POLL_ENTRY
:
2140 zlog_info ("Obsolete command %s received",
2141 lookup (rip_msg
, packet
->command
));
2142 rip_peer_bad_packet (&from
);
2145 zlog_info ("Unknown RIP command %d received", packet
->command
);
2146 rip_peer_bad_packet (&from
);
2153 /* Write routing table entry to the stream and return next index of
2154 the routing table entry in the stream. */
2156 rip_write_rte (int num
, struct stream
*s
, struct prefix_ipv4
*p
,
2157 u_char version
, struct rip_info
*rinfo
)
2159 struct in_addr mask
;
2161 /* Write routing table entry. */
2162 if (version
== RIPv1
)
2164 stream_putw (s
, AF_INET
);
2166 stream_put_ipv4 (s
, p
->prefix
.s_addr
);
2167 stream_put_ipv4 (s
, 0);
2168 stream_put_ipv4 (s
, 0);
2169 stream_putl (s
, rinfo
->metric_out
);
2173 masklen2ip (p
->prefixlen
, &mask
);
2175 stream_putw (s
, AF_INET
);
2176 stream_putw (s
, rinfo
->tag_out
);
2177 stream_put_ipv4 (s
, p
->prefix
.s_addr
);
2178 stream_put_ipv4 (s
, mask
.s_addr
);
2179 stream_put_ipv4 (s
, rinfo
->nexthop_out
.s_addr
);
2180 stream_putl (s
, rinfo
->metric_out
);
2186 /* Send update to the ifp or spcified neighbor. */
2188 rip_output_process (struct connected
*ifc
, struct sockaddr_in
*to
,
2189 int route_type
, u_char version
)
2193 struct route_node
*rp
;
2194 struct rip_info
*rinfo
;
2195 struct rip_interface
*ri
;
2196 struct prefix_ipv4
*p
;
2197 struct prefix_ipv4 classfull
;
2198 struct prefix_ipv4 ifaddrclass
;
2199 struct key
*key
= NULL
;
2200 /* this might need to made dynamic if RIP ever supported auth methods
2201 with larger key string sizes */
2202 char auth_str
[RIP_AUTH_SIMPLE_SIZE
];
2203 size_t doff
= 0; /* offset of digest offset field */
2207 struct list
*list
= NULL
;
2208 struct listnode
*listnode
= NULL
;
2210 /* Logging output event. */
2211 if (IS_RIP_DEBUG_EVENT
)
2214 zlog_debug ("update routes to neighbor %s", inet_ntoa (to
->sin_addr
));
2216 zlog_debug ("update routes on interface %s ifindex %d",
2217 ifc
->ifp
->name
, ifc
->ifp
->ifindex
);
2220 /* Set output stream. */
2223 /* Reset stream and RTE counter. */
2225 rtemax
= RIP_MAX_RTE
;
2227 /* Get RIP interface. */
2228 ri
= ifc
->ifp
->info
;
2230 /* If output interface is in simple password authentication mode, we
2231 need space for authentication data. */
2232 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2235 /* If output interface is in MD5 authentication mode, we need space
2236 for authentication header and data. */
2237 if (ri
->auth_type
== RIP_AUTH_MD5
)
2240 /* If output interface is in simple password authentication mode
2241 and string or keychain is specified we need space for auth. data */
2242 if (ri
->auth_type
!= RIP_NO_AUTH
)
2246 struct keychain
*keychain
;
2248 keychain
= keychain_lookup (ri
->key_chain
);
2250 key
= key_lookup_for_send (keychain
);
2252 /* to be passed to auth functions later */
2253 rip_auth_prepare_str_send (ri
, key
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
2256 if (version
== RIPv1
)
2258 memcpy (&ifaddrclass
, ifc
->address
, sizeof (struct prefix_ipv4
));
2259 apply_classful_mask_ipv4 (&ifaddrclass
);
2261 if (ifc
->address
->prefixlen
> ifaddrclass
.prefixlen
)
2265 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
2266 if ((list
= rp
->info
) != NULL
&& listcount (list
) != 0)
2268 rinfo
= listgetdata (listhead (list
));
2269 /* For RIPv1, if we are subnetted, output subnets in our network */
2270 /* that have the same mask as the output "interface". For other */
2271 /* networks, only the classfull version is output. */
2273 if (version
== RIPv1
)
2275 p
= (struct prefix_ipv4
*) &rp
->p
;
2277 if (IS_RIP_DEBUG_PACKET
)
2278 zlog_debug("RIPv1 mask check, %s/%d considered for output",
2279 inet_ntoa (rp
->p
.u
.prefix4
), rp
->p
.prefixlen
);
2282 prefix_match ((struct prefix
*) &ifaddrclass
, &rp
->p
))
2284 if ((ifc
->address
->prefixlen
!= rp
->p
.prefixlen
) &&
2285 (rp
->p
.prefixlen
!= 32))
2290 memcpy (&classfull
, &rp
->p
, sizeof(struct prefix_ipv4
));
2291 apply_classful_mask_ipv4(&classfull
);
2292 if (rp
->p
.u
.prefix4
.s_addr
!= 0 &&
2293 classfull
.prefixlen
!= rp
->p
.prefixlen
)
2296 if (IS_RIP_DEBUG_PACKET
)
2297 zlog_debug("RIPv1 mask check, %s/%d made it through",
2298 inet_ntoa (rp
->p
.u
.prefix4
), rp
->p
.prefixlen
);
2301 p
= (struct prefix_ipv4
*) &rp
->p
;
2303 /* Apply output filters. */
2304 ret
= rip_outgoing_filter (p
, ri
);
2308 /* Changed route only output. */
2309 if (route_type
== rip_changed_route
&&
2310 (! (rinfo
->flags
& RIP_RTF_CHANGED
)))
2313 /* Split horizon. */
2314 /* if (split_horizon == rip_split_horizon) */
2315 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
)
2318 * We perform split horizon for RIP and connected route.
2319 * For rip routes, we want to suppress the route if we would
2320 * end up sending the route back on the interface that we
2321 * learned it from, with a higher metric. For connected routes,
2322 * we suppress the route if the prefix is a subset of the
2323 * source address that we are going to use for the packet
2324 * (in order to handle the case when multiple subnets are
2325 * configured on the same interface).
2328 struct rip_info
*tmp_rinfo
= NULL
;
2330 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, tmp_rinfo
))
2331 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
&&
2332 tmp_rinfo
->ifindex
== ifc
->ifp
->ifindex
)
2338 if (!suppress
&& rinfo
->type
== ZEBRA_ROUTE_CONNECT
&&
2339 prefix_match((struct prefix
*)p
, ifc
->address
))
2346 /* Preparation for route-map. */
2347 rinfo
->metric_set
= 0;
2348 rinfo
->nexthop_out
.s_addr
= 0;
2349 rinfo
->metric_out
= rinfo
->metric
;
2350 rinfo
->tag_out
= rinfo
->tag
;
2351 rinfo
->ifindex_out
= ifc
->ifp
->ifindex
;
2353 /* In order to avoid some local loops,
2354 * if the RIP route has a nexthop via this interface, keep the nexthop,
2355 * otherwise set it to 0. The nexthop should not be propagated
2356 * beyond the local broadcast/multicast area in order
2357 * to avoid an IGP multi-level recursive look-up.
2360 if (rinfo
->ifindex
== ifc
->ifp
->ifindex
)
2361 rinfo
->nexthop_out
= rinfo
->nexthop
;
2363 /* Interface route-map */
2364 if (ri
->routemap
[RIP_FILTER_OUT
])
2366 ret
= route_map_apply (ri
->routemap
[RIP_FILTER_OUT
],
2367 (struct prefix
*) p
, RMAP_RIP
,
2370 if (ret
== RMAP_DENYMATCH
)
2372 if (IS_RIP_DEBUG_PACKET
)
2373 zlog_debug ("RIP %s/%d is filtered by route-map out",
2374 inet_ntoa (p
->prefix
), p
->prefixlen
);
2379 /* Apply redistribute route map - continue, if deny */
2380 if (rip
->route_map
[rinfo
->type
].name
2381 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
)
2383 ret
= route_map_apply (rip
->route_map
[rinfo
->type
].map
,
2384 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2386 if (ret
== RMAP_DENYMATCH
)
2388 if (IS_RIP_DEBUG_PACKET
)
2389 zlog_debug ("%s/%d is filtered by route-map",
2390 inet_ntoa (p
->prefix
), p
->prefixlen
);
2395 /* When route-map does not set metric. */
2396 if (! rinfo
->metric_set
)
2398 /* If redistribute metric is set. */
2399 if (rip
->route_map
[rinfo
->type
].metric_config
2400 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
2402 rinfo
->metric_out
= rip
->route_map
[rinfo
->type
].metric
;
2406 /* If the route is not connected or localy generated
2407 one, use default-metric value*/
2408 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2409 && rinfo
->type
!= ZEBRA_ROUTE_CONNECT
2410 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
2411 rinfo
->metric_out
= rip
->default_metric
;
2415 /* Apply offset-list */
2416 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2417 rip_offset_list_apply_out (p
, ifc
->ifp
, &rinfo
->metric_out
);
2419 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2420 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2422 /* Perform split-horizon with poisoned reverse
2423 * for RIP and connected routes.
2425 if (ri
->split_horizon
== RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2427 * We perform split horizon for RIP and connected route.
2428 * For rip routes, we want to suppress the route if we would
2429 * end up sending the route back on the interface that we
2430 * learned it from, with a higher metric. For connected routes,
2431 * we suppress the route if the prefix is a subset of the
2432 * source address that we are going to use for the packet
2433 * (in order to handle the case when multiple subnets are
2434 * configured on the same interface).
2436 struct rip_info
*tmp_rinfo
= NULL
;
2438 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, tmp_rinfo
))
2439 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
&&
2440 tmp_rinfo
->ifindex
== ifc
->ifp
->ifindex
)
2441 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2442 if (tmp_rinfo
->type
== ZEBRA_ROUTE_CONNECT
&&
2443 prefix_match((struct prefix
*)p
, ifc
->address
))
2444 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2447 /* Prepare preamble, auth headers, if needs be */
2450 stream_putc (s
, RIP_RESPONSE
);
2451 stream_putc (s
, version
);
2454 /* auth header for !v1 && !no_auth */
2455 if ( (ri
->auth_type
!= RIP_NO_AUTH
) && (version
!= RIPv1
) )
2456 doff
= rip_auth_header_write (s
, ri
, key
, auth_str
,
2457 RIP_AUTH_SIMPLE_SIZE
);
2460 /* Write RTE to the stream. */
2461 num
= rip_write_rte (num
, s
, p
, version
, rinfo
);
2464 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2465 rip_auth_md5_set (s
, ri
, doff
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
2467 ret
= rip_send_packet (STREAM_DATA (s
), stream_get_endp (s
),
2470 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2471 rip_packet_dump ((struct rip_packet
*)STREAM_DATA (s
),
2472 stream_get_endp(s
), "SEND");
2478 /* Flush unwritten RTE. */
2481 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2482 rip_auth_md5_set (s
, ri
, doff
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
2484 ret
= rip_send_packet (STREAM_DATA (s
), stream_get_endp (s
), to
, ifc
);
2486 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2487 rip_packet_dump ((struct rip_packet
*)STREAM_DATA (s
),
2488 stream_get_endp (s
), "SEND");
2493 /* Statistics updates. */
2497 /* Send RIP packet to the interface. */
2499 rip_update_interface (struct connected
*ifc
, u_char version
, int route_type
)
2501 struct sockaddr_in to
;
2503 /* When RIP version is 2 and multicast enable interface. */
2504 if (version
== RIPv2
&& if_is_multicast (ifc
->ifp
))
2506 if (IS_RIP_DEBUG_EVENT
)
2507 zlog_debug ("multicast announce on %s ", ifc
->ifp
->name
);
2509 rip_output_process (ifc
, NULL
, route_type
, version
);
2513 /* If we can't send multicast packet, send it with unicast. */
2514 if (if_is_broadcast (ifc
->ifp
) || if_is_pointopoint (ifc
->ifp
))
2516 if (ifc
->address
->family
== AF_INET
)
2518 /* Destination address and port setting. */
2519 memset (&to
, 0, sizeof (struct sockaddr_in
));
2520 if (ifc
->destination
)
2521 /* use specified broadcast or peer destination addr */
2522 to
.sin_addr
= ifc
->destination
->u
.prefix4
;
2523 else if (ifc
->address
->prefixlen
< IPV4_MAX_PREFIXLEN
)
2524 /* calculate the appropriate broadcast address */
2525 to
.sin_addr
.s_addr
=
2526 ipv4_broadcast_addr(ifc
->address
->u
.prefix4
.s_addr
,
2527 ifc
->address
->prefixlen
);
2529 /* do not know where to send the packet */
2531 to
.sin_port
= htons (RIP_PORT_DEFAULT
);
2533 if (IS_RIP_DEBUG_EVENT
)
2534 zlog_debug("%s announce to %s on %s",
2535 CONNECTED_PEER(ifc
) ? "unicast" : "broadcast",
2536 inet_ntoa (to
.sin_addr
), ifc
->ifp
->name
);
2538 rip_output_process (ifc
, &to
, route_type
, version
);
2543 /* Update send to all interface and neighbor. */
2545 rip_update_process (int route_type
)
2547 struct listnode
*node
;
2548 struct listnode
*ifnode
, *ifnnode
;
2549 struct connected
*connected
;
2550 struct interface
*ifp
;
2551 struct rip_interface
*ri
;
2552 struct route_node
*rp
;
2553 struct sockaddr_in to
;
2556 /* Send RIP update to each interface. */
2557 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
))
2559 if (if_is_loopback (ifp
))
2562 if (! if_is_operative (ifp
))
2565 /* Fetch RIP interface information. */
2568 /* When passive interface is specified, suppress announce to the
2576 * If there is no version configuration in the interface,
2577 * use rip's version setting.
2579 int vsend
= ((ri
->ri_send
== RI_RIP_UNSPEC
) ?
2580 rip
->version_send
: ri
->ri_send
);
2582 if (IS_RIP_DEBUG_EVENT
)
2583 zlog_debug("SEND UPDATE to %s ifindex %d",
2584 ifp
->name
, ifp
->ifindex
);
2586 /* send update on each connected network */
2587 for (ALL_LIST_ELEMENTS (ifp
->connected
, ifnode
, ifnnode
, connected
))
2589 if (connected
->address
->family
== AF_INET
)
2592 rip_update_interface (connected
, RIPv1
, route_type
);
2593 if ((vsend
& RIPv2
) && if_is_multicast(ifp
))
2594 rip_update_interface (connected
, RIPv2
, route_type
);
2600 /* RIP send updates to each neighbor. */
2601 for (rp
= route_top (rip
->neighbor
); rp
; rp
= route_next (rp
))
2602 if (rp
->info
!= NULL
)
2606 ifp
= if_lookup_prefix (p
);
2609 zlog_warn ("Neighbor %s doesnt have connected interface!",
2610 inet_ntoa (p
->u
.prefix4
));
2614 if ( (connected
= connected_lookup_prefix (ifp
, p
)) == NULL
)
2616 zlog_warn ("Neighbor %s doesnt have connected network",
2617 inet_ntoa (p
->u
.prefix4
));
2621 /* Set destination address and port */
2622 memset (&to
, 0, sizeof (struct sockaddr_in
));
2623 to
.sin_addr
= p
->u
.prefix4
;
2624 to
.sin_port
= htons (RIP_PORT_DEFAULT
);
2626 /* RIP version is rip's configuration. */
2627 rip_output_process (connected
, &to
, route_type
, rip
->version_send
);
2631 /* RIP's periodical timer. */
2633 rip_update (struct thread
*t
)
2635 /* Clear timer pointer. */
2636 rip
->t_update
= NULL
;
2638 if (IS_RIP_DEBUG_EVENT
)
2639 zlog_debug ("update timer fire!");
2641 /* Process update output. */
2642 rip_update_process (rip_all_route
);
2644 /* Triggered updates may be suppressed if a regular update is due by
2645 the time the triggered update would be sent. */
2646 if (rip
->t_triggered_interval
)
2648 thread_cancel (rip
->t_triggered_interval
);
2649 rip
->t_triggered_interval
= NULL
;
2653 /* Register myself. */
2654 rip_event (RIP_UPDATE_EVENT
, 0);
2659 /* Walk down the RIP routing table then clear changed flag. */
2661 rip_clear_changed_flag (void)
2663 struct route_node
*rp
;
2664 struct rip_info
*rinfo
= NULL
;
2665 struct list
*list
= NULL
;
2666 struct listnode
*listnode
= NULL
;
2668 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
2669 if ((list
= rp
->info
) != NULL
)
2670 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
2672 UNSET_FLAG (rinfo
->flags
, RIP_RTF_CHANGED
);
2673 /* This flag can be set only on the first entry. */
2678 /* Triggered update interval timer. */
2680 rip_triggered_interval (struct thread
*t
)
2682 int rip_triggered_update (struct thread
*);
2684 rip
->t_triggered_interval
= NULL
;
2689 rip_triggered_update (t
);
2694 /* Execute triggered update. */
2696 rip_triggered_update (struct thread
*t
)
2700 /* Clear thred pointer. */
2701 rip
->t_triggered_update
= NULL
;
2703 /* Cancel interval timer. */
2704 if (rip
->t_triggered_interval
)
2706 thread_cancel (rip
->t_triggered_interval
);
2707 rip
->t_triggered_interval
= NULL
;
2711 /* Logging triggered update. */
2712 if (IS_RIP_DEBUG_EVENT
)
2713 zlog_debug ("triggered update!");
2715 /* Split Horizon processing is done when generating triggered
2716 updates as well as normal updates (see section 2.6). */
2717 rip_update_process (rip_changed_route
);
2719 /* Once all of the triggered updates have been generated, the route
2720 change flags should be cleared. */
2721 rip_clear_changed_flag ();
2723 /* After a triggered update is sent, a timer should be set for a
2724 random interval between 1 and 5 seconds. If other changes that
2725 would trigger updates occur before the timer expires, a single
2726 update is triggered when the timer expires. */
2727 interval
= (random () % 5) + 1;
2729 rip
->t_triggered_interval
=
2730 thread_add_timer (master
, rip_triggered_interval
, NULL
, interval
);
2735 /* Withdraw redistributed route. */
2737 rip_redistribute_withdraw (int type
)
2739 struct route_node
*rp
;
2740 struct rip_info
*rinfo
= NULL
;
2741 struct list
*list
= NULL
;
2746 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
2747 if ((list
= rp
->info
) != NULL
)
2749 rinfo
= listgetdata (listhead (list
));
2750 if (rinfo
->type
== type
2751 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
)
2753 /* Perform poisoned reverse. */
2754 rinfo
->metric
= RIP_METRIC_INFINITY
;
2755 RIP_TIMER_ON (rinfo
->t_garbage_collect
,
2756 rip_garbage_collect
, rip
->garbage_time
);
2757 RIP_TIMER_OFF (rinfo
->t_timeout
);
2758 rinfo
->flags
|= RIP_RTF_CHANGED
;
2760 if (IS_RIP_DEBUG_EVENT
) {
2761 struct prefix_ipv4
*p
= (struct prefix_ipv4
*) &rp
->p
;
2763 zlog_debug ("Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2764 inet_ntoa(p
->prefix
), p
->prefixlen
,
2765 ifindex2ifname(rinfo
->ifindex
));
2768 rip_event (RIP_TRIGGERED_UPDATE
, 0);
2773 /* Create new RIP instance and set it to global variable. */
2777 rip
= XCALLOC (MTYPE_RIP
, sizeof (struct rip
));
2779 /* Set initial value. */
2780 rip
->version_send
= RI_RIP_VERSION_2
;
2781 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2782 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
2783 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
2784 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
2785 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2787 /* Initialize RIP routig table. */
2788 rip
->table
= route_table_init ();
2789 rip
->route
= route_table_init ();
2790 rip
->neighbor
= route_table_init ();
2792 /* Make output stream. */
2793 rip
->obuf
= stream_new (1500);
2796 rip
->sock
= rip_create_socket (NULL
);
2800 /* Create read and timer thread. */
2801 rip_event (RIP_READ
, rip
->sock
);
2802 rip_event (RIP_UPDATE_EVENT
, 1);
2807 /* Sned RIP request to the destination. */
2809 rip_request_send (struct sockaddr_in
*to
, struct interface
*ifp
,
2810 u_char version
, struct connected
*connected
)
2813 struct rip_packet rip_packet
;
2814 struct listnode
*node
, *nnode
;
2816 memset (&rip_packet
, 0, sizeof (rip_packet
));
2818 rip_packet
.command
= RIP_REQUEST
;
2819 rip_packet
.version
= version
;
2820 rte
= rip_packet
.rte
;
2821 rte
->metric
= htonl (RIP_METRIC_INFINITY
);
2826 * connected is only sent for ripv1 case, or when
2827 * interface does not support multicast. Caller loops
2828 * over each connected address for this case.
2830 if (rip_send_packet ((u_char
*) &rip_packet
, sizeof (rip_packet
),
2831 to
, connected
) != sizeof (rip_packet
))
2834 return sizeof (rip_packet
);
2837 /* send request on each connected network */
2838 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, connected
))
2840 struct prefix_ipv4
*p
;
2842 p
= (struct prefix_ipv4
*) connected
->address
;
2844 if (p
->family
!= AF_INET
)
2847 if (rip_send_packet ((u_char
*) &rip_packet
, sizeof (rip_packet
),
2848 to
, connected
) != sizeof (rip_packet
))
2851 return sizeof (rip_packet
);
2855 rip_update_jitter (unsigned long time
)
2857 #define JITTER_BOUND 4
2858 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2859 Given that, we cannot let time be less than JITTER_BOUND seconds.
2860 The RIPv2 RFC says jitter should be small compared to
2861 update_time. We consider 1/JITTER_BOUND to be small.
2864 int jitter_input
= time
;
2867 if (jitter_input
< JITTER_BOUND
)
2868 jitter_input
= JITTER_BOUND
;
2870 jitter
= (((random () % ((jitter_input
* 2) + 1)) - jitter_input
));
2872 return jitter
/JITTER_BOUND
;
2876 rip_event (enum rip_event event
, int sock
)
2883 rip
->t_read
= thread_add_read (master
, rip_read
, NULL
, sock
);
2885 case RIP_UPDATE_EVENT
:
2888 thread_cancel (rip
->t_update
);
2889 rip
->t_update
= NULL
;
2891 jitter
= rip_update_jitter (rip
->update_time
);
2893 thread_add_timer (master
, rip_update
, NULL
,
2894 sock
? 2 : rip
->update_time
+ jitter
);
2896 case RIP_TRIGGERED_UPDATE
:
2897 if (rip
->t_triggered_interval
)
2899 else if (! rip
->t_triggered_update
)
2900 rip
->t_triggered_update
=
2901 thread_add_event (master
, rip_triggered_update
, NULL
, 0);
2911 "Enable a routing process\n"
2912 "Routing Information Protocol (RIP)\n")
2916 /* If rip is not enabled before. */
2919 ret
= rip_create ();
2922 zlog_info ("Can't create RIP");
2926 vty
->node
= RIP_NODE
;
2932 DEFUN (no_router_rip
,
2936 "Enable a routing process\n"
2937 "Routing Information Protocol (RIP)\n")
2947 "Set routing protocol version\n"
2952 version
= atoi (argv
[0]);
2953 if (version
!= RIPv1
&& version
!= RIPv2
)
2955 vty_out (vty
, "invalid rip version %d%s", version
,
2959 rip
->version_send
= version
;
2960 rip
->version_recv
= version
;
2965 DEFUN (no_rip_version
,
2969 "Set routing protocol version\n")
2971 /* Set RIP version to the default. */
2972 rip
->version_send
= RI_RIP_VERSION_2
;
2973 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2978 ALIAS (no_rip_version
,
2979 no_rip_version_val_cmd
,
2982 "Set routing protocol version\n"
2988 "RIP static route configuration\n"
2989 "IP prefix <network>/<length>\n")
2992 struct prefix_ipv4 p
;
2993 struct route_node
*node
;
2995 ret
= str2prefix_ipv4 (argv
[0], &p
);
2998 vty_out (vty
, "Malformed address%s", VTY_NEWLINE
);
3001 apply_mask_ipv4 (&p
);
3003 /* For router rip configuration. */
3004 node
= route_node_get (rip
->route
, (struct prefix
*) &p
);
3008 vty_out (vty
, "There is already same static route.%s", VTY_NEWLINE
);
3009 route_unlock_node (node
);
3013 node
->info
= (void *)1;
3015 rip_redistribute_add (ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0, NULL
, 0, 0);
3020 DEFUN (no_rip_route
,
3022 "no route A.B.C.D/M",
3024 "RIP static route configuration\n"
3025 "IP prefix <network>/<length>\n")
3028 struct prefix_ipv4 p
;
3029 struct route_node
*node
;
3031 ret
= str2prefix_ipv4 (argv
[0], &p
);
3034 vty_out (vty
, "Malformed address%s", VTY_NEWLINE
);
3037 apply_mask_ipv4 (&p
);
3039 /* For router rip configuration. */
3040 node
= route_node_lookup (rip
->route
, (struct prefix
*) &p
);
3043 vty_out (vty
, "Can't find route %s.%s", argv
[0],
3048 rip_redistribute_delete (ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0);
3049 route_unlock_node (node
);
3052 route_unlock_node (node
);
3059 rip_update_default_metric (void)
3061 struct route_node
*np
;
3062 struct rip_info
*rinfo
= NULL
;
3063 struct list
*list
= NULL
;
3064 struct listnode
*listnode
= NULL
;
3066 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
3067 if ((list
= np
->info
) != NULL
)
3068 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
3069 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
3070 rinfo
->metric
= rip
->default_metric
;
3074 DEFUN (rip_default_metric
,
3075 rip_default_metric_cmd
,
3076 "default-metric <1-16>",
3077 "Set a metric of redistribute routes\n"
3082 rip
->default_metric
= atoi (argv
[0]);
3083 /* rip_update_default_metric (); */
3088 DEFUN (no_rip_default_metric
,
3089 no_rip_default_metric_cmd
,
3090 "no default-metric",
3092 "Set a metric of redistribute routes\n"
3097 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
3098 /* rip_update_default_metric (); */
3103 ALIAS (no_rip_default_metric
,
3104 no_rip_default_metric_val_cmd
,
3105 "no default-metric <1-16>",
3107 "Set a metric of redistribute routes\n"
3112 "timers basic <5-2147483647> <5-2147483647> <5-2147483647>",
3113 "Adjust routing timers\n"
3114 "Basic routing protocol update timers\n"
3115 "Routing table update timer value in second. Default is 30.\n"
3116 "Routing information timeout timer. Default is 180.\n"
3117 "Garbage collection timer. Default is 120.\n")
3119 unsigned long update
;
3120 unsigned long timeout
;
3121 unsigned long garbage
;
3122 char *endptr
= NULL
;
3123 unsigned long RIP_TIMER_MAX
= 2147483647;
3124 unsigned long RIP_TIMER_MIN
= 5;
3126 update
= strtoul (argv
[0], &endptr
, 10);
3127 if (update
> RIP_TIMER_MAX
|| update
< RIP_TIMER_MIN
|| *endptr
!= '\0')
3129 vty_out (vty
, "update timer value error%s", VTY_NEWLINE
);
3133 timeout
= strtoul (argv
[1], &endptr
, 10);
3134 if (timeout
> RIP_TIMER_MAX
|| timeout
< RIP_TIMER_MIN
|| *endptr
!= '\0')
3136 vty_out (vty
, "timeout timer value error%s", VTY_NEWLINE
);
3140 garbage
= strtoul (argv
[2], &endptr
, 10);
3141 if (garbage
> RIP_TIMER_MAX
|| garbage
< RIP_TIMER_MIN
|| *endptr
!= '\0')
3143 vty_out (vty
, "garbage timer value error%s", VTY_NEWLINE
);
3147 /* Set each timer value. */
3148 rip
->update_time
= update
;
3149 rip
->timeout_time
= timeout
;
3150 rip
->garbage_time
= garbage
;
3152 /* Reset update timer thread. */
3153 rip_event (RIP_UPDATE_EVENT
, 0);
3158 DEFUN (no_rip_timers
,
3162 "Adjust routing timers\n"
3163 "Basic routing protocol update timers\n")
3165 /* Set each timer value to the default. */
3166 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
3167 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
3168 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
3170 /* Reset update timer thread. */
3171 rip_event (RIP_UPDATE_EVENT
, 0);
3176 ALIAS (no_rip_timers
,
3177 no_rip_timers_val_cmd
,
3178 "no timers basic <0-65535> <0-65535> <0-65535>",
3180 "Adjust routing timers\n"
3181 "Basic routing protocol update timers\n"
3182 "Routing table update timer value in second. Default is 30.\n"
3183 "Routing information timeout timer. Default is 180.\n"
3184 "Garbage collection timer. Default is 120.\n")
3187 struct route_table
*rip_distance_table
;
3191 /* Distance value for the IP source prefix. */
3194 /* Name of the access-list to be matched. */
3198 static struct rip_distance
*
3199 rip_distance_new (void)
3201 return XCALLOC (MTYPE_RIP_DISTANCE
, sizeof (struct rip_distance
));
3205 rip_distance_free (struct rip_distance
*rdistance
)
3207 XFREE (MTYPE_RIP_DISTANCE
, rdistance
);
3211 rip_distance_set (struct vty
*vty
, const char *distance_str
, const char *ip_str
,
3212 const char *access_list_str
)
3215 struct prefix_ipv4 p
;
3217 struct route_node
*rn
;
3218 struct rip_distance
*rdistance
;
3220 ret
= str2prefix_ipv4 (ip_str
, &p
);
3223 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
3227 distance
= atoi (distance_str
);
3229 /* Get RIP distance node. */
3230 rn
= route_node_get (rip_distance_table
, (struct prefix
*) &p
);
3233 rdistance
= rn
->info
;
3234 route_unlock_node (rn
);
3238 rdistance
= rip_distance_new ();
3239 rn
->info
= rdistance
;
3242 /* Set distance value. */
3243 rdistance
->distance
= distance
;
3245 /* Reset access-list configuration. */
3246 if (rdistance
->access_list
)
3248 free (rdistance
->access_list
);
3249 rdistance
->access_list
= NULL
;
3251 if (access_list_str
)
3252 rdistance
->access_list
= strdup (access_list_str
);
3258 rip_distance_unset (struct vty
*vty
, const char *distance_str
,
3259 const char *ip_str
, const char *access_list_str
)
3262 struct prefix_ipv4 p
;
3263 struct route_node
*rn
;
3264 struct rip_distance
*rdistance
;
3266 ret
= str2prefix_ipv4 (ip_str
, &p
);
3269 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
3273 rn
= route_node_lookup (rip_distance_table
, (struct prefix
*)&p
);
3276 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
3280 rdistance
= rn
->info
;
3282 if (rdistance
->access_list
)
3283 free (rdistance
->access_list
);
3284 rip_distance_free (rdistance
);
3287 route_unlock_node (rn
);
3288 route_unlock_node (rn
);
3294 rip_distance_reset (void)
3296 struct route_node
*rn
;
3297 struct rip_distance
*rdistance
;
3299 for (rn
= route_top (rip_distance_table
); rn
; rn
= route_next (rn
))
3300 if ((rdistance
= rn
->info
) != NULL
)
3302 if (rdistance
->access_list
)
3303 free (rdistance
->access_list
);
3304 rip_distance_free (rdistance
);
3306 route_unlock_node (rn
);
3310 /* Apply RIP information to distance method. */
3312 rip_distance_apply (struct rip_info
*rinfo
)
3314 struct route_node
*rn
;
3315 struct prefix_ipv4 p
;
3316 struct rip_distance
*rdistance
;
3317 struct access_list
*alist
;
3322 memset (&p
, 0, sizeof (struct prefix_ipv4
));
3324 p
.prefix
= rinfo
->from
;
3325 p
.prefixlen
= IPV4_MAX_BITLEN
;
3327 /* Check source address. */
3328 rn
= route_node_match (rip_distance_table
, (struct prefix
*) &p
);
3331 rdistance
= rn
->info
;
3332 route_unlock_node (rn
);
3334 if (rdistance
->access_list
)
3336 alist
= access_list_lookup (AFI_IP
, rdistance
->access_list
);
3339 if (access_list_apply (alist
, &rinfo
->rp
->p
) == FILTER_DENY
)
3342 return rdistance
->distance
;
3345 return rdistance
->distance
;
3349 return rip
->distance
;
3355 rip_distance_show (struct vty
*vty
)
3357 struct route_node
*rn
;
3358 struct rip_distance
*rdistance
;
3362 vty_out (vty
, " Distance: (default is %d)%s",
3363 rip
->distance
? rip
->distance
:ZEBRA_RIP_DISTANCE_DEFAULT
,
3366 for (rn
= route_top (rip_distance_table
); rn
; rn
= route_next (rn
))
3367 if ((rdistance
= rn
->info
) != NULL
)
3371 vty_out (vty
, " Address Distance List%s",
3375 sprintf (buf
, "%s/%d", inet_ntoa (rn
->p
.u
.prefix4
), rn
->p
.prefixlen
);
3376 vty_out (vty
, " %-20s %4d %s%s",
3377 buf
, rdistance
->distance
,
3378 rdistance
->access_list
? rdistance
->access_list
: "",
3383 DEFUN (rip_distance
,
3386 "Administrative distance\n"
3389 rip
->distance
= atoi (argv
[0]);
3393 DEFUN (no_rip_distance
,
3394 no_rip_distance_cmd
,
3395 "no distance <1-255>",
3397 "Administrative distance\n"
3404 DEFUN (rip_distance_source
,
3405 rip_distance_source_cmd
,
3406 "distance <1-255> A.B.C.D/M",
3407 "Administrative distance\n"
3409 "IP source prefix\n")
3411 rip_distance_set (vty
, argv
[0], argv
[1], NULL
);
3415 DEFUN (no_rip_distance_source
,
3416 no_rip_distance_source_cmd
,
3417 "no distance <1-255> A.B.C.D/M",
3419 "Administrative distance\n"
3421 "IP source prefix\n")
3423 rip_distance_unset (vty
, argv
[0], argv
[1], NULL
);
3427 DEFUN (rip_distance_source_access_list
,
3428 rip_distance_source_access_list_cmd
,
3429 "distance <1-255> A.B.C.D/M WORD",
3430 "Administrative distance\n"
3432 "IP source prefix\n"
3433 "Access list name\n")
3435 rip_distance_set (vty
, argv
[0], argv
[1], argv
[2]);
3439 DEFUN (no_rip_distance_source_access_list
,
3440 no_rip_distance_source_access_list_cmd
,
3441 "no distance <1-255> A.B.C.D/M WORD",
3443 "Administrative distance\n"
3445 "IP source prefix\n"
3446 "Access list name\n")
3448 rip_distance_unset (vty
, argv
[0], argv
[1], argv
[2]);
3452 /* Update ECMP routes to zebra when ECMP is disabled. */
3454 rip_ecmp_disable (void)
3456 struct route_node
*rp
;
3457 struct rip_info
*rinfo
, *tmp_rinfo
;
3459 struct listnode
*node
, *nextnode
;
3464 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
3465 if ((list
= rp
->info
) != NULL
&& listcount (list
) > 1)
3467 rinfo
= listgetdata (listhead (list
));
3468 if (!rip_route_rte (rinfo
))
3471 /* Drop all other entries, except the first one. */
3472 for (ALL_LIST_ELEMENTS (list
, node
, nextnode
, tmp_rinfo
))
3473 if (tmp_rinfo
!= rinfo
)
3475 RIP_TIMER_OFF (tmp_rinfo
->t_timeout
);
3476 RIP_TIMER_OFF (tmp_rinfo
->t_garbage_collect
);
3477 list_delete_node (list
, node
);
3478 rip_info_free (tmp_rinfo
);
3482 rip_zebra_ipv4_add (rp
);
3484 /* Set the route change flag. */
3485 SET_FLAG (rinfo
->flags
, RIP_RTF_CHANGED
);
3487 /* Signal the output process to trigger an update. */
3488 rip_event (RIP_TRIGGERED_UPDATE
, 0);
3492 DEFUN (rip_allow_ecmp
,
3495 "Allow Equal Cost MultiPath\n")
3499 vty_out (vty
, "ECMP is already enabled.%s", VTY_NEWLINE
);
3504 zlog_info ("ECMP is enabled.");
3508 DEFUN (no_rip_allow_ecmp
,
3509 no_rip_allow_ecmp_cmd
,
3512 "Allow Equal Cost MultiPath\n")
3516 vty_out (vty
, "ECMP is already disabled.%s", VTY_NEWLINE
);
3521 zlog_info ("ECMP is disabled.");
3522 rip_ecmp_disable ();
3526 /* Print out routes update time. */
3528 rip_vty_out_uptime (struct vty
*vty
, struct rip_info
*rinfo
)
3533 char timebuf
[TIME_BUF
];
3534 struct thread
*thread
;
3536 if ((thread
= rinfo
->t_timeout
) != NULL
)
3538 clock
= thread_timer_remain_second (thread
);
3539 tm
= gmtime (&clock
);
3540 strftime (timebuf
, TIME_BUF
, "%M:%S", tm
);
3541 vty_out (vty
, "%5s", timebuf
);
3543 else if ((thread
= rinfo
->t_garbage_collect
) != NULL
)
3545 clock
= thread_timer_remain_second (thread
);
3546 tm
= gmtime (&clock
);
3547 strftime (timebuf
, TIME_BUF
, "%M:%S", tm
);
3548 vty_out (vty
, "%5s", timebuf
);
3553 rip_route_type_print (int sub_type
)
3559 case RIP_ROUTE_STATIC
:
3561 case RIP_ROUTE_DEFAULT
:
3563 case RIP_ROUTE_REDISTRIBUTE
:
3565 case RIP_ROUTE_INTERFACE
:
3577 "Show RIP routes\n")
3579 struct route_node
*np
;
3580 struct rip_info
*rinfo
= NULL
;
3581 struct list
*list
= NULL
;
3582 struct listnode
*listnode
= NULL
;
3587 vty_out (vty
, "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP%s"
3589 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,%s"
3590 " (i) - interface%s%s"
3591 " Network Next Hop Metric From Tag Time%s",
3592 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
3594 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
3595 if ((list
= np
->info
) != NULL
)
3596 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
3600 len
= vty_out (vty
, "%c(%s) %s/%d",
3601 /* np->lock, For debugging. */
3602 zebra_route_char(rinfo
->type
),
3603 rip_route_type_print (rinfo
->sub_type
),
3604 inet_ntoa (np
->p
.u
.prefix4
), np
->p
.prefixlen
);
3609 vty_out (vty
, "%*s", len
, " ");
3611 if (rinfo
->nexthop
.s_addr
)
3612 vty_out (vty
, "%-20s %2d ", inet_ntoa (rinfo
->nexthop
),
3615 vty_out (vty
, "0.0.0.0 %2d ", rinfo
->metric
);
3617 /* Route which exist in kernel routing table. */
3618 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
) &&
3619 (rinfo
->sub_type
== RIP_ROUTE_RTE
))
3621 vty_out (vty
, "%-15s ", inet_ntoa (rinfo
->from
));
3622 vty_out (vty
, "%3d ", rinfo
->tag
);
3623 rip_vty_out_uptime (vty
, rinfo
);
3625 else if (rinfo
->metric
== RIP_METRIC_INFINITY
)
3627 vty_out (vty
, "self ");
3628 vty_out (vty
, "%3d ", rinfo
->tag
);
3629 rip_vty_out_uptime (vty
, rinfo
);
3633 if (rinfo
->external_metric
)
3635 len
= vty_out (vty
, "self (%s:%d)",
3636 zebra_route_string(rinfo
->type
),
3637 rinfo
->external_metric
);
3640 vty_out (vty
, "%*s", len
, " ");
3643 vty_out (vty
, "self ");
3644 vty_out (vty
, "%3d", rinfo
->tag
);
3647 vty_out (vty
, "%s", VTY_NEWLINE
);
3652 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3653 DEFUN (show_ip_rip_status
,
3654 show_ip_rip_status_cmd
,
3655 "show ip rip status",
3659 "IP routing protocol process parameters and statistics\n")
3661 struct listnode
*node
;
3662 struct interface
*ifp
;
3663 struct rip_interface
*ri
;
3664 extern const struct message ri_version_msg
[];
3665 const char *send_version
;
3666 const char *receive_version
;
3671 vty_out (vty
, "Routing Protocol is \"rip\"%s", VTY_NEWLINE
);
3672 vty_out (vty
, " Sending updates every %ld seconds with +/-50%%,",
3674 vty_out (vty
, " next due in %lu seconds%s",
3675 thread_timer_remain_second(rip
->t_update
),
3677 vty_out (vty
, " Timeout after %ld seconds,", rip
->timeout_time
);
3678 vty_out (vty
, " garbage collect after %ld seconds%s", rip
->garbage_time
,
3681 /* Filtering status show. */
3682 config_show_distribute (vty
);
3684 /* Default metric information. */
3685 vty_out (vty
, " Default redistribution metric is %d%s",
3686 rip
->default_metric
, VTY_NEWLINE
);
3688 /* Redistribute information. */
3689 vty_out (vty
, " Redistributing:");
3690 config_write_rip_redistribute (vty
, 0);
3691 vty_out (vty
, "%s", VTY_NEWLINE
);
3693 vty_out (vty
, " Default version control: send version %s,",
3694 lookup(ri_version_msg
,rip
->version_send
));
3695 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3696 vty_out (vty
, " receive any version %s", VTY_NEWLINE
);
3698 vty_out (vty
, " receive version %s %s",
3699 lookup(ri_version_msg
,rip
->version_recv
), VTY_NEWLINE
);
3701 vty_out (vty
, " Interface Send Recv Key-chain%s", VTY_NEWLINE
);
3703 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
))
3710 if (ri
->enable_network
|| ri
->enable_interface
)
3712 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3713 send_version
= lookup (ri_version_msg
, rip
->version_send
);
3715 send_version
= lookup (ri_version_msg
, ri
->ri_send
);
3717 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3718 receive_version
= lookup (ri_version_msg
, rip
->version_recv
);
3720 receive_version
= lookup (ri_version_msg
, ri
->ri_receive
);
3722 vty_out (vty
, " %-17s%-3s %-3s %s%s", ifp
->name
,
3725 ri
->key_chain
? ri
->key_chain
: "",
3730 vty_out (vty
, " Routing for Networks:%s", VTY_NEWLINE
);
3731 config_write_rip_network (vty
, 0);
3734 int found_passive
= 0;
3735 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
))
3739 if ((ri
->enable_network
|| ri
->enable_interface
) && ri
->passive
)
3743 vty_out (vty
, " Passive Interface(s):%s", VTY_NEWLINE
);
3746 vty_out (vty
, " %s%s", ifp
->name
, VTY_NEWLINE
);
3751 vty_out (vty
, " Routing Information Sources:%s", VTY_NEWLINE
);
3752 vty_out (vty
, " Gateway BadPackets BadRoutes Distance Last Update%s", VTY_NEWLINE
);
3753 rip_peer_display (vty
);
3755 rip_distance_show (vty
);
3760 /* RIP configuration write function. */
3762 config_write_rip (struct vty
*vty
)
3765 struct route_node
*rn
;
3766 struct rip_distance
*rdistance
;
3770 /* Router RIP statement. */
3771 vty_out (vty
, "router rip%s", VTY_NEWLINE
);
3774 /* RIP version statement. Default is RIP version 2. */
3775 if (rip
->version_send
!= RI_RIP_VERSION_2
3776 || rip
->version_recv
!= RI_RIP_VERSION_1_AND_2
)
3777 vty_out (vty
, " version %d%s", rip
->version_send
,
3780 /* RIP timer configuration. */
3781 if (rip
->update_time
!= RIP_UPDATE_TIMER_DEFAULT
3782 || rip
->timeout_time
!= RIP_TIMEOUT_TIMER_DEFAULT
3783 || rip
->garbage_time
!= RIP_GARBAGE_TIMER_DEFAULT
)
3784 vty_out (vty
, " timers basic %lu %lu %lu%s",
3790 /* Default information configuration. */
3791 if (rip
->default_information
)
3793 if (rip
->default_information_route_map
)
3794 vty_out (vty
, " default-information originate route-map %s%s",
3795 rip
->default_information_route_map
, VTY_NEWLINE
);
3797 vty_out (vty
, " default-information originate%s",
3801 /* Redistribute configuration. */
3802 config_write_rip_redistribute (vty
, 1);
3804 /* RIP offset-list configuration. */
3805 config_write_rip_offset_list (vty
);
3807 /* RIP enabled network and interface configuration. */
3808 config_write_rip_network (vty
, 1);
3810 /* RIP default metric configuration */
3811 if (rip
->default_metric
!= RIP_DEFAULT_METRIC_DEFAULT
)
3812 vty_out (vty
, " default-metric %d%s",
3813 rip
->default_metric
, VTY_NEWLINE
);
3815 /* Distribute configuration. */
3816 write
+= config_write_distribute (vty
);
3818 /* Interface routemap configuration */
3819 write
+= config_write_if_rmap (vty
);
3821 /* Distance configuration. */
3823 vty_out (vty
, " distance %d%s", rip
->distance
, VTY_NEWLINE
);
3825 /* RIP source IP prefix distance configuration. */
3826 for (rn
= route_top (rip_distance_table
); rn
; rn
= route_next (rn
))
3827 if ((rdistance
= rn
->info
) != NULL
)
3828 vty_out (vty
, " distance %d %s/%d %s%s", rdistance
->distance
,
3829 inet_ntoa (rn
->p
.u
.prefix4
), rn
->p
.prefixlen
,
3830 rdistance
->access_list
? rdistance
->access_list
: "",
3833 /* ECMP configuration. */
3835 vty_out (vty
, " allow-ecmp%s", VTY_NEWLINE
);
3837 /* RIP static route configuration. */
3838 for (rn
= route_top (rip
->route
); rn
; rn
= route_next (rn
))
3840 vty_out (vty
, " route %s/%d%s",
3841 inet_ntoa (rn
->p
.u
.prefix4
),
3849 /* RIP node structure. */
3850 static struct cmd_node rip_node
=
3853 "%s(config-router)# ",
3857 /* Distribute-list update functions. */
3859 rip_distribute_update (struct distribute
*dist
)
3861 struct interface
*ifp
;
3862 struct rip_interface
*ri
;
3863 struct access_list
*alist
;
3864 struct prefix_list
*plist
;
3869 ifp
= if_lookup_by_name (dist
->ifname
);
3875 if (dist
->list
[DISTRIBUTE_IN
])
3877 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_IN
]);
3879 ri
->list
[RIP_FILTER_IN
] = alist
;
3881 ri
->list
[RIP_FILTER_IN
] = NULL
;
3884 ri
->list
[RIP_FILTER_IN
] = NULL
;
3886 if (dist
->list
[DISTRIBUTE_OUT
])
3888 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_OUT
]);
3890 ri
->list
[RIP_FILTER_OUT
] = alist
;
3892 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3895 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3897 if (dist
->prefix
[DISTRIBUTE_IN
])
3899 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_IN
]);
3901 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3903 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3906 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3908 if (dist
->prefix
[DISTRIBUTE_OUT
])
3910 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_OUT
]);
3912 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3914 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3917 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3921 rip_distribute_update_interface (struct interface
*ifp
)
3923 struct distribute
*dist
;
3925 dist
= distribute_lookup (ifp
->name
);
3927 rip_distribute_update (dist
);
3930 /* Update all interface's distribute list. */
3933 rip_distribute_update_all (struct prefix_list
*notused
)
3935 struct interface
*ifp
;
3936 struct listnode
*node
, *nnode
;
3938 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), node
, nnode
, ifp
))
3939 rip_distribute_update_interface (ifp
);
3943 rip_distribute_update_all_wrapper(struct access_list
*notused
)
3945 rip_distribute_update_all(NULL
);
3948 /* Delete all added rip route. */
3953 struct route_node
*rp
;
3954 struct rip_info
*rinfo
= NULL
;
3955 struct list
*list
= NULL
;
3956 struct listnode
*listnode
= NULL
;
3960 /* Clear RIP routes */
3961 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
3962 if ((list
= rp
->info
) != NULL
)
3964 rinfo
= listgetdata (listhead (list
));
3965 if (rip_route_rte (rinfo
))
3966 rip_zebra_ipv4_delete (rp
);
3968 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
3970 RIP_TIMER_OFF (rinfo
->t_timeout
);
3971 RIP_TIMER_OFF (rinfo
->t_garbage_collect
);
3972 rip_info_free (rinfo
);
3976 route_unlock_node (rp
);
3979 /* Cancel RIP related timers. */
3980 RIP_TIMER_OFF (rip
->t_update
);
3981 RIP_TIMER_OFF (rip
->t_triggered_update
);
3982 RIP_TIMER_OFF (rip
->t_triggered_interval
);
3984 /* Cancel read thread. */
3987 thread_cancel (rip
->t_read
);
3991 /* Close RIP socket. */
3998 /* Static RIP route configuration. */
3999 for (rp
= route_top (rip
->route
); rp
; rp
= route_next (rp
))
4003 route_unlock_node (rp
);
4006 /* RIP neighbor configuration. */
4007 for (rp
= route_top (rip
->neighbor
); rp
; rp
= route_next (rp
))
4011 route_unlock_node (rp
);
4014 /* Redistribute related clear. */
4015 if (rip
->default_information_route_map
)
4016 free (rip
->default_information_route_map
);
4018 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
4019 if (rip
->route_map
[i
].name
)
4020 free (rip
->route_map
[i
].name
);
4022 XFREE (MTYPE_ROUTE_TABLE
, rip
->table
);
4023 XFREE (MTYPE_ROUTE_TABLE
, rip
->route
);
4024 XFREE (MTYPE_ROUTE_TABLE
, rip
->neighbor
);
4026 XFREE (MTYPE_RIP
, rip
);
4030 rip_clean_network ();
4031 rip_passive_nondefault_clean ();
4032 rip_offset_clean ();
4033 rip_interface_clean ();
4034 rip_distance_reset ();
4035 rip_redistribute_clean ();
4038 /* Reset all values to the default settings. */
4042 /* Reset global counters. */
4043 rip_global_route_changes
= 0;
4044 rip_global_queries
= 0;
4046 /* Call ripd related reset functions. */
4048 rip_route_map_reset ();
4050 /* Call library reset functions. */
4052 access_list_reset ();
4053 prefix_list_reset ();
4055 distribute_list_reset ();
4057 rip_interface_reset ();
4058 rip_distance_reset ();
4060 rip_zclient_reset ();
4064 rip_if_rmap_update (struct if_rmap
*if_rmap
)
4066 struct interface
*ifp
;
4067 struct rip_interface
*ri
;
4068 struct route_map
*rmap
;
4070 ifp
= if_lookup_by_name (if_rmap
->ifname
);
4076 if (if_rmap
->routemap
[IF_RMAP_IN
])
4078 rmap
= route_map_lookup_by_name (if_rmap
->routemap
[IF_RMAP_IN
]);
4080 ri
->routemap
[IF_RMAP_IN
] = rmap
;
4082 ri
->routemap
[IF_RMAP_IN
] = NULL
;
4085 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
4087 if (if_rmap
->routemap
[IF_RMAP_OUT
])
4089 rmap
= route_map_lookup_by_name (if_rmap
->routemap
[IF_RMAP_OUT
]);
4091 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
4093 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
4096 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
4100 rip_if_rmap_update_interface (struct interface
*ifp
)
4102 struct if_rmap
*if_rmap
;
4104 if_rmap
= if_rmap_lookup (ifp
->name
);
4106 rip_if_rmap_update (if_rmap
);
4110 rip_routemap_update_redistribute (void)
4116 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
4118 if (rip
->route_map
[i
].name
)
4119 rip
->route_map
[i
].map
=
4120 route_map_lookup_by_name (rip
->route_map
[i
].name
);
4127 rip_routemap_update (const char *notused
)
4129 struct interface
*ifp
;
4130 struct listnode
*node
, *nnode
;
4132 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), node
, nnode
, ifp
))
4133 rip_if_rmap_update_interface (ifp
);
4135 rip_routemap_update_redistribute ();
4138 /* Allocate new rip structure and set default value. */
4142 /* Randomize for triggered update random(). */
4143 srandom (time (NULL
));
4145 /* Install top nodes. */
4146 install_node (&rip_node
, config_write_rip
);
4148 /* Install rip commands. */
4149 install_element (VIEW_NODE
, &show_ip_rip_cmd
);
4150 install_element (VIEW_NODE
, &show_ip_rip_status_cmd
);
4151 install_element (ENABLE_NODE
, &show_ip_rip_cmd
);
4152 install_element (ENABLE_NODE
, &show_ip_rip_status_cmd
);
4153 install_element (CONFIG_NODE
, &router_rip_cmd
);
4154 install_element (CONFIG_NODE
, &no_router_rip_cmd
);
4156 install_default (RIP_NODE
);
4157 install_element (RIP_NODE
, &rip_version_cmd
);
4158 install_element (RIP_NODE
, &no_rip_version_cmd
);
4159 install_element (RIP_NODE
, &no_rip_version_val_cmd
);
4160 install_element (RIP_NODE
, &rip_default_metric_cmd
);
4161 install_element (RIP_NODE
, &no_rip_default_metric_cmd
);
4162 install_element (RIP_NODE
, &no_rip_default_metric_val_cmd
);
4163 install_element (RIP_NODE
, &rip_timers_cmd
);
4164 install_element (RIP_NODE
, &no_rip_timers_cmd
);
4165 install_element (RIP_NODE
, &no_rip_timers_val_cmd
);
4166 install_element (RIP_NODE
, &rip_route_cmd
);
4167 install_element (RIP_NODE
, &no_rip_route_cmd
);
4168 install_element (RIP_NODE
, &rip_distance_cmd
);
4169 install_element (RIP_NODE
, &no_rip_distance_cmd
);
4170 install_element (RIP_NODE
, &rip_distance_source_cmd
);
4171 install_element (RIP_NODE
, &no_rip_distance_source_cmd
);
4172 install_element (RIP_NODE
, &rip_distance_source_access_list_cmd
);
4173 install_element (RIP_NODE
, &no_rip_distance_source_access_list_cmd
);
4174 install_element (RIP_NODE
, &rip_allow_ecmp_cmd
);
4175 install_element (RIP_NODE
, &no_rip_allow_ecmp_cmd
);
4177 /* Debug related init. */
4183 #endif /* HAVE_SNMP */
4185 /* Access list install. */
4186 access_list_init ();
4187 access_list_add_hook (rip_distribute_update_all_wrapper
);
4188 access_list_delete_hook (rip_distribute_update_all_wrapper
);
4190 /* Prefix list initialize.*/
4191 prefix_list_init ();
4192 prefix_list_add_hook (rip_distribute_update_all
);
4193 prefix_list_delete_hook (rip_distribute_update_all
);
4195 /* Distribute list install. */
4196 distribute_list_init (RIP_NODE
);
4197 distribute_list_add_hook (rip_distribute_update
);
4198 distribute_list_delete_hook (rip_distribute_update
);
4201 rip_route_map_init ();
4204 route_map_add_hook (rip_routemap_update
);
4205 route_map_delete_hook (rip_routemap_update
);
4207 if_rmap_init (RIP_NODE
);
4208 if_rmap_hook_add (rip_if_rmap_update
);
4209 if_rmap_hook_delete (rip_if_rmap_update
);
4211 /* Distance control. */
4212 rip_distance_table
= route_table_init ();