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
[1]->arg
);
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
;
2966 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
2967 * "no version <1-2>",
2969 * "Set routing protocol version\n"
2973 DEFUN (no_rip_version
,
2977 "Set routing protocol version\n")
2979 /* Set RIP version to the default. */
2980 rip
->version_send
= RI_RIP_VERSION_2
;
2981 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2990 "RIP static route configuration\n"
2991 "IP prefix <network>/<length>\n")
2994 struct prefix_ipv4 p
;
2995 struct route_node
*node
;
2997 ret
= str2prefix_ipv4 (argv
[1]->arg
, &p
);
3000 vty_out (vty
, "Malformed address%s", VTY_NEWLINE
);
3003 apply_mask_ipv4 (&p
);
3005 /* For router rip configuration. */
3006 node
= route_node_get (rip
->route
, (struct prefix
*) &p
);
3010 vty_out (vty
, "There is already same static route.%s", VTY_NEWLINE
);
3011 route_unlock_node (node
);
3015 node
->info
= (void *)1;
3017 rip_redistribute_add (ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0, NULL
, 0, 0);
3022 DEFUN (no_rip_route
,
3024 "no route A.B.C.D/M",
3026 "RIP static route configuration\n"
3027 "IP prefix <network>/<length>\n")
3030 struct prefix_ipv4 p
;
3031 struct route_node
*node
;
3033 ret
= str2prefix_ipv4 (argv
[2]->arg
, &p
);
3036 vty_out (vty
, "Malformed address%s", VTY_NEWLINE
);
3039 apply_mask_ipv4 (&p
);
3041 /* For router rip configuration. */
3042 node
= route_node_lookup (rip
->route
, (struct prefix
*) &p
);
3045 vty_out (vty
, "Can't find route %s.%s", argv
[2]->arg
,
3050 rip_redistribute_delete (ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0);
3051 route_unlock_node (node
);
3054 route_unlock_node (node
);
3061 rip_update_default_metric (void)
3063 struct route_node
*np
;
3064 struct rip_info
*rinfo
= NULL
;
3065 struct list
*list
= NULL
;
3066 struct listnode
*listnode
= NULL
;
3068 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
3069 if ((list
= np
->info
) != NULL
)
3070 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
3071 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
3072 rinfo
->metric
= rip
->default_metric
;
3076 DEFUN (rip_default_metric
,
3077 rip_default_metric_cmd
,
3078 "default-metric (1-16)",
3079 "Set a metric of redistribute routes\n"
3084 rip
->default_metric
= atoi (argv
[1]->arg
);
3085 /* rip_update_default_metric (); */
3091 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3092 * "no default-metric <1-16>",
3094 * "Set a metric of redistribute routes\n"
3095 * "Default metric\n"
3098 DEFUN (no_rip_default_metric
,
3099 no_rip_default_metric_cmd
,
3100 "no default-metric",
3102 "Set a metric of redistribute routes\n"
3107 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
3108 /* rip_update_default_metric (); */
3116 "timers basic (5-2147483647) (5-2147483647) (5-2147483647)",
3117 "Adjust routing timers\n"
3118 "Basic routing protocol update timers\n"
3119 "Routing table update timer value in second. Default is 30.\n"
3120 "Routing information timeout timer. Default is 180.\n"
3121 "Garbage collection timer. Default is 120.\n")
3123 unsigned long update
;
3124 unsigned long timeout
;
3125 unsigned long garbage
;
3126 char *endptr
= NULL
;
3127 unsigned long RIP_TIMER_MAX
= 2147483647;
3128 unsigned long RIP_TIMER_MIN
= 5;
3130 update
= strtoul (argv
[2]->arg
, &endptr
, 10);
3131 if (update
> RIP_TIMER_MAX
|| update
< RIP_TIMER_MIN
|| *endptr
!= '\0')
3133 vty_out (vty
, "update timer value error%s", VTY_NEWLINE
);
3137 timeout
= strtoul (argv
[3]->arg
, &endptr
, 10);
3138 if (timeout
> RIP_TIMER_MAX
|| timeout
< RIP_TIMER_MIN
|| *endptr
!= '\0')
3140 vty_out (vty
, "timeout timer value error%s", VTY_NEWLINE
);
3144 garbage
= strtoul (argv
[4]->arg
, &endptr
, 10);
3145 if (garbage
> RIP_TIMER_MAX
|| garbage
< RIP_TIMER_MIN
|| *endptr
!= '\0')
3147 vty_out (vty
, "garbage timer value error%s", VTY_NEWLINE
);
3151 /* Set each timer value. */
3152 rip
->update_time
= update
;
3153 rip
->timeout_time
= timeout
;
3154 rip
->garbage_time
= garbage
;
3156 /* Reset update timer thread. */
3157 rip_event (RIP_UPDATE_EVENT
, 0);
3163 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3164 * "no timers basic <0-65535> <0-65535> <0-65535>",
3166 * "Adjust routing timers\n"
3167 * "Basic routing protocol update timers\n"
3168 * "Routing table update timer value in second. Default is 30.\n"
3169 * "Routing information timeout timer. Default is 180.\n"
3170 * "Garbage collection timer. Default is 120.\n"
3173 DEFUN (no_rip_timers
,
3177 "Adjust routing timers\n"
3178 "Basic routing protocol update timers\n")
3180 /* Set each timer value to the default. */
3181 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
3182 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
3183 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
3185 /* Reset update timer thread. */
3186 rip_event (RIP_UPDATE_EVENT
, 0);
3193 struct route_table
*rip_distance_table
;
3197 /* Distance value for the IP source prefix. */
3200 /* Name of the access-list to be matched. */
3204 static struct rip_distance
*
3205 rip_distance_new (void)
3207 return XCALLOC (MTYPE_RIP_DISTANCE
, sizeof (struct rip_distance
));
3211 rip_distance_free (struct rip_distance
*rdistance
)
3213 XFREE (MTYPE_RIP_DISTANCE
, rdistance
);
3217 rip_distance_set (struct vty
*vty
, const char *distance_str
, const char *ip_str
,
3218 const char *access_list_str
)
3221 struct prefix_ipv4 p
;
3223 struct route_node
*rn
;
3224 struct rip_distance
*rdistance
;
3226 ret
= str2prefix_ipv4 (ip_str
, &p
);
3229 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
3233 distance
= atoi (distance_str
);
3235 /* Get RIP distance node. */
3236 rn
= route_node_get (rip_distance_table
, (struct prefix
*) &p
);
3239 rdistance
= rn
->info
;
3240 route_unlock_node (rn
);
3244 rdistance
= rip_distance_new ();
3245 rn
->info
= rdistance
;
3248 /* Set distance value. */
3249 rdistance
->distance
= distance
;
3251 /* Reset access-list configuration. */
3252 if (rdistance
->access_list
)
3254 free (rdistance
->access_list
);
3255 rdistance
->access_list
= NULL
;
3257 if (access_list_str
)
3258 rdistance
->access_list
= strdup (access_list_str
);
3264 rip_distance_unset (struct vty
*vty
, const char *distance_str
,
3265 const char *ip_str
, const char *access_list_str
)
3268 struct prefix_ipv4 p
;
3269 struct route_node
*rn
;
3270 struct rip_distance
*rdistance
;
3272 ret
= str2prefix_ipv4 (ip_str
, &p
);
3275 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
3279 rn
= route_node_lookup (rip_distance_table
, (struct prefix
*)&p
);
3282 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
3286 rdistance
= rn
->info
;
3288 if (rdistance
->access_list
)
3289 free (rdistance
->access_list
);
3290 rip_distance_free (rdistance
);
3293 route_unlock_node (rn
);
3294 route_unlock_node (rn
);
3300 rip_distance_reset (void)
3302 struct route_node
*rn
;
3303 struct rip_distance
*rdistance
;
3305 for (rn
= route_top (rip_distance_table
); rn
; rn
= route_next (rn
))
3306 if ((rdistance
= rn
->info
) != NULL
)
3308 if (rdistance
->access_list
)
3309 free (rdistance
->access_list
);
3310 rip_distance_free (rdistance
);
3312 route_unlock_node (rn
);
3316 /* Apply RIP information to distance method. */
3318 rip_distance_apply (struct rip_info
*rinfo
)
3320 struct route_node
*rn
;
3321 struct prefix_ipv4 p
;
3322 struct rip_distance
*rdistance
;
3323 struct access_list
*alist
;
3328 memset (&p
, 0, sizeof (struct prefix_ipv4
));
3330 p
.prefix
= rinfo
->from
;
3331 p
.prefixlen
= IPV4_MAX_BITLEN
;
3333 /* Check source address. */
3334 rn
= route_node_match (rip_distance_table
, (struct prefix
*) &p
);
3337 rdistance
= rn
->info
;
3338 route_unlock_node (rn
);
3340 if (rdistance
->access_list
)
3342 alist
= access_list_lookup (AFI_IP
, rdistance
->access_list
);
3345 if (access_list_apply (alist
, &rinfo
->rp
->p
) == FILTER_DENY
)
3348 return rdistance
->distance
;
3351 return rdistance
->distance
;
3355 return rip
->distance
;
3361 rip_distance_show (struct vty
*vty
)
3363 struct route_node
*rn
;
3364 struct rip_distance
*rdistance
;
3368 vty_out (vty
, " Distance: (default is %d)%s",
3369 rip
->distance
? rip
->distance
:ZEBRA_RIP_DISTANCE_DEFAULT
,
3372 for (rn
= route_top (rip_distance_table
); rn
; rn
= route_next (rn
))
3373 if ((rdistance
= rn
->info
) != NULL
)
3377 vty_out (vty
, " Address Distance List%s",
3381 sprintf (buf
, "%s/%d", inet_ntoa (rn
->p
.u
.prefix4
), rn
->p
.prefixlen
);
3382 vty_out (vty
, " %-20s %4d %s%s",
3383 buf
, rdistance
->distance
,
3384 rdistance
->access_list
? rdistance
->access_list
: "",
3389 DEFUN (rip_distance
,
3392 "Administrative distance\n"
3395 rip
->distance
= atoi (argv
[1]->arg
);
3399 DEFUN (no_rip_distance
,
3400 no_rip_distance_cmd
,
3401 "no distance (1-255)",
3403 "Administrative distance\n"
3410 DEFUN (rip_distance_source
,
3411 rip_distance_source_cmd
,
3412 "distance (1-255) A.B.C.D/M",
3413 "Administrative distance\n"
3415 "IP source prefix\n")
3417 rip_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
3421 DEFUN (no_rip_distance_source
,
3422 no_rip_distance_source_cmd
,
3423 "no distance (1-255) A.B.C.D/M",
3425 "Administrative distance\n"
3427 "IP source prefix\n")
3429 rip_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
3433 DEFUN (rip_distance_source_access_list
,
3434 rip_distance_source_access_list_cmd
,
3435 "distance (1-255) A.B.C.D/M WORD",
3436 "Administrative distance\n"
3438 "IP source prefix\n"
3439 "Access list name\n")
3441 rip_distance_set (vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
3445 DEFUN (no_rip_distance_source_access_list
,
3446 no_rip_distance_source_access_list_cmd
,
3447 "no distance (1-255) A.B.C.D/M WORD",
3449 "Administrative distance\n"
3451 "IP source prefix\n"
3452 "Access list name\n")
3454 rip_distance_unset (vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
3458 /* Update ECMP routes to zebra when ECMP is disabled. */
3460 rip_ecmp_disable (void)
3462 struct route_node
*rp
;
3463 struct rip_info
*rinfo
, *tmp_rinfo
;
3465 struct listnode
*node
, *nextnode
;
3470 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
3471 if ((list
= rp
->info
) != NULL
&& listcount (list
) > 1)
3473 rinfo
= listgetdata (listhead (list
));
3474 if (!rip_route_rte (rinfo
))
3477 /* Drop all other entries, except the first one. */
3478 for (ALL_LIST_ELEMENTS (list
, node
, nextnode
, tmp_rinfo
))
3479 if (tmp_rinfo
!= rinfo
)
3481 RIP_TIMER_OFF (tmp_rinfo
->t_timeout
);
3482 RIP_TIMER_OFF (tmp_rinfo
->t_garbage_collect
);
3483 list_delete_node (list
, node
);
3484 rip_info_free (tmp_rinfo
);
3488 rip_zebra_ipv4_add (rp
);
3490 /* Set the route change flag. */
3491 SET_FLAG (rinfo
->flags
, RIP_RTF_CHANGED
);
3493 /* Signal the output process to trigger an update. */
3494 rip_event (RIP_TRIGGERED_UPDATE
, 0);
3498 DEFUN (rip_allow_ecmp
,
3501 "Allow Equal Cost MultiPath\n")
3505 vty_out (vty
, "ECMP is already enabled.%s", VTY_NEWLINE
);
3510 zlog_info ("ECMP is enabled.");
3514 DEFUN (no_rip_allow_ecmp
,
3515 no_rip_allow_ecmp_cmd
,
3518 "Allow Equal Cost MultiPath\n")
3522 vty_out (vty
, "ECMP is already disabled.%s", VTY_NEWLINE
);
3527 zlog_info ("ECMP is disabled.");
3528 rip_ecmp_disable ();
3532 /* Print out routes update time. */
3534 rip_vty_out_uptime (struct vty
*vty
, struct rip_info
*rinfo
)
3539 char timebuf
[TIME_BUF
];
3540 struct thread
*thread
;
3542 if ((thread
= rinfo
->t_timeout
) != NULL
)
3544 clock
= thread_timer_remain_second (thread
);
3545 tm
= gmtime (&clock
);
3546 strftime (timebuf
, TIME_BUF
, "%M:%S", tm
);
3547 vty_out (vty
, "%5s", timebuf
);
3549 else if ((thread
= rinfo
->t_garbage_collect
) != NULL
)
3551 clock
= thread_timer_remain_second (thread
);
3552 tm
= gmtime (&clock
);
3553 strftime (timebuf
, TIME_BUF
, "%M:%S", tm
);
3554 vty_out (vty
, "%5s", timebuf
);
3559 rip_route_type_print (int sub_type
)
3565 case RIP_ROUTE_STATIC
:
3567 case RIP_ROUTE_DEFAULT
:
3569 case RIP_ROUTE_REDISTRIBUTE
:
3571 case RIP_ROUTE_INTERFACE
:
3583 "Show RIP routes\n")
3585 struct route_node
*np
;
3586 struct rip_info
*rinfo
= NULL
;
3587 struct list
*list
= NULL
;
3588 struct listnode
*listnode
= NULL
;
3593 vty_out (vty
, "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP%s"
3595 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,%s"
3596 " (i) - interface%s%s"
3597 " Network Next Hop Metric From Tag Time%s",
3598 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
3600 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
3601 if ((list
= np
->info
) != NULL
)
3602 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
3606 len
= vty_out (vty
, "%c(%s) %s/%d",
3607 /* np->lock, For debugging. */
3608 zebra_route_char(rinfo
->type
),
3609 rip_route_type_print (rinfo
->sub_type
),
3610 inet_ntoa (np
->p
.u
.prefix4
), np
->p
.prefixlen
);
3615 vty_out (vty
, "%*s", len
, " ");
3617 if (rinfo
->nexthop
.s_addr
)
3618 vty_out (vty
, "%-20s %2d ", inet_ntoa (rinfo
->nexthop
),
3621 vty_out (vty
, "0.0.0.0 %2d ", rinfo
->metric
);
3623 /* Route which exist in kernel routing table. */
3624 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
) &&
3625 (rinfo
->sub_type
== RIP_ROUTE_RTE
))
3627 vty_out (vty
, "%-15s ", inet_ntoa (rinfo
->from
));
3628 vty_out (vty
, "%3d ", rinfo
->tag
);
3629 rip_vty_out_uptime (vty
, rinfo
);
3631 else if (rinfo
->metric
== RIP_METRIC_INFINITY
)
3633 vty_out (vty
, "self ");
3634 vty_out (vty
, "%3d ", rinfo
->tag
);
3635 rip_vty_out_uptime (vty
, rinfo
);
3639 if (rinfo
->external_metric
)
3641 len
= vty_out (vty
, "self (%s:%d)",
3642 zebra_route_string(rinfo
->type
),
3643 rinfo
->external_metric
);
3646 vty_out (vty
, "%*s", len
, " ");
3649 vty_out (vty
, "self ");
3650 vty_out (vty
, "%3d", rinfo
->tag
);
3653 vty_out (vty
, "%s", VTY_NEWLINE
);
3658 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3659 DEFUN (show_ip_rip_status
,
3660 show_ip_rip_status_cmd
,
3661 "show ip rip status",
3665 "IP routing protocol process parameters and statistics\n")
3667 struct listnode
*node
;
3668 struct interface
*ifp
;
3669 struct rip_interface
*ri
;
3670 extern const struct message ri_version_msg
[];
3671 const char *send_version
;
3672 const char *receive_version
;
3677 vty_out (vty
, "Routing Protocol is \"rip\"%s", VTY_NEWLINE
);
3678 vty_out (vty
, " Sending updates every %ld seconds with +/-50%%,",
3680 vty_out (vty
, " next due in %lu seconds%s",
3681 thread_timer_remain_second(rip
->t_update
),
3683 vty_out (vty
, " Timeout after %ld seconds,", rip
->timeout_time
);
3684 vty_out (vty
, " garbage collect after %ld seconds%s", rip
->garbage_time
,
3687 /* Filtering status show. */
3688 config_show_distribute (vty
);
3690 /* Default metric information. */
3691 vty_out (vty
, " Default redistribution metric is %d%s",
3692 rip
->default_metric
, VTY_NEWLINE
);
3694 /* Redistribute information. */
3695 vty_out (vty
, " Redistributing:");
3696 config_write_rip_redistribute (vty
, 0);
3697 vty_out (vty
, "%s", VTY_NEWLINE
);
3699 vty_out (vty
, " Default version control: send version %s,",
3700 lookup(ri_version_msg
,rip
->version_send
));
3701 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3702 vty_out (vty
, " receive any version %s", VTY_NEWLINE
);
3704 vty_out (vty
, " receive version %s %s",
3705 lookup(ri_version_msg
,rip
->version_recv
), VTY_NEWLINE
);
3707 vty_out (vty
, " Interface Send Recv Key-chain%s", VTY_NEWLINE
);
3709 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
))
3716 if (ri
->enable_network
|| ri
->enable_interface
)
3718 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3719 send_version
= lookup (ri_version_msg
, rip
->version_send
);
3721 send_version
= lookup (ri_version_msg
, ri
->ri_send
);
3723 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3724 receive_version
= lookup (ri_version_msg
, rip
->version_recv
);
3726 receive_version
= lookup (ri_version_msg
, ri
->ri_receive
);
3728 vty_out (vty
, " %-17s%-3s %-3s %s%s", ifp
->name
,
3731 ri
->key_chain
? ri
->key_chain
: "",
3736 vty_out (vty
, " Routing for Networks:%s", VTY_NEWLINE
);
3737 config_write_rip_network (vty
, 0);
3740 int found_passive
= 0;
3741 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
))
3745 if ((ri
->enable_network
|| ri
->enable_interface
) && ri
->passive
)
3749 vty_out (vty
, " Passive Interface(s):%s", VTY_NEWLINE
);
3752 vty_out (vty
, " %s%s", ifp
->name
, VTY_NEWLINE
);
3757 vty_out (vty
, " Routing Information Sources:%s", VTY_NEWLINE
);
3758 vty_out (vty
, " Gateway BadPackets BadRoutes Distance Last Update%s", VTY_NEWLINE
);
3759 rip_peer_display (vty
);
3761 rip_distance_show (vty
);
3766 /* RIP configuration write function. */
3768 config_write_rip (struct vty
*vty
)
3771 struct route_node
*rn
;
3772 struct rip_distance
*rdistance
;
3776 /* Router RIP statement. */
3777 vty_out (vty
, "router rip%s", VTY_NEWLINE
);
3780 /* RIP version statement. Default is RIP version 2. */
3781 if (rip
->version_send
!= RI_RIP_VERSION_2
3782 || rip
->version_recv
!= RI_RIP_VERSION_1_AND_2
)
3783 vty_out (vty
, " version %d%s", rip
->version_send
,
3786 /* RIP timer configuration. */
3787 if (rip
->update_time
!= RIP_UPDATE_TIMER_DEFAULT
3788 || rip
->timeout_time
!= RIP_TIMEOUT_TIMER_DEFAULT
3789 || rip
->garbage_time
!= RIP_GARBAGE_TIMER_DEFAULT
)
3790 vty_out (vty
, " timers basic %lu %lu %lu%s",
3796 /* Default information configuration. */
3797 if (rip
->default_information
)
3799 if (rip
->default_information_route_map
)
3800 vty_out (vty
, " default-information originate route-map %s%s",
3801 rip
->default_information_route_map
, VTY_NEWLINE
);
3803 vty_out (vty
, " default-information originate%s",
3807 /* Redistribute configuration. */
3808 config_write_rip_redistribute (vty
, 1);
3810 /* RIP offset-list configuration. */
3811 config_write_rip_offset_list (vty
);
3813 /* RIP enabled network and interface configuration. */
3814 config_write_rip_network (vty
, 1);
3816 /* RIP default metric configuration */
3817 if (rip
->default_metric
!= RIP_DEFAULT_METRIC_DEFAULT
)
3818 vty_out (vty
, " default-metric %d%s",
3819 rip
->default_metric
, VTY_NEWLINE
);
3821 /* Distribute configuration. */
3822 write
+= config_write_distribute (vty
);
3824 /* Interface routemap configuration */
3825 write
+= config_write_if_rmap (vty
);
3827 /* Distance configuration. */
3829 vty_out (vty
, " distance %d%s", rip
->distance
, VTY_NEWLINE
);
3831 /* RIP source IP prefix distance configuration. */
3832 for (rn
= route_top (rip_distance_table
); rn
; rn
= route_next (rn
))
3833 if ((rdistance
= rn
->info
) != NULL
)
3834 vty_out (vty
, " distance %d %s/%d %s%s", rdistance
->distance
,
3835 inet_ntoa (rn
->p
.u
.prefix4
), rn
->p
.prefixlen
,
3836 rdistance
->access_list
? rdistance
->access_list
: "",
3839 /* ECMP configuration. */
3841 vty_out (vty
, " allow-ecmp%s", VTY_NEWLINE
);
3843 /* RIP static route configuration. */
3844 for (rn
= route_top (rip
->route
); rn
; rn
= route_next (rn
))
3846 vty_out (vty
, " route %s/%d%s",
3847 inet_ntoa (rn
->p
.u
.prefix4
),
3855 /* RIP node structure. */
3856 static struct cmd_node rip_node
=
3859 "%s(config-router)# ",
3863 /* Distribute-list update functions. */
3865 rip_distribute_update (struct distribute
*dist
)
3867 struct interface
*ifp
;
3868 struct rip_interface
*ri
;
3869 struct access_list
*alist
;
3870 struct prefix_list
*plist
;
3875 ifp
= if_lookup_by_name (dist
->ifname
);
3881 if (dist
->list
[DISTRIBUTE_IN
])
3883 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_IN
]);
3885 ri
->list
[RIP_FILTER_IN
] = alist
;
3887 ri
->list
[RIP_FILTER_IN
] = NULL
;
3890 ri
->list
[RIP_FILTER_IN
] = NULL
;
3892 if (dist
->list
[DISTRIBUTE_OUT
])
3894 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_OUT
]);
3896 ri
->list
[RIP_FILTER_OUT
] = alist
;
3898 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3901 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3903 if (dist
->prefix
[DISTRIBUTE_IN
])
3905 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_IN
]);
3907 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3909 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3912 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3914 if (dist
->prefix
[DISTRIBUTE_OUT
])
3916 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_OUT
]);
3918 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3920 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3923 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3927 rip_distribute_update_interface (struct interface
*ifp
)
3929 struct distribute
*dist
;
3931 dist
= distribute_lookup (ifp
->name
);
3933 rip_distribute_update (dist
);
3936 /* Update all interface's distribute list. */
3939 rip_distribute_update_all (struct prefix_list
*notused
)
3941 struct interface
*ifp
;
3942 struct listnode
*node
, *nnode
;
3944 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), node
, nnode
, ifp
))
3945 rip_distribute_update_interface (ifp
);
3949 rip_distribute_update_all_wrapper(struct access_list
*notused
)
3951 rip_distribute_update_all(NULL
);
3954 /* Delete all added rip route. */
3959 struct route_node
*rp
;
3960 struct rip_info
*rinfo
= NULL
;
3961 struct list
*list
= NULL
;
3962 struct listnode
*listnode
= NULL
;
3966 /* Clear RIP routes */
3967 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
3968 if ((list
= rp
->info
) != NULL
)
3970 rinfo
= listgetdata (listhead (list
));
3971 if (rip_route_rte (rinfo
))
3972 rip_zebra_ipv4_delete (rp
);
3974 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
3976 RIP_TIMER_OFF (rinfo
->t_timeout
);
3977 RIP_TIMER_OFF (rinfo
->t_garbage_collect
);
3978 rip_info_free (rinfo
);
3982 route_unlock_node (rp
);
3985 /* Cancel RIP related timers. */
3986 RIP_TIMER_OFF (rip
->t_update
);
3987 RIP_TIMER_OFF (rip
->t_triggered_update
);
3988 RIP_TIMER_OFF (rip
->t_triggered_interval
);
3990 /* Cancel read thread. */
3993 thread_cancel (rip
->t_read
);
3997 /* Close RIP socket. */
4004 /* Static RIP route configuration. */
4005 for (rp
= route_top (rip
->route
); rp
; rp
= route_next (rp
))
4009 route_unlock_node (rp
);
4012 /* RIP neighbor configuration. */
4013 for (rp
= route_top (rip
->neighbor
); rp
; rp
= route_next (rp
))
4017 route_unlock_node (rp
);
4020 /* Redistribute related clear. */
4021 if (rip
->default_information_route_map
)
4022 free (rip
->default_information_route_map
);
4024 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
4025 if (rip
->route_map
[i
].name
)
4026 free (rip
->route_map
[i
].name
);
4028 XFREE (MTYPE_ROUTE_TABLE
, rip
->table
);
4029 XFREE (MTYPE_ROUTE_TABLE
, rip
->route
);
4030 XFREE (MTYPE_ROUTE_TABLE
, rip
->neighbor
);
4032 XFREE (MTYPE_RIP
, rip
);
4036 rip_clean_network ();
4037 rip_passive_nondefault_clean ();
4038 rip_offset_clean ();
4039 rip_interface_clean ();
4040 rip_distance_reset ();
4041 rip_redistribute_clean ();
4044 /* Reset all values to the default settings. */
4048 /* Reset global counters. */
4049 rip_global_route_changes
= 0;
4050 rip_global_queries
= 0;
4052 /* Call ripd related reset functions. */
4054 rip_route_map_reset ();
4056 /* Call library reset functions. */
4058 access_list_reset ();
4059 prefix_list_reset ();
4061 distribute_list_reset ();
4063 rip_interface_reset ();
4064 rip_distance_reset ();
4066 rip_zclient_reset ();
4070 rip_if_rmap_update (struct if_rmap
*if_rmap
)
4072 struct interface
*ifp
;
4073 struct rip_interface
*ri
;
4074 struct route_map
*rmap
;
4076 ifp
= if_lookup_by_name (if_rmap
->ifname
);
4082 if (if_rmap
->routemap
[IF_RMAP_IN
])
4084 rmap
= route_map_lookup_by_name (if_rmap
->routemap
[IF_RMAP_IN
]);
4086 ri
->routemap
[IF_RMAP_IN
] = rmap
;
4088 ri
->routemap
[IF_RMAP_IN
] = NULL
;
4091 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
4093 if (if_rmap
->routemap
[IF_RMAP_OUT
])
4095 rmap
= route_map_lookup_by_name (if_rmap
->routemap
[IF_RMAP_OUT
]);
4097 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
4099 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
4102 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
4106 rip_if_rmap_update_interface (struct interface
*ifp
)
4108 struct if_rmap
*if_rmap
;
4110 if_rmap
= if_rmap_lookup (ifp
->name
);
4112 rip_if_rmap_update (if_rmap
);
4116 rip_routemap_update_redistribute (void)
4122 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
4124 if (rip
->route_map
[i
].name
)
4125 rip
->route_map
[i
].map
=
4126 route_map_lookup_by_name (rip
->route_map
[i
].name
);
4133 rip_routemap_update (const char *notused
)
4135 struct interface
*ifp
;
4136 struct listnode
*node
, *nnode
;
4138 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), node
, nnode
, ifp
))
4139 rip_if_rmap_update_interface (ifp
);
4141 rip_routemap_update_redistribute ();
4144 /* Allocate new rip structure and set default value. */
4148 /* Randomize for triggered update random(). */
4149 srandom (time (NULL
));
4151 /* Install top nodes. */
4152 install_node (&rip_node
, config_write_rip
);
4154 /* Install rip commands. */
4155 install_element (VIEW_NODE
, &show_ip_rip_cmd
);
4156 install_element (VIEW_NODE
, &show_ip_rip_status_cmd
);
4157 install_element (ENABLE_NODE
, &show_ip_rip_cmd
);
4158 install_element (ENABLE_NODE
, &show_ip_rip_status_cmd
);
4159 install_element (CONFIG_NODE
, &router_rip_cmd
);
4160 install_element (CONFIG_NODE
, &no_router_rip_cmd
);
4162 install_default (RIP_NODE
);
4163 install_element (RIP_NODE
, &rip_version_cmd
);
4164 install_element (RIP_NODE
, &no_rip_version_cmd
);
4165 install_element (RIP_NODE
, &rip_default_metric_cmd
);
4166 install_element (RIP_NODE
, &no_rip_default_metric_cmd
);
4167 install_element (RIP_NODE
, &rip_timers_cmd
);
4168 install_element (RIP_NODE
, &no_rip_timers_cmd
);
4169 install_element (RIP_NODE
, &rip_route_cmd
);
4170 install_element (RIP_NODE
, &no_rip_route_cmd
);
4171 install_element (RIP_NODE
, &rip_distance_cmd
);
4172 install_element (RIP_NODE
, &no_rip_distance_cmd
);
4173 install_element (RIP_NODE
, &rip_distance_source_cmd
);
4174 install_element (RIP_NODE
, &no_rip_distance_source_cmd
);
4175 install_element (RIP_NODE
, &rip_distance_source_access_list_cmd
);
4176 install_element (RIP_NODE
, &no_rip_distance_source_access_list_cmd
);
4177 install_element (RIP_NODE
, &rip_allow_ecmp_cmd
);
4178 install_element (RIP_NODE
, &no_rip_allow_ecmp_cmd
);
4180 /* Debug related init. */
4186 #endif /* HAVE_SNMP */
4188 /* Access list install. */
4189 access_list_init ();
4190 access_list_add_hook (rip_distribute_update_all_wrapper
);
4191 access_list_delete_hook (rip_distribute_update_all_wrapper
);
4193 /* Prefix list initialize.*/
4194 prefix_list_init ();
4195 prefix_list_add_hook (rip_distribute_update_all
);
4196 prefix_list_delete_hook (rip_distribute_update_all
);
4198 /* Distribute list install. */
4199 distribute_list_init (RIP_NODE
);
4200 distribute_list_add_hook (rip_distribute_update
);
4201 distribute_list_delete_hook (rip_distribute_update
);
4204 rip_route_map_init ();
4207 route_map_add_hook (rip_routemap_update
);
4208 route_map_delete_hook (rip_routemap_update
);
4210 if_rmap_init (RIP_NODE
);
4211 if_rmap_hook_add (rip_if_rmap_update
);
4212 if_rmap_hook_delete (rip_if_rmap_update
);
4214 /* Distance control. */
4215 rip_distance_table
= route_table_init ();