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"
43 #include "lib_errors.h"
45 #include "ripd/ripd.h"
46 #include "ripd/rip_debug.h"
47 #include "ripd/rip_errors.h"
51 /* UDP receive buffer size */
52 #define RIP_UDP_RCV_BUF 41600
55 struct rip
*rip
= NULL
;
57 /* RIP neighbor address table. */
58 struct route_table
*rip_neighbor_table
;
60 /* RIP route changes. */
61 long rip_global_route_changes
= 0;
64 long rip_global_queries
= 0;
67 static void rip_event(enum rip_event
, int);
68 static void rip_output_process(struct connected
*, struct sockaddr_in
*, int,
70 static int rip_triggered_update(struct thread
*);
71 static int rip_update_jitter(unsigned long);
73 /* RIP output routes type. */
74 enum { rip_all_route
, rip_changed_route
};
76 /* RIP command strings. */
77 static const struct message rip_msg
[] = {{RIP_REQUEST
, "REQUEST"},
78 {RIP_RESPONSE
, "RESPONSE"},
79 {RIP_TRACEON
, "TRACEON"},
80 {RIP_TRACEOFF
, "TRACEOFF"},
82 {RIP_POLL_ENTRY
, "POLL ENTRY"},
85 /* Utility function to set boradcast option to the socket. */
86 static int sockopt_broadcast(int sock
)
91 ret
= setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, (char *)&on
,
94 zlog_warn("can't set sockopt SO_BROADCAST to socket %d", sock
);
100 static int rip_route_rte(struct rip_info
*rinfo
)
102 return (rinfo
->type
== ZEBRA_ROUTE_RIP
103 && rinfo
->sub_type
== RIP_ROUTE_RTE
);
106 static struct rip_info
*rip_info_new(void)
108 return XCALLOC(MTYPE_RIP_INFO
, sizeof(struct rip_info
));
111 void rip_info_free(struct rip_info
*rinfo
)
113 XFREE(MTYPE_RIP_INFO
, rinfo
);
116 /* RIP route garbage collect timer. */
117 static int rip_garbage_collect(struct thread
*t
)
119 struct rip_info
*rinfo
;
120 struct route_node
*rp
;
122 rinfo
= THREAD_ARG(t
);
123 rinfo
->t_garbage_collect
= NULL
;
125 /* Off timeout timer. */
126 RIP_TIMER_OFF(rinfo
->t_timeout
);
128 /* Get route_node pointer. */
131 /* Unlock route_node. */
132 listnode_delete(rp
->info
, rinfo
);
133 if (list_isempty((struct list
*)rp
->info
)) {
134 list_delete_and_null((struct list
**)&rp
->info
);
135 route_unlock_node(rp
);
138 /* Free RIP routing information. */
139 rip_info_free(rinfo
);
144 static void rip_timeout_update(struct rip_info
*rinfo
);
146 /* Add new route to the ECMP list.
147 * RETURN: the new entry added in the list, or NULL if it is not the first
148 * entry and ECMP is not allowed.
150 struct rip_info
*rip_ecmp_add(struct rip_info
*rinfo_new
)
152 struct route_node
*rp
= rinfo_new
->rp
;
153 struct rip_info
*rinfo
= NULL
;
154 struct list
*list
= NULL
;
156 if (rp
->info
== NULL
)
157 rp
->info
= list_new();
158 list
= (struct list
*)rp
->info
;
160 /* If ECMP is not allowed and some entry already exists in the list,
162 if (listcount(list
) && !rip
->ecmp
)
165 rinfo
= rip_info_new();
166 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
167 listnode_add(list
, rinfo
);
169 if (rip_route_rte(rinfo
)) {
170 rip_timeout_update(rinfo
);
171 rip_zebra_ipv4_add(rp
);
174 /* Set the route change flag on the first entry. */
175 rinfo
= listgetdata(listhead(list
));
176 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
178 /* Signal the output process to trigger an update (see section 2.5). */
179 rip_event(RIP_TRIGGERED_UPDATE
, 0);
184 /* Replace the ECMP list with the new route.
185 * RETURN: the new entry added in the list
187 struct rip_info
*rip_ecmp_replace(struct rip_info
*rinfo_new
)
189 struct route_node
*rp
= rinfo_new
->rp
;
190 struct list
*list
= (struct list
*)rp
->info
;
191 struct rip_info
*rinfo
= NULL
, *tmp_rinfo
= NULL
;
192 struct listnode
*node
= NULL
, *nextnode
= NULL
;
194 if (list
== NULL
|| listcount(list
) == 0)
195 return rip_ecmp_add(rinfo_new
);
197 /* Get the first entry */
198 rinfo
= listgetdata(listhead(list
));
200 /* Learnt route replaced by a local one. Delete it from zebra. */
201 if (rip_route_rte(rinfo
) && !rip_route_rte(rinfo_new
))
202 if (CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
203 rip_zebra_ipv4_delete(rp
);
205 /* Re-use the first entry, and delete the others. */
206 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
207 if (tmp_rinfo
!= rinfo
) {
208 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
209 RIP_TIMER_OFF(tmp_rinfo
->t_garbage_collect
);
210 list_delete_node(list
, node
);
211 rip_info_free(tmp_rinfo
);
214 RIP_TIMER_OFF(rinfo
->t_timeout
);
215 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
216 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
218 if (rip_route_rte(rinfo
)) {
219 rip_timeout_update(rinfo
);
220 /* The ADD message implies an update. */
221 rip_zebra_ipv4_add(rp
);
224 /* Set the route change flag. */
225 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
227 /* Signal the output process to trigger an update (see section 2.5). */
228 rip_event(RIP_TRIGGERED_UPDATE
, 0);
233 /* Delete one route from the ECMP list.
235 * null - the entry is freed, and other entries exist in the list
236 * the entry - the entry is the last one in the list; its metric is set
237 * to INFINITY, and the garbage collector is started for it
239 struct rip_info
*rip_ecmp_delete(struct rip_info
*rinfo
)
241 struct route_node
*rp
= rinfo
->rp
;
242 struct list
*list
= (struct list
*)rp
->info
;
244 RIP_TIMER_OFF(rinfo
->t_timeout
);
246 if (listcount(list
) > 1) {
247 /* Some other ECMP entries still exist. Just delete this entry.
249 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
250 listnode_delete(list
, rinfo
);
251 if (rip_route_rte(rinfo
)
252 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
253 /* The ADD message implies the update. */
254 rip_zebra_ipv4_add(rp
);
255 rip_info_free(rinfo
);
258 assert(rinfo
== listgetdata(listhead(list
)));
260 /* This is the only entry left in the list. We must keep it in
261 * the list for garbage collection time, with INFINITY metric.
264 rinfo
->metric
= RIP_METRIC_INFINITY
;
265 RIP_TIMER_ON(rinfo
->t_garbage_collect
, rip_garbage_collect
,
268 if (rip_route_rte(rinfo
)
269 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
270 rip_zebra_ipv4_delete(rp
);
273 /* Set the route change flag on the first entry. */
274 rinfo
= listgetdata(listhead(list
));
275 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
277 /* Signal the output process to trigger an update (see section 2.5). */
278 rip_event(RIP_TRIGGERED_UPDATE
, 0);
283 /* Timeout RIP routes. */
284 static int rip_timeout(struct thread
*t
)
286 rip_ecmp_delete((struct rip_info
*)THREAD_ARG(t
));
290 static void rip_timeout_update(struct rip_info
*rinfo
)
292 if (rinfo
->metric
!= RIP_METRIC_INFINITY
) {
293 RIP_TIMER_OFF(rinfo
->t_timeout
);
294 RIP_TIMER_ON(rinfo
->t_timeout
, rip_timeout
, rip
->timeout_time
);
298 static int rip_filter(int rip_distribute
, struct prefix_ipv4
*p
,
299 struct rip_interface
*ri
)
301 struct distribute
*dist
;
302 struct access_list
*alist
;
303 struct prefix_list
*plist
;
304 int distribute
= rip_distribute
== RIP_FILTER_OUT
? DISTRIBUTE_V4_OUT
306 const char *inout
= rip_distribute
== RIP_FILTER_OUT
? "out" : "in";
308 /* Input distribute-list filtering. */
309 if (ri
->list
[rip_distribute
]) {
310 if (access_list_apply(ri
->list
[rip_distribute
],
313 if (IS_RIP_DEBUG_PACKET
)
314 zlog_debug("%s/%d filtered by distribute %s",
315 inet_ntoa(p
->prefix
), p
->prefixlen
,
320 if (ri
->prefix
[rip_distribute
]) {
321 if (prefix_list_apply(ri
->prefix
[rip_distribute
],
324 if (IS_RIP_DEBUG_PACKET
)
325 zlog_debug("%s/%d filtered by prefix-list %s",
326 inet_ntoa(p
->prefix
), p
->prefixlen
,
332 /* All interface filter check. */
333 dist
= distribute_lookup(NULL
);
335 if (dist
->list
[distribute
]) {
336 alist
= access_list_lookup(AFI_IP
,
337 dist
->list
[distribute
]);
340 if (access_list_apply(alist
, (struct prefix
*)p
)
342 if (IS_RIP_DEBUG_PACKET
)
344 "%s/%d filtered by distribute %s",
345 inet_ntoa(p
->prefix
),
346 p
->prefixlen
, inout
);
351 if (dist
->prefix
[distribute
]) {
352 plist
= prefix_list_lookup(AFI_IP
,
353 dist
->prefix
[distribute
]);
356 if (prefix_list_apply(plist
, (struct prefix
*)p
)
358 if (IS_RIP_DEBUG_PACKET
)
360 "%s/%d filtered by prefix-list %s",
361 inet_ntoa(p
->prefix
),
362 p
->prefixlen
, inout
);
371 /* Check nexthop address validity. */
372 static int rip_nexthop_check(struct in_addr
*addr
)
374 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
375 struct interface
*ifp
;
376 struct listnode
*cnode
;
377 struct connected
*ifc
;
380 /* If nexthop address matches local configured address then it is
383 FOR_ALL_INTERFACES (vrf
, ifp
) {
384 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, ifc
)) {
387 if (p
->family
== AF_INET
388 && IPV4_ADDR_SAME(&p
->u
.prefix4
, addr
))
395 /* RIP add route to routing table. */
396 static void rip_rte_process(struct rte
*rte
, struct sockaddr_in
*from
,
397 struct interface
*ifp
)
400 struct prefix_ipv4 p
;
401 struct route_node
*rp
;
402 struct rip_info
*rinfo
= NULL
, newinfo
;
403 struct rip_interface
*ri
;
404 struct in_addr
*nexthop
;
406 unsigned char old_dist
, new_dist
;
407 struct list
*list
= NULL
;
408 struct listnode
*node
= NULL
;
410 /* Make prefix structure. */
411 memset(&p
, 0, sizeof(struct prefix_ipv4
));
413 p
.prefix
= rte
->prefix
;
414 p
.prefixlen
= ip_masklen(rte
->mask
);
416 /* Make sure mask is applied. */
419 /* Apply input filters. */
422 ret
= rip_filter(RIP_FILTER_IN
, &p
, ri
);
426 memset(&newinfo
, 0, sizeof(newinfo
));
427 newinfo
.type
= ZEBRA_ROUTE_RIP
;
428 newinfo
.sub_type
= RIP_ROUTE_RTE
;
429 newinfo
.nh
.gate
.ipv4
= rte
->nexthop
;
430 newinfo
.from
= from
->sin_addr
;
431 newinfo
.nh
.ifindex
= ifp
->ifindex
;
432 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
433 newinfo
.metric
= rte
->metric
;
434 newinfo
.metric_out
= rte
->metric
; /* XXX */
435 newinfo
.tag
= ntohs(rte
->tag
); /* XXX */
437 /* Modify entry according to the interface routemap. */
438 if (ri
->routemap
[RIP_FILTER_IN
]) {
441 /* The object should be of the type of rip_info */
442 ret
= route_map_apply(ri
->routemap
[RIP_FILTER_IN
],
443 (struct prefix
*)&p
, RMAP_RIP
, &newinfo
);
445 if (ret
== RMAP_DENYMATCH
) {
446 if (IS_RIP_DEBUG_PACKET
)
448 "RIP %s/%d is filtered by route-map in",
449 inet_ntoa(p
.prefix
), p
.prefixlen
);
453 /* Get back the object */
454 rte
->nexthop
= newinfo
.nexthop_out
;
455 rte
->tag
= htons(newinfo
.tag_out
); /* XXX */
456 rte
->metric
= newinfo
.metric_out
; /* XXX: the routemap uses the
460 /* Once the entry has been validated, update the metric by
461 adding the cost of the network on wich the message
462 arrived. If the result is greater than infinity, use infinity
463 (RFC2453 Sec. 3.9.2) */
464 /* Zebra ripd can handle offset-list in. */
465 ret
= rip_offset_list_apply_in(&p
, ifp
, &rte
->metric
);
467 /* If offset-list does not modify the metric use interface's
470 rte
->metric
+= ifp
->metric
? ifp
->metric
: 1;
472 if (rte
->metric
> RIP_METRIC_INFINITY
)
473 rte
->metric
= RIP_METRIC_INFINITY
;
475 /* Set nexthop pointer. */
476 if (rte
->nexthop
.s_addr
== 0)
477 nexthop
= &from
->sin_addr
;
479 nexthop
= &rte
->nexthop
;
481 /* Check if nexthop address is myself, then do nothing. */
482 if (rip_nexthop_check(nexthop
) < 0) {
483 if (IS_RIP_DEBUG_PACKET
)
484 zlog_debug("Nexthop address %s is myself",
485 inet_ntoa(*nexthop
));
489 /* Get index for the prefix. */
490 rp
= route_node_get(rip
->table
, (struct prefix
*)&p
);
493 newinfo
.nh
.gate
.ipv4
= *nexthop
;
494 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4
;
495 newinfo
.metric
= rte
->metric
;
496 newinfo
.tag
= ntohs(rte
->tag
);
497 newinfo
.distance
= rip_distance_apply(&newinfo
);
499 new_dist
= newinfo
.distance
? newinfo
.distance
500 : ZEBRA_RIP_DISTANCE_DEFAULT
;
502 /* Check to see whether there is already RIP route on the table. */
503 if ((list
= rp
->info
) != NULL
)
504 for (ALL_LIST_ELEMENTS_RO(list
, node
, rinfo
)) {
505 /* Need to compare with redistributed entry or local
507 if (!rip_route_rte(rinfo
))
510 if (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
511 && IPV4_ADDR_SAME(&rinfo
->nh
.gate
.ipv4
, nexthop
))
514 if (!listnextnode(node
)) {
515 /* Not found in the list */
517 if (rte
->metric
> rinfo
->metric
) {
518 /* New route has a greater metric.
520 route_unlock_node(rp
);
524 if (rte
->metric
< rinfo
->metric
)
525 /* New route has a smaller metric.
526 * Replace the ECMP list
527 * with the new one in below. */
530 /* Metrics are same. We compare the distances.
532 old_dist
= rinfo
->distance
534 : ZEBRA_RIP_DISTANCE_DEFAULT
;
536 if (new_dist
> old_dist
) {
537 /* New route has a greater distance.
539 route_unlock_node(rp
);
543 if (new_dist
< old_dist
)
544 /* New route has a smaller distance.
545 * Replace the ECMP list
546 * with the new one in below. */
549 /* Metrics and distances are both same. Keep
551 * the new route is added in the ECMP list in
557 /* Local static route. */
558 if (rinfo
->type
== ZEBRA_ROUTE_RIP
559 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
560 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))
561 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
562 route_unlock_node(rp
);
566 /* Redistributed route check. */
567 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
568 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
569 old_dist
= rinfo
->distance
;
570 /* Only routes directly connected to an interface
572 * may have a valid NULL distance */
573 if (rinfo
->nh
.gate
.ipv4
.s_addr
!= 0)
576 : ZEBRA_RIP_DISTANCE_DEFAULT
;
577 /* If imported route does not have STRICT precedence,
578 mark it as a ghost */
579 if (new_dist
<= old_dist
580 && rte
->metric
!= RIP_METRIC_INFINITY
)
581 rip_ecmp_replace(&newinfo
);
583 route_unlock_node(rp
);
590 route_unlock_node(rp
);
592 /* Now, check to see whether there is already an explicit route
593 for the destination prefix. If there is no such route, add
594 this route to the routing table, unless the metric is
595 infinity (there is no point in adding a route which
597 if (rte
->metric
!= RIP_METRIC_INFINITY
)
598 rip_ecmp_add(&newinfo
);
600 /* Route is there but we are not sure the route is RIP or not.
603 /* If there is an existing route, compare the next hop address
604 to the address of the router from which the datagram came.
605 If this datagram is from the same router as the existing
606 route, reinitialize the timeout. */
607 same
= (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
608 && (rinfo
->nh
.ifindex
== ifp
->ifindex
));
610 old_dist
= rinfo
->distance
? rinfo
->distance
611 : ZEBRA_RIP_DISTANCE_DEFAULT
;
613 /* Next, compare the metrics. If the datagram is from the same
614 router as the existing route, and the new metric is different
615 than the old one; or, if the new metric is lower than the old
616 one, or if the tag has been changed; or if there is a route
617 with a lower administrave distance; or an update of the
618 distance on the actual route; do the following actions: */
619 if ((same
&& rinfo
->metric
!= rte
->metric
)
620 || (rte
->metric
< rinfo
->metric
)
621 || ((same
) && (rinfo
->metric
== rte
->metric
)
622 && (newinfo
.tag
!= rinfo
->tag
))
623 || (old_dist
> new_dist
)
624 || ((old_dist
!= new_dist
) && same
)) {
625 if (listcount(list
) == 1) {
626 if (newinfo
.metric
!= RIP_METRIC_INFINITY
)
627 rip_ecmp_replace(&newinfo
);
629 rip_ecmp_delete(rinfo
);
631 if (newinfo
.metric
< rinfo
->metric
)
632 rip_ecmp_replace(&newinfo
);
633 else if (newinfo
.metric
> rinfo
->metric
)
634 rip_ecmp_delete(rinfo
);
635 else if (new_dist
< old_dist
)
636 rip_ecmp_replace(&newinfo
);
637 else if (new_dist
> old_dist
)
638 rip_ecmp_delete(rinfo
);
640 int update
= CHECK_FLAG(rinfo
->flags
,
645 assert(newinfo
.metric
646 != RIP_METRIC_INFINITY
);
648 RIP_TIMER_OFF(rinfo
->t_timeout
);
649 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
650 memcpy(rinfo
, &newinfo
,
651 sizeof(struct rip_info
));
652 rip_timeout_update(rinfo
);
655 rip_zebra_ipv4_add(rp
);
657 /* - Set the route change flag on the
659 rinfo
= listgetdata(listhead(list
));
660 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
661 rip_event(RIP_TRIGGERED_UPDATE
, 0);
664 } else /* same & no change */
665 rip_timeout_update(rinfo
);
667 /* Unlock tempolary lock of the route. */
668 route_unlock_node(rp
);
672 /* Dump RIP packet */
673 static void rip_packet_dump(struct rip_packet
*packet
, int size
,
678 const char *command_str
;
679 char pbuf
[BUFSIZ
], nbuf
[BUFSIZ
];
683 /* Set command string. */
684 if (packet
->command
> 0 && packet
->command
< RIP_COMMAND_MAX
)
685 command_str
= lookup_msg(rip_msg
, packet
->command
, NULL
);
687 command_str
= "unknown";
689 /* Dump packet header. */
690 zlog_debug("%s %s version %d packet size %d", sndrcv
, command_str
,
691 packet
->version
, size
);
693 /* Dump each routing table entry. */
696 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
697 if (packet
->version
== RIPv2
) {
698 netmask
= ip_masklen(rte
->mask
);
700 if (rte
->family
== htons(RIP_FAMILY_AUTH
)) {
702 == htons(RIP_AUTH_SIMPLE_PASSWORD
)) {
703 p
= (uint8_t *)&rte
->prefix
;
706 " family 0x%X type %d auth string: %s",
709 } else if (rte
->tag
== htons(RIP_AUTH_MD5
)) {
710 struct rip_md5_info
*md5
;
712 md5
= (struct rip_md5_info
*)&packet
716 " family 0x%X type %d (MD5 authentication)",
720 " RIP-2 packet len %d Key ID %d"
722 ntohs(md5
->packet_len
),
723 md5
->keyid
, md5
->auth_len
);
724 zlog_debug(" Sequence Number %ld",
725 (unsigned long)ntohl(
727 } else if (rte
->tag
== htons(RIP_AUTH_DATA
)) {
728 p
= (uint8_t *)&rte
->prefix
;
731 " family 0x%X type %d (MD5 data)",
735 " MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
736 "%02X%02X%02X%02X%02X%02X%02X%02X",
737 p
[0], p
[1], p
[2], p
[3], p
[4],
738 p
[5], p
[6], p
[7], p
[8], p
[9],
739 p
[10], p
[11], p
[12], p
[13],
743 " family 0x%X type %d (Unknown auth type)",
749 " %s/%d -> %s family %d tag %" ROUTE_TAG_PRI
751 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
,
754 inet_ntop(AF_INET
, &rte
->nexthop
, nbuf
,
757 (route_tag_t
)ntohs(rte
->tag
),
758 (unsigned long)ntohl(rte
->metric
));
761 " %s family %d tag %" ROUTE_TAG_PRI
763 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
765 (route_tag_t
)ntohs(rte
->tag
),
766 (unsigned long)ntohl(rte
->metric
));
771 /* Check if the destination address is valid (unicast; not net 0
772 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
773 check net 0 because we accept default route. */
774 static int rip_destination_check(struct in_addr addr
)
776 uint32_t destination
;
778 /* Convert to host byte order. */
779 destination
= ntohl(addr
.s_addr
);
781 if (IPV4_NET127(destination
))
784 /* Net 0 may match to the default route. */
785 if (IPV4_NET0(destination
) && destination
!= 0)
788 /* Unicast address must belong to class A, B, C. */
789 if (IN_CLASSA(destination
))
791 if (IN_CLASSB(destination
))
793 if (IN_CLASSC(destination
))
799 /* RIP version 2 authentication. */
800 static int rip_auth_simple_password(struct rte
*rte
, struct sockaddr_in
*from
,
801 struct interface
*ifp
)
803 struct rip_interface
*ri
;
804 char *auth_str
= (char *)rte
+ offsetof(struct rte
, prefix
);
807 /* reject passwords with zeros in the middle of the string */
808 for (i
= strnlen(auth_str
, 16); i
< 16; i
++) {
809 if (auth_str
[i
] != '\0')
813 if (IS_RIP_DEBUG_EVENT
)
814 zlog_debug("RIPv2 simple password authentication from %s",
815 inet_ntoa(from
->sin_addr
));
819 if (ri
->auth_type
!= RIP_AUTH_SIMPLE_PASSWORD
820 || rte
->tag
!= htons(RIP_AUTH_SIMPLE_PASSWORD
))
823 /* Simple password authentication. */
825 if (strncmp(auth_str
, ri
->auth_str
, 16) == 0)
829 struct keychain
*keychain
;
832 keychain
= keychain_lookup(ri
->key_chain
);
833 if (keychain
== NULL
|| keychain
->key
== NULL
)
836 key
= key_match_for_accept(keychain
, auth_str
);
843 /* RIP version 2 authentication with MD5. */
844 static int rip_auth_md5(struct rip_packet
*packet
, struct sockaddr_in
*from
,
845 int length
, struct interface
*ifp
)
847 struct rip_interface
*ri
;
848 struct rip_md5_info
*md5
;
849 struct rip_md5_data
*md5data
;
850 struct keychain
*keychain
;
853 uint8_t digest
[RIP_AUTH_MD5_SIZE
];
855 char auth_str
[RIP_AUTH_MD5_SIZE
];
857 if (IS_RIP_DEBUG_EVENT
)
858 zlog_debug("RIPv2 MD5 authentication from %s",
859 inet_ntoa(from
->sin_addr
));
862 md5
= (struct rip_md5_info
*)&packet
->rte
;
864 /* Check auth type. */
865 if (ri
->auth_type
!= RIP_AUTH_MD5
|| md5
->type
!= htons(RIP_AUTH_MD5
))
868 /* If the authentication length is less than 16, then it must be wrong
870 * any interpretation of rfc2082. Some implementations also interpret
871 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka
872 * RIP_AUTH_MD5_COMPAT_SIZE.
874 if (!((md5
->auth_len
== RIP_AUTH_MD5_SIZE
)
875 || (md5
->auth_len
== RIP_AUTH_MD5_COMPAT_SIZE
))) {
876 if (IS_RIP_DEBUG_EVENT
)
878 "RIPv2 MD5 authentication, strange authentication "
884 /* grab and verify check packet length */
885 packet_len
= ntohs(md5
->packet_len
);
887 if (packet_len
> (length
- RIP_HEADER_SIZE
- RIP_AUTH_MD5_SIZE
)) {
888 if (IS_RIP_DEBUG_EVENT
)
890 "RIPv2 MD5 authentication, packet length field %d "
891 "greater than received length %d!",
892 md5
->packet_len
, length
);
896 /* retrieve authentication data */
897 md5data
= (struct rip_md5_data
*)(((uint8_t *)packet
) + packet_len
);
899 memset(auth_str
, 0, RIP_AUTH_MD5_SIZE
);
902 keychain
= keychain_lookup(ri
->key_chain
);
903 if (keychain
== NULL
)
906 key
= key_lookup_for_accept(keychain
, md5
->keyid
);
907 if (key
== NULL
|| key
->string
== NULL
)
910 strncpy(auth_str
, key
->string
, RIP_AUTH_MD5_SIZE
);
911 } else if (ri
->auth_str
)
912 strncpy(auth_str
, ri
->auth_str
, RIP_AUTH_MD5_SIZE
);
914 if (auth_str
[0] == 0)
917 /* MD5 digest authentication. */
918 memset(&ctx
, 0, sizeof(ctx
));
920 MD5Update(&ctx
, packet
, packet_len
+ RIP_HEADER_SIZE
);
921 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
922 MD5Final(digest
, &ctx
);
924 if (memcmp(md5data
->digest
, digest
, RIP_AUTH_MD5_SIZE
) == 0)
930 /* Pick correct auth string for sends, prepare auth_str buffer for use.
931 * (left justified and padded).
933 * presumes one of ri or key is valid, and that the auth strings they point
934 * to are nul terminated. If neither are present, auth_str will be fully
938 static void rip_auth_prepare_str_send(struct rip_interface
*ri
, struct key
*key
,
939 char *auth_str
, int len
)
943 memset(auth_str
, 0, len
);
944 if (key
&& key
->string
)
945 strncpy(auth_str
, key
->string
, len
);
946 else if (ri
->auth_str
)
947 strncpy(auth_str
, ri
->auth_str
, len
);
952 /* Write RIPv2 simple password authentication information
954 * auth_str is presumed to be 2 bytes and correctly prepared
955 * (left justified and zero padded).
957 static void rip_auth_simple_write(struct stream
*s
, char *auth_str
, int len
)
959 assert(s
&& len
== RIP_AUTH_SIMPLE_SIZE
);
961 stream_putw(s
, RIP_FAMILY_AUTH
);
962 stream_putw(s
, RIP_AUTH_SIMPLE_PASSWORD
);
963 stream_put(s
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
968 /* write RIPv2 MD5 "authentication header"
969 * (uses the auth key data field)
971 * Digest offset field is set to 0.
973 * returns: offset of the digest offset field, which must be set when
974 * length to the auth-data MD5 digest is known.
976 static size_t rip_auth_md5_ah_write(struct stream
*s
, struct rip_interface
*ri
,
981 assert(s
&& ri
&& ri
->auth_type
== RIP_AUTH_MD5
);
983 /* MD5 authentication. */
984 stream_putw(s
, RIP_FAMILY_AUTH
);
985 stream_putw(s
, RIP_AUTH_MD5
);
987 /* MD5 AH digest offset field.
989 * Set to placeholder value here, to true value when RIP-2 Packet length
990 * is known. Actual value is set in .....().
992 doff
= stream_get_endp(s
);
997 stream_putc(s
, key
->index
% 256);
1001 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
1002 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for
1004 * to be configurable.
1006 stream_putc(s
, ri
->md5_auth_len
);
1008 /* Sequence Number (non-decreasing). */
1009 /* RFC2080: The value used in the sequence number is
1010 arbitrary, but two suggestions are the time of the
1011 message's creation or a simple message counter. */
1012 stream_putl(s
, time(NULL
));
1014 /* Reserved field must be zero. */
1021 /* If authentication is in used, write the appropriate header
1022 * returns stream offset to which length must later be written
1023 * or 0 if this is not required
1025 static size_t rip_auth_header_write(struct stream
*s
, struct rip_interface
*ri
,
1026 struct key
*key
, char *auth_str
, int len
)
1028 assert(ri
->auth_type
!= RIP_NO_AUTH
);
1030 switch (ri
->auth_type
) {
1031 case RIP_AUTH_SIMPLE_PASSWORD
:
1032 rip_auth_prepare_str_send(ri
, key
, auth_str
, len
);
1033 rip_auth_simple_write(s
, auth_str
, len
);
1036 return rip_auth_md5_ah_write(s
, ri
, key
);
1042 /* Write RIPv2 MD5 authentication data trailer */
1043 static void rip_auth_md5_set(struct stream
*s
, struct rip_interface
*ri
,
1044 size_t doff
, char *auth_str
, int authlen
)
1048 unsigned char digest
[RIP_AUTH_MD5_SIZE
];
1050 /* Make it sure this interface is configured as MD5
1052 assert((ri
->auth_type
== RIP_AUTH_MD5
)
1053 && (authlen
== RIP_AUTH_MD5_SIZE
));
1056 /* Get packet length. */
1057 len
= stream_get_endp(s
);
1059 /* Check packet length. */
1060 if (len
< (RIP_HEADER_SIZE
+ RIP_RTE_SIZE
)) {
1061 flog_err(RIP_ERR_PACKET
,
1062 "rip_auth_md5_set(): packet length %ld is less than minimum length.",
1067 /* Set the digest offset length in the header */
1068 stream_putw_at(s
, doff
, len
);
1070 /* Set authentication data. */
1071 stream_putw(s
, RIP_FAMILY_AUTH
);
1072 stream_putw(s
, RIP_AUTH_DATA
);
1074 /* Generate a digest for the RIP packet. */
1075 memset(&ctx
, 0, sizeof(ctx
));
1077 MD5Update(&ctx
, STREAM_DATA(s
), stream_get_endp(s
));
1078 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1079 MD5Final(digest
, &ctx
);
1081 /* Copy the digest to the packet. */
1082 stream_write(s
, digest
, RIP_AUTH_MD5_SIZE
);
1085 /* RIP routing information. */
1086 static void rip_response_process(struct rip_packet
*packet
, int size
,
1087 struct sockaddr_in
*from
,
1088 struct connected
*ifc
)
1092 struct prefix_ipv4 ifaddr
;
1093 struct prefix_ipv4 ifaddrclass
;
1096 memset(&ifaddr
, 0, sizeof(ifaddr
));
1097 /* We don't know yet. */
1100 /* The Response must be ignored if it is not from the RIP
1101 port. (RFC2453 - Sec. 3.9.2)*/
1102 if (from
->sin_port
!= htons(RIP_PORT_DEFAULT
)) {
1103 zlog_info("response doesn't come from RIP port: %d",
1105 rip_peer_bad_packet(from
);
1109 /* The datagram's IPv4 source address should be checked to see
1110 whether the datagram is from a valid neighbor; the source of the
1111 datagram must be on a directly connected network (RFC2453 - Sec.
1113 if (if_lookup_address((void *)&from
->sin_addr
, AF_INET
, VRF_DEFAULT
)
1116 "This datagram doesn't came from a valid neighbor: %s",
1117 inet_ntoa(from
->sin_addr
));
1118 rip_peer_bad_packet(from
);
1122 /* It is also worth checking to see whether the response is from one
1123 of the router's own addresses. */
1125 ; /* Alredy done in rip_read () */
1127 /* Update RIP peer. */
1128 rip_peer_update(from
, packet
->version
);
1130 /* Set RTE pointer. */
1133 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
1134 /* RIPv2 authentication check. */
1135 /* If the Address Family Identifier of the first (and only the
1136 first) entry in the message is 0xFFFF, then the remainder of
1137 the entry contains the authentication. */
1138 /* If the packet gets here it means authentication enabled */
1139 /* Check is done in rip_read(). So, just skipping it */
1140 if (packet
->version
== RIPv2
&& rte
== packet
->rte
1141 && rte
->family
== htons(RIP_FAMILY_AUTH
))
1144 if (rte
->family
!= htons(AF_INET
)) {
1145 /* Address family check. RIP only supports AF_INET. */
1146 zlog_info("Unsupported family %d from %s.",
1148 inet_ntoa(from
->sin_addr
));
1152 /* - is the destination address valid (e.g., unicast; not net 0
1154 if (!rip_destination_check(rte
->prefix
)) {
1156 "Network is net 0 or net 127 or it is not unicast network");
1157 rip_peer_bad_route(from
);
1161 /* Convert metric value to host byte order. */
1162 rte
->metric
= ntohl(rte
->metric
);
1164 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1165 if (!(rte
->metric
>= 1 && rte
->metric
<= 16)) {
1166 zlog_info("Route's metric is not in the 1-16 range.");
1167 rip_peer_bad_route(from
);
1171 /* RIPv1 does not have nexthop value. */
1172 if (packet
->version
== RIPv1
&& rte
->nexthop
.s_addr
!= 0) {
1173 zlog_info("RIPv1 packet with nexthop value %s",
1174 inet_ntoa(rte
->nexthop
));
1175 rip_peer_bad_route(from
);
1179 /* That is, if the provided information is ignored, a possibly
1180 sub-optimal, but absolutely valid, route may be taken. If
1181 the received Next Hop is not directly reachable, it should be
1182 treated as 0.0.0.0. */
1183 if (packet
->version
== RIPv2
&& rte
->nexthop
.s_addr
!= 0) {
1186 /* Multicast address check. */
1187 addrval
= ntohl(rte
->nexthop
.s_addr
);
1188 if (IN_CLASSD(addrval
)) {
1190 "Nexthop %s is multicast address, skip this rte",
1191 inet_ntoa(rte
->nexthop
));
1195 if (!if_lookup_address((void *)&rte
->nexthop
, AF_INET
,
1197 struct route_node
*rn
;
1198 struct rip_info
*rinfo
;
1200 rn
= route_node_match_ipv4(rip
->table
,
1206 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1209 if (IS_RIP_DEBUG_EVENT
)
1211 "Next hop %s is on RIP network. Set nexthop to the packet's originator",
1214 rte
->nexthop
= rinfo
->from
;
1216 if (IS_RIP_DEBUG_EVENT
)
1218 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1221 rte
->nexthop
.s_addr
= 0;
1224 route_unlock_node(rn
);
1226 if (IS_RIP_DEBUG_EVENT
)
1228 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1231 rte
->nexthop
.s_addr
= 0;
1236 /* For RIPv1, there won't be a valid netmask.
1238 This is a best guess at the masks. If everyone was using old
1239 Ciscos before the 'ip subnet zero' option, it would be almost
1242 Cisco summarize ripv1 advertisments to the classful boundary
1243 (/16 for class B's) except when the RIP packet does to inside
1244 the classful network in question. */
1246 if ((packet
->version
== RIPv1
&& rte
->prefix
.s_addr
!= 0)
1247 || (packet
->version
== RIPv2
1248 && (rte
->prefix
.s_addr
!= 0
1249 && rte
->mask
.s_addr
== 0))) {
1250 uint32_t destination
;
1252 if (subnetted
== -1) {
1253 memcpy(&ifaddr
, ifc
->address
,
1254 sizeof(struct prefix_ipv4
));
1255 memcpy(&ifaddrclass
, &ifaddr
,
1256 sizeof(struct prefix_ipv4
));
1257 apply_classful_mask_ipv4(&ifaddrclass
);
1259 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1263 destination
= ntohl(rte
->prefix
.s_addr
);
1265 if (IN_CLASSA(destination
))
1266 masklen2ip(8, &rte
->mask
);
1267 else if (IN_CLASSB(destination
))
1268 masklen2ip(16, &rte
->mask
);
1269 else if (IN_CLASSC(destination
))
1270 masklen2ip(24, &rte
->mask
);
1273 masklen2ip(ifaddrclass
.prefixlen
,
1274 (struct in_addr
*)&destination
);
1275 if ((subnetted
== 1)
1276 && ((rte
->prefix
.s_addr
& destination
)
1277 == ifaddrclass
.prefix
.s_addr
)) {
1278 masklen2ip(ifaddr
.prefixlen
, &rte
->mask
);
1279 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1280 != rte
->prefix
.s_addr
)
1281 masklen2ip(32, &rte
->mask
);
1282 if (IS_RIP_DEBUG_EVENT
)
1283 zlog_debug("Subnetted route %s",
1284 inet_ntoa(rte
->prefix
));
1286 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1287 != rte
->prefix
.s_addr
)
1291 if (IS_RIP_DEBUG_EVENT
) {
1292 zlog_debug("Resultant route %s",
1293 inet_ntoa(rte
->prefix
));
1294 zlog_debug("Resultant mask %s",
1295 inet_ntoa(rte
->mask
));
1299 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1300 ignore the entry. */
1301 if ((packet
->version
== RIPv2
) && (rte
->mask
.s_addr
!= 0)
1302 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1303 != rte
->prefix
.s_addr
)) {
1305 "RIPv2 address %s is not mask /%d applied one",
1306 inet_ntoa(rte
->prefix
), ip_masklen(rte
->mask
));
1307 rip_peer_bad_route(from
);
1311 /* Default route's netmask is ignored. */
1312 if (packet
->version
== RIPv2
&& (rte
->prefix
.s_addr
== 0)
1313 && (rte
->mask
.s_addr
!= 0)) {
1314 if (IS_RIP_DEBUG_EVENT
)
1316 "Default route with non-zero netmask. Set zero to netmask");
1317 rte
->mask
.s_addr
= 0;
1320 /* Routing table updates. */
1321 rip_rte_process(rte
, from
, ifc
->ifp
);
1325 /* Make socket for RIP protocol. */
1326 static int rip_create_socket(void)
1330 struct sockaddr_in addr
;
1332 memset(&addr
, 0, sizeof(struct sockaddr_in
));
1333 addr
.sin_family
= AF_INET
;
1334 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1335 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1336 addr
.sin_len
= sizeof(struct sockaddr_in
);
1337 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1338 /* sending port must always be the RIP port */
1339 addr
.sin_port
= htons(RIP_PORT_DEFAULT
);
1341 /* Make datagram socket. */
1342 sock
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
1344 flog_err_sys(LIB_ERR_SOCKET
, "Cannot create UDP socket: %s",
1345 safe_strerror(errno
));
1349 sockopt_broadcast(sock
);
1350 sockopt_reuseaddr(sock
);
1351 sockopt_reuseport(sock
);
1352 setsockopt_ipv4_multicast_loop(sock
, 0);
1354 setsockopt_pktinfo(sock
);
1355 #endif /* RIP_RECVMSG */
1356 #ifdef IPTOS_PREC_INTERNETCONTROL
1357 setsockopt_ipv4_tos(sock
, IPTOS_PREC_INTERNETCONTROL
);
1360 frr_elevate_privs(&ripd_privs
) {
1361 setsockopt_so_recvbuf(sock
, RIP_UDP_RCV_BUF
);
1362 if ((ret
= bind(sock
, (struct sockaddr
*)&addr
, sizeof(addr
))) < 0)
1365 int save_errno
= errno
;
1367 zlog_err("%s: Can't bind socket %d to %s port %d: %s",
1369 sock
, inet_ntoa(addr
.sin_addr
),
1370 (int)ntohs(addr
.sin_port
), safe_strerror(save_errno
));
1381 /* RIP packet send to destination address, on interface denoted by
1382 * by connected argument. NULL to argument denotes destination should be
1383 * should be RIP multicast group
1385 static int rip_send_packet(uint8_t *buf
, int size
, struct sockaddr_in
*to
,
1386 struct connected
*ifc
)
1389 struct sockaddr_in sin
;
1391 assert(ifc
!= NULL
);
1393 if (IS_RIP_DEBUG_PACKET
) {
1394 #define ADDRESS_SIZE 20
1395 char dst
[ADDRESS_SIZE
];
1396 dst
[ADDRESS_SIZE
- 1] = '\0';
1399 strncpy(dst
, inet_ntoa(to
->sin_addr
), ADDRESS_SIZE
- 1);
1401 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1402 strncpy(dst
, inet_ntoa(sin
.sin_addr
), ADDRESS_SIZE
- 1);
1405 zlog_debug("rip_send_packet %s > %s (%s)",
1406 inet_ntoa(ifc
->address
->u
.prefix4
), dst
,
1410 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
1412 * ZEBRA_IFA_SECONDARY is set on linux when an interface is
1414 * with multiple addresses on the same subnet: the first address
1415 * on the subnet is configured "primary", and all subsequent
1417 * on that subnet are treated as "secondary" addresses.
1418 * In order to avoid routing-table bloat on other rip listeners,
1419 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY
1421 * XXX Since Linux is the only system for which the
1422 * ZEBRA_IFA_SECONDARY
1423 * flag is set, we would end up sending a packet for a
1425 * source address on non-linux systems.
1427 if (IS_RIP_DEBUG_PACKET
)
1428 zlog_debug("duplicate dropped");
1432 /* Make destination address. */
1433 memset(&sin
, 0, sizeof(struct sockaddr_in
));
1434 sin
.sin_family
= AF_INET
;
1435 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1436 sin
.sin_len
= sizeof(struct sockaddr_in
);
1437 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1439 /* When destination is specified, use it's port and address. */
1441 sin
.sin_port
= to
->sin_port
;
1442 sin
.sin_addr
= to
->sin_addr
;
1444 sin
.sin_port
= htons(RIP_PORT_DEFAULT
);
1445 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1447 rip_interface_multicast_set(rip
->sock
, ifc
);
1450 ret
= sendto(rip
->sock
, buf
, size
, 0, (struct sockaddr
*)&sin
,
1451 sizeof(struct sockaddr_in
));
1453 if (IS_RIP_DEBUG_EVENT
)
1454 zlog_debug("SEND to %s.%d", inet_ntoa(sin
.sin_addr
),
1455 ntohs(sin
.sin_port
));
1458 zlog_warn("can't send packet : %s", safe_strerror(errno
));
1463 /* Add redistributed route to RIP table. */
1464 void rip_redistribute_add(int type
, int sub_type
, struct prefix_ipv4
*p
,
1465 struct nexthop
*nh
, unsigned int metric
,
1466 unsigned char distance
, route_tag_t tag
)
1469 struct route_node
*rp
= NULL
;
1470 struct rip_info
*rinfo
= NULL
, newinfo
;
1471 struct list
*list
= NULL
;
1473 /* Redistribute route */
1474 ret
= rip_destination_check(p
->prefix
);
1478 rp
= route_node_get(rip
->table
, (struct prefix
*)p
);
1480 memset(&newinfo
, 0, sizeof(struct rip_info
));
1481 newinfo
.type
= type
;
1482 newinfo
.sub_type
= sub_type
;
1484 newinfo
.external_metric
= metric
;
1485 newinfo
.distance
= distance
;
1486 if (tag
<= UINT16_MAX
) /* RIP only supports 16 bit tags */
1491 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
1492 rinfo
= listgetdata(listhead(list
));
1494 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
1495 && rinfo
->sub_type
== RIP_ROUTE_INTERFACE
1496 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
1497 route_unlock_node(rp
);
1501 /* Manually configured RIP route check. */
1502 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1503 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
1504 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))) {
1505 if (type
!= ZEBRA_ROUTE_RIP
1506 || ((sub_type
!= RIP_ROUTE_STATIC
)
1507 && (sub_type
!= RIP_ROUTE_DEFAULT
))) {
1508 route_unlock_node(rp
);
1513 (void)rip_ecmp_replace(&newinfo
);
1514 route_unlock_node(rp
);
1516 (void)rip_ecmp_add(&newinfo
);
1518 if (IS_RIP_DEBUG_EVENT
) {
1519 zlog_debug("Redistribute new prefix %s/%d",
1520 inet_ntoa(p
->prefix
), p
->prefixlen
);
1523 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1526 /* Delete redistributed route from RIP table. */
1527 void rip_redistribute_delete(int type
, int sub_type
, struct prefix_ipv4
*p
,
1531 struct route_node
*rp
;
1532 struct rip_info
*rinfo
;
1534 ret
= rip_destination_check(p
->prefix
);
1538 rp
= route_node_lookup(rip
->table
, (struct prefix
*)p
);
1540 struct list
*list
= rp
->info
;
1542 if (list
!= NULL
&& listcount(list
) != 0) {
1543 rinfo
= listgetdata(listhead(list
));
1544 if (rinfo
!= NULL
&& rinfo
->type
== type
1545 && rinfo
->sub_type
== sub_type
1546 && rinfo
->nh
.ifindex
== ifindex
) {
1547 /* Perform poisoned reverse. */
1548 rinfo
->metric
= RIP_METRIC_INFINITY
;
1549 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
1550 rip_garbage_collect
,
1552 RIP_TIMER_OFF(rinfo
->t_timeout
);
1553 rinfo
->flags
|= RIP_RTF_CHANGED
;
1555 if (IS_RIP_DEBUG_EVENT
)
1557 "Poison %s/%d on the interface %s with an "
1558 "infinity metric [delete]",
1559 inet_ntoa(p
->prefix
),
1561 ifindex2ifname(ifindex
,
1564 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1567 route_unlock_node(rp
);
1571 /* Response to request called from rip_read ().*/
1572 static void rip_request_process(struct rip_packet
*packet
, int size
,
1573 struct sockaddr_in
*from
, struct connected
*ifc
)
1577 struct prefix_ipv4 p
;
1578 struct route_node
*rp
;
1579 struct rip_info
*rinfo
;
1580 struct rip_interface
*ri
;
1582 /* Does not reponse to the requests on the loopback interfaces */
1583 if (if_is_loopback(ifc
->ifp
))
1586 /* Check RIP process is enabled on this interface. */
1587 ri
= ifc
->ifp
->info
;
1591 /* When passive interface is specified, suppress responses */
1595 /* RIP peer update. */
1596 rip_peer_update(from
, packet
->version
);
1598 lim
= ((caddr_t
)packet
) + size
;
1601 /* The Request is processed entry by entry. If there are no
1602 entries, no response is given. */
1603 if (lim
== (caddr_t
)rte
)
1606 /* There is one special case. If there is exactly one entry in the
1607 request, and it has an address family identifier of zero and a
1608 metric of infinity (i.e., 16), then this is a request to send the
1609 entire routing table. */
1610 if (lim
== ((caddr_t
)(rte
+ 1)) && ntohs(rte
->family
) == 0
1611 && ntohl(rte
->metric
) == RIP_METRIC_INFINITY
) {
1612 /* All route with split horizon */
1613 rip_output_process(ifc
, from
, rip_all_route
, packet
->version
);
1615 if (ntohs(rte
->family
) != AF_INET
)
1618 /* Examine the list of RTEs in the Request one by one. For each
1619 entry, look up the destination in the router's routing
1620 database and, if there is a route, put that route's metric in
1621 the metric field of the RTE. If there is no explicit route
1622 to the specified destination, put infinity in the metric
1623 field. Once all the entries have been filled in, change the
1624 command from Request to Response and send the datagram back
1625 to the requestor. */
1628 for (; ((caddr_t
)rte
) < lim
; rte
++) {
1629 p
.prefix
= rte
->prefix
;
1630 p
.prefixlen
= ip_masklen(rte
->mask
);
1631 apply_mask_ipv4(&p
);
1633 rp
= route_node_lookup(rip
->table
, (struct prefix
*)&p
);
1635 rinfo
= listgetdata(
1636 listhead((struct list
*)rp
->info
));
1637 rte
->metric
= htonl(rinfo
->metric
);
1638 route_unlock_node(rp
);
1640 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
1642 packet
->command
= RIP_RESPONSE
;
1644 (void)rip_send_packet((uint8_t *)packet
, size
, from
, ifc
);
1646 rip_global_queries
++;
1650 /* Set IPv6 packet info to the socket. */
1651 static int setsockopt_pktinfo(int sock
)
1656 ret
= setsockopt(sock
, IPPROTO_IP
, IP_PKTINFO
, &val
, sizeof(val
));
1658 zlog_warn("Can't setsockopt IP_PKTINFO : %s",
1659 safe_strerror(errno
));
1663 /* Read RIP packet by recvmsg function. */
1664 int rip_recvmsg(int sock
, uint8_t *buf
, int size
, struct sockaddr_in
*from
,
1670 struct cmsghdr
*ptr
;
1673 memset(&msg
, 0, sizeof(msg
));
1674 msg
.msg_name
= (void *)from
;
1675 msg
.msg_namelen
= sizeof(struct sockaddr_in
);
1678 msg
.msg_control
= (void *)adata
;
1679 msg
.msg_controllen
= sizeof adata
;
1683 ret
= recvmsg(sock
, &msg
, 0);
1687 for (ptr
= ZCMSG_FIRSTHDR(&msg
); ptr
!= NULL
;
1688 ptr
= CMSG_NXTHDR(&msg
, ptr
))
1689 if (ptr
->cmsg_level
== IPPROTO_IP
1690 && ptr
->cmsg_type
== IP_PKTINFO
) {
1691 struct in_pktinfo
*pktinfo
;
1694 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(ptr
);
1695 i
= pktinfo
->ipi_ifindex
;
1700 /* RIP packet read function. */
1701 int rip_read_new(struct thread
*t
)
1705 char buf
[RIP_PACKET_MAXSIZ
];
1706 struct sockaddr_in from
;
1709 /* Fetch socket then register myself. */
1710 sock
= THREAD_FD(t
);
1711 rip_event(RIP_READ
, sock
);
1713 /* Read RIP packet. */
1714 ret
= rip_recvmsg(sock
, buf
, RIP_PACKET_MAXSIZ
, &from
, (int *)&ifindex
);
1716 zlog_warn("Can't read RIP packet: %s", safe_strerror(errno
));
1722 #endif /* RIP_RECVMSG */
1724 /* First entry point of RIP packet. */
1725 static int rip_read(struct thread
*t
)
1730 union rip_buf rip_buf
;
1731 struct rip_packet
*packet
;
1732 struct sockaddr_in from
;
1736 struct interface
*ifp
= NULL
;
1737 struct connected
*ifc
;
1738 struct rip_interface
*ri
;
1741 /* Fetch socket then register myself. */
1742 sock
= THREAD_FD(t
);
1745 /* Add myself to tne next event */
1746 rip_event(RIP_READ
, sock
);
1748 /* RIPd manages only IPv4. */
1749 memset(&from
, 0, sizeof(struct sockaddr_in
));
1750 fromlen
= sizeof(struct sockaddr_in
);
1752 len
= recvfrom(sock
, (char *)&rip_buf
.buf
, sizeof(rip_buf
.buf
), 0,
1753 (struct sockaddr
*)&from
, &fromlen
);
1755 zlog_info("recvfrom failed: %s", safe_strerror(errno
));
1759 /* Check is this packet comming from myself? */
1760 if (if_check_address(from
.sin_addr
)) {
1761 if (IS_RIP_DEBUG_PACKET
)
1762 zlog_debug("ignore packet comes from myself");
1766 /* Which interface is this packet comes from. */
1767 ifc
= if_lookup_address((void *)&from
.sin_addr
, AF_INET
, VRF_DEFAULT
);
1771 /* RIP packet received */
1772 if (IS_RIP_DEBUG_EVENT
)
1773 zlog_debug("RECV packet from %s port %d on %s",
1774 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1775 ifp
? ifp
->name
: "unknown");
1777 /* If this packet come from unknown interface, ignore it. */
1780 "rip_read: cannot find interface for packet from %s port %d",
1781 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
));
1786 p
.u
.prefix4
= from
.sin_addr
;
1787 p
.prefixlen
= IPV4_MAX_BITLEN
;
1789 ifc
= connected_lookup_prefix(ifp
, &p
);
1793 "rip_read: cannot find connected address for packet from %s "
1794 "port %d on interface %s",
1795 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1800 /* Packet length check. */
1801 if (len
< RIP_PACKET_MINSIZ
) {
1802 zlog_warn("packet size %d is smaller than minimum size %d", len
,
1804 rip_peer_bad_packet(&from
);
1807 if (len
> RIP_PACKET_MAXSIZ
) {
1808 zlog_warn("packet size %d is larger than max size %d", len
,
1810 rip_peer_bad_packet(&from
);
1814 /* Packet alignment check. */
1815 if ((len
- RIP_PACKET_MINSIZ
) % 20) {
1816 zlog_warn("packet size %d is wrong for RIP packet alignment",
1818 rip_peer_bad_packet(&from
);
1822 /* Set RTE number. */
1823 rtenum
= ((len
- RIP_PACKET_MINSIZ
) / 20);
1825 /* For easy to handle. */
1826 packet
= &rip_buf
.rip_packet
;
1828 /* RIP version check. */
1829 if (packet
->version
== 0) {
1830 zlog_info("version 0 with command %d received.",
1832 rip_peer_bad_packet(&from
);
1836 /* Dump RIP packet. */
1837 if (IS_RIP_DEBUG_RECV
)
1838 rip_packet_dump(packet
, len
, "RECV");
1840 /* RIP version adjust. This code should rethink now. RFC1058 says
1841 that "Version 1 implementations are to ignore this extra data and
1842 process only the fields specified in this document.". So RIPv3
1843 packet should be treated as RIPv1 ignoring must be zero field. */
1844 if (packet
->version
> RIPv2
)
1845 packet
->version
= RIPv2
;
1847 /* Is RIP running or is this RIP neighbor ?*/
1849 if (!ri
->running
&& !rip_neighbor_lookup(&from
)) {
1850 if (IS_RIP_DEBUG_EVENT
)
1851 zlog_debug("RIP is not enabled on interface %s.",
1853 rip_peer_bad_packet(&from
);
1857 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1858 vrecv
= ((ri
->ri_receive
== RI_RIP_UNSPEC
) ? rip
->version_recv
1860 if (vrecv
== RI_RIP_VERSION_NONE
1861 || ((packet
->version
== RIPv1
) && !(vrecv
& RIPv1
))
1862 || ((packet
->version
== RIPv2
) && !(vrecv
& RIPv2
))) {
1863 if (IS_RIP_DEBUG_PACKET
)
1865 " packet's v%d doesn't fit to if version spec",
1867 rip_peer_bad_packet(&from
);
1871 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1872 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1873 accepted; authenticated RIP-2 messages shall be discarded. */
1874 if ((ri
->auth_type
== RIP_NO_AUTH
) && rtenum
1875 && (packet
->version
== RIPv2
)
1876 && (packet
->rte
->family
== htons(RIP_FAMILY_AUTH
))) {
1877 if (IS_RIP_DEBUG_EVENT
)
1879 "packet RIPv%d is dropped because authentication disabled",
1881 rip_peer_bad_packet(&from
);
1886 If the router is configured to authenticate RIP-2 messages, then
1887 RIP-1 messages and RIP-2 messages which pass authentication
1888 testing shall be accepted; unauthenticated and failed
1889 authentication RIP-2 messages shall be discarded. For maximum
1890 security, RIP-1 messages should be ignored when authentication is
1891 in use (see section 4.1); otherwise, the routing information from
1892 authenticated messages will be propagated by RIP-1 routers in an
1893 unauthenticated manner.
1895 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1896 * always reply regardless of authentication settings, because:
1898 * - if there other authorised routers on-link, the REQUESTor can
1899 * passively obtain the routing updates anyway
1900 * - if there are no other authorised routers on-link, RIP can
1901 * easily be disabled for the link to prevent giving out information
1902 * on state of this routers RIP routing table..
1904 * I.e. if RIPv1 has any place anymore these days, it's as a very
1905 * simple way to distribute routing information (e.g. to embedded
1906 * hosts / appliances) and the ability to give out RIPv1
1907 * routing-information freely, while still requiring RIPv2
1908 * authentication for any RESPONSEs might be vaguely useful.
1910 if (ri
->auth_type
!= RIP_NO_AUTH
&& packet
->version
== RIPv1
) {
1911 /* Discard RIPv1 messages other than REQUESTs */
1912 if (packet
->command
!= RIP_REQUEST
) {
1913 if (IS_RIP_DEBUG_PACKET
)
1916 " dropped because authentication enabled");
1917 rip_peer_bad_packet(&from
);
1920 } else if (ri
->auth_type
!= RIP_NO_AUTH
) {
1921 const char *auth_desc
;
1924 /* There definitely is no authentication in the packet.
1926 if (IS_RIP_DEBUG_PACKET
)
1928 "RIPv2 authentication failed: no auth RTE in packet");
1929 rip_peer_bad_packet(&from
);
1933 /* First RTE must be an Authentication Family RTE */
1934 if (packet
->rte
->family
!= htons(RIP_FAMILY_AUTH
)) {
1935 if (IS_RIP_DEBUG_PACKET
)
1938 " dropped because authentication enabled");
1939 rip_peer_bad_packet(&from
);
1943 /* Check RIPv2 authentication. */
1944 switch (ntohs(packet
->rte
->tag
)) {
1945 case RIP_AUTH_SIMPLE_PASSWORD
:
1946 auth_desc
= "simple";
1947 ret
= rip_auth_simple_password(packet
->rte
, &from
, ifp
);
1952 ret
= rip_auth_md5(packet
, &from
, len
, ifp
);
1953 /* Reset RIP packet length to trim MD5 data. */
1959 auth_desc
= "unknown type";
1960 if (IS_RIP_DEBUG_PACKET
)
1962 "RIPv2 Unknown authentication type %d",
1963 ntohs(packet
->rte
->tag
));
1967 if (IS_RIP_DEBUG_PACKET
)
1968 zlog_debug("RIPv2 %s authentication success",
1971 if (IS_RIP_DEBUG_PACKET
)
1972 zlog_debug("RIPv2 %s authentication failure",
1974 rip_peer_bad_packet(&from
);
1979 /* Process each command. */
1980 switch (packet
->command
) {
1982 rip_response_process(packet
, len
, &from
, ifc
);
1986 rip_request_process(packet
, len
, &from
, ifc
);
1991 "Obsolete command %s received, please sent it to routed",
1992 lookup_msg(rip_msg
, packet
->command
, NULL
));
1993 rip_peer_bad_packet(&from
);
1995 case RIP_POLL_ENTRY
:
1996 zlog_info("Obsolete command %s received",
1997 lookup_msg(rip_msg
, packet
->command
, NULL
));
1998 rip_peer_bad_packet(&from
);
2001 zlog_info("Unknown RIP command %d received", packet
->command
);
2002 rip_peer_bad_packet(&from
);
2009 /* Write routing table entry to the stream and return next index of
2010 the routing table entry in the stream. */
2011 static int rip_write_rte(int num
, struct stream
*s
, struct prefix_ipv4
*p
,
2012 uint8_t version
, struct rip_info
*rinfo
)
2014 struct in_addr mask
;
2016 /* Write routing table entry. */
2017 if (version
== RIPv1
) {
2018 stream_putw(s
, AF_INET
);
2020 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2021 stream_put_ipv4(s
, 0);
2022 stream_put_ipv4(s
, 0);
2023 stream_putl(s
, rinfo
->metric_out
);
2025 masklen2ip(p
->prefixlen
, &mask
);
2027 stream_putw(s
, AF_INET
);
2028 stream_putw(s
, rinfo
->tag_out
);
2029 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2030 stream_put_ipv4(s
, mask
.s_addr
);
2031 stream_put_ipv4(s
, rinfo
->nexthop_out
.s_addr
);
2032 stream_putl(s
, rinfo
->metric_out
);
2038 /* Send update to the ifp or spcified neighbor. */
2039 void rip_output_process(struct connected
*ifc
, struct sockaddr_in
*to
,
2040 int route_type
, uint8_t version
)
2044 struct route_node
*rp
;
2045 struct rip_info
*rinfo
;
2046 struct rip_interface
*ri
;
2047 struct prefix_ipv4
*p
;
2048 struct prefix_ipv4 classfull
;
2049 struct prefix_ipv4 ifaddrclass
;
2050 struct key
*key
= NULL
;
2051 /* this might need to made dynamic if RIP ever supported auth methods
2052 with larger key string sizes */
2053 char auth_str
[RIP_AUTH_SIMPLE_SIZE
];
2054 size_t doff
= 0; /* offset of digest offset field */
2058 struct list
*list
= NULL
;
2059 struct listnode
*listnode
= NULL
;
2061 /* Logging output event. */
2062 if (IS_RIP_DEBUG_EVENT
) {
2064 zlog_debug("update routes to neighbor %s",
2065 inet_ntoa(to
->sin_addr
));
2067 zlog_debug("update routes on interface %s ifindex %d",
2068 ifc
->ifp
->name
, ifc
->ifp
->ifindex
);
2071 /* Set output stream. */
2074 /* Reset stream and RTE counter. */
2076 rtemax
= RIP_MAX_RTE
;
2078 /* Get RIP interface. */
2079 ri
= ifc
->ifp
->info
;
2081 /* If output interface is in simple password authentication mode, we
2082 need space for authentication data. */
2083 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2086 /* If output interface is in MD5 authentication mode, we need space
2087 for authentication header and data. */
2088 if (ri
->auth_type
== RIP_AUTH_MD5
)
2091 /* If output interface is in simple password authentication mode
2092 and string or keychain is specified we need space for auth. data */
2093 if (ri
->auth_type
!= RIP_NO_AUTH
) {
2094 if (ri
->key_chain
) {
2095 struct keychain
*keychain
;
2097 keychain
= keychain_lookup(ri
->key_chain
);
2099 key
= key_lookup_for_send(keychain
);
2101 /* to be passed to auth functions later */
2102 rip_auth_prepare_str_send(ri
, key
, auth_str
,
2103 RIP_AUTH_SIMPLE_SIZE
);
2104 if (strlen(auth_str
) == 0)
2108 if (version
== RIPv1
) {
2109 memcpy(&ifaddrclass
, ifc
->address
, sizeof(struct prefix_ipv4
));
2110 apply_classful_mask_ipv4(&ifaddrclass
);
2112 if (ifc
->address
->prefixlen
> ifaddrclass
.prefixlen
)
2116 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2117 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
2118 rinfo
= listgetdata(listhead(list
));
2119 /* For RIPv1, if we are subnetted, output subnets in our
2121 /* that have the same mask as the output "interface".
2123 /* networks, only the classfull version is output. */
2125 if (version
== RIPv1
) {
2126 p
= (struct prefix_ipv4
*)&rp
->p
;
2128 if (IS_RIP_DEBUG_PACKET
)
2130 "RIPv1 mask check, %s/%d considered for output",
2131 inet_ntoa(rp
->p
.u
.prefix4
),
2136 (struct prefix
*)&ifaddrclass
,
2138 if ((ifc
->address
->prefixlen
2140 && (rp
->p
.prefixlen
!= 32))
2143 memcpy(&classfull
, &rp
->p
,
2144 sizeof(struct prefix_ipv4
));
2145 apply_classful_mask_ipv4(&classfull
);
2146 if (rp
->p
.u
.prefix4
.s_addr
!= 0
2147 && classfull
.prefixlen
2151 if (IS_RIP_DEBUG_PACKET
)
2153 "RIPv1 mask check, %s/%d made it through",
2154 inet_ntoa(rp
->p
.u
.prefix4
),
2157 p
= (struct prefix_ipv4
*)&rp
->p
;
2159 /* Apply output filters. */
2160 ret
= rip_filter(RIP_FILTER_OUT
, p
, ri
);
2164 /* Changed route only output. */
2165 if (route_type
== rip_changed_route
2166 && (!(rinfo
->flags
& RIP_RTF_CHANGED
)))
2169 /* Split horizon. */
2170 /* if (split_horizon == rip_split_horizon) */
2171 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
) {
2173 * We perform split horizon for RIP and
2175 * For rip routes, we want to suppress the route
2177 * end up sending the route back on the
2179 * learned it from, with a higher metric. For
2181 * we suppress the route if the prefix is a
2183 * source address that we are going to use for
2185 * (in order to handle the case when multiple
2187 * configured on the same interface).
2190 struct rip_info
*tmp_rinfo
= NULL
;
2191 struct connected
*tmp_ifc
= 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 for (ALL_LIST_ELEMENTS_RO(
2205 ifc
->ifp
->connected
,
2209 tmp_ifc
->address
)) {
2219 /* Preparation for route-map. */
2220 rinfo
->metric_set
= 0;
2221 rinfo
->nexthop_out
.s_addr
= 0;
2222 rinfo
->metric_out
= rinfo
->metric
;
2223 rinfo
->tag_out
= rinfo
->tag
;
2224 rinfo
->ifindex_out
= ifc
->ifp
->ifindex
;
2226 /* In order to avoid some local loops,
2227 * if the RIP route has a nexthop via this interface,
2229 * otherwise set it to 0. The nexthop should not be
2231 * beyond the local broadcast/multicast area in order
2232 * to avoid an IGP multi-level recursive look-up.
2235 if (rinfo
->nh
.ifindex
== ifc
->ifp
->ifindex
)
2236 rinfo
->nexthop_out
= rinfo
->nh
.gate
.ipv4
;
2238 /* Interface route-map */
2239 if (ri
->routemap
[RIP_FILTER_OUT
]) {
2240 ret
= route_map_apply(
2241 ri
->routemap
[RIP_FILTER_OUT
],
2242 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2244 if (ret
== RMAP_DENYMATCH
) {
2245 if (IS_RIP_DEBUG_PACKET
)
2247 "RIP %s/%d is filtered by route-map out",
2248 inet_ntoa(p
->prefix
),
2254 /* Apply redistribute route map - continue, if deny */
2255 if (rip
->route_map
[rinfo
->type
].name
2256 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2257 ret
= route_map_apply(
2258 rip
->route_map
[rinfo
->type
].map
,
2259 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2261 if (ret
== RMAP_DENYMATCH
) {
2262 if (IS_RIP_DEBUG_PACKET
)
2264 "%s/%d is filtered by route-map",
2265 inet_ntoa(p
->prefix
),
2271 /* When route-map does not set metric. */
2272 if (!rinfo
->metric_set
) {
2273 /* If redistribute metric is set. */
2274 if (rip
->route_map
[rinfo
->type
].metric_config
2275 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
2277 rip
->route_map
[rinfo
->type
]
2280 /* If the route is not connected or
2282 one, use default-metric value*/
2283 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2285 != ZEBRA_ROUTE_CONNECT
2287 != RIP_METRIC_INFINITY
)
2289 rip
->default_metric
;
2293 /* Apply offset-list */
2294 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2295 rip_offset_list_apply_out(p
, ifc
->ifp
,
2296 &rinfo
->metric_out
);
2298 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2299 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2301 /* Perform split-horizon with poisoned reverse
2302 * for RIP and connected routes.
2304 if (ri
->split_horizon
2305 == RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2307 * We perform split horizon for RIP and
2309 * For rip routes, we want to suppress the route
2311 * end up sending the route back on the
2313 * learned it from, with a higher metric. For
2315 * we suppress the route if the prefix is a
2317 * source address that we are going to use for
2319 * (in order to handle the case when multiple
2321 * configured on the same interface).
2323 struct rip_info
*tmp_rinfo
= NULL
;
2324 struct connected
*tmp_ifc
= NULL
;
2326 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2328 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2329 && tmp_rinfo
->nh
.ifindex
2330 == ifc
->ifp
->ifindex
)
2332 RIP_METRIC_INFINITY
;
2334 if (rinfo
->metric_out
!= RIP_METRIC_INFINITY
2335 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2336 for (ALL_LIST_ELEMENTS_RO(
2337 ifc
->ifp
->connected
,
2341 tmp_ifc
->address
)) {
2343 RIP_METRIC_INFINITY
;
2349 /* Prepare preamble, auth headers, if needs be */
2351 stream_putc(s
, RIP_RESPONSE
);
2352 stream_putc(s
, version
);
2355 /* auth header for !v1 && !no_auth */
2356 if ((ri
->auth_type
!= RIP_NO_AUTH
)
2357 && (version
!= RIPv1
))
2358 doff
= rip_auth_header_write(
2359 s
, ri
, key
, auth_str
,
2360 RIP_AUTH_SIMPLE_SIZE
);
2363 /* Write RTE to the stream. */
2364 num
= rip_write_rte(num
, s
, p
, version
, rinfo
);
2365 if (num
== rtemax
) {
2366 if (version
== RIPv2
2367 && ri
->auth_type
== RIP_AUTH_MD5
)
2368 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2369 RIP_AUTH_SIMPLE_SIZE
);
2371 ret
= rip_send_packet(STREAM_DATA(s
),
2372 stream_get_endp(s
), to
,
2375 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2376 rip_packet_dump((struct rip_packet
*)
2385 /* Flush unwritten RTE. */
2387 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2388 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2389 RIP_AUTH_SIMPLE_SIZE
);
2391 ret
= rip_send_packet(STREAM_DATA(s
), stream_get_endp(s
), to
,
2394 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2395 rip_packet_dump((struct rip_packet
*)STREAM_DATA(s
),
2396 stream_get_endp(s
), "SEND");
2400 /* Statistics updates. */
2404 /* Send RIP packet to the interface. */
2405 static void rip_update_interface(struct connected
*ifc
, uint8_t version
,
2408 struct interface
*ifp
= ifc
->ifp
;
2409 struct rip_interface
*ri
= ifp
->info
;
2410 struct sockaddr_in to
;
2412 /* When RIP version is 2 and multicast enable interface. */
2413 if (version
== RIPv2
&& !ri
->v2_broadcast
&& if_is_multicast(ifp
)) {
2414 if (IS_RIP_DEBUG_EVENT
)
2415 zlog_debug("multicast announce on %s ", ifp
->name
);
2417 rip_output_process(ifc
, NULL
, route_type
, version
);
2421 /* If we can't send multicast packet, send it with unicast. */
2422 if (if_is_broadcast(ifp
) || if_is_pointopoint(ifp
)) {
2423 if (ifc
->address
->family
== AF_INET
) {
2424 /* Destination address and port setting. */
2425 memset(&to
, 0, sizeof(struct sockaddr_in
));
2426 if (ifc
->destination
)
2427 /* use specified broadcast or peer destination
2429 to
.sin_addr
= ifc
->destination
->u
.prefix4
;
2430 else if (ifc
->address
->prefixlen
< IPV4_MAX_PREFIXLEN
)
2431 /* calculate the appropriate broadcast address
2433 to
.sin_addr
.s_addr
= ipv4_broadcast_addr(
2434 ifc
->address
->u
.prefix4
.s_addr
,
2435 ifc
->address
->prefixlen
);
2437 /* do not know where to send the packet */
2439 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2441 if (IS_RIP_DEBUG_EVENT
)
2442 zlog_debug("%s announce to %s on %s",
2443 CONNECTED_PEER(ifc
) ? "unicast"
2445 inet_ntoa(to
.sin_addr
), ifp
->name
);
2447 rip_output_process(ifc
, &to
, route_type
, version
);
2452 /* Update send to all interface and neighbor. */
2453 static void rip_update_process(int route_type
)
2455 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2456 struct listnode
*ifnode
, *ifnnode
;
2457 struct connected
*connected
;
2458 struct interface
*ifp
;
2459 struct rip_interface
*ri
;
2460 struct route_node
*rp
;
2461 struct sockaddr_in to
;
2464 /* Send RIP update to each interface. */
2465 FOR_ALL_INTERFACES (vrf
, ifp
) {
2466 if (if_is_loopback(ifp
))
2469 if (!if_is_operative(ifp
))
2472 /* Fetch RIP interface information. */
2475 /* When passive interface is specified, suppress announce to the
2482 * If there is no version configuration in the
2484 * use rip's version setting.
2486 int vsend
= ((ri
->ri_send
== RI_RIP_UNSPEC
)
2490 if (IS_RIP_DEBUG_EVENT
)
2491 zlog_debug("SEND UPDATE to %s ifindex %d",
2492 ifp
->name
, ifp
->ifindex
);
2494 /* send update on each connected network */
2495 for (ALL_LIST_ELEMENTS(ifp
->connected
, ifnode
, ifnnode
,
2497 if (connected
->address
->family
== AF_INET
) {
2499 rip_update_interface(
2503 && if_is_multicast(ifp
))
2504 rip_update_interface(
2512 /* RIP send updates to each neighbor. */
2513 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
2514 if (rp
->info
!= NULL
) {
2517 connected
= if_lookup_address(&p
->u
.prefix4
, AF_INET
,
2521 "Neighbor %s doesnt have connected interface!",
2522 inet_ntoa(p
->u
.prefix4
));
2526 /* Set destination address and port */
2527 memset(&to
, 0, sizeof(struct sockaddr_in
));
2528 to
.sin_addr
= p
->u
.prefix4
;
2529 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2531 /* RIP version is rip's configuration. */
2532 rip_output_process(connected
, &to
, route_type
,
2537 /* RIP's periodical timer. */
2538 static int rip_update(struct thread
*t
)
2540 /* Clear timer pointer. */
2541 rip
->t_update
= NULL
;
2543 if (IS_RIP_DEBUG_EVENT
)
2544 zlog_debug("update timer fire!");
2546 /* Process update output. */
2547 rip_update_process(rip_all_route
);
2549 /* Triggered updates may be suppressed if a regular update is due by
2550 the time the triggered update would be sent. */
2551 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2554 /* Register myself. */
2555 rip_event(RIP_UPDATE_EVENT
, 0);
2560 /* Walk down the RIP routing table then clear changed flag. */
2561 static void rip_clear_changed_flag(void)
2563 struct route_node
*rp
;
2564 struct rip_info
*rinfo
= NULL
;
2565 struct list
*list
= NULL
;
2566 struct listnode
*listnode
= NULL
;
2568 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2569 if ((list
= rp
->info
) != NULL
)
2570 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
2571 UNSET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2572 /* This flag can be set only on the first entry.
2578 /* Triggered update interval timer. */
2579 static int rip_triggered_interval(struct thread
*t
)
2581 int rip_triggered_update(struct thread
*);
2583 rip
->t_triggered_interval
= NULL
;
2587 rip_triggered_update(t
);
2592 /* Execute triggered update. */
2593 static int rip_triggered_update(struct thread
*t
)
2597 /* Clear thred pointer. */
2598 rip
->t_triggered_update
= NULL
;
2600 /* Cancel interval timer. */
2601 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2604 /* Logging triggered update. */
2605 if (IS_RIP_DEBUG_EVENT
)
2606 zlog_debug("triggered update!");
2608 /* Split Horizon processing is done when generating triggered
2609 updates as well as normal updates (see section 2.6). */
2610 rip_update_process(rip_changed_route
);
2612 /* Once all of the triggered updates have been generated, the route
2613 change flags should be cleared. */
2614 rip_clear_changed_flag();
2616 /* After a triggered update is sent, a timer should be set for a
2617 random interval between 1 and 5 seconds. If other changes that
2618 would trigger updates occur before the timer expires, a single
2619 update is triggered when the timer expires. */
2620 interval
= (random() % 5) + 1;
2622 rip
->t_triggered_interval
= NULL
;
2623 thread_add_timer(master
, rip_triggered_interval
, NULL
, interval
,
2624 &rip
->t_triggered_interval
);
2629 /* Withdraw redistributed route. */
2630 void rip_redistribute_withdraw(int type
)
2632 struct route_node
*rp
;
2633 struct rip_info
*rinfo
= NULL
;
2634 struct list
*list
= NULL
;
2639 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2640 if ((list
= rp
->info
) != NULL
) {
2641 rinfo
= listgetdata(listhead(list
));
2642 if (rinfo
->type
== type
2643 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2644 /* Perform poisoned reverse. */
2645 rinfo
->metric
= RIP_METRIC_INFINITY
;
2646 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
2647 rip_garbage_collect
,
2649 RIP_TIMER_OFF(rinfo
->t_timeout
);
2650 rinfo
->flags
|= RIP_RTF_CHANGED
;
2652 if (IS_RIP_DEBUG_EVENT
) {
2653 struct prefix_ipv4
*p
=
2654 (struct prefix_ipv4
*)&rp
->p
;
2657 "Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2658 inet_ntoa(p
->prefix
),
2665 rip_event(RIP_TRIGGERED_UPDATE
, 0);
2670 /* Create new RIP instance and set it to global variable. */
2671 static int rip_create(void)
2673 rip
= XCALLOC(MTYPE_RIP
, sizeof(struct rip
));
2675 /* Set initial value. */
2676 rip
->version_send
= RI_RIP_VERSION_2
;
2677 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2678 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
2679 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
2680 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
2681 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2683 /* Initialize RIP routig table. */
2684 rip
->table
= route_table_init();
2685 rip
->route
= route_table_init();
2686 rip
->neighbor
= route_table_init();
2688 /* Make output stream. */
2689 rip
->obuf
= stream_new(1500);
2692 rip
->sock
= rip_create_socket();
2696 /* Create read and timer thread. */
2697 rip_event(RIP_READ
, rip
->sock
);
2698 rip_event(RIP_UPDATE_EVENT
, 1);
2705 /* Sned RIP request to the destination. */
2706 int rip_request_send(struct sockaddr_in
*to
, struct interface
*ifp
,
2707 uint8_t version
, struct connected
*connected
)
2710 struct rip_packet rip_packet
;
2711 struct listnode
*node
, *nnode
;
2713 memset(&rip_packet
, 0, sizeof(rip_packet
));
2715 rip_packet
.command
= RIP_REQUEST
;
2716 rip_packet
.version
= version
;
2717 rte
= rip_packet
.rte
;
2718 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
2722 * connected is only sent for ripv1 case, or when
2723 * interface does not support multicast. Caller loops
2724 * over each connected address for this case.
2726 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2728 != sizeof(rip_packet
))
2731 return sizeof(rip_packet
);
2734 /* send request on each connected network */
2735 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, connected
)) {
2736 struct prefix_ipv4
*p
;
2738 p
= (struct prefix_ipv4
*)connected
->address
;
2740 if (p
->family
!= AF_INET
)
2743 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2745 != sizeof(rip_packet
))
2748 return sizeof(rip_packet
);
2751 static int rip_update_jitter(unsigned long time
)
2753 #define JITTER_BOUND 4
2754 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2755 Given that, we cannot let time be less than JITTER_BOUND seconds.
2756 The RIPv2 RFC says jitter should be small compared to
2757 update_time. We consider 1/JITTER_BOUND to be small.
2760 int jitter_input
= time
;
2763 if (jitter_input
< JITTER_BOUND
)
2764 jitter_input
= JITTER_BOUND
;
2766 jitter
= (((random() % ((jitter_input
* 2) + 1)) - jitter_input
));
2768 return jitter
/ JITTER_BOUND
;
2771 void rip_event(enum rip_event event
, int sock
)
2778 thread_add_read(master
, rip_read
, NULL
, sock
, &rip
->t_read
);
2780 case RIP_UPDATE_EVENT
:
2781 RIP_TIMER_OFF(rip
->t_update
);
2782 jitter
= rip_update_jitter(rip
->update_time
);
2783 thread_add_timer(master
, rip_update
, NULL
,
2784 sock
? 2 : rip
->update_time
+ jitter
,
2787 case RIP_TRIGGERED_UPDATE
:
2788 if (rip
->t_triggered_interval
)
2791 thread_add_event(master
, rip_triggered_update
, NULL
, 0,
2792 &rip
->t_triggered_update
);
2799 DEFUN_NOSH (router_rip
,
2802 "Enable a routing process\n"
2803 "Routing Information Protocol (RIP)\n")
2807 /* If rip is not enabled before. */
2811 zlog_info("Can't create RIP");
2812 return CMD_WARNING_CONFIG_FAILED
;
2816 VTY_PUSH_CONTEXT(RIP_NODE
, rip
);
2821 DEFUN (no_router_rip
,
2825 "Enable a routing process\n"
2826 "Routing Information Protocol (RIP)\n")
2836 "Set routing protocol version\n"
2842 version
= atoi(argv
[idx_number
]->arg
);
2843 if (version
!= RIPv1
&& version
!= RIPv2
) {
2844 vty_out(vty
, "invalid rip version %d\n", version
);
2845 return CMD_WARNING_CONFIG_FAILED
;
2847 rip
->version_send
= version
;
2848 rip
->version_recv
= version
;
2853 DEFUN (no_rip_version
,
2855 "no version [(1-2)]",
2857 "Set routing protocol version\n"
2860 /* Set RIP version to the default. */
2861 rip
->version_send
= RI_RIP_VERSION_2
;
2862 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2871 "RIP static route configuration\n"
2872 "IP prefix <network>/<length>\n")
2874 int idx_ipv4_prefixlen
= 1;
2877 struct prefix_ipv4 p
;
2878 struct route_node
*node
;
2880 memset(&nh
, 0, sizeof(nh
));
2881 nh
.type
= NEXTHOP_TYPE_IPV4
;
2883 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
2885 vty_out(vty
, "Malformed address\n");
2886 return CMD_WARNING_CONFIG_FAILED
;
2888 apply_mask_ipv4(&p
);
2890 /* For router rip configuration. */
2891 node
= route_node_get(rip
->route
, (struct prefix
*)&p
);
2894 vty_out(vty
, "There is already same static route.\n");
2895 route_unlock_node(node
);
2899 node
->info
= (void *)1;
2901 rip_redistribute_add(ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, &nh
, 0, 0,
2907 DEFUN (no_rip_route
,
2909 "no route A.B.C.D/M",
2911 "RIP static route configuration\n"
2912 "IP prefix <network>/<length>\n")
2914 int idx_ipv4_prefixlen
= 2;
2916 struct prefix_ipv4 p
;
2917 struct route_node
*node
;
2919 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
2921 vty_out(vty
, "Malformed address\n");
2922 return CMD_WARNING_CONFIG_FAILED
;
2924 apply_mask_ipv4(&p
);
2926 /* For router rip configuration. */
2927 node
= route_node_lookup(rip
->route
, (struct prefix
*)&p
);
2929 vty_out(vty
, "Can't find route %s.\n",
2930 argv
[idx_ipv4_prefixlen
]->arg
);
2931 return CMD_WARNING_CONFIG_FAILED
;
2934 rip_redistribute_delete(ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0);
2935 route_unlock_node(node
);
2938 route_unlock_node(node
);
2945 rip_update_default_metric (void)
2947 struct route_node
*np
;
2948 struct rip_info
*rinfo
= NULL
;
2949 struct list
*list
= NULL
;
2950 struct listnode
*listnode
= NULL
;
2952 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
2953 if ((list
= np
->info
) != NULL
)
2954 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
2955 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
2956 rinfo
->metric
= rip
->default_metric
;
2960 DEFUN (rip_default_metric
,
2961 rip_default_metric_cmd
,
2962 "default-metric (1-16)",
2963 "Set a metric of redistribute routes\n"
2968 rip
->default_metric
= atoi(argv
[idx_number
]->arg
);
2969 /* rip_update_default_metric (); */
2974 DEFUN (no_rip_default_metric
,
2975 no_rip_default_metric_cmd
,
2976 "no default-metric [(1-16)]",
2978 "Set a metric of redistribute routes\n"
2982 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2983 /* rip_update_default_metric (); */
2991 "timers basic (5-2147483647) (5-2147483647) (5-2147483647)",
2992 "Adjust routing timers\n"
2993 "Basic routing protocol update timers\n"
2994 "Routing table update timer value in second. Default is 30.\n"
2995 "Routing information timeout timer. Default is 180.\n"
2996 "Garbage collection timer. Default is 120.\n")
2999 int idx_number_2
= 3;
3000 int idx_number_3
= 4;
3001 unsigned long update
;
3002 unsigned long timeout
;
3003 unsigned long garbage
;
3004 char *endptr
= NULL
;
3005 unsigned long RIP_TIMER_MAX
= 2147483647;
3006 unsigned long RIP_TIMER_MIN
= 5;
3008 update
= strtoul(argv
[idx_number
]->arg
, &endptr
, 10);
3009 if (update
> RIP_TIMER_MAX
|| update
< RIP_TIMER_MIN
3010 || *endptr
!= '\0') {
3011 vty_out(vty
, "update timer value error\n");
3012 return CMD_WARNING_CONFIG_FAILED
;
3015 timeout
= strtoul(argv
[idx_number_2
]->arg
, &endptr
, 10);
3016 if (timeout
> RIP_TIMER_MAX
|| timeout
< RIP_TIMER_MIN
3017 || *endptr
!= '\0') {
3018 vty_out(vty
, "timeout timer value error\n");
3019 return CMD_WARNING_CONFIG_FAILED
;
3022 garbage
= strtoul(argv
[idx_number_3
]->arg
, &endptr
, 10);
3023 if (garbage
> RIP_TIMER_MAX
|| garbage
< RIP_TIMER_MIN
3024 || *endptr
!= '\0') {
3025 vty_out(vty
, "garbage timer value error\n");
3026 return CMD_WARNING_CONFIG_FAILED
;
3029 /* Set each timer value. */
3030 rip
->update_time
= update
;
3031 rip
->timeout_time
= timeout
;
3032 rip
->garbage_time
= garbage
;
3034 /* Reset update timer thread. */
3035 rip_event(RIP_UPDATE_EVENT
, 0);
3040 DEFUN (no_rip_timers
,
3042 "no timers basic [(0-65535) (0-65535) (0-65535)]",
3044 "Adjust routing timers\n"
3045 "Basic routing protocol update timers\n"
3046 "Routing table update timer value in second. Default is 30.\n"
3047 "Routing information timeout timer. Default is 180.\n"
3048 "Garbage collection timer. Default is 120.\n")
3050 /* Set each timer value to the default. */
3051 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
3052 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
3053 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
3055 /* Reset update timer thread. */
3056 rip_event(RIP_UPDATE_EVENT
, 0);
3062 struct route_table
*rip_distance_table
;
3064 struct rip_distance
{
3065 /* Distance value for the IP source prefix. */
3068 /* Name of the access-list to be matched. */
3072 static struct rip_distance
*rip_distance_new(void)
3074 return XCALLOC(MTYPE_RIP_DISTANCE
, sizeof(struct rip_distance
));
3077 static void rip_distance_free(struct rip_distance
*rdistance
)
3079 XFREE(MTYPE_RIP_DISTANCE
, rdistance
);
3082 static int rip_distance_set(struct vty
*vty
, const char *distance_str
,
3083 const char *ip_str
, const char *access_list_str
)
3086 struct prefix_ipv4 p
;
3088 struct route_node
*rn
;
3089 struct rip_distance
*rdistance
;
3091 ret
= str2prefix_ipv4(ip_str
, &p
);
3093 vty_out(vty
, "Malformed prefix\n");
3094 return CMD_WARNING_CONFIG_FAILED
;
3097 distance
= atoi(distance_str
);
3099 /* Get RIP distance node. */
3100 rn
= route_node_get(rip_distance_table
, (struct prefix
*)&p
);
3102 rdistance
= rn
->info
;
3103 route_unlock_node(rn
);
3105 rdistance
= rip_distance_new();
3106 rn
->info
= rdistance
;
3109 /* Set distance value. */
3110 rdistance
->distance
= distance
;
3112 /* Reset access-list configuration. */
3113 if (rdistance
->access_list
) {
3114 free(rdistance
->access_list
);
3115 rdistance
->access_list
= NULL
;
3117 if (access_list_str
)
3118 rdistance
->access_list
= strdup(access_list_str
);
3123 static int rip_distance_unset(struct vty
*vty
, const char *distance_str
,
3124 const char *ip_str
, const char *access_list_str
)
3127 struct prefix_ipv4 p
;
3128 struct route_node
*rn
;
3129 struct rip_distance
*rdistance
;
3131 ret
= str2prefix_ipv4(ip_str
, &p
);
3133 vty_out(vty
, "Malformed prefix\n");
3134 return CMD_WARNING_CONFIG_FAILED
;
3137 rn
= route_node_lookup(rip_distance_table
, (struct prefix
*)&p
);
3139 vty_out(vty
, "Can't find specified prefix\n");
3140 return CMD_WARNING_CONFIG_FAILED
;
3143 rdistance
= rn
->info
;
3145 if (rdistance
->access_list
)
3146 free(rdistance
->access_list
);
3147 rip_distance_free(rdistance
);
3150 route_unlock_node(rn
);
3151 route_unlock_node(rn
);
3156 static void rip_distance_reset(void)
3158 struct route_node
*rn
;
3159 struct rip_distance
*rdistance
;
3161 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
3162 if ((rdistance
= rn
->info
) != NULL
) {
3163 if (rdistance
->access_list
)
3164 free(rdistance
->access_list
);
3165 rip_distance_free(rdistance
);
3167 route_unlock_node(rn
);
3171 /* Apply RIP information to distance method. */
3172 uint8_t rip_distance_apply(struct rip_info
*rinfo
)
3174 struct route_node
*rn
;
3175 struct prefix_ipv4 p
;
3176 struct rip_distance
*rdistance
;
3177 struct access_list
*alist
;
3182 memset(&p
, 0, sizeof(struct prefix_ipv4
));
3184 p
.prefix
= rinfo
->from
;
3185 p
.prefixlen
= IPV4_MAX_BITLEN
;
3187 /* Check source address. */
3188 rn
= route_node_match(rip_distance_table
, (struct prefix
*)&p
);
3190 rdistance
= rn
->info
;
3191 route_unlock_node(rn
);
3193 if (rdistance
->access_list
) {
3194 alist
= access_list_lookup(AFI_IP
,
3195 rdistance
->access_list
);
3198 if (access_list_apply(alist
, &rinfo
->rp
->p
)
3202 return rdistance
->distance
;
3204 return rdistance
->distance
;
3208 return rip
->distance
;
3213 static void rip_distance_show(struct vty
*vty
)
3215 struct route_node
*rn
;
3216 struct rip_distance
*rdistance
;
3220 vty_out(vty
, " Distance: (default is %d)\n",
3221 rip
->distance
? rip
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
);
3223 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
3224 if ((rdistance
= rn
->info
) != NULL
) {
3227 " Address Distance List\n");
3230 sprintf(buf
, "%s/%d", inet_ntoa(rn
->p
.u
.prefix4
),
3232 vty_out(vty
, " %-20s %4d %s\n", buf
,
3233 rdistance
->distance
,
3234 rdistance
->access_list
? rdistance
->access_list
3239 DEFUN (rip_distance
,
3242 "Administrative distance\n"
3246 rip
->distance
= atoi(argv
[idx_number
]->arg
);
3250 DEFUN (no_rip_distance
,
3251 no_rip_distance_cmd
,
3252 "no distance (1-255)",
3254 "Administrative distance\n"
3261 DEFUN (rip_distance_source
,
3262 rip_distance_source_cmd
,
3263 "distance (1-255) A.B.C.D/M",
3264 "Administrative distance\n"
3266 "IP source prefix\n")
3269 int idx_ipv4_prefixlen
= 2;
3270 rip_distance_set(vty
, argv
[idx_number
]->arg
,
3271 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
3275 DEFUN (no_rip_distance_source
,
3276 no_rip_distance_source_cmd
,
3277 "no distance (1-255) A.B.C.D/M",
3279 "Administrative distance\n"
3281 "IP source prefix\n")
3284 int idx_ipv4_prefixlen
= 3;
3285 rip_distance_unset(vty
, argv
[idx_number
]->arg
,
3286 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
3290 DEFUN (rip_distance_source_access_list
,
3291 rip_distance_source_access_list_cmd
,
3292 "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
= 2;
3301 rip_distance_set(vty
, argv
[idx_number
]->arg
,
3302 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
3306 DEFUN (no_rip_distance_source_access_list
,
3307 no_rip_distance_source_access_list_cmd
,
3308 "no distance (1-255) A.B.C.D/M WORD",
3310 "Administrative distance\n"
3312 "IP source prefix\n"
3313 "Access list name\n")
3316 int idx_ipv4_prefixlen
= 3;
3318 rip_distance_unset(vty
, argv
[idx_number
]->arg
,
3319 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
3323 /* Update ECMP routes to zebra when ECMP is disabled. */
3324 static void rip_ecmp_disable(void)
3326 struct route_node
*rp
;
3327 struct rip_info
*rinfo
, *tmp_rinfo
;
3329 struct listnode
*node
, *nextnode
;
3334 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3335 if ((list
= rp
->info
) != NULL
&& listcount(list
) > 1) {
3336 rinfo
= listgetdata(listhead(list
));
3337 if (!rip_route_rte(rinfo
))
3340 /* Drop all other entries, except the first one. */
3341 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
3342 if (tmp_rinfo
!= rinfo
) {
3343 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
3345 tmp_rinfo
->t_garbage_collect
);
3346 list_delete_node(list
, node
);
3347 rip_info_free(tmp_rinfo
);
3351 rip_zebra_ipv4_add(rp
);
3353 /* Set the route change flag. */
3354 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
3356 /* Signal the output process to trigger an update. */
3357 rip_event(RIP_TRIGGERED_UPDATE
, 0);
3361 DEFUN (rip_allow_ecmp
,
3364 "Allow Equal Cost MultiPath\n")
3367 vty_out(vty
, "ECMP is already enabled.\n");
3372 zlog_info("ECMP is enabled.");
3376 DEFUN (no_rip_allow_ecmp
,
3377 no_rip_allow_ecmp_cmd
,
3380 "Allow Equal Cost MultiPath\n")
3383 vty_out(vty
, "ECMP is already disabled.\n");
3388 zlog_info("ECMP is disabled.");
3393 /* Print out routes update time. */
3394 static void rip_vty_out_uptime(struct vty
*vty
, struct rip_info
*rinfo
)
3399 char timebuf
[TIME_BUF
];
3400 struct thread
*thread
;
3402 if ((thread
= rinfo
->t_timeout
) != NULL
) {
3403 clock
= thread_timer_remain_second(thread
);
3404 tm
= gmtime(&clock
);
3405 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
3406 vty_out(vty
, "%5s", timebuf
);
3407 } else if ((thread
= rinfo
->t_garbage_collect
) != NULL
) {
3408 clock
= thread_timer_remain_second(thread
);
3409 tm
= gmtime(&clock
);
3410 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
3411 vty_out(vty
, "%5s", timebuf
);
3415 static const char *rip_route_type_print(int sub_type
)
3420 case RIP_ROUTE_STATIC
:
3422 case RIP_ROUTE_DEFAULT
:
3424 case RIP_ROUTE_REDISTRIBUTE
:
3426 case RIP_ROUTE_INTERFACE
:
3438 "Show RIP routes\n")
3440 struct route_node
*np
;
3441 struct rip_info
*rinfo
= NULL
;
3442 struct list
*list
= NULL
;
3443 struct listnode
*listnode
= NULL
;
3449 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
3451 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
3452 " (i) - interface\n\n"
3453 " Network Next Hop Metric From Tag Time\n");
3455 for (np
= route_top(rip
->table
); np
; np
= route_next(np
))
3456 if ((list
= np
->info
) != NULL
)
3457 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3461 vty
, "%c(%s) %s/%d",
3462 /* np->lock, For debugging. */
3463 zebra_route_char(rinfo
->type
),
3464 rip_route_type_print(rinfo
->sub_type
),
3465 inet_ntoa(np
->p
.u
.prefix4
),
3471 vty_out(vty
, "%*s", len
, " ");
3473 switch (rinfo
->nh
.type
) {
3474 case NEXTHOP_TYPE_IPV4
:
3475 case NEXTHOP_TYPE_IPV4_IFINDEX
:
3476 vty_out(vty
, "%-20s %2d ",
3477 inet_ntoa(rinfo
->nh
.gate
.ipv4
),
3480 case NEXTHOP_TYPE_IFINDEX
:
3485 case NEXTHOP_TYPE_BLACKHOLE
:
3490 case NEXTHOP_TYPE_IPV6
:
3491 case NEXTHOP_TYPE_IPV6_IFINDEX
:
3493 "V6 Address Hidden %2d ",
3498 /* Route which exist in kernel routing table. */
3499 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
)
3500 && (rinfo
->sub_type
== RIP_ROUTE_RTE
)) {
3501 vty_out(vty
, "%-15s ",
3502 inet_ntoa(rinfo
->from
));
3503 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3504 (route_tag_t
)rinfo
->tag
);
3505 rip_vty_out_uptime(vty
, rinfo
);
3506 } else if (rinfo
->metric
3507 == RIP_METRIC_INFINITY
) {
3508 vty_out(vty
, "self ");
3509 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3510 (route_tag_t
)rinfo
->tag
);
3511 rip_vty_out_uptime(vty
, rinfo
);
3513 if (rinfo
->external_metric
) {
3515 vty
, "self (%s:%d)",
3518 rinfo
->external_metric
);
3521 vty_out(vty
, "%*s", len
,
3526 vty_out(vty
, "%3" ROUTE_TAG_PRI
,
3527 (route_tag_t
)rinfo
->tag
);
3535 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3536 DEFUN (show_ip_rip_status
,
3537 show_ip_rip_status_cmd
,
3538 "show ip rip status",
3542 "IP routing protocol process parameters and statistics\n")
3544 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3545 struct interface
*ifp
;
3546 struct rip_interface
*ri
;
3547 extern const struct message ri_version_msg
[];
3548 const char *send_version
;
3549 const char *receive_version
;
3554 vty_out(vty
, "Routing Protocol is \"rip\"\n");
3555 vty_out(vty
, " Sending updates every %ld seconds with +/-50%%,",
3557 vty_out(vty
, " next due in %lu seconds\n",
3558 thread_timer_remain_second(rip
->t_update
));
3559 vty_out(vty
, " Timeout after %ld seconds,", rip
->timeout_time
);
3560 vty_out(vty
, " garbage collect after %ld seconds\n", rip
->garbage_time
);
3562 /* Filtering status show. */
3563 config_show_distribute(vty
);
3565 /* Default metric information. */
3566 vty_out(vty
, " Default redistribution metric is %d\n",
3567 rip
->default_metric
);
3569 /* Redistribute information. */
3570 vty_out(vty
, " Redistributing:");
3571 config_write_rip_redistribute(vty
, 0);
3574 vty_out(vty
, " Default version control: send version %s,",
3575 lookup_msg(ri_version_msg
, rip
->version_send
, NULL
));
3576 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3577 vty_out(vty
, " receive any version \n");
3579 vty_out(vty
, " receive version %s \n",
3580 lookup_msg(ri_version_msg
, rip
->version_recv
, NULL
));
3582 vty_out(vty
, " Interface Send Recv Key-chain\n");
3584 FOR_ALL_INTERFACES (vrf
, ifp
) {
3590 if (ri
->enable_network
|| ri
->enable_interface
) {
3591 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3593 lookup_msg(ri_version_msg
,
3594 rip
->version_send
, NULL
);
3596 send_version
= lookup_msg(ri_version_msg
,
3599 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3601 lookup_msg(ri_version_msg
,
3602 rip
->version_recv
, NULL
);
3604 receive_version
= lookup_msg(
3605 ri_version_msg
, ri
->ri_receive
, NULL
);
3607 vty_out(vty
, " %-17s%-3s %-3s %s\n", ifp
->name
,
3608 send_version
, receive_version
,
3609 ri
->key_chain
? ri
->key_chain
: "");
3613 vty_out(vty
, " Routing for Networks:\n");
3614 config_write_rip_network(vty
, 0);
3617 int found_passive
= 0;
3618 FOR_ALL_INTERFACES (vrf
, ifp
) {
3621 if ((ri
->enable_network
|| ri
->enable_interface
)
3623 if (!found_passive
) {
3625 " Passive Interface(s):\n");
3628 vty_out(vty
, " %s\n", ifp
->name
);
3633 vty_out(vty
, " Routing Information Sources:\n");
3635 " Gateway BadPackets BadRoutes Distance Last Update\n");
3636 rip_peer_display(vty
);
3638 rip_distance_show(vty
);
3643 /* RIP configuration write function. */
3644 static int config_write_rip(struct vty
*vty
)
3647 struct route_node
*rn
;
3648 struct rip_distance
*rdistance
;
3651 /* Router RIP statement. */
3652 vty_out(vty
, "router rip\n");
3655 /* RIP version statement. Default is RIP version 2. */
3656 if (rip
->version_send
!= RI_RIP_VERSION_2
3657 || rip
->version_recv
!= RI_RIP_VERSION_1_AND_2
)
3658 vty_out(vty
, " version %d\n", rip
->version_send
);
3660 /* RIP timer configuration. */
3661 if (rip
->update_time
!= RIP_UPDATE_TIMER_DEFAULT
3662 || rip
->timeout_time
!= RIP_TIMEOUT_TIMER_DEFAULT
3663 || rip
->garbage_time
!= RIP_GARBAGE_TIMER_DEFAULT
)
3664 vty_out(vty
, " timers basic %lu %lu %lu\n",
3665 rip
->update_time
, rip
->timeout_time
,
3668 /* Default information configuration. */
3669 if (rip
->default_information
) {
3670 if (rip
->default_information_route_map
)
3672 " default-information originate route-map %s\n",
3673 rip
->default_information_route_map
);
3676 " default-information originate\n");
3679 /* Redistribute configuration. */
3680 config_write_rip_redistribute(vty
, 1);
3682 /* RIP offset-list configuration. */
3683 config_write_rip_offset_list(vty
);
3685 /* RIP enabled network and interface configuration. */
3686 config_write_rip_network(vty
, 1);
3688 /* RIP default metric configuration */
3689 if (rip
->default_metric
!= RIP_DEFAULT_METRIC_DEFAULT
)
3690 vty_out(vty
, " default-metric %d\n",
3691 rip
->default_metric
);
3693 /* Distribute configuration. */
3694 write
+= config_write_distribute(vty
);
3696 /* Interface routemap configuration */
3697 write
+= config_write_if_rmap(vty
);
3699 /* Distance configuration. */
3701 vty_out(vty
, " distance %d\n", rip
->distance
);
3703 /* RIP source IP prefix distance configuration. */
3704 for (rn
= route_top(rip_distance_table
); rn
;
3705 rn
= route_next(rn
))
3706 if ((rdistance
= rn
->info
) != NULL
)
3707 vty_out(vty
, " distance %d %s/%d %s\n",
3708 rdistance
->distance
,
3709 inet_ntoa(rn
->p
.u
.prefix4
),
3711 rdistance
->access_list
3712 ? rdistance
->access_list
3715 /* ECMP configuration. */
3717 vty_out(vty
, " allow-ecmp\n");
3719 /* RIP static route configuration. */
3720 for (rn
= route_top(rip
->route
); rn
; rn
= route_next(rn
))
3722 vty_out(vty
, " route %s/%d\n",
3723 inet_ntoa(rn
->p
.u
.prefix4
),
3729 /* RIP node structure. */
3730 static struct cmd_node rip_node
= {RIP_NODE
, "%s(config-router)# ", 1};
3732 /* Distribute-list update functions. */
3733 static void rip_distribute_update(struct distribute
*dist
)
3735 struct interface
*ifp
;
3736 struct rip_interface
*ri
;
3737 struct access_list
*alist
;
3738 struct prefix_list
*plist
;
3743 ifp
= if_lookup_by_name(dist
->ifname
, VRF_DEFAULT
);
3749 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
3750 alist
= access_list_lookup(AFI_IP
,
3751 dist
->list
[DISTRIBUTE_V4_IN
]);
3753 ri
->list
[RIP_FILTER_IN
] = alist
;
3755 ri
->list
[RIP_FILTER_IN
] = NULL
;
3757 ri
->list
[RIP_FILTER_IN
] = NULL
;
3759 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
3760 alist
= access_list_lookup(AFI_IP
,
3761 dist
->list
[DISTRIBUTE_V4_OUT
]);
3763 ri
->list
[RIP_FILTER_OUT
] = alist
;
3765 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3767 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3769 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
3770 plist
= prefix_list_lookup(AFI_IP
,
3771 dist
->prefix
[DISTRIBUTE_V4_IN
]);
3773 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3775 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3777 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3779 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
3780 plist
= prefix_list_lookup(AFI_IP
,
3781 dist
->prefix
[DISTRIBUTE_V4_OUT
]);
3783 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3785 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3787 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3790 void rip_distribute_update_interface(struct interface
*ifp
)
3792 struct distribute
*dist
;
3794 dist
= distribute_lookup(ifp
->name
);
3796 rip_distribute_update(dist
);
3799 /* Update all interface's distribute list. */
3801 static void rip_distribute_update_all(struct prefix_list
*notused
)
3803 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3804 struct interface
*ifp
;
3806 FOR_ALL_INTERFACES (vrf
, ifp
)
3807 rip_distribute_update_interface(ifp
);
3810 static void rip_distribute_update_all_wrapper(struct access_list
*notused
)
3812 rip_distribute_update_all(NULL
);
3815 /* Delete all added rip route. */
3816 void rip_clean(void)
3819 struct route_node
*rp
;
3820 struct rip_info
*rinfo
= NULL
;
3821 struct list
*list
= NULL
;
3822 struct listnode
*listnode
= NULL
;
3827 /* Clear RIP routes */
3828 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3829 if ((list
= rp
->info
) != NULL
) {
3830 rinfo
= listgetdata(listhead(list
));
3831 if (rip_route_rte(rinfo
))
3832 rip_zebra_ipv4_delete(rp
);
3834 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
3836 RIP_TIMER_OFF(rinfo
->t_timeout
);
3837 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
3838 rip_info_free(rinfo
);
3840 list_delete_and_null(&list
);
3842 route_unlock_node(rp
);
3845 /* Cancel RIP related timers. */
3846 RIP_TIMER_OFF(rip
->t_update
);
3847 RIP_TIMER_OFF(rip
->t_triggered_update
);
3848 RIP_TIMER_OFF(rip
->t_triggered_interval
);
3850 /* Cancel read thread. */
3851 THREAD_READ_OFF(rip
->t_read
);
3853 /* Close RIP socket. */
3854 if (rip
->sock
>= 0) {
3859 stream_free(rip
->obuf
);
3860 /* Static RIP route configuration. */
3861 for (rp
= route_top(rip
->route
); rp
; rp
= route_next(rp
))
3864 route_unlock_node(rp
);
3867 /* RIP neighbor configuration. */
3868 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
3871 route_unlock_node(rp
);
3874 /* Redistribute related clear. */
3875 if (rip
->default_information_route_map
)
3876 free(rip
->default_information_route_map
);
3878 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3879 if (rip
->route_map
[i
].name
)
3880 free(rip
->route_map
[i
].name
);
3882 XFREE(MTYPE_ROUTE_TABLE
, rip
->table
);
3883 XFREE(MTYPE_ROUTE_TABLE
, rip
->route
);
3884 XFREE(MTYPE_ROUTE_TABLE
, rip
->neighbor
);
3886 XFREE(MTYPE_RIP
, rip
);
3890 rip_clean_network();
3891 rip_passive_nondefault_clean();
3893 rip_interfaces_clean();
3894 rip_distance_reset();
3895 rip_redistribute_clean();
3898 /* Reset all values to the default settings. */
3899 void rip_reset(void)
3901 /* Reset global counters. */
3902 rip_global_route_changes
= 0;
3903 rip_global_queries
= 0;
3905 /* Call ripd related reset functions. */
3907 rip_route_map_reset();
3909 /* Call library reset functions. */
3911 access_list_reset();
3912 prefix_list_reset();
3914 distribute_list_reset();
3916 rip_interfaces_reset();
3917 rip_distance_reset();
3919 rip_zclient_reset();
3922 static void rip_if_rmap_update(struct if_rmap
*if_rmap
)
3924 struct interface
*ifp
;
3925 struct rip_interface
*ri
;
3926 struct route_map
*rmap
;
3928 ifp
= if_lookup_by_name(if_rmap
->ifname
, VRF_DEFAULT
);
3934 if (if_rmap
->routemap
[IF_RMAP_IN
]) {
3935 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_IN
]);
3937 ri
->routemap
[IF_RMAP_IN
] = rmap
;
3939 ri
->routemap
[IF_RMAP_IN
] = NULL
;
3941 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
3943 if (if_rmap
->routemap
[IF_RMAP_OUT
]) {
3944 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_OUT
]);
3946 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
3948 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
3950 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
3953 void rip_if_rmap_update_interface(struct interface
*ifp
)
3955 struct if_rmap
*if_rmap
;
3957 if_rmap
= if_rmap_lookup(ifp
->name
);
3959 rip_if_rmap_update(if_rmap
);
3962 static void rip_routemap_update_redistribute(void)
3967 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3968 if (rip
->route_map
[i
].name
)
3969 rip
->route_map
[i
].map
=
3970 route_map_lookup_by_name(
3971 rip
->route_map
[i
].name
);
3977 static void rip_routemap_update(const char *notused
)
3979 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3980 struct interface
*ifp
;
3982 FOR_ALL_INTERFACES (vrf
, ifp
)
3983 rip_if_rmap_update_interface(ifp
);
3985 rip_routemap_update_redistribute();
3988 /* Allocate new rip structure and set default value. */
3991 /* Install top nodes. */
3992 install_node(&rip_node
, config_write_rip
);
3994 /* Install rip commands. */
3995 install_element(VIEW_NODE
, &show_ip_rip_cmd
);
3996 install_element(VIEW_NODE
, &show_ip_rip_status_cmd
);
3997 install_element(CONFIG_NODE
, &router_rip_cmd
);
3998 install_element(CONFIG_NODE
, &no_router_rip_cmd
);
4000 install_default(RIP_NODE
);
4001 install_element(RIP_NODE
, &rip_version_cmd
);
4002 install_element(RIP_NODE
, &no_rip_version_cmd
);
4003 install_element(RIP_NODE
, &rip_default_metric_cmd
);
4004 install_element(RIP_NODE
, &no_rip_default_metric_cmd
);
4005 install_element(RIP_NODE
, &rip_timers_cmd
);
4006 install_element(RIP_NODE
, &no_rip_timers_cmd
);
4007 install_element(RIP_NODE
, &rip_route_cmd
);
4008 install_element(RIP_NODE
, &no_rip_route_cmd
);
4009 install_element(RIP_NODE
, &rip_distance_cmd
);
4010 install_element(RIP_NODE
, &no_rip_distance_cmd
);
4011 install_element(RIP_NODE
, &rip_distance_source_cmd
);
4012 install_element(RIP_NODE
, &no_rip_distance_source_cmd
);
4013 install_element(RIP_NODE
, &rip_distance_source_access_list_cmd
);
4014 install_element(RIP_NODE
, &no_rip_distance_source_access_list_cmd
);
4015 install_element(RIP_NODE
, &rip_allow_ecmp_cmd
);
4016 install_element(RIP_NODE
, &no_rip_allow_ecmp_cmd
);
4018 /* Debug related init. */
4021 /* Access list install. */
4023 access_list_add_hook(rip_distribute_update_all_wrapper
);
4024 access_list_delete_hook(rip_distribute_update_all_wrapper
);
4026 /* Prefix list initialize.*/
4028 prefix_list_add_hook(rip_distribute_update_all
);
4029 prefix_list_delete_hook(rip_distribute_update_all
);
4031 /* Distribute list install. */
4032 distribute_list_init(RIP_NODE
);
4033 distribute_list_add_hook(rip_distribute_update
);
4034 distribute_list_delete_hook(rip_distribute_update
);
4037 rip_route_map_init();
4040 route_map_add_hook(rip_routemap_update
);
4041 route_map_delete_hook(rip_routemap_update
);
4043 if_rmap_init(RIP_NODE
);
4044 if_rmap_hook_add(rip_if_rmap_update
);
4045 if_rmap_hook_delete(rip_if_rmap_update
);
4047 /* Distance control. */
4048 rip_distance_table
= route_table_init();