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
53 struct rip
*rip
= NULL
;
55 /* RIP neighbor address table. */
56 struct route_table
*rip_neighbor_table
;
58 /* RIP route changes. */
59 long rip_global_route_changes
= 0;
62 long rip_global_queries
= 0;
65 static void rip_event(enum rip_event
, int);
66 static void rip_output_process(struct connected
*, struct sockaddr_in
*, int,
68 static int rip_triggered_update(struct thread
*);
69 static int rip_update_jitter(unsigned long);
71 /* RIP output routes type. */
72 enum { rip_all_route
, rip_changed_route
};
74 /* RIP command strings. */
75 static const struct message rip_msg
[] = {{RIP_REQUEST
, "REQUEST"},
76 {RIP_RESPONSE
, "RESPONSE"},
77 {RIP_TRACEON
, "TRACEON"},
78 {RIP_TRACEOFF
, "TRACEOFF"},
80 {RIP_POLL_ENTRY
, "POLL ENTRY"},
83 /* Utility function to set boradcast option to the socket. */
84 static int sockopt_broadcast(int sock
)
89 ret
= setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, (char *)&on
,
92 zlog_warn("can't set sockopt SO_BROADCAST to socket %d", sock
);
98 static int rip_route_rte(struct rip_info
*rinfo
)
100 return (rinfo
->type
== ZEBRA_ROUTE_RIP
101 && rinfo
->sub_type
== RIP_ROUTE_RTE
);
104 static struct rip_info
*rip_info_new(void)
106 return XCALLOC(MTYPE_RIP_INFO
, sizeof(struct rip_info
));
109 void rip_info_free(struct rip_info
*rinfo
)
111 XFREE(MTYPE_RIP_INFO
, rinfo
);
114 /* RIP route garbage collect timer. */
115 static int rip_garbage_collect(struct thread
*t
)
117 struct rip_info
*rinfo
;
118 struct route_node
*rp
;
120 rinfo
= THREAD_ARG(t
);
121 rinfo
->t_garbage_collect
= NULL
;
123 /* Off timeout timer. */
124 RIP_TIMER_OFF(rinfo
->t_timeout
);
126 /* Get route_node pointer. */
129 /* Unlock route_node. */
130 listnode_delete(rp
->info
, rinfo
);
131 if (list_isempty((struct list
*)rp
->info
)) {
132 list_delete_and_null((struct list
**)&rp
->info
);
133 route_unlock_node(rp
);
136 /* Free RIP routing information. */
137 rip_info_free(rinfo
);
142 static void rip_timeout_update(struct rip_info
*rinfo
);
144 /* Add new route to the ECMP list.
145 * RETURN: the new entry added in the list, or NULL if it is not the first
146 * entry and ECMP is not allowed.
148 struct rip_info
*rip_ecmp_add(struct rip_info
*rinfo_new
)
150 struct route_node
*rp
= rinfo_new
->rp
;
151 struct rip_info
*rinfo
= NULL
;
152 struct list
*list
= NULL
;
154 if (rp
->info
== NULL
)
155 rp
->info
= list_new();
156 list
= (struct list
*)rp
->info
;
158 /* If ECMP is not allowed and some entry already exists in the list,
160 if (listcount(list
) && !rip
->ecmp
)
163 rinfo
= rip_info_new();
164 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
165 listnode_add(list
, rinfo
);
167 if (rip_route_rte(rinfo
)) {
168 rip_timeout_update(rinfo
);
169 rip_zebra_ipv4_add(rp
);
172 /* Set the route change flag on the first entry. */
173 rinfo
= listgetdata(listhead(list
));
174 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
176 /* Signal the output process to trigger an update (see section 2.5). */
177 rip_event(RIP_TRIGGERED_UPDATE
, 0);
182 /* Replace the ECMP list with the new route.
183 * RETURN: the new entry added in the list
185 struct rip_info
*rip_ecmp_replace(struct rip_info
*rinfo_new
)
187 struct route_node
*rp
= rinfo_new
->rp
;
188 struct list
*list
= (struct list
*)rp
->info
;
189 struct rip_info
*rinfo
= NULL
, *tmp_rinfo
= NULL
;
190 struct listnode
*node
= NULL
, *nextnode
= NULL
;
192 if (list
== NULL
|| listcount(list
) == 0)
193 return rip_ecmp_add(rinfo_new
);
195 /* Get the first entry */
196 rinfo
= listgetdata(listhead(list
));
198 /* Learnt route replaced by a local one. Delete it from zebra. */
199 if (rip_route_rte(rinfo
) && !rip_route_rte(rinfo_new
))
200 if (CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
201 rip_zebra_ipv4_delete(rp
);
203 /* Re-use the first entry, and delete the others. */
204 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
205 if (tmp_rinfo
!= rinfo
) {
206 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
207 RIP_TIMER_OFF(tmp_rinfo
->t_garbage_collect
);
208 list_delete_node(list
, node
);
209 rip_info_free(tmp_rinfo
);
212 RIP_TIMER_OFF(rinfo
->t_timeout
);
213 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
214 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
216 if (rip_route_rte(rinfo
)) {
217 rip_timeout_update(rinfo
);
218 /* The ADD message implies an update. */
219 rip_zebra_ipv4_add(rp
);
222 /* Set the route change flag. */
223 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
225 /* Signal the output process to trigger an update (see section 2.5). */
226 rip_event(RIP_TRIGGERED_UPDATE
, 0);
231 /* Delete one route from the ECMP list.
233 * null - the entry is freed, and other entries exist in the list
234 * the entry - the entry is the last one in the list; its metric is set
235 * to INFINITY, and the garbage collector is started for it
237 struct rip_info
*rip_ecmp_delete(struct rip_info
*rinfo
)
239 struct route_node
*rp
= rinfo
->rp
;
240 struct list
*list
= (struct list
*)rp
->info
;
242 RIP_TIMER_OFF(rinfo
->t_timeout
);
244 if (listcount(list
) > 1) {
245 /* Some other ECMP entries still exist. Just delete this entry.
247 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
248 listnode_delete(list
, rinfo
);
249 if (rip_route_rte(rinfo
)
250 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
251 /* The ADD message implies the update. */
252 rip_zebra_ipv4_add(rp
);
253 rip_info_free(rinfo
);
256 assert(rinfo
== listgetdata(listhead(list
)));
258 /* This is the only entry left in the list. We must keep it in
259 * the list for garbage collection time, with INFINITY metric.
262 rinfo
->metric
= RIP_METRIC_INFINITY
;
263 RIP_TIMER_ON(rinfo
->t_garbage_collect
, rip_garbage_collect
,
266 if (rip_route_rte(rinfo
)
267 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
268 rip_zebra_ipv4_delete(rp
);
271 /* Set the route change flag on the first entry. */
272 rinfo
= listgetdata(listhead(list
));
273 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
275 /* Signal the output process to trigger an update (see section 2.5). */
276 rip_event(RIP_TRIGGERED_UPDATE
, 0);
281 /* Timeout RIP routes. */
282 static int rip_timeout(struct thread
*t
)
284 rip_ecmp_delete((struct rip_info
*)THREAD_ARG(t
));
288 static void rip_timeout_update(struct rip_info
*rinfo
)
290 if (rinfo
->metric
!= RIP_METRIC_INFINITY
) {
291 RIP_TIMER_OFF(rinfo
->t_timeout
);
292 RIP_TIMER_ON(rinfo
->t_timeout
, rip_timeout
, rip
->timeout_time
);
296 static int rip_filter(int rip_distribute
, struct prefix_ipv4
*p
,
297 struct rip_interface
*ri
)
299 struct distribute
*dist
;
300 struct access_list
*alist
;
301 struct prefix_list
*plist
;
302 int distribute
= rip_distribute
== RIP_FILTER_OUT
? DISTRIBUTE_V4_OUT
304 const char *inout
= rip_distribute
== RIP_FILTER_OUT
? "out" : "in";
306 /* Input distribute-list filtering. */
307 if (ri
->list
[rip_distribute
]) {
308 if (access_list_apply(ri
->list
[rip_distribute
],
311 if (IS_RIP_DEBUG_PACKET
)
312 zlog_debug("%s/%d filtered by distribute %s",
313 inet_ntoa(p
->prefix
), p
->prefixlen
,
318 if (ri
->prefix
[rip_distribute
]) {
319 if (prefix_list_apply(ri
->prefix
[rip_distribute
],
322 if (IS_RIP_DEBUG_PACKET
)
323 zlog_debug("%s/%d filtered by prefix-list %s",
324 inet_ntoa(p
->prefix
), p
->prefixlen
,
330 /* All interface filter check. */
331 dist
= distribute_lookup(NULL
);
333 if (dist
->list
[distribute
]) {
334 alist
= access_list_lookup(AFI_IP
,
335 dist
->list
[distribute
]);
338 if (access_list_apply(alist
, (struct prefix
*)p
)
340 if (IS_RIP_DEBUG_PACKET
)
342 "%s/%d filtered by distribute %s",
343 inet_ntoa(p
->prefix
),
344 p
->prefixlen
, inout
);
349 if (dist
->prefix
[distribute
]) {
350 plist
= prefix_list_lookup(AFI_IP
,
351 dist
->prefix
[distribute
]);
354 if (prefix_list_apply(plist
, (struct prefix
*)p
)
356 if (IS_RIP_DEBUG_PACKET
)
358 "%s/%d filtered by prefix-list %s",
359 inet_ntoa(p
->prefix
),
360 p
->prefixlen
, inout
);
369 /* Check nexthop address validity. */
370 static int rip_nexthop_check(struct in_addr
*addr
)
372 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
373 struct interface
*ifp
;
374 struct listnode
*cnode
;
375 struct connected
*ifc
;
378 /* If nexthop address matches local configured address then it is
381 FOR_ALL_INTERFACES (vrf
, ifp
) {
382 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, ifc
)) {
385 if (p
->family
== AF_INET
386 && IPV4_ADDR_SAME(&p
->u
.prefix4
, addr
))
393 /* RIP add route to routing table. */
394 static void rip_rte_process(struct rte
*rte
, struct sockaddr_in
*from
,
395 struct interface
*ifp
)
398 struct prefix_ipv4 p
;
399 struct route_node
*rp
;
400 struct rip_info
*rinfo
= NULL
, newinfo
;
401 struct rip_interface
*ri
;
402 struct in_addr
*nexthop
;
404 unsigned char old_dist
, new_dist
;
405 struct list
*list
= NULL
;
406 struct listnode
*node
= NULL
;
408 /* Make prefix structure. */
409 memset(&p
, 0, sizeof(struct prefix_ipv4
));
411 p
.prefix
= rte
->prefix
;
412 p
.prefixlen
= ip_masklen(rte
->mask
);
414 /* Make sure mask is applied. */
417 /* Apply input filters. */
420 ret
= rip_filter(RIP_FILTER_IN
, &p
, ri
);
424 memset(&newinfo
, 0, sizeof(newinfo
));
425 newinfo
.type
= ZEBRA_ROUTE_RIP
;
426 newinfo
.sub_type
= RIP_ROUTE_RTE
;
427 newinfo
.nh
.gate
.ipv4
= rte
->nexthop
;
428 newinfo
.from
= from
->sin_addr
;
429 newinfo
.nh
.ifindex
= ifp
->ifindex
;
430 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
431 newinfo
.metric
= rte
->metric
;
432 newinfo
.metric_out
= rte
->metric
; /* XXX */
433 newinfo
.tag
= ntohs(rte
->tag
); /* XXX */
435 /* Modify entry according to the interface routemap. */
436 if (ri
->routemap
[RIP_FILTER_IN
]) {
439 /* The object should be of the type of rip_info */
440 ret
= route_map_apply(ri
->routemap
[RIP_FILTER_IN
],
441 (struct prefix
*)&p
, RMAP_RIP
, &newinfo
);
443 if (ret
== RMAP_DENYMATCH
) {
444 if (IS_RIP_DEBUG_PACKET
)
446 "RIP %s/%d is filtered by route-map in",
447 inet_ntoa(p
.prefix
), p
.prefixlen
);
451 /* Get back the object */
452 rte
->nexthop
= newinfo
.nexthop_out
;
453 rte
->tag
= htons(newinfo
.tag_out
); /* XXX */
455 newinfo
.metric_out
; /* XXX: the routemap uses the
459 /* Once the entry has been validated, update the metric by
460 adding the cost of the network on wich the message
461 arrived. If the result is greater than infinity, use infinity
462 (RFC2453 Sec. 3.9.2) */
463 /* Zebra ripd can handle offset-list in. */
464 ret
= rip_offset_list_apply_in(&p
, ifp
, &rte
->metric
);
466 /* If offset-list does not modify the metric use interface's
469 rte
->metric
+= ifp
->metric
? ifp
->metric
: 1;
471 if (rte
->metric
> RIP_METRIC_INFINITY
)
472 rte
->metric
= RIP_METRIC_INFINITY
;
474 /* Set nexthop pointer. */
475 if (rte
->nexthop
.s_addr
== 0)
476 nexthop
= &from
->sin_addr
;
478 nexthop
= &rte
->nexthop
;
480 /* Check if nexthop address is myself, then do nothing. */
481 if (rip_nexthop_check(nexthop
) < 0) {
482 if (IS_RIP_DEBUG_PACKET
)
483 zlog_debug("Nexthop address %s is myself",
484 inet_ntoa(*nexthop
));
488 /* Get index for the prefix. */
489 rp
= route_node_get(rip
->table
, (struct prefix
*)&p
);
492 newinfo
.nh
.gate
.ipv4
= *nexthop
;
493 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4
;
494 newinfo
.metric
= rte
->metric
;
495 newinfo
.tag
= ntohs(rte
->tag
);
496 newinfo
.distance
= rip_distance_apply(&newinfo
);
498 new_dist
= newinfo
.distance
? newinfo
.distance
499 : ZEBRA_RIP_DISTANCE_DEFAULT
;
501 /* Check to see whether there is already RIP route on the table. */
502 if ((list
= rp
->info
) != NULL
)
503 for (ALL_LIST_ELEMENTS_RO(list
, node
, rinfo
)) {
504 /* Need to compare with redistributed entry or local
506 if (!rip_route_rte(rinfo
))
509 if (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
510 && IPV4_ADDR_SAME(&rinfo
->nh
.gate
.ipv4
, nexthop
))
513 if (!listnextnode(node
)) {
514 /* Not found in the list */
516 if (rte
->metric
> rinfo
->metric
) {
517 /* New route has a greater metric.
519 route_unlock_node(rp
);
523 if (rte
->metric
< rinfo
->metric
)
524 /* New route has a smaller metric.
525 * Replace the ECMP list
526 * with the new one in below. */
529 /* Metrics are same. We compare the distances.
531 old_dist
= rinfo
->distance
533 : ZEBRA_RIP_DISTANCE_DEFAULT
;
535 if (new_dist
> old_dist
) {
536 /* New route has a greater distance.
538 route_unlock_node(rp
);
542 if (new_dist
< old_dist
)
543 /* New route has a smaller distance.
544 * Replace the ECMP list
545 * with the new one in below. */
548 /* Metrics and distances are both same. Keep
550 * the new route is added in the ECMP list in
556 /* Local static route. */
557 if (rinfo
->type
== ZEBRA_ROUTE_RIP
558 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
559 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))
560 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
561 route_unlock_node(rp
);
565 /* Redistributed route check. */
566 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
567 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
568 old_dist
= rinfo
->distance
;
569 /* Only routes directly connected to an interface
571 * may have a valid NULL distance */
572 if (rinfo
->nh
.gate
.ipv4
.s_addr
!= 0)
575 : ZEBRA_RIP_DISTANCE_DEFAULT
;
576 /* If imported route does not have STRICT precedence,
577 mark it as a ghost */
578 if (new_dist
<= old_dist
579 && rte
->metric
!= RIP_METRIC_INFINITY
)
580 rip_ecmp_replace(&newinfo
);
582 route_unlock_node(rp
);
589 route_unlock_node(rp
);
591 /* Now, check to see whether there is already an explicit route
592 for the destination prefix. If there is no such route, add
593 this route to the routing table, unless the metric is
594 infinity (there is no point in adding a route which
596 if (rte
->metric
!= RIP_METRIC_INFINITY
)
597 rip_ecmp_add(&newinfo
);
599 /* Route is there but we are not sure the route is RIP or not.
602 /* If there is an existing route, compare the next hop address
603 to the address of the router from which the datagram came.
604 If this datagram is from the same router as the existing
605 route, reinitialize the timeout. */
606 same
= (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
607 && (rinfo
->nh
.ifindex
== ifp
->ifindex
));
609 old_dist
= rinfo
->distance
? rinfo
->distance
610 : ZEBRA_RIP_DISTANCE_DEFAULT
;
612 /* Next, compare the metrics. If the datagram is from the same
613 router as the existing route, and the new metric is different
614 than the old one; or, if the new metric is lower than the old
615 one, or if the tag has been changed; or if there is a route
616 with a lower administrave distance; or an update of the
617 distance on the actual route; do the following actions: */
618 if ((same
&& rinfo
->metric
!= rte
->metric
)
619 || (rte
->metric
< rinfo
->metric
)
620 || ((same
) && (rinfo
->metric
== rte
->metric
)
621 && (newinfo
.tag
!= rinfo
->tag
))
622 || (old_dist
> new_dist
)
623 || ((old_dist
!= new_dist
) && same
)) {
624 if (listcount(list
) == 1) {
625 if (newinfo
.metric
!= RIP_METRIC_INFINITY
)
626 rip_ecmp_replace(&newinfo
);
628 rip_ecmp_delete(rinfo
);
630 if (newinfo
.metric
< rinfo
->metric
)
631 rip_ecmp_replace(&newinfo
);
632 else if (newinfo
.metric
> rinfo
->metric
)
633 rip_ecmp_delete(rinfo
);
634 else if (new_dist
< old_dist
)
635 rip_ecmp_replace(&newinfo
);
636 else if (new_dist
> old_dist
)
637 rip_ecmp_delete(rinfo
);
639 int update
= CHECK_FLAG(rinfo
->flags
,
644 assert(newinfo
.metric
645 != RIP_METRIC_INFINITY
);
647 RIP_TIMER_OFF(rinfo
->t_timeout
);
648 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
649 memcpy(rinfo
, &newinfo
,
650 sizeof(struct rip_info
));
651 rip_timeout_update(rinfo
);
654 rip_zebra_ipv4_add(rp
);
656 /* - Set the route change flag on the
658 rinfo
= listgetdata(listhead(list
));
659 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
660 rip_event(RIP_TRIGGERED_UPDATE
, 0);
663 } else /* same & no change */
664 rip_timeout_update(rinfo
);
666 /* Unlock tempolary lock of the route. */
667 route_unlock_node(rp
);
671 /* Dump RIP packet */
672 static void rip_packet_dump(struct rip_packet
*packet
, int size
,
677 const char *command_str
;
678 char pbuf
[BUFSIZ
], nbuf
[BUFSIZ
];
682 /* Set command string. */
683 if (packet
->command
> 0 && packet
->command
< RIP_COMMAND_MAX
)
684 command_str
= lookup_msg(rip_msg
, packet
->command
, NULL
);
686 command_str
= "unknown";
688 /* Dump packet header. */
689 zlog_debug("%s %s version %d packet size %d", sndrcv
, command_str
,
690 packet
->version
, size
);
692 /* Dump each routing table entry. */
695 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
696 if (packet
->version
== RIPv2
) {
697 netmask
= ip_masklen(rte
->mask
);
699 if (rte
->family
== htons(RIP_FAMILY_AUTH
)) {
701 == htons(RIP_AUTH_SIMPLE_PASSWORD
)) {
702 p
= (u_char
*)&rte
->prefix
;
705 " family 0x%X type %d auth string: %s",
708 } else if (rte
->tag
== htons(RIP_AUTH_MD5
)) {
709 struct rip_md5_info
*md5
;
711 md5
= (struct rip_md5_info
*)&packet
715 " family 0x%X type %d (MD5 authentication)",
719 " RIP-2 packet len %d Key ID %d"
721 ntohs(md5
->packet_len
),
722 md5
->keyid
, md5
->auth_len
);
724 " Sequence Number %ld",
725 (u_long
)ntohl(md5
->sequence
));
726 } else if (rte
->tag
== htons(RIP_AUTH_DATA
)) {
727 p
= (u_char
*)&rte
->prefix
;
730 " family 0x%X type %d (MD5 data)",
734 " MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
735 "%02X%02X%02X%02X%02X%02X%02X%02X",
736 p
[0], p
[1], p
[2], p
[3], p
[4],
737 p
[5], p
[6], p
[7], p
[8], p
[9],
738 p
[10], p
[11], p
[12], p
[13],
742 " family 0x%X type %d (Unknown auth type)",
748 " %s/%d -> %s family %d tag %" ROUTE_TAG_PRI
750 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
,
753 inet_ntop(AF_INET
, &rte
->nexthop
, nbuf
,
756 (route_tag_t
)ntohs(rte
->tag
),
757 (u_long
)ntohl(rte
->metric
));
760 " %s family %d tag %" ROUTE_TAG_PRI
762 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
764 (route_tag_t
)ntohs(rte
->tag
),
765 (u_long
)ntohl(rte
->metric
));
770 /* Check if the destination address is valid (unicast; not net 0
771 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
772 check net 0 because we accept default route. */
773 static int rip_destination_check(struct in_addr addr
)
775 u_int32_t destination
;
777 /* Convert to host byte order. */
778 destination
= ntohl(addr
.s_addr
);
780 if (IPV4_NET127(destination
))
783 /* Net 0 may match to the default route. */
784 if (IPV4_NET0(destination
) && destination
!= 0)
787 /* Unicast address must belong to class A, B, C. */
788 if (IN_CLASSA(destination
))
790 if (IN_CLASSB(destination
))
792 if (IN_CLASSC(destination
))
798 /* RIP version 2 authentication. */
799 static int rip_auth_simple_password(struct rte
*rte
, struct sockaddr_in
*from
,
800 struct interface
*ifp
)
802 struct rip_interface
*ri
;
803 char *auth_str
= (char *)&rte
->prefix
;
806 /* reject passwords with zeros in the middle of the string */
807 for (i
= strlen(auth_str
); i
< 16; i
++) {
808 if (auth_str
[i
] != '\0')
812 if (IS_RIP_DEBUG_EVENT
)
813 zlog_debug("RIPv2 simple password authentication from %s",
814 inet_ntoa(from
->sin_addr
));
818 if (ri
->auth_type
!= RIP_AUTH_SIMPLE_PASSWORD
819 || rte
->tag
!= htons(RIP_AUTH_SIMPLE_PASSWORD
))
822 /* Simple password authentication. */
824 if (strncmp(auth_str
, ri
->auth_str
, 16) == 0)
828 struct keychain
*keychain
;
831 keychain
= keychain_lookup(ri
->key_chain
);
832 if (keychain
== NULL
)
835 key
= key_match_for_accept(keychain
, auth_str
);
842 /* RIP version 2 authentication with MD5. */
843 static int rip_auth_md5(struct rip_packet
*packet
, struct sockaddr_in
*from
,
844 int length
, struct interface
*ifp
)
846 struct rip_interface
*ri
;
847 struct rip_md5_info
*md5
;
848 struct rip_md5_data
*md5data
;
849 struct keychain
*keychain
;
852 u_char digest
[RIP_AUTH_MD5_SIZE
];
853 u_int16_t packet_len
;
854 char auth_str
[RIP_AUTH_MD5_SIZE
];
856 if (IS_RIP_DEBUG_EVENT
)
857 zlog_debug("RIPv2 MD5 authentication from %s",
858 inet_ntoa(from
->sin_addr
));
861 md5
= (struct rip_md5_info
*)&packet
->rte
;
863 /* Check auth type. */
864 if (ri
->auth_type
!= RIP_AUTH_MD5
|| md5
->type
!= htons(RIP_AUTH_MD5
))
867 /* If the authentication length is less than 16, then it must be wrong
869 * any interpretation of rfc2082. Some implementations also interpret
870 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka
871 * RIP_AUTH_MD5_COMPAT_SIZE.
873 if (!((md5
->auth_len
== RIP_AUTH_MD5_SIZE
)
874 || (md5
->auth_len
== RIP_AUTH_MD5_COMPAT_SIZE
))) {
875 if (IS_RIP_DEBUG_EVENT
)
877 "RIPv2 MD5 authentication, strange authentication "
883 /* grab and verify check packet length */
884 packet_len
= ntohs(md5
->packet_len
);
886 if (packet_len
> (length
- RIP_HEADER_SIZE
- RIP_AUTH_MD5_SIZE
)) {
887 if (IS_RIP_DEBUG_EVENT
)
889 "RIPv2 MD5 authentication, packet length field %d "
890 "greater than received length %d!",
891 md5
->packet_len
, length
);
895 /* retrieve authentication data */
896 md5data
= (struct rip_md5_data
*)(((u_char
*)packet
) + packet_len
);
898 memset(auth_str
, 0, RIP_AUTH_MD5_SIZE
);
901 keychain
= keychain_lookup(ri
->key_chain
);
902 if (keychain
== NULL
)
905 key
= key_lookup_for_accept(keychain
, md5
->keyid
);
909 strncpy(auth_str
, key
->string
, RIP_AUTH_MD5_SIZE
);
910 } else if (ri
->auth_str
)
911 strncpy(auth_str
, ri
->auth_str
, RIP_AUTH_MD5_SIZE
);
913 if (auth_str
[0] == 0)
916 /* MD5 digest authentication. */
917 memset(&ctx
, 0, sizeof(ctx
));
919 MD5Update(&ctx
, packet
, packet_len
+ RIP_HEADER_SIZE
);
920 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
921 MD5Final(digest
, &ctx
);
923 if (memcmp(md5data
->digest
, digest
, RIP_AUTH_MD5_SIZE
) == 0)
929 /* Pick correct auth string for sends, prepare auth_str buffer for use.
930 * (left justified and padded).
932 * presumes one of ri or key is valid, and that the auth strings they point
933 * to are nul terminated. If neither are present, auth_str will be fully
937 static void rip_auth_prepare_str_send(struct rip_interface
*ri
, struct key
*key
,
938 char *auth_str
, int len
)
942 memset(auth_str
, 0, len
);
943 if (key
&& key
->string
)
944 strncpy(auth_str
, key
->string
, len
);
945 else if (ri
->auth_str
)
946 strncpy(auth_str
, ri
->auth_str
, len
);
951 /* Write RIPv2 simple password authentication information
953 * auth_str is presumed to be 2 bytes and correctly prepared
954 * (left justified and zero padded).
956 static void rip_auth_simple_write(struct stream
*s
, char *auth_str
, int len
)
958 assert(s
&& len
== RIP_AUTH_SIMPLE_SIZE
);
960 stream_putw(s
, RIP_FAMILY_AUTH
);
961 stream_putw(s
, RIP_AUTH_SIMPLE_PASSWORD
);
962 stream_put(s
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
967 /* write RIPv2 MD5 "authentication header"
968 * (uses the auth key data field)
970 * Digest offset field is set to 0.
972 * returns: offset of the digest offset field, which must be set when
973 * length to the auth-data MD5 digest is known.
975 static size_t rip_auth_md5_ah_write(struct stream
*s
, struct rip_interface
*ri
,
980 assert(s
&& ri
&& ri
->auth_type
== RIP_AUTH_MD5
);
982 /* MD5 authentication. */
983 stream_putw(s
, RIP_FAMILY_AUTH
);
984 stream_putw(s
, RIP_AUTH_MD5
);
986 /* MD5 AH digest offset field.
988 * Set to placeholder value here, to true value when RIP-2 Packet length
989 * is known. Actual value is set in .....().
991 doff
= stream_get_endp(s
);
996 stream_putc(s
, key
->index
% 256);
1000 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
1001 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for
1003 * to be configurable.
1005 stream_putc(s
, ri
->md5_auth_len
);
1007 /* Sequence Number (non-decreasing). */
1008 /* RFC2080: The value used in the sequence number is
1009 arbitrary, but two suggestions are the time of the
1010 message's creation or a simple message counter. */
1011 stream_putl(s
, time(NULL
));
1013 /* Reserved field must be zero. */
1020 /* If authentication is in used, write the appropriate header
1021 * returns stream offset to which length must later be written
1022 * or 0 if this is not required
1024 static size_t rip_auth_header_write(struct stream
*s
, struct rip_interface
*ri
,
1025 struct key
*key
, char *auth_str
, int len
)
1027 assert(ri
->auth_type
!= RIP_NO_AUTH
);
1029 switch (ri
->auth_type
) {
1030 case RIP_AUTH_SIMPLE_PASSWORD
:
1031 rip_auth_prepare_str_send(ri
, key
, auth_str
, len
);
1032 rip_auth_simple_write(s
, auth_str
, len
);
1035 return rip_auth_md5_ah_write(s
, ri
, key
);
1041 /* Write RIPv2 MD5 authentication data trailer */
1042 static void rip_auth_md5_set(struct stream
*s
, struct rip_interface
*ri
,
1043 size_t doff
, char *auth_str
, int authlen
)
1047 unsigned char digest
[RIP_AUTH_MD5_SIZE
];
1049 /* Make it sure this interface is configured as MD5
1051 assert((ri
->auth_type
== RIP_AUTH_MD5
)
1052 && (authlen
== RIP_AUTH_MD5_SIZE
));
1055 /* Get packet length. */
1056 len
= stream_get_endp(s
);
1058 /* Check packet length. */
1059 if (len
< (RIP_HEADER_SIZE
+ RIP_RTE_SIZE
)) {
1061 "rip_auth_md5_set(): packet length %ld is less than minimum length.",
1066 /* Set the digest offset length in the header */
1067 stream_putw_at(s
, doff
, len
);
1069 /* Set authentication data. */
1070 stream_putw(s
, RIP_FAMILY_AUTH
);
1071 stream_putw(s
, RIP_AUTH_DATA
);
1073 /* Generate a digest for the RIP packet. */
1074 memset(&ctx
, 0, sizeof(ctx
));
1076 MD5Update(&ctx
, STREAM_DATA(s
), stream_get_endp(s
));
1077 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1078 MD5Final(digest
, &ctx
);
1080 /* Copy the digest to the packet. */
1081 stream_write(s
, digest
, RIP_AUTH_MD5_SIZE
);
1084 /* RIP routing information. */
1085 static void rip_response_process(struct rip_packet
*packet
, int size
,
1086 struct sockaddr_in
*from
,
1087 struct connected
*ifc
)
1091 struct prefix_ipv4 ifaddr
;
1092 struct prefix_ipv4 ifaddrclass
;
1095 memset(&ifaddr
, 0, sizeof(ifaddr
));
1096 /* We don't know yet. */
1099 /* The Response must be ignored if it is not from the RIP
1100 port. (RFC2453 - Sec. 3.9.2)*/
1101 if (from
->sin_port
!= htons(RIP_PORT_DEFAULT
)) {
1102 zlog_info("response doesn't come from RIP port: %d",
1104 rip_peer_bad_packet(from
);
1108 /* The datagram's IPv4 source address should be checked to see
1109 whether the datagram is from a valid neighbor; the source of the
1110 datagram must be on a directly connected network (RFC2453 - Sec.
1112 if (if_lookup_address((void *)&from
->sin_addr
, AF_INET
, VRF_DEFAULT
)
1115 "This datagram doesn't came from a valid neighbor: %s",
1116 inet_ntoa(from
->sin_addr
));
1117 rip_peer_bad_packet(from
);
1121 /* It is also worth checking to see whether the response is from one
1122 of the router's own addresses. */
1124 ; /* Alredy done in rip_read () */
1126 /* Update RIP peer. */
1127 rip_peer_update(from
, packet
->version
);
1129 /* Set RTE pointer. */
1132 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
1133 /* RIPv2 authentication check. */
1134 /* If the Address Family Identifier of the first (and only the
1135 first) entry in the message is 0xFFFF, then the remainder of
1136 the entry contains the authentication. */
1137 /* If the packet gets here it means authentication enabled */
1138 /* Check is done in rip_read(). So, just skipping it */
1139 if (packet
->version
== RIPv2
&& rte
== packet
->rte
1140 && rte
->family
== htons(RIP_FAMILY_AUTH
))
1143 if (rte
->family
!= htons(AF_INET
)) {
1144 /* Address family check. RIP only supports AF_INET. */
1145 zlog_info("Unsupported family %d from %s.",
1147 inet_ntoa(from
->sin_addr
));
1151 /* - is the destination address valid (e.g., unicast; not net 0
1153 if (!rip_destination_check(rte
->prefix
)) {
1155 "Network is net 0 or net 127 or it is not unicast network");
1156 rip_peer_bad_route(from
);
1160 /* Convert metric value to host byte order. */
1161 rte
->metric
= ntohl(rte
->metric
);
1163 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1164 if (!(rte
->metric
>= 1 && rte
->metric
<= 16)) {
1165 zlog_info("Route's metric is not in the 1-16 range.");
1166 rip_peer_bad_route(from
);
1170 /* RIPv1 does not have nexthop value. */
1171 if (packet
->version
== RIPv1
&& rte
->nexthop
.s_addr
!= 0) {
1172 zlog_info("RIPv1 packet with nexthop value %s",
1173 inet_ntoa(rte
->nexthop
));
1174 rip_peer_bad_route(from
);
1178 /* That is, if the provided information is ignored, a possibly
1179 sub-optimal, but absolutely valid, route may be taken. If
1180 the received Next Hop is not directly reachable, it should be
1181 treated as 0.0.0.0. */
1182 if (packet
->version
== RIPv2
&& rte
->nexthop
.s_addr
!= 0) {
1185 /* Multicast address check. */
1186 addrval
= ntohl(rte
->nexthop
.s_addr
);
1187 if (IN_CLASSD(addrval
)) {
1189 "Nexthop %s is multicast address, skip this rte",
1190 inet_ntoa(rte
->nexthop
));
1194 if (!if_lookup_address((void *)&rte
->nexthop
, AF_INET
,
1196 struct route_node
*rn
;
1197 struct rip_info
*rinfo
;
1199 rn
= route_node_match_ipv4(rip
->table
,
1205 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1208 if (IS_RIP_DEBUG_EVENT
)
1210 "Next hop %s is on RIP network. Set nexthop to the packet's originator",
1213 rte
->nexthop
= rinfo
->from
;
1215 if (IS_RIP_DEBUG_EVENT
)
1217 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1220 rte
->nexthop
.s_addr
= 0;
1223 route_unlock_node(rn
);
1225 if (IS_RIP_DEBUG_EVENT
)
1227 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1230 rte
->nexthop
.s_addr
= 0;
1235 /* For RIPv1, there won't be a valid netmask.
1237 This is a best guess at the masks. If everyone was using old
1238 Ciscos before the 'ip subnet zero' option, it would be almost
1241 Cisco summarize ripv1 advertisments to the classful boundary
1242 (/16 for class B's) except when the RIP packet does to inside
1243 the classful network in question. */
1245 if ((packet
->version
== RIPv1
&& rte
->prefix
.s_addr
!= 0)
1246 || (packet
->version
== RIPv2
1247 && (rte
->prefix
.s_addr
!= 0
1248 && rte
->mask
.s_addr
== 0))) {
1249 u_int32_t destination
;
1251 if (subnetted
== -1) {
1252 memcpy(&ifaddr
, ifc
->address
,
1253 sizeof(struct prefix_ipv4
));
1254 memcpy(&ifaddrclass
, &ifaddr
,
1255 sizeof(struct prefix_ipv4
));
1256 apply_classful_mask_ipv4(&ifaddrclass
);
1258 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1262 destination
= ntohl(rte
->prefix
.s_addr
);
1264 if (IN_CLASSA(destination
))
1265 masklen2ip(8, &rte
->mask
);
1266 else if (IN_CLASSB(destination
))
1267 masklen2ip(16, &rte
->mask
);
1268 else if (IN_CLASSC(destination
))
1269 masklen2ip(24, &rte
->mask
);
1272 masklen2ip(ifaddrclass
.prefixlen
,
1273 (struct in_addr
*)&destination
);
1274 if ((subnetted
== 1)
1275 && ((rte
->prefix
.s_addr
& destination
)
1276 == ifaddrclass
.prefix
.s_addr
)) {
1277 masklen2ip(ifaddr
.prefixlen
, &rte
->mask
);
1278 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1279 != rte
->prefix
.s_addr
)
1280 masklen2ip(32, &rte
->mask
);
1281 if (IS_RIP_DEBUG_EVENT
)
1282 zlog_debug("Subnetted route %s",
1283 inet_ntoa(rte
->prefix
));
1285 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1286 != rte
->prefix
.s_addr
)
1290 if (IS_RIP_DEBUG_EVENT
) {
1291 zlog_debug("Resultant route %s",
1292 inet_ntoa(rte
->prefix
));
1293 zlog_debug("Resultant mask %s",
1294 inet_ntoa(rte
->mask
));
1298 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1299 ignore the entry. */
1300 if ((packet
->version
== RIPv2
) && (rte
->mask
.s_addr
!= 0)
1301 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1302 != rte
->prefix
.s_addr
)) {
1304 "RIPv2 address %s is not mask /%d applied one",
1305 inet_ntoa(rte
->prefix
), ip_masklen(rte
->mask
));
1306 rip_peer_bad_route(from
);
1310 /* Default route's netmask is ignored. */
1311 if (packet
->version
== RIPv2
&& (rte
->prefix
.s_addr
== 0)
1312 && (rte
->mask
.s_addr
!= 0)) {
1313 if (IS_RIP_DEBUG_EVENT
)
1315 "Default route with non-zero netmask. Set zero to netmask");
1316 rte
->mask
.s_addr
= 0;
1319 /* Routing table updates. */
1320 rip_rte_process(rte
, from
, ifc
->ifp
);
1324 /* Make socket for RIP protocol. */
1325 static int rip_create_socket(void)
1329 struct sockaddr_in addr
;
1331 memset(&addr
, 0, sizeof(struct sockaddr_in
));
1332 addr
.sin_family
= AF_INET
;
1333 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1334 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1335 addr
.sin_len
= sizeof(struct sockaddr_in
);
1336 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1337 /* sending port must always be the RIP port */
1338 addr
.sin_port
= htons(RIP_PORT_DEFAULT
);
1340 /* Make datagram socket. */
1341 sock
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
1343 zlog_err("Cannot create UDP socket: %s", safe_strerror(errno
));
1347 sockopt_broadcast(sock
);
1348 sockopt_reuseaddr(sock
);
1349 sockopt_reuseport(sock
);
1350 setsockopt_ipv4_multicast_loop(sock
, 0);
1352 setsockopt_pktinfo(sock
);
1353 #endif /* RIP_RECVMSG */
1354 #ifdef IPTOS_PREC_INTERNETCONTROL
1355 setsockopt_ipv4_tos(sock
, IPTOS_PREC_INTERNETCONTROL
);
1358 if (ripd_privs
.change(ZPRIVS_RAISE
))
1359 zlog_err("rip_create_socket: could not raise privs");
1360 setsockopt_so_recvbuf(sock
, RIP_UDP_RCV_BUF
);
1361 if ((ret
= bind(sock
, (struct sockaddr
*)&addr
, sizeof(addr
))) < 0)
1364 int save_errno
= errno
;
1365 if (ripd_privs
.change(ZPRIVS_LOWER
))
1366 zlog_err("rip_create_socket: could not lower privs");
1368 zlog_err("%s: Can't bind socket %d to %s port %d: %s", __func__
,
1369 sock
, inet_ntoa(addr
.sin_addr
),
1370 (int)ntohs(addr
.sin_port
), safe_strerror(save_errno
));
1376 if (ripd_privs
.change(ZPRIVS_LOWER
))
1377 zlog_err("rip_create_socket: could not lower privs");
1382 /* RIP packet send to destination address, on interface denoted by
1383 * by connected argument. NULL to argument denotes destination should be
1384 * should be RIP multicast group
1386 static int rip_send_packet(u_char
*buf
, int size
, struct sockaddr_in
*to
,
1387 struct connected
*ifc
)
1390 struct sockaddr_in sin
;
1392 assert(ifc
!= NULL
);
1394 if (IS_RIP_DEBUG_PACKET
) {
1395 #define ADDRESS_SIZE 20
1396 char dst
[ADDRESS_SIZE
];
1397 dst
[ADDRESS_SIZE
- 1] = '\0';
1400 strncpy(dst
, inet_ntoa(to
->sin_addr
), ADDRESS_SIZE
- 1);
1402 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1403 strncpy(dst
, inet_ntoa(sin
.sin_addr
), ADDRESS_SIZE
- 1);
1406 zlog_debug("rip_send_packet %s > %s (%s)",
1407 inet_ntoa(ifc
->address
->u
.prefix4
), dst
,
1411 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
1413 * ZEBRA_IFA_SECONDARY is set on linux when an interface is
1415 * with multiple addresses on the same subnet: the first address
1416 * on the subnet is configured "primary", and all subsequent
1418 * on that subnet are treated as "secondary" addresses.
1419 * In order to avoid routing-table bloat on other rip listeners,
1420 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY
1422 * XXX Since Linux is the only system for which the
1423 * ZEBRA_IFA_SECONDARY
1424 * flag is set, we would end up sending a packet for a
1426 * source address on non-linux systems.
1428 if (IS_RIP_DEBUG_PACKET
)
1429 zlog_debug("duplicate dropped");
1433 /* Make destination address. */
1434 memset(&sin
, 0, sizeof(struct sockaddr_in
));
1435 sin
.sin_family
= AF_INET
;
1436 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1437 sin
.sin_len
= sizeof(struct sockaddr_in
);
1438 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1440 /* When destination is specified, use it's port and address. */
1442 sin
.sin_port
= to
->sin_port
;
1443 sin
.sin_addr
= to
->sin_addr
;
1445 sin
.sin_port
= htons(RIP_PORT_DEFAULT
);
1446 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1448 rip_interface_multicast_set(rip
->sock
, ifc
);
1451 ret
= sendto(rip
->sock
, buf
, size
, 0, (struct sockaddr
*)&sin
,
1452 sizeof(struct sockaddr_in
));
1454 if (IS_RIP_DEBUG_EVENT
)
1455 zlog_debug("SEND to %s.%d", inet_ntoa(sin
.sin_addr
),
1456 ntohs(sin
.sin_port
));
1459 zlog_warn("can't send packet : %s", safe_strerror(errno
));
1464 /* Add redistributed route to RIP table. */
1465 void rip_redistribute_add(int type
, int sub_type
, struct prefix_ipv4
*p
,
1467 unsigned int metric
, unsigned char distance
,
1471 struct route_node
*rp
= NULL
;
1472 struct rip_info
*rinfo
= NULL
, newinfo
;
1473 struct list
*list
= NULL
;
1475 /* Redistribute route */
1476 ret
= rip_destination_check(p
->prefix
);
1480 rp
= route_node_get(rip
->table
, (struct prefix
*)p
);
1482 memset(&newinfo
, 0, sizeof(struct rip_info
));
1483 newinfo
.type
= type
;
1484 newinfo
.sub_type
= sub_type
;
1486 newinfo
.external_metric
= metric
;
1487 newinfo
.distance
= distance
;
1488 if (tag
<= UINT16_MAX
) /* RIP only supports 16 bit tags */
1493 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
1494 rinfo
= listgetdata(listhead(list
));
1496 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
1497 && rinfo
->sub_type
== RIP_ROUTE_INTERFACE
1498 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
1499 route_unlock_node(rp
);
1503 /* Manually configured RIP route check. */
1504 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1505 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
1506 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))) {
1507 if (type
!= ZEBRA_ROUTE_RIP
1508 || ((sub_type
!= RIP_ROUTE_STATIC
)
1509 && (sub_type
!= RIP_ROUTE_DEFAULT
))) {
1510 route_unlock_node(rp
);
1515 (void)rip_ecmp_replace(&newinfo
);
1516 route_unlock_node(rp
);
1518 (void)rip_ecmp_add(&newinfo
);
1520 if (IS_RIP_DEBUG_EVENT
) {
1522 "Redistribute new prefix %s/%d",
1523 inet_ntoa(p
->prefix
), p
->prefixlen
);
1526 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1529 /* Delete redistributed route from RIP table. */
1530 void rip_redistribute_delete(int type
, int sub_type
, struct prefix_ipv4
*p
,
1534 struct route_node
*rp
;
1535 struct rip_info
*rinfo
;
1537 ret
= rip_destination_check(p
->prefix
);
1541 rp
= route_node_lookup(rip
->table
, (struct prefix
*)p
);
1543 struct list
*list
= rp
->info
;
1545 if (list
!= NULL
&& listcount(list
) != 0) {
1546 rinfo
= listgetdata(listhead(list
));
1547 if (rinfo
!= NULL
&& rinfo
->type
== type
1548 && rinfo
->sub_type
== sub_type
1549 && rinfo
->nh
.ifindex
== ifindex
) {
1550 /* Perform poisoned reverse. */
1551 rinfo
->metric
= RIP_METRIC_INFINITY
;
1552 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
1553 rip_garbage_collect
,
1555 RIP_TIMER_OFF(rinfo
->t_timeout
);
1556 rinfo
->flags
|= RIP_RTF_CHANGED
;
1558 if (IS_RIP_DEBUG_EVENT
)
1560 "Poison %s/%d on the interface %s with an "
1561 "infinity metric [delete]",
1562 inet_ntoa(p
->prefix
),
1564 ifindex2ifname(ifindex
,
1567 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1570 route_unlock_node(rp
);
1574 /* Response to request called from rip_read ().*/
1575 static void rip_request_process(struct rip_packet
*packet
, int size
,
1576 struct sockaddr_in
*from
, struct connected
*ifc
)
1580 struct prefix_ipv4 p
;
1581 struct route_node
*rp
;
1582 struct rip_info
*rinfo
;
1583 struct rip_interface
*ri
;
1585 /* Does not reponse to the requests on the loopback interfaces */
1586 if (if_is_loopback(ifc
->ifp
))
1589 /* Check RIP process is enabled on this interface. */
1590 ri
= ifc
->ifp
->info
;
1594 /* When passive interface is specified, suppress responses */
1598 /* RIP peer update. */
1599 rip_peer_update(from
, packet
->version
);
1601 lim
= ((caddr_t
)packet
) + size
;
1604 /* The Request is processed entry by entry. If there are no
1605 entries, no response is given. */
1606 if (lim
== (caddr_t
)rte
)
1609 /* There is one special case. If there is exactly one entry in the
1610 request, and it has an address family identifier of zero and a
1611 metric of infinity (i.e., 16), then this is a request to send the
1612 entire routing table. */
1613 if (lim
== ((caddr_t
)(rte
+ 1)) && ntohs(rte
->family
) == 0
1614 && ntohl(rte
->metric
) == RIP_METRIC_INFINITY
) {
1615 /* All route with split horizon */
1616 rip_output_process(ifc
, from
, rip_all_route
, packet
->version
);
1618 if (ntohs(rte
->family
) != AF_INET
)
1621 /* Examine the list of RTEs in the Request one by one. For each
1622 entry, look up the destination in the router's routing
1623 database and, if there is a route, put that route's metric in
1624 the metric field of the RTE. If there is no explicit route
1625 to the specified destination, put infinity in the metric
1626 field. Once all the entries have been filled in, change the
1627 command from Request to Response and send the datagram back
1628 to the requestor. */
1631 for (; ((caddr_t
)rte
) < lim
; rte
++) {
1632 p
.prefix
= rte
->prefix
;
1633 p
.prefixlen
= ip_masklen(rte
->mask
);
1634 apply_mask_ipv4(&p
);
1636 rp
= route_node_lookup(rip
->table
, (struct prefix
*)&p
);
1638 rinfo
= listgetdata(
1639 listhead((struct list
*)rp
->info
));
1640 rte
->metric
= htonl(rinfo
->metric
);
1641 route_unlock_node(rp
);
1643 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
1645 packet
->command
= RIP_RESPONSE
;
1647 rip_send_packet((u_char
*)packet
, size
, from
, ifc
);
1649 rip_global_queries
++;
1653 /* Set IPv6 packet info to the socket. */
1654 static int setsockopt_pktinfo(int sock
)
1659 ret
= setsockopt(sock
, IPPROTO_IP
, IP_PKTINFO
, &val
, sizeof(val
));
1661 zlog_warn("Can't setsockopt IP_PKTINFO : %s",
1662 safe_strerror(errno
));
1666 /* Read RIP packet by recvmsg function. */
1667 int rip_recvmsg(int sock
, u_char
*buf
, int size
, struct sockaddr_in
*from
,
1673 struct cmsghdr
*ptr
;
1676 memset(&msg
, 0, sizeof(msg
));
1677 msg
.msg_name
= (void *)from
;
1678 msg
.msg_namelen
= sizeof(struct sockaddr_in
);
1681 msg
.msg_control
= (void *)adata
;
1682 msg
.msg_controllen
= sizeof adata
;
1686 ret
= recvmsg(sock
, &msg
, 0);
1690 for (ptr
= ZCMSG_FIRSTHDR(&msg
); ptr
!= NULL
;
1691 ptr
= CMSG_NXTHDR(&msg
, ptr
))
1692 if (ptr
->cmsg_level
== IPPROTO_IP
1693 && ptr
->cmsg_type
== IP_PKTINFO
) {
1694 struct in_pktinfo
*pktinfo
;
1697 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(ptr
);
1698 i
= pktinfo
->ipi_ifindex
;
1703 /* RIP packet read function. */
1704 int rip_read_new(struct thread
*t
)
1708 char buf
[RIP_PACKET_MAXSIZ
];
1709 struct sockaddr_in from
;
1712 /* Fetch socket then register myself. */
1713 sock
= THREAD_FD(t
);
1714 rip_event(RIP_READ
, sock
);
1716 /* Read RIP packet. */
1717 ret
= rip_recvmsg(sock
, buf
, RIP_PACKET_MAXSIZ
, &from
, (int *)&ifindex
);
1719 zlog_warn("Can't read RIP packet: %s", safe_strerror(errno
));
1725 #endif /* RIP_RECVMSG */
1727 /* First entry point of RIP packet. */
1728 static int rip_read(struct thread
*t
)
1733 union rip_buf rip_buf
;
1734 struct rip_packet
*packet
;
1735 struct sockaddr_in from
;
1739 struct interface
*ifp
= NULL
;
1740 struct connected
*ifc
;
1741 struct rip_interface
*ri
;
1744 /* Fetch socket then register myself. */
1745 sock
= THREAD_FD(t
);
1748 /* Add myself to tne next event */
1749 rip_event(RIP_READ
, sock
);
1751 /* RIPd manages only IPv4. */
1752 memset(&from
, 0, sizeof(struct sockaddr_in
));
1753 fromlen
= sizeof(struct sockaddr_in
);
1755 len
= recvfrom(sock
, (char *)&rip_buf
.buf
, sizeof(rip_buf
.buf
), 0,
1756 (struct sockaddr
*)&from
, &fromlen
);
1758 zlog_info("recvfrom failed: %s", safe_strerror(errno
));
1762 /* Check is this packet comming from myself? */
1763 if (if_check_address(from
.sin_addr
)) {
1764 if (IS_RIP_DEBUG_PACKET
)
1765 zlog_debug("ignore packet comes from myself");
1769 /* Which interface is this packet comes from. */
1770 ifc
= if_lookup_address((void *)&from
.sin_addr
, AF_INET
, VRF_DEFAULT
);
1774 /* RIP packet received */
1775 if (IS_RIP_DEBUG_EVENT
)
1776 zlog_debug("RECV packet from %s port %d on %s",
1777 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1778 ifp
? ifp
->name
: "unknown");
1780 /* If this packet come from unknown interface, ignore it. */
1783 "rip_read: cannot find interface for packet from %s port %d",
1784 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
));
1789 p
.u
.prefix4
= from
.sin_addr
;
1790 p
.prefixlen
= IPV4_MAX_BITLEN
;
1792 ifc
= connected_lookup_prefix(ifp
, &p
);
1796 "rip_read: cannot find connected address for packet from %s "
1797 "port %d on interface %s",
1798 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1803 /* Packet length check. */
1804 if (len
< RIP_PACKET_MINSIZ
) {
1805 zlog_warn("packet size %d is smaller than minimum size %d", len
,
1807 rip_peer_bad_packet(&from
);
1810 if (len
> RIP_PACKET_MAXSIZ
) {
1811 zlog_warn("packet size %d is larger than max size %d", len
,
1813 rip_peer_bad_packet(&from
);
1817 /* Packet alignment check. */
1818 if ((len
- RIP_PACKET_MINSIZ
) % 20) {
1819 zlog_warn("packet size %d is wrong for RIP packet alignment",
1821 rip_peer_bad_packet(&from
);
1825 /* Set RTE number. */
1826 rtenum
= ((len
- RIP_PACKET_MINSIZ
) / 20);
1828 /* For easy to handle. */
1829 packet
= &rip_buf
.rip_packet
;
1831 /* RIP version check. */
1832 if (packet
->version
== 0) {
1833 zlog_info("version 0 with command %d received.",
1835 rip_peer_bad_packet(&from
);
1839 /* Dump RIP packet. */
1840 if (IS_RIP_DEBUG_RECV
)
1841 rip_packet_dump(packet
, len
, "RECV");
1843 /* RIP version adjust. This code should rethink now. RFC1058 says
1844 that "Version 1 implementations are to ignore this extra data and
1845 process only the fields specified in this document.". So RIPv3
1846 packet should be treated as RIPv1 ignoring must be zero field. */
1847 if (packet
->version
> RIPv2
)
1848 packet
->version
= RIPv2
;
1850 /* Is RIP running or is this RIP neighbor ?*/
1852 if (!ri
->running
&& !rip_neighbor_lookup(&from
)) {
1853 if (IS_RIP_DEBUG_EVENT
)
1854 zlog_debug("RIP is not enabled on interface %s.",
1856 rip_peer_bad_packet(&from
);
1860 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1861 vrecv
= ((ri
->ri_receive
== RI_RIP_UNSPEC
) ? rip
->version_recv
1863 if (vrecv
== RI_RIP_VERSION_NONE
1864 || ((packet
->version
== RIPv1
) && !(vrecv
& RIPv1
))
1865 || ((packet
->version
== RIPv2
) && !(vrecv
& RIPv2
))) {
1866 if (IS_RIP_DEBUG_PACKET
)
1868 " packet's v%d doesn't fit to if version spec",
1870 rip_peer_bad_packet(&from
);
1874 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1875 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1876 accepted; authenticated RIP-2 messages shall be discarded. */
1877 if ((ri
->auth_type
== RIP_NO_AUTH
) && rtenum
1878 && (packet
->version
== RIPv2
)
1879 && (packet
->rte
->family
== htons(RIP_FAMILY_AUTH
))) {
1880 if (IS_RIP_DEBUG_EVENT
)
1882 "packet RIPv%d is dropped because authentication disabled",
1884 rip_peer_bad_packet(&from
);
1889 If the router is configured to authenticate RIP-2 messages, then
1890 RIP-1 messages and RIP-2 messages which pass authentication
1891 testing shall be accepted; unauthenticated and failed
1892 authentication RIP-2 messages shall be discarded. For maximum
1893 security, RIP-1 messages should be ignored when authentication is
1894 in use (see section 4.1); otherwise, the routing information from
1895 authenticated messages will be propagated by RIP-1 routers in an
1896 unauthenticated manner.
1898 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1899 * always reply regardless of authentication settings, because:
1901 * - if there other authorised routers on-link, the REQUESTor can
1902 * passively obtain the routing updates anyway
1903 * - if there are no other authorised routers on-link, RIP can
1904 * easily be disabled for the link to prevent giving out information
1905 * on state of this routers RIP routing table..
1907 * I.e. if RIPv1 has any place anymore these days, it's as a very
1908 * simple way to distribute routing information (e.g. to embedded
1909 * hosts / appliances) and the ability to give out RIPv1
1910 * routing-information freely, while still requiring RIPv2
1911 * authentication for any RESPONSEs might be vaguely useful.
1913 if (ri
->auth_type
!= RIP_NO_AUTH
&& packet
->version
== RIPv1
) {
1914 /* Discard RIPv1 messages other than REQUESTs */
1915 if (packet
->command
!= RIP_REQUEST
) {
1916 if (IS_RIP_DEBUG_PACKET
)
1919 " dropped because authentication enabled");
1920 rip_peer_bad_packet(&from
);
1923 } else if (ri
->auth_type
!= RIP_NO_AUTH
) {
1924 const char *auth_desc
;
1927 /* There definitely is no authentication in the packet.
1929 if (IS_RIP_DEBUG_PACKET
)
1931 "RIPv2 authentication failed: no auth RTE in packet");
1932 rip_peer_bad_packet(&from
);
1936 /* First RTE must be an Authentication Family RTE */
1937 if (packet
->rte
->family
!= htons(RIP_FAMILY_AUTH
)) {
1938 if (IS_RIP_DEBUG_PACKET
)
1941 " dropped because authentication enabled");
1942 rip_peer_bad_packet(&from
);
1946 /* Check RIPv2 authentication. */
1947 switch (ntohs(packet
->rte
->tag
)) {
1948 case RIP_AUTH_SIMPLE_PASSWORD
:
1949 auth_desc
= "simple";
1950 ret
= rip_auth_simple_password(packet
->rte
, &from
, ifp
);
1955 ret
= rip_auth_md5(packet
, &from
, len
, ifp
);
1956 /* Reset RIP packet length to trim MD5 data. */
1962 auth_desc
= "unknown type";
1963 if (IS_RIP_DEBUG_PACKET
)
1965 "RIPv2 Unknown authentication type %d",
1966 ntohs(packet
->rte
->tag
));
1970 if (IS_RIP_DEBUG_PACKET
)
1971 zlog_debug("RIPv2 %s authentication success",
1974 if (IS_RIP_DEBUG_PACKET
)
1975 zlog_debug("RIPv2 %s authentication failure",
1977 rip_peer_bad_packet(&from
);
1982 /* Process each command. */
1983 switch (packet
->command
) {
1985 rip_response_process(packet
, len
, &from
, ifc
);
1989 rip_request_process(packet
, len
, &from
, ifc
);
1994 "Obsolete command %s received, please sent it to routed",
1995 lookup_msg(rip_msg
, packet
->command
, NULL
));
1996 rip_peer_bad_packet(&from
);
1998 case RIP_POLL_ENTRY
:
1999 zlog_info("Obsolete command %s received",
2000 lookup_msg(rip_msg
, packet
->command
, NULL
));
2001 rip_peer_bad_packet(&from
);
2004 zlog_info("Unknown RIP command %d received", packet
->command
);
2005 rip_peer_bad_packet(&from
);
2012 /* Write routing table entry to the stream and return next index of
2013 the routing table entry in the stream. */
2014 static int rip_write_rte(int num
, struct stream
*s
, struct prefix_ipv4
*p
,
2015 u_char version
, struct rip_info
*rinfo
)
2017 struct in_addr mask
;
2019 /* Write routing table entry. */
2020 if (version
== RIPv1
) {
2021 stream_putw(s
, AF_INET
);
2023 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2024 stream_put_ipv4(s
, 0);
2025 stream_put_ipv4(s
, 0);
2026 stream_putl(s
, rinfo
->metric_out
);
2028 masklen2ip(p
->prefixlen
, &mask
);
2030 stream_putw(s
, AF_INET
);
2031 stream_putw(s
, rinfo
->tag_out
);
2032 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2033 stream_put_ipv4(s
, mask
.s_addr
);
2034 stream_put_ipv4(s
, rinfo
->nexthop_out
.s_addr
);
2035 stream_putl(s
, rinfo
->metric_out
);
2041 /* Send update to the ifp or spcified neighbor. */
2042 void rip_output_process(struct connected
*ifc
, struct sockaddr_in
*to
,
2043 int route_type
, u_char version
)
2047 struct route_node
*rp
;
2048 struct rip_info
*rinfo
;
2049 struct rip_interface
*ri
;
2050 struct prefix_ipv4
*p
;
2051 struct prefix_ipv4 classfull
;
2052 struct prefix_ipv4 ifaddrclass
;
2053 struct key
*key
= NULL
;
2054 /* this might need to made dynamic if RIP ever supported auth methods
2055 with larger key string sizes */
2056 char auth_str
[RIP_AUTH_SIMPLE_SIZE
];
2057 size_t doff
= 0; /* offset of digest offset field */
2061 struct list
*list
= NULL
;
2062 struct listnode
*listnode
= NULL
;
2064 /* Logging output event. */
2065 if (IS_RIP_DEBUG_EVENT
) {
2067 zlog_debug("update routes to neighbor %s",
2068 inet_ntoa(to
->sin_addr
));
2070 zlog_debug("update routes on interface %s ifindex %d",
2071 ifc
->ifp
->name
, ifc
->ifp
->ifindex
);
2074 /* Set output stream. */
2077 /* Reset stream and RTE counter. */
2079 rtemax
= RIP_MAX_RTE
;
2081 /* Get RIP interface. */
2082 ri
= ifc
->ifp
->info
;
2084 /* If output interface is in simple password authentication mode, we
2085 need space for authentication data. */
2086 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2089 /* If output interface is in MD5 authentication mode, we need space
2090 for authentication header and data. */
2091 if (ri
->auth_type
== RIP_AUTH_MD5
)
2094 /* If output interface is in simple password authentication mode
2095 and string or keychain is specified we need space for auth. data */
2096 if (ri
->auth_type
!= RIP_NO_AUTH
) {
2097 if (ri
->key_chain
) {
2098 struct keychain
*keychain
;
2100 keychain
= keychain_lookup(ri
->key_chain
);
2102 key
= key_lookup_for_send(keychain
);
2104 /* to be passed to auth functions later */
2105 rip_auth_prepare_str_send(ri
, key
, auth_str
,
2106 RIP_AUTH_SIMPLE_SIZE
);
2109 if (version
== RIPv1
) {
2110 memcpy(&ifaddrclass
, ifc
->address
, sizeof(struct prefix_ipv4
));
2111 apply_classful_mask_ipv4(&ifaddrclass
);
2113 if (ifc
->address
->prefixlen
> ifaddrclass
.prefixlen
)
2117 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2118 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
2119 rinfo
= listgetdata(listhead(list
));
2120 /* For RIPv1, if we are subnetted, output subnets in our
2122 /* that have the same mask as the output "interface".
2124 /* networks, only the classfull version is output. */
2126 if (version
== RIPv1
) {
2127 p
= (struct prefix_ipv4
*)&rp
->p
;
2129 if (IS_RIP_DEBUG_PACKET
)
2131 "RIPv1 mask check, %s/%d considered for output",
2132 inet_ntoa(rp
->p
.u
.prefix4
),
2137 (struct prefix
*)&ifaddrclass
,
2139 if ((ifc
->address
->prefixlen
2141 && (rp
->p
.prefixlen
!= 32))
2144 memcpy(&classfull
, &rp
->p
,
2145 sizeof(struct prefix_ipv4
));
2146 apply_classful_mask_ipv4(&classfull
);
2147 if (rp
->p
.u
.prefix4
.s_addr
!= 0
2148 && classfull
.prefixlen
2152 if (IS_RIP_DEBUG_PACKET
)
2154 "RIPv1 mask check, %s/%d made it through",
2155 inet_ntoa(rp
->p
.u
.prefix4
),
2158 p
= (struct prefix_ipv4
*)&rp
->p
;
2160 /* Apply output filters. */
2161 ret
= rip_filter(RIP_FILTER_OUT
, p
, ri
);
2165 /* Changed route only output. */
2166 if (route_type
== rip_changed_route
2167 && (!(rinfo
->flags
& RIP_RTF_CHANGED
)))
2170 /* Split horizon. */
2171 /* if (split_horizon == rip_split_horizon) */
2172 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
) {
2174 * We perform split horizon for RIP and
2176 * For rip routes, we want to suppress the route
2178 * end up sending the route back on the
2180 * learned it from, with a higher metric. For
2182 * we suppress the route if the prefix is a
2184 * source address that we are going to use for
2186 * (in order to handle the case when multiple
2188 * configured on the same interface).
2191 struct rip_info
*tmp_rinfo
= NULL
;
2193 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2195 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2196 && tmp_rinfo
->nh
.ifindex
2197 == ifc
->ifp
->ifindex
) {
2203 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
2204 && prefix_match((struct prefix
*)p
,
2212 /* Preparation for route-map. */
2213 rinfo
->metric_set
= 0;
2214 rinfo
->nexthop_out
.s_addr
= 0;
2215 rinfo
->metric_out
= rinfo
->metric
;
2216 rinfo
->tag_out
= rinfo
->tag
;
2217 rinfo
->ifindex_out
= ifc
->ifp
->ifindex
;
2219 /* In order to avoid some local loops,
2220 * if the RIP route has a nexthop via this interface,
2222 * otherwise set it to 0. The nexthop should not be
2224 * beyond the local broadcast/multicast area in order
2225 * to avoid an IGP multi-level recursive look-up.
2228 if (rinfo
->nh
.ifindex
== ifc
->ifp
->ifindex
)
2229 rinfo
->nexthop_out
= rinfo
->nh
.gate
.ipv4
;
2231 /* Interface route-map */
2232 if (ri
->routemap
[RIP_FILTER_OUT
]) {
2233 ret
= route_map_apply(
2234 ri
->routemap
[RIP_FILTER_OUT
],
2235 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2237 if (ret
== RMAP_DENYMATCH
) {
2238 if (IS_RIP_DEBUG_PACKET
)
2240 "RIP %s/%d is filtered by route-map out",
2241 inet_ntoa(p
->prefix
),
2247 /* Apply redistribute route map - continue, if deny */
2248 if (rip
->route_map
[rinfo
->type
].name
2249 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2250 ret
= route_map_apply(
2251 rip
->route_map
[rinfo
->type
].map
,
2252 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2254 if (ret
== RMAP_DENYMATCH
) {
2255 if (IS_RIP_DEBUG_PACKET
)
2257 "%s/%d is filtered by route-map",
2258 inet_ntoa(p
->prefix
),
2264 /* When route-map does not set metric. */
2265 if (!rinfo
->metric_set
) {
2266 /* If redistribute metric is set. */
2267 if (rip
->route_map
[rinfo
->type
].metric_config
2268 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
2270 rip
->route_map
[rinfo
->type
]
2273 /* If the route is not connected or
2275 one, use default-metric value*/
2276 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2278 != ZEBRA_ROUTE_CONNECT
2280 != RIP_METRIC_INFINITY
)
2282 rip
->default_metric
;
2286 /* Apply offset-list */
2287 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2288 rip_offset_list_apply_out(p
, ifc
->ifp
,
2289 &rinfo
->metric_out
);
2291 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2292 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2294 /* Perform split-horizon with poisoned reverse
2295 * for RIP and connected routes.
2297 if (ri
->split_horizon
2298 == RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2300 * We perform split horizon for RIP and
2302 * For rip routes, we want to suppress the route
2304 * end up sending the route back on the
2306 * learned it from, with a higher metric. For
2308 * we suppress the route if the prefix is a
2310 * source address that we are going to use for
2312 * (in order to handle the case when multiple
2314 * configured on the same interface).
2316 struct rip_info
*tmp_rinfo
= NULL
;
2318 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2320 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2321 && tmp_rinfo
->nh
.ifindex
2322 == ifc
->ifp
->ifindex
)
2323 tmp_rinfo
->metric_out
=
2324 RIP_METRIC_INFINITY
;
2326 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
2327 && prefix_match((struct prefix
*)p
,
2330 RIP_METRIC_INFINITY
;
2333 /* Prepare preamble, auth headers, if needs be */
2335 stream_putc(s
, RIP_RESPONSE
);
2336 stream_putc(s
, version
);
2339 /* auth header for !v1 && !no_auth */
2340 if ((ri
->auth_type
!= RIP_NO_AUTH
)
2341 && (version
!= RIPv1
))
2342 doff
= rip_auth_header_write(
2343 s
, ri
, key
, auth_str
,
2344 RIP_AUTH_SIMPLE_SIZE
);
2347 /* Write RTE to the stream. */
2348 num
= rip_write_rte(num
, s
, p
, version
, rinfo
);
2349 if (num
== rtemax
) {
2350 if (version
== RIPv2
2351 && ri
->auth_type
== RIP_AUTH_MD5
)
2352 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2353 RIP_AUTH_SIMPLE_SIZE
);
2355 ret
= rip_send_packet(STREAM_DATA(s
),
2356 stream_get_endp(s
), to
,
2359 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2360 rip_packet_dump((struct rip_packet
*)
2369 /* Flush unwritten RTE. */
2371 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2372 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2373 RIP_AUTH_SIMPLE_SIZE
);
2375 ret
= rip_send_packet(STREAM_DATA(s
), stream_get_endp(s
), to
,
2378 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2379 rip_packet_dump((struct rip_packet
*)STREAM_DATA(s
),
2380 stream_get_endp(s
), "SEND");
2384 /* Statistics updates. */
2388 /* Send RIP packet to the interface. */
2389 static void rip_update_interface(struct connected
*ifc
, u_char version
,
2392 struct interface
*ifp
= ifc
->ifp
;
2393 struct rip_interface
*ri
= ifp
->info
;
2394 struct sockaddr_in to
;
2396 /* When RIP version is 2 and multicast enable interface. */
2397 if (version
== RIPv2
&& !ri
->v2_broadcast
&& if_is_multicast(ifp
)) {
2398 if (IS_RIP_DEBUG_EVENT
)
2399 zlog_debug("multicast announce on %s ", ifp
->name
);
2401 rip_output_process(ifc
, NULL
, route_type
, version
);
2405 /* If we can't send multicast packet, send it with unicast. */
2406 if (if_is_broadcast(ifp
) || if_is_pointopoint(ifp
)) {
2407 if (ifc
->address
->family
== AF_INET
) {
2408 /* Destination address and port setting. */
2409 memset(&to
, 0, sizeof(struct sockaddr_in
));
2410 if (ifc
->destination
)
2411 /* use specified broadcast or peer destination
2413 to
.sin_addr
= ifc
->destination
->u
.prefix4
;
2414 else if (ifc
->address
->prefixlen
< IPV4_MAX_PREFIXLEN
)
2415 /* calculate the appropriate broadcast address
2417 to
.sin_addr
.s_addr
= ipv4_broadcast_addr(
2418 ifc
->address
->u
.prefix4
.s_addr
,
2419 ifc
->address
->prefixlen
);
2421 /* do not know where to send the packet */
2423 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2425 if (IS_RIP_DEBUG_EVENT
)
2426 zlog_debug("%s announce to %s on %s",
2427 CONNECTED_PEER(ifc
) ? "unicast"
2429 inet_ntoa(to
.sin_addr
), ifp
->name
);
2431 rip_output_process(ifc
, &to
, route_type
, version
);
2436 /* Update send to all interface and neighbor. */
2437 static void rip_update_process(int route_type
)
2439 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2440 struct listnode
*ifnode
, *ifnnode
;
2441 struct connected
*connected
;
2442 struct interface
*ifp
;
2443 struct rip_interface
*ri
;
2444 struct route_node
*rp
;
2445 struct sockaddr_in to
;
2448 /* Send RIP update to each interface. */
2449 FOR_ALL_INTERFACES (vrf
, ifp
) {
2450 if (if_is_loopback(ifp
))
2453 if (!if_is_operative(ifp
))
2456 /* Fetch RIP interface information. */
2459 /* When passive interface is specified, suppress announce to the
2466 * If there is no version configuration in the
2468 * use rip's version setting.
2470 int vsend
= ((ri
->ri_send
== RI_RIP_UNSPEC
)
2474 if (IS_RIP_DEBUG_EVENT
)
2475 zlog_debug("SEND UPDATE to %s ifindex %d",
2476 ifp
->name
, ifp
->ifindex
);
2478 /* send update on each connected network */
2479 for (ALL_LIST_ELEMENTS(ifp
->connected
, ifnode
, ifnnode
,
2481 if (connected
->address
->family
== AF_INET
) {
2483 rip_update_interface(
2487 && if_is_multicast(ifp
))
2488 rip_update_interface(
2496 /* RIP send updates to each neighbor. */
2497 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
2498 if (rp
->info
!= NULL
) {
2501 connected
= if_lookup_address(&p
->u
.prefix4
, AF_INET
,
2505 "Neighbor %s doesnt have connected interface!",
2506 inet_ntoa(p
->u
.prefix4
));
2510 /* Set destination address and port */
2511 memset(&to
, 0, sizeof(struct sockaddr_in
));
2512 to
.sin_addr
= p
->u
.prefix4
;
2513 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2515 /* RIP version is rip's configuration. */
2516 rip_output_process(connected
, &to
, route_type
,
2521 /* RIP's periodical timer. */
2522 static int rip_update(struct thread
*t
)
2524 /* Clear timer pointer. */
2525 rip
->t_update
= NULL
;
2527 if (IS_RIP_DEBUG_EVENT
)
2528 zlog_debug("update timer fire!");
2530 /* Process update output. */
2531 rip_update_process(rip_all_route
);
2533 /* Triggered updates may be suppressed if a regular update is due by
2534 the time the triggered update would be sent. */
2535 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2538 /* Register myself. */
2539 rip_event(RIP_UPDATE_EVENT
, 0);
2544 /* Walk down the RIP routing table then clear changed flag. */
2545 static void rip_clear_changed_flag(void)
2547 struct route_node
*rp
;
2548 struct rip_info
*rinfo
= NULL
;
2549 struct list
*list
= NULL
;
2550 struct listnode
*listnode
= NULL
;
2552 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2553 if ((list
= rp
->info
) != NULL
)
2554 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
2555 UNSET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2556 /* This flag can be set only on the first entry.
2562 /* Triggered update interval timer. */
2563 static int rip_triggered_interval(struct thread
*t
)
2565 int rip_triggered_update(struct thread
*);
2567 rip
->t_triggered_interval
= NULL
;
2571 rip_triggered_update(t
);
2576 /* Execute triggered update. */
2577 static int rip_triggered_update(struct thread
*t
)
2581 /* Clear thred pointer. */
2582 rip
->t_triggered_update
= NULL
;
2584 /* Cancel interval timer. */
2585 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2588 /* Logging triggered update. */
2589 if (IS_RIP_DEBUG_EVENT
)
2590 zlog_debug("triggered update!");
2592 /* Split Horizon processing is done when generating triggered
2593 updates as well as normal updates (see section 2.6). */
2594 rip_update_process(rip_changed_route
);
2596 /* Once all of the triggered updates have been generated, the route
2597 change flags should be cleared. */
2598 rip_clear_changed_flag();
2600 /* After a triggered update is sent, a timer should be set for a
2601 random interval between 1 and 5 seconds. If other changes that
2602 would trigger updates occur before the timer expires, a single
2603 update is triggered when the timer expires. */
2604 interval
= (random() % 5) + 1;
2606 rip
->t_triggered_interval
= NULL
;
2607 thread_add_timer(master
, rip_triggered_interval
, NULL
, interval
,
2608 &rip
->t_triggered_interval
);
2613 /* Withdraw redistributed route. */
2614 void rip_redistribute_withdraw(int type
)
2616 struct route_node
*rp
;
2617 struct rip_info
*rinfo
= NULL
;
2618 struct list
*list
= NULL
;
2623 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2624 if ((list
= rp
->info
) != NULL
) {
2625 rinfo
= listgetdata(listhead(list
));
2626 if (rinfo
->type
== type
2627 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2628 /* Perform poisoned reverse. */
2629 rinfo
->metric
= RIP_METRIC_INFINITY
;
2630 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
2631 rip_garbage_collect
,
2633 RIP_TIMER_OFF(rinfo
->t_timeout
);
2634 rinfo
->flags
|= RIP_RTF_CHANGED
;
2636 if (IS_RIP_DEBUG_EVENT
) {
2637 struct prefix_ipv4
*p
=
2638 (struct prefix_ipv4
*)&rp
->p
;
2641 "Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2642 inet_ntoa(p
->prefix
),
2649 rip_event(RIP_TRIGGERED_UPDATE
, 0);
2654 /* Create new RIP instance and set it to global variable. */
2655 static int rip_create(void)
2657 rip
= XCALLOC(MTYPE_RIP
, sizeof(struct rip
));
2659 /* Set initial value. */
2660 rip
->version_send
= RI_RIP_VERSION_2
;
2661 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2662 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
2663 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
2664 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
2665 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2667 /* Initialize RIP routig table. */
2668 rip
->table
= route_table_init();
2669 rip
->route
= route_table_init();
2670 rip
->neighbor
= route_table_init();
2672 /* Make output stream. */
2673 rip
->obuf
= stream_new(1500);
2676 rip
->sock
= rip_create_socket();
2680 /* Create read and timer thread. */
2681 rip_event(RIP_READ
, rip
->sock
);
2682 rip_event(RIP_UPDATE_EVENT
, 1);
2689 /* Sned RIP request to the destination. */
2690 int rip_request_send(struct sockaddr_in
*to
, struct interface
*ifp
,
2691 u_char version
, struct connected
*connected
)
2694 struct rip_packet rip_packet
;
2695 struct listnode
*node
, *nnode
;
2697 memset(&rip_packet
, 0, sizeof(rip_packet
));
2699 rip_packet
.command
= RIP_REQUEST
;
2700 rip_packet
.version
= version
;
2701 rte
= rip_packet
.rte
;
2702 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
2706 * connected is only sent for ripv1 case, or when
2707 * interface does not support multicast. Caller loops
2708 * over each connected address for this case.
2710 if (rip_send_packet((u_char
*)&rip_packet
, sizeof(rip_packet
),
2712 != sizeof(rip_packet
))
2715 return sizeof(rip_packet
);
2718 /* send request on each connected network */
2719 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, connected
)) {
2720 struct prefix_ipv4
*p
;
2722 p
= (struct prefix_ipv4
*)connected
->address
;
2724 if (p
->family
!= AF_INET
)
2727 if (rip_send_packet((u_char
*)&rip_packet
, sizeof(rip_packet
),
2729 != sizeof(rip_packet
))
2732 return sizeof(rip_packet
);
2735 static int rip_update_jitter(unsigned long time
)
2737 #define JITTER_BOUND 4
2738 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2739 Given that, we cannot let time be less than JITTER_BOUND seconds.
2740 The RIPv2 RFC says jitter should be small compared to
2741 update_time. We consider 1/JITTER_BOUND to be small.
2744 int jitter_input
= time
;
2747 if (jitter_input
< JITTER_BOUND
)
2748 jitter_input
= JITTER_BOUND
;
2750 jitter
= (((random() % ((jitter_input
* 2) + 1)) - jitter_input
));
2752 return jitter
/ JITTER_BOUND
;
2755 void rip_event(enum rip_event event
, int sock
)
2762 thread_add_read(master
, rip_read
, NULL
, sock
, &rip
->t_read
);
2764 case RIP_UPDATE_EVENT
:
2765 RIP_TIMER_OFF(rip
->t_update
);
2766 jitter
= rip_update_jitter(rip
->update_time
);
2767 thread_add_timer(master
, rip_update
, NULL
,
2768 sock
? 2 : rip
->update_time
+ jitter
,
2771 case RIP_TRIGGERED_UPDATE
:
2772 if (rip
->t_triggered_interval
)
2775 thread_add_event(master
, rip_triggered_update
, NULL
, 0,
2776 &rip
->t_triggered_update
);
2783 DEFUN_NOSH (router_rip
,
2786 "Enable a routing process\n"
2787 "Routing Information Protocol (RIP)\n")
2791 /* If rip is not enabled before. */
2795 zlog_info("Can't create RIP");
2796 return CMD_WARNING_CONFIG_FAILED
;
2799 VTY_PUSH_CONTEXT(RIP_NODE
, rip
);
2804 DEFUN (no_router_rip
,
2808 "Enable a routing process\n"
2809 "Routing Information Protocol (RIP)\n")
2819 "Set routing protocol version\n"
2825 version
= atoi(argv
[idx_number
]->arg
);
2826 if (version
!= RIPv1
&& version
!= RIPv2
) {
2827 vty_out(vty
, "invalid rip version %d\n", version
);
2828 return CMD_WARNING_CONFIG_FAILED
;
2830 rip
->version_send
= version
;
2831 rip
->version_recv
= version
;
2836 DEFUN (no_rip_version
,
2838 "no version [(1-2)]",
2840 "Set routing protocol version\n"
2843 /* Set RIP version to the default. */
2844 rip
->version_send
= RI_RIP_VERSION_2
;
2845 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2854 "RIP static route configuration\n"
2855 "IP prefix <network>/<length>\n")
2857 int idx_ipv4_prefixlen
= 1;
2860 struct prefix_ipv4 p
;
2861 struct route_node
*node
;
2863 memset(&nh
, 0, sizeof(nh
));
2864 nh
.type
= NEXTHOP_TYPE_IPV4
;
2866 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
2868 vty_out(vty
, "Malformed address\n");
2869 return CMD_WARNING_CONFIG_FAILED
;
2871 apply_mask_ipv4(&p
);
2873 /* For router rip configuration. */
2874 node
= route_node_get(rip
->route
, (struct prefix
*)&p
);
2877 vty_out(vty
, "There is already same static route.\n");
2878 route_unlock_node(node
);
2882 node
->info
= (void *)1;
2884 rip_redistribute_add(ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, &nh
, 0,
2890 DEFUN (no_rip_route
,
2892 "no route A.B.C.D/M",
2894 "RIP static route configuration\n"
2895 "IP prefix <network>/<length>\n")
2897 int idx_ipv4_prefixlen
= 2;
2899 struct prefix_ipv4 p
;
2900 struct route_node
*node
;
2902 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
2904 vty_out(vty
, "Malformed address\n");
2905 return CMD_WARNING_CONFIG_FAILED
;
2907 apply_mask_ipv4(&p
);
2909 /* For router rip configuration. */
2910 node
= route_node_lookup(rip
->route
, (struct prefix
*)&p
);
2912 vty_out(vty
, "Can't find route %s.\n",
2913 argv
[idx_ipv4_prefixlen
]->arg
);
2914 return CMD_WARNING_CONFIG_FAILED
;
2917 rip_redistribute_delete(ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0);
2918 route_unlock_node(node
);
2921 route_unlock_node(node
);
2928 rip_update_default_metric (void)
2930 struct route_node
*np
;
2931 struct rip_info
*rinfo
= NULL
;
2932 struct list
*list
= NULL
;
2933 struct listnode
*listnode
= NULL
;
2935 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
2936 if ((list
= np
->info
) != NULL
)
2937 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
2938 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
2939 rinfo
->metric
= rip
->default_metric
;
2943 DEFUN (rip_default_metric
,
2944 rip_default_metric_cmd
,
2945 "default-metric (1-16)",
2946 "Set a metric of redistribute routes\n"
2951 rip
->default_metric
= atoi(argv
[idx_number
]->arg
);
2952 /* rip_update_default_metric (); */
2957 DEFUN (no_rip_default_metric
,
2958 no_rip_default_metric_cmd
,
2959 "no default-metric [(1-16)]",
2961 "Set a metric of redistribute routes\n"
2965 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2966 /* rip_update_default_metric (); */
2974 "timers basic (5-2147483647) (5-2147483647) (5-2147483647)",
2975 "Adjust routing timers\n"
2976 "Basic routing protocol update timers\n"
2977 "Routing table update timer value in second. Default is 30.\n"
2978 "Routing information timeout timer. Default is 180.\n"
2979 "Garbage collection timer. Default is 120.\n")
2982 int idx_number_2
= 3;
2983 int idx_number_3
= 4;
2984 unsigned long update
;
2985 unsigned long timeout
;
2986 unsigned long garbage
;
2987 char *endptr
= NULL
;
2988 unsigned long RIP_TIMER_MAX
= 2147483647;
2989 unsigned long RIP_TIMER_MIN
= 5;
2991 update
= strtoul(argv
[idx_number
]->arg
, &endptr
, 10);
2992 if (update
> RIP_TIMER_MAX
|| update
< RIP_TIMER_MIN
2993 || *endptr
!= '\0') {
2994 vty_out(vty
, "update timer value error\n");
2995 return CMD_WARNING_CONFIG_FAILED
;
2998 timeout
= strtoul(argv
[idx_number_2
]->arg
, &endptr
, 10);
2999 if (timeout
> RIP_TIMER_MAX
|| timeout
< RIP_TIMER_MIN
3000 || *endptr
!= '\0') {
3001 vty_out(vty
, "timeout timer value error\n");
3002 return CMD_WARNING_CONFIG_FAILED
;
3005 garbage
= strtoul(argv
[idx_number_3
]->arg
, &endptr
, 10);
3006 if (garbage
> RIP_TIMER_MAX
|| garbage
< RIP_TIMER_MIN
3007 || *endptr
!= '\0') {
3008 vty_out(vty
, "garbage timer value error\n");
3009 return CMD_WARNING_CONFIG_FAILED
;
3012 /* Set each timer value. */
3013 rip
->update_time
= update
;
3014 rip
->timeout_time
= timeout
;
3015 rip
->garbage_time
= garbage
;
3017 /* Reset update timer thread. */
3018 rip_event(RIP_UPDATE_EVENT
, 0);
3023 DEFUN (no_rip_timers
,
3025 "no timers basic [(0-65535) (0-65535) (0-65535)]",
3027 "Adjust routing timers\n"
3028 "Basic routing protocol update timers\n"
3029 "Routing table update timer value in second. Default is 30.\n"
3030 "Routing information timeout timer. Default is 180.\n"
3031 "Garbage collection timer. Default is 120.\n")
3033 /* Set each timer value to the default. */
3034 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
3035 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
3036 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
3038 /* Reset update timer thread. */
3039 rip_event(RIP_UPDATE_EVENT
, 0);
3045 struct route_table
*rip_distance_table
;
3047 struct rip_distance
{
3048 /* Distance value for the IP source prefix. */
3051 /* Name of the access-list to be matched. */
3055 static struct rip_distance
*rip_distance_new(void)
3057 return XCALLOC(MTYPE_RIP_DISTANCE
, sizeof(struct rip_distance
));
3060 static void rip_distance_free(struct rip_distance
*rdistance
)
3062 XFREE(MTYPE_RIP_DISTANCE
, rdistance
);
3065 static int rip_distance_set(struct vty
*vty
, const char *distance_str
,
3066 const char *ip_str
, const char *access_list_str
)
3069 struct prefix_ipv4 p
;
3071 struct route_node
*rn
;
3072 struct rip_distance
*rdistance
;
3074 ret
= str2prefix_ipv4(ip_str
, &p
);
3076 vty_out(vty
, "Malformed prefix\n");
3077 return CMD_WARNING_CONFIG_FAILED
;
3080 distance
= atoi(distance_str
);
3082 /* Get RIP distance node. */
3083 rn
= route_node_get(rip_distance_table
, (struct prefix
*)&p
);
3085 rdistance
= rn
->info
;
3086 route_unlock_node(rn
);
3088 rdistance
= rip_distance_new();
3089 rn
->info
= rdistance
;
3092 /* Set distance value. */
3093 rdistance
->distance
= distance
;
3095 /* Reset access-list configuration. */
3096 if (rdistance
->access_list
) {
3097 free(rdistance
->access_list
);
3098 rdistance
->access_list
= NULL
;
3100 if (access_list_str
)
3101 rdistance
->access_list
= strdup(access_list_str
);
3106 static int rip_distance_unset(struct vty
*vty
, const char *distance_str
,
3107 const char *ip_str
, const char *access_list_str
)
3110 struct prefix_ipv4 p
;
3111 struct route_node
*rn
;
3112 struct rip_distance
*rdistance
;
3114 ret
= str2prefix_ipv4(ip_str
, &p
);
3116 vty_out(vty
, "Malformed prefix\n");
3117 return CMD_WARNING_CONFIG_FAILED
;
3120 rn
= route_node_lookup(rip_distance_table
, (struct prefix
*)&p
);
3122 vty_out(vty
, "Can't find specified prefix\n");
3123 return CMD_WARNING_CONFIG_FAILED
;
3126 rdistance
= rn
->info
;
3128 if (rdistance
->access_list
)
3129 free(rdistance
->access_list
);
3130 rip_distance_free(rdistance
);
3133 route_unlock_node(rn
);
3134 route_unlock_node(rn
);
3139 static void rip_distance_reset(void)
3141 struct route_node
*rn
;
3142 struct rip_distance
*rdistance
;
3144 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
3145 if ((rdistance
= rn
->info
) != NULL
) {
3146 if (rdistance
->access_list
)
3147 free(rdistance
->access_list
);
3148 rip_distance_free(rdistance
);
3150 route_unlock_node(rn
);
3154 /* Apply RIP information to distance method. */
3155 u_char
rip_distance_apply(struct rip_info
*rinfo
)
3157 struct route_node
*rn
;
3158 struct prefix_ipv4 p
;
3159 struct rip_distance
*rdistance
;
3160 struct access_list
*alist
;
3165 memset(&p
, 0, sizeof(struct prefix_ipv4
));
3167 p
.prefix
= rinfo
->from
;
3168 p
.prefixlen
= IPV4_MAX_BITLEN
;
3170 /* Check source address. */
3171 rn
= route_node_match(rip_distance_table
, (struct prefix
*)&p
);
3173 rdistance
= rn
->info
;
3174 route_unlock_node(rn
);
3176 if (rdistance
->access_list
) {
3177 alist
= access_list_lookup(AFI_IP
,
3178 rdistance
->access_list
);
3181 if (access_list_apply(alist
, &rinfo
->rp
->p
)
3185 return rdistance
->distance
;
3187 return rdistance
->distance
;
3191 return rip
->distance
;
3196 static void rip_distance_show(struct vty
*vty
)
3198 struct route_node
*rn
;
3199 struct rip_distance
*rdistance
;
3203 vty_out(vty
, " Distance: (default is %d)\n",
3204 rip
->distance
? rip
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
);
3206 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
3207 if ((rdistance
= rn
->info
) != NULL
) {
3210 " Address Distance List\n");
3213 sprintf(buf
, "%s/%d", inet_ntoa(rn
->p
.u
.prefix4
),
3215 vty_out(vty
, " %-20s %4d %s\n", buf
,
3216 rdistance
->distance
,
3217 rdistance
->access_list
? rdistance
->access_list
3222 DEFUN (rip_distance
,
3225 "Administrative distance\n"
3229 rip
->distance
= atoi(argv
[idx_number
]->arg
);
3233 DEFUN (no_rip_distance
,
3234 no_rip_distance_cmd
,
3235 "no distance (1-255)",
3237 "Administrative distance\n"
3244 DEFUN (rip_distance_source
,
3245 rip_distance_source_cmd
,
3246 "distance (1-255) A.B.C.D/M",
3247 "Administrative distance\n"
3249 "IP source prefix\n")
3252 int idx_ipv4_prefixlen
= 2;
3253 rip_distance_set(vty
, argv
[idx_number
]->arg
,
3254 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
3258 DEFUN (no_rip_distance_source
,
3259 no_rip_distance_source_cmd
,
3260 "no distance (1-255) A.B.C.D/M",
3262 "Administrative distance\n"
3264 "IP source prefix\n")
3267 int idx_ipv4_prefixlen
= 3;
3268 rip_distance_unset(vty
, argv
[idx_number
]->arg
,
3269 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
3273 DEFUN (rip_distance_source_access_list
,
3274 rip_distance_source_access_list_cmd
,
3275 "distance (1-255) A.B.C.D/M WORD",
3276 "Administrative distance\n"
3278 "IP source prefix\n"
3279 "Access list name\n")
3282 int idx_ipv4_prefixlen
= 2;
3284 rip_distance_set(vty
, argv
[idx_number
]->arg
,
3285 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
3289 DEFUN (no_rip_distance_source_access_list
,
3290 no_rip_distance_source_access_list_cmd
,
3291 "no distance (1-255) A.B.C.D/M WORD",
3293 "Administrative distance\n"
3295 "IP source prefix\n"
3296 "Access list name\n")
3299 int idx_ipv4_prefixlen
= 3;
3301 rip_distance_unset(vty
, argv
[idx_number
]->arg
,
3302 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
3306 /* Update ECMP routes to zebra when ECMP is disabled. */
3307 static void rip_ecmp_disable(void)
3309 struct route_node
*rp
;
3310 struct rip_info
*rinfo
, *tmp_rinfo
;
3312 struct listnode
*node
, *nextnode
;
3317 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3318 if ((list
= rp
->info
) != NULL
&& listcount(list
) > 1) {
3319 rinfo
= listgetdata(listhead(list
));
3320 if (!rip_route_rte(rinfo
))
3323 /* Drop all other entries, except the first one. */
3324 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
3325 if (tmp_rinfo
!= rinfo
) {
3326 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
3328 tmp_rinfo
->t_garbage_collect
);
3329 list_delete_node(list
, node
);
3330 rip_info_free(tmp_rinfo
);
3334 rip_zebra_ipv4_add(rp
);
3336 /* Set the route change flag. */
3337 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
3339 /* Signal the output process to trigger an update. */
3340 rip_event(RIP_TRIGGERED_UPDATE
, 0);
3344 DEFUN (rip_allow_ecmp
,
3347 "Allow Equal Cost MultiPath\n")
3350 vty_out(vty
, "ECMP is already enabled.\n");
3355 zlog_info("ECMP is enabled.");
3359 DEFUN (no_rip_allow_ecmp
,
3360 no_rip_allow_ecmp_cmd
,
3363 "Allow Equal Cost MultiPath\n")
3366 vty_out(vty
, "ECMP is already disabled.\n");
3371 zlog_info("ECMP is disabled.");
3376 /* Print out routes update time. */
3377 static void rip_vty_out_uptime(struct vty
*vty
, struct rip_info
*rinfo
)
3382 char timebuf
[TIME_BUF
];
3383 struct thread
*thread
;
3385 if ((thread
= rinfo
->t_timeout
) != NULL
) {
3386 clock
= thread_timer_remain_second(thread
);
3387 tm
= gmtime(&clock
);
3388 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
3389 vty_out(vty
, "%5s", timebuf
);
3390 } else if ((thread
= rinfo
->t_garbage_collect
) != 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
);
3398 static const char *rip_route_type_print(int sub_type
)
3403 case RIP_ROUTE_STATIC
:
3405 case RIP_ROUTE_DEFAULT
:
3407 case RIP_ROUTE_REDISTRIBUTE
:
3409 case RIP_ROUTE_INTERFACE
:
3421 "Show RIP routes\n")
3423 struct route_node
*np
;
3424 struct rip_info
*rinfo
= NULL
;
3425 struct list
*list
= NULL
;
3426 struct listnode
*listnode
= NULL
;
3432 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
3434 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
3435 " (i) - interface\n\n"
3436 " Network Next Hop Metric From Tag Time\n");
3438 for (np
= route_top(rip
->table
); np
; np
= route_next(np
))
3439 if ((list
= np
->info
) != NULL
)
3440 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3444 vty
, "%c(%s) %s/%d",
3445 /* np->lock, For debugging. */
3446 zebra_route_char(rinfo
->type
),
3447 rip_route_type_print(rinfo
->sub_type
),
3448 inet_ntoa(np
->p
.u
.prefix4
),
3454 vty_out(vty
, "%*s", len
, " ");
3456 switch(rinfo
->nh
.type
) {
3457 case NEXTHOP_TYPE_IPV4
:
3458 case NEXTHOP_TYPE_IPV4_IFINDEX
:
3459 vty_out(vty
, "%-20s %2d ",
3460 inet_ntoa(rinfo
->nh
.gate
.ipv4
),
3463 case NEXTHOP_TYPE_IFINDEX
:
3468 case NEXTHOP_TYPE_BLACKHOLE
:
3473 case NEXTHOP_TYPE_IPV6
:
3474 case NEXTHOP_TYPE_IPV6_IFINDEX
:
3476 "V6 Address Hidden %2d ",
3481 /* Route which exist in kernel routing table. */
3482 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
)
3483 && (rinfo
->sub_type
== RIP_ROUTE_RTE
)) {
3484 vty_out(vty
, "%-15s ",
3485 inet_ntoa(rinfo
->from
));
3486 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3487 (route_tag_t
)rinfo
->tag
);
3488 rip_vty_out_uptime(vty
, rinfo
);
3489 } else if (rinfo
->metric
3490 == RIP_METRIC_INFINITY
) {
3491 vty_out(vty
, "self ");
3492 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3493 (route_tag_t
)rinfo
->tag
);
3494 rip_vty_out_uptime(vty
, rinfo
);
3496 if (rinfo
->external_metric
) {
3498 vty
, "self (%s:%d)",
3501 rinfo
->external_metric
);
3504 vty_out(vty
, "%*s", len
,
3509 vty_out(vty
, "%3" ROUTE_TAG_PRI
,
3510 (route_tag_t
)rinfo
->tag
);
3518 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3519 DEFUN (show_ip_rip_status
,
3520 show_ip_rip_status_cmd
,
3521 "show ip rip status",
3525 "IP routing protocol process parameters and statistics\n")
3527 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3528 struct interface
*ifp
;
3529 struct rip_interface
*ri
;
3530 extern const struct message ri_version_msg
[];
3531 const char *send_version
;
3532 const char *receive_version
;
3537 vty_out(vty
, "Routing Protocol is \"rip\"\n");
3538 vty_out(vty
, " Sending updates every %ld seconds with +/-50%%,",
3540 vty_out(vty
, " next due in %lu seconds\n",
3541 thread_timer_remain_second(rip
->t_update
));
3542 vty_out(vty
, " Timeout after %ld seconds,", rip
->timeout_time
);
3543 vty_out(vty
, " garbage collect after %ld seconds\n", rip
->garbage_time
);
3545 /* Filtering status show. */
3546 config_show_distribute(vty
);
3548 /* Default metric information. */
3549 vty_out(vty
, " Default redistribution metric is %d\n",
3550 rip
->default_metric
);
3552 /* Redistribute information. */
3553 vty_out(vty
, " Redistributing:");
3554 config_write_rip_redistribute(vty
, 0);
3557 vty_out(vty
, " Default version control: send version %s,",
3558 lookup_msg(ri_version_msg
, rip
->version_send
, NULL
));
3559 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3560 vty_out(vty
, " receive any version \n");
3562 vty_out(vty
, " receive version %s \n",
3563 lookup_msg(ri_version_msg
, rip
->version_recv
, NULL
));
3565 vty_out(vty
, " Interface Send Recv Key-chain\n");
3567 FOR_ALL_INTERFACES (vrf
, ifp
) {
3573 if (ri
->enable_network
|| ri
->enable_interface
) {
3574 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3576 lookup_msg(ri_version_msg
,
3577 rip
->version_send
, NULL
);
3579 send_version
= lookup_msg(ri_version_msg
,
3582 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3584 lookup_msg(ri_version_msg
,
3585 rip
->version_recv
, NULL
);
3587 receive_version
= lookup_msg(
3588 ri_version_msg
, ri
->ri_receive
, NULL
);
3590 vty_out(vty
, " %-17s%-3s %-3s %s\n", ifp
->name
,
3591 send_version
, receive_version
,
3592 ri
->key_chain
? ri
->key_chain
: "");
3596 vty_out(vty
, " Routing for Networks:\n");
3597 config_write_rip_network(vty
, 0);
3600 int found_passive
= 0;
3601 FOR_ALL_INTERFACES (vrf
, ifp
) {
3604 if ((ri
->enable_network
|| ri
->enable_interface
)
3606 if (!found_passive
) {
3608 " Passive Interface(s):\n");
3611 vty_out(vty
, " %s\n", ifp
->name
);
3616 vty_out(vty
, " Routing Information Sources:\n");
3618 " Gateway BadPackets BadRoutes Distance Last Update\n");
3619 rip_peer_display(vty
);
3621 rip_distance_show(vty
);
3626 /* RIP configuration write function. */
3627 static int config_write_rip(struct vty
*vty
)
3630 struct route_node
*rn
;
3631 struct rip_distance
*rdistance
;
3634 /* Router RIP statement. */
3635 vty_out(vty
, "router rip\n");
3638 /* RIP version statement. Default is RIP version 2. */
3639 if (rip
->version_send
!= RI_RIP_VERSION_2
3640 || rip
->version_recv
!= RI_RIP_VERSION_1_AND_2
)
3641 vty_out(vty
, " version %d\n", rip
->version_send
);
3643 /* RIP timer configuration. */
3644 if (rip
->update_time
!= RIP_UPDATE_TIMER_DEFAULT
3645 || rip
->timeout_time
!= RIP_TIMEOUT_TIMER_DEFAULT
3646 || rip
->garbage_time
!= RIP_GARBAGE_TIMER_DEFAULT
)
3647 vty_out(vty
, " timers basic %lu %lu %lu\n",
3648 rip
->update_time
, rip
->timeout_time
,
3651 /* Default information configuration. */
3652 if (rip
->default_information
) {
3653 if (rip
->default_information_route_map
)
3655 " default-information originate route-map %s\n",
3656 rip
->default_information_route_map
);
3659 " default-information originate\n");
3662 /* Redistribute configuration. */
3663 config_write_rip_redistribute(vty
, 1);
3665 /* RIP offset-list configuration. */
3666 config_write_rip_offset_list(vty
);
3668 /* RIP enabled network and interface configuration. */
3669 config_write_rip_network(vty
, 1);
3671 /* RIP default metric configuration */
3672 if (rip
->default_metric
!= RIP_DEFAULT_METRIC_DEFAULT
)
3673 vty_out(vty
, " default-metric %d\n",
3674 rip
->default_metric
);
3676 /* Distribute configuration. */
3677 write
+= config_write_distribute(vty
);
3679 /* Interface routemap configuration */
3680 write
+= config_write_if_rmap(vty
);
3682 /* Distance configuration. */
3684 vty_out(vty
, " distance %d\n", rip
->distance
);
3686 /* RIP source IP prefix distance configuration. */
3687 for (rn
= route_top(rip_distance_table
); rn
;
3688 rn
= route_next(rn
))
3689 if ((rdistance
= rn
->info
) != NULL
)
3690 vty_out(vty
, " distance %d %s/%d %s\n",
3691 rdistance
->distance
,
3692 inet_ntoa(rn
->p
.u
.prefix4
),
3694 rdistance
->access_list
3695 ? rdistance
->access_list
3698 /* ECMP configuration. */
3700 vty_out(vty
, " allow-ecmp\n");
3702 /* RIP static route configuration. */
3703 for (rn
= route_top(rip
->route
); rn
; rn
= route_next(rn
))
3705 vty_out(vty
, " route %s/%d\n",
3706 inet_ntoa(rn
->p
.u
.prefix4
),
3712 /* RIP node structure. */
3713 static struct cmd_node rip_node
= {RIP_NODE
, "%s(config-router)# ", 1};
3715 /* Distribute-list update functions. */
3716 static void rip_distribute_update(struct distribute
*dist
)
3718 struct interface
*ifp
;
3719 struct rip_interface
*ri
;
3720 struct access_list
*alist
;
3721 struct prefix_list
*plist
;
3726 ifp
= if_lookup_by_name(dist
->ifname
, VRF_DEFAULT
);
3732 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
3733 alist
= access_list_lookup(AFI_IP
,
3734 dist
->list
[DISTRIBUTE_V4_IN
]);
3736 ri
->list
[RIP_FILTER_IN
] = alist
;
3738 ri
->list
[RIP_FILTER_IN
] = NULL
;
3740 ri
->list
[RIP_FILTER_IN
] = NULL
;
3742 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
3743 alist
= access_list_lookup(AFI_IP
,
3744 dist
->list
[DISTRIBUTE_V4_OUT
]);
3746 ri
->list
[RIP_FILTER_OUT
] = alist
;
3748 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3750 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3752 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
3753 plist
= prefix_list_lookup(AFI_IP
,
3754 dist
->prefix
[DISTRIBUTE_V4_IN
]);
3756 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3758 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3760 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3762 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
3763 plist
= prefix_list_lookup(AFI_IP
,
3764 dist
->prefix
[DISTRIBUTE_V4_OUT
]);
3766 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3768 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3770 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3773 void rip_distribute_update_interface(struct interface
*ifp
)
3775 struct distribute
*dist
;
3777 dist
= distribute_lookup(ifp
->name
);
3779 rip_distribute_update(dist
);
3782 /* Update all interface's distribute list. */
3784 static void rip_distribute_update_all(struct prefix_list
*notused
)
3786 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3787 struct interface
*ifp
;
3789 FOR_ALL_INTERFACES (vrf
, ifp
)
3790 rip_distribute_update_interface(ifp
);
3793 static void rip_distribute_update_all_wrapper(struct access_list
*notused
)
3795 rip_distribute_update_all(NULL
);
3798 /* Delete all added rip route. */
3799 void rip_clean(void)
3802 struct route_node
*rp
;
3803 struct rip_info
*rinfo
= NULL
;
3804 struct list
*list
= NULL
;
3805 struct listnode
*listnode
= NULL
;
3810 /* Clear RIP routes */
3811 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3812 if ((list
= rp
->info
) != NULL
) {
3813 rinfo
= listgetdata(listhead(list
));
3814 if (rip_route_rte(rinfo
))
3815 rip_zebra_ipv4_delete(rp
);
3817 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
3819 RIP_TIMER_OFF(rinfo
->t_timeout
);
3820 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
3821 rip_info_free(rinfo
);
3823 list_delete_and_null(&list
);
3825 route_unlock_node(rp
);
3828 /* Cancel RIP related timers. */
3829 RIP_TIMER_OFF(rip
->t_update
);
3830 RIP_TIMER_OFF(rip
->t_triggered_update
);
3831 RIP_TIMER_OFF(rip
->t_triggered_interval
);
3833 /* Cancel read thread. */
3834 THREAD_READ_OFF(rip
->t_read
);
3836 /* Close RIP socket. */
3837 if (rip
->sock
>= 0) {
3842 stream_free(rip
->obuf
);
3843 /* Static RIP route configuration. */
3844 for (rp
= route_top(rip
->route
); rp
; rp
= route_next(rp
))
3847 route_unlock_node(rp
);
3850 /* RIP neighbor configuration. */
3851 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
3854 route_unlock_node(rp
);
3857 /* Redistribute related clear. */
3858 if (rip
->default_information_route_map
)
3859 free(rip
->default_information_route_map
);
3861 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3862 if (rip
->route_map
[i
].name
)
3863 free(rip
->route_map
[i
].name
);
3865 XFREE(MTYPE_ROUTE_TABLE
, rip
->table
);
3866 XFREE(MTYPE_ROUTE_TABLE
, rip
->route
);
3867 XFREE(MTYPE_ROUTE_TABLE
, rip
->neighbor
);
3869 XFREE(MTYPE_RIP
, rip
);
3873 rip_clean_network();
3874 rip_passive_nondefault_clean();
3876 rip_interfaces_clean();
3877 rip_distance_reset();
3878 rip_redistribute_clean();
3881 /* Reset all values to the default settings. */
3882 void rip_reset(void)
3884 /* Reset global counters. */
3885 rip_global_route_changes
= 0;
3886 rip_global_queries
= 0;
3888 /* Call ripd related reset functions. */
3890 rip_route_map_reset();
3892 /* Call library reset functions. */
3894 access_list_reset();
3895 prefix_list_reset();
3897 distribute_list_reset();
3899 rip_interfaces_reset();
3900 rip_distance_reset();
3902 rip_zclient_reset();
3905 static void rip_if_rmap_update(struct if_rmap
*if_rmap
)
3907 struct interface
*ifp
;
3908 struct rip_interface
*ri
;
3909 struct route_map
*rmap
;
3911 ifp
= if_lookup_by_name(if_rmap
->ifname
, VRF_DEFAULT
);
3917 if (if_rmap
->routemap
[IF_RMAP_IN
]) {
3918 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_IN
]);
3920 ri
->routemap
[IF_RMAP_IN
] = rmap
;
3922 ri
->routemap
[IF_RMAP_IN
] = NULL
;
3924 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
3926 if (if_rmap
->routemap
[IF_RMAP_OUT
]) {
3927 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_OUT
]);
3929 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
3931 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
3933 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
3936 void rip_if_rmap_update_interface(struct interface
*ifp
)
3938 struct if_rmap
*if_rmap
;
3940 if_rmap
= if_rmap_lookup(ifp
->name
);
3942 rip_if_rmap_update(if_rmap
);
3945 static void rip_routemap_update_redistribute(void)
3950 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3951 if (rip
->route_map
[i
].name
)
3952 rip
->route_map
[i
].map
=
3953 route_map_lookup_by_name(
3954 rip
->route_map
[i
].name
);
3960 static void rip_routemap_update(const char *notused
)
3962 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3963 struct interface
*ifp
;
3965 FOR_ALL_INTERFACES (vrf
, ifp
)
3966 rip_if_rmap_update_interface(ifp
);
3968 rip_routemap_update_redistribute();
3971 /* Allocate new rip structure and set default value. */
3974 /* Install top nodes. */
3975 install_node(&rip_node
, config_write_rip
);
3977 /* Install rip commands. */
3978 install_element(VIEW_NODE
, &show_ip_rip_cmd
);
3979 install_element(VIEW_NODE
, &show_ip_rip_status_cmd
);
3980 install_element(CONFIG_NODE
, &router_rip_cmd
);
3981 install_element(CONFIG_NODE
, &no_router_rip_cmd
);
3983 install_default(RIP_NODE
);
3984 install_element(RIP_NODE
, &rip_version_cmd
);
3985 install_element(RIP_NODE
, &no_rip_version_cmd
);
3986 install_element(RIP_NODE
, &rip_default_metric_cmd
);
3987 install_element(RIP_NODE
, &no_rip_default_metric_cmd
);
3988 install_element(RIP_NODE
, &rip_timers_cmd
);
3989 install_element(RIP_NODE
, &no_rip_timers_cmd
);
3990 install_element(RIP_NODE
, &rip_route_cmd
);
3991 install_element(RIP_NODE
, &no_rip_route_cmd
);
3992 install_element(RIP_NODE
, &rip_distance_cmd
);
3993 install_element(RIP_NODE
, &no_rip_distance_cmd
);
3994 install_element(RIP_NODE
, &rip_distance_source_cmd
);
3995 install_element(RIP_NODE
, &no_rip_distance_source_cmd
);
3996 install_element(RIP_NODE
, &rip_distance_source_access_list_cmd
);
3997 install_element(RIP_NODE
, &no_rip_distance_source_access_list_cmd
);
3998 install_element(RIP_NODE
, &rip_allow_ecmp_cmd
);
3999 install_element(RIP_NODE
, &no_rip_allow_ecmp_cmd
);
4001 /* Debug related init. */
4004 /* Access list install. */
4006 access_list_add_hook(rip_distribute_update_all_wrapper
);
4007 access_list_delete_hook(rip_distribute_update_all_wrapper
);
4009 /* Prefix list initialize.*/
4011 prefix_list_add_hook(rip_distribute_update_all
);
4012 prefix_list_delete_hook(rip_distribute_update_all
);
4014 /* Distribute list install. */
4015 distribute_list_init(RIP_NODE
);
4016 distribute_list_add_hook(rip_distribute_update
);
4017 distribute_list_delete_hook(rip_distribute_update
);
4020 rip_route_map_init();
4023 route_map_add_hook(rip_routemap_update
);
4024 route_map_delete_hook(rip_routemap_update
);
4026 if_rmap_init(RIP_NODE
);
4027 if_rmap_hook_add(rip_if_rmap_update
);
4028 if_rmap_hook_delete(rip_if_rmap_update
);
4030 /* Distance control. */
4031 rip_distance_table
= route_table_init();