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_filter (int rip_distribute
, struct prefix_ipv4
*p
, struct rip_interface
*ri
)
321 struct distribute
*dist
;
322 struct access_list
*alist
;
323 struct prefix_list
*plist
;
324 int distribute
= rip_distribute
== RIP_FILTER_OUT
?
325 DISTRIBUTE_V4_OUT
: DISTRIBUTE_V4_IN
;
326 const char *inout
= rip_distribute
== RIP_FILTER_OUT
? "out" : "in";
328 /* Input distribute-list filtering. */
329 if (ri
->list
[rip_distribute
])
331 if (access_list_apply (ri
->list
[rip_distribute
],
332 (struct prefix
*) p
) == FILTER_DENY
)
334 if (IS_RIP_DEBUG_PACKET
)
335 zlog_debug ("%s/%d filtered by distribute %s",
336 inet_ntoa (p
->prefix
), p
->prefixlen
, inout
);
340 if (ri
->prefix
[rip_distribute
])
342 if (prefix_list_apply (ri
->prefix
[rip_distribute
],
343 (struct prefix
*) p
) == PREFIX_DENY
)
345 if (IS_RIP_DEBUG_PACKET
)
346 zlog_debug ("%s/%d filtered by prefix-list %s",
347 inet_ntoa (p
->prefix
), p
->prefixlen
, inout
);
352 /* All interface filter check. */
353 dist
= distribute_lookup (NULL
);
356 if (dist
->list
[distribute
])
358 alist
= access_list_lookup (AFI_IP
, dist
->list
[distribute
]);
362 if (access_list_apply (alist
, (struct prefix
*) p
) == FILTER_DENY
)
364 if (IS_RIP_DEBUG_PACKET
)
365 zlog_debug ("%s/%d filtered by distribute %s",
366 inet_ntoa (p
->prefix
), p
->prefixlen
, inout
);
371 if (dist
->prefix
[distribute
])
373 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[distribute
]);
377 if (prefix_list_apply (plist
,
378 (struct prefix
*) p
) == PREFIX_DENY
)
380 if (IS_RIP_DEBUG_PACKET
)
381 zlog_debug ("%s/%d filtered by prefix-list %s",
382 inet_ntoa (p
->prefix
), p
->prefixlen
, inout
);
391 /* Check nexthop address validity. */
393 rip_nexthop_check (struct in_addr
*addr
)
395 struct listnode
*node
;
396 struct listnode
*cnode
;
397 struct interface
*ifp
;
398 struct connected
*ifc
;
401 /* If nexthop address matches local configured address then it is
404 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
))
406 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, ifc
))
410 if (p
->family
== AF_INET
411 && IPV4_ADDR_SAME (&p
->u
.prefix4
, addr
))
418 /* RIP add route to routing table. */
420 rip_rte_process (struct rte
*rte
, struct sockaddr_in
*from
,
421 struct interface
*ifp
)
424 struct prefix_ipv4 p
;
425 struct route_node
*rp
;
426 struct rip_info
*rinfo
= NULL
, newinfo
;
427 struct rip_interface
*ri
;
428 struct in_addr
*nexthop
;
430 unsigned char old_dist
, new_dist
;
431 struct list
*list
= NULL
;
432 struct listnode
*node
= NULL
;
434 /* Make prefix structure. */
435 memset (&p
, 0, sizeof (struct prefix_ipv4
));
437 p
.prefix
= rte
->prefix
;
438 p
.prefixlen
= ip_masklen (rte
->mask
);
440 /* Make sure mask is applied. */
441 apply_mask_ipv4 (&p
);
443 /* Apply input filters. */
446 ret
= rip_filter (RIP_FILTER_IN
, &p
, ri
);
450 memset (&newinfo
, 0, sizeof (newinfo
));
451 newinfo
.type
= ZEBRA_ROUTE_RIP
;
452 newinfo
.sub_type
= RIP_ROUTE_RTE
;
453 newinfo
.nexthop
= rte
->nexthop
;
454 newinfo
.from
= from
->sin_addr
;
455 newinfo
.ifindex
= ifp
->ifindex
;
456 newinfo
.metric
= rte
->metric
;
457 newinfo
.metric_out
= rte
->metric
; /* XXX */
458 newinfo
.tag
= ntohs (rte
->tag
); /* XXX */
460 /* Modify entry according to the interface routemap. */
461 if (ri
->routemap
[RIP_FILTER_IN
])
465 /* The object should be of the type of rip_info */
466 ret
= route_map_apply (ri
->routemap
[RIP_FILTER_IN
],
467 (struct prefix
*) &p
, RMAP_RIP
, &newinfo
);
469 if (ret
== RMAP_DENYMATCH
)
471 if (IS_RIP_DEBUG_PACKET
)
472 zlog_debug ("RIP %s/%d is filtered by route-map in",
473 inet_ntoa (p
.prefix
), p
.prefixlen
);
477 /* Get back the object */
478 rte
->nexthop
= newinfo
.nexthop_out
;
479 rte
->tag
= htons (newinfo
.tag_out
); /* XXX */
480 rte
->metric
= newinfo
.metric_out
; /* XXX: the routemap uses the metric_out field */
483 /* Once the entry has been validated, update the metric by
484 adding the cost of the network on wich the message
485 arrived. If the result is greater than infinity, use infinity
486 (RFC2453 Sec. 3.9.2) */
487 /* Zebra ripd can handle offset-list in. */
488 ret
= rip_offset_list_apply_in (&p
, ifp
, &rte
->metric
);
490 /* If offset-list does not modify the metric use interface's
493 rte
->metric
+= ifp
->metric
? ifp
->metric
: 1;
495 if (rte
->metric
> RIP_METRIC_INFINITY
)
496 rte
->metric
= RIP_METRIC_INFINITY
;
498 /* Set nexthop pointer. */
499 if (rte
->nexthop
.s_addr
== 0)
500 nexthop
= &from
->sin_addr
;
502 nexthop
= &rte
->nexthop
;
504 /* Check if nexthop address is myself, then do nothing. */
505 if (rip_nexthop_check (nexthop
) < 0)
507 if (IS_RIP_DEBUG_PACKET
)
508 zlog_debug ("Nexthop address %s is myself", inet_ntoa (*nexthop
));
512 /* Get index for the prefix. */
513 rp
= route_node_get (rip
->table
, (struct prefix
*) &p
);
516 newinfo
.nexthop
= *nexthop
;
517 newinfo
.metric
= rte
->metric
;
518 newinfo
.tag
= ntohs (rte
->tag
);
519 newinfo
.distance
= rip_distance_apply (&newinfo
);
521 new_dist
= newinfo
.distance
? newinfo
.distance
: ZEBRA_RIP_DISTANCE_DEFAULT
;
523 /* Check to see whether there is already RIP route on the table. */
524 if ((list
= rp
->info
) != NULL
)
525 for (ALL_LIST_ELEMENTS_RO (list
, node
, rinfo
))
527 /* Need to compare with redistributed entry or local entry */
528 if (!rip_route_rte (rinfo
))
531 if (IPV4_ADDR_SAME (&rinfo
->from
, &from
->sin_addr
) &&
532 IPV4_ADDR_SAME (&rinfo
->nexthop
, nexthop
))
535 if (!listnextnode (node
))
537 /* Not found in the list */
539 if (rte
->metric
> rinfo
->metric
)
541 /* New route has a greater metric. Discard it. */
542 route_unlock_node (rp
);
546 if (rte
->metric
< rinfo
->metric
)
547 /* New route has a smaller metric. Replace the ECMP list
548 * with the new one in below. */
551 /* Metrics are same. We compare the distances. */
552 old_dist
= rinfo
->distance
? \
553 rinfo
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
;
555 if (new_dist
> old_dist
)
557 /* New route has a greater distance. Discard it. */
558 route_unlock_node (rp
);
562 if (new_dist
< old_dist
)
563 /* New route has a smaller distance. Replace the ECMP list
564 * with the new one in below. */
567 /* Metrics and distances are both same. Keep "rinfo" null and
568 * the new route is added in the ECMP list in below. */
574 /* Local static route. */
575 if (rinfo
->type
== ZEBRA_ROUTE_RIP
576 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
) ||
577 (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))
578 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
580 route_unlock_node (rp
);
584 /* Redistributed route check. */
585 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
586 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
588 old_dist
= rinfo
->distance
;
589 /* Only routes directly connected to an interface (nexthop == 0)
590 * may have a valid NULL distance */
591 if (rinfo
->nexthop
.s_addr
!= 0)
592 old_dist
= old_dist
? old_dist
: ZEBRA_RIP_DISTANCE_DEFAULT
;
593 /* If imported route does not have STRICT precedence,
594 mark it as a ghost */
595 if (new_dist
<= old_dist
&& rte
->metric
!= RIP_METRIC_INFINITY
)
596 rip_ecmp_replace (&newinfo
);
598 route_unlock_node (rp
);
606 route_unlock_node (rp
);
608 /* Now, check to see whether there is already an explicit route
609 for the destination prefix. If there is no such route, add
610 this route to the routing table, unless the metric is
611 infinity (there is no point in adding a route which
613 if (rte
->metric
!= RIP_METRIC_INFINITY
)
614 rip_ecmp_add (&newinfo
);
618 /* Route is there but we are not sure the route is RIP or not. */
620 /* If there is an existing route, compare the next hop address
621 to the address of the router from which the datagram came.
622 If this datagram is from the same router as the existing
623 route, reinitialize the timeout. */
624 same
= (IPV4_ADDR_SAME (&rinfo
->from
, &from
->sin_addr
)
625 && (rinfo
->ifindex
== ifp
->ifindex
));
627 old_dist
= rinfo
->distance
? \
628 rinfo
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
;
630 /* Next, compare the metrics. If the datagram is from the same
631 router as the existing route, and the new metric is different
632 than the old one; or, if the new metric is lower than the old
633 one, or if the tag has been changed; or if there is a route
634 with a lower administrave distance; or an update of the
635 distance on the actual route; do the following actions: */
636 if ((same
&& rinfo
->metric
!= rte
->metric
)
637 || (rte
->metric
< rinfo
->metric
)
639 && (rinfo
->metric
== rte
->metric
)
640 && (newinfo
.tag
!= rinfo
->tag
))
641 || (old_dist
> new_dist
)
642 || ((old_dist
!= new_dist
) && same
))
644 if (listcount (list
) == 1)
646 if (newinfo
.metric
!= RIP_METRIC_INFINITY
)
647 rip_ecmp_replace (&newinfo
);
649 rip_ecmp_delete (rinfo
);
653 if (newinfo
.metric
< rinfo
->metric
)
654 rip_ecmp_replace (&newinfo
);
655 else if (newinfo
.metric
> rinfo
->metric
)
656 rip_ecmp_delete (rinfo
);
657 else if (new_dist
< old_dist
)
658 rip_ecmp_replace (&newinfo
);
659 else if (new_dist
> old_dist
)
660 rip_ecmp_delete (rinfo
);
663 int update
= CHECK_FLAG (rinfo
->flags
, RIP_RTF_FIB
) ? 1 : 0;
665 assert (newinfo
.metric
!= RIP_METRIC_INFINITY
);
667 RIP_TIMER_OFF (rinfo
->t_timeout
);
668 RIP_TIMER_OFF (rinfo
->t_garbage_collect
);
669 memcpy (rinfo
, &newinfo
, sizeof (struct rip_info
));
670 rip_timeout_update (rinfo
);
673 rip_zebra_ipv4_add (rp
);
675 /* - Set the route change flag on the first entry. */
676 rinfo
= listgetdata (listhead (list
));
677 SET_FLAG (rinfo
->flags
, RIP_RTF_CHANGED
);
678 rip_event (RIP_TRIGGERED_UPDATE
, 0);
682 else /* same & no change */
683 rip_timeout_update (rinfo
);
685 /* Unlock tempolary lock of the route. */
686 route_unlock_node (rp
);
690 /* Dump RIP packet */
692 rip_packet_dump (struct rip_packet
*packet
, int size
, const char *sndrcv
)
696 const char *command_str
;
697 char pbuf
[BUFSIZ
], nbuf
[BUFSIZ
];
701 /* Set command string. */
702 if (packet
->command
> 0 && packet
->command
< RIP_COMMAND_MAX
)
703 command_str
= lookup (rip_msg
, packet
->command
);
705 command_str
= "unknown";
707 /* Dump packet header. */
708 zlog_debug ("%s %s version %d packet size %d",
709 sndrcv
, command_str
, packet
->version
, size
);
711 /* Dump each routing table entry. */
714 for (lim
= (caddr_t
) packet
+ size
; (caddr_t
) rte
< lim
; rte
++)
716 if (packet
->version
== RIPv2
)
718 netmask
= ip_masklen (rte
->mask
);
720 if (rte
->family
== htons (RIP_FAMILY_AUTH
))
722 if (rte
->tag
== htons (RIP_AUTH_SIMPLE_PASSWORD
))
724 p
= (u_char
*)&rte
->prefix
;
726 zlog_debug (" family 0x%X type %d auth string: %s",
727 ntohs (rte
->family
), ntohs (rte
->tag
), p
);
729 else if (rte
->tag
== htons (RIP_AUTH_MD5
))
731 struct rip_md5_info
*md5
;
733 md5
= (struct rip_md5_info
*) &packet
->rte
;
735 zlog_debug (" family 0x%X type %d (MD5 authentication)",
736 ntohs (md5
->family
), ntohs (md5
->type
));
737 zlog_debug (" RIP-2 packet len %d Key ID %d"
739 ntohs (md5
->packet_len
), md5
->keyid
,
741 zlog_debug (" Sequence Number %ld",
742 (u_long
) ntohl (md5
->sequence
));
744 else if (rte
->tag
== htons (RIP_AUTH_DATA
))
746 p
= (u_char
*)&rte
->prefix
;
748 zlog_debug (" family 0x%X type %d (MD5 data)",
749 ntohs (rte
->family
), ntohs (rte
->tag
));
750 zlog_debug (" MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
751 "%02X%02X%02X%02X%02X%02X%02X%02X",
752 p
[0], p
[1], p
[2], p
[3], p
[4], p
[5], p
[6],
753 p
[7], p
[8], p
[9], p
[10], p
[11], p
[12], p
[13],
758 zlog_debug (" family 0x%X type %d (Unknown auth type)",
759 ntohs (rte
->family
), ntohs (rte
->tag
));
763 zlog_debug (" %s/%d -> %s family %d tag %"ROUTE_TAG_PRI
" metric %ld",
764 inet_ntop (AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
765 netmask
, inet_ntop (AF_INET
, &rte
->nexthop
, nbuf
,
766 BUFSIZ
), ntohs (rte
->family
),
767 (route_tag_t
)ntohs (rte
->tag
),
768 (u_long
) ntohl (rte
->metric
));
772 zlog_debug (" %s family %d tag %"ROUTE_TAG_PRI
" metric %ld",
773 inet_ntop (AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
774 ntohs (rte
->family
), (route_tag_t
)ntohs (rte
->tag
),
775 (u_long
)ntohl (rte
->metric
));
780 /* Check if the destination address is valid (unicast; not net 0
781 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
782 check net 0 because we accept default route. */
784 rip_destination_check (struct in_addr addr
)
786 u_int32_t destination
;
788 /* Convert to host byte order. */
789 destination
= ntohl (addr
.s_addr
);
791 if (IPV4_NET127 (destination
))
794 /* Net 0 may match to the default route. */
795 if (IPV4_NET0 (destination
) && destination
!= 0)
798 /* Unicast address must belong to class A, B, C. */
799 if (IN_CLASSA (destination
))
801 if (IN_CLASSB (destination
))
803 if (IN_CLASSC (destination
))
809 /* RIP version 2 authentication. */
811 rip_auth_simple_password (struct rte
*rte
, struct sockaddr_in
*from
,
812 struct interface
*ifp
)
814 struct rip_interface
*ri
;
815 char *auth_str
= (char *) &rte
->prefix
;
818 /* reject passwords with zeros in the middle of the string */
819 for (i
= strlen (auth_str
); i
< 16; i
++)
821 if (auth_str
[i
] != '\0')
825 if (IS_RIP_DEBUG_EVENT
)
826 zlog_debug ("RIPv2 simple password authentication from %s",
827 inet_ntoa (from
->sin_addr
));
831 if (ri
->auth_type
!= RIP_AUTH_SIMPLE_PASSWORD
832 || rte
->tag
!= htons(RIP_AUTH_SIMPLE_PASSWORD
))
835 /* Simple password authentication. */
838 if (strncmp (auth_str
, ri
->auth_str
, 16) == 0)
843 struct keychain
*keychain
;
846 keychain
= keychain_lookup (ri
->key_chain
);
847 if (keychain
== NULL
)
850 key
= key_match_for_accept (keychain
, auth_str
);
857 /* RIP version 2 authentication with MD5. */
859 rip_auth_md5 (struct rip_packet
*packet
, struct sockaddr_in
*from
,
860 int length
, struct interface
*ifp
)
862 struct rip_interface
*ri
;
863 struct rip_md5_info
*md5
;
864 struct rip_md5_data
*md5data
;
865 struct keychain
*keychain
;
868 u_char digest
[RIP_AUTH_MD5_SIZE
];
869 u_int16_t packet_len
;
870 char auth_str
[RIP_AUTH_MD5_SIZE
];
872 if (IS_RIP_DEBUG_EVENT
)
873 zlog_debug ("RIPv2 MD5 authentication from %s",
874 inet_ntoa (from
->sin_addr
));
877 md5
= (struct rip_md5_info
*) &packet
->rte
;
879 /* Check auth type. */
880 if (ri
->auth_type
!= RIP_AUTH_MD5
|| md5
->type
!= htons(RIP_AUTH_MD5
))
883 /* If the authentication length is less than 16, then it must be wrong for
884 * any interpretation of rfc2082. Some implementations also interpret
885 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka RIP_AUTH_MD5_COMPAT_SIZE.
887 if ( !((md5
->auth_len
== RIP_AUTH_MD5_SIZE
)
888 || (md5
->auth_len
== RIP_AUTH_MD5_COMPAT_SIZE
)))
890 if (IS_RIP_DEBUG_EVENT
)
891 zlog_debug ("RIPv2 MD5 authentication, strange authentication "
892 "length field %d", md5
->auth_len
);
896 /* grab and verify check packet length */
897 packet_len
= ntohs (md5
->packet_len
);
899 if (packet_len
> (length
- RIP_HEADER_SIZE
- RIP_AUTH_MD5_SIZE
))
901 if (IS_RIP_DEBUG_EVENT
)
902 zlog_debug ("RIPv2 MD5 authentication, packet length field %d "
903 "greater than received length %d!",
904 md5
->packet_len
, length
);
908 /* retrieve authentication data */
909 md5data
= (struct rip_md5_data
*) (((u_char
*) packet
) + packet_len
);
911 memset (auth_str
, 0, RIP_AUTH_MD5_SIZE
);
915 keychain
= keychain_lookup (ri
->key_chain
);
916 if (keychain
== NULL
)
919 key
= key_lookup_for_accept (keychain
, md5
->keyid
);
923 strncpy (auth_str
, key
->string
, RIP_AUTH_MD5_SIZE
);
925 else if (ri
->auth_str
)
926 strncpy (auth_str
, ri
->auth_str
, RIP_AUTH_MD5_SIZE
);
928 if (auth_str
[0] == 0)
931 /* MD5 digest authentication. */
932 memset (&ctx
, 0, sizeof(ctx
));
934 MD5Update(&ctx
, packet
, packet_len
+ RIP_HEADER_SIZE
);
935 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
936 MD5Final(digest
, &ctx
);
938 if (memcmp (md5data
->digest
, digest
, RIP_AUTH_MD5_SIZE
) == 0)
944 /* Pick correct auth string for sends, prepare auth_str buffer for use.
945 * (left justified and padded).
947 * presumes one of ri or key is valid, and that the auth strings they point
948 * to are nul terminated. If neither are present, auth_str will be fully
953 rip_auth_prepare_str_send (struct rip_interface
*ri
, struct key
*key
,
954 char *auth_str
, int len
)
958 memset (auth_str
, 0, len
);
959 if (key
&& key
->string
)
960 strncpy (auth_str
, key
->string
, len
);
961 else if (ri
->auth_str
)
962 strncpy (auth_str
, ri
->auth_str
, len
);
967 /* Write RIPv2 simple password authentication information
969 * auth_str is presumed to be 2 bytes and correctly prepared
970 * (left justified and zero padded).
973 rip_auth_simple_write (struct stream
*s
, char *auth_str
, int len
)
975 assert (s
&& len
== RIP_AUTH_SIMPLE_SIZE
);
977 stream_putw (s
, RIP_FAMILY_AUTH
);
978 stream_putw (s
, RIP_AUTH_SIMPLE_PASSWORD
);
979 stream_put (s
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
984 /* write RIPv2 MD5 "authentication header"
985 * (uses the auth key data field)
987 * Digest offset field is set to 0.
989 * returns: offset of the digest offset field, which must be set when
990 * length to the auth-data MD5 digest is known.
993 rip_auth_md5_ah_write (struct stream
*s
, struct rip_interface
*ri
,
998 assert (s
&& ri
&& ri
->auth_type
== RIP_AUTH_MD5
);
1000 /* MD5 authentication. */
1001 stream_putw (s
, RIP_FAMILY_AUTH
);
1002 stream_putw (s
, RIP_AUTH_MD5
);
1004 /* MD5 AH digest offset field.
1006 * Set to placeholder value here, to true value when RIP-2 Packet length
1007 * is known. Actual value is set in .....().
1009 doff
= stream_get_endp(s
);
1014 stream_putc (s
, key
->index
% 256);
1018 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
1019 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for this
1020 * to be configurable.
1022 stream_putc (s
, ri
->md5_auth_len
);
1024 /* Sequence Number (non-decreasing). */
1025 /* RFC2080: The value used in the sequence number is
1026 arbitrary, but two suggestions are the time of the
1027 message's creation or a simple message counter. */
1028 stream_putl (s
, time (NULL
));
1030 /* Reserved field must be zero. */
1037 /* If authentication is in used, write the appropriate header
1038 * returns stream offset to which length must later be written
1039 * or 0 if this is not required
1042 rip_auth_header_write (struct stream
*s
, struct rip_interface
*ri
,
1043 struct key
*key
, char *auth_str
, int len
)
1045 assert (ri
->auth_type
!= RIP_NO_AUTH
);
1047 switch (ri
->auth_type
)
1049 case RIP_AUTH_SIMPLE_PASSWORD
:
1050 rip_auth_prepare_str_send (ri
, key
, auth_str
, len
);
1051 rip_auth_simple_write (s
, auth_str
, len
);
1054 return rip_auth_md5_ah_write (s
, ri
, key
);
1060 /* Write RIPv2 MD5 authentication data trailer */
1062 rip_auth_md5_set (struct stream
*s
, struct rip_interface
*ri
, size_t doff
,
1063 char *auth_str
, int authlen
)
1067 unsigned char digest
[RIP_AUTH_MD5_SIZE
];
1069 /* Make it sure this interface is configured as MD5
1071 assert ((ri
->auth_type
== RIP_AUTH_MD5
) && (authlen
== RIP_AUTH_MD5_SIZE
));
1074 /* Get packet length. */
1075 len
= stream_get_endp(s
);
1077 /* Check packet length. */
1078 if (len
< (RIP_HEADER_SIZE
+ RIP_RTE_SIZE
))
1080 zlog_err ("rip_auth_md5_set(): packet length %ld is less than minimum length.", len
);
1084 /* Set the digest offset length in the header */
1085 stream_putw_at (s
, doff
, len
);
1087 /* Set authentication data. */
1088 stream_putw (s
, RIP_FAMILY_AUTH
);
1089 stream_putw (s
, RIP_AUTH_DATA
);
1091 /* Generate a digest for the RIP packet. */
1092 memset(&ctx
, 0, sizeof(ctx
));
1094 MD5Update(&ctx
, STREAM_DATA (s
), stream_get_endp (s
));
1095 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1096 MD5Final(digest
, &ctx
);
1098 /* Copy the digest to the packet. */
1099 stream_write (s
, digest
, RIP_AUTH_MD5_SIZE
);
1102 /* RIP routing information. */
1104 rip_response_process (struct rip_packet
*packet
, int size
,
1105 struct sockaddr_in
*from
, struct connected
*ifc
)
1109 struct prefix_ipv4 ifaddr
;
1110 struct prefix_ipv4 ifaddrclass
;
1113 memset(&ifaddr
, 0, sizeof(ifaddr
));
1114 /* We don't know yet. */
1117 /* The Response must be ignored if it is not from the RIP
1118 port. (RFC2453 - Sec. 3.9.2)*/
1119 if (from
->sin_port
!= htons(RIP_PORT_DEFAULT
))
1121 zlog_info ("response doesn't come from RIP port: %d",
1123 rip_peer_bad_packet (from
);
1127 /* The datagram's IPv4 source address should be checked to see
1128 whether the datagram is from a valid neighbor; the source of the
1129 datagram must be on a directly connected network (RFC2453 - Sec. 3.9.2) */
1130 if (if_lookup_address((void *)&from
->sin_addr
, AF_INET
) == NULL
)
1132 zlog_info ("This datagram doesn't came from a valid neighbor: %s",
1133 inet_ntoa (from
->sin_addr
));
1134 rip_peer_bad_packet (from
);
1138 /* It is also worth checking to see whether the response is from one
1139 of the router's own addresses. */
1141 ; /* Alredy done in rip_read () */
1143 /* Update RIP peer. */
1144 rip_peer_update (from
, packet
->version
);
1146 /* Set RTE pointer. */
1149 for (lim
= (caddr_t
) packet
+ size
; (caddr_t
) rte
< lim
; rte
++)
1151 /* RIPv2 authentication check. */
1152 /* If the Address Family Identifier of the first (and only the
1153 first) entry in the message is 0xFFFF, then the remainder of
1154 the entry contains the authentication. */
1155 /* If the packet gets here it means authentication enabled */
1156 /* Check is done in rip_read(). So, just skipping it */
1157 if (packet
->version
== RIPv2
&&
1158 rte
== packet
->rte
&&
1159 rte
->family
== htons(RIP_FAMILY_AUTH
))
1162 if (rte
->family
!= htons(AF_INET
))
1164 /* Address family check. RIP only supports AF_INET. */
1165 zlog_info ("Unsupported family %d from %s.",
1166 ntohs (rte
->family
), inet_ntoa (from
->sin_addr
));
1170 /* - is the destination address valid (e.g., unicast; not net 0
1172 if (! rip_destination_check (rte
->prefix
))
1174 zlog_info ("Network is net 0 or net 127 or it is not unicast network");
1175 rip_peer_bad_route (from
);
1179 /* Convert metric value to host byte order. */
1180 rte
->metric
= ntohl (rte
->metric
);
1182 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1183 if (! (rte
->metric
>= 1 && rte
->metric
<= 16))
1185 zlog_info ("Route's metric is not in the 1-16 range.");
1186 rip_peer_bad_route (from
);
1190 /* RIPv1 does not have nexthop value. */
1191 if (packet
->version
== RIPv1
&& rte
->nexthop
.s_addr
!= 0)
1193 zlog_info ("RIPv1 packet with nexthop value %s",
1194 inet_ntoa (rte
->nexthop
));
1195 rip_peer_bad_route (from
);
1199 /* That is, if the provided information is ignored, a possibly
1200 sub-optimal, but absolutely valid, route may be taken. If
1201 the received Next Hop is not directly reachable, it should be
1202 treated as 0.0.0.0. */
1203 if (packet
->version
== RIPv2
&& rte
->nexthop
.s_addr
!= 0)
1207 /* Multicast address check. */
1208 addrval
= ntohl (rte
->nexthop
.s_addr
);
1209 if (IN_CLASSD (addrval
))
1211 zlog_info ("Nexthop %s is multicast address, skip this rte",
1212 inet_ntoa (rte
->nexthop
));
1216 if (! if_lookup_address ((void *)&rte
->nexthop
, AF_INET
))
1218 struct route_node
*rn
;
1219 struct rip_info
*rinfo
;
1221 rn
= route_node_match_ipv4 (rip
->table
, &rte
->nexthop
);
1227 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1228 && rinfo
->sub_type
== RIP_ROUTE_RTE
)
1230 if (IS_RIP_DEBUG_EVENT
)
1231 zlog_debug ("Next hop %s is on RIP network. Set nexthop to the packet's originator", inet_ntoa (rte
->nexthop
));
1232 rte
->nexthop
= rinfo
->from
;
1236 if (IS_RIP_DEBUG_EVENT
)
1237 zlog_debug ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte
->nexthop
));
1238 rte
->nexthop
.s_addr
= 0;
1241 route_unlock_node (rn
);
1245 if (IS_RIP_DEBUG_EVENT
)
1246 zlog_debug ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte
->nexthop
));
1247 rte
->nexthop
.s_addr
= 0;
1253 /* For RIPv1, there won't be a valid netmask.
1255 This is a best guess at the masks. If everyone was using old
1256 Ciscos before the 'ip subnet zero' option, it would be almost
1259 Cisco summarize ripv1 advertisments to the classful boundary
1260 (/16 for class B's) except when the RIP packet does to inside
1261 the classful network in question. */
1263 if ((packet
->version
== RIPv1
&& rte
->prefix
.s_addr
!= 0)
1264 || (packet
->version
== RIPv2
1265 && (rte
->prefix
.s_addr
!= 0 && rte
->mask
.s_addr
== 0)))
1267 u_int32_t destination
;
1269 if (subnetted
== -1)
1271 memcpy (&ifaddr
, ifc
->address
, sizeof (struct prefix_ipv4
));
1272 memcpy (&ifaddrclass
, &ifaddr
, sizeof (struct prefix_ipv4
));
1273 apply_classful_mask_ipv4 (&ifaddrclass
);
1275 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1279 destination
= ntohl (rte
->prefix
.s_addr
);
1281 if (IN_CLASSA (destination
))
1282 masklen2ip (8, &rte
->mask
);
1283 else if (IN_CLASSB (destination
))
1284 masklen2ip (16, &rte
->mask
);
1285 else if (IN_CLASSC (destination
))
1286 masklen2ip (24, &rte
->mask
);
1289 masklen2ip (ifaddrclass
.prefixlen
,
1290 (struct in_addr
*) &destination
);
1291 if ((subnetted
== 1) && ((rte
->prefix
.s_addr
& destination
) ==
1292 ifaddrclass
.prefix
.s_addr
))
1294 masklen2ip (ifaddr
.prefixlen
, &rte
->mask
);
1295 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
) != rte
->prefix
.s_addr
)
1296 masklen2ip (32, &rte
->mask
);
1297 if (IS_RIP_DEBUG_EVENT
)
1298 zlog_debug ("Subnetted route %s", inet_ntoa (rte
->prefix
));
1302 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
) != rte
->prefix
.s_addr
)
1306 if (IS_RIP_DEBUG_EVENT
)
1308 zlog_debug ("Resultant route %s", inet_ntoa (rte
->prefix
));
1309 zlog_debug ("Resultant mask %s", inet_ntoa (rte
->mask
));
1313 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1314 ignore the entry. */
1315 if ((packet
->version
== RIPv2
)
1316 && (rte
->mask
.s_addr
!= 0)
1317 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
) != rte
->prefix
.s_addr
))
1319 zlog_warn ("RIPv2 address %s is not mask /%d applied one",
1320 inet_ntoa (rte
->prefix
), ip_masklen (rte
->mask
));
1321 rip_peer_bad_route (from
);
1325 /* Default route's netmask is ignored. */
1326 if (packet
->version
== RIPv2
1327 && (rte
->prefix
.s_addr
== 0)
1328 && (rte
->mask
.s_addr
!= 0))
1330 if (IS_RIP_DEBUG_EVENT
)
1331 zlog_debug ("Default route with non-zero netmask. Set zero to netmask");
1332 rte
->mask
.s_addr
= 0;
1335 /* Routing table updates. */
1336 rip_rte_process (rte
, from
, ifc
->ifp
);
1340 /* Make socket for RIP protocol. */
1342 rip_create_socket (void)
1346 struct sockaddr_in addr
;
1348 memset (&addr
, 0, sizeof (struct sockaddr_in
));
1349 addr
.sin_family
= AF_INET
;
1350 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1351 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1352 addr
.sin_len
= sizeof (struct sockaddr_in
);
1353 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1354 /* sending port must always be the RIP port */
1355 addr
.sin_port
= htons (RIP_PORT_DEFAULT
);
1357 /* Make datagram socket. */
1358 sock
= socket (AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
1361 zlog_err("Cannot create UDP socket: %s", safe_strerror(errno
));
1365 sockopt_broadcast (sock
);
1366 sockopt_reuseaddr (sock
);
1367 sockopt_reuseport (sock
);
1368 setsockopt_ipv4_multicast_loop (sock
, 0);
1370 setsockopt_pktinfo (sock
);
1371 #endif /* RIP_RECVMSG */
1372 #ifdef IPTOS_PREC_INTERNETCONTROL
1373 setsockopt_ipv4_tos (sock
, IPTOS_PREC_INTERNETCONTROL
);
1376 if (ripd_privs
.change (ZPRIVS_RAISE
))
1377 zlog_err ("rip_create_socket: could not raise privs");
1378 setsockopt_so_recvbuf (sock
, RIP_UDP_RCV_BUF
);
1379 if ( (ret
= bind (sock
, (struct sockaddr
*) & addr
, sizeof (addr
))) < 0)
1382 int save_errno
= errno
;
1383 if (ripd_privs
.change (ZPRIVS_LOWER
))
1384 zlog_err ("rip_create_socket: could not lower privs");
1386 zlog_err("%s: Can't bind socket %d to %s port %d: %s", __func__
,
1387 sock
, inet_ntoa(addr
.sin_addr
),
1388 (int) ntohs(addr
.sin_port
),
1389 safe_strerror(save_errno
));
1395 if (ripd_privs
.change (ZPRIVS_LOWER
))
1396 zlog_err ("rip_create_socket: could not lower privs");
1401 /* RIP packet send to destination address, on interface denoted by
1402 * by connected argument. NULL to argument denotes destination should be
1403 * should be RIP multicast group
1406 rip_send_packet (u_char
* buf
, int size
, struct sockaddr_in
*to
,
1407 struct connected
*ifc
)
1410 struct sockaddr_in sin
;
1412 assert (ifc
!= NULL
);
1414 if (IS_RIP_DEBUG_PACKET
)
1416 #define ADDRESS_SIZE 20
1417 char dst
[ADDRESS_SIZE
];
1418 dst
[ADDRESS_SIZE
- 1] = '\0';
1422 strncpy (dst
, inet_ntoa(to
->sin_addr
), ADDRESS_SIZE
- 1);
1426 sin
.sin_addr
.s_addr
= htonl (INADDR_RIP_GROUP
);
1427 strncpy (dst
, inet_ntoa(sin
.sin_addr
), ADDRESS_SIZE
- 1);
1430 zlog_debug("rip_send_packet %s > %s (%s)",
1431 inet_ntoa(ifc
->address
->u
.prefix4
),
1432 dst
, ifc
->ifp
->name
);
1435 if ( CHECK_FLAG (ifc
->flags
, ZEBRA_IFA_SECONDARY
) )
1438 * ZEBRA_IFA_SECONDARY is set on linux when an interface is configured
1439 * with multiple addresses on the same subnet: the first address
1440 * on the subnet is configured "primary", and all subsequent addresses
1441 * on that subnet are treated as "secondary" addresses.
1442 * In order to avoid routing-table bloat on other rip listeners,
1443 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY source addrs.
1444 * XXX Since Linux is the only system for which the ZEBRA_IFA_SECONDARY
1445 * flag is set, we would end up sending a packet for a "secondary"
1446 * source address on non-linux systems.
1448 if (IS_RIP_DEBUG_PACKET
)
1449 zlog_debug("duplicate dropped");
1453 /* Make destination address. */
1454 memset (&sin
, 0, sizeof (struct sockaddr_in
));
1455 sin
.sin_family
= AF_INET
;
1456 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1457 sin
.sin_len
= sizeof (struct sockaddr_in
);
1458 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1460 /* When destination is specified, use it's port and address. */
1463 sin
.sin_port
= to
->sin_port
;
1464 sin
.sin_addr
= to
->sin_addr
;
1468 sin
.sin_port
= htons (RIP_PORT_DEFAULT
);
1469 sin
.sin_addr
.s_addr
= htonl (INADDR_RIP_GROUP
);
1471 rip_interface_multicast_set (rip
->sock
, ifc
);
1474 ret
= sendto (rip
->sock
, buf
, size
, 0, (struct sockaddr
*)&sin
,
1475 sizeof (struct sockaddr_in
));
1477 if (IS_RIP_DEBUG_EVENT
)
1478 zlog_debug ("SEND to %s.%d", inet_ntoa(sin
.sin_addr
),
1479 ntohs (sin
.sin_port
));
1482 zlog_warn ("can't send packet : %s", safe_strerror (errno
));
1487 /* Add redistributed route to RIP table. */
1489 rip_redistribute_add (int type
, int sub_type
, struct prefix_ipv4
*p
,
1490 ifindex_t ifindex
, struct in_addr
*nexthop
,
1491 unsigned int metric
, unsigned char distance
,
1495 struct route_node
*rp
= NULL
;
1496 struct rip_info
*rinfo
= NULL
, newinfo
;
1497 struct list
*list
= NULL
;
1499 /* Redistribute route */
1500 ret
= rip_destination_check (p
->prefix
);
1504 rp
= route_node_get (rip
->table
, (struct prefix
*) p
);
1506 memset (&newinfo
, 0, sizeof (struct rip_info
));
1507 newinfo
.type
= type
;
1508 newinfo
.sub_type
= sub_type
;
1509 newinfo
.ifindex
= ifindex
;
1511 newinfo
.external_metric
= metric
;
1512 newinfo
.distance
= distance
;
1513 if (tag
<= UINT16_MAX
) /* RIP only supports 16 bit tags */
1517 newinfo
.nexthop
= *nexthop
;
1519 if ((list
= rp
->info
) != NULL
&& listcount (list
) != 0)
1521 rinfo
= listgetdata (listhead (list
));
1523 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
1524 && rinfo
->sub_type
== RIP_ROUTE_INTERFACE
1525 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
1527 route_unlock_node (rp
);
1531 /* Manually configured RIP route check. */
1532 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1533 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
) ||
1534 (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
)) )
1536 if (type
!= ZEBRA_ROUTE_RIP
|| ((sub_type
!= RIP_ROUTE_STATIC
) &&
1537 (sub_type
!= RIP_ROUTE_DEFAULT
)))
1539 route_unlock_node (rp
);
1544 rinfo
= rip_ecmp_replace (&newinfo
);
1545 route_unlock_node (rp
);
1548 rinfo
= rip_ecmp_add (&newinfo
);
1550 if (IS_RIP_DEBUG_EVENT
) {
1552 zlog_debug ("Redistribute new prefix %s/%d on the interface %s",
1553 inet_ntoa(p
->prefix
), p
->prefixlen
,
1554 ifindex2ifname(ifindex
));
1556 zlog_debug ("Redistribute new prefix %s/%d with nexthop %s on the interface %s",
1557 inet_ntoa(p
->prefix
), p
->prefixlen
, inet_ntoa(rinfo
->nexthop
),
1558 ifindex2ifname(ifindex
));
1561 rip_event (RIP_TRIGGERED_UPDATE
, 0);
1564 /* Delete redistributed route from RIP table. */
1566 rip_redistribute_delete (int type
, int sub_type
, struct prefix_ipv4
*p
,
1570 struct route_node
*rp
;
1571 struct rip_info
*rinfo
;
1573 ret
= rip_destination_check (p
->prefix
);
1577 rp
= route_node_lookup (rip
->table
, (struct prefix
*) p
);
1580 struct list
*list
= rp
->info
;
1582 if (list
!= NULL
&& listcount (list
) != 0)
1584 rinfo
= listgetdata (listhead (list
));
1586 && rinfo
->type
== type
1587 && rinfo
->sub_type
== sub_type
1588 && rinfo
->ifindex
== ifindex
)
1590 /* Perform poisoned reverse. */
1591 rinfo
->metric
= RIP_METRIC_INFINITY
;
1592 RIP_TIMER_ON (rinfo
->t_garbage_collect
,
1593 rip_garbage_collect
, rip
->garbage_time
);
1594 RIP_TIMER_OFF (rinfo
->t_timeout
);
1595 rinfo
->flags
|= RIP_RTF_CHANGED
;
1597 if (IS_RIP_DEBUG_EVENT
)
1598 zlog_debug ("Poisone %s/%d on the interface %s with an "
1599 "infinity metric [delete]",
1600 inet_ntoa(p
->prefix
), p
->prefixlen
,
1601 ifindex2ifname(ifindex
));
1603 rip_event (RIP_TRIGGERED_UPDATE
, 0);
1606 route_unlock_node (rp
);
1610 /* Response to request called from rip_read ().*/
1612 rip_request_process (struct rip_packet
*packet
, int size
,
1613 struct sockaddr_in
*from
, struct connected
*ifc
)
1617 struct prefix_ipv4 p
;
1618 struct route_node
*rp
;
1619 struct rip_info
*rinfo
;
1620 struct rip_interface
*ri
;
1622 /* Does not reponse to the requests on the loopback interfaces */
1623 if (if_is_loopback (ifc
->ifp
))
1626 /* Check RIP process is enabled on this interface. */
1627 ri
= ifc
->ifp
->info
;
1631 /* When passive interface is specified, suppress responses */
1635 /* RIP peer update. */
1636 rip_peer_update (from
, packet
->version
);
1638 lim
= ((caddr_t
) packet
) + size
;
1641 /* The Request is processed entry by entry. If there are no
1642 entries, no response is given. */
1643 if (lim
== (caddr_t
) rte
)
1646 /* There is one special case. If there is exactly one entry in the
1647 request, and it has an address family identifier of zero and a
1648 metric of infinity (i.e., 16), then this is a request to send the
1649 entire routing table. */
1650 if (lim
== ((caddr_t
) (rte
+ 1)) &&
1651 ntohs (rte
->family
) == 0 &&
1652 ntohl (rte
->metric
) == RIP_METRIC_INFINITY
)
1654 /* All route with split horizon */
1655 rip_output_process (ifc
, from
, rip_all_route
, packet
->version
);
1659 if (ntohs (rte
->family
) != AF_INET
)
1662 /* Examine the list of RTEs in the Request one by one. For each
1663 entry, look up the destination in the router's routing
1664 database and, if there is a route, put that route's metric in
1665 the metric field of the RTE. If there is no explicit route
1666 to the specified destination, put infinity in the metric
1667 field. Once all the entries have been filled in, change the
1668 command from Request to Response and send the datagram back
1669 to the requestor. */
1672 for (; ((caddr_t
) rte
) < lim
; rte
++)
1674 p
.prefix
= rte
->prefix
;
1675 p
.prefixlen
= ip_masklen (rte
->mask
);
1676 apply_mask_ipv4 (&p
);
1678 rp
= route_node_lookup (rip
->table
, (struct prefix
*) &p
);
1681 rinfo
= listgetdata (listhead ((struct list
*)rp
->info
));
1682 rte
->metric
= htonl (rinfo
->metric
);
1683 route_unlock_node (rp
);
1686 rte
->metric
= htonl (RIP_METRIC_INFINITY
);
1688 packet
->command
= RIP_RESPONSE
;
1690 rip_send_packet ((u_char
*)packet
, size
, from
, ifc
);
1692 rip_global_queries
++;
1696 /* Set IPv6 packet info to the socket. */
1698 setsockopt_pktinfo (int sock
)
1703 ret
= setsockopt(sock
, IPPROTO_IP
, IP_PKTINFO
, &val
, sizeof(val
));
1705 zlog_warn ("Can't setsockopt IP_PKTINFO : %s", safe_strerror (errno
));
1709 /* Read RIP packet by recvmsg function. */
1711 rip_recvmsg (int sock
, u_char
*buf
, int size
, struct sockaddr_in
*from
,
1717 struct cmsghdr
*ptr
;
1720 msg
.msg_name
= (void *) from
;
1721 msg
.msg_namelen
= sizeof (struct sockaddr_in
);
1724 msg
.msg_control
= (void *) adata
;
1725 msg
.msg_controllen
= sizeof adata
;
1729 ret
= recvmsg (sock
, &msg
, 0);
1733 for (ptr
= ZCMSG_FIRSTHDR(&msg
); ptr
!= NULL
; ptr
= CMSG_NXTHDR(&msg
, ptr
))
1734 if (ptr
->cmsg_level
== IPPROTO_IP
&& ptr
->cmsg_type
== IP_PKTINFO
)
1736 struct in_pktinfo
*pktinfo
;
1739 pktinfo
= (struct in_pktinfo
*) CMSG_DATA (ptr
);
1740 i
= pktinfo
->ipi_ifindex
;
1745 /* RIP packet read function. */
1747 rip_read_new (struct thread
*t
)
1751 char buf
[RIP_PACKET_MAXSIZ
];
1752 struct sockaddr_in from
;
1755 /* Fetch socket then register myself. */
1756 sock
= THREAD_FD (t
);
1757 rip_event (RIP_READ
, sock
);
1759 /* Read RIP packet. */
1760 ret
= rip_recvmsg (sock
, buf
, RIP_PACKET_MAXSIZ
, &from
, (int *)&ifindex
);
1763 zlog_warn ("Can't read RIP packet: %s", safe_strerror (errno
));
1769 #endif /* RIP_RECVMSG */
1771 /* First entry point of RIP packet. */
1773 rip_read (struct thread
*t
)
1778 union rip_buf rip_buf
;
1779 struct rip_packet
*packet
;
1780 struct sockaddr_in from
;
1784 struct interface
*ifp
= NULL
;
1785 struct connected
*ifc
;
1786 struct rip_interface
*ri
;
1789 /* Fetch socket then register myself. */
1790 sock
= THREAD_FD (t
);
1793 /* Add myself to tne next event */
1794 rip_event (RIP_READ
, sock
);
1796 /* RIPd manages only IPv4. */
1797 memset (&from
, 0, sizeof (struct sockaddr_in
));
1798 fromlen
= sizeof (struct sockaddr_in
);
1800 len
= recvfrom (sock
, (char *)&rip_buf
.buf
, sizeof (rip_buf
.buf
), 0,
1801 (struct sockaddr
*) &from
, &fromlen
);
1804 zlog_info ("recvfrom failed: %s", safe_strerror (errno
));
1808 /* Check is this packet comming from myself? */
1809 if (if_check_address (from
.sin_addr
))
1811 if (IS_RIP_DEBUG_PACKET
)
1812 zlog_debug ("ignore packet comes from myself");
1816 /* Which interface is this packet comes from. */
1817 ifc
= if_lookup_address ((void *)&from
.sin_addr
, AF_INET
);
1821 /* RIP packet received */
1822 if (IS_RIP_DEBUG_EVENT
)
1823 zlog_debug ("RECV packet from %s port %d on %s",
1824 inet_ntoa (from
.sin_addr
), ntohs (from
.sin_port
),
1825 ifp
? ifp
->name
: "unknown");
1827 /* If this packet come from unknown interface, ignore it. */
1830 zlog_info ("rip_read: cannot find interface for packet from %s port %d",
1831 inet_ntoa(from
.sin_addr
), ntohs (from
.sin_port
));
1836 p
.u
.prefix4
= from
.sin_addr
;
1837 p
.prefixlen
= IPV4_MAX_BITLEN
;
1839 ifc
= connected_lookup_prefix (ifp
, &p
);
1843 zlog_info ("rip_read: cannot find connected address for packet from %s "
1844 "port %d on interface %s",
1845 inet_ntoa(from
.sin_addr
), ntohs (from
.sin_port
), ifp
->name
);
1849 /* Packet length check. */
1850 if (len
< RIP_PACKET_MINSIZ
)
1852 zlog_warn ("packet size %d is smaller than minimum size %d",
1853 len
, RIP_PACKET_MINSIZ
);
1854 rip_peer_bad_packet (&from
);
1857 if (len
> RIP_PACKET_MAXSIZ
)
1859 zlog_warn ("packet size %d is larger than max size %d",
1860 len
, RIP_PACKET_MAXSIZ
);
1861 rip_peer_bad_packet (&from
);
1865 /* Packet alignment check. */
1866 if ((len
- RIP_PACKET_MINSIZ
) % 20)
1868 zlog_warn ("packet size %d is wrong for RIP packet alignment", len
);
1869 rip_peer_bad_packet (&from
);
1873 /* Set RTE number. */
1874 rtenum
= ((len
- RIP_PACKET_MINSIZ
) / 20);
1876 /* For easy to handle. */
1877 packet
= &rip_buf
.rip_packet
;
1879 /* RIP version check. */
1880 if (packet
->version
== 0)
1882 zlog_info ("version 0 with command %d received.", packet
->command
);
1883 rip_peer_bad_packet (&from
);
1887 /* Dump RIP packet. */
1888 if (IS_RIP_DEBUG_RECV
)
1889 rip_packet_dump (packet
, len
, "RECV");
1891 /* RIP version adjust. This code should rethink now. RFC1058 says
1892 that "Version 1 implementations are to ignore this extra data and
1893 process only the fields specified in this document.". So RIPv3
1894 packet should be treated as RIPv1 ignoring must be zero field. */
1895 if (packet
->version
> RIPv2
)
1896 packet
->version
= RIPv2
;
1898 /* Is RIP running or is this RIP neighbor ?*/
1900 if (! ri
->running
&& ! rip_neighbor_lookup (&from
))
1902 if (IS_RIP_DEBUG_EVENT
)
1903 zlog_debug ("RIP is not enabled on interface %s.", ifp
->name
);
1904 rip_peer_bad_packet (&from
);
1908 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1909 vrecv
= ((ri
->ri_receive
== RI_RIP_UNSPEC
) ?
1910 rip
->version_recv
: ri
->ri_receive
);
1911 if (vrecv
== RI_RIP_VERSION_NONE
||
1912 ((packet
->version
== RIPv1
) && !(vrecv
& RIPv1
)) ||
1913 ((packet
->version
== RIPv2
) && !(vrecv
& RIPv2
)))
1915 if (IS_RIP_DEBUG_PACKET
)
1916 zlog_debug (" packet's v%d doesn't fit to if version spec",
1918 rip_peer_bad_packet (&from
);
1922 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1923 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1924 accepted; authenticated RIP-2 messages shall be discarded. */
1925 if ((ri
->auth_type
== RIP_NO_AUTH
)
1927 && (packet
->version
== RIPv2
)
1928 && (packet
->rte
->family
== htons(RIP_FAMILY_AUTH
)))
1930 if (IS_RIP_DEBUG_EVENT
)
1931 zlog_debug ("packet RIPv%d is dropped because authentication disabled",
1933 rip_peer_bad_packet (&from
);
1938 If the router is configured to authenticate RIP-2 messages, then
1939 RIP-1 messages and RIP-2 messages which pass authentication
1940 testing shall be accepted; unauthenticated and failed
1941 authentication RIP-2 messages shall be discarded. For maximum
1942 security, RIP-1 messages should be ignored when authentication is
1943 in use (see section 4.1); otherwise, the routing information from
1944 authenticated messages will be propagated by RIP-1 routers in an
1945 unauthenticated manner.
1947 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1948 * always reply regardless of authentication settings, because:
1950 * - if there other authorised routers on-link, the REQUESTor can
1951 * passively obtain the routing updates anyway
1952 * - if there are no other authorised routers on-link, RIP can
1953 * easily be disabled for the link to prevent giving out information
1954 * on state of this routers RIP routing table..
1956 * I.e. if RIPv1 has any place anymore these days, it's as a very
1957 * simple way to distribute routing information (e.g. to embedded
1958 * hosts / appliances) and the ability to give out RIPv1
1959 * routing-information freely, while still requiring RIPv2
1960 * authentication for any RESPONSEs might be vaguely useful.
1962 if (ri
->auth_type
!= RIP_NO_AUTH
1963 && packet
->version
== RIPv1
)
1965 /* Discard RIPv1 messages other than REQUESTs */
1966 if (packet
->command
!= RIP_REQUEST
)
1968 if (IS_RIP_DEBUG_PACKET
)
1969 zlog_debug ("RIPv1" " dropped because authentication enabled");
1970 rip_peer_bad_packet (&from
);
1974 else if (ri
->auth_type
!= RIP_NO_AUTH
)
1976 const char *auth_desc
;
1980 /* There definitely is no authentication in the packet. */
1981 if (IS_RIP_DEBUG_PACKET
)
1982 zlog_debug ("RIPv2 authentication failed: no auth RTE in packet");
1983 rip_peer_bad_packet (&from
);
1987 /* First RTE must be an Authentication Family RTE */
1988 if (packet
->rte
->family
!= htons(RIP_FAMILY_AUTH
))
1990 if (IS_RIP_DEBUG_PACKET
)
1991 zlog_debug ("RIPv2" " dropped because authentication enabled");
1992 rip_peer_bad_packet (&from
);
1996 /* Check RIPv2 authentication. */
1997 switch (ntohs(packet
->rte
->tag
))
1999 case RIP_AUTH_SIMPLE_PASSWORD
:
2000 auth_desc
= "simple";
2001 ret
= rip_auth_simple_password (packet
->rte
, &from
, ifp
);
2006 ret
= rip_auth_md5 (packet
, &from
, len
, ifp
);
2007 /* Reset RIP packet length to trim MD5 data. */
2013 auth_desc
= "unknown type";
2014 if (IS_RIP_DEBUG_PACKET
)
2015 zlog_debug ("RIPv2 Unknown authentication type %d",
2016 ntohs (packet
->rte
->tag
));
2021 if (IS_RIP_DEBUG_PACKET
)
2022 zlog_debug ("RIPv2 %s authentication success", auth_desc
);
2026 if (IS_RIP_DEBUG_PACKET
)
2027 zlog_debug ("RIPv2 %s authentication failure", auth_desc
);
2028 rip_peer_bad_packet (&from
);
2033 /* Process each command. */
2034 switch (packet
->command
)
2037 rip_response_process (packet
, len
, &from
, ifc
);
2041 rip_request_process (packet
, len
, &from
, ifc
);
2045 zlog_info ("Obsolete command %s received, please sent it to routed",
2046 lookup (rip_msg
, packet
->command
));
2047 rip_peer_bad_packet (&from
);
2049 case RIP_POLL_ENTRY
:
2050 zlog_info ("Obsolete command %s received",
2051 lookup (rip_msg
, packet
->command
));
2052 rip_peer_bad_packet (&from
);
2055 zlog_info ("Unknown RIP command %d received", packet
->command
);
2056 rip_peer_bad_packet (&from
);
2063 /* Write routing table entry to the stream and return next index of
2064 the routing table entry in the stream. */
2066 rip_write_rte (int num
, struct stream
*s
, struct prefix_ipv4
*p
,
2067 u_char version
, struct rip_info
*rinfo
)
2069 struct in_addr mask
;
2071 /* Write routing table entry. */
2072 if (version
== RIPv1
)
2074 stream_putw (s
, AF_INET
);
2076 stream_put_ipv4 (s
, p
->prefix
.s_addr
);
2077 stream_put_ipv4 (s
, 0);
2078 stream_put_ipv4 (s
, 0);
2079 stream_putl (s
, rinfo
->metric_out
);
2083 masklen2ip (p
->prefixlen
, &mask
);
2085 stream_putw (s
, AF_INET
);
2086 stream_putw (s
, rinfo
->tag_out
);
2087 stream_put_ipv4 (s
, p
->prefix
.s_addr
);
2088 stream_put_ipv4 (s
, mask
.s_addr
);
2089 stream_put_ipv4 (s
, rinfo
->nexthop_out
.s_addr
);
2090 stream_putl (s
, rinfo
->metric_out
);
2096 /* Send update to the ifp or spcified neighbor. */
2098 rip_output_process (struct connected
*ifc
, struct sockaddr_in
*to
,
2099 int route_type
, u_char version
)
2103 struct route_node
*rp
;
2104 struct rip_info
*rinfo
;
2105 struct rip_interface
*ri
;
2106 struct prefix_ipv4
*p
;
2107 struct prefix_ipv4 classfull
;
2108 struct prefix_ipv4 ifaddrclass
;
2109 struct key
*key
= NULL
;
2110 /* this might need to made dynamic if RIP ever supported auth methods
2111 with larger key string sizes */
2112 char auth_str
[RIP_AUTH_SIMPLE_SIZE
];
2113 size_t doff
= 0; /* offset of digest offset field */
2117 struct list
*list
= NULL
;
2118 struct listnode
*listnode
= NULL
;
2120 /* Logging output event. */
2121 if (IS_RIP_DEBUG_EVENT
)
2124 zlog_debug ("update routes to neighbor %s", inet_ntoa (to
->sin_addr
));
2126 zlog_debug ("update routes on interface %s ifindex %d",
2127 ifc
->ifp
->name
, ifc
->ifp
->ifindex
);
2130 /* Set output stream. */
2133 /* Reset stream and RTE counter. */
2135 rtemax
= RIP_MAX_RTE
;
2137 /* Get RIP interface. */
2138 ri
= ifc
->ifp
->info
;
2140 /* If output interface is in simple password authentication mode, we
2141 need space for authentication data. */
2142 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2145 /* If output interface is in MD5 authentication mode, we need space
2146 for authentication header and data. */
2147 if (ri
->auth_type
== RIP_AUTH_MD5
)
2150 /* If output interface is in simple password authentication mode
2151 and string or keychain is specified we need space for auth. data */
2152 if (ri
->auth_type
!= RIP_NO_AUTH
)
2156 struct keychain
*keychain
;
2158 keychain
= keychain_lookup (ri
->key_chain
);
2160 key
= key_lookup_for_send (keychain
);
2162 /* to be passed to auth functions later */
2163 rip_auth_prepare_str_send (ri
, key
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
2166 if (version
== RIPv1
)
2168 memcpy (&ifaddrclass
, ifc
->address
, sizeof (struct prefix_ipv4
));
2169 apply_classful_mask_ipv4 (&ifaddrclass
);
2171 if (ifc
->address
->prefixlen
> ifaddrclass
.prefixlen
)
2175 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
2176 if ((list
= rp
->info
) != NULL
&& listcount (list
) != 0)
2178 rinfo
= listgetdata (listhead (list
));
2179 /* For RIPv1, if we are subnetted, output subnets in our network */
2180 /* that have the same mask as the output "interface". For other */
2181 /* networks, only the classfull version is output. */
2183 if (version
== RIPv1
)
2185 p
= (struct prefix_ipv4
*) &rp
->p
;
2187 if (IS_RIP_DEBUG_PACKET
)
2188 zlog_debug("RIPv1 mask check, %s/%d considered for output",
2189 inet_ntoa (rp
->p
.u
.prefix4
), rp
->p
.prefixlen
);
2192 prefix_match ((struct prefix
*) &ifaddrclass
, &rp
->p
))
2194 if ((ifc
->address
->prefixlen
!= rp
->p
.prefixlen
) &&
2195 (rp
->p
.prefixlen
!= 32))
2200 memcpy (&classfull
, &rp
->p
, sizeof(struct prefix_ipv4
));
2201 apply_classful_mask_ipv4(&classfull
);
2202 if (rp
->p
.u
.prefix4
.s_addr
!= 0 &&
2203 classfull
.prefixlen
!= rp
->p
.prefixlen
)
2206 if (IS_RIP_DEBUG_PACKET
)
2207 zlog_debug("RIPv1 mask check, %s/%d made it through",
2208 inet_ntoa (rp
->p
.u
.prefix4
), rp
->p
.prefixlen
);
2211 p
= (struct prefix_ipv4
*) &rp
->p
;
2213 /* Apply output filters. */
2214 ret
= rip_filter (RIP_FILTER_OUT
, p
, ri
);
2218 /* Changed route only output. */
2219 if (route_type
== rip_changed_route
&&
2220 (! (rinfo
->flags
& RIP_RTF_CHANGED
)))
2223 /* Split horizon. */
2224 /* if (split_horizon == rip_split_horizon) */
2225 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
)
2228 * We perform split horizon for RIP and connected route.
2229 * For rip routes, we want to suppress the route if we would
2230 * end up sending the route back on the interface that we
2231 * learned it from, with a higher metric. For connected routes,
2232 * we suppress the route if the prefix is a subset of the
2233 * source address that we are going to use for the packet
2234 * (in order to handle the case when multiple subnets are
2235 * configured on the same interface).
2238 struct rip_info
*tmp_rinfo
= NULL
;
2240 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, tmp_rinfo
))
2241 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
&&
2242 tmp_rinfo
->ifindex
== ifc
->ifp
->ifindex
)
2248 if (!suppress
&& rinfo
->type
== ZEBRA_ROUTE_CONNECT
&&
2249 prefix_match((struct prefix
*)p
, ifc
->address
))
2256 /* Preparation for route-map. */
2257 rinfo
->metric_set
= 0;
2258 rinfo
->nexthop_out
.s_addr
= 0;
2259 rinfo
->metric_out
= rinfo
->metric
;
2260 rinfo
->tag_out
= rinfo
->tag
;
2261 rinfo
->ifindex_out
= ifc
->ifp
->ifindex
;
2263 /* In order to avoid some local loops,
2264 * if the RIP route has a nexthop via this interface, keep the nexthop,
2265 * otherwise set it to 0. The nexthop should not be propagated
2266 * beyond the local broadcast/multicast area in order
2267 * to avoid an IGP multi-level recursive look-up.
2270 if (rinfo
->ifindex
== ifc
->ifp
->ifindex
)
2271 rinfo
->nexthop_out
= rinfo
->nexthop
;
2273 /* Interface route-map */
2274 if (ri
->routemap
[RIP_FILTER_OUT
])
2276 ret
= route_map_apply (ri
->routemap
[RIP_FILTER_OUT
],
2277 (struct prefix
*) p
, RMAP_RIP
,
2280 if (ret
== RMAP_DENYMATCH
)
2282 if (IS_RIP_DEBUG_PACKET
)
2283 zlog_debug ("RIP %s/%d is filtered by route-map out",
2284 inet_ntoa (p
->prefix
), p
->prefixlen
);
2289 /* Apply redistribute route map - continue, if deny */
2290 if (rip
->route_map
[rinfo
->type
].name
2291 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
)
2293 ret
= route_map_apply (rip
->route_map
[rinfo
->type
].map
,
2294 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2296 if (ret
== RMAP_DENYMATCH
)
2298 if (IS_RIP_DEBUG_PACKET
)
2299 zlog_debug ("%s/%d is filtered by route-map",
2300 inet_ntoa (p
->prefix
), p
->prefixlen
);
2305 /* When route-map does not set metric. */
2306 if (! rinfo
->metric_set
)
2308 /* If redistribute metric is set. */
2309 if (rip
->route_map
[rinfo
->type
].metric_config
2310 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
2312 rinfo
->metric_out
= rip
->route_map
[rinfo
->type
].metric
;
2316 /* If the route is not connected or localy generated
2317 one, use default-metric value*/
2318 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2319 && rinfo
->type
!= ZEBRA_ROUTE_CONNECT
2320 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
2321 rinfo
->metric_out
= rip
->default_metric
;
2325 /* Apply offset-list */
2326 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2327 rip_offset_list_apply_out (p
, ifc
->ifp
, &rinfo
->metric_out
);
2329 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2330 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2332 /* Perform split-horizon with poisoned reverse
2333 * for RIP and connected routes.
2335 if (ri
->split_horizon
== RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2337 * We perform split horizon for RIP and connected route.
2338 * For rip routes, we want to suppress the route if we would
2339 * end up sending the route back on the interface that we
2340 * learned it from, with a higher metric. For connected routes,
2341 * we suppress the route if the prefix is a subset of the
2342 * source address that we are going to use for the packet
2343 * (in order to handle the case when multiple subnets are
2344 * configured on the same interface).
2346 struct rip_info
*tmp_rinfo
= NULL
;
2348 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, tmp_rinfo
))
2349 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
&&
2350 tmp_rinfo
->ifindex
== ifc
->ifp
->ifindex
)
2351 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2352 if (tmp_rinfo
->type
== ZEBRA_ROUTE_CONNECT
&&
2353 prefix_match((struct prefix
*)p
, ifc
->address
))
2354 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2357 /* Prepare preamble, auth headers, if needs be */
2360 stream_putc (s
, RIP_RESPONSE
);
2361 stream_putc (s
, version
);
2364 /* auth header for !v1 && !no_auth */
2365 if ( (ri
->auth_type
!= RIP_NO_AUTH
) && (version
!= RIPv1
) )
2366 doff
= rip_auth_header_write (s
, ri
, key
, auth_str
,
2367 RIP_AUTH_SIMPLE_SIZE
);
2370 /* Write RTE to the stream. */
2371 num
= rip_write_rte (num
, s
, p
, version
, rinfo
);
2374 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2375 rip_auth_md5_set (s
, ri
, doff
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
2377 ret
= rip_send_packet (STREAM_DATA (s
), stream_get_endp (s
),
2380 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2381 rip_packet_dump ((struct rip_packet
*)STREAM_DATA (s
),
2382 stream_get_endp(s
), "SEND");
2388 /* Flush unwritten RTE. */
2391 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2392 rip_auth_md5_set (s
, ri
, doff
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
2394 ret
= rip_send_packet (STREAM_DATA (s
), stream_get_endp (s
), to
, ifc
);
2396 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2397 rip_packet_dump ((struct rip_packet
*)STREAM_DATA (s
),
2398 stream_get_endp (s
), "SEND");
2403 /* Statistics updates. */
2407 /* Send RIP packet to the interface. */
2409 rip_update_interface (struct connected
*ifc
, u_char version
, int route_type
)
2411 struct interface
*ifp
= ifc
->ifp
;
2412 struct rip_interface
*ri
= ifp
->info
;
2413 struct sockaddr_in to
;
2415 /* When RIP version is 2 and multicast enable interface. */
2416 if (version
== RIPv2
&& !ri
->v2_broadcast
&& if_is_multicast (ifp
))
2418 if (IS_RIP_DEBUG_EVENT
)
2419 zlog_debug ("multicast announce on %s ", ifp
->name
);
2421 rip_output_process (ifc
, NULL
, route_type
, version
);
2425 /* If we can't send multicast packet, send it with unicast. */
2426 if (if_is_broadcast (ifp
) || if_is_pointopoint (ifp
))
2428 if (ifc
->address
->family
== AF_INET
)
2430 /* Destination address and port setting. */
2431 memset (&to
, 0, sizeof (struct sockaddr_in
));
2432 if (ifc
->destination
)
2433 /* use specified broadcast or peer destination addr */
2434 to
.sin_addr
= ifc
->destination
->u
.prefix4
;
2435 else if (ifc
->address
->prefixlen
< IPV4_MAX_PREFIXLEN
)
2436 /* calculate the appropriate broadcast address */
2437 to
.sin_addr
.s_addr
=
2438 ipv4_broadcast_addr(ifc
->address
->u
.prefix4
.s_addr
,
2439 ifc
->address
->prefixlen
);
2441 /* do not know where to send the packet */
2443 to
.sin_port
= htons (RIP_PORT_DEFAULT
);
2445 if (IS_RIP_DEBUG_EVENT
)
2446 zlog_debug("%s announce to %s on %s",
2447 CONNECTED_PEER(ifc
) ? "unicast" : "broadcast",
2448 inet_ntoa (to
.sin_addr
), ifp
->name
);
2450 rip_output_process (ifc
, &to
, route_type
, version
);
2455 /* Update send to all interface and neighbor. */
2457 rip_update_process (int route_type
)
2459 struct listnode
*node
;
2460 struct listnode
*ifnode
, *ifnnode
;
2461 struct connected
*connected
;
2462 struct interface
*ifp
;
2463 struct rip_interface
*ri
;
2464 struct route_node
*rp
;
2465 struct sockaddr_in to
;
2468 /* Send RIP update to each interface. */
2469 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
))
2471 if (if_is_loopback (ifp
))
2474 if (! if_is_operative (ifp
))
2477 /* Fetch RIP interface information. */
2480 /* When passive interface is specified, suppress announce to the
2488 * If there is no version configuration in the interface,
2489 * use rip's version setting.
2491 int vsend
= ((ri
->ri_send
== RI_RIP_UNSPEC
) ?
2492 rip
->version_send
: ri
->ri_send
);
2494 if (IS_RIP_DEBUG_EVENT
)
2495 zlog_debug("SEND UPDATE to %s ifindex %d",
2496 ifp
->name
, ifp
->ifindex
);
2498 /* send update on each connected network */
2499 for (ALL_LIST_ELEMENTS (ifp
->connected
, ifnode
, ifnnode
, connected
))
2501 if (connected
->address
->family
== AF_INET
)
2504 rip_update_interface (connected
, RIPv1
, route_type
);
2505 if ((vsend
& RIPv2
) && if_is_multicast(ifp
))
2506 rip_update_interface (connected
, RIPv2
, route_type
);
2512 /* RIP send updates to each neighbor. */
2513 for (rp
= route_top (rip
->neighbor
); rp
; rp
= route_next (rp
))
2514 if (rp
->info
!= NULL
)
2518 connected
= if_lookup_address (&p
->u
.prefix4
, AF_INET
);
2521 zlog_warn ("Neighbor %s doesnt have connected interface!",
2522 inet_ntoa (p
->u
.prefix4
));
2526 /* Set destination address and port */
2527 memset (&to
, 0, sizeof (struct sockaddr_in
));
2528 to
.sin_addr
= p
->u
.prefix4
;
2529 to
.sin_port
= htons (RIP_PORT_DEFAULT
);
2531 /* RIP version is rip's configuration. */
2532 rip_output_process (connected
, &to
, route_type
, rip
->version_send
);
2536 /* RIP's periodical timer. */
2538 rip_update (struct thread
*t
)
2540 /* Clear timer pointer. */
2541 rip
->t_update
= NULL
;
2543 if (IS_RIP_DEBUG_EVENT
)
2544 zlog_debug ("update timer fire!");
2546 /* Process update output. */
2547 rip_update_process (rip_all_route
);
2549 /* Triggered updates may be suppressed if a regular update is due by
2550 the time the triggered update would be sent. */
2551 RIP_TIMER_OFF (rip
->t_triggered_interval
);
2554 /* Register myself. */
2555 rip_event (RIP_UPDATE_EVENT
, 0);
2560 /* Walk down the RIP routing table then clear changed flag. */
2562 rip_clear_changed_flag (void)
2564 struct route_node
*rp
;
2565 struct rip_info
*rinfo
= NULL
;
2566 struct list
*list
= NULL
;
2567 struct listnode
*listnode
= NULL
;
2569 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
2570 if ((list
= rp
->info
) != NULL
)
2571 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
2573 UNSET_FLAG (rinfo
->flags
, RIP_RTF_CHANGED
);
2574 /* This flag can be set only on the first entry. */
2579 /* Triggered update interval timer. */
2581 rip_triggered_interval (struct thread
*t
)
2583 int rip_triggered_update (struct thread
*);
2585 rip
->t_triggered_interval
= NULL
;
2590 rip_triggered_update (t
);
2595 /* Execute triggered update. */
2597 rip_triggered_update (struct thread
*t
)
2601 /* Clear thred pointer. */
2602 rip
->t_triggered_update
= NULL
;
2604 /* Cancel interval timer. */
2605 RIP_TIMER_OFF (rip
->t_triggered_interval
);
2608 /* Logging triggered update. */
2609 if (IS_RIP_DEBUG_EVENT
)
2610 zlog_debug ("triggered update!");
2612 /* Split Horizon processing is done when generating triggered
2613 updates as well as normal updates (see section 2.6). */
2614 rip_update_process (rip_changed_route
);
2616 /* Once all of the triggered updates have been generated, the route
2617 change flags should be cleared. */
2618 rip_clear_changed_flag ();
2620 /* After a triggered update is sent, a timer should be set for a
2621 random interval between 1 and 5 seconds. If other changes that
2622 would trigger updates occur before the timer expires, a single
2623 update is triggered when the timer expires. */
2624 interval
= (random () % 5) + 1;
2626 rip
->t_triggered_interval
=
2627 thread_add_timer (master
, rip_triggered_interval
, NULL
, interval
);
2632 /* Withdraw redistributed route. */
2634 rip_redistribute_withdraw (int type
)
2636 struct route_node
*rp
;
2637 struct rip_info
*rinfo
= NULL
;
2638 struct list
*list
= NULL
;
2643 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
2644 if ((list
= rp
->info
) != NULL
)
2646 rinfo
= listgetdata (listhead (list
));
2647 if (rinfo
->type
== type
2648 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
)
2650 /* Perform poisoned reverse. */
2651 rinfo
->metric
= RIP_METRIC_INFINITY
;
2652 RIP_TIMER_ON (rinfo
->t_garbage_collect
,
2653 rip_garbage_collect
, rip
->garbage_time
);
2654 RIP_TIMER_OFF (rinfo
->t_timeout
);
2655 rinfo
->flags
|= RIP_RTF_CHANGED
;
2657 if (IS_RIP_DEBUG_EVENT
) {
2658 struct prefix_ipv4
*p
= (struct prefix_ipv4
*) &rp
->p
;
2660 zlog_debug ("Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2661 inet_ntoa(p
->prefix
), p
->prefixlen
,
2662 ifindex2ifname(rinfo
->ifindex
));
2665 rip_event (RIP_TRIGGERED_UPDATE
, 0);
2670 /* Create new RIP instance and set it to global variable. */
2674 rip
= XCALLOC (MTYPE_RIP
, sizeof (struct rip
));
2676 /* Set initial value. */
2677 rip
->version_send
= RI_RIP_VERSION_2
;
2678 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2679 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
2680 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
2681 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
2682 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2684 /* Initialize RIP routig table. */
2685 rip
->table
= route_table_init ();
2686 rip
->route
= route_table_init ();
2687 rip
->neighbor
= route_table_init ();
2689 /* Make output stream. */
2690 rip
->obuf
= stream_new (1500);
2693 rip
->sock
= rip_create_socket ();
2697 /* Create read and timer thread. */
2698 rip_event (RIP_READ
, rip
->sock
);
2699 rip_event (RIP_UPDATE_EVENT
, 1);
2704 /* Sned RIP request to the destination. */
2706 rip_request_send (struct sockaddr_in
*to
, struct interface
*ifp
,
2707 u_char version
, struct connected
*connected
)
2710 struct rip_packet rip_packet
;
2711 struct listnode
*node
, *nnode
;
2713 memset (&rip_packet
, 0, sizeof (rip_packet
));
2715 rip_packet
.command
= RIP_REQUEST
;
2716 rip_packet
.version
= version
;
2717 rte
= rip_packet
.rte
;
2718 rte
->metric
= htonl (RIP_METRIC_INFINITY
);
2723 * connected is only sent for ripv1 case, or when
2724 * interface does not support multicast. Caller loops
2725 * over each connected address for this case.
2727 if (rip_send_packet ((u_char
*) &rip_packet
, sizeof (rip_packet
),
2728 to
, connected
) != sizeof (rip_packet
))
2731 return sizeof (rip_packet
);
2734 /* send request on each connected network */
2735 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, connected
))
2737 struct prefix_ipv4
*p
;
2739 p
= (struct prefix_ipv4
*) connected
->address
;
2741 if (p
->family
!= AF_INET
)
2744 if (rip_send_packet ((u_char
*) &rip_packet
, sizeof (rip_packet
),
2745 to
, connected
) != sizeof (rip_packet
))
2748 return sizeof (rip_packet
);
2752 rip_update_jitter (unsigned long time
)
2754 #define JITTER_BOUND 4
2755 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2756 Given that, we cannot let time be less than JITTER_BOUND seconds.
2757 The RIPv2 RFC says jitter should be small compared to
2758 update_time. We consider 1/JITTER_BOUND to be small.
2761 int jitter_input
= time
;
2764 if (jitter_input
< JITTER_BOUND
)
2765 jitter_input
= JITTER_BOUND
;
2767 jitter
= (((random () % ((jitter_input
* 2) + 1)) - jitter_input
));
2769 return jitter
/JITTER_BOUND
;
2773 rip_event (enum rip_event event
, int sock
)
2780 rip
->t_read
= thread_add_read (master
, rip_read
, NULL
, sock
);
2782 case RIP_UPDATE_EVENT
:
2783 RIP_TIMER_OFF (rip
->t_update
);
2784 jitter
= rip_update_jitter (rip
->update_time
);
2786 thread_add_timer (master
, rip_update
, NULL
,
2787 sock
? 2 : rip
->update_time
+ jitter
);
2789 case RIP_TRIGGERED_UPDATE
:
2790 if (rip
->t_triggered_interval
)
2792 else if (! rip
->t_triggered_update
)
2793 rip
->t_triggered_update
=
2794 thread_add_event (master
, rip_triggered_update
, NULL
, 0);
2804 "Enable a routing process\n"
2805 "Routing Information Protocol (RIP)\n")
2809 /* If rip is not enabled before. */
2812 ret
= rip_create ();
2815 zlog_info ("Can't create RIP");
2819 vty
->node
= RIP_NODE
;
2825 DEFUN (no_router_rip
,
2829 "Enable a routing process\n"
2830 "Routing Information Protocol (RIP)\n")
2840 "Set routing protocol version\n"
2846 version
= atoi (argv
[idx_number
]->arg
);
2847 if (version
!= RIPv1
&& version
!= RIPv2
)
2849 vty_out (vty
, "invalid rip version %d%s", version
,
2853 rip
->version_send
= version
;
2854 rip
->version_recv
= version
;
2859 DEFUN (no_rip_version
,
2861 "no version [(1-2)]",
2863 "Set routing protocol version\n"
2866 /* Set RIP version to the default. */
2867 rip
->version_send
= RI_RIP_VERSION_2
;
2868 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2877 "RIP static route configuration\n"
2878 "IP prefix <network>/<length>\n")
2880 int idx_ipv4_prefixlen
= 1;
2882 struct prefix_ipv4 p
;
2883 struct route_node
*node
;
2885 ret
= str2prefix_ipv4 (argv
[idx_ipv4_prefixlen
]->arg
, &p
);
2888 vty_out (vty
, "Malformed address%s", VTY_NEWLINE
);
2891 apply_mask_ipv4 (&p
);
2893 /* For router rip configuration. */
2894 node
= route_node_get (rip
->route
, (struct prefix
*) &p
);
2898 vty_out (vty
, "There is already same static route.%s", VTY_NEWLINE
);
2899 route_unlock_node (node
);
2903 node
->info
= (void *)1;
2905 rip_redistribute_add (ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0, NULL
, 0, 0, 0);
2910 DEFUN (no_rip_route
,
2912 "no route A.B.C.D/M",
2914 "RIP static route configuration\n"
2915 "IP prefix <network>/<length>\n")
2917 int idx_ipv4_prefixlen
= 2;
2919 struct prefix_ipv4 p
;
2920 struct route_node
*node
;
2922 ret
= str2prefix_ipv4 (argv
[idx_ipv4_prefixlen
]->arg
, &p
);
2925 vty_out (vty
, "Malformed address%s", VTY_NEWLINE
);
2928 apply_mask_ipv4 (&p
);
2930 /* For router rip configuration. */
2931 node
= route_node_lookup (rip
->route
, (struct prefix
*) &p
);
2934 vty_out (vty
, "Can't find route %s.%s", argv
[idx_ipv4_prefixlen
]->arg
,
2939 rip_redistribute_delete (ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0);
2940 route_unlock_node (node
);
2943 route_unlock_node (node
);
2950 rip_update_default_metric (void)
2952 struct route_node
*np
;
2953 struct rip_info
*rinfo
= NULL
;
2954 struct list
*list
= NULL
;
2955 struct listnode
*listnode
= NULL
;
2957 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
2958 if ((list
= np
->info
) != NULL
)
2959 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
2960 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
2961 rinfo
->metric
= rip
->default_metric
;
2965 DEFUN (rip_default_metric
,
2966 rip_default_metric_cmd
,
2967 "default-metric (1-16)",
2968 "Set a metric of redistribute routes\n"
2974 rip
->default_metric
= atoi (argv
[idx_number
]->arg
);
2975 /* rip_update_default_metric (); */
2980 DEFUN (no_rip_default_metric
,
2981 no_rip_default_metric_cmd
,
2982 "no default-metric [(1-16)]",
2984 "Set a metric of redistribute routes\n"
2989 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2990 /* rip_update_default_metric (); */
2998 "timers basic (5-2147483647) (5-2147483647) (5-2147483647)",
2999 "Adjust routing timers\n"
3000 "Basic routing protocol update timers\n"
3001 "Routing table update timer value in second. Default is 30.\n"
3002 "Routing information timeout timer. Default is 180.\n"
3003 "Garbage collection timer. Default is 120.\n")
3006 int idx_number_2
= 3;
3007 int idx_number_3
= 4;
3008 unsigned long update
;
3009 unsigned long timeout
;
3010 unsigned long garbage
;
3011 char *endptr
= NULL
;
3012 unsigned long RIP_TIMER_MAX
= 2147483647;
3013 unsigned long RIP_TIMER_MIN
= 5;
3015 update
= strtoul (argv
[idx_number
]->arg
, &endptr
, 10);
3016 if (update
> RIP_TIMER_MAX
|| update
< RIP_TIMER_MIN
|| *endptr
!= '\0')
3018 vty_out (vty
, "update timer value error%s", VTY_NEWLINE
);
3022 timeout
= strtoul (argv
[idx_number_2
]->arg
, &endptr
, 10);
3023 if (timeout
> RIP_TIMER_MAX
|| timeout
< RIP_TIMER_MIN
|| *endptr
!= '\0')
3025 vty_out (vty
, "timeout timer value error%s", VTY_NEWLINE
);
3029 garbage
= strtoul (argv
[idx_number_3
]->arg
, &endptr
, 10);
3030 if (garbage
> RIP_TIMER_MAX
|| garbage
< RIP_TIMER_MIN
|| *endptr
!= '\0')
3032 vty_out (vty
, "garbage timer value error%s", VTY_NEWLINE
);
3036 /* Set each timer value. */
3037 rip
->update_time
= update
;
3038 rip
->timeout_time
= timeout
;
3039 rip
->garbage_time
= garbage
;
3041 /* Reset update timer thread. */
3042 rip_event (RIP_UPDATE_EVENT
, 0);
3047 DEFUN (no_rip_timers
,
3049 "no timers basic [(0-65535) (0-65535) (0-65535)]",
3051 "Adjust routing timers\n"
3052 "Basic routing protocol update timers\n"
3053 "Routing table update timer value in second. Default is 30.\n"
3054 "Routing information timeout timer. Default is 180.\n"
3055 "Garbage collection timer. Default is 120.\n")
3057 /* Set each timer value to the default. */
3058 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
3059 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
3060 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
3062 /* Reset update timer thread. */
3063 rip_event (RIP_UPDATE_EVENT
, 0);
3070 struct route_table
*rip_distance_table
;
3074 /* Distance value for the IP source prefix. */
3077 /* Name of the access-list to be matched. */
3081 static struct rip_distance
*
3082 rip_distance_new (void)
3084 return XCALLOC (MTYPE_RIP_DISTANCE
, sizeof (struct rip_distance
));
3088 rip_distance_free (struct rip_distance
*rdistance
)
3090 XFREE (MTYPE_RIP_DISTANCE
, rdistance
);
3094 rip_distance_set (struct vty
*vty
, const char *distance_str
, const char *ip_str
,
3095 const char *access_list_str
)
3098 struct prefix_ipv4 p
;
3100 struct route_node
*rn
;
3101 struct rip_distance
*rdistance
;
3103 ret
= str2prefix_ipv4 (ip_str
, &p
);
3106 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
3110 distance
= atoi (distance_str
);
3112 /* Get RIP distance node. */
3113 rn
= route_node_get (rip_distance_table
, (struct prefix
*) &p
);
3116 rdistance
= rn
->info
;
3117 route_unlock_node (rn
);
3121 rdistance
= rip_distance_new ();
3122 rn
->info
= rdistance
;
3125 /* Set distance value. */
3126 rdistance
->distance
= distance
;
3128 /* Reset access-list configuration. */
3129 if (rdistance
->access_list
)
3131 free (rdistance
->access_list
);
3132 rdistance
->access_list
= NULL
;
3134 if (access_list_str
)
3135 rdistance
->access_list
= strdup (access_list_str
);
3141 rip_distance_unset (struct vty
*vty
, const char *distance_str
,
3142 const char *ip_str
, const char *access_list_str
)
3145 struct prefix_ipv4 p
;
3146 struct route_node
*rn
;
3147 struct rip_distance
*rdistance
;
3149 ret
= str2prefix_ipv4 (ip_str
, &p
);
3152 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
3156 rn
= route_node_lookup (rip_distance_table
, (struct prefix
*)&p
);
3159 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
3163 rdistance
= rn
->info
;
3165 if (rdistance
->access_list
)
3166 free (rdistance
->access_list
);
3167 rip_distance_free (rdistance
);
3170 route_unlock_node (rn
);
3171 route_unlock_node (rn
);
3177 rip_distance_reset (void)
3179 struct route_node
*rn
;
3180 struct rip_distance
*rdistance
;
3182 for (rn
= route_top (rip_distance_table
); rn
; rn
= route_next (rn
))
3183 if ((rdistance
= rn
->info
) != NULL
)
3185 if (rdistance
->access_list
)
3186 free (rdistance
->access_list
);
3187 rip_distance_free (rdistance
);
3189 route_unlock_node (rn
);
3193 /* Apply RIP information to distance method. */
3195 rip_distance_apply (struct rip_info
*rinfo
)
3197 struct route_node
*rn
;
3198 struct prefix_ipv4 p
;
3199 struct rip_distance
*rdistance
;
3200 struct access_list
*alist
;
3205 memset (&p
, 0, sizeof (struct prefix_ipv4
));
3207 p
.prefix
= rinfo
->from
;
3208 p
.prefixlen
= IPV4_MAX_BITLEN
;
3210 /* Check source address. */
3211 rn
= route_node_match (rip_distance_table
, (struct prefix
*) &p
);
3214 rdistance
= rn
->info
;
3215 route_unlock_node (rn
);
3217 if (rdistance
->access_list
)
3219 alist
= access_list_lookup (AFI_IP
, rdistance
->access_list
);
3222 if (access_list_apply (alist
, &rinfo
->rp
->p
) == FILTER_DENY
)
3225 return rdistance
->distance
;
3228 return rdistance
->distance
;
3232 return rip
->distance
;
3238 rip_distance_show (struct vty
*vty
)
3240 struct route_node
*rn
;
3241 struct rip_distance
*rdistance
;
3245 vty_out (vty
, " Distance: (default is %d)%s",
3246 rip
->distance
? rip
->distance
:ZEBRA_RIP_DISTANCE_DEFAULT
,
3249 for (rn
= route_top (rip_distance_table
); rn
; rn
= route_next (rn
))
3250 if ((rdistance
= rn
->info
) != NULL
)
3254 vty_out (vty
, " Address Distance List%s",
3258 sprintf (buf
, "%s/%d", inet_ntoa (rn
->p
.u
.prefix4
), rn
->p
.prefixlen
);
3259 vty_out (vty
, " %-20s %4d %s%s",
3260 buf
, rdistance
->distance
,
3261 rdistance
->access_list
? rdistance
->access_list
: "",
3266 DEFUN (rip_distance
,
3269 "Administrative distance\n"
3273 rip
->distance
= atoi (argv
[idx_number
]->arg
);
3277 DEFUN (no_rip_distance
,
3278 no_rip_distance_cmd
,
3279 "no distance (1-255)",
3281 "Administrative distance\n"
3288 DEFUN (rip_distance_source
,
3289 rip_distance_source_cmd
,
3290 "distance (1-255) A.B.C.D/M",
3291 "Administrative distance\n"
3293 "IP source prefix\n")
3296 int idx_ipv4_prefixlen
= 2;
3297 rip_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
3301 DEFUN (no_rip_distance_source
,
3302 no_rip_distance_source_cmd
,
3303 "no distance (1-255) A.B.C.D/M",
3305 "Administrative distance\n"
3307 "IP source prefix\n")
3310 int idx_ipv4_prefixlen
= 3;
3311 rip_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
3315 DEFUN (rip_distance_source_access_list
,
3316 rip_distance_source_access_list_cmd
,
3317 "distance (1-255) A.B.C.D/M WORD",
3318 "Administrative distance\n"
3320 "IP source prefix\n"
3321 "Access list name\n")
3324 int idx_ipv4_prefixlen
= 2;
3326 rip_distance_set (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
3330 DEFUN (no_rip_distance_source_access_list
,
3331 no_rip_distance_source_access_list_cmd
,
3332 "no distance (1-255) A.B.C.D/M WORD",
3334 "Administrative distance\n"
3336 "IP source prefix\n"
3337 "Access list name\n")
3340 int idx_ipv4_prefixlen
= 3;
3342 rip_distance_unset (vty
, argv
[idx_number
]->arg
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
3346 /* Update ECMP routes to zebra when ECMP is disabled. */
3348 rip_ecmp_disable (void)
3350 struct route_node
*rp
;
3351 struct rip_info
*rinfo
, *tmp_rinfo
;
3353 struct listnode
*node
, *nextnode
;
3358 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
3359 if ((list
= rp
->info
) != NULL
&& listcount (list
) > 1)
3361 rinfo
= listgetdata (listhead (list
));
3362 if (!rip_route_rte (rinfo
))
3365 /* Drop all other entries, except the first one. */
3366 for (ALL_LIST_ELEMENTS (list
, node
, nextnode
, tmp_rinfo
))
3367 if (tmp_rinfo
!= rinfo
)
3369 RIP_TIMER_OFF (tmp_rinfo
->t_timeout
);
3370 RIP_TIMER_OFF (tmp_rinfo
->t_garbage_collect
);
3371 list_delete_node (list
, node
);
3372 rip_info_free (tmp_rinfo
);
3376 rip_zebra_ipv4_add (rp
);
3378 /* Set the route change flag. */
3379 SET_FLAG (rinfo
->flags
, RIP_RTF_CHANGED
);
3381 /* Signal the output process to trigger an update. */
3382 rip_event (RIP_TRIGGERED_UPDATE
, 0);
3386 DEFUN (rip_allow_ecmp
,
3389 "Allow Equal Cost MultiPath\n")
3393 vty_out (vty
, "ECMP is already enabled.%s", VTY_NEWLINE
);
3398 zlog_info ("ECMP is enabled.");
3402 DEFUN (no_rip_allow_ecmp
,
3403 no_rip_allow_ecmp_cmd
,
3406 "Allow Equal Cost MultiPath\n")
3410 vty_out (vty
, "ECMP is already disabled.%s", VTY_NEWLINE
);
3415 zlog_info ("ECMP is disabled.");
3416 rip_ecmp_disable ();
3420 /* Print out routes update time. */
3422 rip_vty_out_uptime (struct vty
*vty
, struct rip_info
*rinfo
)
3427 char timebuf
[TIME_BUF
];
3428 struct thread
*thread
;
3430 if ((thread
= rinfo
->t_timeout
) != NULL
)
3432 clock
= thread_timer_remain_second (thread
);
3433 tm
= gmtime (&clock
);
3434 strftime (timebuf
, TIME_BUF
, "%M:%S", tm
);
3435 vty_out (vty
, "%5s", timebuf
);
3437 else if ((thread
= rinfo
->t_garbage_collect
) != NULL
)
3439 clock
= thread_timer_remain_second (thread
);
3440 tm
= gmtime (&clock
);
3441 strftime (timebuf
, TIME_BUF
, "%M:%S", tm
);
3442 vty_out (vty
, "%5s", timebuf
);
3447 rip_route_type_print (int sub_type
)
3453 case RIP_ROUTE_STATIC
:
3455 case RIP_ROUTE_DEFAULT
:
3457 case RIP_ROUTE_REDISTRIBUTE
:
3459 case RIP_ROUTE_INTERFACE
:
3471 "Show RIP routes\n")
3473 struct route_node
*np
;
3474 struct rip_info
*rinfo
= NULL
;
3475 struct list
*list
= NULL
;
3476 struct listnode
*listnode
= NULL
;
3481 vty_out (vty
, "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP%s"
3483 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,%s"
3484 " (i) - interface%s%s"
3485 " Network Next Hop Metric From Tag Time%s",
3486 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
3488 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
3489 if ((list
= np
->info
) != NULL
)
3490 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
3494 len
= vty_out (vty
, "%c(%s) %s/%d",
3495 /* np->lock, For debugging. */
3496 zebra_route_char(rinfo
->type
),
3497 rip_route_type_print (rinfo
->sub_type
),
3498 inet_ntoa (np
->p
.u
.prefix4
), np
->p
.prefixlen
);
3503 vty_out (vty
, "%*s", len
, " ");
3505 if (rinfo
->nexthop
.s_addr
)
3506 vty_out (vty
, "%-20s %2d ", inet_ntoa (rinfo
->nexthop
),
3509 vty_out (vty
, "0.0.0.0 %2d ", rinfo
->metric
);
3511 /* Route which exist in kernel routing table. */
3512 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
) &&
3513 (rinfo
->sub_type
== RIP_ROUTE_RTE
))
3515 vty_out (vty
, "%-15s ", inet_ntoa (rinfo
->from
));
3516 vty_out (vty
, "%3"ROUTE_TAG_PRI
" ", (route_tag_t
)rinfo
->tag
);
3517 rip_vty_out_uptime (vty
, rinfo
);
3519 else if (rinfo
->metric
== RIP_METRIC_INFINITY
)
3521 vty_out (vty
, "self ");
3522 vty_out (vty
, "%3"ROUTE_TAG_PRI
" ", (route_tag_t
)rinfo
->tag
);
3523 rip_vty_out_uptime (vty
, rinfo
);
3527 if (rinfo
->external_metric
)
3529 len
= vty_out (vty
, "self (%s:%d)",
3530 zebra_route_string(rinfo
->type
),
3531 rinfo
->external_metric
);
3534 vty_out (vty
, "%*s", len
, " ");
3537 vty_out (vty
, "self ");
3538 vty_out (vty
, "%3"ROUTE_TAG_PRI
, (route_tag_t
)rinfo
->tag
);
3541 vty_out (vty
, "%s", VTY_NEWLINE
);
3546 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3547 DEFUN (show_ip_rip_status
,
3548 show_ip_rip_status_cmd
,
3549 "show ip rip status",
3553 "IP routing protocol process parameters and statistics\n")
3555 struct listnode
*node
;
3556 struct interface
*ifp
;
3557 struct rip_interface
*ri
;
3558 extern const struct message ri_version_msg
[];
3559 const char *send_version
;
3560 const char *receive_version
;
3565 vty_out (vty
, "Routing Protocol is \"rip\"%s", VTY_NEWLINE
);
3566 vty_out (vty
, " Sending updates every %ld seconds with +/-50%%,",
3568 vty_out (vty
, " next due in %lu seconds%s",
3569 thread_timer_remain_second(rip
->t_update
),
3571 vty_out (vty
, " Timeout after %ld seconds,", rip
->timeout_time
);
3572 vty_out (vty
, " garbage collect after %ld seconds%s", rip
->garbage_time
,
3575 /* Filtering status show. */
3576 config_show_distribute (vty
);
3578 /* Default metric information. */
3579 vty_out (vty
, " Default redistribution metric is %d%s",
3580 rip
->default_metric
, VTY_NEWLINE
);
3582 /* Redistribute information. */
3583 vty_out (vty
, " Redistributing:");
3584 config_write_rip_redistribute (vty
, 0);
3585 vty_out (vty
, "%s", VTY_NEWLINE
);
3587 vty_out (vty
, " Default version control: send version %s,",
3588 lookup(ri_version_msg
,rip
->version_send
));
3589 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3590 vty_out (vty
, " receive any version %s", VTY_NEWLINE
);
3592 vty_out (vty
, " receive version %s %s",
3593 lookup(ri_version_msg
,rip
->version_recv
), VTY_NEWLINE
);
3595 vty_out (vty
, " Interface Send Recv Key-chain%s", VTY_NEWLINE
);
3597 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
))
3604 if (ri
->enable_network
|| ri
->enable_interface
)
3606 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3607 send_version
= lookup (ri_version_msg
, rip
->version_send
);
3609 send_version
= lookup (ri_version_msg
, ri
->ri_send
);
3611 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3612 receive_version
= lookup (ri_version_msg
, rip
->version_recv
);
3614 receive_version
= lookup (ri_version_msg
, ri
->ri_receive
);
3616 vty_out (vty
, " %-17s%-3s %-3s %s%s", ifp
->name
,
3619 ri
->key_chain
? ri
->key_chain
: "",
3624 vty_out (vty
, " Routing for Networks:%s", VTY_NEWLINE
);
3625 config_write_rip_network (vty
, 0);
3628 int found_passive
= 0;
3629 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
))
3633 if ((ri
->enable_network
|| ri
->enable_interface
) && ri
->passive
)
3637 vty_out (vty
, " Passive Interface(s):%s", VTY_NEWLINE
);
3640 vty_out (vty
, " %s%s", ifp
->name
, VTY_NEWLINE
);
3645 vty_out (vty
, " Routing Information Sources:%s", VTY_NEWLINE
);
3646 vty_out (vty
, " Gateway BadPackets BadRoutes Distance Last Update%s", VTY_NEWLINE
);
3647 rip_peer_display (vty
);
3649 rip_distance_show (vty
);
3654 /* RIP configuration write function. */
3656 config_write_rip (struct vty
*vty
)
3659 struct route_node
*rn
;
3660 struct rip_distance
*rdistance
;
3664 /* Router RIP statement. */
3665 vty_out (vty
, "router rip%s", VTY_NEWLINE
);
3668 /* RIP version statement. Default is RIP version 2. */
3669 if (rip
->version_send
!= RI_RIP_VERSION_2
3670 || rip
->version_recv
!= RI_RIP_VERSION_1_AND_2
)
3671 vty_out (vty
, " version %d%s", rip
->version_send
,
3674 /* RIP timer configuration. */
3675 if (rip
->update_time
!= RIP_UPDATE_TIMER_DEFAULT
3676 || rip
->timeout_time
!= RIP_TIMEOUT_TIMER_DEFAULT
3677 || rip
->garbage_time
!= RIP_GARBAGE_TIMER_DEFAULT
)
3678 vty_out (vty
, " timers basic %lu %lu %lu%s",
3684 /* Default information configuration. */
3685 if (rip
->default_information
)
3687 if (rip
->default_information_route_map
)
3688 vty_out (vty
, " default-information originate route-map %s%s",
3689 rip
->default_information_route_map
, VTY_NEWLINE
);
3691 vty_out (vty
, " default-information originate%s",
3695 /* Redistribute configuration. */
3696 config_write_rip_redistribute (vty
, 1);
3698 /* RIP offset-list configuration. */
3699 config_write_rip_offset_list (vty
);
3701 /* RIP enabled network and interface configuration. */
3702 config_write_rip_network (vty
, 1);
3704 /* RIP default metric configuration */
3705 if (rip
->default_metric
!= RIP_DEFAULT_METRIC_DEFAULT
)
3706 vty_out (vty
, " default-metric %d%s",
3707 rip
->default_metric
, VTY_NEWLINE
);
3709 /* Distribute configuration. */
3710 write
+= config_write_distribute (vty
);
3712 /* Interface routemap configuration */
3713 write
+= config_write_if_rmap (vty
);
3715 /* Distance configuration. */
3717 vty_out (vty
, " distance %d%s", rip
->distance
, VTY_NEWLINE
);
3719 /* RIP source IP prefix distance configuration. */
3720 for (rn
= route_top (rip_distance_table
); rn
; rn
= route_next (rn
))
3721 if ((rdistance
= rn
->info
) != NULL
)
3722 vty_out (vty
, " distance %d %s/%d %s%s", rdistance
->distance
,
3723 inet_ntoa (rn
->p
.u
.prefix4
), rn
->p
.prefixlen
,
3724 rdistance
->access_list
? rdistance
->access_list
: "",
3727 /* ECMP configuration. */
3729 vty_out (vty
, " allow-ecmp%s", VTY_NEWLINE
);
3731 /* RIP static route configuration. */
3732 for (rn
= route_top (rip
->route
); rn
; rn
= route_next (rn
))
3734 vty_out (vty
, " route %s/%d%s",
3735 inet_ntoa (rn
->p
.u
.prefix4
),
3743 /* RIP node structure. */
3744 static struct cmd_node rip_node
=
3747 "%s(config-router)# ",
3751 /* Distribute-list update functions. */
3753 rip_distribute_update (struct distribute
*dist
)
3755 struct interface
*ifp
;
3756 struct rip_interface
*ri
;
3757 struct access_list
*alist
;
3758 struct prefix_list
*plist
;
3763 ifp
= if_lookup_by_name (dist
->ifname
);
3769 if (dist
->list
[DISTRIBUTE_V4_IN
])
3771 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_V4_IN
]);
3773 ri
->list
[RIP_FILTER_IN
] = alist
;
3775 ri
->list
[RIP_FILTER_IN
] = NULL
;
3778 ri
->list
[RIP_FILTER_IN
] = NULL
;
3780 if (dist
->list
[DISTRIBUTE_V4_OUT
])
3782 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_V4_OUT
]);
3784 ri
->list
[RIP_FILTER_OUT
] = alist
;
3786 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3789 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3791 if (dist
->prefix
[DISTRIBUTE_V4_IN
])
3793 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_V4_IN
]);
3795 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3797 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3800 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3802 if (dist
->prefix
[DISTRIBUTE_V4_OUT
])
3804 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_V4_OUT
]);
3806 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3808 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3811 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3815 rip_distribute_update_interface (struct interface
*ifp
)
3817 struct distribute
*dist
;
3819 dist
= distribute_lookup (ifp
->name
);
3821 rip_distribute_update (dist
);
3824 /* Update all interface's distribute list. */
3827 rip_distribute_update_all (struct prefix_list
*notused
)
3829 struct interface
*ifp
;
3830 struct listnode
*node
, *nnode
;
3832 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), node
, nnode
, ifp
))
3833 rip_distribute_update_interface (ifp
);
3837 rip_distribute_update_all_wrapper(struct access_list
*notused
)
3839 rip_distribute_update_all(NULL
);
3842 /* Delete all added rip route. */
3847 struct route_node
*rp
;
3848 struct rip_info
*rinfo
= NULL
;
3849 struct list
*list
= NULL
;
3850 struct listnode
*listnode
= NULL
;
3854 /* Clear RIP routes */
3855 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
3856 if ((list
= rp
->info
) != NULL
)
3858 rinfo
= listgetdata (listhead (list
));
3859 if (rip_route_rte (rinfo
))
3860 rip_zebra_ipv4_delete (rp
);
3862 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
3864 RIP_TIMER_OFF (rinfo
->t_timeout
);
3865 RIP_TIMER_OFF (rinfo
->t_garbage_collect
);
3866 rip_info_free (rinfo
);
3870 route_unlock_node (rp
);
3873 /* Cancel RIP related timers. */
3874 RIP_TIMER_OFF (rip
->t_update
);
3875 RIP_TIMER_OFF (rip
->t_triggered_update
);
3876 RIP_TIMER_OFF (rip
->t_triggered_interval
);
3878 /* Cancel read thread. */
3879 THREAD_READ_OFF (rip
->t_read
);
3881 /* Close RIP socket. */
3888 /* Static RIP route configuration. */
3889 for (rp
= route_top (rip
->route
); rp
; rp
= route_next (rp
))
3893 route_unlock_node (rp
);
3896 /* RIP neighbor configuration. */
3897 for (rp
= route_top (rip
->neighbor
); rp
; rp
= route_next (rp
))
3901 route_unlock_node (rp
);
3904 /* Redistribute related clear. */
3905 if (rip
->default_information_route_map
)
3906 free (rip
->default_information_route_map
);
3908 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3909 if (rip
->route_map
[i
].name
)
3910 free (rip
->route_map
[i
].name
);
3912 XFREE (MTYPE_ROUTE_TABLE
, rip
->table
);
3913 XFREE (MTYPE_ROUTE_TABLE
, rip
->route
);
3914 XFREE (MTYPE_ROUTE_TABLE
, rip
->neighbor
);
3916 XFREE (MTYPE_RIP
, rip
);
3920 rip_clean_network ();
3921 rip_passive_nondefault_clean ();
3922 rip_offset_clean ();
3923 rip_interfaces_clean ();
3924 rip_distance_reset ();
3925 rip_redistribute_clean ();
3928 /* Reset all values to the default settings. */
3932 /* Reset global counters. */
3933 rip_global_route_changes
= 0;
3934 rip_global_queries
= 0;
3936 /* Call ripd related reset functions. */
3938 rip_route_map_reset ();
3940 /* Call library reset functions. */
3942 access_list_reset ();
3943 prefix_list_reset ();
3945 distribute_list_reset ();
3947 rip_interfaces_reset ();
3948 rip_distance_reset ();
3950 rip_zclient_reset ();
3954 rip_if_rmap_update (struct if_rmap
*if_rmap
)
3956 struct interface
*ifp
;
3957 struct rip_interface
*ri
;
3958 struct route_map
*rmap
;
3960 ifp
= if_lookup_by_name (if_rmap
->ifname
);
3966 if (if_rmap
->routemap
[IF_RMAP_IN
])
3968 rmap
= route_map_lookup_by_name (if_rmap
->routemap
[IF_RMAP_IN
]);
3970 ri
->routemap
[IF_RMAP_IN
] = rmap
;
3972 ri
->routemap
[IF_RMAP_IN
] = NULL
;
3975 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
3977 if (if_rmap
->routemap
[IF_RMAP_OUT
])
3979 rmap
= route_map_lookup_by_name (if_rmap
->routemap
[IF_RMAP_OUT
]);
3981 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
3983 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
3986 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
3990 rip_if_rmap_update_interface (struct interface
*ifp
)
3992 struct if_rmap
*if_rmap
;
3994 if_rmap
= if_rmap_lookup (ifp
->name
);
3996 rip_if_rmap_update (if_rmap
);
4000 rip_routemap_update_redistribute (void)
4006 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
4008 if (rip
->route_map
[i
].name
)
4009 rip
->route_map
[i
].map
=
4010 route_map_lookup_by_name (rip
->route_map
[i
].name
);
4017 rip_routemap_update (const char *notused
)
4019 struct interface
*ifp
;
4020 struct listnode
*node
, *nnode
;
4022 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), node
, nnode
, ifp
))
4023 rip_if_rmap_update_interface (ifp
);
4025 rip_routemap_update_redistribute ();
4028 /* Allocate new rip structure and set default value. */
4032 /* Randomize for triggered update random(). */
4033 srandom (time (NULL
));
4035 /* Install top nodes. */
4036 install_node (&rip_node
, config_write_rip
);
4038 /* Install rip commands. */
4039 install_element (VIEW_NODE
, &show_ip_rip_cmd
);
4040 install_element (VIEW_NODE
, &show_ip_rip_status_cmd
);
4041 install_element (CONFIG_NODE
, &router_rip_cmd
);
4042 install_element (CONFIG_NODE
, &no_router_rip_cmd
);
4044 install_default (RIP_NODE
);
4045 install_element (RIP_NODE
, &rip_version_cmd
);
4046 install_element (RIP_NODE
, &no_rip_version_cmd
);
4047 install_element (RIP_NODE
, &rip_default_metric_cmd
);
4048 install_element (RIP_NODE
, &no_rip_default_metric_cmd
);
4049 install_element (RIP_NODE
, &rip_timers_cmd
);
4050 install_element (RIP_NODE
, &no_rip_timers_cmd
);
4051 install_element (RIP_NODE
, &rip_route_cmd
);
4052 install_element (RIP_NODE
, &no_rip_route_cmd
);
4053 install_element (RIP_NODE
, &rip_distance_cmd
);
4054 install_element (RIP_NODE
, &no_rip_distance_cmd
);
4055 install_element (RIP_NODE
, &rip_distance_source_cmd
);
4056 install_element (RIP_NODE
, &no_rip_distance_source_cmd
);
4057 install_element (RIP_NODE
, &rip_distance_source_access_list_cmd
);
4058 install_element (RIP_NODE
, &no_rip_distance_source_access_list_cmd
);
4059 install_element (RIP_NODE
, &rip_allow_ecmp_cmd
);
4060 install_element (RIP_NODE
, &no_rip_allow_ecmp_cmd
);
4062 /* Debug related init. */
4068 #endif /* HAVE_SNMP */
4070 /* Access list install. */
4071 access_list_init ();
4072 access_list_add_hook (rip_distribute_update_all_wrapper
);
4073 access_list_delete_hook (rip_distribute_update_all_wrapper
);
4075 /* Prefix list initialize.*/
4076 prefix_list_init ();
4077 prefix_list_add_hook (rip_distribute_update_all
);
4078 prefix_list_delete_hook (rip_distribute_update_all
);
4080 /* Distribute list install. */
4081 distribute_list_init (RIP_NODE
);
4082 distribute_list_add_hook (rip_distribute_update
);
4083 distribute_list_delete_hook (rip_distribute_update
);
4086 rip_route_map_init ();
4089 route_map_add_hook (rip_routemap_update
);
4090 route_map_delete_hook (rip_routemap_update
);
4092 if_rmap_init (RIP_NODE
);
4093 if_rmap_hook_add (rip_if_rmap_update
);
4094 if_rmap_hook_delete (rip_if_rmap_update
);
4096 /* Distance control. */
4097 rip_distance_table
= route_table_init ();