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
]) {
439 /* The object should be of the type of rip_info */
440 ret
= route_map_apply(ri
->routemap
[RIP_FILTER_IN
],
441 (struct prefix
*)&p
, RMAP_RIP
, &newinfo
);
443 if (ret
== RMAP_DENYMATCH
) {
444 if (IS_RIP_DEBUG_PACKET
)
446 "RIP %s/%d is filtered by route-map in",
447 inet_ntoa(p
.prefix
), p
.prefixlen
);
451 /* Get back the object */
452 rte
->nexthop
= newinfo
.nexthop_out
;
453 rte
->tag
= htons(newinfo
.tag_out
); /* XXX */
454 rte
->metric
= newinfo
.metric_out
; /* XXX: the routemap uses the
458 /* Once the entry has been validated, update the metric by
459 adding the cost of the network on wich the message
460 arrived. If the result is greater than infinity, use infinity
461 (RFC2453 Sec. 3.9.2) */
462 /* Zebra ripd can handle offset-list in. */
463 ret
= rip_offset_list_apply_in(&p
, ifp
, &rte
->metric
);
465 /* If offset-list does not modify the metric use interface's
468 rte
->metric
+= ifp
->metric
? ifp
->metric
: 1;
470 if (rte
->metric
> RIP_METRIC_INFINITY
)
471 rte
->metric
= RIP_METRIC_INFINITY
;
473 /* Set nexthop pointer. */
474 if (rte
->nexthop
.s_addr
== 0)
475 nexthop
= &from
->sin_addr
;
477 nexthop
= &rte
->nexthop
;
479 /* Check if nexthop address is myself, then do nothing. */
480 if (rip_nexthop_check(nexthop
) < 0) {
481 if (IS_RIP_DEBUG_PACKET
)
482 zlog_debug("Nexthop address %s is myself",
483 inet_ntoa(*nexthop
));
487 /* Get index for the prefix. */
488 rp
= route_node_get(rip
->table
, (struct prefix
*)&p
);
491 newinfo
.nh
.gate
.ipv4
= *nexthop
;
492 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4
;
493 newinfo
.metric
= rte
->metric
;
494 newinfo
.tag
= ntohs(rte
->tag
);
495 newinfo
.distance
= rip_distance_apply(&newinfo
);
497 new_dist
= newinfo
.distance
? newinfo
.distance
498 : ZEBRA_RIP_DISTANCE_DEFAULT
;
500 /* Check to see whether there is already RIP route on the table. */
501 if ((list
= rp
->info
) != NULL
)
502 for (ALL_LIST_ELEMENTS_RO(list
, node
, rinfo
)) {
503 /* Need to compare with redistributed entry or local
505 if (!rip_route_rte(rinfo
))
508 if (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
509 && IPV4_ADDR_SAME(&rinfo
->nh
.gate
.ipv4
, nexthop
))
512 if (!listnextnode(node
)) {
513 /* Not found in the list */
515 if (rte
->metric
> rinfo
->metric
) {
516 /* New route has a greater metric.
518 route_unlock_node(rp
);
522 if (rte
->metric
< rinfo
->metric
)
523 /* New route has a smaller metric.
524 * Replace the ECMP list
525 * with the new one in below. */
528 /* Metrics are same. We compare the distances.
530 old_dist
= rinfo
->distance
532 : ZEBRA_RIP_DISTANCE_DEFAULT
;
534 if (new_dist
> old_dist
) {
535 /* New route has a greater distance.
537 route_unlock_node(rp
);
541 if (new_dist
< old_dist
)
542 /* New route has a smaller distance.
543 * Replace the ECMP list
544 * with the new one in below. */
547 /* Metrics and distances are both same. Keep
549 * the new route is added in the ECMP list in
555 /* Local static route. */
556 if (rinfo
->type
== ZEBRA_ROUTE_RIP
557 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
558 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))
559 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
560 route_unlock_node(rp
);
564 /* Redistributed route check. */
565 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
566 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
567 old_dist
= rinfo
->distance
;
568 /* Only routes directly connected to an interface
570 * may have a valid NULL distance */
571 if (rinfo
->nh
.gate
.ipv4
.s_addr
!= 0)
574 : ZEBRA_RIP_DISTANCE_DEFAULT
;
575 /* If imported route does not have STRICT precedence,
576 mark it as a ghost */
577 if (new_dist
<= old_dist
578 && rte
->metric
!= RIP_METRIC_INFINITY
)
579 rip_ecmp_replace(&newinfo
);
581 route_unlock_node(rp
);
588 route_unlock_node(rp
);
590 /* Now, check to see whether there is already an explicit route
591 for the destination prefix. If there is no such route, add
592 this route to the routing table, unless the metric is
593 infinity (there is no point in adding a route which
595 if (rte
->metric
!= RIP_METRIC_INFINITY
)
596 rip_ecmp_add(&newinfo
);
598 /* Route is there but we are not sure the route is RIP or not.
601 /* If there is an existing route, compare the next hop address
602 to the address of the router from which the datagram came.
603 If this datagram is from the same router as the existing
604 route, reinitialize the timeout. */
605 same
= (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
606 && (rinfo
->nh
.ifindex
== ifp
->ifindex
));
608 old_dist
= rinfo
->distance
? rinfo
->distance
609 : ZEBRA_RIP_DISTANCE_DEFAULT
;
611 /* Next, compare the metrics. If the datagram is from the same
612 router as the existing route, and the new metric is different
613 than the old one; or, if the new metric is lower than the old
614 one, or if the tag has been changed; or if there is a route
615 with a lower administrave distance; or an update of the
616 distance on the actual route; do the following actions: */
617 if ((same
&& rinfo
->metric
!= rte
->metric
)
618 || (rte
->metric
< rinfo
->metric
)
619 || ((same
) && (rinfo
->metric
== rte
->metric
)
620 && (newinfo
.tag
!= rinfo
->tag
))
621 || (old_dist
> new_dist
)
622 || ((old_dist
!= new_dist
) && same
)) {
623 if (listcount(list
) == 1) {
624 if (newinfo
.metric
!= RIP_METRIC_INFINITY
)
625 rip_ecmp_replace(&newinfo
);
627 rip_ecmp_delete(rinfo
);
629 if (newinfo
.metric
< rinfo
->metric
)
630 rip_ecmp_replace(&newinfo
);
631 else if (newinfo
.metric
> rinfo
->metric
)
632 rip_ecmp_delete(rinfo
);
633 else if (new_dist
< old_dist
)
634 rip_ecmp_replace(&newinfo
);
635 else if (new_dist
> old_dist
)
636 rip_ecmp_delete(rinfo
);
638 int update
= CHECK_FLAG(rinfo
->flags
,
643 assert(newinfo
.metric
644 != RIP_METRIC_INFINITY
);
646 RIP_TIMER_OFF(rinfo
->t_timeout
);
647 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
648 memcpy(rinfo
, &newinfo
,
649 sizeof(struct rip_info
));
650 rip_timeout_update(rinfo
);
653 rip_zebra_ipv4_add(rp
);
655 /* - Set the route change flag on the
657 rinfo
= listgetdata(listhead(list
));
658 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
659 rip_event(RIP_TRIGGERED_UPDATE
, 0);
662 } else /* same & no change */
663 rip_timeout_update(rinfo
);
665 /* Unlock tempolary lock of the route. */
666 route_unlock_node(rp
);
670 /* Dump RIP packet */
671 static void rip_packet_dump(struct rip_packet
*packet
, int size
,
676 const char *command_str
;
677 char pbuf
[BUFSIZ
], nbuf
[BUFSIZ
];
681 /* Set command string. */
682 if (packet
->command
> 0 && packet
->command
< RIP_COMMAND_MAX
)
683 command_str
= lookup_msg(rip_msg
, packet
->command
, NULL
);
685 command_str
= "unknown";
687 /* Dump packet header. */
688 zlog_debug("%s %s version %d packet size %d", sndrcv
, command_str
,
689 packet
->version
, size
);
691 /* Dump each routing table entry. */
694 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
695 if (packet
->version
== RIPv2
) {
696 netmask
= ip_masklen(rte
->mask
);
698 if (rte
->family
== htons(RIP_FAMILY_AUTH
)) {
700 == htons(RIP_AUTH_SIMPLE_PASSWORD
)) {
701 p
= (uint8_t *)&rte
->prefix
;
704 " family 0x%X type %d auth string: %s",
707 } else if (rte
->tag
== htons(RIP_AUTH_MD5
)) {
708 struct rip_md5_info
*md5
;
710 md5
= (struct rip_md5_info
*)&packet
714 " family 0x%X type %d (MD5 authentication)",
718 " RIP-2 packet len %d Key ID %d"
720 ntohs(md5
->packet_len
),
721 md5
->keyid
, md5
->auth_len
);
722 zlog_debug(" Sequence Number %ld",
723 (unsigned long)ntohl(
725 } else if (rte
->tag
== htons(RIP_AUTH_DATA
)) {
726 p
= (uint8_t *)&rte
->prefix
;
729 " family 0x%X type %d (MD5 data)",
733 " MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
734 "%02X%02X%02X%02X%02X%02X%02X%02X",
735 p
[0], p
[1], p
[2], p
[3], p
[4],
736 p
[5], p
[6], p
[7], p
[8], p
[9],
737 p
[10], p
[11], p
[12], p
[13],
741 " family 0x%X type %d (Unknown auth type)",
747 " %s/%d -> %s family %d tag %" ROUTE_TAG_PRI
749 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
,
752 inet_ntop(AF_INET
, &rte
->nexthop
, nbuf
,
755 (route_tag_t
)ntohs(rte
->tag
),
756 (unsigned long)ntohl(rte
->metric
));
759 " %s family %d tag %" ROUTE_TAG_PRI
761 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
763 (route_tag_t
)ntohs(rte
->tag
),
764 (unsigned long)ntohl(rte
->metric
));
769 /* Check if the destination address is valid (unicast; not net 0
770 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
771 check net 0 because we accept default route. */
772 static int rip_destination_check(struct in_addr addr
)
774 uint32_t destination
;
776 /* Convert to host byte order. */
777 destination
= ntohl(addr
.s_addr
);
779 if (IPV4_NET127(destination
))
782 /* Net 0 may match to the default route. */
783 if (IPV4_NET0(destination
) && destination
!= 0)
786 /* Unicast address must belong to class A, B, C. */
787 if (IN_CLASSA(destination
))
789 if (IN_CLASSB(destination
))
791 if (IN_CLASSC(destination
))
797 /* RIP version 2 authentication. */
798 static int rip_auth_simple_password(struct rte
*rte
, struct sockaddr_in
*from
,
799 struct interface
*ifp
)
801 struct rip_interface
*ri
;
802 char *auth_str
= (char *)rte
+ offsetof(struct rte
, prefix
);
805 /* reject passwords with zeros in the middle of the string */
806 for (i
= strnlen(auth_str
, 16); i
< 16; i
++) {
807 if (auth_str
[i
] != '\0')
811 if (IS_RIP_DEBUG_EVENT
)
812 zlog_debug("RIPv2 simple password authentication from %s",
813 inet_ntoa(from
->sin_addr
));
817 if (ri
->auth_type
!= RIP_AUTH_SIMPLE_PASSWORD
818 || rte
->tag
!= htons(RIP_AUTH_SIMPLE_PASSWORD
))
821 /* Simple password authentication. */
823 if (strncmp(auth_str
, ri
->auth_str
, 16) == 0)
827 struct keychain
*keychain
;
830 keychain
= keychain_lookup(ri
->key_chain
);
831 if (keychain
== NULL
|| keychain
->key
== NULL
)
834 key
= key_match_for_accept(keychain
, auth_str
);
841 /* RIP version 2 authentication with MD5. */
842 static int rip_auth_md5(struct rip_packet
*packet
, struct sockaddr_in
*from
,
843 int length
, struct interface
*ifp
)
845 struct rip_interface
*ri
;
846 struct rip_md5_info
*md5
;
847 struct rip_md5_data
*md5data
;
848 struct keychain
*keychain
;
851 uint8_t digest
[RIP_AUTH_MD5_SIZE
];
853 char auth_str
[RIP_AUTH_MD5_SIZE
];
855 if (IS_RIP_DEBUG_EVENT
)
856 zlog_debug("RIPv2 MD5 authentication from %s",
857 inet_ntoa(from
->sin_addr
));
860 md5
= (struct rip_md5_info
*)&packet
->rte
;
862 /* Check auth type. */
863 if (ri
->auth_type
!= RIP_AUTH_MD5
|| md5
->type
!= htons(RIP_AUTH_MD5
))
866 /* If the authentication length is less than 16, then it must be wrong
868 * any interpretation of rfc2082. Some implementations also interpret
869 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka
870 * RIP_AUTH_MD5_COMPAT_SIZE.
872 if (!((md5
->auth_len
== RIP_AUTH_MD5_SIZE
)
873 || (md5
->auth_len
== RIP_AUTH_MD5_COMPAT_SIZE
))) {
874 if (IS_RIP_DEBUG_EVENT
)
876 "RIPv2 MD5 authentication, strange authentication "
882 /* grab and verify check packet length */
883 packet_len
= ntohs(md5
->packet_len
);
885 if (packet_len
> (length
- RIP_HEADER_SIZE
- RIP_AUTH_MD5_SIZE
)) {
886 if (IS_RIP_DEBUG_EVENT
)
888 "RIPv2 MD5 authentication, packet length field %d "
889 "greater than received length %d!",
890 md5
->packet_len
, length
);
894 /* retrieve authentication data */
895 md5data
= (struct rip_md5_data
*)(((uint8_t *)packet
) + packet_len
);
897 memset(auth_str
, 0, RIP_AUTH_MD5_SIZE
);
900 keychain
= keychain_lookup(ri
->key_chain
);
901 if (keychain
== NULL
)
904 key
= key_lookup_for_accept(keychain
, md5
->keyid
);
905 if (key
== NULL
|| key
->string
== NULL
)
908 strncpy(auth_str
, key
->string
, RIP_AUTH_MD5_SIZE
);
909 } else if (ri
->auth_str
)
910 strncpy(auth_str
, ri
->auth_str
, RIP_AUTH_MD5_SIZE
);
912 if (auth_str
[0] == 0)
915 /* MD5 digest authentication. */
916 memset(&ctx
, 0, sizeof(ctx
));
918 MD5Update(&ctx
, packet
, packet_len
+ RIP_HEADER_SIZE
);
919 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
920 MD5Final(digest
, &ctx
);
922 if (memcmp(md5data
->digest
, digest
, RIP_AUTH_MD5_SIZE
) == 0)
928 /* Pick correct auth string for sends, prepare auth_str buffer for use.
929 * (left justified and padded).
931 * presumes one of ri or key is valid, and that the auth strings they point
932 * to are nul terminated. If neither are present, auth_str will be fully
936 static void rip_auth_prepare_str_send(struct rip_interface
*ri
, struct key
*key
,
937 char *auth_str
, int len
)
941 memset(auth_str
, 0, len
);
942 if (key
&& key
->string
)
943 strncpy(auth_str
, key
->string
, len
);
944 else if (ri
->auth_str
)
945 strncpy(auth_str
, ri
->auth_str
, len
);
950 /* Write RIPv2 simple password authentication information
952 * auth_str is presumed to be 2 bytes and correctly prepared
953 * (left justified and zero padded).
955 static void rip_auth_simple_write(struct stream
*s
, char *auth_str
, int len
)
957 assert(s
&& len
== RIP_AUTH_SIMPLE_SIZE
);
959 stream_putw(s
, RIP_FAMILY_AUTH
);
960 stream_putw(s
, RIP_AUTH_SIMPLE_PASSWORD
);
961 stream_put(s
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
966 /* write RIPv2 MD5 "authentication header"
967 * (uses the auth key data field)
969 * Digest offset field is set to 0.
971 * returns: offset of the digest offset field, which must be set when
972 * length to the auth-data MD5 digest is known.
974 static size_t rip_auth_md5_ah_write(struct stream
*s
, struct rip_interface
*ri
,
979 assert(s
&& ri
&& ri
->auth_type
== RIP_AUTH_MD5
);
981 /* MD5 authentication. */
982 stream_putw(s
, RIP_FAMILY_AUTH
);
983 stream_putw(s
, RIP_AUTH_MD5
);
985 /* MD5 AH digest offset field.
987 * Set to placeholder value here, to true value when RIP-2 Packet length
988 * is known. Actual value is set in .....().
990 doff
= stream_get_endp(s
);
995 stream_putc(s
, key
->index
% 256);
999 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
1000 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for
1002 * to be configurable.
1004 stream_putc(s
, ri
->md5_auth_len
);
1006 /* Sequence Number (non-decreasing). */
1007 /* RFC2080: The value used in the sequence number is
1008 arbitrary, but two suggestions are the time of the
1009 message's creation or a simple message counter. */
1010 stream_putl(s
, time(NULL
));
1012 /* Reserved field must be zero. */
1019 /* If authentication is in used, write the appropriate header
1020 * returns stream offset to which length must later be written
1021 * or 0 if this is not required
1023 static size_t rip_auth_header_write(struct stream
*s
, struct rip_interface
*ri
,
1024 struct key
*key
, char *auth_str
, int len
)
1026 assert(ri
->auth_type
!= RIP_NO_AUTH
);
1028 switch (ri
->auth_type
) {
1029 case RIP_AUTH_SIMPLE_PASSWORD
:
1030 rip_auth_prepare_str_send(ri
, key
, auth_str
, len
);
1031 rip_auth_simple_write(s
, auth_str
, len
);
1034 return rip_auth_md5_ah_write(s
, ri
, key
);
1040 /* Write RIPv2 MD5 authentication data trailer */
1041 static void rip_auth_md5_set(struct stream
*s
, struct rip_interface
*ri
,
1042 size_t doff
, char *auth_str
, int authlen
)
1046 unsigned char digest
[RIP_AUTH_MD5_SIZE
];
1048 /* Make it sure this interface is configured as MD5
1050 assert((ri
->auth_type
== RIP_AUTH_MD5
)
1051 && (authlen
== RIP_AUTH_MD5_SIZE
));
1054 /* Get packet length. */
1055 len
= stream_get_endp(s
);
1057 /* Check packet length. */
1058 if (len
< (RIP_HEADER_SIZE
+ RIP_RTE_SIZE
)) {
1059 flog_err(RIP_ERR_PACKET
,
1060 "rip_auth_md5_set(): packet length %ld is less than minimum length.",
1065 /* Set the digest offset length in the header */
1066 stream_putw_at(s
, doff
, len
);
1068 /* Set authentication data. */
1069 stream_putw(s
, RIP_FAMILY_AUTH
);
1070 stream_putw(s
, RIP_AUTH_DATA
);
1072 /* Generate a digest for the RIP packet. */
1073 memset(&ctx
, 0, sizeof(ctx
));
1075 MD5Update(&ctx
, STREAM_DATA(s
), stream_get_endp(s
));
1076 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1077 MD5Final(digest
, &ctx
);
1079 /* Copy the digest to the packet. */
1080 stream_write(s
, digest
, RIP_AUTH_MD5_SIZE
);
1083 /* RIP routing information. */
1084 static void rip_response_process(struct rip_packet
*packet
, int size
,
1085 struct sockaddr_in
*from
,
1086 struct connected
*ifc
)
1090 struct prefix_ipv4 ifaddr
;
1091 struct prefix_ipv4 ifaddrclass
;
1094 memset(&ifaddr
, 0, sizeof(ifaddr
));
1095 /* We don't know yet. */
1098 /* The Response must be ignored if it is not from the RIP
1099 port. (RFC2453 - Sec. 3.9.2)*/
1100 if (from
->sin_port
!= htons(RIP_PORT_DEFAULT
)) {
1101 zlog_info("response doesn't come from RIP port: %d",
1103 rip_peer_bad_packet(from
);
1107 /* The datagram's IPv4 source address should be checked to see
1108 whether the datagram is from a valid neighbor; the source of the
1109 datagram must be on a directly connected network (RFC2453 - Sec.
1111 if (if_lookup_address((void *)&from
->sin_addr
, AF_INET
, VRF_DEFAULT
)
1114 "This datagram doesn't came from a valid neighbor: %s",
1115 inet_ntoa(from
->sin_addr
));
1116 rip_peer_bad_packet(from
);
1120 /* It is also worth checking to see whether the response is from one
1121 of the router's own addresses. */
1123 ; /* Alredy done in rip_read () */
1125 /* Update RIP peer. */
1126 rip_peer_update(from
, packet
->version
);
1128 /* Set RTE pointer. */
1131 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
1132 /* RIPv2 authentication check. */
1133 /* If the Address Family Identifier of the first (and only the
1134 first) entry in the message is 0xFFFF, then the remainder of
1135 the entry contains the authentication. */
1136 /* If the packet gets here it means authentication enabled */
1137 /* Check is done in rip_read(). So, just skipping it */
1138 if (packet
->version
== RIPv2
&& rte
== packet
->rte
1139 && rte
->family
== htons(RIP_FAMILY_AUTH
))
1142 if (rte
->family
!= htons(AF_INET
)) {
1143 /* Address family check. RIP only supports AF_INET. */
1144 zlog_info("Unsupported family %d from %s.",
1146 inet_ntoa(from
->sin_addr
));
1150 /* - is the destination address valid (e.g., unicast; not net 0
1152 if (!rip_destination_check(rte
->prefix
)) {
1154 "Network is net 0 or net 127 or it is not unicast network");
1155 rip_peer_bad_route(from
);
1159 /* Convert metric value to host byte order. */
1160 rte
->metric
= ntohl(rte
->metric
);
1162 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1163 if (!(rte
->metric
>= 1 && rte
->metric
<= 16)) {
1164 zlog_info("Route's metric is not in the 1-16 range.");
1165 rip_peer_bad_route(from
);
1169 /* RIPv1 does not have nexthop value. */
1170 if (packet
->version
== RIPv1
&& rte
->nexthop
.s_addr
!= 0) {
1171 zlog_info("RIPv1 packet with nexthop value %s",
1172 inet_ntoa(rte
->nexthop
));
1173 rip_peer_bad_route(from
);
1177 /* That is, if the provided information is ignored, a possibly
1178 sub-optimal, but absolutely valid, route may be taken. If
1179 the received Next Hop is not directly reachable, it should be
1180 treated as 0.0.0.0. */
1181 if (packet
->version
== RIPv2
&& rte
->nexthop
.s_addr
!= 0) {
1184 /* Multicast address check. */
1185 addrval
= ntohl(rte
->nexthop
.s_addr
);
1186 if (IN_CLASSD(addrval
)) {
1188 "Nexthop %s is multicast address, skip this rte",
1189 inet_ntoa(rte
->nexthop
));
1193 if (!if_lookup_address((void *)&rte
->nexthop
, AF_INET
,
1195 struct route_node
*rn
;
1196 struct rip_info
*rinfo
;
1198 rn
= route_node_match_ipv4(rip
->table
,
1204 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1207 if (IS_RIP_DEBUG_EVENT
)
1209 "Next hop %s is on RIP network. Set nexthop to the packet's originator",
1212 rte
->nexthop
= rinfo
->from
;
1214 if (IS_RIP_DEBUG_EVENT
)
1216 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1219 rte
->nexthop
.s_addr
= 0;
1222 route_unlock_node(rn
);
1224 if (IS_RIP_DEBUG_EVENT
)
1226 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1229 rte
->nexthop
.s_addr
= 0;
1234 /* For RIPv1, there won't be a valid netmask.
1236 This is a best guess at the masks. If everyone was using old
1237 Ciscos before the 'ip subnet zero' option, it would be almost
1240 Cisco summarize ripv1 advertisments to the classful boundary
1241 (/16 for class B's) except when the RIP packet does to inside
1242 the classful network in question. */
1244 if ((packet
->version
== RIPv1
&& rte
->prefix
.s_addr
!= 0)
1245 || (packet
->version
== RIPv2
1246 && (rte
->prefix
.s_addr
!= 0
1247 && rte
->mask
.s_addr
== 0))) {
1248 uint32_t destination
;
1250 if (subnetted
== -1) {
1251 memcpy(&ifaddr
, ifc
->address
,
1252 sizeof(struct prefix_ipv4
));
1253 memcpy(&ifaddrclass
, &ifaddr
,
1254 sizeof(struct prefix_ipv4
));
1255 apply_classful_mask_ipv4(&ifaddrclass
);
1257 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1261 destination
= ntohl(rte
->prefix
.s_addr
);
1263 if (IN_CLASSA(destination
))
1264 masklen2ip(8, &rte
->mask
);
1265 else if (IN_CLASSB(destination
))
1266 masklen2ip(16, &rte
->mask
);
1267 else if (IN_CLASSC(destination
))
1268 masklen2ip(24, &rte
->mask
);
1271 masklen2ip(ifaddrclass
.prefixlen
,
1272 (struct in_addr
*)&destination
);
1273 if ((subnetted
== 1)
1274 && ((rte
->prefix
.s_addr
& destination
)
1275 == ifaddrclass
.prefix
.s_addr
)) {
1276 masklen2ip(ifaddr
.prefixlen
, &rte
->mask
);
1277 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1278 != rte
->prefix
.s_addr
)
1279 masklen2ip(32, &rte
->mask
);
1280 if (IS_RIP_DEBUG_EVENT
)
1281 zlog_debug("Subnetted route %s",
1282 inet_ntoa(rte
->prefix
));
1284 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1285 != rte
->prefix
.s_addr
)
1289 if (IS_RIP_DEBUG_EVENT
) {
1290 zlog_debug("Resultant route %s",
1291 inet_ntoa(rte
->prefix
));
1292 zlog_debug("Resultant mask %s",
1293 inet_ntoa(rte
->mask
));
1297 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1298 ignore the entry. */
1299 if ((packet
->version
== RIPv2
) && (rte
->mask
.s_addr
!= 0)
1300 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1301 != rte
->prefix
.s_addr
)) {
1303 "RIPv2 address %s is not mask /%d applied one",
1304 inet_ntoa(rte
->prefix
), ip_masklen(rte
->mask
));
1305 rip_peer_bad_route(from
);
1309 /* Default route's netmask is ignored. */
1310 if (packet
->version
== RIPv2
&& (rte
->prefix
.s_addr
== 0)
1311 && (rte
->mask
.s_addr
!= 0)) {
1312 if (IS_RIP_DEBUG_EVENT
)
1314 "Default route with non-zero netmask. Set zero to netmask");
1315 rte
->mask
.s_addr
= 0;
1318 /* Routing table updates. */
1319 rip_rte_process(rte
, from
, ifc
->ifp
);
1323 /* Make socket for RIP protocol. */
1324 static int rip_create_socket(void)
1328 struct sockaddr_in addr
;
1330 memset(&addr
, 0, sizeof(struct sockaddr_in
));
1331 addr
.sin_family
= AF_INET
;
1332 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1333 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1334 addr
.sin_len
= sizeof(struct sockaddr_in
);
1335 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1336 /* sending port must always be the RIP port */
1337 addr
.sin_port
= htons(RIP_PORT_DEFAULT
);
1339 /* Make datagram socket. */
1340 sock
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
1342 flog_err_sys(LIB_ERR_SOCKET
, "Cannot create UDP socket: %s",
1343 safe_strerror(errno
));
1347 sockopt_broadcast(sock
);
1348 sockopt_reuseaddr(sock
);
1349 sockopt_reuseport(sock
);
1350 setsockopt_ipv4_multicast_loop(sock
, 0);
1352 setsockopt_pktinfo(sock
);
1353 #endif /* RIP_RECVMSG */
1354 #ifdef IPTOS_PREC_INTERNETCONTROL
1355 setsockopt_ipv4_tos(sock
, IPTOS_PREC_INTERNETCONTROL
);
1358 frr_elevate_privs(&ripd_privs
) {
1359 setsockopt_so_recvbuf(sock
, RIP_UDP_RCV_BUF
);
1360 if ((ret
= bind(sock
, (struct sockaddr
*)&addr
, sizeof(addr
)))
1362 zlog_err("%s: Can't bind socket %d to %s port %d: %s",
1363 __func__
, sock
, inet_ntoa(addr
.sin_addr
),
1364 (int)ntohs(addr
.sin_port
),
1365 safe_strerror(errno
));
1375 /* RIP packet send to destination address, on interface denoted by
1376 * by connected argument. NULL to argument denotes destination should be
1377 * should be RIP multicast group
1379 static int rip_send_packet(uint8_t *buf
, int size
, struct sockaddr_in
*to
,
1380 struct connected
*ifc
)
1383 struct sockaddr_in sin
;
1385 assert(ifc
!= NULL
);
1387 if (IS_RIP_DEBUG_PACKET
) {
1388 #define ADDRESS_SIZE 20
1389 char dst
[ADDRESS_SIZE
];
1390 dst
[ADDRESS_SIZE
- 1] = '\0';
1393 strncpy(dst
, inet_ntoa(to
->sin_addr
), ADDRESS_SIZE
- 1);
1395 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1396 strncpy(dst
, inet_ntoa(sin
.sin_addr
), ADDRESS_SIZE
- 1);
1399 zlog_debug("rip_send_packet %s > %s (%s)",
1400 inet_ntoa(ifc
->address
->u
.prefix4
), dst
,
1404 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
1406 * ZEBRA_IFA_SECONDARY is set on linux when an interface is
1408 * with multiple addresses on the same subnet: the first address
1409 * on the subnet is configured "primary", and all subsequent
1411 * on that subnet are treated as "secondary" addresses.
1412 * In order to avoid routing-table bloat on other rip listeners,
1413 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY
1415 * XXX Since Linux is the only system for which the
1416 * ZEBRA_IFA_SECONDARY
1417 * flag is set, we would end up sending a packet for a
1419 * source address on non-linux systems.
1421 if (IS_RIP_DEBUG_PACKET
)
1422 zlog_debug("duplicate dropped");
1426 /* Make destination address. */
1427 memset(&sin
, 0, sizeof(struct sockaddr_in
));
1428 sin
.sin_family
= AF_INET
;
1429 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1430 sin
.sin_len
= sizeof(struct sockaddr_in
);
1431 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1433 /* When destination is specified, use it's port and address. */
1435 sin
.sin_port
= to
->sin_port
;
1436 sin
.sin_addr
= to
->sin_addr
;
1438 sin
.sin_port
= htons(RIP_PORT_DEFAULT
);
1439 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1441 rip_interface_multicast_set(rip
->sock
, ifc
);
1444 ret
= sendto(rip
->sock
, buf
, size
, 0, (struct sockaddr
*)&sin
,
1445 sizeof(struct sockaddr_in
));
1447 if (IS_RIP_DEBUG_EVENT
)
1448 zlog_debug("SEND to %s.%d", inet_ntoa(sin
.sin_addr
),
1449 ntohs(sin
.sin_port
));
1452 zlog_warn("can't send packet : %s", safe_strerror(errno
));
1457 /* Add redistributed route to RIP table. */
1458 void rip_redistribute_add(int type
, int sub_type
, struct prefix_ipv4
*p
,
1459 struct nexthop
*nh
, unsigned int metric
,
1460 unsigned char distance
, route_tag_t tag
)
1463 struct route_node
*rp
= NULL
;
1464 struct rip_info
*rinfo
= NULL
, newinfo
;
1465 struct list
*list
= NULL
;
1467 /* Redistribute route */
1468 ret
= rip_destination_check(p
->prefix
);
1472 rp
= route_node_get(rip
->table
, (struct prefix
*)p
);
1474 memset(&newinfo
, 0, sizeof(struct rip_info
));
1475 newinfo
.type
= type
;
1476 newinfo
.sub_type
= sub_type
;
1478 newinfo
.external_metric
= metric
;
1479 newinfo
.distance
= distance
;
1480 if (tag
<= UINT16_MAX
) /* RIP only supports 16 bit tags */
1485 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
1486 rinfo
= listgetdata(listhead(list
));
1488 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
1489 && rinfo
->sub_type
== RIP_ROUTE_INTERFACE
1490 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
1491 route_unlock_node(rp
);
1495 /* Manually configured RIP route check. */
1496 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1497 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
1498 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))) {
1499 if (type
!= ZEBRA_ROUTE_RIP
1500 || ((sub_type
!= RIP_ROUTE_STATIC
)
1501 && (sub_type
!= RIP_ROUTE_DEFAULT
))) {
1502 route_unlock_node(rp
);
1507 (void)rip_ecmp_replace(&newinfo
);
1508 route_unlock_node(rp
);
1510 (void)rip_ecmp_add(&newinfo
);
1512 if (IS_RIP_DEBUG_EVENT
) {
1513 zlog_debug("Redistribute new prefix %s/%d",
1514 inet_ntoa(p
->prefix
), p
->prefixlen
);
1517 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1520 /* Delete redistributed route from RIP table. */
1521 void rip_redistribute_delete(int type
, int sub_type
, struct prefix_ipv4
*p
,
1525 struct route_node
*rp
;
1526 struct rip_info
*rinfo
;
1528 ret
= rip_destination_check(p
->prefix
);
1532 rp
= route_node_lookup(rip
->table
, (struct prefix
*)p
);
1534 struct list
*list
= rp
->info
;
1536 if (list
!= NULL
&& listcount(list
) != 0) {
1537 rinfo
= listgetdata(listhead(list
));
1538 if (rinfo
!= NULL
&& rinfo
->type
== type
1539 && rinfo
->sub_type
== sub_type
1540 && rinfo
->nh
.ifindex
== ifindex
) {
1541 /* Perform poisoned reverse. */
1542 rinfo
->metric
= RIP_METRIC_INFINITY
;
1543 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
1544 rip_garbage_collect
,
1546 RIP_TIMER_OFF(rinfo
->t_timeout
);
1547 rinfo
->flags
|= RIP_RTF_CHANGED
;
1549 if (IS_RIP_DEBUG_EVENT
)
1551 "Poison %s/%d on the interface %s with an "
1552 "infinity metric [delete]",
1553 inet_ntoa(p
->prefix
),
1555 ifindex2ifname(ifindex
,
1558 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1561 route_unlock_node(rp
);
1565 /* Response to request called from rip_read ().*/
1566 static void rip_request_process(struct rip_packet
*packet
, int size
,
1567 struct sockaddr_in
*from
, struct connected
*ifc
)
1571 struct prefix_ipv4 p
;
1572 struct route_node
*rp
;
1573 struct rip_info
*rinfo
;
1574 struct rip_interface
*ri
;
1576 /* Does not reponse to the requests on the loopback interfaces */
1577 if (if_is_loopback(ifc
->ifp
))
1580 /* Check RIP process is enabled on this interface. */
1581 ri
= ifc
->ifp
->info
;
1585 /* When passive interface is specified, suppress responses */
1589 /* RIP peer update. */
1590 rip_peer_update(from
, packet
->version
);
1592 lim
= ((caddr_t
)packet
) + size
;
1595 /* The Request is processed entry by entry. If there are no
1596 entries, no response is given. */
1597 if (lim
== (caddr_t
)rte
)
1600 /* There is one special case. If there is exactly one entry in the
1601 request, and it has an address family identifier of zero and a
1602 metric of infinity (i.e., 16), then this is a request to send the
1603 entire routing table. */
1604 if (lim
== ((caddr_t
)(rte
+ 1)) && ntohs(rte
->family
) == 0
1605 && ntohl(rte
->metric
) == RIP_METRIC_INFINITY
) {
1606 /* All route with split horizon */
1607 rip_output_process(ifc
, from
, rip_all_route
, packet
->version
);
1609 if (ntohs(rte
->family
) != AF_INET
)
1612 /* Examine the list of RTEs in the Request one by one. For each
1613 entry, look up the destination in the router's routing
1614 database and, if there is a route, put that route's metric in
1615 the metric field of the RTE. If there is no explicit route
1616 to the specified destination, put infinity in the metric
1617 field. Once all the entries have been filled in, change the
1618 command from Request to Response and send the datagram back
1619 to the requestor. */
1622 for (; ((caddr_t
)rte
) < lim
; rte
++) {
1623 p
.prefix
= rte
->prefix
;
1624 p
.prefixlen
= ip_masklen(rte
->mask
);
1625 apply_mask_ipv4(&p
);
1627 rp
= route_node_lookup(rip
->table
, (struct prefix
*)&p
);
1629 rinfo
= listgetdata(
1630 listhead((struct list
*)rp
->info
));
1631 rte
->metric
= htonl(rinfo
->metric
);
1632 route_unlock_node(rp
);
1634 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
1636 packet
->command
= RIP_RESPONSE
;
1638 (void)rip_send_packet((uint8_t *)packet
, size
, from
, ifc
);
1640 rip_global_queries
++;
1644 /* Set IPv6 packet info to the socket. */
1645 static int setsockopt_pktinfo(int sock
)
1650 ret
= setsockopt(sock
, IPPROTO_IP
, IP_PKTINFO
, &val
, sizeof(val
));
1652 zlog_warn("Can't setsockopt IP_PKTINFO : %s",
1653 safe_strerror(errno
));
1657 /* Read RIP packet by recvmsg function. */
1658 int rip_recvmsg(int sock
, uint8_t *buf
, int size
, struct sockaddr_in
*from
,
1664 struct cmsghdr
*ptr
;
1667 memset(&msg
, 0, sizeof(msg
));
1668 msg
.msg_name
= (void *)from
;
1669 msg
.msg_namelen
= sizeof(struct sockaddr_in
);
1672 msg
.msg_control
= (void *)adata
;
1673 msg
.msg_controllen
= sizeof adata
;
1677 ret
= recvmsg(sock
, &msg
, 0);
1681 for (ptr
= ZCMSG_FIRSTHDR(&msg
); ptr
!= NULL
;
1682 ptr
= CMSG_NXTHDR(&msg
, ptr
))
1683 if (ptr
->cmsg_level
== IPPROTO_IP
1684 && ptr
->cmsg_type
== IP_PKTINFO
) {
1685 struct in_pktinfo
*pktinfo
;
1688 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(ptr
);
1689 i
= pktinfo
->ipi_ifindex
;
1694 /* RIP packet read function. */
1695 int rip_read_new(struct thread
*t
)
1699 char buf
[RIP_PACKET_MAXSIZ
];
1700 struct sockaddr_in from
;
1703 /* Fetch socket then register myself. */
1704 sock
= THREAD_FD(t
);
1705 rip_event(RIP_READ
, sock
);
1707 /* Read RIP packet. */
1708 ret
= rip_recvmsg(sock
, buf
, RIP_PACKET_MAXSIZ
, &from
, (int *)&ifindex
);
1710 zlog_warn("Can't read RIP packet: %s", safe_strerror(errno
));
1716 #endif /* RIP_RECVMSG */
1718 /* First entry point of RIP packet. */
1719 static int rip_read(struct thread
*t
)
1724 union rip_buf rip_buf
;
1725 struct rip_packet
*packet
;
1726 struct sockaddr_in from
;
1730 struct interface
*ifp
= NULL
;
1731 struct connected
*ifc
;
1732 struct rip_interface
*ri
;
1735 /* Fetch socket then register myself. */
1736 sock
= THREAD_FD(t
);
1739 /* Add myself to tne next event */
1740 rip_event(RIP_READ
, sock
);
1742 /* RIPd manages only IPv4. */
1743 memset(&from
, 0, sizeof(struct sockaddr_in
));
1744 fromlen
= sizeof(struct sockaddr_in
);
1746 len
= recvfrom(sock
, (char *)&rip_buf
.buf
, sizeof(rip_buf
.buf
), 0,
1747 (struct sockaddr
*)&from
, &fromlen
);
1749 zlog_info("recvfrom failed: %s", safe_strerror(errno
));
1753 /* Check is this packet comming from myself? */
1754 if (if_check_address(from
.sin_addr
)) {
1755 if (IS_RIP_DEBUG_PACKET
)
1756 zlog_debug("ignore packet comes from myself");
1760 /* Which interface is this packet comes from. */
1761 ifc
= if_lookup_address((void *)&from
.sin_addr
, AF_INET
, VRF_DEFAULT
);
1765 /* RIP packet received */
1766 if (IS_RIP_DEBUG_EVENT
)
1767 zlog_debug("RECV packet from %s port %d on %s",
1768 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1769 ifp
? ifp
->name
: "unknown");
1771 /* If this packet come from unknown interface, ignore it. */
1774 "rip_read: cannot find interface for packet from %s port %d",
1775 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
));
1780 p
.u
.prefix4
= from
.sin_addr
;
1781 p
.prefixlen
= IPV4_MAX_BITLEN
;
1783 ifc
= connected_lookup_prefix(ifp
, &p
);
1787 "rip_read: cannot find connected address for packet from %s "
1788 "port %d on interface %s",
1789 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1794 /* Packet length check. */
1795 if (len
< RIP_PACKET_MINSIZ
) {
1796 zlog_warn("packet size %d is smaller than minimum size %d", len
,
1798 rip_peer_bad_packet(&from
);
1801 if (len
> RIP_PACKET_MAXSIZ
) {
1802 zlog_warn("packet size %d is larger than max size %d", len
,
1804 rip_peer_bad_packet(&from
);
1808 /* Packet alignment check. */
1809 if ((len
- RIP_PACKET_MINSIZ
) % 20) {
1810 zlog_warn("packet size %d is wrong for RIP packet alignment",
1812 rip_peer_bad_packet(&from
);
1816 /* Set RTE number. */
1817 rtenum
= ((len
- RIP_PACKET_MINSIZ
) / 20);
1819 /* For easy to handle. */
1820 packet
= &rip_buf
.rip_packet
;
1822 /* RIP version check. */
1823 if (packet
->version
== 0) {
1824 zlog_info("version 0 with command %d received.",
1826 rip_peer_bad_packet(&from
);
1830 /* Dump RIP packet. */
1831 if (IS_RIP_DEBUG_RECV
)
1832 rip_packet_dump(packet
, len
, "RECV");
1834 /* RIP version adjust. This code should rethink now. RFC1058 says
1835 that "Version 1 implementations are to ignore this extra data and
1836 process only the fields specified in this document.". So RIPv3
1837 packet should be treated as RIPv1 ignoring must be zero field. */
1838 if (packet
->version
> RIPv2
)
1839 packet
->version
= RIPv2
;
1841 /* Is RIP running or is this RIP neighbor ?*/
1843 if (!ri
->running
&& !rip_neighbor_lookup(&from
)) {
1844 if (IS_RIP_DEBUG_EVENT
)
1845 zlog_debug("RIP is not enabled on interface %s.",
1847 rip_peer_bad_packet(&from
);
1851 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1852 vrecv
= ((ri
->ri_receive
== RI_RIP_UNSPEC
) ? rip
->version_recv
1854 if (vrecv
== RI_RIP_VERSION_NONE
1855 || ((packet
->version
== RIPv1
) && !(vrecv
& RIPv1
))
1856 || ((packet
->version
== RIPv2
) && !(vrecv
& RIPv2
))) {
1857 if (IS_RIP_DEBUG_PACKET
)
1859 " packet's v%d doesn't fit to if version spec",
1861 rip_peer_bad_packet(&from
);
1865 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1866 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1867 accepted; authenticated RIP-2 messages shall be discarded. */
1868 if ((ri
->auth_type
== RIP_NO_AUTH
) && rtenum
1869 && (packet
->version
== RIPv2
)
1870 && (packet
->rte
->family
== htons(RIP_FAMILY_AUTH
))) {
1871 if (IS_RIP_DEBUG_EVENT
)
1873 "packet RIPv%d is dropped because authentication disabled",
1875 rip_peer_bad_packet(&from
);
1880 If the router is configured to authenticate RIP-2 messages, then
1881 RIP-1 messages and RIP-2 messages which pass authentication
1882 testing shall be accepted; unauthenticated and failed
1883 authentication RIP-2 messages shall be discarded. For maximum
1884 security, RIP-1 messages should be ignored when authentication is
1885 in use (see section 4.1); otherwise, the routing information from
1886 authenticated messages will be propagated by RIP-1 routers in an
1887 unauthenticated manner.
1889 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1890 * always reply regardless of authentication settings, because:
1892 * - if there other authorised routers on-link, the REQUESTor can
1893 * passively obtain the routing updates anyway
1894 * - if there are no other authorised routers on-link, RIP can
1895 * easily be disabled for the link to prevent giving out information
1896 * on state of this routers RIP routing table..
1898 * I.e. if RIPv1 has any place anymore these days, it's as a very
1899 * simple way to distribute routing information (e.g. to embedded
1900 * hosts / appliances) and the ability to give out RIPv1
1901 * routing-information freely, while still requiring RIPv2
1902 * authentication for any RESPONSEs might be vaguely useful.
1904 if (ri
->auth_type
!= RIP_NO_AUTH
&& packet
->version
== RIPv1
) {
1905 /* Discard RIPv1 messages other than REQUESTs */
1906 if (packet
->command
!= RIP_REQUEST
) {
1907 if (IS_RIP_DEBUG_PACKET
)
1910 " dropped because authentication enabled");
1911 rip_peer_bad_packet(&from
);
1914 } else if (ri
->auth_type
!= RIP_NO_AUTH
) {
1915 const char *auth_desc
;
1918 /* There definitely is no authentication in the packet.
1920 if (IS_RIP_DEBUG_PACKET
)
1922 "RIPv2 authentication failed: no auth RTE in packet");
1923 rip_peer_bad_packet(&from
);
1927 /* First RTE must be an Authentication Family RTE */
1928 if (packet
->rte
->family
!= htons(RIP_FAMILY_AUTH
)) {
1929 if (IS_RIP_DEBUG_PACKET
)
1932 " dropped because authentication enabled");
1933 rip_peer_bad_packet(&from
);
1937 /* Check RIPv2 authentication. */
1938 switch (ntohs(packet
->rte
->tag
)) {
1939 case RIP_AUTH_SIMPLE_PASSWORD
:
1940 auth_desc
= "simple";
1941 ret
= rip_auth_simple_password(packet
->rte
, &from
, ifp
);
1946 ret
= rip_auth_md5(packet
, &from
, len
, ifp
);
1947 /* Reset RIP packet length to trim MD5 data. */
1953 auth_desc
= "unknown type";
1954 if (IS_RIP_DEBUG_PACKET
)
1956 "RIPv2 Unknown authentication type %d",
1957 ntohs(packet
->rte
->tag
));
1961 if (IS_RIP_DEBUG_PACKET
)
1962 zlog_debug("RIPv2 %s authentication success",
1965 if (IS_RIP_DEBUG_PACKET
)
1966 zlog_debug("RIPv2 %s authentication failure",
1968 rip_peer_bad_packet(&from
);
1973 /* Process each command. */
1974 switch (packet
->command
) {
1976 rip_response_process(packet
, len
, &from
, ifc
);
1980 rip_request_process(packet
, len
, &from
, ifc
);
1985 "Obsolete command %s received, please sent it to routed",
1986 lookup_msg(rip_msg
, packet
->command
, NULL
));
1987 rip_peer_bad_packet(&from
);
1989 case RIP_POLL_ENTRY
:
1990 zlog_info("Obsolete command %s received",
1991 lookup_msg(rip_msg
, packet
->command
, NULL
));
1992 rip_peer_bad_packet(&from
);
1995 zlog_info("Unknown RIP command %d received", packet
->command
);
1996 rip_peer_bad_packet(&from
);
2003 /* Write routing table entry to the stream and return next index of
2004 the routing table entry in the stream. */
2005 static int rip_write_rte(int num
, struct stream
*s
, struct prefix_ipv4
*p
,
2006 uint8_t version
, struct rip_info
*rinfo
)
2008 struct in_addr mask
;
2010 /* Write routing table entry. */
2011 if (version
== RIPv1
) {
2012 stream_putw(s
, AF_INET
);
2014 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2015 stream_put_ipv4(s
, 0);
2016 stream_put_ipv4(s
, 0);
2017 stream_putl(s
, rinfo
->metric_out
);
2019 masklen2ip(p
->prefixlen
, &mask
);
2021 stream_putw(s
, AF_INET
);
2022 stream_putw(s
, rinfo
->tag_out
);
2023 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2024 stream_put_ipv4(s
, mask
.s_addr
);
2025 stream_put_ipv4(s
, rinfo
->nexthop_out
.s_addr
);
2026 stream_putl(s
, rinfo
->metric_out
);
2032 /* Send update to the ifp or spcified neighbor. */
2033 void rip_output_process(struct connected
*ifc
, struct sockaddr_in
*to
,
2034 int route_type
, uint8_t version
)
2038 struct route_node
*rp
;
2039 struct rip_info
*rinfo
;
2040 struct rip_interface
*ri
;
2041 struct prefix_ipv4
*p
;
2042 struct prefix_ipv4 classfull
;
2043 struct prefix_ipv4 ifaddrclass
;
2044 struct key
*key
= NULL
;
2045 /* this might need to made dynamic if RIP ever supported auth methods
2046 with larger key string sizes */
2047 char auth_str
[RIP_AUTH_SIMPLE_SIZE
];
2048 size_t doff
= 0; /* offset of digest offset field */
2052 struct list
*list
= NULL
;
2053 struct listnode
*listnode
= NULL
;
2055 /* Logging output event. */
2056 if (IS_RIP_DEBUG_EVENT
) {
2058 zlog_debug("update routes to neighbor %s",
2059 inet_ntoa(to
->sin_addr
));
2061 zlog_debug("update routes on interface %s ifindex %d",
2062 ifc
->ifp
->name
, ifc
->ifp
->ifindex
);
2065 /* Set output stream. */
2068 /* Reset stream and RTE counter. */
2070 rtemax
= RIP_MAX_RTE
;
2072 /* Get RIP interface. */
2073 ri
= ifc
->ifp
->info
;
2075 /* If output interface is in simple password authentication mode, we
2076 need space for authentication data. */
2077 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2080 /* If output interface is in MD5 authentication mode, we need space
2081 for authentication header and data. */
2082 if (ri
->auth_type
== RIP_AUTH_MD5
)
2085 /* If output interface is in simple password authentication mode
2086 and string or keychain is specified we need space for auth. data */
2087 if (ri
->auth_type
!= RIP_NO_AUTH
) {
2088 if (ri
->key_chain
) {
2089 struct keychain
*keychain
;
2091 keychain
= keychain_lookup(ri
->key_chain
);
2093 key
= key_lookup_for_send(keychain
);
2095 /* to be passed to auth functions later */
2096 rip_auth_prepare_str_send(ri
, key
, auth_str
,
2097 RIP_AUTH_SIMPLE_SIZE
);
2098 if (strlen(auth_str
) == 0)
2102 if (version
== RIPv1
) {
2103 memcpy(&ifaddrclass
, ifc
->address
, sizeof(struct prefix_ipv4
));
2104 apply_classful_mask_ipv4(&ifaddrclass
);
2106 if (ifc
->address
->prefixlen
> ifaddrclass
.prefixlen
)
2110 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2111 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
2112 rinfo
= listgetdata(listhead(list
));
2113 /* For RIPv1, if we are subnetted, output subnets in our
2115 /* that have the same mask as the output "interface".
2117 /* networks, only the classfull version is output. */
2119 if (version
== RIPv1
) {
2120 p
= (struct prefix_ipv4
*)&rp
->p
;
2122 if (IS_RIP_DEBUG_PACKET
)
2124 "RIPv1 mask check, %s/%d considered for output",
2125 inet_ntoa(rp
->p
.u
.prefix4
),
2130 (struct prefix
*)&ifaddrclass
,
2132 if ((ifc
->address
->prefixlen
2134 && (rp
->p
.prefixlen
!= 32))
2137 memcpy(&classfull
, &rp
->p
,
2138 sizeof(struct prefix_ipv4
));
2139 apply_classful_mask_ipv4(&classfull
);
2140 if (rp
->p
.u
.prefix4
.s_addr
!= 0
2141 && classfull
.prefixlen
2145 if (IS_RIP_DEBUG_PACKET
)
2147 "RIPv1 mask check, %s/%d made it through",
2148 inet_ntoa(rp
->p
.u
.prefix4
),
2151 p
= (struct prefix_ipv4
*)&rp
->p
;
2153 /* Apply output filters. */
2154 ret
= rip_filter(RIP_FILTER_OUT
, p
, ri
);
2158 /* Changed route only output. */
2159 if (route_type
== rip_changed_route
2160 && (!(rinfo
->flags
& RIP_RTF_CHANGED
)))
2163 /* Split horizon. */
2164 /* if (split_horizon == rip_split_horizon) */
2165 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
) {
2167 * We perform split horizon for RIP and
2169 * For rip routes, we want to suppress the route
2171 * end up sending the route back on the
2173 * learned it from, with a higher metric. For
2175 * we suppress the route if the prefix is a
2177 * source address that we are going to use for
2179 * (in order to handle the case when multiple
2181 * configured on the same interface).
2184 struct rip_info
*tmp_rinfo
= NULL
;
2185 struct connected
*tmp_ifc
= NULL
;
2187 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2189 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2190 && tmp_rinfo
->nh
.ifindex
2191 == ifc
->ifp
->ifindex
) {
2197 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2198 for (ALL_LIST_ELEMENTS_RO(
2199 ifc
->ifp
->connected
,
2203 tmp_ifc
->address
)) {
2213 /* Preparation for route-map. */
2214 rinfo
->metric_set
= 0;
2215 rinfo
->nexthop_out
.s_addr
= 0;
2216 rinfo
->metric_out
= rinfo
->metric
;
2217 rinfo
->tag_out
= rinfo
->tag
;
2218 rinfo
->ifindex_out
= ifc
->ifp
->ifindex
;
2220 /* In order to avoid some local loops,
2221 * if the RIP route has a nexthop via this interface,
2223 * otherwise set it to 0. The nexthop should not be
2225 * beyond the local broadcast/multicast area in order
2226 * to avoid an IGP multi-level recursive look-up.
2229 if (rinfo
->nh
.ifindex
== ifc
->ifp
->ifindex
)
2230 rinfo
->nexthop_out
= rinfo
->nh
.gate
.ipv4
;
2232 /* Interface route-map */
2233 if (ri
->routemap
[RIP_FILTER_OUT
]) {
2234 ret
= route_map_apply(
2235 ri
->routemap
[RIP_FILTER_OUT
],
2236 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2238 if (ret
== RMAP_DENYMATCH
) {
2239 if (IS_RIP_DEBUG_PACKET
)
2241 "RIP %s/%d is filtered by route-map out",
2242 inet_ntoa(p
->prefix
),
2248 /* Apply redistribute route map - continue, if deny */
2249 if (rip
->route_map
[rinfo
->type
].name
2250 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2251 ret
= route_map_apply(
2252 rip
->route_map
[rinfo
->type
].map
,
2253 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2255 if (ret
== RMAP_DENYMATCH
) {
2256 if (IS_RIP_DEBUG_PACKET
)
2258 "%s/%d is filtered by route-map",
2259 inet_ntoa(p
->prefix
),
2265 /* When route-map does not set metric. */
2266 if (!rinfo
->metric_set
) {
2267 /* If redistribute metric is set. */
2268 if (rip
->route_map
[rinfo
->type
].metric_config
2269 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
2271 rip
->route_map
[rinfo
->type
]
2274 /* If the route is not connected or
2276 one, use default-metric value*/
2277 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2279 != ZEBRA_ROUTE_CONNECT
2281 != RIP_METRIC_INFINITY
)
2283 rip
->default_metric
;
2287 /* Apply offset-list */
2288 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2289 rip_offset_list_apply_out(p
, ifc
->ifp
,
2290 &rinfo
->metric_out
);
2292 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2293 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2295 /* Perform split-horizon with poisoned reverse
2296 * for RIP and connected routes.
2298 if (ri
->split_horizon
2299 == RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2301 * We perform split horizon for RIP and
2303 * For rip routes, we want to suppress the route
2305 * end up sending the route back on the
2307 * learned it from, with a higher metric. For
2309 * we suppress the route if the prefix is a
2311 * source address that we are going to use for
2313 * (in order to handle the case when multiple
2315 * configured on the same interface).
2317 struct rip_info
*tmp_rinfo
= NULL
;
2318 struct connected
*tmp_ifc
= NULL
;
2320 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2322 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2323 && tmp_rinfo
->nh
.ifindex
2324 == ifc
->ifp
->ifindex
)
2326 RIP_METRIC_INFINITY
;
2328 if (rinfo
->metric_out
!= RIP_METRIC_INFINITY
2329 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2330 for (ALL_LIST_ELEMENTS_RO(
2331 ifc
->ifp
->connected
,
2335 tmp_ifc
->address
)) {
2337 RIP_METRIC_INFINITY
;
2343 /* Prepare preamble, auth headers, if needs be */
2345 stream_putc(s
, RIP_RESPONSE
);
2346 stream_putc(s
, version
);
2349 /* auth header for !v1 && !no_auth */
2350 if ((ri
->auth_type
!= RIP_NO_AUTH
)
2351 && (version
!= RIPv1
))
2352 doff
= rip_auth_header_write(
2353 s
, ri
, key
, auth_str
,
2354 RIP_AUTH_SIMPLE_SIZE
);
2357 /* Write RTE to the stream. */
2358 num
= rip_write_rte(num
, s
, p
, version
, rinfo
);
2359 if (num
== rtemax
) {
2360 if (version
== RIPv2
2361 && ri
->auth_type
== RIP_AUTH_MD5
)
2362 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2363 RIP_AUTH_SIMPLE_SIZE
);
2365 ret
= rip_send_packet(STREAM_DATA(s
),
2366 stream_get_endp(s
), to
,
2369 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2370 rip_packet_dump((struct rip_packet
*)
2379 /* Flush unwritten RTE. */
2381 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2382 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2383 RIP_AUTH_SIMPLE_SIZE
);
2385 ret
= rip_send_packet(STREAM_DATA(s
), stream_get_endp(s
), to
,
2388 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2389 rip_packet_dump((struct rip_packet
*)STREAM_DATA(s
),
2390 stream_get_endp(s
), "SEND");
2394 /* Statistics updates. */
2398 /* Send RIP packet to the interface. */
2399 static void rip_update_interface(struct connected
*ifc
, uint8_t version
,
2402 struct interface
*ifp
= ifc
->ifp
;
2403 struct rip_interface
*ri
= ifp
->info
;
2404 struct sockaddr_in to
;
2406 /* When RIP version is 2 and multicast enable interface. */
2407 if (version
== RIPv2
&& !ri
->v2_broadcast
&& if_is_multicast(ifp
)) {
2408 if (IS_RIP_DEBUG_EVENT
)
2409 zlog_debug("multicast announce on %s ", ifp
->name
);
2411 rip_output_process(ifc
, NULL
, route_type
, version
);
2415 /* If we can't send multicast packet, send it with unicast. */
2416 if (if_is_broadcast(ifp
) || if_is_pointopoint(ifp
)) {
2417 if (ifc
->address
->family
== AF_INET
) {
2418 /* Destination address and port setting. */
2419 memset(&to
, 0, sizeof(struct sockaddr_in
));
2420 if (ifc
->destination
)
2421 /* use specified broadcast or peer destination
2423 to
.sin_addr
= ifc
->destination
->u
.prefix4
;
2424 else if (ifc
->address
->prefixlen
< IPV4_MAX_PREFIXLEN
)
2425 /* calculate the appropriate broadcast address
2427 to
.sin_addr
.s_addr
= ipv4_broadcast_addr(
2428 ifc
->address
->u
.prefix4
.s_addr
,
2429 ifc
->address
->prefixlen
);
2431 /* do not know where to send the packet */
2433 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2435 if (IS_RIP_DEBUG_EVENT
)
2436 zlog_debug("%s announce to %s on %s",
2437 CONNECTED_PEER(ifc
) ? "unicast"
2439 inet_ntoa(to
.sin_addr
), ifp
->name
);
2441 rip_output_process(ifc
, &to
, route_type
, version
);
2446 /* Update send to all interface and neighbor. */
2447 static void rip_update_process(int route_type
)
2449 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2450 struct listnode
*ifnode
, *ifnnode
;
2451 struct connected
*connected
;
2452 struct interface
*ifp
;
2453 struct rip_interface
*ri
;
2454 struct route_node
*rp
;
2455 struct sockaddr_in to
;
2458 /* Send RIP update to each interface. */
2459 FOR_ALL_INTERFACES (vrf
, ifp
) {
2460 if (if_is_loopback(ifp
))
2463 if (!if_is_operative(ifp
))
2466 /* Fetch RIP interface information. */
2469 /* When passive interface is specified, suppress announce to the
2476 * If there is no version configuration in the
2478 * use rip's version setting.
2480 int vsend
= ((ri
->ri_send
== RI_RIP_UNSPEC
)
2484 if (IS_RIP_DEBUG_EVENT
)
2485 zlog_debug("SEND UPDATE to %s ifindex %d",
2486 ifp
->name
, ifp
->ifindex
);
2488 /* send update on each connected network */
2489 for (ALL_LIST_ELEMENTS(ifp
->connected
, ifnode
, ifnnode
,
2491 if (connected
->address
->family
== AF_INET
) {
2493 rip_update_interface(
2497 && if_is_multicast(ifp
))
2498 rip_update_interface(
2506 /* RIP send updates to each neighbor. */
2507 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
2508 if (rp
->info
!= NULL
) {
2511 connected
= if_lookup_address(&p
->u
.prefix4
, AF_INET
,
2515 "Neighbor %s doesnt have connected interface!",
2516 inet_ntoa(p
->u
.prefix4
));
2520 /* Set destination address and port */
2521 memset(&to
, 0, sizeof(struct sockaddr_in
));
2522 to
.sin_addr
= p
->u
.prefix4
;
2523 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2525 /* RIP version is rip's configuration. */
2526 rip_output_process(connected
, &to
, route_type
,
2531 /* RIP's periodical timer. */
2532 static int rip_update(struct thread
*t
)
2534 /* Clear timer pointer. */
2535 rip
->t_update
= NULL
;
2537 if (IS_RIP_DEBUG_EVENT
)
2538 zlog_debug("update timer fire!");
2540 /* Process update output. */
2541 rip_update_process(rip_all_route
);
2543 /* Triggered updates may be suppressed if a regular update is due by
2544 the time the triggered update would be sent. */
2545 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2548 /* Register myself. */
2549 rip_event(RIP_UPDATE_EVENT
, 0);
2554 /* Walk down the RIP routing table then clear changed flag. */
2555 static void rip_clear_changed_flag(void)
2557 struct route_node
*rp
;
2558 struct rip_info
*rinfo
= NULL
;
2559 struct list
*list
= NULL
;
2560 struct listnode
*listnode
= NULL
;
2562 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2563 if ((list
= rp
->info
) != NULL
)
2564 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
2565 UNSET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2566 /* This flag can be set only on the first entry.
2572 /* Triggered update interval timer. */
2573 static int rip_triggered_interval(struct thread
*t
)
2575 int rip_triggered_update(struct thread
*);
2577 rip
->t_triggered_interval
= NULL
;
2581 rip_triggered_update(t
);
2586 /* Execute triggered update. */
2587 static int rip_triggered_update(struct thread
*t
)
2591 /* Clear thred pointer. */
2592 rip
->t_triggered_update
= NULL
;
2594 /* Cancel interval timer. */
2595 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2598 /* Logging triggered update. */
2599 if (IS_RIP_DEBUG_EVENT
)
2600 zlog_debug("triggered update!");
2602 /* Split Horizon processing is done when generating triggered
2603 updates as well as normal updates (see section 2.6). */
2604 rip_update_process(rip_changed_route
);
2606 /* Once all of the triggered updates have been generated, the route
2607 change flags should be cleared. */
2608 rip_clear_changed_flag();
2610 /* After a triggered update is sent, a timer should be set for a
2611 random interval between 1 and 5 seconds. If other changes that
2612 would trigger updates occur before the timer expires, a single
2613 update is triggered when the timer expires. */
2614 interval
= (random() % 5) + 1;
2616 rip
->t_triggered_interval
= NULL
;
2617 thread_add_timer(master
, rip_triggered_interval
, NULL
, interval
,
2618 &rip
->t_triggered_interval
);
2623 /* Withdraw redistributed route. */
2624 void rip_redistribute_withdraw(int type
)
2626 struct route_node
*rp
;
2627 struct rip_info
*rinfo
= NULL
;
2628 struct list
*list
= NULL
;
2633 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2634 if ((list
= rp
->info
) != NULL
) {
2635 rinfo
= listgetdata(listhead(list
));
2636 if (rinfo
->type
== type
2637 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2638 /* Perform poisoned reverse. */
2639 rinfo
->metric
= RIP_METRIC_INFINITY
;
2640 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
2641 rip_garbage_collect
,
2643 RIP_TIMER_OFF(rinfo
->t_timeout
);
2644 rinfo
->flags
|= RIP_RTF_CHANGED
;
2646 if (IS_RIP_DEBUG_EVENT
) {
2647 struct prefix_ipv4
*p
=
2648 (struct prefix_ipv4
*)&rp
->p
;
2651 "Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2652 inet_ntoa(p
->prefix
),
2659 rip_event(RIP_TRIGGERED_UPDATE
, 0);
2664 /* Create new RIP instance and set it to global variable. */
2665 static int rip_create(void)
2667 rip
= XCALLOC(MTYPE_RIP
, sizeof(struct rip
));
2669 /* Set initial value. */
2670 rip
->version_send
= RI_RIP_VERSION_2
;
2671 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2672 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
2673 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
2674 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
2675 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2677 /* Initialize RIP routig table. */
2678 rip
->table
= route_table_init();
2679 rip
->route
= route_table_init();
2680 rip
->neighbor
= route_table_init();
2682 /* Make output stream. */
2683 rip
->obuf
= stream_new(1500);
2686 rip
->sock
= rip_create_socket();
2690 /* Create read and timer thread. */
2691 rip_event(RIP_READ
, rip
->sock
);
2692 rip_event(RIP_UPDATE_EVENT
, 1);
2699 /* Sned RIP request to the destination. */
2700 int rip_request_send(struct sockaddr_in
*to
, struct interface
*ifp
,
2701 uint8_t version
, struct connected
*connected
)
2704 struct rip_packet rip_packet
;
2705 struct listnode
*node
, *nnode
;
2707 memset(&rip_packet
, 0, sizeof(rip_packet
));
2709 rip_packet
.command
= RIP_REQUEST
;
2710 rip_packet
.version
= version
;
2711 rte
= rip_packet
.rte
;
2712 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
2716 * connected is only sent for ripv1 case, or when
2717 * interface does not support multicast. Caller loops
2718 * over each connected address for this case.
2720 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2722 != sizeof(rip_packet
))
2725 return sizeof(rip_packet
);
2728 /* send request on each connected network */
2729 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, connected
)) {
2730 struct prefix_ipv4
*p
;
2732 p
= (struct prefix_ipv4
*)connected
->address
;
2734 if (p
->family
!= AF_INET
)
2737 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2739 != sizeof(rip_packet
))
2742 return sizeof(rip_packet
);
2745 static int rip_update_jitter(unsigned long time
)
2747 #define JITTER_BOUND 4
2748 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2749 Given that, we cannot let time be less than JITTER_BOUND seconds.
2750 The RIPv2 RFC says jitter should be small compared to
2751 update_time. We consider 1/JITTER_BOUND to be small.
2754 int jitter_input
= time
;
2757 if (jitter_input
< JITTER_BOUND
)
2758 jitter_input
= JITTER_BOUND
;
2760 jitter
= (((random() % ((jitter_input
* 2) + 1)) - jitter_input
));
2762 return jitter
/ JITTER_BOUND
;
2765 void rip_event(enum rip_event event
, int sock
)
2772 thread_add_read(master
, rip_read
, NULL
, sock
, &rip
->t_read
);
2774 case RIP_UPDATE_EVENT
:
2775 RIP_TIMER_OFF(rip
->t_update
);
2776 jitter
= rip_update_jitter(rip
->update_time
);
2777 thread_add_timer(master
, rip_update
, NULL
,
2778 sock
? 2 : rip
->update_time
+ jitter
,
2781 case RIP_TRIGGERED_UPDATE
:
2782 if (rip
->t_triggered_interval
)
2785 thread_add_event(master
, rip_triggered_update
, NULL
, 0,
2786 &rip
->t_triggered_update
);
2793 DEFUN_NOSH (router_rip
,
2796 "Enable a routing process\n"
2797 "Routing Information Protocol (RIP)\n")
2801 /* If rip is not enabled before. */
2805 zlog_info("Can't create RIP");
2806 return CMD_WARNING_CONFIG_FAILED
;
2810 VTY_PUSH_CONTEXT(RIP_NODE
, rip
);
2815 DEFUN (no_router_rip
,
2819 "Enable a routing process\n"
2820 "Routing Information Protocol (RIP)\n")
2830 "Set routing protocol version\n"
2836 version
= atoi(argv
[idx_number
]->arg
);
2837 if (version
!= RIPv1
&& version
!= RIPv2
) {
2838 vty_out(vty
, "invalid rip version %d\n", version
);
2839 return CMD_WARNING_CONFIG_FAILED
;
2841 rip
->version_send
= version
;
2842 rip
->version_recv
= version
;
2847 DEFUN (no_rip_version
,
2849 "no version [(1-2)]",
2851 "Set routing protocol version\n"
2854 /* Set RIP version to the default. */
2855 rip
->version_send
= RI_RIP_VERSION_2
;
2856 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2865 "RIP static route configuration\n"
2866 "IP prefix <network>/<length>\n")
2868 int idx_ipv4_prefixlen
= 1;
2871 struct prefix_ipv4 p
;
2872 struct route_node
*node
;
2874 memset(&nh
, 0, sizeof(nh
));
2875 nh
.type
= NEXTHOP_TYPE_IPV4
;
2877 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
2879 vty_out(vty
, "Malformed address\n");
2880 return CMD_WARNING_CONFIG_FAILED
;
2882 apply_mask_ipv4(&p
);
2884 /* For router rip configuration. */
2885 node
= route_node_get(rip
->route
, (struct prefix
*)&p
);
2888 vty_out(vty
, "There is already same static route.\n");
2889 route_unlock_node(node
);
2893 node
->info
= (void *)1;
2895 rip_redistribute_add(ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, &nh
, 0, 0,
2901 DEFUN (no_rip_route
,
2903 "no route A.B.C.D/M",
2905 "RIP static route configuration\n"
2906 "IP prefix <network>/<length>\n")
2908 int idx_ipv4_prefixlen
= 2;
2910 struct prefix_ipv4 p
;
2911 struct route_node
*node
;
2913 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
2915 vty_out(vty
, "Malformed address\n");
2916 return CMD_WARNING_CONFIG_FAILED
;
2918 apply_mask_ipv4(&p
);
2920 /* For router rip configuration. */
2921 node
= route_node_lookup(rip
->route
, (struct prefix
*)&p
);
2923 vty_out(vty
, "Can't find route %s.\n",
2924 argv
[idx_ipv4_prefixlen
]->arg
);
2925 return CMD_WARNING_CONFIG_FAILED
;
2928 rip_redistribute_delete(ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0);
2929 route_unlock_node(node
);
2932 route_unlock_node(node
);
2939 rip_update_default_metric (void)
2941 struct route_node
*np
;
2942 struct rip_info
*rinfo
= NULL
;
2943 struct list
*list
= NULL
;
2944 struct listnode
*listnode
= NULL
;
2946 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
2947 if ((list
= np
->info
) != NULL
)
2948 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
2949 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
2950 rinfo
->metric
= rip
->default_metric
;
2954 DEFUN (rip_default_metric
,
2955 rip_default_metric_cmd
,
2956 "default-metric (1-16)",
2957 "Set a metric of redistribute routes\n"
2962 rip
->default_metric
= atoi(argv
[idx_number
]->arg
);
2963 /* rip_update_default_metric (); */
2968 DEFUN (no_rip_default_metric
,
2969 no_rip_default_metric_cmd
,
2970 "no default-metric [(1-16)]",
2972 "Set a metric of redistribute routes\n"
2976 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2977 /* rip_update_default_metric (); */
2985 "timers basic (5-2147483647) (5-2147483647) (5-2147483647)",
2986 "Adjust routing timers\n"
2987 "Basic routing protocol update timers\n"
2988 "Routing table update timer value in second. Default is 30.\n"
2989 "Routing information timeout timer. Default is 180.\n"
2990 "Garbage collection timer. Default is 120.\n")
2993 int idx_number_2
= 3;
2994 int idx_number_3
= 4;
2995 unsigned long update
;
2996 unsigned long timeout
;
2997 unsigned long garbage
;
2998 char *endptr
= NULL
;
2999 unsigned long RIP_TIMER_MAX
= 2147483647;
3000 unsigned long RIP_TIMER_MIN
= 5;
3002 update
= strtoul(argv
[idx_number
]->arg
, &endptr
, 10);
3003 if (update
> RIP_TIMER_MAX
|| update
< RIP_TIMER_MIN
3004 || *endptr
!= '\0') {
3005 vty_out(vty
, "update timer value error\n");
3006 return CMD_WARNING_CONFIG_FAILED
;
3009 timeout
= strtoul(argv
[idx_number_2
]->arg
, &endptr
, 10);
3010 if (timeout
> RIP_TIMER_MAX
|| timeout
< RIP_TIMER_MIN
3011 || *endptr
!= '\0') {
3012 vty_out(vty
, "timeout timer value error\n");
3013 return CMD_WARNING_CONFIG_FAILED
;
3016 garbage
= strtoul(argv
[idx_number_3
]->arg
, &endptr
, 10);
3017 if (garbage
> RIP_TIMER_MAX
|| garbage
< RIP_TIMER_MIN
3018 || *endptr
!= '\0') {
3019 vty_out(vty
, "garbage timer value error\n");
3020 return CMD_WARNING_CONFIG_FAILED
;
3023 /* Set each timer value. */
3024 rip
->update_time
= update
;
3025 rip
->timeout_time
= timeout
;
3026 rip
->garbage_time
= garbage
;
3028 /* Reset update timer thread. */
3029 rip_event(RIP_UPDATE_EVENT
, 0);
3034 DEFUN (no_rip_timers
,
3036 "no timers basic [(0-65535) (0-65535) (0-65535)]",
3038 "Adjust routing timers\n"
3039 "Basic routing protocol update timers\n"
3040 "Routing table update timer value in second. Default is 30.\n"
3041 "Routing information timeout timer. Default is 180.\n"
3042 "Garbage collection timer. Default is 120.\n")
3044 /* Set each timer value to the default. */
3045 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
3046 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
3047 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
3049 /* Reset update timer thread. */
3050 rip_event(RIP_UPDATE_EVENT
, 0);
3056 struct route_table
*rip_distance_table
;
3058 struct rip_distance
{
3059 /* Distance value for the IP source prefix. */
3062 /* Name of the access-list to be matched. */
3066 static struct rip_distance
*rip_distance_new(void)
3068 return XCALLOC(MTYPE_RIP_DISTANCE
, sizeof(struct rip_distance
));
3071 static void rip_distance_free(struct rip_distance
*rdistance
)
3073 XFREE(MTYPE_RIP_DISTANCE
, rdistance
);
3076 static int rip_distance_set(struct vty
*vty
, const char *distance_str
,
3077 const char *ip_str
, const char *access_list_str
)
3080 struct prefix_ipv4 p
;
3082 struct route_node
*rn
;
3083 struct rip_distance
*rdistance
;
3085 ret
= str2prefix_ipv4(ip_str
, &p
);
3087 vty_out(vty
, "Malformed prefix\n");
3088 return CMD_WARNING_CONFIG_FAILED
;
3091 distance
= atoi(distance_str
);
3093 /* Get RIP distance node. */
3094 rn
= route_node_get(rip_distance_table
, (struct prefix
*)&p
);
3096 rdistance
= rn
->info
;
3097 route_unlock_node(rn
);
3099 rdistance
= rip_distance_new();
3100 rn
->info
= rdistance
;
3103 /* Set distance value. */
3104 rdistance
->distance
= distance
;
3106 /* Reset access-list configuration. */
3107 if (rdistance
->access_list
) {
3108 free(rdistance
->access_list
);
3109 rdistance
->access_list
= NULL
;
3111 if (access_list_str
)
3112 rdistance
->access_list
= strdup(access_list_str
);
3117 static int rip_distance_unset(struct vty
*vty
, const char *distance_str
,
3118 const char *ip_str
, const char *access_list_str
)
3121 struct prefix_ipv4 p
;
3122 struct route_node
*rn
;
3123 struct rip_distance
*rdistance
;
3125 ret
= str2prefix_ipv4(ip_str
, &p
);
3127 vty_out(vty
, "Malformed prefix\n");
3128 return CMD_WARNING_CONFIG_FAILED
;
3131 rn
= route_node_lookup(rip_distance_table
, (struct prefix
*)&p
);
3133 vty_out(vty
, "Can't find specified prefix\n");
3134 return CMD_WARNING_CONFIG_FAILED
;
3137 rdistance
= rn
->info
;
3139 if (rdistance
->access_list
)
3140 free(rdistance
->access_list
);
3141 rip_distance_free(rdistance
);
3144 route_unlock_node(rn
);
3145 route_unlock_node(rn
);
3150 static void rip_distance_reset(void)
3152 struct route_node
*rn
;
3153 struct rip_distance
*rdistance
;
3155 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
3156 if ((rdistance
= rn
->info
) != NULL
) {
3157 if (rdistance
->access_list
)
3158 free(rdistance
->access_list
);
3159 rip_distance_free(rdistance
);
3161 route_unlock_node(rn
);
3165 /* Apply RIP information to distance method. */
3166 uint8_t rip_distance_apply(struct rip_info
*rinfo
)
3168 struct route_node
*rn
;
3169 struct prefix_ipv4 p
;
3170 struct rip_distance
*rdistance
;
3171 struct access_list
*alist
;
3176 memset(&p
, 0, sizeof(struct prefix_ipv4
));
3178 p
.prefix
= rinfo
->from
;
3179 p
.prefixlen
= IPV4_MAX_BITLEN
;
3181 /* Check source address. */
3182 rn
= route_node_match(rip_distance_table
, (struct prefix
*)&p
);
3184 rdistance
= rn
->info
;
3185 route_unlock_node(rn
);
3187 if (rdistance
->access_list
) {
3188 alist
= access_list_lookup(AFI_IP
,
3189 rdistance
->access_list
);
3192 if (access_list_apply(alist
, &rinfo
->rp
->p
)
3196 return rdistance
->distance
;
3198 return rdistance
->distance
;
3202 return rip
->distance
;
3207 static void rip_distance_show(struct vty
*vty
)
3209 struct route_node
*rn
;
3210 struct rip_distance
*rdistance
;
3214 vty_out(vty
, " Distance: (default is %d)\n",
3215 rip
->distance
? rip
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
);
3217 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
3218 if ((rdistance
= rn
->info
) != NULL
) {
3221 " Address Distance List\n");
3224 sprintf(buf
, "%s/%d", inet_ntoa(rn
->p
.u
.prefix4
),
3226 vty_out(vty
, " %-20s %4d %s\n", buf
,
3227 rdistance
->distance
,
3228 rdistance
->access_list
? rdistance
->access_list
3233 DEFUN (rip_distance
,
3236 "Administrative distance\n"
3240 rip
->distance
= atoi(argv
[idx_number
]->arg
);
3244 DEFUN (no_rip_distance
,
3245 no_rip_distance_cmd
,
3246 "no distance (1-255)",
3248 "Administrative distance\n"
3255 DEFUN (rip_distance_source
,
3256 rip_distance_source_cmd
,
3257 "distance (1-255) A.B.C.D/M",
3258 "Administrative distance\n"
3260 "IP source prefix\n")
3263 int idx_ipv4_prefixlen
= 2;
3264 rip_distance_set(vty
, argv
[idx_number
]->arg
,
3265 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
3269 DEFUN (no_rip_distance_source
,
3270 no_rip_distance_source_cmd
,
3271 "no distance (1-255) A.B.C.D/M",
3273 "Administrative distance\n"
3275 "IP source prefix\n")
3278 int idx_ipv4_prefixlen
= 3;
3279 rip_distance_unset(vty
, argv
[idx_number
]->arg
,
3280 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
3284 DEFUN (rip_distance_source_access_list
,
3285 rip_distance_source_access_list_cmd
,
3286 "distance (1-255) A.B.C.D/M WORD",
3287 "Administrative distance\n"
3289 "IP source prefix\n"
3290 "Access list name\n")
3293 int idx_ipv4_prefixlen
= 2;
3295 rip_distance_set(vty
, argv
[idx_number
]->arg
,
3296 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
3300 DEFUN (no_rip_distance_source_access_list
,
3301 no_rip_distance_source_access_list_cmd
,
3302 "no distance (1-255) A.B.C.D/M WORD",
3304 "Administrative distance\n"
3306 "IP source prefix\n"
3307 "Access list name\n")
3310 int idx_ipv4_prefixlen
= 3;
3312 rip_distance_unset(vty
, argv
[idx_number
]->arg
,
3313 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
3317 /* Update ECMP routes to zebra when ECMP is disabled. */
3318 static void rip_ecmp_disable(void)
3320 struct route_node
*rp
;
3321 struct rip_info
*rinfo
, *tmp_rinfo
;
3323 struct listnode
*node
, *nextnode
;
3328 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3329 if ((list
= rp
->info
) != NULL
&& listcount(list
) > 1) {
3330 rinfo
= listgetdata(listhead(list
));
3331 if (!rip_route_rte(rinfo
))
3334 /* Drop all other entries, except the first one. */
3335 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
3336 if (tmp_rinfo
!= rinfo
) {
3337 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
3339 tmp_rinfo
->t_garbage_collect
);
3340 list_delete_node(list
, node
);
3341 rip_info_free(tmp_rinfo
);
3345 rip_zebra_ipv4_add(rp
);
3347 /* Set the route change flag. */
3348 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
3350 /* Signal the output process to trigger an update. */
3351 rip_event(RIP_TRIGGERED_UPDATE
, 0);
3355 DEFUN (rip_allow_ecmp
,
3358 "Allow Equal Cost MultiPath\n")
3361 vty_out(vty
, "ECMP is already enabled.\n");
3366 zlog_info("ECMP is enabled.");
3370 DEFUN (no_rip_allow_ecmp
,
3371 no_rip_allow_ecmp_cmd
,
3374 "Allow Equal Cost MultiPath\n")
3377 vty_out(vty
, "ECMP is already disabled.\n");
3382 zlog_info("ECMP is disabled.");
3387 /* Print out routes update time. */
3388 static void rip_vty_out_uptime(struct vty
*vty
, struct rip_info
*rinfo
)
3393 char timebuf
[TIME_BUF
];
3394 struct thread
*thread
;
3396 if ((thread
= rinfo
->t_timeout
) != NULL
) {
3397 clock
= thread_timer_remain_second(thread
);
3398 tm
= gmtime(&clock
);
3399 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
3400 vty_out(vty
, "%5s", timebuf
);
3401 } else if ((thread
= rinfo
->t_garbage_collect
) != NULL
) {
3402 clock
= thread_timer_remain_second(thread
);
3403 tm
= gmtime(&clock
);
3404 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
3405 vty_out(vty
, "%5s", timebuf
);
3409 static const char *rip_route_type_print(int sub_type
)
3414 case RIP_ROUTE_STATIC
:
3416 case RIP_ROUTE_DEFAULT
:
3418 case RIP_ROUTE_REDISTRIBUTE
:
3420 case RIP_ROUTE_INTERFACE
:
3432 "Show RIP routes\n")
3434 struct route_node
*np
;
3435 struct rip_info
*rinfo
= NULL
;
3436 struct list
*list
= NULL
;
3437 struct listnode
*listnode
= NULL
;
3443 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
3445 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
3446 " (i) - interface\n\n"
3447 " Network Next Hop Metric From Tag Time\n");
3449 for (np
= route_top(rip
->table
); np
; np
= route_next(np
))
3450 if ((list
= np
->info
) != NULL
)
3451 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3455 vty
, "%c(%s) %s/%d",
3456 /* np->lock, For debugging. */
3457 zebra_route_char(rinfo
->type
),
3458 rip_route_type_print(rinfo
->sub_type
),
3459 inet_ntoa(np
->p
.u
.prefix4
),
3465 vty_out(vty
, "%*s", len
, " ");
3467 switch (rinfo
->nh
.type
) {
3468 case NEXTHOP_TYPE_IPV4
:
3469 case NEXTHOP_TYPE_IPV4_IFINDEX
:
3470 vty_out(vty
, "%-20s %2d ",
3471 inet_ntoa(rinfo
->nh
.gate
.ipv4
),
3474 case NEXTHOP_TYPE_IFINDEX
:
3479 case NEXTHOP_TYPE_BLACKHOLE
:
3484 case NEXTHOP_TYPE_IPV6
:
3485 case NEXTHOP_TYPE_IPV6_IFINDEX
:
3487 "V6 Address Hidden %2d ",
3492 /* Route which exist in kernel routing table. */
3493 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
)
3494 && (rinfo
->sub_type
== RIP_ROUTE_RTE
)) {
3495 vty_out(vty
, "%-15s ",
3496 inet_ntoa(rinfo
->from
));
3497 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3498 (route_tag_t
)rinfo
->tag
);
3499 rip_vty_out_uptime(vty
, rinfo
);
3500 } else if (rinfo
->metric
3501 == RIP_METRIC_INFINITY
) {
3502 vty_out(vty
, "self ");
3503 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3504 (route_tag_t
)rinfo
->tag
);
3505 rip_vty_out_uptime(vty
, rinfo
);
3507 if (rinfo
->external_metric
) {
3509 vty
, "self (%s:%d)",
3512 rinfo
->external_metric
);
3515 vty_out(vty
, "%*s", len
,
3520 vty_out(vty
, "%3" ROUTE_TAG_PRI
,
3521 (route_tag_t
)rinfo
->tag
);
3529 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3530 DEFUN (show_ip_rip_status
,
3531 show_ip_rip_status_cmd
,
3532 "show ip rip status",
3536 "IP routing protocol process parameters and statistics\n")
3538 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3539 struct interface
*ifp
;
3540 struct rip_interface
*ri
;
3541 extern const struct message ri_version_msg
[];
3542 const char *send_version
;
3543 const char *receive_version
;
3548 vty_out(vty
, "Routing Protocol is \"rip\"\n");
3549 vty_out(vty
, " Sending updates every %ld seconds with +/-50%%,",
3551 vty_out(vty
, " next due in %lu seconds\n",
3552 thread_timer_remain_second(rip
->t_update
));
3553 vty_out(vty
, " Timeout after %ld seconds,", rip
->timeout_time
);
3554 vty_out(vty
, " garbage collect after %ld seconds\n", rip
->garbage_time
);
3556 /* Filtering status show. */
3557 config_show_distribute(vty
);
3559 /* Default metric information. */
3560 vty_out(vty
, " Default redistribution metric is %d\n",
3561 rip
->default_metric
);
3563 /* Redistribute information. */
3564 vty_out(vty
, " Redistributing:");
3565 config_write_rip_redistribute(vty
, 0);
3568 vty_out(vty
, " Default version control: send version %s,",
3569 lookup_msg(ri_version_msg
, rip
->version_send
, NULL
));
3570 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3571 vty_out(vty
, " receive any version \n");
3573 vty_out(vty
, " receive version %s \n",
3574 lookup_msg(ri_version_msg
, rip
->version_recv
, NULL
));
3576 vty_out(vty
, " Interface Send Recv Key-chain\n");
3578 FOR_ALL_INTERFACES (vrf
, ifp
) {
3584 if (ri
->enable_network
|| ri
->enable_interface
) {
3585 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3587 lookup_msg(ri_version_msg
,
3588 rip
->version_send
, NULL
);
3590 send_version
= lookup_msg(ri_version_msg
,
3593 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3595 lookup_msg(ri_version_msg
,
3596 rip
->version_recv
, NULL
);
3598 receive_version
= lookup_msg(
3599 ri_version_msg
, ri
->ri_receive
, NULL
);
3601 vty_out(vty
, " %-17s%-3s %-3s %s\n", ifp
->name
,
3602 send_version
, receive_version
,
3603 ri
->key_chain
? ri
->key_chain
: "");
3607 vty_out(vty
, " Routing for Networks:\n");
3608 config_write_rip_network(vty
, 0);
3611 int found_passive
= 0;
3612 FOR_ALL_INTERFACES (vrf
, ifp
) {
3615 if ((ri
->enable_network
|| ri
->enable_interface
)
3617 if (!found_passive
) {
3619 " Passive Interface(s):\n");
3622 vty_out(vty
, " %s\n", ifp
->name
);
3627 vty_out(vty
, " Routing Information Sources:\n");
3629 " Gateway BadPackets BadRoutes Distance Last Update\n");
3630 rip_peer_display(vty
);
3632 rip_distance_show(vty
);
3637 /* RIP configuration write function. */
3638 static int config_write_rip(struct vty
*vty
)
3641 struct route_node
*rn
;
3642 struct rip_distance
*rdistance
;
3645 /* Router RIP statement. */
3646 vty_out(vty
, "router rip\n");
3649 /* RIP version statement. Default is RIP version 2. */
3650 if (rip
->version_send
!= RI_RIP_VERSION_2
3651 || rip
->version_recv
!= RI_RIP_VERSION_1_AND_2
)
3652 vty_out(vty
, " version %d\n", rip
->version_send
);
3654 /* RIP timer configuration. */
3655 if (rip
->update_time
!= RIP_UPDATE_TIMER_DEFAULT
3656 || rip
->timeout_time
!= RIP_TIMEOUT_TIMER_DEFAULT
3657 || rip
->garbage_time
!= RIP_GARBAGE_TIMER_DEFAULT
)
3658 vty_out(vty
, " timers basic %lu %lu %lu\n",
3659 rip
->update_time
, rip
->timeout_time
,
3662 /* Default information configuration. */
3663 if (rip
->default_information
) {
3664 if (rip
->default_information_route_map
)
3666 " default-information originate route-map %s\n",
3667 rip
->default_information_route_map
);
3670 " default-information originate\n");
3673 /* Redistribute configuration. */
3674 config_write_rip_redistribute(vty
, 1);
3676 /* RIP offset-list configuration. */
3677 config_write_rip_offset_list(vty
);
3679 /* RIP enabled network and interface configuration. */
3680 config_write_rip_network(vty
, 1);
3682 /* RIP default metric configuration */
3683 if (rip
->default_metric
!= RIP_DEFAULT_METRIC_DEFAULT
)
3684 vty_out(vty
, " default-metric %d\n",
3685 rip
->default_metric
);
3687 /* Distribute configuration. */
3688 write
+= config_write_distribute(vty
);
3690 /* Interface routemap configuration */
3691 write
+= config_write_if_rmap(vty
);
3693 /* Distance configuration. */
3695 vty_out(vty
, " distance %d\n", rip
->distance
);
3697 /* RIP source IP prefix distance configuration. */
3698 for (rn
= route_top(rip_distance_table
); rn
;
3699 rn
= route_next(rn
))
3700 if ((rdistance
= rn
->info
) != NULL
)
3701 vty_out(vty
, " distance %d %s/%d %s\n",
3702 rdistance
->distance
,
3703 inet_ntoa(rn
->p
.u
.prefix4
),
3705 rdistance
->access_list
3706 ? rdistance
->access_list
3709 /* ECMP configuration. */
3711 vty_out(vty
, " allow-ecmp\n");
3713 /* RIP static route configuration. */
3714 for (rn
= route_top(rip
->route
); rn
; rn
= route_next(rn
))
3716 vty_out(vty
, " route %s/%d\n",
3717 inet_ntoa(rn
->p
.u
.prefix4
),
3723 /* RIP node structure. */
3724 static struct cmd_node rip_node
= {RIP_NODE
, "%s(config-router)# ", 1};
3726 /* Distribute-list update functions. */
3727 static void rip_distribute_update(struct distribute
*dist
)
3729 struct interface
*ifp
;
3730 struct rip_interface
*ri
;
3731 struct access_list
*alist
;
3732 struct prefix_list
*plist
;
3737 ifp
= if_lookup_by_name(dist
->ifname
, VRF_DEFAULT
);
3743 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
3744 alist
= access_list_lookup(AFI_IP
,
3745 dist
->list
[DISTRIBUTE_V4_IN
]);
3747 ri
->list
[RIP_FILTER_IN
] = alist
;
3749 ri
->list
[RIP_FILTER_IN
] = NULL
;
3751 ri
->list
[RIP_FILTER_IN
] = NULL
;
3753 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
3754 alist
= access_list_lookup(AFI_IP
,
3755 dist
->list
[DISTRIBUTE_V4_OUT
]);
3757 ri
->list
[RIP_FILTER_OUT
] = alist
;
3759 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3761 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3763 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
3764 plist
= prefix_list_lookup(AFI_IP
,
3765 dist
->prefix
[DISTRIBUTE_V4_IN
]);
3767 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3769 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3771 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3773 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
3774 plist
= prefix_list_lookup(AFI_IP
,
3775 dist
->prefix
[DISTRIBUTE_V4_OUT
]);
3777 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3779 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3781 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3784 void rip_distribute_update_interface(struct interface
*ifp
)
3786 struct distribute
*dist
;
3788 dist
= distribute_lookup(ifp
->name
);
3790 rip_distribute_update(dist
);
3793 /* Update all interface's distribute list. */
3795 static void rip_distribute_update_all(struct prefix_list
*notused
)
3797 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3798 struct interface
*ifp
;
3800 FOR_ALL_INTERFACES (vrf
, ifp
)
3801 rip_distribute_update_interface(ifp
);
3804 static void rip_distribute_update_all_wrapper(struct access_list
*notused
)
3806 rip_distribute_update_all(NULL
);
3809 /* Delete all added rip route. */
3810 void rip_clean(void)
3813 struct route_node
*rp
;
3814 struct rip_info
*rinfo
= NULL
;
3815 struct list
*list
= NULL
;
3816 struct listnode
*listnode
= NULL
;
3821 /* Clear RIP routes */
3822 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3823 if ((list
= rp
->info
) != NULL
) {
3824 rinfo
= listgetdata(listhead(list
));
3825 if (rip_route_rte(rinfo
))
3826 rip_zebra_ipv4_delete(rp
);
3828 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
3830 RIP_TIMER_OFF(rinfo
->t_timeout
);
3831 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
3832 rip_info_free(rinfo
);
3834 list_delete_and_null(&list
);
3836 route_unlock_node(rp
);
3839 /* Cancel RIP related timers. */
3840 RIP_TIMER_OFF(rip
->t_update
);
3841 RIP_TIMER_OFF(rip
->t_triggered_update
);
3842 RIP_TIMER_OFF(rip
->t_triggered_interval
);
3844 /* Cancel read thread. */
3845 THREAD_READ_OFF(rip
->t_read
);
3847 /* Close RIP socket. */
3848 if (rip
->sock
>= 0) {
3853 stream_free(rip
->obuf
);
3854 /* Static RIP route configuration. */
3855 for (rp
= route_top(rip
->route
); rp
; rp
= route_next(rp
))
3858 route_unlock_node(rp
);
3861 /* RIP neighbor configuration. */
3862 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
3865 route_unlock_node(rp
);
3868 /* Redistribute related clear. */
3869 if (rip
->default_information_route_map
)
3870 free(rip
->default_information_route_map
);
3872 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3873 if (rip
->route_map
[i
].name
)
3874 free(rip
->route_map
[i
].name
);
3876 XFREE(MTYPE_ROUTE_TABLE
, rip
->table
);
3877 XFREE(MTYPE_ROUTE_TABLE
, rip
->route
);
3878 XFREE(MTYPE_ROUTE_TABLE
, rip
->neighbor
);
3880 XFREE(MTYPE_RIP
, rip
);
3884 rip_clean_network();
3885 rip_passive_nondefault_clean();
3887 rip_interfaces_clean();
3888 rip_distance_reset();
3889 rip_redistribute_clean();
3892 /* Reset all values to the default settings. */
3893 void rip_reset(void)
3895 /* Reset global counters. */
3896 rip_global_route_changes
= 0;
3897 rip_global_queries
= 0;
3899 /* Call ripd related reset functions. */
3901 rip_route_map_reset();
3903 /* Call library reset functions. */
3905 access_list_reset();
3906 prefix_list_reset();
3908 distribute_list_reset();
3910 rip_interfaces_reset();
3911 rip_distance_reset();
3913 rip_zclient_reset();
3916 static void rip_if_rmap_update(struct if_rmap
*if_rmap
)
3918 struct interface
*ifp
;
3919 struct rip_interface
*ri
;
3920 struct route_map
*rmap
;
3922 ifp
= if_lookup_by_name(if_rmap
->ifname
, VRF_DEFAULT
);
3928 if (if_rmap
->routemap
[IF_RMAP_IN
]) {
3929 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_IN
]);
3931 ri
->routemap
[IF_RMAP_IN
] = rmap
;
3933 ri
->routemap
[IF_RMAP_IN
] = NULL
;
3935 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
3937 if (if_rmap
->routemap
[IF_RMAP_OUT
]) {
3938 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_OUT
]);
3940 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
3942 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
3944 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
3947 void rip_if_rmap_update_interface(struct interface
*ifp
)
3949 struct if_rmap
*if_rmap
;
3951 if_rmap
= if_rmap_lookup(ifp
->name
);
3953 rip_if_rmap_update(if_rmap
);
3956 static void rip_routemap_update_redistribute(void)
3961 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3962 if (rip
->route_map
[i
].name
)
3963 rip
->route_map
[i
].map
=
3964 route_map_lookup_by_name(
3965 rip
->route_map
[i
].name
);
3971 static void rip_routemap_update(const char *notused
)
3973 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3974 struct interface
*ifp
;
3976 FOR_ALL_INTERFACES (vrf
, ifp
)
3977 rip_if_rmap_update_interface(ifp
);
3979 rip_routemap_update_redistribute();
3982 /* Allocate new rip structure and set default value. */
3985 /* Install top nodes. */
3986 install_node(&rip_node
, config_write_rip
);
3988 /* Install rip commands. */
3989 install_element(VIEW_NODE
, &show_ip_rip_cmd
);
3990 install_element(VIEW_NODE
, &show_ip_rip_status_cmd
);
3991 install_element(CONFIG_NODE
, &router_rip_cmd
);
3992 install_element(CONFIG_NODE
, &no_router_rip_cmd
);
3994 install_default(RIP_NODE
);
3995 install_element(RIP_NODE
, &rip_version_cmd
);
3996 install_element(RIP_NODE
, &no_rip_version_cmd
);
3997 install_element(RIP_NODE
, &rip_default_metric_cmd
);
3998 install_element(RIP_NODE
, &no_rip_default_metric_cmd
);
3999 install_element(RIP_NODE
, &rip_timers_cmd
);
4000 install_element(RIP_NODE
, &no_rip_timers_cmd
);
4001 install_element(RIP_NODE
, &rip_route_cmd
);
4002 install_element(RIP_NODE
, &no_rip_route_cmd
);
4003 install_element(RIP_NODE
, &rip_distance_cmd
);
4004 install_element(RIP_NODE
, &no_rip_distance_cmd
);
4005 install_element(RIP_NODE
, &rip_distance_source_cmd
);
4006 install_element(RIP_NODE
, &no_rip_distance_source_cmd
);
4007 install_element(RIP_NODE
, &rip_distance_source_access_list_cmd
);
4008 install_element(RIP_NODE
, &no_rip_distance_source_access_list_cmd
);
4009 install_element(RIP_NODE
, &rip_allow_ecmp_cmd
);
4010 install_element(RIP_NODE
, &no_rip_allow_ecmp_cmd
);
4012 /* Debug related init. */
4015 /* Access list install. */
4017 access_list_add_hook(rip_distribute_update_all_wrapper
);
4018 access_list_delete_hook(rip_distribute_update_all_wrapper
);
4020 /* Prefix list initialize.*/
4022 prefix_list_add_hook(rip_distribute_update_all
);
4023 prefix_list_delete_hook(rip_distribute_update_all
);
4025 /* Distribute list install. */
4026 distribute_list_init(RIP_NODE
);
4027 distribute_list_add_hook(rip_distribute_update
);
4028 distribute_list_delete_hook(rip_distribute_update
);
4031 rip_route_map_init();
4034 route_map_add_hook(rip_routemap_update
);
4035 route_map_delete_hook(rip_routemap_update
);
4037 if_rmap_init(RIP_NODE
);
4038 if_rmap_hook_add(rip_if_rmap_update
);
4039 if_rmap_hook_delete(rip_if_rmap_update
);
4041 /* Distance control. */
4042 rip_distance_table
= route_table_init();