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"
44 #include "northbound_cli.h"
46 #include "ripd/ripd.h"
47 #include "ripd/rip_debug.h"
48 #include "ripd/rip_errors.h"
52 /* UDP receive buffer size */
53 #define RIP_UDP_RCV_BUF 41600
56 struct rip
*rip
= NULL
;
58 /* RIP neighbor address table. */
59 struct route_table
*rip_neighbor_table
;
61 /* RIP route changes. */
62 long rip_global_route_changes
= 0;
65 long rip_global_queries
= 0;
68 static void rip_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((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
)) {
1061 "rip_auth_md5_set(): packet length %ld is less than minimum length.",
1066 /* Set the digest offset length in the header */
1067 stream_putw_at(s
, doff
, len
);
1069 /* Set authentication data. */
1070 stream_putw(s
, RIP_FAMILY_AUTH
);
1071 stream_putw(s
, RIP_AUTH_DATA
);
1073 /* Generate a digest for the RIP packet. */
1074 memset(&ctx
, 0, sizeof(ctx
));
1076 MD5Update(&ctx
, STREAM_DATA(s
), stream_get_endp(s
));
1077 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1078 MD5Final(digest
, &ctx
);
1080 /* Copy the digest to the packet. */
1081 stream_write(s
, digest
, RIP_AUTH_MD5_SIZE
);
1084 /* RIP routing information. */
1085 static void rip_response_process(struct rip_packet
*packet
, int size
,
1086 struct sockaddr_in
*from
,
1087 struct connected
*ifc
)
1091 struct prefix_ipv4 ifaddr
;
1092 struct prefix_ipv4 ifaddrclass
;
1095 memset(&ifaddr
, 0, sizeof(ifaddr
));
1096 /* We don't know yet. */
1099 /* The Response must be ignored if it is not from the RIP
1100 port. (RFC2453 - Sec. 3.9.2)*/
1101 if (from
->sin_port
!= htons(RIP_PORT_DEFAULT
)) {
1102 zlog_info("response doesn't come from RIP port: %d",
1104 rip_peer_bad_packet(from
);
1108 /* The datagram's IPv4 source address should be checked to see
1109 whether the datagram is from a valid neighbor; the source of the
1110 datagram must be on a directly connected network (RFC2453 - Sec.
1112 if (if_lookup_address((void *)&from
->sin_addr
, AF_INET
, VRF_DEFAULT
)
1115 "This datagram doesn't came from a valid neighbor: %s",
1116 inet_ntoa(from
->sin_addr
));
1117 rip_peer_bad_packet(from
);
1121 /* It is also worth checking to see whether the response is from one
1122 of the router's own addresses. */
1124 ; /* Alredy done in rip_read () */
1126 /* Update RIP peer. */
1127 rip_peer_update(from
, packet
->version
);
1129 /* Set RTE pointer. */
1132 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
1133 /* RIPv2 authentication check. */
1134 /* If the Address Family Identifier of the first (and only the
1135 first) entry in the message is 0xFFFF, then the remainder of
1136 the entry contains the authentication. */
1137 /* If the packet gets here it means authentication enabled */
1138 /* Check is done in rip_read(). So, just skipping it */
1139 if (packet
->version
== RIPv2
&& rte
== packet
->rte
1140 && rte
->family
== htons(RIP_FAMILY_AUTH
))
1143 if (rte
->family
!= htons(AF_INET
)) {
1144 /* Address family check. RIP only supports AF_INET. */
1145 zlog_info("Unsupported family %d from %s.",
1147 inet_ntoa(from
->sin_addr
));
1151 /* - is the destination address valid (e.g., unicast; not net 0
1153 if (!rip_destination_check(rte
->prefix
)) {
1155 "Network is net 0 or net 127 or it is not unicast network");
1156 rip_peer_bad_route(from
);
1160 /* Convert metric value to host byte order. */
1161 rte
->metric
= ntohl(rte
->metric
);
1163 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1164 if (!(rte
->metric
>= 1 && rte
->metric
<= 16)) {
1165 zlog_info("Route's metric is not in the 1-16 range.");
1166 rip_peer_bad_route(from
);
1170 /* RIPv1 does not have nexthop value. */
1171 if (packet
->version
== RIPv1
&& rte
->nexthop
.s_addr
!= 0) {
1172 zlog_info("RIPv1 packet with nexthop value %s",
1173 inet_ntoa(rte
->nexthop
));
1174 rip_peer_bad_route(from
);
1178 /* That is, if the provided information is ignored, a possibly
1179 sub-optimal, but absolutely valid, route may be taken. If
1180 the received Next Hop is not directly reachable, it should be
1181 treated as 0.0.0.0. */
1182 if (packet
->version
== RIPv2
&& rte
->nexthop
.s_addr
!= 0) {
1185 /* Multicast address check. */
1186 addrval
= ntohl(rte
->nexthop
.s_addr
);
1187 if (IN_CLASSD(addrval
)) {
1189 "Nexthop %s is multicast address, skip this rte",
1190 inet_ntoa(rte
->nexthop
));
1194 if (!if_lookup_address((void *)&rte
->nexthop
, AF_INET
,
1196 struct route_node
*rn
;
1197 struct rip_info
*rinfo
;
1199 rn
= route_node_match_ipv4(rip
->table
,
1205 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1208 if (IS_RIP_DEBUG_EVENT
)
1210 "Next hop %s is on RIP network. Set nexthop to the packet's originator",
1213 rte
->nexthop
= rinfo
->from
;
1215 if (IS_RIP_DEBUG_EVENT
)
1217 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1220 rte
->nexthop
.s_addr
= 0;
1223 route_unlock_node(rn
);
1225 if (IS_RIP_DEBUG_EVENT
)
1227 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1230 rte
->nexthop
.s_addr
= 0;
1235 /* For RIPv1, there won't be a valid netmask.
1237 This is a best guess at the masks. If everyone was using old
1238 Ciscos before the 'ip subnet zero' option, it would be almost
1241 Cisco summarize ripv1 advertisements to the classful boundary
1242 (/16 for class B's) except when the RIP packet does to inside
1243 the classful network in question. */
1245 if ((packet
->version
== RIPv1
&& rte
->prefix
.s_addr
!= 0)
1246 || (packet
->version
== RIPv2
1247 && (rte
->prefix
.s_addr
!= 0
1248 && rte
->mask
.s_addr
== 0))) {
1249 uint32_t destination
;
1251 if (subnetted
== -1) {
1252 memcpy(&ifaddr
, ifc
->address
,
1253 sizeof(struct prefix_ipv4
));
1254 memcpy(&ifaddrclass
, &ifaddr
,
1255 sizeof(struct prefix_ipv4
));
1256 apply_classful_mask_ipv4(&ifaddrclass
);
1258 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1262 destination
= ntohl(rte
->prefix
.s_addr
);
1264 if (IN_CLASSA(destination
))
1265 masklen2ip(8, &rte
->mask
);
1266 else if (IN_CLASSB(destination
))
1267 masklen2ip(16, &rte
->mask
);
1268 else if (IN_CLASSC(destination
))
1269 masklen2ip(24, &rte
->mask
);
1272 masklen2ip(ifaddrclass
.prefixlen
,
1273 (struct in_addr
*)&destination
);
1274 if ((subnetted
== 1)
1275 && ((rte
->prefix
.s_addr
& destination
)
1276 == ifaddrclass
.prefix
.s_addr
)) {
1277 masklen2ip(ifaddr
.prefixlen
, &rte
->mask
);
1278 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1279 != rte
->prefix
.s_addr
)
1280 masklen2ip(32, &rte
->mask
);
1281 if (IS_RIP_DEBUG_EVENT
)
1282 zlog_debug("Subnetted route %s",
1283 inet_ntoa(rte
->prefix
));
1285 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1286 != rte
->prefix
.s_addr
)
1290 if (IS_RIP_DEBUG_EVENT
) {
1291 zlog_debug("Resultant route %s",
1292 inet_ntoa(rte
->prefix
));
1293 zlog_debug("Resultant mask %s",
1294 inet_ntoa(rte
->mask
));
1298 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1299 ignore the entry. */
1300 if ((packet
->version
== RIPv2
) && (rte
->mask
.s_addr
!= 0)
1301 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1302 != rte
->prefix
.s_addr
)) {
1304 "RIPv2 address %s is not mask /%d applied one",
1305 inet_ntoa(rte
->prefix
), ip_masklen(rte
->mask
));
1306 rip_peer_bad_route(from
);
1310 /* Default route's netmask is ignored. */
1311 if (packet
->version
== RIPv2
&& (rte
->prefix
.s_addr
== 0)
1312 && (rte
->mask
.s_addr
!= 0)) {
1313 if (IS_RIP_DEBUG_EVENT
)
1315 "Default route with non-zero netmask. Set zero to netmask");
1316 rte
->mask
.s_addr
= 0;
1319 /* Routing table updates. */
1320 rip_rte_process(rte
, from
, ifc
->ifp
);
1324 /* Make socket for RIP protocol. */
1325 int rip_create_socket(void)
1329 struct sockaddr_in addr
;
1331 memset(&addr
, 0, sizeof(struct sockaddr_in
));
1332 addr
.sin_family
= AF_INET
;
1333 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1334 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1335 addr
.sin_len
= sizeof(struct sockaddr_in
);
1336 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1337 /* sending port must always be the RIP port */
1338 addr
.sin_port
= htons(RIP_PORT_DEFAULT
);
1340 /* Make datagram socket. */
1341 sock
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
1343 flog_err_sys(EC_LIB_SOCKET
, "Cannot create UDP socket: %s",
1344 safe_strerror(errno
));
1348 sockopt_broadcast(sock
);
1349 sockopt_reuseaddr(sock
);
1350 sockopt_reuseport(sock
);
1351 setsockopt_ipv4_multicast_loop(sock
, 0);
1353 setsockopt_pktinfo(sock
);
1354 #endif /* RIP_RECVMSG */
1355 #ifdef IPTOS_PREC_INTERNETCONTROL
1356 setsockopt_ipv4_tos(sock
, IPTOS_PREC_INTERNETCONTROL
);
1359 frr_elevate_privs(&ripd_privs
) {
1360 setsockopt_so_recvbuf(sock
, RIP_UDP_RCV_BUF
);
1361 if ((ret
= bind(sock
, (struct sockaddr
*)&addr
, sizeof(addr
)))
1363 zlog_err("%s: Can't bind socket %d to %s port %d: %s",
1364 __func__
, sock
, inet_ntoa(addr
.sin_addr
),
1365 (int)ntohs(addr
.sin_port
),
1366 safe_strerror(errno
));
1376 /* RIP packet send to destination address, on interface denoted by
1377 * by connected argument. NULL to argument denotes destination should be
1378 * should be RIP multicast group
1380 static int rip_send_packet(uint8_t *buf
, int size
, struct sockaddr_in
*to
,
1381 struct connected
*ifc
)
1384 struct sockaddr_in sin
;
1386 assert(ifc
!= NULL
);
1388 if (IS_RIP_DEBUG_PACKET
) {
1389 #define ADDRESS_SIZE 20
1390 char dst
[ADDRESS_SIZE
];
1391 dst
[ADDRESS_SIZE
- 1] = '\0';
1394 strncpy(dst
, inet_ntoa(to
->sin_addr
), ADDRESS_SIZE
- 1);
1396 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1397 strncpy(dst
, inet_ntoa(sin
.sin_addr
), ADDRESS_SIZE
- 1);
1400 zlog_debug("rip_send_packet %s > %s (%s)",
1401 inet_ntoa(ifc
->address
->u
.prefix4
), dst
,
1405 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
1407 * ZEBRA_IFA_SECONDARY is set on linux when an interface is
1409 * with multiple addresses on the same subnet: the first address
1410 * on the subnet is configured "primary", and all subsequent
1412 * on that subnet are treated as "secondary" addresses.
1413 * In order to avoid routing-table bloat on other rip listeners,
1414 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY
1416 * XXX Since Linux is the only system for which the
1417 * ZEBRA_IFA_SECONDARY
1418 * flag is set, we would end up sending a packet for a
1420 * source address on non-linux systems.
1422 if (IS_RIP_DEBUG_PACKET
)
1423 zlog_debug("duplicate dropped");
1427 /* Make destination address. */
1428 memset(&sin
, 0, sizeof(struct sockaddr_in
));
1429 sin
.sin_family
= AF_INET
;
1430 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1431 sin
.sin_len
= sizeof(struct sockaddr_in
);
1432 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1434 /* When destination is specified, use it's port and address. */
1436 sin
.sin_port
= to
->sin_port
;
1437 sin
.sin_addr
= to
->sin_addr
;
1439 sin
.sin_port
= htons(RIP_PORT_DEFAULT
);
1440 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1442 rip_interface_multicast_set(rip
->sock
, ifc
);
1445 ret
= sendto(rip
->sock
, buf
, size
, 0, (struct sockaddr
*)&sin
,
1446 sizeof(struct sockaddr_in
));
1448 if (IS_RIP_DEBUG_EVENT
)
1449 zlog_debug("SEND to %s.%d", inet_ntoa(sin
.sin_addr
),
1450 ntohs(sin
.sin_port
));
1453 zlog_warn("can't send packet : %s", safe_strerror(errno
));
1458 /* Add redistributed route to RIP table. */
1459 void rip_redistribute_add(int type
, int sub_type
, struct prefix_ipv4
*p
,
1460 struct nexthop
*nh
, unsigned int metric
,
1461 unsigned char distance
, route_tag_t tag
)
1464 struct route_node
*rp
= NULL
;
1465 struct rip_info
*rinfo
= NULL
, newinfo
;
1466 struct list
*list
= NULL
;
1468 /* Redistribute route */
1469 ret
= rip_destination_check(p
->prefix
);
1473 rp
= route_node_get(rip
->table
, (struct prefix
*)p
);
1475 memset(&newinfo
, 0, sizeof(struct rip_info
));
1476 newinfo
.type
= type
;
1477 newinfo
.sub_type
= sub_type
;
1479 newinfo
.external_metric
= metric
;
1480 newinfo
.distance
= distance
;
1481 if (tag
<= UINT16_MAX
) /* RIP only supports 16 bit tags */
1486 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
1487 rinfo
= listgetdata(listhead(list
));
1489 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
1490 && rinfo
->sub_type
== RIP_ROUTE_INTERFACE
1491 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
1492 route_unlock_node(rp
);
1496 /* Manually configured RIP route check. */
1497 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1498 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
1499 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))) {
1500 if (type
!= ZEBRA_ROUTE_RIP
1501 || ((sub_type
!= RIP_ROUTE_STATIC
)
1502 && (sub_type
!= RIP_ROUTE_DEFAULT
))) {
1503 route_unlock_node(rp
);
1508 (void)rip_ecmp_replace(&newinfo
);
1509 route_unlock_node(rp
);
1511 (void)rip_ecmp_add(&newinfo
);
1513 if (IS_RIP_DEBUG_EVENT
) {
1514 zlog_debug("Redistribute new prefix %s/%d",
1515 inet_ntoa(p
->prefix
), p
->prefixlen
);
1518 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1521 /* Delete redistributed route from RIP table. */
1522 void rip_redistribute_delete(int type
, int sub_type
, struct prefix_ipv4
*p
,
1526 struct route_node
*rp
;
1527 struct rip_info
*rinfo
;
1529 ret
= rip_destination_check(p
->prefix
);
1533 rp
= route_node_lookup(rip
->table
, (struct prefix
*)p
);
1535 struct list
*list
= rp
->info
;
1537 if (list
!= NULL
&& listcount(list
) != 0) {
1538 rinfo
= listgetdata(listhead(list
));
1539 if (rinfo
!= NULL
&& rinfo
->type
== type
1540 && rinfo
->sub_type
== sub_type
1541 && rinfo
->nh
.ifindex
== ifindex
) {
1542 /* Perform poisoned reverse. */
1543 rinfo
->metric
= RIP_METRIC_INFINITY
;
1544 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
1545 rip_garbage_collect
,
1547 RIP_TIMER_OFF(rinfo
->t_timeout
);
1548 rinfo
->flags
|= RIP_RTF_CHANGED
;
1550 if (IS_RIP_DEBUG_EVENT
)
1552 "Poison %s/%d on the interface %s with an "
1553 "infinity metric [delete]",
1554 inet_ntoa(p
->prefix
),
1556 ifindex2ifname(ifindex
,
1559 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1562 route_unlock_node(rp
);
1566 /* Response to request called from rip_read ().*/
1567 static void rip_request_process(struct rip_packet
*packet
, int size
,
1568 struct sockaddr_in
*from
, struct connected
*ifc
)
1572 struct prefix_ipv4 p
;
1573 struct route_node
*rp
;
1574 struct rip_info
*rinfo
;
1575 struct rip_interface
*ri
;
1577 /* Does not reponse to the requests on the loopback interfaces */
1578 if (if_is_loopback(ifc
->ifp
))
1581 /* Check RIP process is enabled on this interface. */
1582 ri
= ifc
->ifp
->info
;
1586 /* When passive interface is specified, suppress responses */
1590 /* RIP peer update. */
1591 rip_peer_update(from
, packet
->version
);
1593 lim
= ((caddr_t
)packet
) + size
;
1596 /* The Request is processed entry by entry. If there are no
1597 entries, no response is given. */
1598 if (lim
== (caddr_t
)rte
)
1601 /* There is one special case. If there is exactly one entry in the
1602 request, and it has an address family identifier of zero and a
1603 metric of infinity (i.e., 16), then this is a request to send the
1604 entire routing table. */
1605 if (lim
== ((caddr_t
)(rte
+ 1)) && ntohs(rte
->family
) == 0
1606 && ntohl(rte
->metric
) == RIP_METRIC_INFINITY
) {
1607 /* All route with split horizon */
1608 rip_output_process(ifc
, from
, rip_all_route
, packet
->version
);
1610 if (ntohs(rte
->family
) != AF_INET
)
1613 /* Examine the list of RTEs in the Request one by one. For each
1614 entry, look up the destination in the router's routing
1615 database and, if there is a route, put that route's metric in
1616 the metric field of the RTE. If there is no explicit route
1617 to the specified destination, put infinity in the metric
1618 field. Once all the entries have been filled in, change the
1619 command from Request to Response and send the datagram back
1620 to the requestor. */
1623 for (; ((caddr_t
)rte
) < lim
; rte
++) {
1624 p
.prefix
= rte
->prefix
;
1625 p
.prefixlen
= ip_masklen(rte
->mask
);
1626 apply_mask_ipv4(&p
);
1628 rp
= route_node_lookup(rip
->table
, (struct prefix
*)&p
);
1630 rinfo
= listgetdata(
1631 listhead((struct list
*)rp
->info
));
1632 rte
->metric
= htonl(rinfo
->metric
);
1633 route_unlock_node(rp
);
1635 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
1637 packet
->command
= RIP_RESPONSE
;
1639 (void)rip_send_packet((uint8_t *)packet
, size
, from
, ifc
);
1641 rip_global_queries
++;
1645 /* Set IPv6 packet info to the socket. */
1646 static int setsockopt_pktinfo(int sock
)
1651 ret
= setsockopt(sock
, IPPROTO_IP
, IP_PKTINFO
, &val
, sizeof(val
));
1653 zlog_warn("Can't setsockopt IP_PKTINFO : %s",
1654 safe_strerror(errno
));
1658 /* Read RIP packet by recvmsg function. */
1659 int rip_recvmsg(int sock
, uint8_t *buf
, int size
, struct sockaddr_in
*from
,
1665 struct cmsghdr
*ptr
;
1668 memset(&msg
, 0, sizeof(msg
));
1669 msg
.msg_name
= (void *)from
;
1670 msg
.msg_namelen
= sizeof(struct sockaddr_in
);
1673 msg
.msg_control
= (void *)adata
;
1674 msg
.msg_controllen
= sizeof adata
;
1678 ret
= recvmsg(sock
, &msg
, 0);
1682 for (ptr
= ZCMSG_FIRSTHDR(&msg
); ptr
!= NULL
;
1683 ptr
= CMSG_NXTHDR(&msg
, ptr
))
1684 if (ptr
->cmsg_level
== IPPROTO_IP
1685 && ptr
->cmsg_type
== IP_PKTINFO
) {
1686 struct in_pktinfo
*pktinfo
;
1689 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(ptr
);
1690 i
= pktinfo
->ipi_ifindex
;
1695 /* RIP packet read function. */
1696 int rip_read_new(struct thread
*t
)
1700 char buf
[RIP_PACKET_MAXSIZ
];
1701 struct sockaddr_in from
;
1704 /* Fetch socket then register myself. */
1705 sock
= THREAD_FD(t
);
1706 rip_event(RIP_READ
, sock
);
1708 /* Read RIP packet. */
1709 ret
= rip_recvmsg(sock
, buf
, RIP_PACKET_MAXSIZ
, &from
, (int *)&ifindex
);
1711 zlog_warn("Can't read RIP packet: %s", safe_strerror(errno
));
1717 #endif /* RIP_RECVMSG */
1719 /* First entry point of RIP packet. */
1720 static int rip_read(struct thread
*t
)
1725 union rip_buf rip_buf
;
1726 struct rip_packet
*packet
;
1727 struct sockaddr_in from
;
1731 struct interface
*ifp
= NULL
;
1732 struct connected
*ifc
;
1733 struct rip_interface
*ri
;
1736 /* Fetch socket then register myself. */
1737 sock
= THREAD_FD(t
);
1740 /* Add myself to tne next event */
1741 rip_event(RIP_READ
, sock
);
1743 /* RIPd manages only IPv4. */
1744 memset(&from
, 0, sizeof(struct sockaddr_in
));
1745 fromlen
= sizeof(struct sockaddr_in
);
1747 len
= recvfrom(sock
, (char *)&rip_buf
.buf
, sizeof(rip_buf
.buf
), 0,
1748 (struct sockaddr
*)&from
, &fromlen
);
1750 zlog_info("recvfrom failed: %s", safe_strerror(errno
));
1754 /* Check is this packet comming from myself? */
1755 if (if_check_address(from
.sin_addr
)) {
1756 if (IS_RIP_DEBUG_PACKET
)
1757 zlog_debug("ignore packet comes from myself");
1761 /* Which interface is this packet comes from. */
1762 ifc
= if_lookup_address((void *)&from
.sin_addr
, AF_INET
, VRF_DEFAULT
);
1766 /* RIP packet received */
1767 if (IS_RIP_DEBUG_EVENT
)
1768 zlog_debug("RECV packet from %s port %d on %s",
1769 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1770 ifp
? ifp
->name
: "unknown");
1772 /* If this packet come from unknown interface, ignore it. */
1775 "rip_read: cannot find interface for packet from %s port %d",
1776 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
));
1781 p
.u
.prefix4
= from
.sin_addr
;
1782 p
.prefixlen
= IPV4_MAX_BITLEN
;
1784 ifc
= connected_lookup_prefix(ifp
, &p
);
1788 "rip_read: cannot find connected address for packet from %s "
1789 "port %d on interface %s",
1790 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1795 /* Packet length check. */
1796 if (len
< RIP_PACKET_MINSIZ
) {
1797 zlog_warn("packet size %d is smaller than minimum size %d", len
,
1799 rip_peer_bad_packet(&from
);
1802 if (len
> RIP_PACKET_MAXSIZ
) {
1803 zlog_warn("packet size %d is larger than max size %d", len
,
1805 rip_peer_bad_packet(&from
);
1809 /* Packet alignment check. */
1810 if ((len
- RIP_PACKET_MINSIZ
) % 20) {
1811 zlog_warn("packet size %d is wrong for RIP packet alignment",
1813 rip_peer_bad_packet(&from
);
1817 /* Set RTE number. */
1818 rtenum
= ((len
- RIP_PACKET_MINSIZ
) / 20);
1820 /* For easy to handle. */
1821 packet
= &rip_buf
.rip_packet
;
1823 /* RIP version check. */
1824 if (packet
->version
== 0) {
1825 zlog_info("version 0 with command %d received.",
1827 rip_peer_bad_packet(&from
);
1831 /* Dump RIP packet. */
1832 if (IS_RIP_DEBUG_RECV
)
1833 rip_packet_dump(packet
, len
, "RECV");
1835 /* RIP version adjust. This code should rethink now. RFC1058 says
1836 that "Version 1 implementations are to ignore this extra data and
1837 process only the fields specified in this document.". So RIPv3
1838 packet should be treated as RIPv1 ignoring must be zero field. */
1839 if (packet
->version
> RIPv2
)
1840 packet
->version
= RIPv2
;
1842 /* Is RIP running or is this RIP neighbor ?*/
1844 if (!ri
->running
&& !rip_neighbor_lookup(&from
)) {
1845 if (IS_RIP_DEBUG_EVENT
)
1846 zlog_debug("RIP is not enabled on interface %s.",
1848 rip_peer_bad_packet(&from
);
1852 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1853 vrecv
= ((ri
->ri_receive
== RI_RIP_UNSPEC
) ? rip
->version_recv
1855 if (vrecv
== RI_RIP_VERSION_NONE
1856 || ((packet
->version
== RIPv1
) && !(vrecv
& RIPv1
))
1857 || ((packet
->version
== RIPv2
) && !(vrecv
& RIPv2
))) {
1858 if (IS_RIP_DEBUG_PACKET
)
1860 " packet's v%d doesn't fit to if version spec",
1862 rip_peer_bad_packet(&from
);
1866 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1867 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1868 accepted; authenticated RIP-2 messages shall be discarded. */
1869 if ((ri
->auth_type
== RIP_NO_AUTH
) && rtenum
1870 && (packet
->version
== RIPv2
)
1871 && (packet
->rte
->family
== htons(RIP_FAMILY_AUTH
))) {
1872 if (IS_RIP_DEBUG_EVENT
)
1874 "packet RIPv%d is dropped because authentication disabled",
1876 rip_peer_bad_packet(&from
);
1881 If the router is configured to authenticate RIP-2 messages, then
1882 RIP-1 messages and RIP-2 messages which pass authentication
1883 testing shall be accepted; unauthenticated and failed
1884 authentication RIP-2 messages shall be discarded. For maximum
1885 security, RIP-1 messages should be ignored when authentication is
1886 in use (see section 4.1); otherwise, the routing information from
1887 authenticated messages will be propagated by RIP-1 routers in an
1888 unauthenticated manner.
1890 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1891 * always reply regardless of authentication settings, because:
1893 * - if there other authorised routers on-link, the REQUESTor can
1894 * passively obtain the routing updates anyway
1895 * - if there are no other authorised routers on-link, RIP can
1896 * easily be disabled for the link to prevent giving out information
1897 * on state of this routers RIP routing table..
1899 * I.e. if RIPv1 has any place anymore these days, it's as a very
1900 * simple way to distribute routing information (e.g. to embedded
1901 * hosts / appliances) and the ability to give out RIPv1
1902 * routing-information freely, while still requiring RIPv2
1903 * authentication for any RESPONSEs might be vaguely useful.
1905 if (ri
->auth_type
!= RIP_NO_AUTH
&& packet
->version
== RIPv1
) {
1906 /* Discard RIPv1 messages other than REQUESTs */
1907 if (packet
->command
!= RIP_REQUEST
) {
1908 if (IS_RIP_DEBUG_PACKET
)
1911 " dropped because authentication enabled");
1912 rip_peer_bad_packet(&from
);
1915 } else if (ri
->auth_type
!= RIP_NO_AUTH
) {
1916 const char *auth_desc
;
1919 /* There definitely is no authentication in the packet.
1921 if (IS_RIP_DEBUG_PACKET
)
1923 "RIPv2 authentication failed: no auth RTE in packet");
1924 rip_peer_bad_packet(&from
);
1928 /* First RTE must be an Authentication Family RTE */
1929 if (packet
->rte
->family
!= htons(RIP_FAMILY_AUTH
)) {
1930 if (IS_RIP_DEBUG_PACKET
)
1933 " dropped because authentication enabled");
1934 rip_peer_bad_packet(&from
);
1938 /* Check RIPv2 authentication. */
1939 switch (ntohs(packet
->rte
->tag
)) {
1940 case RIP_AUTH_SIMPLE_PASSWORD
:
1941 auth_desc
= "simple";
1942 ret
= rip_auth_simple_password(packet
->rte
, &from
, ifp
);
1947 ret
= rip_auth_md5(packet
, &from
, len
, ifp
);
1948 /* Reset RIP packet length to trim MD5 data. */
1954 auth_desc
= "unknown type";
1955 if (IS_RIP_DEBUG_PACKET
)
1957 "RIPv2 Unknown authentication type %d",
1958 ntohs(packet
->rte
->tag
));
1962 if (IS_RIP_DEBUG_PACKET
)
1963 zlog_debug("RIPv2 %s authentication success",
1966 if (IS_RIP_DEBUG_PACKET
)
1967 zlog_debug("RIPv2 %s authentication failure",
1969 rip_peer_bad_packet(&from
);
1974 /* Process each command. */
1975 switch (packet
->command
) {
1977 rip_response_process(packet
, len
, &from
, ifc
);
1981 rip_request_process(packet
, len
, &from
, ifc
);
1986 "Obsolete command %s received, please sent it to routed",
1987 lookup_msg(rip_msg
, packet
->command
, NULL
));
1988 rip_peer_bad_packet(&from
);
1990 case RIP_POLL_ENTRY
:
1991 zlog_info("Obsolete command %s received",
1992 lookup_msg(rip_msg
, packet
->command
, NULL
));
1993 rip_peer_bad_packet(&from
);
1996 zlog_info("Unknown RIP command %d received", packet
->command
);
1997 rip_peer_bad_packet(&from
);
2004 /* Write routing table entry to the stream and return next index of
2005 the routing table entry in the stream. */
2006 static int rip_write_rte(int num
, struct stream
*s
, struct prefix_ipv4
*p
,
2007 uint8_t version
, struct rip_info
*rinfo
)
2009 struct in_addr mask
;
2011 /* Write routing table entry. */
2012 if (version
== RIPv1
) {
2013 stream_putw(s
, AF_INET
);
2015 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2016 stream_put_ipv4(s
, 0);
2017 stream_put_ipv4(s
, 0);
2018 stream_putl(s
, rinfo
->metric_out
);
2020 masklen2ip(p
->prefixlen
, &mask
);
2022 stream_putw(s
, AF_INET
);
2023 stream_putw(s
, rinfo
->tag_out
);
2024 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2025 stream_put_ipv4(s
, mask
.s_addr
);
2026 stream_put_ipv4(s
, rinfo
->nexthop_out
.s_addr
);
2027 stream_putl(s
, rinfo
->metric_out
);
2033 /* Send update to the ifp or spcified neighbor. */
2034 void rip_output_process(struct connected
*ifc
, struct sockaddr_in
*to
,
2035 int route_type
, uint8_t version
)
2039 struct route_node
*rp
;
2040 struct rip_info
*rinfo
;
2041 struct rip_interface
*ri
;
2042 struct prefix_ipv4
*p
;
2043 struct prefix_ipv4 classfull
;
2044 struct prefix_ipv4 ifaddrclass
;
2045 struct key
*key
= NULL
;
2046 /* this might need to made dynamic if RIP ever supported auth methods
2047 with larger key string sizes */
2048 char auth_str
[RIP_AUTH_SIMPLE_SIZE
];
2049 size_t doff
= 0; /* offset of digest offset field */
2053 struct list
*list
= NULL
;
2054 struct listnode
*listnode
= NULL
;
2056 /* Logging output event. */
2057 if (IS_RIP_DEBUG_EVENT
) {
2059 zlog_debug("update routes to neighbor %s",
2060 inet_ntoa(to
->sin_addr
));
2062 zlog_debug("update routes on interface %s ifindex %d",
2063 ifc
->ifp
->name
, ifc
->ifp
->ifindex
);
2066 /* Set output stream. */
2069 /* Reset stream and RTE counter. */
2071 rtemax
= RIP_MAX_RTE
;
2073 /* Get RIP interface. */
2074 ri
= ifc
->ifp
->info
;
2076 /* If output interface is in simple password authentication mode, we
2077 need space for authentication data. */
2078 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2081 /* If output interface is in MD5 authentication mode, we need space
2082 for authentication header and data. */
2083 if (ri
->auth_type
== RIP_AUTH_MD5
)
2086 /* If output interface is in simple password authentication mode
2087 and string or keychain is specified we need space for auth. data */
2088 if (ri
->auth_type
!= RIP_NO_AUTH
) {
2089 if (ri
->key_chain
) {
2090 struct keychain
*keychain
;
2092 keychain
= keychain_lookup(ri
->key_chain
);
2094 key
= key_lookup_for_send(keychain
);
2096 /* to be passed to auth functions later */
2097 rip_auth_prepare_str_send(ri
, key
, auth_str
,
2098 RIP_AUTH_SIMPLE_SIZE
);
2099 if (strlen(auth_str
) == 0)
2103 if (version
== RIPv1
) {
2104 memcpy(&ifaddrclass
, ifc
->address
, sizeof(struct prefix_ipv4
));
2105 apply_classful_mask_ipv4(&ifaddrclass
);
2107 if (ifc
->address
->prefixlen
> ifaddrclass
.prefixlen
)
2111 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2112 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
2113 rinfo
= listgetdata(listhead(list
));
2114 /* For RIPv1, if we are subnetted, output subnets in our
2116 /* that have the same mask as the output "interface".
2118 /* networks, only the classfull version is output. */
2120 if (version
== RIPv1
) {
2121 p
= (struct prefix_ipv4
*)&rp
->p
;
2123 if (IS_RIP_DEBUG_PACKET
)
2125 "RIPv1 mask check, %s/%d considered for output",
2126 inet_ntoa(rp
->p
.u
.prefix4
),
2131 (struct prefix
*)&ifaddrclass
,
2133 if ((ifc
->address
->prefixlen
2135 && (rp
->p
.prefixlen
!= 32))
2138 memcpy(&classfull
, &rp
->p
,
2139 sizeof(struct prefix_ipv4
));
2140 apply_classful_mask_ipv4(&classfull
);
2141 if (rp
->p
.u
.prefix4
.s_addr
!= 0
2142 && classfull
.prefixlen
2146 if (IS_RIP_DEBUG_PACKET
)
2148 "RIPv1 mask check, %s/%d made it through",
2149 inet_ntoa(rp
->p
.u
.prefix4
),
2152 p
= (struct prefix_ipv4
*)&rp
->p
;
2154 /* Apply output filters. */
2155 ret
= rip_filter(RIP_FILTER_OUT
, p
, ri
);
2159 /* Changed route only output. */
2160 if (route_type
== rip_changed_route
2161 && (!(rinfo
->flags
& RIP_RTF_CHANGED
)))
2164 /* Split horizon. */
2165 /* if (split_horizon == rip_split_horizon) */
2166 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
) {
2168 * We perform split horizon for RIP and
2170 * For rip routes, we want to suppress the route
2172 * end up sending the route back on the
2174 * learned it from, with a higher metric. For
2176 * we suppress the route if the prefix is a
2178 * source address that we are going to use for
2180 * (in order to handle the case when multiple
2182 * configured on the same interface).
2185 struct rip_info
*tmp_rinfo
= NULL
;
2186 struct connected
*tmp_ifc
= NULL
;
2188 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2190 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2191 && tmp_rinfo
->nh
.ifindex
2192 == ifc
->ifp
->ifindex
) {
2198 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2199 for (ALL_LIST_ELEMENTS_RO(
2200 ifc
->ifp
->connected
,
2204 tmp_ifc
->address
)) {
2214 /* Preparation for route-map. */
2215 rinfo
->metric_set
= 0;
2216 rinfo
->nexthop_out
.s_addr
= 0;
2217 rinfo
->metric_out
= rinfo
->metric
;
2218 rinfo
->tag_out
= rinfo
->tag
;
2219 rinfo
->ifindex_out
= ifc
->ifp
->ifindex
;
2221 /* In order to avoid some local loops,
2222 * if the RIP route has a nexthop via this interface,
2224 * otherwise set it to 0. The nexthop should not be
2226 * beyond the local broadcast/multicast area in order
2227 * to avoid an IGP multi-level recursive look-up.
2230 if (rinfo
->nh
.ifindex
== ifc
->ifp
->ifindex
)
2231 rinfo
->nexthop_out
= rinfo
->nh
.gate
.ipv4
;
2233 /* Interface route-map */
2234 if (ri
->routemap
[RIP_FILTER_OUT
]) {
2235 ret
= route_map_apply(
2236 ri
->routemap
[RIP_FILTER_OUT
],
2237 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2239 if (ret
== RMAP_DENYMATCH
) {
2240 if (IS_RIP_DEBUG_PACKET
)
2242 "RIP %s/%d is filtered by route-map out",
2243 inet_ntoa(p
->prefix
),
2249 /* Apply redistribute route map - continue, if deny */
2250 if (rip
->route_map
[rinfo
->type
].name
2251 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2252 ret
= route_map_apply(
2253 rip
->route_map
[rinfo
->type
].map
,
2254 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2256 if (ret
== RMAP_DENYMATCH
) {
2257 if (IS_RIP_DEBUG_PACKET
)
2259 "%s/%d is filtered by route-map",
2260 inet_ntoa(p
->prefix
),
2266 /* When route-map does not set metric. */
2267 if (!rinfo
->metric_set
) {
2268 /* If redistribute metric is set. */
2269 if (rip
->route_map
[rinfo
->type
].metric_config
2270 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
2272 rip
->route_map
[rinfo
->type
]
2275 /* If the route is not connected or
2277 one, use default-metric value*/
2278 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2280 != ZEBRA_ROUTE_CONNECT
2282 != RIP_METRIC_INFINITY
)
2284 rip
->default_metric
;
2288 /* Apply offset-list */
2289 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2290 rip_offset_list_apply_out(p
, ifc
->ifp
,
2291 &rinfo
->metric_out
);
2293 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2294 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2296 /* Perform split-horizon with poisoned reverse
2297 * for RIP and connected routes.
2299 if (ri
->split_horizon
2300 == RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2302 * We perform split horizon for RIP and
2304 * For rip routes, we want to suppress the route
2306 * end up sending the route back on the
2308 * learned it from, with a higher metric. For
2310 * we suppress the route if the prefix is a
2312 * source address that we are going to use for
2314 * (in order to handle the case when multiple
2316 * configured on the same interface).
2318 struct rip_info
*tmp_rinfo
= NULL
;
2319 struct connected
*tmp_ifc
= NULL
;
2321 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2323 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2324 && tmp_rinfo
->nh
.ifindex
2325 == ifc
->ifp
->ifindex
)
2327 RIP_METRIC_INFINITY
;
2329 if (rinfo
->metric_out
!= RIP_METRIC_INFINITY
2330 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2331 for (ALL_LIST_ELEMENTS_RO(
2332 ifc
->ifp
->connected
,
2336 tmp_ifc
->address
)) {
2338 RIP_METRIC_INFINITY
;
2344 /* Prepare preamble, auth headers, if needs be */
2346 stream_putc(s
, RIP_RESPONSE
);
2347 stream_putc(s
, version
);
2350 /* auth header for !v1 && !no_auth */
2351 if ((ri
->auth_type
!= RIP_NO_AUTH
)
2352 && (version
!= RIPv1
))
2353 doff
= rip_auth_header_write(
2354 s
, ri
, key
, auth_str
,
2355 RIP_AUTH_SIMPLE_SIZE
);
2358 /* Write RTE to the stream. */
2359 num
= rip_write_rte(num
, s
, p
, version
, rinfo
);
2360 if (num
== rtemax
) {
2361 if (version
== RIPv2
2362 && ri
->auth_type
== RIP_AUTH_MD5
)
2363 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2364 RIP_AUTH_SIMPLE_SIZE
);
2366 ret
= rip_send_packet(STREAM_DATA(s
),
2367 stream_get_endp(s
), to
,
2370 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2371 rip_packet_dump((struct rip_packet
*)
2380 /* Flush unwritten RTE. */
2382 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2383 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2384 RIP_AUTH_SIMPLE_SIZE
);
2386 ret
= rip_send_packet(STREAM_DATA(s
), stream_get_endp(s
), to
,
2389 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2390 rip_packet_dump((struct rip_packet
*)STREAM_DATA(s
),
2391 stream_get_endp(s
), "SEND");
2395 /* Statistics updates. */
2399 /* Send RIP packet to the interface. */
2400 static void rip_update_interface(struct connected
*ifc
, uint8_t version
,
2403 struct interface
*ifp
= ifc
->ifp
;
2404 struct rip_interface
*ri
= ifp
->info
;
2405 struct sockaddr_in to
;
2407 /* When RIP version is 2 and multicast enable interface. */
2408 if (version
== RIPv2
&& !ri
->v2_broadcast
&& if_is_multicast(ifp
)) {
2409 if (IS_RIP_DEBUG_EVENT
)
2410 zlog_debug("multicast announce on %s ", ifp
->name
);
2412 rip_output_process(ifc
, NULL
, route_type
, version
);
2416 /* If we can't send multicast packet, send it with unicast. */
2417 if (if_is_broadcast(ifp
) || if_is_pointopoint(ifp
)) {
2418 if (ifc
->address
->family
== AF_INET
) {
2419 /* Destination address and port setting. */
2420 memset(&to
, 0, sizeof(struct sockaddr_in
));
2421 if (ifc
->destination
)
2422 /* use specified broadcast or peer destination
2424 to
.sin_addr
= ifc
->destination
->u
.prefix4
;
2425 else if (ifc
->address
->prefixlen
< IPV4_MAX_PREFIXLEN
)
2426 /* calculate the appropriate broadcast address
2428 to
.sin_addr
.s_addr
= ipv4_broadcast_addr(
2429 ifc
->address
->u
.prefix4
.s_addr
,
2430 ifc
->address
->prefixlen
);
2432 /* do not know where to send the packet */
2434 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2436 if (IS_RIP_DEBUG_EVENT
)
2437 zlog_debug("%s announce to %s on %s",
2438 CONNECTED_PEER(ifc
) ? "unicast"
2440 inet_ntoa(to
.sin_addr
), ifp
->name
);
2442 rip_output_process(ifc
, &to
, route_type
, version
);
2447 /* Update send to all interface and neighbor. */
2448 static void rip_update_process(int route_type
)
2450 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2451 struct listnode
*ifnode
, *ifnnode
;
2452 struct connected
*connected
;
2453 struct interface
*ifp
;
2454 struct rip_interface
*ri
;
2455 struct route_node
*rp
;
2456 struct sockaddr_in to
;
2459 /* Send RIP update to each interface. */
2460 FOR_ALL_INTERFACES (vrf
, ifp
) {
2461 if (if_is_loopback(ifp
))
2464 if (!if_is_operative(ifp
))
2467 /* Fetch RIP interface information. */
2470 /* When passive interface is specified, suppress announce to the
2477 * If there is no version configuration in the
2479 * use rip's version setting.
2481 int vsend
= ((ri
->ri_send
== RI_RIP_UNSPEC
)
2485 if (IS_RIP_DEBUG_EVENT
)
2486 zlog_debug("SEND UPDATE to %s ifindex %d",
2487 ifp
->name
, ifp
->ifindex
);
2489 /* send update on each connected network */
2490 for (ALL_LIST_ELEMENTS(ifp
->connected
, ifnode
, ifnnode
,
2492 if (connected
->address
->family
== AF_INET
) {
2494 rip_update_interface(
2498 && if_is_multicast(ifp
))
2499 rip_update_interface(
2507 /* RIP send updates to each neighbor. */
2508 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
2509 if (rp
->info
!= NULL
) {
2512 connected
= if_lookup_address(&p
->u
.prefix4
, AF_INET
,
2516 "Neighbor %s doesn't have connected interface!",
2517 inet_ntoa(p
->u
.prefix4
));
2521 /* Set destination address and port */
2522 memset(&to
, 0, sizeof(struct sockaddr_in
));
2523 to
.sin_addr
= p
->u
.prefix4
;
2524 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2526 /* RIP version is rip's configuration. */
2527 rip_output_process(connected
, &to
, route_type
,
2532 /* RIP's periodical timer. */
2533 static int rip_update(struct thread
*t
)
2535 /* Clear timer pointer. */
2536 rip
->t_update
= NULL
;
2538 if (IS_RIP_DEBUG_EVENT
)
2539 zlog_debug("update timer fire!");
2541 /* Process update output. */
2542 rip_update_process(rip_all_route
);
2544 /* Triggered updates may be suppressed if a regular update is due by
2545 the time the triggered update would be sent. */
2546 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2549 /* Register myself. */
2550 rip_event(RIP_UPDATE_EVENT
, 0);
2555 /* Walk down the RIP routing table then clear changed flag. */
2556 static void rip_clear_changed_flag(void)
2558 struct route_node
*rp
;
2559 struct rip_info
*rinfo
= NULL
;
2560 struct list
*list
= NULL
;
2561 struct listnode
*listnode
= NULL
;
2563 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2564 if ((list
= rp
->info
) != NULL
)
2565 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
2566 UNSET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2567 /* This flag can be set only on the first entry.
2573 /* Triggered update interval timer. */
2574 static int rip_triggered_interval(struct thread
*t
)
2576 int rip_triggered_update(struct thread
*);
2578 rip
->t_triggered_interval
= NULL
;
2582 rip_triggered_update(t
);
2587 /* Execute triggered update. */
2588 static int rip_triggered_update(struct thread
*t
)
2592 /* Clear thred pointer. */
2593 rip
->t_triggered_update
= NULL
;
2595 /* Cancel interval timer. */
2596 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2599 /* Logging triggered update. */
2600 if (IS_RIP_DEBUG_EVENT
)
2601 zlog_debug("triggered update!");
2603 /* Split Horizon processing is done when generating triggered
2604 updates as well as normal updates (see section 2.6). */
2605 rip_update_process(rip_changed_route
);
2607 /* Once all of the triggered updates have been generated, the route
2608 change flags should be cleared. */
2609 rip_clear_changed_flag();
2611 /* After a triggered update is sent, a timer should be set for a
2612 random interval between 1 and 5 seconds. If other changes that
2613 would trigger updates occur before the timer expires, a single
2614 update is triggered when the timer expires. */
2615 interval
= (random() % 5) + 1;
2617 rip
->t_triggered_interval
= NULL
;
2618 thread_add_timer(master
, rip_triggered_interval
, NULL
, interval
,
2619 &rip
->t_triggered_interval
);
2624 /* Withdraw redistributed route. */
2625 void rip_redistribute_withdraw(int type
)
2627 struct route_node
*rp
;
2628 struct rip_info
*rinfo
= NULL
;
2629 struct list
*list
= NULL
;
2634 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2635 if ((list
= rp
->info
) != NULL
) {
2636 rinfo
= listgetdata(listhead(list
));
2637 if (rinfo
->type
== type
2638 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2639 /* Perform poisoned reverse. */
2640 rinfo
->metric
= RIP_METRIC_INFINITY
;
2641 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
2642 rip_garbage_collect
,
2644 RIP_TIMER_OFF(rinfo
->t_timeout
);
2645 rinfo
->flags
|= RIP_RTF_CHANGED
;
2647 if (IS_RIP_DEBUG_EVENT
) {
2648 struct prefix_ipv4
*p
=
2649 (struct prefix_ipv4
*)&rp
->p
;
2652 "Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2653 inet_ntoa(p
->prefix
),
2660 rip_event(RIP_TRIGGERED_UPDATE
, 0);
2665 /* Create new RIP instance and set it to global variable. */
2666 int rip_create(int socket
)
2668 rip
= XCALLOC(MTYPE_RIP
, sizeof(struct rip
));
2670 /* Set initial value. */
2671 rip
->ecmp
= yang_get_default_bool("%s/allow-ecmp", RIP_INSTANCE
);
2672 rip
->default_metric
=
2673 yang_get_default_uint8("%s/default-metric", RIP_INSTANCE
);
2675 yang_get_default_uint8("%s/distance/default", RIP_INSTANCE
);
2676 rip
->passive_default
=
2677 yang_get_default_bool("%s/passive-default", RIP_INSTANCE
);
2678 rip
->garbage_time
= yang_get_default_uint32("%s/timers/flush-interval",
2680 rip
->timeout_time
= yang_get_default_uint32(
2681 "%s/timers/holddown-interval", RIP_INSTANCE
);
2682 rip
->update_time
= yang_get_default_uint32("%s/timers/update-interval",
2685 yang_get_default_enum("%s/version/send", RIP_INSTANCE
);
2687 yang_get_default_enum("%s/version/receive", RIP_INSTANCE
);
2689 /* Initialize RIP routig table. */
2690 rip
->table
= route_table_init();
2691 rip
->neighbor
= route_table_init();
2693 /* Make output stream. */
2694 rip
->obuf
= stream_new(1500);
2699 /* Create read and timer thread. */
2700 rip_event(RIP_READ
, rip
->sock
);
2701 rip_event(RIP_UPDATE_EVENT
, 1);
2708 /* Sned RIP request to the destination. */
2709 int rip_request_send(struct sockaddr_in
*to
, struct interface
*ifp
,
2710 uint8_t version
, struct connected
*connected
)
2713 struct rip_packet rip_packet
;
2714 struct listnode
*node
, *nnode
;
2716 memset(&rip_packet
, 0, sizeof(rip_packet
));
2718 rip_packet
.command
= RIP_REQUEST
;
2719 rip_packet
.version
= version
;
2720 rte
= rip_packet
.rte
;
2721 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
2725 * connected is only sent for ripv1 case, or when
2726 * interface does not support multicast. Caller loops
2727 * over each connected address for this case.
2729 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2731 != sizeof(rip_packet
))
2734 return sizeof(rip_packet
);
2737 /* send request on each connected network */
2738 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, connected
)) {
2739 struct prefix_ipv4
*p
;
2741 p
= (struct prefix_ipv4
*)connected
->address
;
2743 if (p
->family
!= AF_INET
)
2746 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2748 != sizeof(rip_packet
))
2751 return sizeof(rip_packet
);
2754 static int rip_update_jitter(unsigned long time
)
2756 #define JITTER_BOUND 4
2757 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2758 Given that, we cannot let time be less than JITTER_BOUND seconds.
2759 The RIPv2 RFC says jitter should be small compared to
2760 update_time. We consider 1/JITTER_BOUND to be small.
2763 int jitter_input
= time
;
2766 if (jitter_input
< JITTER_BOUND
)
2767 jitter_input
= JITTER_BOUND
;
2769 jitter
= (((random() % ((jitter_input
* 2) + 1)) - jitter_input
));
2771 return jitter
/ JITTER_BOUND
;
2774 void rip_event(enum rip_event event
, int sock
)
2781 thread_add_read(master
, rip_read
, NULL
, sock
, &rip
->t_read
);
2783 case RIP_UPDATE_EVENT
:
2784 RIP_TIMER_OFF(rip
->t_update
);
2785 jitter
= rip_update_jitter(rip
->update_time
);
2786 thread_add_timer(master
, rip_update
, NULL
,
2787 sock
? 2 : rip
->update_time
+ jitter
,
2790 case RIP_TRIGGERED_UPDATE
:
2791 if (rip
->t_triggered_interval
)
2794 thread_add_event(master
, rip_triggered_update
, NULL
, 0,
2795 &rip
->t_triggered_update
);
2805 "Set routing protocol version\n"
2811 version
= atoi(argv
[idx_number
]->arg
);
2812 if (version
!= RIPv1
&& version
!= RIPv2
) {
2813 vty_out(vty
, "invalid rip version %d\n", version
);
2814 return CMD_WARNING_CONFIG_FAILED
;
2816 rip
->version_send
= version
;
2817 rip
->version_recv
= version
;
2822 DEFUN (no_rip_version
,
2824 "no version [(1-2)]",
2826 "Set routing protocol version\n"
2829 /* Set RIP version to the default. */
2830 rip
->version_send
= RI_RIP_VERSION_2
;
2831 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2838 rip_update_default_metric (void)
2840 struct route_node
*np
;
2841 struct rip_info
*rinfo
= NULL
;
2842 struct list
*list
= NULL
;
2843 struct listnode
*listnode
= NULL
;
2845 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
2846 if ((list
= np
->info
) != NULL
)
2847 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
2848 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
2849 rinfo
->metric
= rip
->default_metric
;
2854 struct route_table
*rip_distance_table
;
2856 struct rip_distance
*rip_distance_new(void)
2858 return XCALLOC(MTYPE_RIP_DISTANCE
, sizeof(struct rip_distance
));
2861 void rip_distance_free(struct rip_distance
*rdistance
)
2863 XFREE(MTYPE_RIP_DISTANCE
, rdistance
);
2866 static void rip_distance_reset(void)
2868 struct route_node
*rn
;
2869 struct rip_distance
*rdistance
;
2871 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
2872 if ((rdistance
= rn
->info
) != NULL
) {
2873 if (rdistance
->access_list
)
2874 free(rdistance
->access_list
);
2875 rip_distance_free(rdistance
);
2877 route_unlock_node(rn
);
2881 /* Apply RIP information to distance method. */
2882 uint8_t rip_distance_apply(struct rip_info
*rinfo
)
2884 struct route_node
*rn
;
2885 struct prefix_ipv4 p
;
2886 struct rip_distance
*rdistance
;
2887 struct access_list
*alist
;
2892 memset(&p
, 0, sizeof(struct prefix_ipv4
));
2894 p
.prefix
= rinfo
->from
;
2895 p
.prefixlen
= IPV4_MAX_BITLEN
;
2897 /* Check source address. */
2898 rn
= route_node_match(rip_distance_table
, (struct prefix
*)&p
);
2900 rdistance
= rn
->info
;
2901 route_unlock_node(rn
);
2903 if (rdistance
->access_list
) {
2904 alist
= access_list_lookup(AFI_IP
,
2905 rdistance
->access_list
);
2908 if (access_list_apply(alist
, &rinfo
->rp
->p
)
2912 return rdistance
->distance
;
2914 return rdistance
->distance
;
2918 return rip
->distance
;
2923 static void rip_distance_show(struct vty
*vty
)
2925 struct route_node
*rn
;
2926 struct rip_distance
*rdistance
;
2930 vty_out(vty
, " Distance: (default is %u)\n",
2931 rip
->distance
? rip
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
);
2933 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
2934 if ((rdistance
= rn
->info
) != NULL
) {
2937 " Address Distance List\n");
2940 sprintf(buf
, "%s/%d", inet_ntoa(rn
->p
.u
.prefix4
),
2942 vty_out(vty
, " %-20s %4d %s\n", buf
,
2943 rdistance
->distance
,
2944 rdistance
->access_list
? rdistance
->access_list
2949 /* Update ECMP routes to zebra when ECMP is disabled. */
2950 void rip_ecmp_disable(void)
2952 struct route_node
*rp
;
2953 struct rip_info
*rinfo
, *tmp_rinfo
;
2955 struct listnode
*node
, *nextnode
;
2960 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2961 if ((list
= rp
->info
) != NULL
&& listcount(list
) > 1) {
2962 rinfo
= listgetdata(listhead(list
));
2963 if (!rip_route_rte(rinfo
))
2966 /* Drop all other entries, except the first one. */
2967 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
2968 if (tmp_rinfo
!= rinfo
) {
2969 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
2971 tmp_rinfo
->t_garbage_collect
);
2972 list_delete_node(list
, node
);
2973 rip_info_free(tmp_rinfo
);
2977 rip_zebra_ipv4_add(rp
);
2979 /* Set the route change flag. */
2980 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2982 /* Signal the output process to trigger an update. */
2983 rip_event(RIP_TRIGGERED_UPDATE
, 0);
2987 /* Print out routes update time. */
2988 static void rip_vty_out_uptime(struct vty
*vty
, struct rip_info
*rinfo
)
2993 char timebuf
[TIME_BUF
];
2994 struct thread
*thread
;
2996 if ((thread
= rinfo
->t_timeout
) != NULL
) {
2997 clock
= thread_timer_remain_second(thread
);
2998 tm
= gmtime(&clock
);
2999 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
3000 vty_out(vty
, "%5s", timebuf
);
3001 } else if ((thread
= rinfo
->t_garbage_collect
) != NULL
) {
3002 clock
= thread_timer_remain_second(thread
);
3003 tm
= gmtime(&clock
);
3004 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
3005 vty_out(vty
, "%5s", timebuf
);
3009 static const char *rip_route_type_print(int sub_type
)
3014 case RIP_ROUTE_STATIC
:
3016 case RIP_ROUTE_DEFAULT
:
3018 case RIP_ROUTE_REDISTRIBUTE
:
3020 case RIP_ROUTE_INTERFACE
:
3032 "Show RIP routes\n")
3034 struct route_node
*np
;
3035 struct rip_info
*rinfo
= NULL
;
3036 struct list
*list
= NULL
;
3037 struct listnode
*listnode
= NULL
;
3043 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
3045 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
3046 " (i) - interface\n\n"
3047 " Network Next Hop Metric From Tag Time\n");
3049 for (np
= route_top(rip
->table
); np
; np
= route_next(np
))
3050 if ((list
= np
->info
) != NULL
)
3051 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3055 vty
, "%c(%s) %s/%d",
3056 /* np->lock, For debugging. */
3057 zebra_route_char(rinfo
->type
),
3058 rip_route_type_print(rinfo
->sub_type
),
3059 inet_ntoa(np
->p
.u
.prefix4
),
3065 vty_out(vty
, "%*s", len
, " ");
3067 switch (rinfo
->nh
.type
) {
3068 case NEXTHOP_TYPE_IPV4
:
3069 case NEXTHOP_TYPE_IPV4_IFINDEX
:
3070 vty_out(vty
, "%-20s %2d ",
3071 inet_ntoa(rinfo
->nh
.gate
.ipv4
),
3074 case NEXTHOP_TYPE_IFINDEX
:
3079 case NEXTHOP_TYPE_BLACKHOLE
:
3084 case NEXTHOP_TYPE_IPV6
:
3085 case NEXTHOP_TYPE_IPV6_IFINDEX
:
3087 "V6 Address Hidden %2d ",
3092 /* Route which exist in kernel routing table. */
3093 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
)
3094 && (rinfo
->sub_type
== RIP_ROUTE_RTE
)) {
3095 vty_out(vty
, "%-15s ",
3096 inet_ntoa(rinfo
->from
));
3097 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3098 (route_tag_t
)rinfo
->tag
);
3099 rip_vty_out_uptime(vty
, rinfo
);
3100 } else if (rinfo
->metric
3101 == RIP_METRIC_INFINITY
) {
3102 vty_out(vty
, "self ");
3103 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3104 (route_tag_t
)rinfo
->tag
);
3105 rip_vty_out_uptime(vty
, rinfo
);
3107 if (rinfo
->external_metric
) {
3109 vty
, "self (%s:%d)",
3112 rinfo
->external_metric
);
3115 vty_out(vty
, "%*s", len
,
3120 vty_out(vty
, "%3" ROUTE_TAG_PRI
,
3121 (route_tag_t
)rinfo
->tag
);
3129 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3130 DEFUN (show_ip_rip_status
,
3131 show_ip_rip_status_cmd
,
3132 "show ip rip status",
3136 "IP routing protocol process parameters and statistics\n")
3138 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3139 struct interface
*ifp
;
3140 struct rip_interface
*ri
;
3141 extern const struct message ri_version_msg
[];
3142 const char *send_version
;
3143 const char *receive_version
;
3148 vty_out(vty
, "Routing Protocol is \"rip\"\n");
3149 vty_out(vty
, " Sending updates every %u seconds with +/-50%%,",
3151 vty_out(vty
, " next due in %lu seconds\n",
3152 thread_timer_remain_second(rip
->t_update
));
3153 vty_out(vty
, " Timeout after %u seconds,", rip
->timeout_time
);
3154 vty_out(vty
, " garbage collect after %u seconds\n", rip
->garbage_time
);
3156 /* Filtering status show. */
3157 config_show_distribute(vty
);
3159 /* Default metric information. */
3160 vty_out(vty
, " Default redistribution metric is %u\n",
3161 rip
->default_metric
);
3163 /* Redistribute information. */
3164 vty_out(vty
, " Redistributing:");
3165 rip_show_redistribute_config(vty
);
3168 vty_out(vty
, " Default version control: send version %s,",
3169 lookup_msg(ri_version_msg
, rip
->version_send
, NULL
));
3170 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3171 vty_out(vty
, " receive any version \n");
3173 vty_out(vty
, " receive version %s \n",
3174 lookup_msg(ri_version_msg
, rip
->version_recv
, NULL
));
3176 vty_out(vty
, " Interface Send Recv Key-chain\n");
3178 FOR_ALL_INTERFACES (vrf
, ifp
) {
3184 if (ri
->enable_network
|| ri
->enable_interface
) {
3185 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3187 lookup_msg(ri_version_msg
,
3188 rip
->version_send
, NULL
);
3190 send_version
= lookup_msg(ri_version_msg
,
3193 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3195 lookup_msg(ri_version_msg
,
3196 rip
->version_recv
, NULL
);
3198 receive_version
= lookup_msg(
3199 ri_version_msg
, ri
->ri_receive
, NULL
);
3201 vty_out(vty
, " %-17s%-3s %-3s %s\n", ifp
->name
,
3202 send_version
, receive_version
,
3203 ri
->key_chain
? ri
->key_chain
: "");
3207 vty_out(vty
, " Routing for Networks:\n");
3208 rip_show_network_config(vty
);
3211 int found_passive
= 0;
3212 FOR_ALL_INTERFACES (vrf
, ifp
) {
3215 if ((ri
->enable_network
|| ri
->enable_interface
)
3217 if (!found_passive
) {
3219 " Passive Interface(s):\n");
3222 vty_out(vty
, " %s\n", ifp
->name
);
3227 vty_out(vty
, " Routing Information Sources:\n");
3229 " Gateway BadPackets BadRoutes Distance Last Update\n");
3230 rip_peer_display(vty
);
3232 rip_distance_show(vty
);
3237 /* RIP configuration write function. */
3238 static int config_write_rip(struct vty
*vty
)
3241 struct lyd_node
*dnode
;
3243 dnode
= yang_dnode_get(running_config
->dnode
,
3244 "/frr-ripd:ripd/instance");
3248 nb_cli_show_dnode_cmds(vty
, dnode
, false);
3250 /* RIP version statement. Default is RIP version 2. */
3251 if (rip
->version_send
!= RI_RIP_VERSION_2
3252 || rip
->version_recv
!= RI_RIP_VERSION_1_AND_2
)
3253 vty_out(vty
, " version %d\n", rip
->version_send
);
3255 /* Distribute configuration. */
3256 write
+= config_write_distribute(vty
);
3258 /* Interface routemap configuration */
3259 write
+= config_write_if_rmap(vty
);
3264 /* RIP node structure. */
3265 static struct cmd_node rip_node
= {RIP_NODE
, "%s(config-router)# ", 1};
3267 /* Distribute-list update functions. */
3268 static void rip_distribute_update(struct distribute
*dist
)
3270 struct interface
*ifp
;
3271 struct rip_interface
*ri
;
3272 struct access_list
*alist
;
3273 struct prefix_list
*plist
;
3278 ifp
= if_lookup_by_name(dist
->ifname
, VRF_DEFAULT
);
3284 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
3285 alist
= access_list_lookup(AFI_IP
,
3286 dist
->list
[DISTRIBUTE_V4_IN
]);
3288 ri
->list
[RIP_FILTER_IN
] = alist
;
3290 ri
->list
[RIP_FILTER_IN
] = NULL
;
3292 ri
->list
[RIP_FILTER_IN
] = NULL
;
3294 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
3295 alist
= access_list_lookup(AFI_IP
,
3296 dist
->list
[DISTRIBUTE_V4_OUT
]);
3298 ri
->list
[RIP_FILTER_OUT
] = alist
;
3300 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3302 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3304 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
3305 plist
= prefix_list_lookup(AFI_IP
,
3306 dist
->prefix
[DISTRIBUTE_V4_IN
]);
3308 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3310 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3312 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3314 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
3315 plist
= prefix_list_lookup(AFI_IP
,
3316 dist
->prefix
[DISTRIBUTE_V4_OUT
]);
3318 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3320 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3322 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3325 void rip_distribute_update_interface(struct interface
*ifp
)
3327 struct distribute
*dist
;
3329 dist
= distribute_lookup(ifp
->name
);
3331 rip_distribute_update(dist
);
3334 /* Update all interface's distribute list. */
3336 static void rip_distribute_update_all(struct prefix_list
*notused
)
3338 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3339 struct interface
*ifp
;
3341 FOR_ALL_INTERFACES (vrf
, ifp
)
3342 rip_distribute_update_interface(ifp
);
3345 static void rip_distribute_update_all_wrapper(struct access_list
*notused
)
3347 rip_distribute_update_all(NULL
);
3350 /* Delete all added rip route. */
3351 void rip_clean(void)
3354 struct route_node
*rp
;
3355 struct rip_info
*rinfo
= NULL
;
3356 struct list
*list
= NULL
;
3357 struct listnode
*listnode
= NULL
;
3362 /* Clear RIP routes */
3363 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3364 if ((list
= rp
->info
) != NULL
) {
3365 rinfo
= listgetdata(listhead(list
));
3366 if (rip_route_rte(rinfo
))
3367 rip_zebra_ipv4_delete(rp
);
3369 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
3371 RIP_TIMER_OFF(rinfo
->t_timeout
);
3372 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
3373 rip_info_free(rinfo
);
3377 route_unlock_node(rp
);
3380 /* Cancel RIP related timers. */
3381 RIP_TIMER_OFF(rip
->t_update
);
3382 RIP_TIMER_OFF(rip
->t_triggered_update
);
3383 RIP_TIMER_OFF(rip
->t_triggered_interval
);
3385 /* Cancel read thread. */
3386 THREAD_READ_OFF(rip
->t_read
);
3388 /* Close RIP socket. */
3389 if (rip
->sock
>= 0) {
3394 stream_free(rip
->obuf
);
3396 /* RIP neighbor configuration. */
3397 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
3400 route_unlock_node(rp
);
3403 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3404 if (rip
->route_map
[i
].name
)
3405 free(rip
->route_map
[i
].name
);
3407 XFREE(MTYPE_ROUTE_TABLE
, rip
->table
);
3408 XFREE(MTYPE_ROUTE_TABLE
, rip
->neighbor
);
3410 XFREE(MTYPE_RIP
, rip
);
3414 rip_clean_network();
3415 rip_passive_nondefault_clean();
3417 rip_interfaces_clean();
3418 rip_distance_reset();
3419 rip_redistribute_clean();
3422 /* Reset all values to the default settings. */
3423 void rip_reset(void)
3425 /* Reset global counters. */
3426 rip_global_route_changes
= 0;
3427 rip_global_queries
= 0;
3429 /* Call ripd related reset functions. */
3431 rip_route_map_reset();
3433 /* Call library reset functions. */
3435 access_list_reset();
3436 prefix_list_reset();
3438 distribute_list_reset();
3440 rip_interfaces_reset();
3441 rip_distance_reset();
3443 rip_zclient_reset();
3446 static void rip_if_rmap_update(struct if_rmap
*if_rmap
)
3448 struct interface
*ifp
;
3449 struct rip_interface
*ri
;
3450 struct route_map
*rmap
;
3452 ifp
= if_lookup_by_name(if_rmap
->ifname
, VRF_DEFAULT
);
3458 if (if_rmap
->routemap
[IF_RMAP_IN
]) {
3459 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_IN
]);
3461 ri
->routemap
[IF_RMAP_IN
] = rmap
;
3463 ri
->routemap
[IF_RMAP_IN
] = NULL
;
3465 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
3467 if (if_rmap
->routemap
[IF_RMAP_OUT
]) {
3468 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_OUT
]);
3470 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
3472 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
3474 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
3477 void rip_if_rmap_update_interface(struct interface
*ifp
)
3479 struct if_rmap
*if_rmap
;
3481 if_rmap
= if_rmap_lookup(ifp
->name
);
3483 rip_if_rmap_update(if_rmap
);
3486 static void rip_routemap_update_redistribute(void)
3491 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3492 if (rip
->route_map
[i
].name
)
3493 rip
->route_map
[i
].map
=
3494 route_map_lookup_by_name(
3495 rip
->route_map
[i
].name
);
3501 static void rip_routemap_update(const char *notused
)
3503 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3504 struct interface
*ifp
;
3506 FOR_ALL_INTERFACES (vrf
, ifp
)
3507 rip_if_rmap_update_interface(ifp
);
3509 rip_routemap_update_redistribute();
3512 /* Allocate new rip structure and set default value. */
3515 /* Install top nodes. */
3516 install_node(&rip_node
, config_write_rip
);
3518 /* Install rip commands. */
3519 install_element(VIEW_NODE
, &show_ip_rip_cmd
);
3520 install_element(VIEW_NODE
, &show_ip_rip_status_cmd
);
3522 install_default(RIP_NODE
);
3523 install_element(RIP_NODE
, &rip_version_cmd
);
3524 install_element(RIP_NODE
, &no_rip_version_cmd
);
3526 /* Debug related init. */
3529 /* Access list install. */
3531 access_list_add_hook(rip_distribute_update_all_wrapper
);
3532 access_list_delete_hook(rip_distribute_update_all_wrapper
);
3534 /* Prefix list initialize.*/
3536 prefix_list_add_hook(rip_distribute_update_all
);
3537 prefix_list_delete_hook(rip_distribute_update_all
);
3539 /* Distribute list install. */
3540 distribute_list_init(RIP_NODE
);
3541 distribute_list_add_hook(rip_distribute_update
);
3542 distribute_list_delete_hook(rip_distribute_update
);
3545 rip_route_map_init();
3548 route_map_add_hook(rip_routemap_update
);
3549 route_map_delete_hook(rip_routemap_update
);
3551 if_rmap_init(RIP_NODE
);
3552 if_rmap_hook_add(rip_if_rmap_update
);
3553 if_rmap_hook_delete(rip_if_rmap_update
);
3555 /* Distance control. */
3556 rip_distance_table
= route_table_init();