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 along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "sockunion.h"
39 #include "distribute.h"
44 #include "ripd/ripd.h"
45 #include "ripd/rip_debug.h"
49 /* UDP receive buffer size */
50 #define RIP_UDP_RCV_BUF 41600
52 /* privileges global */
53 extern struct zebra_privs_t ripd_privs
;
56 struct rip
*rip
= NULL
;
58 /* RIP neighbor address table. */
59 struct route_table
*rip_neighbor_table
;
61 /* RIP route changes. */
62 long rip_global_route_changes
= 0;
65 long rip_global_queries
= 0;
68 static void rip_event(enum rip_event
, int);
69 static void rip_output_process(struct connected
*, struct sockaddr_in
*, int,
71 static int rip_triggered_update(struct thread
*);
72 static int rip_update_jitter(unsigned long);
74 /* RIP output routes type. */
75 enum { rip_all_route
, rip_changed_route
};
77 /* RIP command strings. */
78 static const struct message rip_msg
[] = {{RIP_REQUEST
, "REQUEST"},
79 {RIP_RESPONSE
, "RESPONSE"},
80 {RIP_TRACEON
, "TRACEON"},
81 {RIP_TRACEOFF
, "TRACEOFF"},
83 {RIP_POLL_ENTRY
, "POLL ENTRY"},
86 /* Utility function to set boradcast option to the socket. */
87 static int sockopt_broadcast(int sock
)
92 ret
= setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, (char *)&on
,
95 zlog_warn("can't set sockopt SO_BROADCAST to socket %d", sock
);
101 static int rip_route_rte(struct rip_info
*rinfo
)
103 return (rinfo
->type
== ZEBRA_ROUTE_RIP
104 && rinfo
->sub_type
== RIP_ROUTE_RTE
);
107 static struct rip_info
*rip_info_new(void)
109 return XCALLOC(MTYPE_RIP_INFO
, sizeof(struct rip_info
));
112 void rip_info_free(struct rip_info
*rinfo
)
114 XFREE(MTYPE_RIP_INFO
, rinfo
);
117 /* RIP route garbage collect timer. */
118 static int rip_garbage_collect(struct thread
*t
)
120 struct rip_info
*rinfo
;
121 struct route_node
*rp
;
123 rinfo
= THREAD_ARG(t
);
124 rinfo
->t_garbage_collect
= NULL
;
126 /* Off timeout timer. */
127 RIP_TIMER_OFF(rinfo
->t_timeout
);
129 /* Get route_node pointer. */
132 /* Unlock route_node. */
133 listnode_delete(rp
->info
, rinfo
);
134 if (list_isempty((struct list
*)rp
->info
)) {
137 route_unlock_node(rp
);
140 /* Free RIP routing information. */
141 rip_info_free(rinfo
);
146 static void rip_timeout_update(struct rip_info
*rinfo
);
148 /* Add new route to the ECMP list.
149 * RETURN: the new entry added in the list, or NULL if it is not the first
150 * entry and ECMP is not allowed.
152 struct rip_info
*rip_ecmp_add(struct rip_info
*rinfo_new
)
154 struct route_node
*rp
= rinfo_new
->rp
;
155 struct rip_info
*rinfo
= NULL
;
156 struct list
*list
= NULL
;
158 if (rp
->info
== NULL
)
159 rp
->info
= list_new();
160 list
= (struct list
*)rp
->info
;
162 /* If ECMP is not allowed and some entry already exists in the list,
164 if (listcount(list
) && !rip
->ecmp
)
167 rinfo
= rip_info_new();
168 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
169 listnode_add(list
, rinfo
);
171 if (rip_route_rte(rinfo
)) {
172 rip_timeout_update(rinfo
);
173 rip_zebra_ipv4_add(rp
);
176 /* Set the route change flag on the first entry. */
177 rinfo
= listgetdata(listhead(list
));
178 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
180 /* Signal the output process to trigger an update (see section 2.5). */
181 rip_event(RIP_TRIGGERED_UPDATE
, 0);
186 /* Replace the ECMP list with the new route.
187 * RETURN: the new entry added in the list
189 struct rip_info
*rip_ecmp_replace(struct rip_info
*rinfo_new
)
191 struct route_node
*rp
= rinfo_new
->rp
;
192 struct list
*list
= (struct list
*)rp
->info
;
193 struct rip_info
*rinfo
= NULL
, *tmp_rinfo
= NULL
;
194 struct listnode
*node
= NULL
, *nextnode
= NULL
;
196 if (list
== NULL
|| listcount(list
) == 0)
197 return rip_ecmp_add(rinfo_new
);
199 /* Get the first entry */
200 rinfo
= listgetdata(listhead(list
));
202 /* Learnt route replaced by a local one. Delete it from zebra. */
203 if (rip_route_rte(rinfo
) && !rip_route_rte(rinfo_new
))
204 if (CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
205 rip_zebra_ipv4_delete(rp
);
207 /* Re-use the first entry, and delete the others. */
208 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
209 if (tmp_rinfo
!= rinfo
) {
210 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
211 RIP_TIMER_OFF(tmp_rinfo
->t_garbage_collect
);
212 list_delete_node(list
, node
);
213 rip_info_free(tmp_rinfo
);
216 RIP_TIMER_OFF(rinfo
->t_timeout
);
217 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
218 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
220 if (rip_route_rte(rinfo
)) {
221 rip_timeout_update(rinfo
);
222 /* The ADD message implies an update. */
223 rip_zebra_ipv4_add(rp
);
226 /* Set the route change flag. */
227 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
229 /* Signal the output process to trigger an update (see section 2.5). */
230 rip_event(RIP_TRIGGERED_UPDATE
, 0);
235 /* Delete one route from the ECMP list.
237 * null - the entry is freed, and other entries exist in the list
238 * the entry - the entry is the last one in the list; its metric is set
239 * to INFINITY, and the garbage collector is started for it
241 struct rip_info
*rip_ecmp_delete(struct rip_info
*rinfo
)
243 struct route_node
*rp
= rinfo
->rp
;
244 struct list
*list
= (struct list
*)rp
->info
;
246 RIP_TIMER_OFF(rinfo
->t_timeout
);
248 if (listcount(list
) > 1) {
249 /* Some other ECMP entries still exist. Just delete this entry.
251 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
252 listnode_delete(list
, rinfo
);
253 if (rip_route_rte(rinfo
)
254 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
255 /* The ADD message implies the update. */
256 rip_zebra_ipv4_add(rp
);
257 rip_info_free(rinfo
);
260 assert(rinfo
== listgetdata(listhead(list
)));
262 /* This is the only entry left in the list. We must keep it in
263 * the list for garbage collection time, with INFINITY metric.
266 rinfo
->metric
= RIP_METRIC_INFINITY
;
267 RIP_TIMER_ON(rinfo
->t_garbage_collect
, rip_garbage_collect
,
270 if (rip_route_rte(rinfo
)
271 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
272 rip_zebra_ipv4_delete(rp
);
275 /* Set the route change flag on the first entry. */
276 rinfo
= listgetdata(listhead(list
));
277 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
279 /* Signal the output process to trigger an update (see section 2.5). */
280 rip_event(RIP_TRIGGERED_UPDATE
, 0);
285 /* Timeout RIP routes. */
286 static int rip_timeout(struct thread
*t
)
288 rip_ecmp_delete((struct rip_info
*)THREAD_ARG(t
));
292 static void rip_timeout_update(struct rip_info
*rinfo
)
294 if (rinfo
->metric
!= RIP_METRIC_INFINITY
) {
295 RIP_TIMER_OFF(rinfo
->t_timeout
);
296 RIP_TIMER_ON(rinfo
->t_timeout
, rip_timeout
, rip
->timeout_time
);
300 static int rip_filter(int rip_distribute
, struct prefix_ipv4
*p
,
301 struct rip_interface
*ri
)
303 struct distribute
*dist
;
304 struct access_list
*alist
;
305 struct prefix_list
*plist
;
306 int distribute
= rip_distribute
== RIP_FILTER_OUT
? DISTRIBUTE_V4_OUT
308 const char *inout
= rip_distribute
== RIP_FILTER_OUT
? "out" : "in";
310 /* Input distribute-list filtering. */
311 if (ri
->list
[rip_distribute
]) {
312 if (access_list_apply(ri
->list
[rip_distribute
],
315 if (IS_RIP_DEBUG_PACKET
)
316 zlog_debug("%s/%d filtered by distribute %s",
317 inet_ntoa(p
->prefix
), p
->prefixlen
,
322 if (ri
->prefix
[rip_distribute
]) {
323 if (prefix_list_apply(ri
->prefix
[rip_distribute
],
326 if (IS_RIP_DEBUG_PACKET
)
327 zlog_debug("%s/%d filtered by prefix-list %s",
328 inet_ntoa(p
->prefix
), p
->prefixlen
,
334 /* All interface filter check. */
335 dist
= distribute_lookup(NULL
);
337 if (dist
->list
[distribute
]) {
338 alist
= access_list_lookup(AFI_IP
,
339 dist
->list
[distribute
]);
342 if (access_list_apply(alist
, (struct prefix
*)p
)
344 if (IS_RIP_DEBUG_PACKET
)
346 "%s/%d filtered by distribute %s",
347 inet_ntoa(p
->prefix
),
348 p
->prefixlen
, inout
);
353 if (dist
->prefix
[distribute
]) {
354 plist
= prefix_list_lookup(AFI_IP
,
355 dist
->prefix
[distribute
]);
358 if (prefix_list_apply(plist
, (struct prefix
*)p
)
360 if (IS_RIP_DEBUG_PACKET
)
362 "%s/%d filtered by prefix-list %s",
363 inet_ntoa(p
->prefix
),
364 p
->prefixlen
, inout
);
373 /* Check nexthop address validity. */
374 static int rip_nexthop_check(struct in_addr
*addr
)
376 struct listnode
*node
;
377 struct listnode
*cnode
;
378 struct interface
*ifp
;
379 struct connected
*ifc
;
382 /* If nexthop address matches local configured address then it is
385 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
)) {
386 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, ifc
)) {
389 if (p
->family
== AF_INET
390 && IPV4_ADDR_SAME(&p
->u
.prefix4
, addr
))
397 /* RIP add route to routing table. */
398 static void rip_rte_process(struct rte
*rte
, struct sockaddr_in
*from
,
399 struct interface
*ifp
)
402 struct prefix_ipv4 p
;
403 struct route_node
*rp
;
404 struct rip_info
*rinfo
= NULL
, newinfo
;
405 struct rip_interface
*ri
;
406 struct in_addr
*nexthop
;
408 unsigned char old_dist
, new_dist
;
409 struct list
*list
= NULL
;
410 struct listnode
*node
= NULL
;
412 /* Make prefix structure. */
413 memset(&p
, 0, sizeof(struct prefix_ipv4
));
415 p
.prefix
= rte
->prefix
;
416 p
.prefixlen
= ip_masklen(rte
->mask
);
418 /* Make sure mask is applied. */
421 /* Apply input filters. */
424 ret
= rip_filter(RIP_FILTER_IN
, &p
, ri
);
428 memset(&newinfo
, 0, sizeof(newinfo
));
429 newinfo
.type
= ZEBRA_ROUTE_RIP
;
430 newinfo
.sub_type
= RIP_ROUTE_RTE
;
431 newinfo
.nexthop
= rte
->nexthop
;
432 newinfo
.from
= from
->sin_addr
;
433 newinfo
.ifindex
= ifp
->ifindex
;
434 newinfo
.metric
= rte
->metric
;
435 newinfo
.metric_out
= rte
->metric
; /* XXX */
436 newinfo
.tag
= ntohs(rte
->tag
); /* XXX */
438 /* Modify entry according to the interface routemap. */
439 if (ri
->routemap
[RIP_FILTER_IN
]) {
442 /* The object should be of the type of rip_info */
443 ret
= route_map_apply(ri
->routemap
[RIP_FILTER_IN
],
444 (struct prefix
*)&p
, RMAP_RIP
, &newinfo
);
446 if (ret
== RMAP_DENYMATCH
) {
447 if (IS_RIP_DEBUG_PACKET
)
449 "RIP %s/%d is filtered by route-map in",
450 inet_ntoa(p
.prefix
), p
.prefixlen
);
454 /* Get back the object */
455 rte
->nexthop
= newinfo
.nexthop_out
;
456 rte
->tag
= htons(newinfo
.tag_out
); /* XXX */
458 newinfo
.metric_out
; /* XXX: the routemap uses the
462 /* Once the entry has been validated, update the metric by
463 adding the cost of the network on wich the message
464 arrived. If the result is greater than infinity, use infinity
465 (RFC2453 Sec. 3.9.2) */
466 /* Zebra ripd can handle offset-list in. */
467 ret
= rip_offset_list_apply_in(&p
, ifp
, &rte
->metric
);
469 /* If offset-list does not modify the metric use interface's
472 rte
->metric
+= ifp
->metric
? ifp
->metric
: 1;
474 if (rte
->metric
> RIP_METRIC_INFINITY
)
475 rte
->metric
= RIP_METRIC_INFINITY
;
477 /* Set nexthop pointer. */
478 if (rte
->nexthop
.s_addr
== 0)
479 nexthop
= &from
->sin_addr
;
481 nexthop
= &rte
->nexthop
;
483 /* Check if nexthop address is myself, then do nothing. */
484 if (rip_nexthop_check(nexthop
) < 0) {
485 if (IS_RIP_DEBUG_PACKET
)
486 zlog_debug("Nexthop address %s is myself",
487 inet_ntoa(*nexthop
));
491 /* Get index for the prefix. */
492 rp
= route_node_get(rip
->table
, (struct prefix
*)&p
);
495 newinfo
.nexthop
= *nexthop
;
496 newinfo
.metric
= rte
->metric
;
497 newinfo
.tag
= ntohs(rte
->tag
);
498 newinfo
.distance
= rip_distance_apply(&newinfo
);
500 new_dist
= newinfo
.distance
? newinfo
.distance
501 : ZEBRA_RIP_DISTANCE_DEFAULT
;
503 /* Check to see whether there is already RIP route on the table. */
504 if ((list
= rp
->info
) != NULL
)
505 for (ALL_LIST_ELEMENTS_RO(list
, node
, rinfo
)) {
506 /* Need to compare with redistributed entry or local
508 if (!rip_route_rte(rinfo
))
511 if (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
512 && IPV4_ADDR_SAME(&rinfo
->nexthop
, nexthop
))
515 if (!listnextnode(node
)) {
516 /* Not found in the list */
518 if (rte
->metric
> rinfo
->metric
) {
519 /* New route has a greater metric.
521 route_unlock_node(rp
);
525 if (rte
->metric
< rinfo
->metric
)
526 /* New route has a smaller metric.
527 * Replace the ECMP list
528 * with the new one in below. */
531 /* Metrics are same. We compare the distances.
533 old_dist
= rinfo
->distance
535 : ZEBRA_RIP_DISTANCE_DEFAULT
;
537 if (new_dist
> old_dist
) {
538 /* New route has a greater distance.
540 route_unlock_node(rp
);
544 if (new_dist
< old_dist
)
545 /* New route has a smaller distance.
546 * Replace the ECMP list
547 * with the new one in below. */
550 /* Metrics and distances are both same. Keep
552 * the new route is added in the ECMP list in
558 /* Local static route. */
559 if (rinfo
->type
== ZEBRA_ROUTE_RIP
560 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
561 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))
562 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
563 route_unlock_node(rp
);
567 /* Redistributed route check. */
568 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
569 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
570 old_dist
= rinfo
->distance
;
571 /* Only routes directly connected to an interface
573 * may have a valid NULL distance */
574 if (rinfo
->nexthop
.s_addr
!= 0)
577 : ZEBRA_RIP_DISTANCE_DEFAULT
;
578 /* If imported route does not have STRICT precedence,
579 mark it as a ghost */
580 if (new_dist
<= old_dist
581 && rte
->metric
!= RIP_METRIC_INFINITY
)
582 rip_ecmp_replace(&newinfo
);
584 route_unlock_node(rp
);
591 route_unlock_node(rp
);
593 /* Now, check to see whether there is already an explicit route
594 for the destination prefix. If there is no such route, add
595 this route to the routing table, unless the metric is
596 infinity (there is no point in adding a route which
598 if (rte
->metric
!= RIP_METRIC_INFINITY
)
599 rip_ecmp_add(&newinfo
);
601 /* Route is there but we are not sure the route is RIP or not.
604 /* If there is an existing route, compare the next hop address
605 to the address of the router from which the datagram came.
606 If this datagram is from the same router as the existing
607 route, reinitialize the timeout. */
608 same
= (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
609 && (rinfo
->ifindex
== ifp
->ifindex
));
611 old_dist
= rinfo
->distance
? rinfo
->distance
612 : ZEBRA_RIP_DISTANCE_DEFAULT
;
614 /* Next, compare the metrics. If the datagram is from the same
615 router as the existing route, and the new metric is different
616 than the old one; or, if the new metric is lower than the old
617 one, or if the tag has been changed; or if there is a route
618 with a lower administrave distance; or an update of the
619 distance on the actual route; do the following actions: */
620 if ((same
&& rinfo
->metric
!= rte
->metric
)
621 || (rte
->metric
< rinfo
->metric
)
622 || ((same
) && (rinfo
->metric
== rte
->metric
)
623 && (newinfo
.tag
!= rinfo
->tag
))
624 || (old_dist
> new_dist
)
625 || ((old_dist
!= new_dist
) && same
)) {
626 if (listcount(list
) == 1) {
627 if (newinfo
.metric
!= RIP_METRIC_INFINITY
)
628 rip_ecmp_replace(&newinfo
);
630 rip_ecmp_delete(rinfo
);
632 if (newinfo
.metric
< rinfo
->metric
)
633 rip_ecmp_replace(&newinfo
);
634 else if (newinfo
.metric
> rinfo
->metric
)
635 rip_ecmp_delete(rinfo
);
636 else if (new_dist
< old_dist
)
637 rip_ecmp_replace(&newinfo
);
638 else if (new_dist
> old_dist
)
639 rip_ecmp_delete(rinfo
);
641 int update
= CHECK_FLAG(rinfo
->flags
,
646 assert(newinfo
.metric
647 != RIP_METRIC_INFINITY
);
649 RIP_TIMER_OFF(rinfo
->t_timeout
);
650 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
651 memcpy(rinfo
, &newinfo
,
652 sizeof(struct rip_info
));
653 rip_timeout_update(rinfo
);
656 rip_zebra_ipv4_add(rp
);
658 /* - Set the route change flag on the
660 rinfo
= listgetdata(listhead(list
));
661 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
662 rip_event(RIP_TRIGGERED_UPDATE
, 0);
665 } else /* same & no change */
666 rip_timeout_update(rinfo
);
668 /* Unlock tempolary lock of the route. */
669 route_unlock_node(rp
);
673 /* Dump RIP packet */
674 static void rip_packet_dump(struct rip_packet
*packet
, int size
,
679 const char *command_str
;
680 char pbuf
[BUFSIZ
], nbuf
[BUFSIZ
];
684 /* Set command string. */
685 if (packet
->command
> 0 && packet
->command
< RIP_COMMAND_MAX
)
686 command_str
= lookup_msg(rip_msg
, packet
->command
, NULL
);
688 command_str
= "unknown";
690 /* Dump packet header. */
691 zlog_debug("%s %s version %d packet size %d", sndrcv
, command_str
,
692 packet
->version
, size
);
694 /* Dump each routing table entry. */
697 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
698 if (packet
->version
== RIPv2
) {
699 netmask
= ip_masklen(rte
->mask
);
701 if (rte
->family
== htons(RIP_FAMILY_AUTH
)) {
703 == htons(RIP_AUTH_SIMPLE_PASSWORD
)) {
704 p
= (u_char
*)&rte
->prefix
;
707 " family 0x%X type %d auth string: %s",
710 } else if (rte
->tag
== htons(RIP_AUTH_MD5
)) {
711 struct rip_md5_info
*md5
;
713 md5
= (struct rip_md5_info
*)&packet
717 " family 0x%X type %d (MD5 authentication)",
721 " RIP-2 packet len %d Key ID %d"
723 ntohs(md5
->packet_len
),
724 md5
->keyid
, md5
->auth_len
);
726 " Sequence Number %ld",
727 (u_long
)ntohl(md5
->sequence
));
728 } else if (rte
->tag
== htons(RIP_AUTH_DATA
)) {
729 p
= (u_char
*)&rte
->prefix
;
732 " family 0x%X type %d (MD5 data)",
736 " MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
737 "%02X%02X%02X%02X%02X%02X%02X%02X",
738 p
[0], p
[1], p
[2], p
[3], p
[4],
739 p
[5], p
[6], p
[7], p
[8], p
[9],
740 p
[10], p
[11], p
[12], p
[13],
744 " family 0x%X type %d (Unknown auth type)",
750 " %s/%d -> %s family %d tag %" ROUTE_TAG_PRI
752 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
,
755 inet_ntop(AF_INET
, &rte
->nexthop
, nbuf
,
758 (route_tag_t
)ntohs(rte
->tag
),
759 (u_long
)ntohl(rte
->metric
));
762 " %s family %d tag %" ROUTE_TAG_PRI
764 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
766 (route_tag_t
)ntohs(rte
->tag
),
767 (u_long
)ntohl(rte
->metric
));
772 /* Check if the destination address is valid (unicast; not net 0
773 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
774 check net 0 because we accept default route. */
775 static int rip_destination_check(struct in_addr addr
)
777 u_int32_t destination
;
779 /* Convert to host byte order. */
780 destination
= ntohl(addr
.s_addr
);
782 if (IPV4_NET127(destination
))
785 /* Net 0 may match to the default route. */
786 if (IPV4_NET0(destination
) && destination
!= 0)
789 /* Unicast address must belong to class A, B, C. */
790 if (IN_CLASSA(destination
))
792 if (IN_CLASSB(destination
))
794 if (IN_CLASSC(destination
))
800 /* RIP version 2 authentication. */
801 static int rip_auth_simple_password(struct rte
*rte
, struct sockaddr_in
*from
,
802 struct interface
*ifp
)
804 struct rip_interface
*ri
;
805 char *auth_str
= (char *)&rte
->prefix
;
808 /* reject passwords with zeros in the middle of the string */
809 for (i
= strlen(auth_str
); i
< 16; i
++) {
810 if (auth_str
[i
] != '\0')
814 if (IS_RIP_DEBUG_EVENT
)
815 zlog_debug("RIPv2 simple password authentication from %s",
816 inet_ntoa(from
->sin_addr
));
820 if (ri
->auth_type
!= RIP_AUTH_SIMPLE_PASSWORD
821 || rte
->tag
!= htons(RIP_AUTH_SIMPLE_PASSWORD
))
824 /* Simple password authentication. */
826 if (strncmp(auth_str
, ri
->auth_str
, 16) == 0)
830 struct keychain
*keychain
;
833 keychain
= keychain_lookup(ri
->key_chain
);
834 if (keychain
== NULL
)
837 key
= key_match_for_accept(keychain
, auth_str
);
844 /* RIP version 2 authentication with MD5. */
845 static int rip_auth_md5(struct rip_packet
*packet
, struct sockaddr_in
*from
,
846 int length
, struct interface
*ifp
)
848 struct rip_interface
*ri
;
849 struct rip_md5_info
*md5
;
850 struct rip_md5_data
*md5data
;
851 struct keychain
*keychain
;
854 u_char digest
[RIP_AUTH_MD5_SIZE
];
855 u_int16_t packet_len
;
856 char auth_str
[RIP_AUTH_MD5_SIZE
];
858 if (IS_RIP_DEBUG_EVENT
)
859 zlog_debug("RIPv2 MD5 authentication from %s",
860 inet_ntoa(from
->sin_addr
));
863 md5
= (struct rip_md5_info
*)&packet
->rte
;
865 /* Check auth type. */
866 if (ri
->auth_type
!= RIP_AUTH_MD5
|| md5
->type
!= htons(RIP_AUTH_MD5
))
869 /* If the authentication length is less than 16, then it must be wrong
871 * any interpretation of rfc2082. Some implementations also interpret
872 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka
873 * RIP_AUTH_MD5_COMPAT_SIZE.
875 if (!((md5
->auth_len
== RIP_AUTH_MD5_SIZE
)
876 || (md5
->auth_len
== RIP_AUTH_MD5_COMPAT_SIZE
))) {
877 if (IS_RIP_DEBUG_EVENT
)
879 "RIPv2 MD5 authentication, strange authentication "
885 /* grab and verify check packet length */
886 packet_len
= ntohs(md5
->packet_len
);
888 if (packet_len
> (length
- RIP_HEADER_SIZE
- RIP_AUTH_MD5_SIZE
)) {
889 if (IS_RIP_DEBUG_EVENT
)
891 "RIPv2 MD5 authentication, packet length field %d "
892 "greater than received length %d!",
893 md5
->packet_len
, length
);
897 /* retrieve authentication data */
898 md5data
= (struct rip_md5_data
*)(((u_char
*)packet
) + packet_len
);
900 memset(auth_str
, 0, RIP_AUTH_MD5_SIZE
);
903 keychain
= keychain_lookup(ri
->key_chain
);
904 if (keychain
== NULL
)
907 key
= key_lookup_for_accept(keychain
, md5
->keyid
);
911 strncpy(auth_str
, key
->string
, RIP_AUTH_MD5_SIZE
);
912 } else if (ri
->auth_str
)
913 strncpy(auth_str
, ri
->auth_str
, RIP_AUTH_MD5_SIZE
);
915 if (auth_str
[0] == 0)
918 /* MD5 digest authentication. */
919 memset(&ctx
, 0, sizeof(ctx
));
921 MD5Update(&ctx
, packet
, packet_len
+ RIP_HEADER_SIZE
);
922 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
923 MD5Final(digest
, &ctx
);
925 if (memcmp(md5data
->digest
, digest
, RIP_AUTH_MD5_SIZE
) == 0)
931 /* Pick correct auth string for sends, prepare auth_str buffer for use.
932 * (left justified and padded).
934 * presumes one of ri or key is valid, and that the auth strings they point
935 * to are nul terminated. If neither are present, auth_str will be fully
939 static void rip_auth_prepare_str_send(struct rip_interface
*ri
, struct key
*key
,
940 char *auth_str
, int len
)
944 memset(auth_str
, 0, len
);
945 if (key
&& key
->string
)
946 strncpy(auth_str
, key
->string
, len
);
947 else if (ri
->auth_str
)
948 strncpy(auth_str
, ri
->auth_str
, len
);
953 /* Write RIPv2 simple password authentication information
955 * auth_str is presumed to be 2 bytes and correctly prepared
956 * (left justified and zero padded).
958 static void rip_auth_simple_write(struct stream
*s
, char *auth_str
, int len
)
960 assert(s
&& len
== RIP_AUTH_SIMPLE_SIZE
);
962 stream_putw(s
, RIP_FAMILY_AUTH
);
963 stream_putw(s
, RIP_AUTH_SIMPLE_PASSWORD
);
964 stream_put(s
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
969 /* write RIPv2 MD5 "authentication header"
970 * (uses the auth key data field)
972 * Digest offset field is set to 0.
974 * returns: offset of the digest offset field, which must be set when
975 * length to the auth-data MD5 digest is known.
977 static size_t rip_auth_md5_ah_write(struct stream
*s
, struct rip_interface
*ri
,
982 assert(s
&& ri
&& ri
->auth_type
== RIP_AUTH_MD5
);
984 /* MD5 authentication. */
985 stream_putw(s
, RIP_FAMILY_AUTH
);
986 stream_putw(s
, RIP_AUTH_MD5
);
988 /* MD5 AH digest offset field.
990 * Set to placeholder value here, to true value when RIP-2 Packet length
991 * is known. Actual value is set in .....().
993 doff
= stream_get_endp(s
);
998 stream_putc(s
, key
->index
% 256);
1002 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
1003 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for
1005 * to be configurable.
1007 stream_putc(s
, ri
->md5_auth_len
);
1009 /* Sequence Number (non-decreasing). */
1010 /* RFC2080: The value used in the sequence number is
1011 arbitrary, but two suggestions are the time of the
1012 message's creation or a simple message counter. */
1013 stream_putl(s
, time(NULL
));
1015 /* Reserved field must be zero. */
1022 /* If authentication is in used, write the appropriate header
1023 * returns stream offset to which length must later be written
1024 * or 0 if this is not required
1026 static size_t rip_auth_header_write(struct stream
*s
, struct rip_interface
*ri
,
1027 struct key
*key
, char *auth_str
, int len
)
1029 assert(ri
->auth_type
!= RIP_NO_AUTH
);
1031 switch (ri
->auth_type
) {
1032 case RIP_AUTH_SIMPLE_PASSWORD
:
1033 rip_auth_prepare_str_send(ri
, key
, auth_str
, len
);
1034 rip_auth_simple_write(s
, auth_str
, len
);
1037 return rip_auth_md5_ah_write(s
, ri
, key
);
1043 /* Write RIPv2 MD5 authentication data trailer */
1044 static void rip_auth_md5_set(struct stream
*s
, struct rip_interface
*ri
,
1045 size_t doff
, char *auth_str
, int authlen
)
1049 unsigned char digest
[RIP_AUTH_MD5_SIZE
];
1051 /* Make it sure this interface is configured as MD5
1053 assert((ri
->auth_type
== RIP_AUTH_MD5
)
1054 && (authlen
== RIP_AUTH_MD5_SIZE
));
1057 /* Get packet length. */
1058 len
= stream_get_endp(s
);
1060 /* Check packet length. */
1061 if (len
< (RIP_HEADER_SIZE
+ RIP_RTE_SIZE
)) {
1063 "rip_auth_md5_set(): packet length %ld is less than minimum length.",
1068 /* Set the digest offset length in the header */
1069 stream_putw_at(s
, doff
, len
);
1071 /* Set authentication data. */
1072 stream_putw(s
, RIP_FAMILY_AUTH
);
1073 stream_putw(s
, RIP_AUTH_DATA
);
1075 /* Generate a digest for the RIP packet. */
1076 memset(&ctx
, 0, sizeof(ctx
));
1078 MD5Update(&ctx
, STREAM_DATA(s
), stream_get_endp(s
));
1079 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1080 MD5Final(digest
, &ctx
);
1082 /* Copy the digest to the packet. */
1083 stream_write(s
, digest
, RIP_AUTH_MD5_SIZE
);
1086 /* RIP routing information. */
1087 static void rip_response_process(struct rip_packet
*packet
, int size
,
1088 struct sockaddr_in
*from
,
1089 struct connected
*ifc
)
1093 struct prefix_ipv4 ifaddr
;
1094 struct prefix_ipv4 ifaddrclass
;
1097 memset(&ifaddr
, 0, sizeof(ifaddr
));
1098 /* We don't know yet. */
1101 /* The Response must be ignored if it is not from the RIP
1102 port. (RFC2453 - Sec. 3.9.2)*/
1103 if (from
->sin_port
!= htons(RIP_PORT_DEFAULT
)) {
1104 zlog_info("response doesn't come from RIP port: %d",
1106 rip_peer_bad_packet(from
);
1110 /* The datagram's IPv4 source address should be checked to see
1111 whether the datagram is from a valid neighbor; the source of the
1112 datagram must be on a directly connected network (RFC2453 - Sec.
1114 if (if_lookup_address((void *)&from
->sin_addr
, AF_INET
, VRF_DEFAULT
)
1117 "This datagram doesn't came from a valid neighbor: %s",
1118 inet_ntoa(from
->sin_addr
));
1119 rip_peer_bad_packet(from
);
1123 /* It is also worth checking to see whether the response is from one
1124 of the router's own addresses. */
1126 ; /* Alredy done in rip_read () */
1128 /* Update RIP peer. */
1129 rip_peer_update(from
, packet
->version
);
1131 /* Set RTE pointer. */
1134 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
1135 /* RIPv2 authentication check. */
1136 /* If the Address Family Identifier of the first (and only the
1137 first) entry in the message is 0xFFFF, then the remainder of
1138 the entry contains the authentication. */
1139 /* If the packet gets here it means authentication enabled */
1140 /* Check is done in rip_read(). So, just skipping it */
1141 if (packet
->version
== RIPv2
&& rte
== packet
->rte
1142 && rte
->family
== htons(RIP_FAMILY_AUTH
))
1145 if (rte
->family
!= htons(AF_INET
)) {
1146 /* Address family check. RIP only supports AF_INET. */
1147 zlog_info("Unsupported family %d from %s.",
1149 inet_ntoa(from
->sin_addr
));
1153 /* - is the destination address valid (e.g., unicast; not net 0
1155 if (!rip_destination_check(rte
->prefix
)) {
1157 "Network is net 0 or net 127 or it is not unicast network");
1158 rip_peer_bad_route(from
);
1162 /* Convert metric value to host byte order. */
1163 rte
->metric
= ntohl(rte
->metric
);
1165 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1166 if (!(rte
->metric
>= 1 && rte
->metric
<= 16)) {
1167 zlog_info("Route's metric is not in the 1-16 range.");
1168 rip_peer_bad_route(from
);
1172 /* RIPv1 does not have nexthop value. */
1173 if (packet
->version
== RIPv1
&& rte
->nexthop
.s_addr
!= 0) {
1174 zlog_info("RIPv1 packet with nexthop value %s",
1175 inet_ntoa(rte
->nexthop
));
1176 rip_peer_bad_route(from
);
1180 /* That is, if the provided information is ignored, a possibly
1181 sub-optimal, but absolutely valid, route may be taken. If
1182 the received Next Hop is not directly reachable, it should be
1183 treated as 0.0.0.0. */
1184 if (packet
->version
== RIPv2
&& rte
->nexthop
.s_addr
!= 0) {
1187 /* Multicast address check. */
1188 addrval
= ntohl(rte
->nexthop
.s_addr
);
1189 if (IN_CLASSD(addrval
)) {
1191 "Nexthop %s is multicast address, skip this rte",
1192 inet_ntoa(rte
->nexthop
));
1196 if (!if_lookup_address((void *)&rte
->nexthop
, AF_INET
,
1198 struct route_node
*rn
;
1199 struct rip_info
*rinfo
;
1201 rn
= route_node_match_ipv4(rip
->table
,
1207 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1210 if (IS_RIP_DEBUG_EVENT
)
1212 "Next hop %s is on RIP network. Set nexthop to the packet's originator",
1215 rte
->nexthop
= rinfo
->from
;
1217 if (IS_RIP_DEBUG_EVENT
)
1219 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1222 rte
->nexthop
.s_addr
= 0;
1225 route_unlock_node(rn
);
1227 if (IS_RIP_DEBUG_EVENT
)
1229 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1232 rte
->nexthop
.s_addr
= 0;
1237 /* For RIPv1, there won't be a valid netmask.
1239 This is a best guess at the masks. If everyone was using old
1240 Ciscos before the 'ip subnet zero' option, it would be almost
1243 Cisco summarize ripv1 advertisments to the classful boundary
1244 (/16 for class B's) except when the RIP packet does to inside
1245 the classful network in question. */
1247 if ((packet
->version
== RIPv1
&& rte
->prefix
.s_addr
!= 0)
1248 || (packet
->version
== RIPv2
1249 && (rte
->prefix
.s_addr
!= 0
1250 && rte
->mask
.s_addr
== 0))) {
1251 u_int32_t destination
;
1253 if (subnetted
== -1) {
1254 memcpy(&ifaddr
, ifc
->address
,
1255 sizeof(struct prefix_ipv4
));
1256 memcpy(&ifaddrclass
, &ifaddr
,
1257 sizeof(struct prefix_ipv4
));
1258 apply_classful_mask_ipv4(&ifaddrclass
);
1260 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1264 destination
= ntohl(rte
->prefix
.s_addr
);
1266 if (IN_CLASSA(destination
))
1267 masklen2ip(8, &rte
->mask
);
1268 else if (IN_CLASSB(destination
))
1269 masklen2ip(16, &rte
->mask
);
1270 else if (IN_CLASSC(destination
))
1271 masklen2ip(24, &rte
->mask
);
1274 masklen2ip(ifaddrclass
.prefixlen
,
1275 (struct in_addr
*)&destination
);
1276 if ((subnetted
== 1)
1277 && ((rte
->prefix
.s_addr
& destination
)
1278 == ifaddrclass
.prefix
.s_addr
)) {
1279 masklen2ip(ifaddr
.prefixlen
, &rte
->mask
);
1280 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1281 != rte
->prefix
.s_addr
)
1282 masklen2ip(32, &rte
->mask
);
1283 if (IS_RIP_DEBUG_EVENT
)
1284 zlog_debug("Subnetted route %s",
1285 inet_ntoa(rte
->prefix
));
1287 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1288 != rte
->prefix
.s_addr
)
1292 if (IS_RIP_DEBUG_EVENT
) {
1293 zlog_debug("Resultant route %s",
1294 inet_ntoa(rte
->prefix
));
1295 zlog_debug("Resultant mask %s",
1296 inet_ntoa(rte
->mask
));
1300 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1301 ignore the entry. */
1302 if ((packet
->version
== RIPv2
) && (rte
->mask
.s_addr
!= 0)
1303 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1304 != rte
->prefix
.s_addr
)) {
1306 "RIPv2 address %s is not mask /%d applied one",
1307 inet_ntoa(rte
->prefix
), ip_masklen(rte
->mask
));
1308 rip_peer_bad_route(from
);
1312 /* Default route's netmask is ignored. */
1313 if (packet
->version
== RIPv2
&& (rte
->prefix
.s_addr
== 0)
1314 && (rte
->mask
.s_addr
!= 0)) {
1315 if (IS_RIP_DEBUG_EVENT
)
1317 "Default route with non-zero netmask. Set zero to netmask");
1318 rte
->mask
.s_addr
= 0;
1321 /* Routing table updates. */
1322 rip_rte_process(rte
, from
, ifc
->ifp
);
1326 /* Make socket for RIP protocol. */
1327 static int rip_create_socket(void)
1331 struct sockaddr_in addr
;
1333 memset(&addr
, 0, sizeof(struct sockaddr_in
));
1334 addr
.sin_family
= AF_INET
;
1335 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1336 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1337 addr
.sin_len
= sizeof(struct sockaddr_in
);
1338 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1339 /* sending port must always be the RIP port */
1340 addr
.sin_port
= htons(RIP_PORT_DEFAULT
);
1342 /* Make datagram socket. */
1343 sock
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
1345 zlog_err("Cannot create UDP socket: %s", safe_strerror(errno
));
1349 sockopt_broadcast(sock
);
1350 sockopt_reuseaddr(sock
);
1351 sockopt_reuseport(sock
);
1352 setsockopt_ipv4_multicast_loop(sock
, 0);
1354 setsockopt_pktinfo(sock
);
1355 #endif /* RIP_RECVMSG */
1356 #ifdef IPTOS_PREC_INTERNETCONTROL
1357 setsockopt_ipv4_tos(sock
, IPTOS_PREC_INTERNETCONTROL
);
1360 if (ripd_privs
.change(ZPRIVS_RAISE
))
1361 zlog_err("rip_create_socket: could not raise privs");
1362 setsockopt_so_recvbuf(sock
, RIP_UDP_RCV_BUF
);
1363 if ((ret
= bind(sock
, (struct sockaddr
*)&addr
, sizeof(addr
))) < 0)
1366 int save_errno
= errno
;
1367 if (ripd_privs
.change(ZPRIVS_LOWER
))
1368 zlog_err("rip_create_socket: could not lower privs");
1370 zlog_err("%s: Can't bind socket %d to %s port %d: %s", __func__
,
1371 sock
, inet_ntoa(addr
.sin_addr
),
1372 (int)ntohs(addr
.sin_port
), safe_strerror(save_errno
));
1378 if (ripd_privs
.change(ZPRIVS_LOWER
))
1379 zlog_err("rip_create_socket: could not lower privs");
1384 /* RIP packet send to destination address, on interface denoted by
1385 * by connected argument. NULL to argument denotes destination should be
1386 * should be RIP multicast group
1388 static int rip_send_packet(u_char
*buf
, int size
, struct sockaddr_in
*to
,
1389 struct connected
*ifc
)
1392 struct sockaddr_in sin
;
1394 assert(ifc
!= NULL
);
1396 if (IS_RIP_DEBUG_PACKET
) {
1397 #define ADDRESS_SIZE 20
1398 char dst
[ADDRESS_SIZE
];
1399 dst
[ADDRESS_SIZE
- 1] = '\0';
1402 strncpy(dst
, inet_ntoa(to
->sin_addr
), ADDRESS_SIZE
- 1);
1404 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1405 strncpy(dst
, inet_ntoa(sin
.sin_addr
), ADDRESS_SIZE
- 1);
1408 zlog_debug("rip_send_packet %s > %s (%s)",
1409 inet_ntoa(ifc
->address
->u
.prefix4
), dst
,
1413 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
1415 * ZEBRA_IFA_SECONDARY is set on linux when an interface is
1417 * with multiple addresses on the same subnet: the first address
1418 * on the subnet is configured "primary", and all subsequent
1420 * on that subnet are treated as "secondary" addresses.
1421 * In order to avoid routing-table bloat on other rip listeners,
1422 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY
1424 * XXX Since Linux is the only system for which the
1425 * ZEBRA_IFA_SECONDARY
1426 * flag is set, we would end up sending a packet for a
1428 * source address on non-linux systems.
1430 if (IS_RIP_DEBUG_PACKET
)
1431 zlog_debug("duplicate dropped");
1435 /* Make destination address. */
1436 memset(&sin
, 0, sizeof(struct sockaddr_in
));
1437 sin
.sin_family
= AF_INET
;
1438 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1439 sin
.sin_len
= sizeof(struct sockaddr_in
);
1440 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1442 /* When destination is specified, use it's port and address. */
1444 sin
.sin_port
= to
->sin_port
;
1445 sin
.sin_addr
= to
->sin_addr
;
1447 sin
.sin_port
= htons(RIP_PORT_DEFAULT
);
1448 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1450 rip_interface_multicast_set(rip
->sock
, ifc
);
1453 ret
= sendto(rip
->sock
, buf
, size
, 0, (struct sockaddr
*)&sin
,
1454 sizeof(struct sockaddr_in
));
1456 if (IS_RIP_DEBUG_EVENT
)
1457 zlog_debug("SEND to %s.%d", inet_ntoa(sin
.sin_addr
),
1458 ntohs(sin
.sin_port
));
1461 zlog_warn("can't send packet : %s", safe_strerror(errno
));
1466 /* Add redistributed route to RIP table. */
1467 void rip_redistribute_add(int type
, int sub_type
, struct prefix_ipv4
*p
,
1468 ifindex_t ifindex
, struct in_addr
*nexthop
,
1469 unsigned int metric
, unsigned char distance
,
1473 struct route_node
*rp
= NULL
;
1474 struct rip_info
*rinfo
= NULL
, newinfo
;
1475 struct list
*list
= NULL
;
1477 /* Redistribute route */
1478 ret
= rip_destination_check(p
->prefix
);
1482 rp
= route_node_get(rip
->table
, (struct prefix
*)p
);
1484 memset(&newinfo
, 0, sizeof(struct rip_info
));
1485 newinfo
.type
= type
;
1486 newinfo
.sub_type
= sub_type
;
1487 newinfo
.ifindex
= ifindex
;
1489 newinfo
.external_metric
= metric
;
1490 newinfo
.distance
= distance
;
1491 if (tag
<= UINT16_MAX
) /* RIP only supports 16 bit tags */
1495 newinfo
.nexthop
= *nexthop
;
1497 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
1498 rinfo
= listgetdata(listhead(list
));
1500 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
1501 && rinfo
->sub_type
== RIP_ROUTE_INTERFACE
1502 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
1503 route_unlock_node(rp
);
1507 /* Manually configured RIP route check. */
1508 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1509 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
1510 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))) {
1511 if (type
!= ZEBRA_ROUTE_RIP
1512 || ((sub_type
!= RIP_ROUTE_STATIC
)
1513 && (sub_type
!= RIP_ROUTE_DEFAULT
))) {
1514 route_unlock_node(rp
);
1519 rinfo
= rip_ecmp_replace(&newinfo
);
1520 route_unlock_node(rp
);
1522 rinfo
= rip_ecmp_add(&newinfo
);
1524 if (IS_RIP_DEBUG_EVENT
) {
1527 "Redistribute new prefix %s/%d on the interface %s",
1528 inet_ntoa(p
->prefix
), p
->prefixlen
,
1529 ifindex2ifname(ifindex
, VRF_DEFAULT
));
1532 "Redistribute new prefix %s/%d with nexthop %s on the interface %s",
1533 inet_ntoa(p
->prefix
), p
->prefixlen
,
1534 inet_ntoa(rinfo
->nexthop
),
1535 ifindex2ifname(ifindex
, VRF_DEFAULT
));
1538 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1541 /* Delete redistributed route from RIP table. */
1542 void rip_redistribute_delete(int type
, int sub_type
, struct prefix_ipv4
*p
,
1546 struct route_node
*rp
;
1547 struct rip_info
*rinfo
;
1549 ret
= rip_destination_check(p
->prefix
);
1553 rp
= route_node_lookup(rip
->table
, (struct prefix
*)p
);
1555 struct list
*list
= rp
->info
;
1557 if (list
!= NULL
&& listcount(list
) != 0) {
1558 rinfo
= listgetdata(listhead(list
));
1559 if (rinfo
!= NULL
&& rinfo
->type
== type
1560 && rinfo
->sub_type
== sub_type
1561 && rinfo
->ifindex
== ifindex
) {
1562 /* Perform poisoned reverse. */
1563 rinfo
->metric
= RIP_METRIC_INFINITY
;
1564 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
1565 rip_garbage_collect
,
1567 RIP_TIMER_OFF(rinfo
->t_timeout
);
1568 rinfo
->flags
|= RIP_RTF_CHANGED
;
1570 if (IS_RIP_DEBUG_EVENT
)
1572 "Poisone %s/%d on the interface %s with an "
1573 "infinity metric [delete]",
1574 inet_ntoa(p
->prefix
),
1576 ifindex2ifname(ifindex
,
1579 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1582 route_unlock_node(rp
);
1586 /* Response to request called from rip_read ().*/
1587 static void rip_request_process(struct rip_packet
*packet
, int size
,
1588 struct sockaddr_in
*from
, struct connected
*ifc
)
1592 struct prefix_ipv4 p
;
1593 struct route_node
*rp
;
1594 struct rip_info
*rinfo
;
1595 struct rip_interface
*ri
;
1597 /* Does not reponse to the requests on the loopback interfaces */
1598 if (if_is_loopback(ifc
->ifp
))
1601 /* Check RIP process is enabled on this interface. */
1602 ri
= ifc
->ifp
->info
;
1606 /* When passive interface is specified, suppress responses */
1610 /* RIP peer update. */
1611 rip_peer_update(from
, packet
->version
);
1613 lim
= ((caddr_t
)packet
) + size
;
1616 /* The Request is processed entry by entry. If there are no
1617 entries, no response is given. */
1618 if (lim
== (caddr_t
)rte
)
1621 /* There is one special case. If there is exactly one entry in the
1622 request, and it has an address family identifier of zero and a
1623 metric of infinity (i.e., 16), then this is a request to send the
1624 entire routing table. */
1625 if (lim
== ((caddr_t
)(rte
+ 1)) && ntohs(rte
->family
) == 0
1626 && ntohl(rte
->metric
) == RIP_METRIC_INFINITY
) {
1627 /* All route with split horizon */
1628 rip_output_process(ifc
, from
, rip_all_route
, packet
->version
);
1630 if (ntohs(rte
->family
) != AF_INET
)
1633 /* Examine the list of RTEs in the Request one by one. For each
1634 entry, look up the destination in the router's routing
1635 database and, if there is a route, put that route's metric in
1636 the metric field of the RTE. If there is no explicit route
1637 to the specified destination, put infinity in the metric
1638 field. Once all the entries have been filled in, change the
1639 command from Request to Response and send the datagram back
1640 to the requestor. */
1643 for (; ((caddr_t
)rte
) < lim
; rte
++) {
1644 p
.prefix
= rte
->prefix
;
1645 p
.prefixlen
= ip_masklen(rte
->mask
);
1646 apply_mask_ipv4(&p
);
1648 rp
= route_node_lookup(rip
->table
, (struct prefix
*)&p
);
1650 rinfo
= listgetdata(
1651 listhead((struct list
*)rp
->info
));
1652 rte
->metric
= htonl(rinfo
->metric
);
1653 route_unlock_node(rp
);
1655 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
1657 packet
->command
= RIP_RESPONSE
;
1659 rip_send_packet((u_char
*)packet
, size
, from
, ifc
);
1661 rip_global_queries
++;
1665 /* Set IPv6 packet info to the socket. */
1666 static int setsockopt_pktinfo(int sock
)
1671 ret
= setsockopt(sock
, IPPROTO_IP
, IP_PKTINFO
, &val
, sizeof(val
));
1673 zlog_warn("Can't setsockopt IP_PKTINFO : %s",
1674 safe_strerror(errno
));
1678 /* Read RIP packet by recvmsg function. */
1679 int rip_recvmsg(int sock
, u_char
*buf
, int size
, struct sockaddr_in
*from
,
1685 struct cmsghdr
*ptr
;
1688 memset(&msg
, 0, sizeof(msg
));
1689 msg
.msg_name
= (void *)from
;
1690 msg
.msg_namelen
= sizeof(struct sockaddr_in
);
1693 msg
.msg_control
= (void *)adata
;
1694 msg
.msg_controllen
= sizeof adata
;
1698 ret
= recvmsg(sock
, &msg
, 0);
1702 for (ptr
= ZCMSG_FIRSTHDR(&msg
); ptr
!= NULL
;
1703 ptr
= CMSG_NXTHDR(&msg
, ptr
))
1704 if (ptr
->cmsg_level
== IPPROTO_IP
1705 && ptr
->cmsg_type
== IP_PKTINFO
) {
1706 struct in_pktinfo
*pktinfo
;
1709 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(ptr
);
1710 i
= pktinfo
->ipi_ifindex
;
1715 /* RIP packet read function. */
1716 int rip_read_new(struct thread
*t
)
1720 char buf
[RIP_PACKET_MAXSIZ
];
1721 struct sockaddr_in from
;
1724 /* Fetch socket then register myself. */
1725 sock
= THREAD_FD(t
);
1726 rip_event(RIP_READ
, sock
);
1728 /* Read RIP packet. */
1729 ret
= rip_recvmsg(sock
, buf
, RIP_PACKET_MAXSIZ
, &from
, (int *)&ifindex
);
1731 zlog_warn("Can't read RIP packet: %s", safe_strerror(errno
));
1737 #endif /* RIP_RECVMSG */
1739 /* First entry point of RIP packet. */
1740 static int rip_read(struct thread
*t
)
1745 union rip_buf rip_buf
;
1746 struct rip_packet
*packet
;
1747 struct sockaddr_in from
;
1751 struct interface
*ifp
= NULL
;
1752 struct connected
*ifc
;
1753 struct rip_interface
*ri
;
1756 /* Fetch socket then register myself. */
1757 sock
= THREAD_FD(t
);
1760 /* Add myself to tne next event */
1761 rip_event(RIP_READ
, sock
);
1763 /* RIPd manages only IPv4. */
1764 memset(&from
, 0, sizeof(struct sockaddr_in
));
1765 fromlen
= sizeof(struct sockaddr_in
);
1767 len
= recvfrom(sock
, (char *)&rip_buf
.buf
, sizeof(rip_buf
.buf
), 0,
1768 (struct sockaddr
*)&from
, &fromlen
);
1770 zlog_info("recvfrom failed: %s", safe_strerror(errno
));
1774 /* Check is this packet comming from myself? */
1775 if (if_check_address(from
.sin_addr
)) {
1776 if (IS_RIP_DEBUG_PACKET
)
1777 zlog_debug("ignore packet comes from myself");
1781 /* Which interface is this packet comes from. */
1782 ifc
= if_lookup_address((void *)&from
.sin_addr
, AF_INET
, VRF_DEFAULT
);
1786 /* RIP packet received */
1787 if (IS_RIP_DEBUG_EVENT
)
1788 zlog_debug("RECV packet from %s port %d on %s",
1789 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1790 ifp
? ifp
->name
: "unknown");
1792 /* If this packet come from unknown interface, ignore it. */
1795 "rip_read: cannot find interface for packet from %s port %d",
1796 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
));
1801 p
.u
.prefix4
= from
.sin_addr
;
1802 p
.prefixlen
= IPV4_MAX_BITLEN
;
1804 ifc
= connected_lookup_prefix(ifp
, &p
);
1808 "rip_read: cannot find connected address for packet from %s "
1809 "port %d on interface %s",
1810 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1815 /* Packet length check. */
1816 if (len
< RIP_PACKET_MINSIZ
) {
1817 zlog_warn("packet size %d is smaller than minimum size %d", len
,
1819 rip_peer_bad_packet(&from
);
1822 if (len
> RIP_PACKET_MAXSIZ
) {
1823 zlog_warn("packet size %d is larger than max size %d", len
,
1825 rip_peer_bad_packet(&from
);
1829 /* Packet alignment check. */
1830 if ((len
- RIP_PACKET_MINSIZ
) % 20) {
1831 zlog_warn("packet size %d is wrong for RIP packet alignment",
1833 rip_peer_bad_packet(&from
);
1837 /* Set RTE number. */
1838 rtenum
= ((len
- RIP_PACKET_MINSIZ
) / 20);
1840 /* For easy to handle. */
1841 packet
= &rip_buf
.rip_packet
;
1843 /* RIP version check. */
1844 if (packet
->version
== 0) {
1845 zlog_info("version 0 with command %d received.",
1847 rip_peer_bad_packet(&from
);
1851 /* Dump RIP packet. */
1852 if (IS_RIP_DEBUG_RECV
)
1853 rip_packet_dump(packet
, len
, "RECV");
1855 /* RIP version adjust. This code should rethink now. RFC1058 says
1856 that "Version 1 implementations are to ignore this extra data and
1857 process only the fields specified in this document.". So RIPv3
1858 packet should be treated as RIPv1 ignoring must be zero field. */
1859 if (packet
->version
> RIPv2
)
1860 packet
->version
= RIPv2
;
1862 /* Is RIP running or is this RIP neighbor ?*/
1864 if (!ri
->running
&& !rip_neighbor_lookup(&from
)) {
1865 if (IS_RIP_DEBUG_EVENT
)
1866 zlog_debug("RIP is not enabled on interface %s.",
1868 rip_peer_bad_packet(&from
);
1872 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1873 vrecv
= ((ri
->ri_receive
== RI_RIP_UNSPEC
) ? rip
->version_recv
1875 if (vrecv
== RI_RIP_VERSION_NONE
1876 || ((packet
->version
== RIPv1
) && !(vrecv
& RIPv1
))
1877 || ((packet
->version
== RIPv2
) && !(vrecv
& RIPv2
))) {
1878 if (IS_RIP_DEBUG_PACKET
)
1880 " packet's v%d doesn't fit to if version spec",
1882 rip_peer_bad_packet(&from
);
1886 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1887 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1888 accepted; authenticated RIP-2 messages shall be discarded. */
1889 if ((ri
->auth_type
== RIP_NO_AUTH
) && rtenum
1890 && (packet
->version
== RIPv2
)
1891 && (packet
->rte
->family
== htons(RIP_FAMILY_AUTH
))) {
1892 if (IS_RIP_DEBUG_EVENT
)
1894 "packet RIPv%d is dropped because authentication disabled",
1896 rip_peer_bad_packet(&from
);
1901 If the router is configured to authenticate RIP-2 messages, then
1902 RIP-1 messages and RIP-2 messages which pass authentication
1903 testing shall be accepted; unauthenticated and failed
1904 authentication RIP-2 messages shall be discarded. For maximum
1905 security, RIP-1 messages should be ignored when authentication is
1906 in use (see section 4.1); otherwise, the routing information from
1907 authenticated messages will be propagated by RIP-1 routers in an
1908 unauthenticated manner.
1910 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1911 * always reply regardless of authentication settings, because:
1913 * - if there other authorised routers on-link, the REQUESTor can
1914 * passively obtain the routing updates anyway
1915 * - if there are no other authorised routers on-link, RIP can
1916 * easily be disabled for the link to prevent giving out information
1917 * on state of this routers RIP routing table..
1919 * I.e. if RIPv1 has any place anymore these days, it's as a very
1920 * simple way to distribute routing information (e.g. to embedded
1921 * hosts / appliances) and the ability to give out RIPv1
1922 * routing-information freely, while still requiring RIPv2
1923 * authentication for any RESPONSEs might be vaguely useful.
1925 if (ri
->auth_type
!= RIP_NO_AUTH
&& packet
->version
== RIPv1
) {
1926 /* Discard RIPv1 messages other than REQUESTs */
1927 if (packet
->command
!= RIP_REQUEST
) {
1928 if (IS_RIP_DEBUG_PACKET
)
1931 " dropped because authentication enabled");
1932 rip_peer_bad_packet(&from
);
1935 } else if (ri
->auth_type
!= RIP_NO_AUTH
) {
1936 const char *auth_desc
;
1939 /* There definitely is no authentication in the packet.
1941 if (IS_RIP_DEBUG_PACKET
)
1943 "RIPv2 authentication failed: no auth RTE in packet");
1944 rip_peer_bad_packet(&from
);
1948 /* First RTE must be an Authentication Family RTE */
1949 if (packet
->rte
->family
!= htons(RIP_FAMILY_AUTH
)) {
1950 if (IS_RIP_DEBUG_PACKET
)
1953 " dropped because authentication enabled");
1954 rip_peer_bad_packet(&from
);
1958 /* Check RIPv2 authentication. */
1959 switch (ntohs(packet
->rte
->tag
)) {
1960 case RIP_AUTH_SIMPLE_PASSWORD
:
1961 auth_desc
= "simple";
1962 ret
= rip_auth_simple_password(packet
->rte
, &from
, ifp
);
1967 ret
= rip_auth_md5(packet
, &from
, len
, ifp
);
1968 /* Reset RIP packet length to trim MD5 data. */
1974 auth_desc
= "unknown type";
1975 if (IS_RIP_DEBUG_PACKET
)
1977 "RIPv2 Unknown authentication type %d",
1978 ntohs(packet
->rte
->tag
));
1982 if (IS_RIP_DEBUG_PACKET
)
1983 zlog_debug("RIPv2 %s authentication success",
1986 if (IS_RIP_DEBUG_PACKET
)
1987 zlog_debug("RIPv2 %s authentication failure",
1989 rip_peer_bad_packet(&from
);
1994 /* Process each command. */
1995 switch (packet
->command
) {
1997 rip_response_process(packet
, len
, &from
, ifc
);
2001 rip_request_process(packet
, len
, &from
, ifc
);
2006 "Obsolete command %s received, please sent it to routed",
2007 lookup_msg(rip_msg
, packet
->command
, NULL
));
2008 rip_peer_bad_packet(&from
);
2010 case RIP_POLL_ENTRY
:
2011 zlog_info("Obsolete command %s received",
2012 lookup_msg(rip_msg
, packet
->command
, NULL
));
2013 rip_peer_bad_packet(&from
);
2016 zlog_info("Unknown RIP command %d received", packet
->command
);
2017 rip_peer_bad_packet(&from
);
2024 /* Write routing table entry to the stream and return next index of
2025 the routing table entry in the stream. */
2026 static int rip_write_rte(int num
, struct stream
*s
, struct prefix_ipv4
*p
,
2027 u_char version
, struct rip_info
*rinfo
)
2029 struct in_addr mask
;
2031 /* Write routing table entry. */
2032 if (version
== RIPv1
) {
2033 stream_putw(s
, AF_INET
);
2035 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2036 stream_put_ipv4(s
, 0);
2037 stream_put_ipv4(s
, 0);
2038 stream_putl(s
, rinfo
->metric_out
);
2040 masklen2ip(p
->prefixlen
, &mask
);
2042 stream_putw(s
, AF_INET
);
2043 stream_putw(s
, rinfo
->tag_out
);
2044 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2045 stream_put_ipv4(s
, mask
.s_addr
);
2046 stream_put_ipv4(s
, rinfo
->nexthop_out
.s_addr
);
2047 stream_putl(s
, rinfo
->metric_out
);
2053 /* Send update to the ifp or spcified neighbor. */
2054 void rip_output_process(struct connected
*ifc
, struct sockaddr_in
*to
,
2055 int route_type
, u_char version
)
2059 struct route_node
*rp
;
2060 struct rip_info
*rinfo
;
2061 struct rip_interface
*ri
;
2062 struct prefix_ipv4
*p
;
2063 struct prefix_ipv4 classfull
;
2064 struct prefix_ipv4 ifaddrclass
;
2065 struct key
*key
= NULL
;
2066 /* this might need to made dynamic if RIP ever supported auth methods
2067 with larger key string sizes */
2068 char auth_str
[RIP_AUTH_SIMPLE_SIZE
];
2069 size_t doff
= 0; /* offset of digest offset field */
2073 struct list
*list
= NULL
;
2074 struct listnode
*listnode
= NULL
;
2076 /* Logging output event. */
2077 if (IS_RIP_DEBUG_EVENT
) {
2079 zlog_debug("update routes to neighbor %s",
2080 inet_ntoa(to
->sin_addr
));
2082 zlog_debug("update routes on interface %s ifindex %d",
2083 ifc
->ifp
->name
, ifc
->ifp
->ifindex
);
2086 /* Set output stream. */
2089 /* Reset stream and RTE counter. */
2091 rtemax
= RIP_MAX_RTE
;
2093 /* Get RIP interface. */
2094 ri
= ifc
->ifp
->info
;
2096 /* If output interface is in simple password authentication mode, we
2097 need space for authentication data. */
2098 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2101 /* If output interface is in MD5 authentication mode, we need space
2102 for authentication header and data. */
2103 if (ri
->auth_type
== RIP_AUTH_MD5
)
2106 /* If output interface is in simple password authentication mode
2107 and string or keychain is specified we need space for auth. data */
2108 if (ri
->auth_type
!= RIP_NO_AUTH
) {
2109 if (ri
->key_chain
) {
2110 struct keychain
*keychain
;
2112 keychain
= keychain_lookup(ri
->key_chain
);
2114 key
= key_lookup_for_send(keychain
);
2116 /* to be passed to auth functions later */
2117 rip_auth_prepare_str_send(ri
, key
, auth_str
,
2118 RIP_AUTH_SIMPLE_SIZE
);
2121 if (version
== RIPv1
) {
2122 memcpy(&ifaddrclass
, ifc
->address
, sizeof(struct prefix_ipv4
));
2123 apply_classful_mask_ipv4(&ifaddrclass
);
2125 if (ifc
->address
->prefixlen
> ifaddrclass
.prefixlen
)
2129 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2130 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
2131 rinfo
= listgetdata(listhead(list
));
2132 /* For RIPv1, if we are subnetted, output subnets in our
2134 /* that have the same mask as the output "interface".
2136 /* networks, only the classfull version is output. */
2138 if (version
== RIPv1
) {
2139 p
= (struct prefix_ipv4
*)&rp
->p
;
2141 if (IS_RIP_DEBUG_PACKET
)
2143 "RIPv1 mask check, %s/%d considered for output",
2144 inet_ntoa(rp
->p
.u
.prefix4
),
2149 (struct prefix
*)&ifaddrclass
,
2151 if ((ifc
->address
->prefixlen
2153 && (rp
->p
.prefixlen
!= 32))
2156 memcpy(&classfull
, &rp
->p
,
2157 sizeof(struct prefix_ipv4
));
2158 apply_classful_mask_ipv4(&classfull
);
2159 if (rp
->p
.u
.prefix4
.s_addr
!= 0
2160 && classfull
.prefixlen
2164 if (IS_RIP_DEBUG_PACKET
)
2166 "RIPv1 mask check, %s/%d made it through",
2167 inet_ntoa(rp
->p
.u
.prefix4
),
2170 p
= (struct prefix_ipv4
*)&rp
->p
;
2172 /* Apply output filters. */
2173 ret
= rip_filter(RIP_FILTER_OUT
, p
, ri
);
2177 /* Changed route only output. */
2178 if (route_type
== rip_changed_route
2179 && (!(rinfo
->flags
& RIP_RTF_CHANGED
)))
2182 /* Split horizon. */
2183 /* if (split_horizon == rip_split_horizon) */
2184 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
) {
2186 * We perform split horizon for RIP and
2188 * For rip routes, we want to suppress the route
2190 * end up sending the route back on the
2192 * learned it from, with a higher metric. For
2194 * we suppress the route if the prefix is a
2196 * source address that we are going to use for
2198 * (in order to handle the case when multiple
2200 * configured on the same interface).
2203 struct rip_info
*tmp_rinfo
= NULL
;
2205 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2207 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2208 && tmp_rinfo
->ifindex
2209 == ifc
->ifp
->ifindex
) {
2215 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
2216 && prefix_match((struct prefix
*)p
,
2224 /* Preparation for route-map. */
2225 rinfo
->metric_set
= 0;
2226 rinfo
->nexthop_out
.s_addr
= 0;
2227 rinfo
->metric_out
= rinfo
->metric
;
2228 rinfo
->tag_out
= rinfo
->tag
;
2229 rinfo
->ifindex_out
= ifc
->ifp
->ifindex
;
2231 /* In order to avoid some local loops,
2232 * if the RIP route has a nexthop via this interface,
2234 * otherwise set it to 0. The nexthop should not be
2236 * beyond the local broadcast/multicast area in order
2237 * to avoid an IGP multi-level recursive look-up.
2240 if (rinfo
->ifindex
== ifc
->ifp
->ifindex
)
2241 rinfo
->nexthop_out
= rinfo
->nexthop
;
2243 /* Interface route-map */
2244 if (ri
->routemap
[RIP_FILTER_OUT
]) {
2245 ret
= route_map_apply(
2246 ri
->routemap
[RIP_FILTER_OUT
],
2247 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2249 if (ret
== RMAP_DENYMATCH
) {
2250 if (IS_RIP_DEBUG_PACKET
)
2252 "RIP %s/%d is filtered by route-map out",
2253 inet_ntoa(p
->prefix
),
2259 /* Apply redistribute route map - continue, if deny */
2260 if (rip
->route_map
[rinfo
->type
].name
2261 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2262 ret
= route_map_apply(
2263 rip
->route_map
[rinfo
->type
].map
,
2264 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2266 if (ret
== RMAP_DENYMATCH
) {
2267 if (IS_RIP_DEBUG_PACKET
)
2269 "%s/%d is filtered by route-map",
2270 inet_ntoa(p
->prefix
),
2276 /* When route-map does not set metric. */
2277 if (!rinfo
->metric_set
) {
2278 /* If redistribute metric is set. */
2279 if (rip
->route_map
[rinfo
->type
].metric_config
2280 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
2282 rip
->route_map
[rinfo
->type
]
2285 /* If the route is not connected or
2287 one, use default-metric value*/
2288 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2290 != ZEBRA_ROUTE_CONNECT
2292 != RIP_METRIC_INFINITY
)
2294 rip
->default_metric
;
2298 /* Apply offset-list */
2299 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2300 rip_offset_list_apply_out(p
, ifc
->ifp
,
2301 &rinfo
->metric_out
);
2303 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2304 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2306 /* Perform split-horizon with poisoned reverse
2307 * for RIP and connected routes.
2309 if (ri
->split_horizon
2310 == RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2312 * We perform split horizon for RIP and
2314 * For rip routes, we want to suppress the route
2316 * end up sending the route back on the
2318 * learned it from, with a higher metric. For
2320 * we suppress the route if the prefix is a
2322 * source address that we are going to use for
2324 * (in order to handle the case when multiple
2326 * configured on the same interface).
2328 struct rip_info
*tmp_rinfo
= NULL
;
2330 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2332 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2333 && tmp_rinfo
->ifindex
2334 == ifc
->ifp
->ifindex
)
2336 RIP_METRIC_INFINITY
;
2337 if (tmp_rinfo
->type
== ZEBRA_ROUTE_CONNECT
2338 && prefix_match((struct prefix
*)p
,
2340 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2343 /* Prepare preamble, auth headers, if needs be */
2345 stream_putc(s
, RIP_RESPONSE
);
2346 stream_putc(s
, version
);
2349 /* auth header for !v1 && !no_auth */
2350 if ((ri
->auth_type
!= RIP_NO_AUTH
)
2351 && (version
!= RIPv1
))
2352 doff
= rip_auth_header_write(
2353 s
, ri
, key
, auth_str
,
2354 RIP_AUTH_SIMPLE_SIZE
);
2357 /* Write RTE to the stream. */
2358 num
= rip_write_rte(num
, s
, p
, version
, rinfo
);
2359 if (num
== rtemax
) {
2360 if (version
== RIPv2
2361 && ri
->auth_type
== RIP_AUTH_MD5
)
2362 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2363 RIP_AUTH_SIMPLE_SIZE
);
2365 ret
= rip_send_packet(STREAM_DATA(s
),
2366 stream_get_endp(s
), to
,
2369 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2370 rip_packet_dump((struct rip_packet
*)
2379 /* Flush unwritten RTE. */
2381 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2382 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2383 RIP_AUTH_SIMPLE_SIZE
);
2385 ret
= rip_send_packet(STREAM_DATA(s
), stream_get_endp(s
), to
,
2388 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2389 rip_packet_dump((struct rip_packet
*)STREAM_DATA(s
),
2390 stream_get_endp(s
), "SEND");
2394 /* Statistics updates. */
2398 /* Send RIP packet to the interface. */
2399 static void rip_update_interface(struct connected
*ifc
, u_char version
,
2402 struct interface
*ifp
= ifc
->ifp
;
2403 struct rip_interface
*ri
= ifp
->info
;
2404 struct sockaddr_in to
;
2406 /* When RIP version is 2 and multicast enable interface. */
2407 if (version
== RIPv2
&& !ri
->v2_broadcast
&& if_is_multicast(ifp
)) {
2408 if (IS_RIP_DEBUG_EVENT
)
2409 zlog_debug("multicast announce on %s ", ifp
->name
);
2411 rip_output_process(ifc
, NULL
, route_type
, version
);
2415 /* If we can't send multicast packet, send it with unicast. */
2416 if (if_is_broadcast(ifp
) || if_is_pointopoint(ifp
)) {
2417 if (ifc
->address
->family
== AF_INET
) {
2418 /* Destination address and port setting. */
2419 memset(&to
, 0, sizeof(struct sockaddr_in
));
2420 if (ifc
->destination
)
2421 /* use specified broadcast or peer destination
2423 to
.sin_addr
= ifc
->destination
->u
.prefix4
;
2424 else if (ifc
->address
->prefixlen
< IPV4_MAX_PREFIXLEN
)
2425 /* calculate the appropriate broadcast address
2427 to
.sin_addr
.s_addr
= ipv4_broadcast_addr(
2428 ifc
->address
->u
.prefix4
.s_addr
,
2429 ifc
->address
->prefixlen
);
2431 /* do not know where to send the packet */
2433 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2435 if (IS_RIP_DEBUG_EVENT
)
2436 zlog_debug("%s announce to %s on %s",
2437 CONNECTED_PEER(ifc
) ? "unicast"
2439 inet_ntoa(to
.sin_addr
), ifp
->name
);
2441 rip_output_process(ifc
, &to
, route_type
, version
);
2446 /* Update send to all interface and neighbor. */
2447 static void rip_update_process(int route_type
)
2449 struct listnode
*node
;
2450 struct listnode
*ifnode
, *ifnnode
;
2451 struct connected
*connected
;
2452 struct interface
*ifp
;
2453 struct rip_interface
*ri
;
2454 struct route_node
*rp
;
2455 struct sockaddr_in to
;
2458 /* Send RIP update to each interface. */
2459 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
)) {
2460 if (if_is_loopback(ifp
))
2463 if (!if_is_operative(ifp
))
2466 /* Fetch RIP interface information. */
2469 /* When passive interface is specified, suppress announce to the
2476 * If there is no version configuration in the
2478 * use rip's version setting.
2480 int vsend
= ((ri
->ri_send
== RI_RIP_UNSPEC
)
2484 if (IS_RIP_DEBUG_EVENT
)
2485 zlog_debug("SEND UPDATE to %s ifindex %d",
2486 ifp
->name
, ifp
->ifindex
);
2488 /* send update on each connected network */
2489 for (ALL_LIST_ELEMENTS(ifp
->connected
, ifnode
, ifnnode
,
2491 if (connected
->address
->family
== AF_INET
) {
2493 rip_update_interface(
2497 && if_is_multicast(ifp
))
2498 rip_update_interface(
2506 /* RIP send updates to each neighbor. */
2507 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
2508 if (rp
->info
!= NULL
) {
2511 connected
= if_lookup_address(&p
->u
.prefix4
, AF_INET
,
2515 "Neighbor %s doesnt have connected interface!",
2516 inet_ntoa(p
->u
.prefix4
));
2520 /* Set destination address and port */
2521 memset(&to
, 0, sizeof(struct sockaddr_in
));
2522 to
.sin_addr
= p
->u
.prefix4
;
2523 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2525 /* RIP version is rip's configuration. */
2526 rip_output_process(connected
, &to
, route_type
,
2531 /* RIP's periodical timer. */
2532 static int rip_update(struct thread
*t
)
2534 /* Clear timer pointer. */
2535 rip
->t_update
= NULL
;
2537 if (IS_RIP_DEBUG_EVENT
)
2538 zlog_debug("update timer fire!");
2540 /* Process update output. */
2541 rip_update_process(rip_all_route
);
2543 /* Triggered updates may be suppressed if a regular update is due by
2544 the time the triggered update would be sent. */
2545 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2548 /* Register myself. */
2549 rip_event(RIP_UPDATE_EVENT
, 0);
2554 /* Walk down the RIP routing table then clear changed flag. */
2555 static void rip_clear_changed_flag(void)
2557 struct route_node
*rp
;
2558 struct rip_info
*rinfo
= NULL
;
2559 struct list
*list
= NULL
;
2560 struct listnode
*listnode
= NULL
;
2562 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2563 if ((list
= rp
->info
) != NULL
)
2564 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
2565 UNSET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2566 /* This flag can be set only on the first entry.
2572 /* Triggered update interval timer. */
2573 static int rip_triggered_interval(struct thread
*t
)
2575 int rip_triggered_update(struct thread
*);
2577 rip
->t_triggered_interval
= NULL
;
2581 rip_triggered_update(t
);
2586 /* Execute triggered update. */
2587 static int rip_triggered_update(struct thread
*t
)
2591 /* Clear thred pointer. */
2592 rip
->t_triggered_update
= NULL
;
2594 /* Cancel interval timer. */
2595 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2598 /* Logging triggered update. */
2599 if (IS_RIP_DEBUG_EVENT
)
2600 zlog_debug("triggered update!");
2602 /* Split Horizon processing is done when generating triggered
2603 updates as well as normal updates (see section 2.6). */
2604 rip_update_process(rip_changed_route
);
2606 /* Once all of the triggered updates have been generated, the route
2607 change flags should be cleared. */
2608 rip_clear_changed_flag();
2610 /* After a triggered update is sent, a timer should be set for a
2611 random interval between 1 and 5 seconds. If other changes that
2612 would trigger updates occur before the timer expires, a single
2613 update is triggered when the timer expires. */
2614 interval
= (random() % 5) + 1;
2616 rip
->t_triggered_interval
= NULL
;
2617 thread_add_timer(master
, rip_triggered_interval
, NULL
, interval
,
2618 &rip
->t_triggered_interval
);
2623 /* Withdraw redistributed route. */
2624 void rip_redistribute_withdraw(int type
)
2626 struct route_node
*rp
;
2627 struct rip_info
*rinfo
= NULL
;
2628 struct list
*list
= NULL
;
2633 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2634 if ((list
= rp
->info
) != NULL
) {
2635 rinfo
= listgetdata(listhead(list
));
2636 if (rinfo
->type
== type
2637 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2638 /* Perform poisoned reverse. */
2639 rinfo
->metric
= RIP_METRIC_INFINITY
;
2640 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
2641 rip_garbage_collect
,
2643 RIP_TIMER_OFF(rinfo
->t_timeout
);
2644 rinfo
->flags
|= RIP_RTF_CHANGED
;
2646 if (IS_RIP_DEBUG_EVENT
) {
2647 struct prefix_ipv4
*p
=
2648 (struct prefix_ipv4
*)&rp
->p
;
2651 "Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2652 inet_ntoa(p
->prefix
),
2654 ifindex2ifname(rinfo
->ifindex
,
2658 rip_event(RIP_TRIGGERED_UPDATE
, 0);
2663 /* Create new RIP instance and set it to global variable. */
2664 static int rip_create(void)
2666 rip
= XCALLOC(MTYPE_RIP
, sizeof(struct rip
));
2668 /* Set initial value. */
2669 rip
->version_send
= RI_RIP_VERSION_2
;
2670 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2671 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
2672 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
2673 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
2674 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2676 /* Initialize RIP routig table. */
2677 rip
->table
= route_table_init();
2678 rip
->route
= route_table_init();
2679 rip
->neighbor
= route_table_init();
2681 /* Make output stream. */
2682 rip
->obuf
= stream_new(1500);
2685 rip
->sock
= rip_create_socket();
2689 /* Create read and timer thread. */
2690 rip_event(RIP_READ
, rip
->sock
);
2691 rip_event(RIP_UPDATE_EVENT
, 1);
2698 /* Sned RIP request to the destination. */
2699 int rip_request_send(struct sockaddr_in
*to
, struct interface
*ifp
,
2700 u_char version
, struct connected
*connected
)
2703 struct rip_packet rip_packet
;
2704 struct listnode
*node
, *nnode
;
2706 memset(&rip_packet
, 0, sizeof(rip_packet
));
2708 rip_packet
.command
= RIP_REQUEST
;
2709 rip_packet
.version
= version
;
2710 rte
= rip_packet
.rte
;
2711 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
2715 * connected is only sent for ripv1 case, or when
2716 * interface does not support multicast. Caller loops
2717 * over each connected address for this case.
2719 if (rip_send_packet((u_char
*)&rip_packet
, sizeof(rip_packet
),
2721 != sizeof(rip_packet
))
2724 return sizeof(rip_packet
);
2727 /* send request on each connected network */
2728 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, connected
)) {
2729 struct prefix_ipv4
*p
;
2731 p
= (struct prefix_ipv4
*)connected
->address
;
2733 if (p
->family
!= AF_INET
)
2736 if (rip_send_packet((u_char
*)&rip_packet
, sizeof(rip_packet
),
2738 != sizeof(rip_packet
))
2741 return sizeof(rip_packet
);
2744 static int rip_update_jitter(unsigned long time
)
2746 #define JITTER_BOUND 4
2747 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2748 Given that, we cannot let time be less than JITTER_BOUND seconds.
2749 The RIPv2 RFC says jitter should be small compared to
2750 update_time. We consider 1/JITTER_BOUND to be small.
2753 int jitter_input
= time
;
2756 if (jitter_input
< JITTER_BOUND
)
2757 jitter_input
= JITTER_BOUND
;
2759 jitter
= (((random() % ((jitter_input
* 2) + 1)) - jitter_input
));
2761 return jitter
/ JITTER_BOUND
;
2764 void rip_event(enum rip_event event
, int sock
)
2771 thread_add_read(master
, rip_read
, NULL
, sock
, &rip
->t_read
);
2773 case RIP_UPDATE_EVENT
:
2774 RIP_TIMER_OFF(rip
->t_update
);
2775 jitter
= rip_update_jitter(rip
->update_time
);
2776 thread_add_timer(master
, rip_update
, NULL
,
2777 sock
? 2 : rip
->update_time
+ jitter
,
2780 case RIP_TRIGGERED_UPDATE
:
2781 if (rip
->t_triggered_interval
)
2784 thread_add_event(master
, rip_triggered_update
, NULL
, 0,
2785 &rip
->t_triggered_update
);
2792 DEFUN_NOSH (router_rip
,
2795 "Enable a routing process\n"
2796 "Routing Information Protocol (RIP)\n")
2800 /* If rip is not enabled before. */
2804 zlog_info("Can't create RIP");
2805 return CMD_WARNING_CONFIG_FAILED
;
2808 VTY_PUSH_CONTEXT(RIP_NODE
, rip
);
2813 DEFUN (no_router_rip
,
2817 "Enable a routing process\n"
2818 "Routing Information Protocol (RIP)\n")
2828 "Set routing protocol version\n"
2834 version
= atoi(argv
[idx_number
]->arg
);
2835 if (version
!= RIPv1
&& version
!= RIPv2
) {
2836 vty_out(vty
, "invalid rip version %d\n", version
);
2837 return CMD_WARNING_CONFIG_FAILED
;
2839 rip
->version_send
= version
;
2840 rip
->version_recv
= version
;
2845 DEFUN (no_rip_version
,
2847 "no version [(1-2)]",
2849 "Set routing protocol version\n"
2852 /* Set RIP version to the default. */
2853 rip
->version_send
= RI_RIP_VERSION_2
;
2854 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2863 "RIP static route configuration\n"
2864 "IP prefix <network>/<length>\n")
2866 int idx_ipv4_prefixlen
= 1;
2868 struct prefix_ipv4 p
;
2869 struct route_node
*node
;
2871 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
2873 vty_out(vty
, "Malformed address\n");
2874 return CMD_WARNING_CONFIG_FAILED
;
2876 apply_mask_ipv4(&p
);
2878 /* For router rip configuration. */
2879 node
= route_node_get(rip
->route
, (struct prefix
*)&p
);
2882 vty_out(vty
, "There is already same static route.\n");
2883 route_unlock_node(node
);
2887 node
->info
= (void *)1;
2889 rip_redistribute_add(ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0, NULL
, 0,
2895 DEFUN (no_rip_route
,
2897 "no route A.B.C.D/M",
2899 "RIP static route configuration\n"
2900 "IP prefix <network>/<length>\n")
2902 int idx_ipv4_prefixlen
= 2;
2904 struct prefix_ipv4 p
;
2905 struct route_node
*node
;
2907 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
2909 vty_out(vty
, "Malformed address\n");
2910 return CMD_WARNING_CONFIG_FAILED
;
2912 apply_mask_ipv4(&p
);
2914 /* For router rip configuration. */
2915 node
= route_node_lookup(rip
->route
, (struct prefix
*)&p
);
2917 vty_out(vty
, "Can't find route %s.\n",
2918 argv
[idx_ipv4_prefixlen
]->arg
);
2919 return CMD_WARNING_CONFIG_FAILED
;
2922 rip_redistribute_delete(ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0);
2923 route_unlock_node(node
);
2926 route_unlock_node(node
);
2933 rip_update_default_metric (void)
2935 struct route_node
*np
;
2936 struct rip_info
*rinfo
= NULL
;
2937 struct list
*list
= NULL
;
2938 struct listnode
*listnode
= NULL
;
2940 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
2941 if ((list
= np
->info
) != NULL
)
2942 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
2943 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
2944 rinfo
->metric
= rip
->default_metric
;
2948 DEFUN (rip_default_metric
,
2949 rip_default_metric_cmd
,
2950 "default-metric (1-16)",
2951 "Set a metric of redistribute routes\n"
2956 rip
->default_metric
= atoi(argv
[idx_number
]->arg
);
2957 /* rip_update_default_metric (); */
2962 DEFUN (no_rip_default_metric
,
2963 no_rip_default_metric_cmd
,
2964 "no default-metric [(1-16)]",
2966 "Set a metric of redistribute routes\n"
2970 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2971 /* rip_update_default_metric (); */
2979 "timers basic (5-2147483647) (5-2147483647) (5-2147483647)",
2980 "Adjust routing timers\n"
2981 "Basic routing protocol update timers\n"
2982 "Routing table update timer value in second. Default is 30.\n"
2983 "Routing information timeout timer. Default is 180.\n"
2984 "Garbage collection timer. Default is 120.\n")
2987 int idx_number_2
= 3;
2988 int idx_number_3
= 4;
2989 unsigned long update
;
2990 unsigned long timeout
;
2991 unsigned long garbage
;
2992 char *endptr
= NULL
;
2993 unsigned long RIP_TIMER_MAX
= 2147483647;
2994 unsigned long RIP_TIMER_MIN
= 5;
2996 update
= strtoul(argv
[idx_number
]->arg
, &endptr
, 10);
2997 if (update
> RIP_TIMER_MAX
|| update
< RIP_TIMER_MIN
2998 || *endptr
!= '\0') {
2999 vty_out(vty
, "update timer value error\n");
3000 return CMD_WARNING_CONFIG_FAILED
;
3003 timeout
= strtoul(argv
[idx_number_2
]->arg
, &endptr
, 10);
3004 if (timeout
> RIP_TIMER_MAX
|| timeout
< RIP_TIMER_MIN
3005 || *endptr
!= '\0') {
3006 vty_out(vty
, "timeout timer value error\n");
3007 return CMD_WARNING_CONFIG_FAILED
;
3010 garbage
= strtoul(argv
[idx_number_3
]->arg
, &endptr
, 10);
3011 if (garbage
> RIP_TIMER_MAX
|| garbage
< RIP_TIMER_MIN
3012 || *endptr
!= '\0') {
3013 vty_out(vty
, "garbage timer value error\n");
3014 return CMD_WARNING_CONFIG_FAILED
;
3017 /* Set each timer value. */
3018 rip
->update_time
= update
;
3019 rip
->timeout_time
= timeout
;
3020 rip
->garbage_time
= garbage
;
3022 /* Reset update timer thread. */
3023 rip_event(RIP_UPDATE_EVENT
, 0);
3028 DEFUN (no_rip_timers
,
3030 "no timers basic [(0-65535) (0-65535) (0-65535)]",
3032 "Adjust routing timers\n"
3033 "Basic routing protocol update timers\n"
3034 "Routing table update timer value in second. Default is 30.\n"
3035 "Routing information timeout timer. Default is 180.\n"
3036 "Garbage collection timer. Default is 120.\n")
3038 /* Set each timer value to the default. */
3039 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
3040 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
3041 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
3043 /* Reset update timer thread. */
3044 rip_event(RIP_UPDATE_EVENT
, 0);
3050 struct route_table
*rip_distance_table
;
3052 struct rip_distance
{
3053 /* Distance value for the IP source prefix. */
3056 /* Name of the access-list to be matched. */
3060 static struct rip_distance
*rip_distance_new(void)
3062 return XCALLOC(MTYPE_RIP_DISTANCE
, sizeof(struct rip_distance
));
3065 static void rip_distance_free(struct rip_distance
*rdistance
)
3067 XFREE(MTYPE_RIP_DISTANCE
, rdistance
);
3070 static int rip_distance_set(struct vty
*vty
, const char *distance_str
,
3071 const char *ip_str
, const char *access_list_str
)
3074 struct prefix_ipv4 p
;
3076 struct route_node
*rn
;
3077 struct rip_distance
*rdistance
;
3079 ret
= str2prefix_ipv4(ip_str
, &p
);
3081 vty_out(vty
, "Malformed prefix\n");
3082 return CMD_WARNING_CONFIG_FAILED
;
3085 distance
= atoi(distance_str
);
3087 /* Get RIP distance node. */
3088 rn
= route_node_get(rip_distance_table
, (struct prefix
*)&p
);
3090 rdistance
= rn
->info
;
3091 route_unlock_node(rn
);
3093 rdistance
= rip_distance_new();
3094 rn
->info
= rdistance
;
3097 /* Set distance value. */
3098 rdistance
->distance
= distance
;
3100 /* Reset access-list configuration. */
3101 if (rdistance
->access_list
) {
3102 free(rdistance
->access_list
);
3103 rdistance
->access_list
= NULL
;
3105 if (access_list_str
)
3106 rdistance
->access_list
= strdup(access_list_str
);
3111 static int rip_distance_unset(struct vty
*vty
, const char *distance_str
,
3112 const char *ip_str
, const char *access_list_str
)
3115 struct prefix_ipv4 p
;
3116 struct route_node
*rn
;
3117 struct rip_distance
*rdistance
;
3119 ret
= str2prefix_ipv4(ip_str
, &p
);
3121 vty_out(vty
, "Malformed prefix\n");
3122 return CMD_WARNING_CONFIG_FAILED
;
3125 rn
= route_node_lookup(rip_distance_table
, (struct prefix
*)&p
);
3127 vty_out(vty
, "Can't find specified prefix\n");
3128 return CMD_WARNING_CONFIG_FAILED
;
3131 rdistance
= rn
->info
;
3133 if (rdistance
->access_list
)
3134 free(rdistance
->access_list
);
3135 rip_distance_free(rdistance
);
3138 route_unlock_node(rn
);
3139 route_unlock_node(rn
);
3144 static void rip_distance_reset(void)
3146 struct route_node
*rn
;
3147 struct rip_distance
*rdistance
;
3149 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
3150 if ((rdistance
= rn
->info
) != NULL
) {
3151 if (rdistance
->access_list
)
3152 free(rdistance
->access_list
);
3153 rip_distance_free(rdistance
);
3155 route_unlock_node(rn
);
3159 /* Apply RIP information to distance method. */
3160 u_char
rip_distance_apply(struct rip_info
*rinfo
)
3162 struct route_node
*rn
;
3163 struct prefix_ipv4 p
;
3164 struct rip_distance
*rdistance
;
3165 struct access_list
*alist
;
3170 memset(&p
, 0, sizeof(struct prefix_ipv4
));
3172 p
.prefix
= rinfo
->from
;
3173 p
.prefixlen
= IPV4_MAX_BITLEN
;
3175 /* Check source address. */
3176 rn
= route_node_match(rip_distance_table
, (struct prefix
*)&p
);
3178 rdistance
= rn
->info
;
3179 route_unlock_node(rn
);
3181 if (rdistance
->access_list
) {
3182 alist
= access_list_lookup(AFI_IP
,
3183 rdistance
->access_list
);
3186 if (access_list_apply(alist
, &rinfo
->rp
->p
)
3190 return rdistance
->distance
;
3192 return rdistance
->distance
;
3196 return rip
->distance
;
3201 static void rip_distance_show(struct vty
*vty
)
3203 struct route_node
*rn
;
3204 struct rip_distance
*rdistance
;
3208 vty_out(vty
, " Distance: (default is %d)\n",
3209 rip
->distance
? rip
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
);
3211 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
3212 if ((rdistance
= rn
->info
) != NULL
) {
3215 " Address Distance List\n");
3218 sprintf(buf
, "%s/%d", inet_ntoa(rn
->p
.u
.prefix4
),
3220 vty_out(vty
, " %-20s %4d %s\n", buf
,
3221 rdistance
->distance
,
3222 rdistance
->access_list
? rdistance
->access_list
3227 DEFUN (rip_distance
,
3230 "Administrative distance\n"
3234 rip
->distance
= atoi(argv
[idx_number
]->arg
);
3238 DEFUN (no_rip_distance
,
3239 no_rip_distance_cmd
,
3240 "no distance (1-255)",
3242 "Administrative distance\n"
3249 DEFUN (rip_distance_source
,
3250 rip_distance_source_cmd
,
3251 "distance (1-255) A.B.C.D/M",
3252 "Administrative distance\n"
3254 "IP source prefix\n")
3257 int idx_ipv4_prefixlen
= 2;
3258 rip_distance_set(vty
, argv
[idx_number
]->arg
,
3259 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
3263 DEFUN (no_rip_distance_source
,
3264 no_rip_distance_source_cmd
,
3265 "no distance (1-255) A.B.C.D/M",
3267 "Administrative distance\n"
3269 "IP source prefix\n")
3272 int idx_ipv4_prefixlen
= 3;
3273 rip_distance_unset(vty
, argv
[idx_number
]->arg
,
3274 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
3278 DEFUN (rip_distance_source_access_list
,
3279 rip_distance_source_access_list_cmd
,
3280 "distance (1-255) A.B.C.D/M WORD",
3281 "Administrative distance\n"
3283 "IP source prefix\n"
3284 "Access list name\n")
3287 int idx_ipv4_prefixlen
= 2;
3289 rip_distance_set(vty
, argv
[idx_number
]->arg
,
3290 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
3294 DEFUN (no_rip_distance_source_access_list
,
3295 no_rip_distance_source_access_list_cmd
,
3296 "no distance (1-255) A.B.C.D/M WORD",
3298 "Administrative distance\n"
3300 "IP source prefix\n"
3301 "Access list name\n")
3304 int idx_ipv4_prefixlen
= 3;
3306 rip_distance_unset(vty
, argv
[idx_number
]->arg
,
3307 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
3311 /* Update ECMP routes to zebra when ECMP is disabled. */
3312 static void rip_ecmp_disable(void)
3314 struct route_node
*rp
;
3315 struct rip_info
*rinfo
, *tmp_rinfo
;
3317 struct listnode
*node
, *nextnode
;
3322 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3323 if ((list
= rp
->info
) != NULL
&& listcount(list
) > 1) {
3324 rinfo
= listgetdata(listhead(list
));
3325 if (!rip_route_rte(rinfo
))
3328 /* Drop all other entries, except the first one. */
3329 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
3330 if (tmp_rinfo
!= rinfo
) {
3331 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
3333 tmp_rinfo
->t_garbage_collect
);
3334 list_delete_node(list
, node
);
3335 rip_info_free(tmp_rinfo
);
3339 rip_zebra_ipv4_add(rp
);
3341 /* Set the route change flag. */
3342 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
3344 /* Signal the output process to trigger an update. */
3345 rip_event(RIP_TRIGGERED_UPDATE
, 0);
3349 DEFUN (rip_allow_ecmp
,
3352 "Allow Equal Cost MultiPath\n")
3355 vty_out(vty
, "ECMP is already enabled.\n");
3360 zlog_info("ECMP is enabled.");
3364 DEFUN (no_rip_allow_ecmp
,
3365 no_rip_allow_ecmp_cmd
,
3368 "Allow Equal Cost MultiPath\n")
3371 vty_out(vty
, "ECMP is already disabled.\n");
3376 zlog_info("ECMP is disabled.");
3381 /* Print out routes update time. */
3382 static void rip_vty_out_uptime(struct vty
*vty
, struct rip_info
*rinfo
)
3387 char timebuf
[TIME_BUF
];
3388 struct thread
*thread
;
3390 if ((thread
= rinfo
->t_timeout
) != NULL
) {
3391 clock
= thread_timer_remain_second(thread
);
3392 tm
= gmtime(&clock
);
3393 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
3394 vty_out(vty
, "%5s", timebuf
);
3395 } else if ((thread
= rinfo
->t_garbage_collect
) != NULL
) {
3396 clock
= thread_timer_remain_second(thread
);
3397 tm
= gmtime(&clock
);
3398 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
3399 vty_out(vty
, "%5s", timebuf
);
3403 static const char *rip_route_type_print(int sub_type
)
3408 case RIP_ROUTE_STATIC
:
3410 case RIP_ROUTE_DEFAULT
:
3412 case RIP_ROUTE_REDISTRIBUTE
:
3414 case RIP_ROUTE_INTERFACE
:
3426 "Show RIP routes\n")
3428 struct route_node
*np
;
3429 struct rip_info
*rinfo
= NULL
;
3430 struct list
*list
= NULL
;
3431 struct listnode
*listnode
= NULL
;
3437 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
3439 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
3440 " (i) - interface\n\n"
3441 " Network Next Hop Metric From Tag Time\n");
3443 for (np
= route_top(rip
->table
); np
; np
= route_next(np
))
3444 if ((list
= np
->info
) != NULL
)
3445 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3449 vty
, "%c(%s) %s/%d",
3450 /* np->lock, For debugging. */
3451 zebra_route_char(rinfo
->type
),
3452 rip_route_type_print(rinfo
->sub_type
),
3453 inet_ntoa(np
->p
.u
.prefix4
),
3459 vty_out(vty
, "%*s", len
, " ");
3461 if (rinfo
->nexthop
.s_addr
)
3462 vty_out(vty
, "%-20s %2d ",
3463 inet_ntoa(rinfo
->nexthop
),
3470 /* Route which exist in kernel routing table. */
3471 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
)
3472 && (rinfo
->sub_type
== RIP_ROUTE_RTE
)) {
3473 vty_out(vty
, "%-15s ",
3474 inet_ntoa(rinfo
->from
));
3475 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3476 (route_tag_t
)rinfo
->tag
);
3477 rip_vty_out_uptime(vty
, rinfo
);
3478 } else if (rinfo
->metric
3479 == RIP_METRIC_INFINITY
) {
3480 vty_out(vty
, "self ");
3481 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3482 (route_tag_t
)rinfo
->tag
);
3483 rip_vty_out_uptime(vty
, rinfo
);
3485 if (rinfo
->external_metric
) {
3487 vty
, "self (%s:%d)",
3490 rinfo
->external_metric
);
3493 vty_out(vty
, "%*s", len
,
3498 vty_out(vty
, "%3" ROUTE_TAG_PRI
,
3499 (route_tag_t
)rinfo
->tag
);
3507 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3508 DEFUN (show_ip_rip_status
,
3509 show_ip_rip_status_cmd
,
3510 "show ip rip status",
3514 "IP routing protocol process parameters and statistics\n")
3516 struct listnode
*node
;
3517 struct interface
*ifp
;
3518 struct rip_interface
*ri
;
3519 extern const struct message ri_version_msg
[];
3520 const char *send_version
;
3521 const char *receive_version
;
3526 vty_out(vty
, "Routing Protocol is \"rip\"\n");
3527 vty_out(vty
, " Sending updates every %ld seconds with +/-50%%,",
3529 vty_out(vty
, " next due in %lu seconds\n",
3530 thread_timer_remain_second(rip
->t_update
));
3531 vty_out(vty
, " Timeout after %ld seconds,", rip
->timeout_time
);
3532 vty_out(vty
, " garbage collect after %ld seconds\n", rip
->garbage_time
);
3534 /* Filtering status show. */
3535 config_show_distribute(vty
);
3537 /* Default metric information. */
3538 vty_out(vty
, " Default redistribution metric is %d\n",
3539 rip
->default_metric
);
3541 /* Redistribute information. */
3542 vty_out(vty
, " Redistributing:");
3543 config_write_rip_redistribute(vty
, 0);
3546 vty_out(vty
, " Default version control: send version %s,",
3547 lookup_msg(ri_version_msg
, rip
->version_send
, NULL
));
3548 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3549 vty_out(vty
, " receive any version \n");
3551 vty_out(vty
, " receive version %s \n",
3552 lookup_msg(ri_version_msg
, rip
->version_recv
, NULL
));
3554 vty_out(vty
, " Interface Send Recv Key-chain\n");
3556 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
)) {
3562 if (ri
->enable_network
|| ri
->enable_interface
) {
3563 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3565 lookup_msg(ri_version_msg
,
3566 rip
->version_send
, NULL
);
3568 send_version
= lookup_msg(ri_version_msg
,
3571 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3573 lookup_msg(ri_version_msg
,
3574 rip
->version_recv
, NULL
);
3576 receive_version
= lookup_msg(
3577 ri_version_msg
, ri
->ri_receive
, NULL
);
3579 vty_out(vty
, " %-17s%-3s %-3s %s\n", ifp
->name
,
3580 send_version
, receive_version
,
3581 ri
->key_chain
? ri
->key_chain
: "");
3585 vty_out(vty
, " Routing for Networks:\n");
3586 config_write_rip_network(vty
, 0);
3589 int found_passive
= 0;
3590 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
)) {
3593 if ((ri
->enable_network
|| ri
->enable_interface
)
3595 if (!found_passive
) {
3597 " Passive Interface(s):\n");
3600 vty_out(vty
, " %s\n", ifp
->name
);
3605 vty_out(vty
, " Routing Information Sources:\n");
3607 " Gateway BadPackets BadRoutes Distance Last Update\n");
3608 rip_peer_display(vty
);
3610 rip_distance_show(vty
);
3615 /* RIP configuration write function. */
3616 static int config_write_rip(struct vty
*vty
)
3619 struct route_node
*rn
;
3620 struct rip_distance
*rdistance
;
3623 /* Router RIP statement. */
3624 vty_out(vty
, "router rip\n");
3627 /* RIP version statement. Default is RIP version 2. */
3628 if (rip
->version_send
!= RI_RIP_VERSION_2
3629 || rip
->version_recv
!= RI_RIP_VERSION_1_AND_2
)
3630 vty_out(vty
, " version %d\n", rip
->version_send
);
3632 /* RIP timer configuration. */
3633 if (rip
->update_time
!= RIP_UPDATE_TIMER_DEFAULT
3634 || rip
->timeout_time
!= RIP_TIMEOUT_TIMER_DEFAULT
3635 || rip
->garbage_time
!= RIP_GARBAGE_TIMER_DEFAULT
)
3636 vty_out(vty
, " timers basic %lu %lu %lu\n",
3637 rip
->update_time
, rip
->timeout_time
,
3640 /* Default information configuration. */
3641 if (rip
->default_information
) {
3642 if (rip
->default_information_route_map
)
3644 " default-information originate route-map %s\n",
3645 rip
->default_information_route_map
);
3648 " default-information originate\n");
3651 /* Redistribute configuration. */
3652 config_write_rip_redistribute(vty
, 1);
3654 /* RIP offset-list configuration. */
3655 config_write_rip_offset_list(vty
);
3657 /* RIP enabled network and interface configuration. */
3658 config_write_rip_network(vty
, 1);
3660 /* RIP default metric configuration */
3661 if (rip
->default_metric
!= RIP_DEFAULT_METRIC_DEFAULT
)
3662 vty_out(vty
, " default-metric %d\n",
3663 rip
->default_metric
);
3665 /* Distribute configuration. */
3666 write
+= config_write_distribute(vty
);
3668 /* Interface routemap configuration */
3669 write
+= config_write_if_rmap(vty
);
3671 /* Distance configuration. */
3673 vty_out(vty
, " distance %d\n", rip
->distance
);
3675 /* RIP source IP prefix distance configuration. */
3676 for (rn
= route_top(rip_distance_table
); rn
;
3677 rn
= route_next(rn
))
3678 if ((rdistance
= rn
->info
) != NULL
)
3679 vty_out(vty
, " distance %d %s/%d %s\n",
3680 rdistance
->distance
,
3681 inet_ntoa(rn
->p
.u
.prefix4
),
3683 rdistance
->access_list
3684 ? rdistance
->access_list
3687 /* ECMP configuration. */
3689 vty_out(vty
, " allow-ecmp\n");
3691 /* RIP static route configuration. */
3692 for (rn
= route_top(rip
->route
); rn
; rn
= route_next(rn
))
3694 vty_out(vty
, " route %s/%d\n",
3695 inet_ntoa(rn
->p
.u
.prefix4
),
3701 /* RIP node structure. */
3702 static struct cmd_node rip_node
= {RIP_NODE
, "%s(config-router)# ", 1};
3704 /* Distribute-list update functions. */
3705 static void rip_distribute_update(struct distribute
*dist
)
3707 struct interface
*ifp
;
3708 struct rip_interface
*ri
;
3709 struct access_list
*alist
;
3710 struct prefix_list
*plist
;
3715 ifp
= if_lookup_by_name(dist
->ifname
, VRF_DEFAULT
);
3721 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
3722 alist
= access_list_lookup(AFI_IP
,
3723 dist
->list
[DISTRIBUTE_V4_IN
]);
3725 ri
->list
[RIP_FILTER_IN
] = alist
;
3727 ri
->list
[RIP_FILTER_IN
] = NULL
;
3729 ri
->list
[RIP_FILTER_IN
] = NULL
;
3731 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
3732 alist
= access_list_lookup(AFI_IP
,
3733 dist
->list
[DISTRIBUTE_V4_OUT
]);
3735 ri
->list
[RIP_FILTER_OUT
] = alist
;
3737 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3739 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3741 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
3742 plist
= prefix_list_lookup(AFI_IP
,
3743 dist
->prefix
[DISTRIBUTE_V4_IN
]);
3745 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3747 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3749 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3751 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
3752 plist
= prefix_list_lookup(AFI_IP
,
3753 dist
->prefix
[DISTRIBUTE_V4_OUT
]);
3755 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3757 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3759 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3762 void rip_distribute_update_interface(struct interface
*ifp
)
3764 struct distribute
*dist
;
3766 dist
= distribute_lookup(ifp
->name
);
3768 rip_distribute_update(dist
);
3771 /* Update all interface's distribute list. */
3773 static void rip_distribute_update_all(struct prefix_list
*notused
)
3775 struct interface
*ifp
;
3776 struct listnode
*node
, *nnode
;
3778 for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT
), node
, nnode
, ifp
))
3779 rip_distribute_update_interface(ifp
);
3782 static void rip_distribute_update_all_wrapper(struct access_list
*notused
)
3784 rip_distribute_update_all(NULL
);
3787 /* Delete all added rip route. */
3788 void rip_clean(void)
3791 struct route_node
*rp
;
3792 struct rip_info
*rinfo
= NULL
;
3793 struct list
*list
= NULL
;
3794 struct listnode
*listnode
= NULL
;
3799 /* Clear RIP routes */
3800 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3801 if ((list
= rp
->info
) != NULL
) {
3802 rinfo
= listgetdata(listhead(list
));
3803 if (rip_route_rte(rinfo
))
3804 rip_zebra_ipv4_delete(rp
);
3806 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
3808 RIP_TIMER_OFF(rinfo
->t_timeout
);
3809 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
3810 rip_info_free(rinfo
);
3814 route_unlock_node(rp
);
3817 /* Cancel RIP related timers. */
3818 RIP_TIMER_OFF(rip
->t_update
);
3819 RIP_TIMER_OFF(rip
->t_triggered_update
);
3820 RIP_TIMER_OFF(rip
->t_triggered_interval
);
3822 /* Cancel read thread. */
3823 THREAD_READ_OFF(rip
->t_read
);
3825 /* Close RIP socket. */
3826 if (rip
->sock
>= 0) {
3831 /* Static RIP route configuration. */
3832 for (rp
= route_top(rip
->route
); rp
; rp
= route_next(rp
))
3835 route_unlock_node(rp
);
3838 /* RIP neighbor configuration. */
3839 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
3842 route_unlock_node(rp
);
3845 /* Redistribute related clear. */
3846 if (rip
->default_information_route_map
)
3847 free(rip
->default_information_route_map
);
3849 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3850 if (rip
->route_map
[i
].name
)
3851 free(rip
->route_map
[i
].name
);
3853 XFREE(MTYPE_ROUTE_TABLE
, rip
->table
);
3854 XFREE(MTYPE_ROUTE_TABLE
, rip
->route
);
3855 XFREE(MTYPE_ROUTE_TABLE
, rip
->neighbor
);
3857 XFREE(MTYPE_RIP
, rip
);
3861 rip_clean_network();
3862 rip_passive_nondefault_clean();
3864 rip_interfaces_clean();
3865 rip_distance_reset();
3866 rip_redistribute_clean();
3869 /* Reset all values to the default settings. */
3870 void rip_reset(void)
3872 /* Reset global counters. */
3873 rip_global_route_changes
= 0;
3874 rip_global_queries
= 0;
3876 /* Call ripd related reset functions. */
3878 rip_route_map_reset();
3880 /* Call library reset functions. */
3882 access_list_reset();
3883 prefix_list_reset();
3885 distribute_list_reset();
3887 rip_interfaces_reset();
3888 rip_distance_reset();
3890 rip_zclient_reset();
3893 static void rip_if_rmap_update(struct if_rmap
*if_rmap
)
3895 struct interface
*ifp
;
3896 struct rip_interface
*ri
;
3897 struct route_map
*rmap
;
3899 ifp
= if_lookup_by_name(if_rmap
->ifname
, VRF_DEFAULT
);
3905 if (if_rmap
->routemap
[IF_RMAP_IN
]) {
3906 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_IN
]);
3908 ri
->routemap
[IF_RMAP_IN
] = rmap
;
3910 ri
->routemap
[IF_RMAP_IN
] = NULL
;
3912 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
3914 if (if_rmap
->routemap
[IF_RMAP_OUT
]) {
3915 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_OUT
]);
3917 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
3919 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
3921 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
3924 void rip_if_rmap_update_interface(struct interface
*ifp
)
3926 struct if_rmap
*if_rmap
;
3928 if_rmap
= if_rmap_lookup(ifp
->name
);
3930 rip_if_rmap_update(if_rmap
);
3933 static void rip_routemap_update_redistribute(void)
3938 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3939 if (rip
->route_map
[i
].name
)
3940 rip
->route_map
[i
].map
=
3941 route_map_lookup_by_name(
3942 rip
->route_map
[i
].name
);
3948 static void rip_routemap_update(const char *notused
)
3950 struct interface
*ifp
;
3951 struct listnode
*node
, *nnode
;
3953 for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT
), node
, nnode
, ifp
))
3954 rip_if_rmap_update_interface(ifp
);
3956 rip_routemap_update_redistribute();
3959 /* Allocate new rip structure and set default value. */
3962 /* Install top nodes. */
3963 install_node(&rip_node
, config_write_rip
);
3965 /* Install rip commands. */
3966 install_element(VIEW_NODE
, &show_ip_rip_cmd
);
3967 install_element(VIEW_NODE
, &show_ip_rip_status_cmd
);
3968 install_element(CONFIG_NODE
, &router_rip_cmd
);
3969 install_element(CONFIG_NODE
, &no_router_rip_cmd
);
3971 install_default(RIP_NODE
);
3972 install_element(RIP_NODE
, &rip_version_cmd
);
3973 install_element(RIP_NODE
, &no_rip_version_cmd
);
3974 install_element(RIP_NODE
, &rip_default_metric_cmd
);
3975 install_element(RIP_NODE
, &no_rip_default_metric_cmd
);
3976 install_element(RIP_NODE
, &rip_timers_cmd
);
3977 install_element(RIP_NODE
, &no_rip_timers_cmd
);
3978 install_element(RIP_NODE
, &rip_route_cmd
);
3979 install_element(RIP_NODE
, &no_rip_route_cmd
);
3980 install_element(RIP_NODE
, &rip_distance_cmd
);
3981 install_element(RIP_NODE
, &no_rip_distance_cmd
);
3982 install_element(RIP_NODE
, &rip_distance_source_cmd
);
3983 install_element(RIP_NODE
, &no_rip_distance_source_cmd
);
3984 install_element(RIP_NODE
, &rip_distance_source_access_list_cmd
);
3985 install_element(RIP_NODE
, &no_rip_distance_source_access_list_cmd
);
3986 install_element(RIP_NODE
, &rip_allow_ecmp_cmd
);
3987 install_element(RIP_NODE
, &no_rip_allow_ecmp_cmd
);
3989 /* Debug related init. */
3992 /* Access list install. */
3994 access_list_add_hook(rip_distribute_update_all_wrapper
);
3995 access_list_delete_hook(rip_distribute_update_all_wrapper
);
3997 /* Prefix list initialize.*/
3999 prefix_list_add_hook(rip_distribute_update_all
);
4000 prefix_list_delete_hook(rip_distribute_update_all
);
4002 /* Distribute list install. */
4003 distribute_list_init(RIP_NODE
);
4004 distribute_list_add_hook(rip_distribute_update
);
4005 distribute_list_delete_hook(rip_distribute_update
);
4008 rip_route_map_init();
4011 route_map_add_hook(rip_routemap_update
);
4012 route_map_delete_hook(rip_routemap_update
);
4014 if_rmap_init(RIP_NODE
);
4015 if_rmap_hook_add(rip_if_rmap_update
);
4016 if_rmap_hook_delete(rip_if_rmap_update
);
4018 /* Distance control. */
4019 rip_distance_table
= route_table_init();