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"
50 /* UDP receive buffer size */
51 #define RIP_UDP_RCV_BUF 41600
54 static void rip_output_process(struct connected
*, struct sockaddr_in
*, int,
56 static int rip_triggered_update(struct thread
*);
57 static int rip_update_jitter(unsigned long);
58 static void rip_distance_table_node_cleanup(struct route_table
*table
,
59 struct route_node
*node
);
61 static void rip_distribute_update(struct distribute_ctx
*ctx
,
62 struct distribute
*dist
);
64 /* RIP output routes type. */
65 enum { rip_all_route
, rip_changed_route
};
67 /* RIP command strings. */
68 static const struct message rip_msg
[] = {{RIP_REQUEST
, "REQUEST"},
69 {RIP_RESPONSE
, "RESPONSE"},
70 {RIP_TRACEON
, "TRACEON"},
71 {RIP_TRACEOFF
, "TRACEOFF"},
73 {RIP_POLL_ENTRY
, "POLL ENTRY"},
76 /* Utility function to set boradcast option to the socket. */
77 static int sockopt_broadcast(int sock
)
82 ret
= setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, (char *)&on
,
85 zlog_warn("can't set sockopt SO_BROADCAST to socket %d", sock
);
91 int rip_route_rte(struct rip_info
*rinfo
)
93 return (rinfo
->type
== ZEBRA_ROUTE_RIP
94 && rinfo
->sub_type
== RIP_ROUTE_RTE
);
97 static struct rip_info
*rip_info_new(void)
99 return XCALLOC(MTYPE_RIP_INFO
, sizeof(struct rip_info
));
102 void rip_info_free(struct rip_info
*rinfo
)
104 XFREE(MTYPE_RIP_INFO
, rinfo
);
107 struct rip
*rip_info_get_instance(const struct rip_info
*rinfo
)
109 return route_table_get_info(rinfo
->rp
->table
);
112 /* RIP route garbage collect timer. */
113 static int rip_garbage_collect(struct thread
*t
)
115 struct rip_info
*rinfo
;
116 struct route_node
*rp
;
118 rinfo
= THREAD_ARG(t
);
119 rinfo
->t_garbage_collect
= NULL
;
121 /* Off timeout timer. */
122 RIP_TIMER_OFF(rinfo
->t_timeout
);
124 /* Get route_node pointer. */
127 /* Unlock route_node. */
128 listnode_delete(rp
->info
, rinfo
);
129 if (list_isempty((struct list
*)rp
->info
)) {
130 list_delete((struct list
**)&rp
->info
);
131 route_unlock_node(rp
);
134 /* Free RIP routing information. */
135 rip_info_free(rinfo
);
140 static void rip_timeout_update(struct rip
*rip
, struct rip_info
*rinfo
);
142 /* Add new route to the ECMP list.
143 * RETURN: the new entry added in the list, or NULL if it is not the first
144 * entry and ECMP is not allowed.
146 struct rip_info
*rip_ecmp_add(struct rip
*rip
, struct rip_info
*rinfo_new
)
148 struct route_node
*rp
= rinfo_new
->rp
;
149 struct rip_info
*rinfo
= NULL
;
150 struct list
*list
= NULL
;
152 if (rp
->info
== NULL
)
153 rp
->info
= list_new();
154 list
= (struct list
*)rp
->info
;
156 /* If ECMP is not allowed and some entry already exists in the list,
158 if (listcount(list
) && !rip
->ecmp
)
161 rinfo
= rip_info_new();
162 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
163 listnode_add(list
, rinfo
);
165 if (rip_route_rte(rinfo
)) {
166 rip_timeout_update(rip
, rinfo
);
167 rip_zebra_ipv4_add(rip
, rp
);
170 /* Set the route change flag on the first entry. */
171 rinfo
= listgetdata(listhead(list
));
172 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
174 /* Signal the output process to trigger an update (see section 2.5). */
175 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
180 /* Replace the ECMP list with the new route.
181 * RETURN: the new entry added in the list
183 struct rip_info
*rip_ecmp_replace(struct rip
*rip
, struct rip_info
*rinfo_new
)
185 struct route_node
*rp
= rinfo_new
->rp
;
186 struct list
*list
= (struct list
*)rp
->info
;
187 struct rip_info
*rinfo
= NULL
, *tmp_rinfo
= NULL
;
188 struct listnode
*node
= NULL
, *nextnode
= NULL
;
190 if (list
== NULL
|| listcount(list
) == 0)
191 return rip_ecmp_add(rip
, rinfo_new
);
193 /* Get the first entry */
194 rinfo
= listgetdata(listhead(list
));
196 /* Learnt route replaced by a local one. Delete it from zebra. */
197 if (rip_route_rte(rinfo
) && !rip_route_rte(rinfo_new
))
198 if (CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
199 rip_zebra_ipv4_delete(rip
, rp
);
201 /* Re-use the first entry, and delete the others. */
202 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
203 if (tmp_rinfo
!= rinfo
) {
204 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
205 RIP_TIMER_OFF(tmp_rinfo
->t_garbage_collect
);
206 list_delete_node(list
, node
);
207 rip_info_free(tmp_rinfo
);
210 RIP_TIMER_OFF(rinfo
->t_timeout
);
211 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
212 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
214 if (rip_route_rte(rinfo
)) {
215 rip_timeout_update(rip
, rinfo
);
216 /* The ADD message implies an update. */
217 rip_zebra_ipv4_add(rip
, rp
);
220 /* Set the route change flag. */
221 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
223 /* Signal the output process to trigger an update (see section 2.5). */
224 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
229 /* Delete one route from the ECMP list.
231 * null - the entry is freed, and other entries exist in the list
232 * the entry - the entry is the last one in the list; its metric is set
233 * to INFINITY, and the garbage collector is started for it
235 struct rip_info
*rip_ecmp_delete(struct rip
*rip
, struct rip_info
*rinfo
)
237 struct route_node
*rp
= rinfo
->rp
;
238 struct list
*list
= (struct list
*)rp
->info
;
240 RIP_TIMER_OFF(rinfo
->t_timeout
);
242 if (listcount(list
) > 1) {
243 /* Some other ECMP entries still exist. Just delete this entry.
245 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
246 listnode_delete(list
, rinfo
);
247 if (rip_route_rte(rinfo
)
248 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
249 /* The ADD message implies the update. */
250 rip_zebra_ipv4_add(rip
, rp
);
251 rip_info_free(rinfo
);
254 assert(rinfo
== listgetdata(listhead(list
)));
256 /* This is the only entry left in the list. We must keep it in
257 * the list for garbage collection time, with INFINITY metric.
260 rinfo
->metric
= RIP_METRIC_INFINITY
;
261 RIP_TIMER_ON(rinfo
->t_garbage_collect
, rip_garbage_collect
,
264 if (rip_route_rte(rinfo
)
265 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
266 rip_zebra_ipv4_delete(rip
, rp
);
269 /* Set the route change flag on the first entry. */
270 rinfo
= listgetdata(listhead(list
));
271 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
273 /* Signal the output process to trigger an update (see section 2.5). */
274 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
279 /* Timeout RIP routes. */
280 static int rip_timeout(struct thread
*t
)
282 struct rip_info
*rinfo
= THREAD_ARG(t
);
283 struct rip
*rip
= rip_info_get_instance(rinfo
);
285 rip_ecmp_delete(rip
, rinfo
);
290 static void rip_timeout_update(struct rip
*rip
, struct rip_info
*rinfo
)
292 if (rinfo
->metric
!= RIP_METRIC_INFINITY
) {
293 RIP_TIMER_OFF(rinfo
->t_timeout
);
294 thread_add_timer(master
, rip_timeout
, rinfo
, rip
->timeout_time
,
299 static int rip_filter(int rip_distribute
, struct prefix_ipv4
*p
,
300 struct rip_interface
*ri
)
302 struct distribute
*dist
;
303 struct access_list
*alist
;
304 struct prefix_list
*plist
;
305 int distribute
= rip_distribute
== RIP_FILTER_OUT
? DISTRIBUTE_V4_OUT
307 const char *inout
= rip_distribute
== RIP_FILTER_OUT
? "out" : "in";
309 /* Input distribute-list filtering. */
310 if (ri
->list
[rip_distribute
]) {
311 if (access_list_apply(ri
->list
[rip_distribute
],
314 if (IS_RIP_DEBUG_PACKET
)
315 zlog_debug("%s/%d filtered by distribute %s",
316 inet_ntoa(p
->prefix
), p
->prefixlen
,
321 if (ri
->prefix
[rip_distribute
]) {
322 if (prefix_list_apply(ri
->prefix
[rip_distribute
],
325 if (IS_RIP_DEBUG_PACKET
)
326 zlog_debug("%s/%d filtered by prefix-list %s",
327 inet_ntoa(p
->prefix
), p
->prefixlen
,
333 /* All interface filter check. */
334 dist
= distribute_lookup(ri
->rip
->distribute_ctx
, NULL
);
336 if (dist
->list
[distribute
]) {
337 alist
= access_list_lookup(AFI_IP
,
338 dist
->list
[distribute
]);
341 if (access_list_apply(alist
, (struct prefix
*)p
)
343 if (IS_RIP_DEBUG_PACKET
)
345 "%s/%d filtered by distribute %s",
346 inet_ntoa(p
->prefix
),
347 p
->prefixlen
, inout
);
352 if (dist
->prefix
[distribute
]) {
353 plist
= prefix_list_lookup(AFI_IP
,
354 dist
->prefix
[distribute
]);
357 if (prefix_list_apply(plist
, (struct prefix
*)p
)
359 if (IS_RIP_DEBUG_PACKET
)
361 "%s/%d filtered by prefix-list %s",
362 inet_ntoa(p
->prefix
),
363 p
->prefixlen
, inout
);
372 /* Check nexthop address validity. */
373 static int rip_nexthop_check(struct rip
*rip
, struct in_addr
*addr
)
375 struct vrf
*vrf
= vrf_lookup_by_id(rip
->vrf_id
);
376 struct interface
*ifp
;
377 struct listnode
*cnode
;
378 struct connected
*ifc
;
381 /* If nexthop address matches local configured address then it is
384 FOR_ALL_INTERFACES (vrf
, ifp
) {
385 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, ifc
)) {
388 if (p
->family
== AF_INET
389 && IPV4_ADDR_SAME(&p
->u
.prefix4
, addr
))
396 /* RIP add route to routing table. */
397 static void rip_rte_process(struct rte
*rte
, struct sockaddr_in
*from
,
398 struct interface
*ifp
)
402 struct prefix_ipv4 p
;
403 struct route_node
*rp
;
404 struct rip_info
*rinfo
= NULL
, newinfo
;
405 struct rip_interface
*ri
;
406 struct in_addr
*nexthop
;
408 unsigned char old_dist
, new_dist
;
409 struct list
*list
= NULL
;
410 struct listnode
*node
= NULL
;
412 /* Make prefix structure. */
413 memset(&p
, 0, sizeof(struct prefix_ipv4
));
415 p
.prefix
= rte
->prefix
;
416 p
.prefixlen
= ip_masklen(rte
->mask
);
418 /* Make sure mask is applied. */
424 /* Apply input filters. */
425 ret
= rip_filter(RIP_FILTER_IN
, &p
, ri
);
429 memset(&newinfo
, 0, sizeof(newinfo
));
430 newinfo
.type
= ZEBRA_ROUTE_RIP
;
431 newinfo
.sub_type
= RIP_ROUTE_RTE
;
432 newinfo
.nh
.gate
.ipv4
= rte
->nexthop
;
433 newinfo
.from
= from
->sin_addr
;
434 newinfo
.nh
.ifindex
= ifp
->ifindex
;
435 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
436 newinfo
.metric
= rte
->metric
;
437 newinfo
.metric_out
= rte
->metric
; /* XXX */
438 newinfo
.tag
= ntohs(rte
->tag
); /* XXX */
440 /* Modify entry according to the interface routemap. */
441 if (ri
->routemap
[RIP_FILTER_IN
]) {
442 /* The object should be of the type of rip_info */
443 ret
= route_map_apply(ri
->routemap
[RIP_FILTER_IN
],
444 (struct prefix
*)&p
, RMAP_RIP
, &newinfo
);
446 if (ret
== RMAP_DENYMATCH
) {
447 if (IS_RIP_DEBUG_PACKET
)
449 "RIP %s/%d is filtered by route-map in",
450 inet_ntoa(p
.prefix
), p
.prefixlen
);
454 /* Get back the object */
455 rte
->nexthop
= newinfo
.nexthop_out
;
456 rte
->tag
= htons(newinfo
.tag_out
); /* XXX */
457 rte
->metric
= newinfo
.metric_out
; /* XXX: the routemap uses the
461 /* Once the entry has been validated, update the metric by
462 adding the cost of the network on wich the message
463 arrived. If the result is greater than infinity, use infinity
464 (RFC2453 Sec. 3.9.2) */
465 /* Zebra ripd can handle offset-list in. */
466 ret
= rip_offset_list_apply_in(&p
, ifp
, &rte
->metric
);
468 /* If offset-list does not modify the metric use interface's
471 rte
->metric
+= ifp
->metric
? ifp
->metric
: 1;
473 if (rte
->metric
> RIP_METRIC_INFINITY
)
474 rte
->metric
= RIP_METRIC_INFINITY
;
476 /* Set nexthop pointer. */
477 if (rte
->nexthop
.s_addr
== 0)
478 nexthop
= &from
->sin_addr
;
480 nexthop
= &rte
->nexthop
;
482 /* Check if nexthop address is myself, then do nothing. */
483 if (rip_nexthop_check(rip
, nexthop
) < 0) {
484 if (IS_RIP_DEBUG_PACKET
)
485 zlog_debug("Nexthop address %s is myself",
486 inet_ntoa(*nexthop
));
490 /* Get index for the prefix. */
491 rp
= route_node_get(rip
->table
, (struct prefix
*)&p
);
494 newinfo
.nh
.gate
.ipv4
= *nexthop
;
495 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4
;
496 newinfo
.metric
= rte
->metric
;
497 newinfo
.tag
= ntohs(rte
->tag
);
498 newinfo
.distance
= rip_distance_apply(rip
, &newinfo
);
500 new_dist
= newinfo
.distance
? newinfo
.distance
501 : ZEBRA_RIP_DISTANCE_DEFAULT
;
503 /* Check to see whether there is already RIP route on the table. */
504 if ((list
= rp
->info
) != NULL
)
505 for (ALL_LIST_ELEMENTS_RO(list
, node
, rinfo
)) {
506 /* Need to compare with redistributed entry or local
508 if (!rip_route_rte(rinfo
))
511 if (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
512 && IPV4_ADDR_SAME(&rinfo
->nh
.gate
.ipv4
, nexthop
))
515 if (!listnextnode(node
)) {
516 /* Not found in the list */
518 if (rte
->metric
> rinfo
->metric
) {
519 /* New route has a greater metric.
521 route_unlock_node(rp
);
525 if (rte
->metric
< rinfo
->metric
)
526 /* New route has a smaller metric.
527 * Replace the ECMP list
528 * with the new one in below. */
531 /* Metrics are same. We compare the distances.
533 old_dist
= rinfo
->distance
535 : ZEBRA_RIP_DISTANCE_DEFAULT
;
537 if (new_dist
> old_dist
) {
538 /* New route has a greater distance.
540 route_unlock_node(rp
);
544 if (new_dist
< old_dist
)
545 /* New route has a smaller distance.
546 * Replace the ECMP list
547 * with the new one in below. */
550 /* Metrics and distances are both same. Keep
552 * the new route is added in the ECMP list in
558 /* Local static route. */
559 if (rinfo
->type
== ZEBRA_ROUTE_RIP
560 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
561 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))
562 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
563 route_unlock_node(rp
);
567 /* Redistributed route check. */
568 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
569 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
570 old_dist
= rinfo
->distance
;
571 /* Only routes directly connected to an interface
573 * may have a valid NULL distance */
574 if (rinfo
->nh
.gate
.ipv4
.s_addr
!= 0)
577 : ZEBRA_RIP_DISTANCE_DEFAULT
;
578 /* If imported route does not have STRICT precedence,
579 mark it as a ghost */
580 if (new_dist
<= old_dist
581 && rte
->metric
!= RIP_METRIC_INFINITY
)
582 rip_ecmp_replace(rip
, &newinfo
);
584 route_unlock_node(rp
);
591 route_unlock_node(rp
);
593 /* Now, check to see whether there is already an explicit route
594 for the destination prefix. If there is no such route, add
595 this route to the routing table, unless the metric is
596 infinity (there is no point in adding a route which
598 if (rte
->metric
!= RIP_METRIC_INFINITY
)
599 rip_ecmp_add(rip
, &newinfo
);
601 /* Route is there but we are not sure the route is RIP or not.
604 /* If there is an existing route, compare the next hop address
605 to the address of the router from which the datagram came.
606 If this datagram is from the same router as the existing
607 route, reinitialize the timeout. */
608 same
= (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
609 && (rinfo
->nh
.ifindex
== ifp
->ifindex
));
611 old_dist
= rinfo
->distance
? rinfo
->distance
612 : ZEBRA_RIP_DISTANCE_DEFAULT
;
614 /* Next, compare the metrics. If the datagram is from the same
615 router as the existing route, and the new metric is different
616 than the old one; or, if the new metric is lower than the old
617 one, or if the tag has been changed; or if there is a route
618 with a lower administrave distance; or an update of the
619 distance on the actual route; do the following actions: */
620 if ((same
&& rinfo
->metric
!= rte
->metric
)
621 || (rte
->metric
< rinfo
->metric
)
622 || ((same
) && (rinfo
->metric
== rte
->metric
)
623 && (newinfo
.tag
!= rinfo
->tag
))
624 || (old_dist
> new_dist
)
625 || ((old_dist
!= new_dist
) && same
)) {
626 if (listcount(list
) == 1) {
627 if (newinfo
.metric
!= RIP_METRIC_INFINITY
)
628 rip_ecmp_replace(rip
, &newinfo
);
630 rip_ecmp_delete(rip
, rinfo
);
632 if (newinfo
.metric
< rinfo
->metric
)
633 rip_ecmp_replace(rip
, &newinfo
);
634 else if (newinfo
.metric
> rinfo
->metric
)
635 rip_ecmp_delete(rip
, rinfo
);
636 else if (new_dist
< old_dist
)
637 rip_ecmp_replace(rip
, &newinfo
);
638 else if (new_dist
> old_dist
)
639 rip_ecmp_delete(rip
, rinfo
);
641 int update
= CHECK_FLAG(rinfo
->flags
,
646 assert(newinfo
.metric
647 != RIP_METRIC_INFINITY
);
649 RIP_TIMER_OFF(rinfo
->t_timeout
);
650 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
651 memcpy(rinfo
, &newinfo
,
652 sizeof(struct rip_info
));
653 rip_timeout_update(rip
, rinfo
);
656 rip_zebra_ipv4_add(rip
, rp
);
658 /* - Set the route change flag on the
660 rinfo
= listgetdata(listhead(list
));
661 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
662 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
665 } else /* same & no change */
666 rip_timeout_update(rip
, rinfo
);
668 /* Unlock tempolary lock of the route. */
669 route_unlock_node(rp
);
673 /* Dump RIP packet */
674 static void rip_packet_dump(struct rip_packet
*packet
, int size
,
679 const char *command_str
;
680 char pbuf
[BUFSIZ
], nbuf
[BUFSIZ
];
684 /* Set command string. */
685 if (packet
->command
> 0 && packet
->command
< RIP_COMMAND_MAX
)
686 command_str
= lookup_msg(rip_msg
, packet
->command
, NULL
);
688 command_str
= "unknown";
690 /* Dump packet header. */
691 zlog_debug("%s %s version %d packet size %d", sndrcv
, command_str
,
692 packet
->version
, size
);
694 /* Dump each routing table entry. */
697 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
698 if (packet
->version
== RIPv2
) {
699 netmask
= ip_masklen(rte
->mask
);
701 if (rte
->family
== htons(RIP_FAMILY_AUTH
)) {
703 == htons(RIP_AUTH_SIMPLE_PASSWORD
)) {
704 p
= (uint8_t *)&rte
->prefix
;
707 " family 0x%X type %d auth string: %s",
710 } else if (rte
->tag
== htons(RIP_AUTH_MD5
)) {
711 struct rip_md5_info
*md5
;
713 md5
= (struct rip_md5_info
*)&packet
717 " family 0x%X type %d (MD5 authentication)",
721 " RIP-2 packet len %d Key ID %d"
723 ntohs(md5
->packet_len
),
724 md5
->keyid
, md5
->auth_len
);
725 zlog_debug(" Sequence Number %ld",
726 (unsigned long)ntohl(
728 } else if (rte
->tag
== htons(RIP_AUTH_DATA
)) {
729 p
= (uint8_t *)&rte
->prefix
;
732 " family 0x%X type %d (MD5 data)",
736 " MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
737 "%02X%02X%02X%02X%02X%02X%02X%02X",
738 p
[0], p
[1], p
[2], p
[3], p
[4],
739 p
[5], p
[6], p
[7], p
[8], p
[9],
740 p
[10], p
[11], p
[12], p
[13],
744 " family 0x%X type %d (Unknown auth type)",
750 " %s/%d -> %s family %d tag %" ROUTE_TAG_PRI
752 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
,
755 inet_ntop(AF_INET
, &rte
->nexthop
, nbuf
,
758 (route_tag_t
)ntohs(rte
->tag
),
759 (unsigned long)ntohl(rte
->metric
));
762 " %s family %d tag %" ROUTE_TAG_PRI
764 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
766 (route_tag_t
)ntohs(rte
->tag
),
767 (unsigned long)ntohl(rte
->metric
));
772 /* Check if the destination address is valid (unicast; not net 0
773 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
774 check net 0 because we accept default route. */
775 static int rip_destination_check(struct in_addr addr
)
777 uint32_t destination
;
779 /* Convert to host byte order. */
780 destination
= ntohl(addr
.s_addr
);
782 if (IPV4_NET127(destination
))
785 /* Net 0 may match to the default route. */
786 if (IPV4_NET0(destination
) && destination
!= 0)
789 /* Unicast address must belong to class A, B, C. */
790 if (IN_CLASSA(destination
))
792 if (IN_CLASSB(destination
))
794 if (IN_CLASSC(destination
))
800 /* RIP version 2 authentication. */
801 static int rip_auth_simple_password(struct rte
*rte
, struct sockaddr_in
*from
,
802 struct interface
*ifp
)
804 struct rip_interface
*ri
;
805 char *auth_str
= (char *)rte
+ offsetof(struct rte
, prefix
);
808 /* reject passwords with zeros in the middle of the string */
809 for (i
= strnlen(auth_str
, 16); i
< 16; i
++) {
810 if (auth_str
[i
] != '\0')
814 if (IS_RIP_DEBUG_EVENT
)
815 zlog_debug("RIPv2 simple password authentication from %s",
816 inet_ntoa(from
->sin_addr
));
820 if (ri
->auth_type
!= RIP_AUTH_SIMPLE_PASSWORD
821 || rte
->tag
!= htons(RIP_AUTH_SIMPLE_PASSWORD
))
824 /* Simple password authentication. */
826 if (strncmp(auth_str
, ri
->auth_str
, 16) == 0)
830 struct keychain
*keychain
;
833 keychain
= keychain_lookup(ri
->key_chain
);
834 if (keychain
== NULL
|| keychain
->key
== NULL
)
837 key
= key_match_for_accept(keychain
, auth_str
);
844 /* RIP version 2 authentication with MD5. */
845 static int rip_auth_md5(struct rip_packet
*packet
, struct sockaddr_in
*from
,
846 int length
, struct interface
*ifp
)
848 struct rip_interface
*ri
;
849 struct rip_md5_info
*md5
;
850 struct rip_md5_data
*md5data
;
851 struct keychain
*keychain
;
854 uint8_t digest
[RIP_AUTH_MD5_SIZE
];
856 char auth_str
[RIP_AUTH_MD5_SIZE
];
858 if (IS_RIP_DEBUG_EVENT
)
859 zlog_debug("RIPv2 MD5 authentication from %s",
860 inet_ntoa(from
->sin_addr
));
863 md5
= (struct rip_md5_info
*)&packet
->rte
;
865 /* Check auth type. */
866 if (ri
->auth_type
!= RIP_AUTH_MD5
|| md5
->type
!= htons(RIP_AUTH_MD5
))
869 /* If the authentication length is less than 16, then it must be wrong
871 * any interpretation of rfc2082. Some implementations also interpret
872 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka
873 * RIP_AUTH_MD5_COMPAT_SIZE.
875 if (!((md5
->auth_len
== RIP_AUTH_MD5_SIZE
)
876 || (md5
->auth_len
== RIP_AUTH_MD5_COMPAT_SIZE
))) {
877 if (IS_RIP_DEBUG_EVENT
)
879 "RIPv2 MD5 authentication, strange authentication "
885 /* grab and verify check packet length */
886 packet_len
= ntohs(md5
->packet_len
);
888 if (packet_len
> (length
- RIP_HEADER_SIZE
- RIP_AUTH_MD5_SIZE
)) {
889 if (IS_RIP_DEBUG_EVENT
)
891 "RIPv2 MD5 authentication, packet length field %d "
892 "greater than received length %d!",
893 md5
->packet_len
, length
);
897 /* retrieve authentication data */
898 md5data
= (struct rip_md5_data
*)(((uint8_t *)packet
) + packet_len
);
900 memset(auth_str
, 0, RIP_AUTH_MD5_SIZE
);
903 keychain
= keychain_lookup(ri
->key_chain
);
904 if (keychain
== NULL
)
907 key
= key_lookup_for_accept(keychain
, md5
->keyid
);
908 if (key
== NULL
|| key
->string
== NULL
)
911 strncpy(auth_str
, key
->string
, RIP_AUTH_MD5_SIZE
);
912 } else if (ri
->auth_str
)
913 strncpy(auth_str
, ri
->auth_str
, RIP_AUTH_MD5_SIZE
);
915 if (auth_str
[0] == 0)
918 /* MD5 digest authentication. */
919 memset(&ctx
, 0, sizeof(ctx
));
921 MD5Update(&ctx
, packet
, packet_len
+ RIP_HEADER_SIZE
);
922 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
923 MD5Final(digest
, &ctx
);
925 if (memcmp(md5data
->digest
, digest
, RIP_AUTH_MD5_SIZE
) == 0)
931 /* Pick correct auth string for sends, prepare auth_str buffer for use.
932 * (left justified and padded).
934 * presumes one of ri or key is valid, and that the auth strings they point
935 * to are nul terminated. If neither are present, auth_str will be fully
939 static void rip_auth_prepare_str_send(struct rip_interface
*ri
, struct key
*key
,
940 char *auth_str
, int len
)
944 memset(auth_str
, 0, len
);
945 if (key
&& key
->string
)
946 strncpy(auth_str
, key
->string
, len
);
947 else if (ri
->auth_str
)
948 strncpy(auth_str
, ri
->auth_str
, len
);
953 /* Write RIPv2 simple password authentication information
955 * auth_str is presumed to be 2 bytes and correctly prepared
956 * (left justified and zero padded).
958 static void rip_auth_simple_write(struct stream
*s
, char *auth_str
, int len
)
960 assert(s
&& len
== RIP_AUTH_SIMPLE_SIZE
);
962 stream_putw(s
, RIP_FAMILY_AUTH
);
963 stream_putw(s
, RIP_AUTH_SIMPLE_PASSWORD
);
964 stream_put(s
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
969 /* write RIPv2 MD5 "authentication header"
970 * (uses the auth key data field)
972 * Digest offset field is set to 0.
974 * returns: offset of the digest offset field, which must be set when
975 * length to the auth-data MD5 digest is known.
977 static size_t rip_auth_md5_ah_write(struct stream
*s
, struct rip_interface
*ri
,
982 assert(s
&& ri
&& ri
->auth_type
== RIP_AUTH_MD5
);
984 /* MD5 authentication. */
985 stream_putw(s
, RIP_FAMILY_AUTH
);
986 stream_putw(s
, RIP_AUTH_MD5
);
988 /* MD5 AH digest offset field.
990 * Set to placeholder value here, to true value when RIP-2 Packet length
991 * is known. Actual value is set in .....().
993 doff
= stream_get_endp(s
);
998 stream_putc(s
, key
->index
% 256);
1002 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
1003 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for
1005 * to be configurable.
1007 stream_putc(s
, ri
->md5_auth_len
);
1009 /* Sequence Number (non-decreasing). */
1010 /* RFC2080: The value used in the sequence number is
1011 arbitrary, but two suggestions are the time of the
1012 message's creation or a simple message counter. */
1013 stream_putl(s
, time(NULL
));
1015 /* Reserved field must be zero. */
1022 /* If authentication is in used, write the appropriate header
1023 * returns stream offset to which length must later be written
1024 * or 0 if this is not required
1026 static size_t rip_auth_header_write(struct stream
*s
, struct rip_interface
*ri
,
1027 struct key
*key
, char *auth_str
, int len
)
1029 assert(ri
->auth_type
!= RIP_NO_AUTH
);
1031 switch (ri
->auth_type
) {
1032 case RIP_AUTH_SIMPLE_PASSWORD
:
1033 rip_auth_prepare_str_send(ri
, key
, auth_str
, len
);
1034 rip_auth_simple_write(s
, auth_str
, len
);
1037 return rip_auth_md5_ah_write(s
, ri
, key
);
1043 /* Write RIPv2 MD5 authentication data trailer */
1044 static void rip_auth_md5_set(struct stream
*s
, struct rip_interface
*ri
,
1045 size_t doff
, char *auth_str
, int authlen
)
1049 unsigned char digest
[RIP_AUTH_MD5_SIZE
];
1051 /* Make it sure this interface is configured as MD5
1053 assert((ri
->auth_type
== RIP_AUTH_MD5
)
1054 && (authlen
== RIP_AUTH_MD5_SIZE
));
1057 /* Get packet length. */
1058 len
= stream_get_endp(s
);
1060 /* Check packet length. */
1061 if (len
< (RIP_HEADER_SIZE
+ RIP_RTE_SIZE
)) {
1064 "rip_auth_md5_set(): packet length %ld is less than minimum length.",
1069 /* Set the digest offset length in the header */
1070 stream_putw_at(s
, doff
, len
);
1072 /* Set authentication data. */
1073 stream_putw(s
, RIP_FAMILY_AUTH
);
1074 stream_putw(s
, RIP_AUTH_DATA
);
1076 /* Generate a digest for the RIP packet. */
1077 memset(&ctx
, 0, sizeof(ctx
));
1079 MD5Update(&ctx
, STREAM_DATA(s
), stream_get_endp(s
));
1080 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1081 MD5Final(digest
, &ctx
);
1083 /* Copy the digest to the packet. */
1084 stream_write(s
, digest
, RIP_AUTH_MD5_SIZE
);
1087 /* RIP routing information. */
1088 static void rip_response_process(struct rip_packet
*packet
, int size
,
1089 struct sockaddr_in
*from
,
1090 struct connected
*ifc
)
1092 struct rip_interface
*ri
= ifc
->ifp
->info
;
1093 struct rip
*rip
= ri
->rip
;
1096 struct prefix_ipv4 ifaddr
;
1097 struct prefix_ipv4 ifaddrclass
;
1100 memset(&ifaddr
, 0, sizeof(ifaddr
));
1101 /* We don't know yet. */
1104 /* The Response must be ignored if it is not from the RIP
1105 port. (RFC2453 - Sec. 3.9.2)*/
1106 if (from
->sin_port
!= htons(RIP_PORT_DEFAULT
)) {
1107 zlog_info("response doesn't come from RIP port: %d",
1109 rip_peer_bad_packet(rip
, from
);
1113 /* The datagram's IPv4 source address should be checked to see
1114 whether the datagram is from a valid neighbor; the source of the
1115 datagram must be on a directly connected network (RFC2453 - Sec.
1117 if (if_lookup_address((void *)&from
->sin_addr
, AF_INET
, rip
->vrf_id
)
1120 "This datagram doesn't came from a valid neighbor: %s",
1121 inet_ntoa(from
->sin_addr
));
1122 rip_peer_bad_packet(rip
, from
);
1126 /* It is also worth checking to see whether the response is from one
1127 of the router's own addresses. */
1129 ; /* Alredy done in rip_read () */
1131 /* Update RIP peer. */
1132 rip_peer_update(rip
, from
, packet
->version
);
1134 /* Set RTE pointer. */
1137 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
1138 /* RIPv2 authentication check. */
1139 /* If the Address Family Identifier of the first (and only the
1140 first) entry in the message is 0xFFFF, then the remainder of
1141 the entry contains the authentication. */
1142 /* If the packet gets here it means authentication enabled */
1143 /* Check is done in rip_read(). So, just skipping it */
1144 if (packet
->version
== RIPv2
&& rte
== packet
->rte
1145 && rte
->family
== htons(RIP_FAMILY_AUTH
))
1148 if (rte
->family
!= htons(AF_INET
)) {
1149 /* Address family check. RIP only supports AF_INET. */
1150 zlog_info("Unsupported family %d from %s.",
1152 inet_ntoa(from
->sin_addr
));
1156 /* - is the destination address valid (e.g., unicast; not net 0
1158 if (!rip_destination_check(rte
->prefix
)) {
1160 "Network is net 0 or net 127 or it is not unicast network");
1161 rip_peer_bad_route(rip
, from
);
1165 /* Convert metric value to host byte order. */
1166 rte
->metric
= ntohl(rte
->metric
);
1168 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1169 if (!(rte
->metric
>= 1 && rte
->metric
<= 16)) {
1170 zlog_info("Route's metric is not in the 1-16 range.");
1171 rip_peer_bad_route(rip
, from
);
1175 /* RIPv1 does not have nexthop value. */
1176 if (packet
->version
== RIPv1
&& rte
->nexthop
.s_addr
!= 0) {
1177 zlog_info("RIPv1 packet with nexthop value %s",
1178 inet_ntoa(rte
->nexthop
));
1179 rip_peer_bad_route(rip
, from
);
1183 /* That is, if the provided information is ignored, a possibly
1184 sub-optimal, but absolutely valid, route may be taken. If
1185 the received Next Hop is not directly reachable, it should be
1186 treated as 0.0.0.0. */
1187 if (packet
->version
== RIPv2
&& rte
->nexthop
.s_addr
!= 0) {
1190 /* Multicast address check. */
1191 addrval
= ntohl(rte
->nexthop
.s_addr
);
1192 if (IN_CLASSD(addrval
)) {
1194 "Nexthop %s is multicast address, skip this rte",
1195 inet_ntoa(rte
->nexthop
));
1199 if (!if_lookup_address((void *)&rte
->nexthop
, AF_INET
,
1201 struct route_node
*rn
;
1202 struct rip_info
*rinfo
;
1204 rn
= route_node_match_ipv4(rip
->table
,
1210 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1213 if (IS_RIP_DEBUG_EVENT
)
1215 "Next hop %s is on RIP network. Set nexthop to the packet's originator",
1218 rte
->nexthop
= rinfo
->from
;
1220 if (IS_RIP_DEBUG_EVENT
)
1222 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1225 rte
->nexthop
.s_addr
= 0;
1228 route_unlock_node(rn
);
1230 if (IS_RIP_DEBUG_EVENT
)
1232 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1235 rte
->nexthop
.s_addr
= 0;
1240 /* For RIPv1, there won't be a valid netmask.
1242 This is a best guess at the masks. If everyone was using old
1243 Ciscos before the 'ip subnet zero' option, it would be almost
1246 Cisco summarize ripv1 advertisements to the classful boundary
1247 (/16 for class B's) except when the RIP packet does to inside
1248 the classful network in question. */
1250 if ((packet
->version
== RIPv1
&& rte
->prefix
.s_addr
!= 0)
1251 || (packet
->version
== RIPv2
1252 && (rte
->prefix
.s_addr
!= 0
1253 && rte
->mask
.s_addr
== 0))) {
1254 uint32_t destination
;
1256 if (subnetted
== -1) {
1257 memcpy(&ifaddr
, ifc
->address
,
1258 sizeof(struct prefix_ipv4
));
1259 memcpy(&ifaddrclass
, &ifaddr
,
1260 sizeof(struct prefix_ipv4
));
1261 apply_classful_mask_ipv4(&ifaddrclass
);
1263 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1267 destination
= ntohl(rte
->prefix
.s_addr
);
1269 if (IN_CLASSA(destination
))
1270 masklen2ip(8, &rte
->mask
);
1271 else if (IN_CLASSB(destination
))
1272 masklen2ip(16, &rte
->mask
);
1273 else if (IN_CLASSC(destination
))
1274 masklen2ip(24, &rte
->mask
);
1277 masklen2ip(ifaddrclass
.prefixlen
,
1278 (struct in_addr
*)&destination
);
1279 if ((subnetted
== 1)
1280 && ((rte
->prefix
.s_addr
& destination
)
1281 == ifaddrclass
.prefix
.s_addr
)) {
1282 masklen2ip(ifaddr
.prefixlen
, &rte
->mask
);
1283 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1284 != rte
->prefix
.s_addr
)
1285 masklen2ip(32, &rte
->mask
);
1286 if (IS_RIP_DEBUG_EVENT
)
1287 zlog_debug("Subnetted route %s",
1288 inet_ntoa(rte
->prefix
));
1290 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1291 != rte
->prefix
.s_addr
)
1295 if (IS_RIP_DEBUG_EVENT
) {
1296 zlog_debug("Resultant route %s",
1297 inet_ntoa(rte
->prefix
));
1298 zlog_debug("Resultant mask %s",
1299 inet_ntoa(rte
->mask
));
1303 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1304 ignore the entry. */
1305 if ((packet
->version
== RIPv2
) && (rte
->mask
.s_addr
!= 0)
1306 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1307 != rte
->prefix
.s_addr
)) {
1309 "RIPv2 address %s is not mask /%d applied one",
1310 inet_ntoa(rte
->prefix
), ip_masklen(rte
->mask
));
1311 rip_peer_bad_route(rip
, from
);
1315 /* Default route's netmask is ignored. */
1316 if (packet
->version
== RIPv2
&& (rte
->prefix
.s_addr
== 0)
1317 && (rte
->mask
.s_addr
!= 0)) {
1318 if (IS_RIP_DEBUG_EVENT
)
1320 "Default route with non-zero netmask. Set zero to netmask");
1321 rte
->mask
.s_addr
= 0;
1324 /* Routing table updates. */
1325 rip_rte_process(rte
, from
, ifc
->ifp
);
1329 /* Make socket for RIP protocol. */
1330 int rip_create_socket(void)
1334 struct sockaddr_in addr
;
1336 memset(&addr
, 0, sizeof(struct sockaddr_in
));
1337 addr
.sin_family
= AF_INET
;
1338 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1339 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1340 addr
.sin_len
= sizeof(struct sockaddr_in
);
1341 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1342 /* sending port must always be the RIP port */
1343 addr
.sin_port
= htons(RIP_PORT_DEFAULT
);
1345 /* Make datagram socket. */
1346 sock
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
1348 flog_err_sys(EC_LIB_SOCKET
, "Cannot create UDP socket: %s",
1349 safe_strerror(errno
));
1353 sockopt_broadcast(sock
);
1354 sockopt_reuseaddr(sock
);
1355 sockopt_reuseport(sock
);
1356 setsockopt_ipv4_multicast_loop(sock
, 0);
1357 #ifdef IPTOS_PREC_INTERNETCONTROL
1358 setsockopt_ipv4_tos(sock
, IPTOS_PREC_INTERNETCONTROL
);
1361 frr_elevate_privs(&ripd_privs
) {
1362 setsockopt_so_recvbuf(sock
, RIP_UDP_RCV_BUF
);
1363 if ((ret
= bind(sock
, (struct sockaddr
*)&addr
, sizeof(addr
)))
1365 zlog_err("%s: Can't bind socket %d to %s port %d: %s",
1366 __func__
, sock
, inet_ntoa(addr
.sin_addr
),
1367 (int)ntohs(addr
.sin_port
),
1368 safe_strerror(errno
));
1378 /* RIP packet send to destination address, on interface denoted by
1379 * by connected argument. NULL to argument denotes destination should be
1380 * should be RIP multicast group
1382 static int rip_send_packet(uint8_t *buf
, int size
, struct sockaddr_in
*to
,
1383 struct connected
*ifc
)
1385 struct rip_interface
*ri
;
1388 struct sockaddr_in sin
;
1392 struct cmsghdr
*cmsgptr
;
1393 char adata
[256] = {};
1394 struct in_pktinfo
*pkt
;
1395 #endif /* GNU_LINUX */
1397 assert(ifc
!= NULL
);
1398 ri
= ifc
->ifp
->info
;
1401 if (IS_RIP_DEBUG_PACKET
) {
1402 #define ADDRESS_SIZE 20
1403 char dst
[ADDRESS_SIZE
];
1404 dst
[ADDRESS_SIZE
- 1] = '\0';
1407 strncpy(dst
, inet_ntoa(to
->sin_addr
), ADDRESS_SIZE
- 1);
1409 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1410 strncpy(dst
, inet_ntoa(sin
.sin_addr
), ADDRESS_SIZE
- 1);
1413 zlog_debug("rip_send_packet %s > %s (%s)",
1414 inet_ntoa(ifc
->address
->u
.prefix4
), dst
,
1418 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
1420 * ZEBRA_IFA_SECONDARY is set on linux when an interface is
1422 * with multiple addresses on the same subnet: the first address
1423 * on the subnet is configured "primary", and all subsequent
1425 * on that subnet are treated as "secondary" addresses.
1426 * In order to avoid routing-table bloat on other rip listeners,
1427 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY
1429 * XXX Since Linux is the only system for which the
1430 * ZEBRA_IFA_SECONDARY
1431 * flag is set, we would end up sending a packet for a
1433 * source address on non-linux systems.
1435 if (IS_RIP_DEBUG_PACKET
)
1436 zlog_debug("duplicate dropped");
1440 /* Make destination address. */
1441 memset(&sin
, 0, sizeof(struct sockaddr_in
));
1442 sin
.sin_family
= AF_INET
;
1443 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1444 sin
.sin_len
= sizeof(struct sockaddr_in
);
1445 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1447 /* When destination is specified, use it's port and address. */
1449 sin
.sin_port
= to
->sin_port
;
1450 sin
.sin_addr
= to
->sin_addr
;
1452 sin
.sin_port
= htons(RIP_PORT_DEFAULT
);
1453 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1455 rip_interface_multicast_set(rip
->sock
, ifc
);
1458 memset(&msg
, 0, sizeof(msg
));
1459 msg
.msg_name
= (void *)&sin
;
1460 msg
.msg_namelen
= sizeof(struct sockaddr_in
);
1467 msg
.msg_control
= (void *)adata
;
1468 msg
.msg_controllen
= CMSG_SPACE(sizeof(struct in_pktinfo
));
1470 cmsgptr
= (struct cmsghdr
*)adata
;
1471 cmsgptr
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
1472 cmsgptr
->cmsg_level
= IPPROTO_IP
;
1473 cmsgptr
->cmsg_type
= IP_PKTINFO
;
1474 pkt
= (struct in_pktinfo
*)CMSG_DATA(cmsgptr
);
1475 pkt
->ipi_ifindex
= ifc
->ifp
->ifindex
;
1476 #endif /* GNU_LINUX */
1478 ret
= sendmsg(rip
->sock
, &msg
, 0);
1480 if (IS_RIP_DEBUG_EVENT
)
1481 zlog_debug("SEND to %s.%d", inet_ntoa(sin
.sin_addr
),
1482 ntohs(sin
.sin_port
));
1485 zlog_warn("can't send packet : %s", safe_strerror(errno
));
1490 /* Add redistributed route to RIP table. */
1491 void rip_redistribute_add(struct rip
*rip
, int type
, int sub_type
,
1492 struct prefix_ipv4
*p
, struct nexthop
*nh
,
1493 unsigned int metric
, unsigned char distance
,
1497 struct route_node
*rp
= NULL
;
1498 struct rip_info
*rinfo
= NULL
, newinfo
;
1499 struct list
*list
= NULL
;
1501 /* Redistribute route */
1502 ret
= rip_destination_check(p
->prefix
);
1506 rp
= route_node_get(rip
->table
, (struct prefix
*)p
);
1508 memset(&newinfo
, 0, sizeof(struct rip_info
));
1509 newinfo
.type
= type
;
1510 newinfo
.sub_type
= sub_type
;
1512 newinfo
.external_metric
= metric
;
1513 newinfo
.distance
= distance
;
1514 if (tag
<= UINT16_MAX
) /* RIP only supports 16 bit tags */
1519 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
1520 rinfo
= listgetdata(listhead(list
));
1522 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
1523 && rinfo
->sub_type
== RIP_ROUTE_INTERFACE
1524 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
1525 route_unlock_node(rp
);
1529 /* Manually configured RIP route check. */
1530 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1531 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
1532 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))) {
1533 if (type
!= ZEBRA_ROUTE_RIP
1534 || ((sub_type
!= RIP_ROUTE_STATIC
)
1535 && (sub_type
!= RIP_ROUTE_DEFAULT
))) {
1536 route_unlock_node(rp
);
1541 (void)rip_ecmp_replace(rip
, &newinfo
);
1542 route_unlock_node(rp
);
1544 (void)rip_ecmp_add(rip
, &newinfo
);
1546 if (IS_RIP_DEBUG_EVENT
) {
1547 zlog_debug("Redistribute new prefix %s/%d",
1548 inet_ntoa(p
->prefix
), p
->prefixlen
);
1551 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
1554 /* Delete redistributed route from RIP table. */
1555 void rip_redistribute_delete(struct rip
*rip
, int type
, int sub_type
,
1556 struct prefix_ipv4
*p
, ifindex_t ifindex
)
1559 struct route_node
*rp
;
1560 struct rip_info
*rinfo
;
1562 ret
= rip_destination_check(p
->prefix
);
1566 rp
= route_node_lookup(rip
->table
, (struct prefix
*)p
);
1568 struct list
*list
= rp
->info
;
1570 if (list
!= NULL
&& listcount(list
) != 0) {
1571 rinfo
= listgetdata(listhead(list
));
1572 if (rinfo
!= NULL
&& rinfo
->type
== type
1573 && rinfo
->sub_type
== sub_type
1574 && rinfo
->nh
.ifindex
== ifindex
) {
1575 /* Perform poisoned reverse. */
1576 rinfo
->metric
= RIP_METRIC_INFINITY
;
1577 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
1578 rip_garbage_collect
,
1580 RIP_TIMER_OFF(rinfo
->t_timeout
);
1581 rinfo
->flags
|= RIP_RTF_CHANGED
;
1583 if (IS_RIP_DEBUG_EVENT
)
1585 "Poison %s/%d on the interface %s with an "
1586 "infinity metric [delete]",
1587 inet_ntoa(p
->prefix
),
1589 ifindex2ifname(ifindex
,
1592 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
1595 route_unlock_node(rp
);
1599 /* Response to request called from rip_read ().*/
1600 static void rip_request_process(struct rip_packet
*packet
, int size
,
1601 struct sockaddr_in
*from
, struct connected
*ifc
)
1606 struct prefix_ipv4 p
;
1607 struct route_node
*rp
;
1608 struct rip_info
*rinfo
;
1609 struct rip_interface
*ri
;
1611 /* Does not reponse to the requests on the loopback interfaces */
1612 if (if_is_loopback(ifc
->ifp
))
1615 /* Check RIP process is enabled on this interface. */
1616 ri
= ifc
->ifp
->info
;
1621 /* When passive interface is specified, suppress responses */
1625 /* RIP peer update. */
1626 rip_peer_update(rip
, from
, packet
->version
);
1628 lim
= ((caddr_t
)packet
) + size
;
1631 /* The Request is processed entry by entry. If there are no
1632 entries, no response is given. */
1633 if (lim
== (caddr_t
)rte
)
1636 /* There is one special case. If there is exactly one entry in the
1637 request, and it has an address family identifier of zero and a
1638 metric of infinity (i.e., 16), then this is a request to send the
1639 entire routing table. */
1640 if (lim
== ((caddr_t
)(rte
+ 1)) && ntohs(rte
->family
) == 0
1641 && ntohl(rte
->metric
) == RIP_METRIC_INFINITY
) {
1642 /* All route with split horizon */
1643 rip_output_process(ifc
, from
, rip_all_route
, packet
->version
);
1645 if (ntohs(rte
->family
) != AF_INET
)
1648 /* Examine the list of RTEs in the Request one by one. For each
1649 entry, look up the destination in the router's routing
1650 database and, if there is a route, put that route's metric in
1651 the metric field of the RTE. If there is no explicit route
1652 to the specified destination, put infinity in the metric
1653 field. Once all the entries have been filled in, change the
1654 command from Request to Response and send the datagram back
1655 to the requestor. */
1658 for (; ((caddr_t
)rte
) < lim
; rte
++) {
1659 p
.prefix
= rte
->prefix
;
1660 p
.prefixlen
= ip_masklen(rte
->mask
);
1661 apply_mask_ipv4(&p
);
1663 rp
= route_node_lookup(rip
->table
, (struct prefix
*)&p
);
1665 rinfo
= listgetdata(
1666 listhead((struct list
*)rp
->info
));
1667 rte
->metric
= htonl(rinfo
->metric
);
1668 route_unlock_node(rp
);
1670 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
1672 packet
->command
= RIP_RESPONSE
;
1674 (void)rip_send_packet((uint8_t *)packet
, size
, from
, ifc
);
1676 rip
->counters
.queries
++;
1679 /* First entry point of RIP packet. */
1680 static int rip_read(struct thread
*t
)
1682 struct rip
*rip
= THREAD_ARG(t
);
1686 union rip_buf rip_buf
;
1687 struct rip_packet
*packet
;
1688 struct sockaddr_in from
;
1692 struct interface
*ifp
= NULL
;
1693 struct connected
*ifc
;
1694 struct rip_interface
*ri
;
1697 /* Fetch socket then register myself. */
1698 sock
= THREAD_FD(t
);
1701 /* Add myself to tne next event */
1702 rip_event(rip
, RIP_READ
, sock
);
1704 /* RIPd manages only IPv4. */
1705 memset(&from
, 0, sizeof(struct sockaddr_in
));
1706 fromlen
= sizeof(struct sockaddr_in
);
1708 len
= recvfrom(sock
, (char *)&rip_buf
.buf
, sizeof(rip_buf
.buf
), 0,
1709 (struct sockaddr
*)&from
, &fromlen
);
1711 zlog_info("recvfrom failed: %s", safe_strerror(errno
));
1715 /* Check is this packet comming from myself? */
1716 if (if_check_address(rip
, from
.sin_addr
)) {
1717 if (IS_RIP_DEBUG_PACKET
)
1718 zlog_debug("ignore packet comes from myself");
1722 /* Which interface is this packet comes from. */
1723 ifc
= if_lookup_address((void *)&from
.sin_addr
, AF_INET
, rip
->vrf_id
);
1727 /* RIP packet received */
1728 if (IS_RIP_DEBUG_EVENT
)
1729 zlog_debug("RECV packet from %s port %d on %s",
1730 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1731 ifp
? ifp
->name
: "unknown");
1733 /* If this packet come from unknown interface, ignore it. */
1736 "rip_read: cannot find interface for packet from %s port %d",
1737 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
));
1742 p
.u
.prefix4
= from
.sin_addr
;
1743 p
.prefixlen
= IPV4_MAX_BITLEN
;
1745 ifc
= connected_lookup_prefix(ifp
, &p
);
1749 "rip_read: cannot find connected address for packet from %s "
1750 "port %d on interface %s",
1751 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1756 /* Packet length check. */
1757 if (len
< RIP_PACKET_MINSIZ
) {
1758 zlog_warn("packet size %d is smaller than minimum size %d", len
,
1760 rip_peer_bad_packet(rip
, &from
);
1763 if (len
> RIP_PACKET_MAXSIZ
) {
1764 zlog_warn("packet size %d is larger than max size %d", len
,
1766 rip_peer_bad_packet(rip
, &from
);
1770 /* Packet alignment check. */
1771 if ((len
- RIP_PACKET_MINSIZ
) % 20) {
1772 zlog_warn("packet size %d is wrong for RIP packet alignment",
1774 rip_peer_bad_packet(rip
, &from
);
1778 /* Set RTE number. */
1779 rtenum
= ((len
- RIP_PACKET_MINSIZ
) / 20);
1781 /* For easy to handle. */
1782 packet
= &rip_buf
.rip_packet
;
1784 /* RIP version check. */
1785 if (packet
->version
== 0) {
1786 zlog_info("version 0 with command %d received.",
1788 rip_peer_bad_packet(rip
, &from
);
1792 /* Dump RIP packet. */
1793 if (IS_RIP_DEBUG_RECV
)
1794 rip_packet_dump(packet
, len
, "RECV");
1796 /* RIP version adjust. This code should rethink now. RFC1058 says
1797 that "Version 1 implementations are to ignore this extra data and
1798 process only the fields specified in this document.". So RIPv3
1799 packet should be treated as RIPv1 ignoring must be zero field. */
1800 if (packet
->version
> RIPv2
)
1801 packet
->version
= RIPv2
;
1803 /* Is RIP running or is this RIP neighbor ?*/
1805 if (!ri
->running
&& !rip_neighbor_lookup(rip
, &from
)) {
1806 if (IS_RIP_DEBUG_EVENT
)
1807 zlog_debug("RIP is not enabled on interface %s.",
1809 rip_peer_bad_packet(rip
, &from
);
1813 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1814 vrecv
= ((ri
->ri_receive
== RI_RIP_UNSPEC
) ? rip
->version_recv
1816 if (vrecv
== RI_RIP_VERSION_NONE
1817 || ((packet
->version
== RIPv1
) && !(vrecv
& RIPv1
))
1818 || ((packet
->version
== RIPv2
) && !(vrecv
& RIPv2
))) {
1819 if (IS_RIP_DEBUG_PACKET
)
1821 " packet's v%d doesn't fit to if version spec",
1823 rip_peer_bad_packet(rip
, &from
);
1827 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1828 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1829 accepted; authenticated RIP-2 messages shall be discarded. */
1830 if ((ri
->auth_type
== RIP_NO_AUTH
) && rtenum
1831 && (packet
->version
== RIPv2
)
1832 && (packet
->rte
->family
== htons(RIP_FAMILY_AUTH
))) {
1833 if (IS_RIP_DEBUG_EVENT
)
1835 "packet RIPv%d is dropped because authentication disabled",
1837 ripd_notif_send_auth_type_failure(ifp
->name
);
1838 rip_peer_bad_packet(rip
, &from
);
1843 If the router is configured to authenticate RIP-2 messages, then
1844 RIP-1 messages and RIP-2 messages which pass authentication
1845 testing shall be accepted; unauthenticated and failed
1846 authentication RIP-2 messages shall be discarded. For maximum
1847 security, RIP-1 messages should be ignored when authentication is
1848 in use (see section 4.1); otherwise, the routing information from
1849 authenticated messages will be propagated by RIP-1 routers in an
1850 unauthenticated manner.
1852 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1853 * always reply regardless of authentication settings, because:
1855 * - if there other authorised routers on-link, the REQUESTor can
1856 * passively obtain the routing updates anyway
1857 * - if there are no other authorised routers on-link, RIP can
1858 * easily be disabled for the link to prevent giving out information
1859 * on state of this routers RIP routing table..
1861 * I.e. if RIPv1 has any place anymore these days, it's as a very
1862 * simple way to distribute routing information (e.g. to embedded
1863 * hosts / appliances) and the ability to give out RIPv1
1864 * routing-information freely, while still requiring RIPv2
1865 * authentication for any RESPONSEs might be vaguely useful.
1867 if (ri
->auth_type
!= RIP_NO_AUTH
&& packet
->version
== RIPv1
) {
1868 /* Discard RIPv1 messages other than REQUESTs */
1869 if (packet
->command
!= RIP_REQUEST
) {
1870 if (IS_RIP_DEBUG_PACKET
)
1873 " dropped because authentication enabled");
1874 ripd_notif_send_auth_type_failure(ifp
->name
);
1875 rip_peer_bad_packet(rip
, &from
);
1878 } else if (ri
->auth_type
!= RIP_NO_AUTH
) {
1879 const char *auth_desc
;
1882 /* There definitely is no authentication in the packet.
1884 if (IS_RIP_DEBUG_PACKET
)
1886 "RIPv2 authentication failed: no auth RTE in packet");
1887 ripd_notif_send_auth_type_failure(ifp
->name
);
1888 rip_peer_bad_packet(rip
, &from
);
1892 /* First RTE must be an Authentication Family RTE */
1893 if (packet
->rte
->family
!= htons(RIP_FAMILY_AUTH
)) {
1894 if (IS_RIP_DEBUG_PACKET
)
1897 " dropped because authentication enabled");
1898 ripd_notif_send_auth_type_failure(ifp
->name
);
1899 rip_peer_bad_packet(rip
, &from
);
1903 /* Check RIPv2 authentication. */
1904 switch (ntohs(packet
->rte
->tag
)) {
1905 case RIP_AUTH_SIMPLE_PASSWORD
:
1906 auth_desc
= "simple";
1907 ret
= rip_auth_simple_password(packet
->rte
, &from
, ifp
);
1912 ret
= rip_auth_md5(packet
, &from
, len
, ifp
);
1913 /* Reset RIP packet length to trim MD5 data. */
1919 auth_desc
= "unknown type";
1920 if (IS_RIP_DEBUG_PACKET
)
1922 "RIPv2 Unknown authentication type %d",
1923 ntohs(packet
->rte
->tag
));
1927 if (IS_RIP_DEBUG_PACKET
)
1928 zlog_debug("RIPv2 %s authentication success",
1931 if (IS_RIP_DEBUG_PACKET
)
1932 zlog_debug("RIPv2 %s authentication failure",
1934 ripd_notif_send_auth_failure(ifp
->name
);
1935 rip_peer_bad_packet(rip
, &from
);
1940 /* Process each command. */
1941 switch (packet
->command
) {
1943 rip_response_process(packet
, len
, &from
, ifc
);
1947 rip_request_process(packet
, len
, &from
, ifc
);
1952 "Obsolete command %s received, please sent it to routed",
1953 lookup_msg(rip_msg
, packet
->command
, NULL
));
1954 rip_peer_bad_packet(rip
, &from
);
1956 case RIP_POLL_ENTRY
:
1957 zlog_info("Obsolete command %s received",
1958 lookup_msg(rip_msg
, packet
->command
, NULL
));
1959 rip_peer_bad_packet(rip
, &from
);
1962 zlog_info("Unknown RIP command %d received", packet
->command
);
1963 rip_peer_bad_packet(rip
, &from
);
1970 /* Write routing table entry to the stream and return next index of
1971 the routing table entry in the stream. */
1972 static int rip_write_rte(int num
, struct stream
*s
, struct prefix_ipv4
*p
,
1973 uint8_t version
, struct rip_info
*rinfo
)
1975 struct in_addr mask
;
1977 /* Write routing table entry. */
1978 if (version
== RIPv1
) {
1979 stream_putw(s
, AF_INET
);
1981 stream_put_ipv4(s
, p
->prefix
.s_addr
);
1982 stream_put_ipv4(s
, 0);
1983 stream_put_ipv4(s
, 0);
1984 stream_putl(s
, rinfo
->metric_out
);
1986 masklen2ip(p
->prefixlen
, &mask
);
1988 stream_putw(s
, AF_INET
);
1989 stream_putw(s
, rinfo
->tag_out
);
1990 stream_put_ipv4(s
, p
->prefix
.s_addr
);
1991 stream_put_ipv4(s
, mask
.s_addr
);
1992 stream_put_ipv4(s
, rinfo
->nexthop_out
.s_addr
);
1993 stream_putl(s
, rinfo
->metric_out
);
1999 /* Send update to the ifp or spcified neighbor. */
2000 void rip_output_process(struct connected
*ifc
, struct sockaddr_in
*to
,
2001 int route_type
, uint8_t version
)
2006 struct route_node
*rp
;
2007 struct rip_info
*rinfo
;
2008 struct rip_interface
*ri
;
2009 struct prefix_ipv4
*p
;
2010 struct prefix_ipv4 classfull
;
2011 struct prefix_ipv4 ifaddrclass
;
2012 struct key
*key
= NULL
;
2013 /* this might need to made dynamic if RIP ever supported auth methods
2014 with larger key string sizes */
2015 char auth_str
[RIP_AUTH_SIMPLE_SIZE
];
2016 size_t doff
= 0; /* offset of digest offset field */
2020 struct list
*list
= NULL
;
2021 struct listnode
*listnode
= NULL
;
2023 /* Logging output event. */
2024 if (IS_RIP_DEBUG_EVENT
) {
2026 zlog_debug("update routes to neighbor %s",
2027 inet_ntoa(to
->sin_addr
));
2029 zlog_debug("update routes on interface %s ifindex %d",
2030 ifc
->ifp
->name
, ifc
->ifp
->ifindex
);
2033 /* Get RIP interface. */
2034 ri
= ifc
->ifp
->info
;
2037 /* Set output stream. */
2040 /* Reset stream and RTE counter. */
2042 rtemax
= RIP_MAX_RTE
;
2044 /* If output interface is in simple password authentication mode, we
2045 need space for authentication data. */
2046 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2049 /* If output interface is in MD5 authentication mode, we need space
2050 for authentication header and data. */
2051 if (ri
->auth_type
== RIP_AUTH_MD5
)
2054 /* If output interface is in simple password authentication mode
2055 and string or keychain is specified we need space for auth. data */
2056 if (ri
->auth_type
!= RIP_NO_AUTH
) {
2057 if (ri
->key_chain
) {
2058 struct keychain
*keychain
;
2060 keychain
= keychain_lookup(ri
->key_chain
);
2062 key
= key_lookup_for_send(keychain
);
2064 /* to be passed to auth functions later */
2065 rip_auth_prepare_str_send(ri
, key
, auth_str
,
2066 RIP_AUTH_SIMPLE_SIZE
);
2067 if (strlen(auth_str
) == 0)
2071 if (version
== RIPv1
) {
2072 memcpy(&ifaddrclass
, ifc
->address
, sizeof(struct prefix_ipv4
));
2073 apply_classful_mask_ipv4(&ifaddrclass
);
2075 if (ifc
->address
->prefixlen
> ifaddrclass
.prefixlen
)
2079 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2080 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
2081 rinfo
= listgetdata(listhead(list
));
2082 /* For RIPv1, if we are subnetted, output subnets in our
2084 /* that have the same mask as the output "interface".
2086 /* networks, only the classfull version is output. */
2088 if (version
== RIPv1
) {
2089 p
= (struct prefix_ipv4
*)&rp
->p
;
2091 if (IS_RIP_DEBUG_PACKET
)
2093 "RIPv1 mask check, %s/%d considered for output",
2094 inet_ntoa(rp
->p
.u
.prefix4
),
2099 (struct prefix
*)&ifaddrclass
,
2101 if ((ifc
->address
->prefixlen
2103 && (rp
->p
.prefixlen
!= 32))
2106 memcpy(&classfull
, &rp
->p
,
2107 sizeof(struct prefix_ipv4
));
2108 apply_classful_mask_ipv4(&classfull
);
2109 if (rp
->p
.u
.prefix4
.s_addr
!= 0
2110 && classfull
.prefixlen
2114 if (IS_RIP_DEBUG_PACKET
)
2116 "RIPv1 mask check, %s/%d made it through",
2117 inet_ntoa(rp
->p
.u
.prefix4
),
2120 p
= (struct prefix_ipv4
*)&rp
->p
;
2122 /* Apply output filters. */
2123 ret
= rip_filter(RIP_FILTER_OUT
, p
, ri
);
2127 /* Changed route only output. */
2128 if (route_type
== rip_changed_route
2129 && (!(rinfo
->flags
& RIP_RTF_CHANGED
)))
2132 /* Split horizon. */
2133 /* if (split_horizon == rip_split_horizon) */
2134 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
) {
2136 * We perform split horizon for RIP and
2138 * For rip routes, we want to suppress the route
2140 * end up sending the route back on the
2142 * learned it from, with a higher metric. For
2144 * we suppress the route if the prefix is a
2146 * source address that we are going to use for
2148 * (in order to handle the case when multiple
2150 * configured on the same interface).
2153 struct rip_info
*tmp_rinfo
= NULL
;
2154 struct connected
*tmp_ifc
= NULL
;
2156 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2158 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2159 && tmp_rinfo
->nh
.ifindex
2160 == ifc
->ifp
->ifindex
) {
2166 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2167 for (ALL_LIST_ELEMENTS_RO(
2168 ifc
->ifp
->connected
,
2172 tmp_ifc
->address
)) {
2182 /* Preparation for route-map. */
2183 rinfo
->metric_set
= 0;
2184 rinfo
->nexthop_out
.s_addr
= 0;
2185 rinfo
->metric_out
= rinfo
->metric
;
2186 rinfo
->tag_out
= rinfo
->tag
;
2187 rinfo
->ifindex_out
= ifc
->ifp
->ifindex
;
2189 /* In order to avoid some local loops,
2190 * if the RIP route has a nexthop via this interface,
2192 * otherwise set it to 0. The nexthop should not be
2194 * beyond the local broadcast/multicast area in order
2195 * to avoid an IGP multi-level recursive look-up.
2198 if (rinfo
->nh
.ifindex
== ifc
->ifp
->ifindex
)
2199 rinfo
->nexthop_out
= rinfo
->nh
.gate
.ipv4
;
2201 /* Interface route-map */
2202 if (ri
->routemap
[RIP_FILTER_OUT
]) {
2203 ret
= route_map_apply(
2204 ri
->routemap
[RIP_FILTER_OUT
],
2205 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2207 if (ret
== RMAP_DENYMATCH
) {
2208 if (IS_RIP_DEBUG_PACKET
)
2210 "RIP %s/%d is filtered by route-map out",
2211 inet_ntoa(p
->prefix
),
2217 /* Apply redistribute route map - continue, if deny */
2218 if (rip
->route_map
[rinfo
->type
].name
2219 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2220 ret
= route_map_apply(
2221 rip
->route_map
[rinfo
->type
].map
,
2222 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2224 if (ret
== RMAP_DENYMATCH
) {
2225 if (IS_RIP_DEBUG_PACKET
)
2227 "%s/%d is filtered by route-map",
2228 inet_ntoa(p
->prefix
),
2234 /* When route-map does not set metric. */
2235 if (!rinfo
->metric_set
) {
2236 /* If redistribute metric is set. */
2237 if (rip
->route_map
[rinfo
->type
].metric_config
2238 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
2240 rip
->route_map
[rinfo
->type
]
2243 /* If the route is not connected or
2245 one, use default-metric value*/
2246 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2248 != ZEBRA_ROUTE_CONNECT
2250 != RIP_METRIC_INFINITY
)
2252 rip
->default_metric
;
2256 /* Apply offset-list */
2257 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2258 rip_offset_list_apply_out(p
, ifc
->ifp
,
2259 &rinfo
->metric_out
);
2261 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2262 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2264 /* Perform split-horizon with poisoned reverse
2265 * for RIP and connected routes.
2267 if (ri
->split_horizon
2268 == RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2270 * We perform split horizon for RIP and
2272 * For rip routes, we want to suppress the route
2274 * end up sending the route back on the
2276 * learned it from, with a higher metric. For
2278 * we suppress the route if the prefix is a
2280 * source address that we are going to use for
2282 * (in order to handle the case when multiple
2284 * configured on the same interface).
2286 struct rip_info
*tmp_rinfo
= NULL
;
2287 struct connected
*tmp_ifc
= NULL
;
2289 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2291 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2292 && tmp_rinfo
->nh
.ifindex
2293 == ifc
->ifp
->ifindex
)
2295 RIP_METRIC_INFINITY
;
2297 if (rinfo
->metric_out
!= RIP_METRIC_INFINITY
2298 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2299 for (ALL_LIST_ELEMENTS_RO(
2300 ifc
->ifp
->connected
,
2304 tmp_ifc
->address
)) {
2306 RIP_METRIC_INFINITY
;
2312 /* Prepare preamble, auth headers, if needs be */
2314 stream_putc(s
, RIP_RESPONSE
);
2315 stream_putc(s
, version
);
2318 /* auth header for !v1 && !no_auth */
2319 if ((ri
->auth_type
!= RIP_NO_AUTH
)
2320 && (version
!= RIPv1
))
2321 doff
= rip_auth_header_write(
2322 s
, ri
, key
, auth_str
,
2323 RIP_AUTH_SIMPLE_SIZE
);
2326 /* Write RTE to the stream. */
2327 num
= rip_write_rte(num
, s
, p
, version
, rinfo
);
2328 if (num
== rtemax
) {
2329 if (version
== RIPv2
2330 && ri
->auth_type
== RIP_AUTH_MD5
)
2331 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2332 RIP_AUTH_SIMPLE_SIZE
);
2334 ret
= rip_send_packet(STREAM_DATA(s
),
2335 stream_get_endp(s
), to
,
2338 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2339 rip_packet_dump((struct rip_packet
*)
2348 /* Flush unwritten RTE. */
2350 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2351 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2352 RIP_AUTH_SIMPLE_SIZE
);
2354 ret
= rip_send_packet(STREAM_DATA(s
), stream_get_endp(s
), to
,
2357 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2358 rip_packet_dump((struct rip_packet
*)STREAM_DATA(s
),
2359 stream_get_endp(s
), "SEND");
2363 /* Statistics updates. */
2367 /* Send RIP packet to the interface. */
2368 static void rip_update_interface(struct connected
*ifc
, uint8_t version
,
2371 struct interface
*ifp
= ifc
->ifp
;
2372 struct rip_interface
*ri
= ifp
->info
;
2373 struct sockaddr_in to
;
2375 /* When RIP version is 2 and multicast enable interface. */
2376 if (version
== RIPv2
&& !ri
->v2_broadcast
&& if_is_multicast(ifp
)) {
2377 if (IS_RIP_DEBUG_EVENT
)
2378 zlog_debug("multicast announce on %s ", ifp
->name
);
2380 rip_output_process(ifc
, NULL
, route_type
, version
);
2384 /* If we can't send multicast packet, send it with unicast. */
2385 if (if_is_broadcast(ifp
) || if_is_pointopoint(ifp
)) {
2386 if (ifc
->address
->family
== AF_INET
) {
2387 /* Destination address and port setting. */
2388 memset(&to
, 0, sizeof(struct sockaddr_in
));
2389 if (ifc
->destination
)
2390 /* use specified broadcast or peer destination
2392 to
.sin_addr
= ifc
->destination
->u
.prefix4
;
2393 else if (ifc
->address
->prefixlen
< IPV4_MAX_PREFIXLEN
)
2394 /* calculate the appropriate broadcast address
2396 to
.sin_addr
.s_addr
= ipv4_broadcast_addr(
2397 ifc
->address
->u
.prefix4
.s_addr
,
2398 ifc
->address
->prefixlen
);
2400 /* do not know where to send the packet */
2402 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2404 if (IS_RIP_DEBUG_EVENT
)
2405 zlog_debug("%s announce to %s on %s",
2406 CONNECTED_PEER(ifc
) ? "unicast"
2408 inet_ntoa(to
.sin_addr
), ifp
->name
);
2410 rip_output_process(ifc
, &to
, route_type
, version
);
2415 /* Update send to all interface and neighbor. */
2416 static void rip_update_process(struct rip
*rip
, int route_type
)
2418 struct vrf
*vrf
= vrf_lookup_by_id(rip
->vrf_id
);
2419 struct listnode
*ifnode
, *ifnnode
;
2420 struct connected
*connected
;
2421 struct interface
*ifp
;
2422 struct rip_interface
*ri
;
2423 struct route_node
*rp
;
2424 struct sockaddr_in to
;
2427 /* Send RIP update to each interface. */
2428 FOR_ALL_INTERFACES (vrf
, ifp
) {
2429 if (if_is_loopback(ifp
))
2432 if (!if_is_operative(ifp
))
2435 /* Fetch RIP interface information. */
2438 /* When passive interface is specified, suppress announce to the
2445 * If there is no version configuration in the
2447 * use rip's version setting.
2449 int vsend
= ((ri
->ri_send
== RI_RIP_UNSPEC
)
2453 if (IS_RIP_DEBUG_EVENT
)
2454 zlog_debug("SEND UPDATE to %s ifindex %d",
2455 ifp
->name
, ifp
->ifindex
);
2457 /* send update on each connected network */
2458 for (ALL_LIST_ELEMENTS(ifp
->connected
, ifnode
, ifnnode
,
2460 if (connected
->address
->family
== AF_INET
) {
2462 rip_update_interface(
2466 && if_is_multicast(ifp
))
2467 rip_update_interface(
2475 /* RIP send updates to each neighbor. */
2476 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
2477 if (rp
->info
!= NULL
) {
2480 connected
= if_lookup_address(&p
->u
.prefix4
, AF_INET
,
2484 "Neighbor %s doesn't have connected interface!",
2485 inet_ntoa(p
->u
.prefix4
));
2489 /* Set destination address and port */
2490 memset(&to
, 0, sizeof(struct sockaddr_in
));
2491 to
.sin_addr
= p
->u
.prefix4
;
2492 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2494 /* RIP version is rip's configuration. */
2495 rip_output_process(connected
, &to
, route_type
,
2500 /* RIP's periodical timer. */
2501 static int rip_update(struct thread
*t
)
2503 struct rip
*rip
= THREAD_ARG(t
);
2505 /* Clear timer pointer. */
2506 rip
->t_update
= NULL
;
2508 if (IS_RIP_DEBUG_EVENT
)
2509 zlog_debug("update timer fire!");
2511 /* Process update output. */
2512 rip_update_process(rip
, rip_all_route
);
2514 /* Triggered updates may be suppressed if a regular update is due by
2515 the time the triggered update would be sent. */
2516 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2519 /* Register myself. */
2520 rip_event(rip
, RIP_UPDATE_EVENT
, 0);
2525 /* Walk down the RIP routing table then clear changed flag. */
2526 static void rip_clear_changed_flag(struct rip
*rip
)
2528 struct route_node
*rp
;
2529 struct rip_info
*rinfo
= NULL
;
2530 struct list
*list
= NULL
;
2531 struct listnode
*listnode
= NULL
;
2533 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2534 if ((list
= rp
->info
) != NULL
)
2535 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
2536 UNSET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2537 /* This flag can be set only on the first entry.
2543 /* Triggered update interval timer. */
2544 static int rip_triggered_interval(struct thread
*t
)
2546 struct rip
*rip
= THREAD_ARG(t
);
2548 rip
->t_triggered_interval
= NULL
;
2552 rip_triggered_update(t
);
2557 /* Execute triggered update. */
2558 static int rip_triggered_update(struct thread
*t
)
2560 struct rip
*rip
= THREAD_ARG(t
);
2563 /* Clear thred pointer. */
2564 rip
->t_triggered_update
= NULL
;
2566 /* Cancel interval timer. */
2567 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2570 /* Logging triggered update. */
2571 if (IS_RIP_DEBUG_EVENT
)
2572 zlog_debug("triggered update!");
2574 /* Split Horizon processing is done when generating triggered
2575 updates as well as normal updates (see section 2.6). */
2576 rip_update_process(rip
, rip_changed_route
);
2578 /* Once all of the triggered updates have been generated, the route
2579 change flags should be cleared. */
2580 rip_clear_changed_flag(rip
);
2582 /* After a triggered update is sent, a timer should be set for a
2583 random interval between 1 and 5 seconds. If other changes that
2584 would trigger updates occur before the timer expires, a single
2585 update is triggered when the timer expires. */
2586 interval
= (random() % 5) + 1;
2588 rip
->t_triggered_interval
= NULL
;
2589 thread_add_timer(master
, rip_triggered_interval
, rip
, interval
,
2590 &rip
->t_triggered_interval
);
2595 /* Withdraw redistributed route. */
2596 void rip_redistribute_withdraw(struct rip
*rip
, int type
)
2598 struct route_node
*rp
;
2599 struct rip_info
*rinfo
= NULL
;
2600 struct list
*list
= NULL
;
2602 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2603 if ((list
= rp
->info
) != NULL
) {
2604 rinfo
= listgetdata(listhead(list
));
2605 if (rinfo
->type
== type
2606 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2607 /* Perform poisoned reverse. */
2608 rinfo
->metric
= RIP_METRIC_INFINITY
;
2609 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
2610 rip_garbage_collect
,
2612 RIP_TIMER_OFF(rinfo
->t_timeout
);
2613 rinfo
->flags
|= RIP_RTF_CHANGED
;
2615 if (IS_RIP_DEBUG_EVENT
) {
2616 struct prefix_ipv4
*p
=
2617 (struct prefix_ipv4
*)&rp
->p
;
2620 "Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2621 inet_ntoa(p
->prefix
),
2628 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
2633 struct rip
*rip_lookup_by_vrf_id(vrf_id_t vrf_id
)
2637 vrf
= vrf_lookup_by_id(vrf_id
);
2644 /* Create new RIP instance and set it to global variable. */
2645 struct rip
*rip_create(struct vrf
*vrf
, int socket
)
2648 struct interface
*ifp
;
2650 rip
= XCALLOC(MTYPE_RIP
, sizeof(struct rip
));
2652 /* Set initial value. */
2653 rip
->ecmp
= yang_get_default_bool("%s/allow-ecmp", RIP_INSTANCE
);
2654 rip
->default_metric
=
2655 yang_get_default_uint8("%s/default-metric", RIP_INSTANCE
);
2657 yang_get_default_uint8("%s/distance/default", RIP_INSTANCE
);
2658 rip
->passive_default
=
2659 yang_get_default_bool("%s/passive-default", RIP_INSTANCE
);
2660 rip
->garbage_time
= yang_get_default_uint32("%s/timers/flush-interval",
2662 rip
->timeout_time
= yang_get_default_uint32(
2663 "%s/timers/holddown-interval", RIP_INSTANCE
);
2664 rip
->update_time
= yang_get_default_uint32("%s/timers/update-interval",
2667 yang_get_default_enum("%s/version/send", RIP_INSTANCE
);
2669 yang_get_default_enum("%s/version/receive", RIP_INSTANCE
);
2671 /* Initialize RIP data structures. */
2672 rip
->table
= route_table_init();
2673 route_table_set_info(rip
->table
, rip
);
2674 rip
->neighbor
= route_table_init();
2675 rip
->peer_list
= list_new();
2676 rip
->peer_list
->cmp
= (int (*)(void *, void *))rip_peer_list_cmp
;
2677 rip
->peer_list
->del
= rip_peer_list_del
;
2678 rip
->distance_table
= route_table_init();
2679 rip
->distance_table
->cleanup
= rip_distance_table_node_cleanup
;
2680 rip
->enable_interface
= vector_init(1);
2681 rip
->enable_network
= route_table_init();
2682 rip
->passive_nondefault
= vector_init(1);
2683 rip
->offset_list_master
= list_new();
2684 rip
->offset_list_master
->cmp
= (int (*)(void *, void *))offset_list_cmp
;
2685 rip
->offset_list_master
->del
= (void (*)(void *))offset_list_del
;
2687 /* Distribute list install. */
2688 rip
->distribute_ctx
=
2689 distribute_list_ctx_create(vrf_lookup_by_id(VRF_DEFAULT
));
2690 distribute_list_add_hook(rip
->distribute_ctx
, rip_distribute_update
);
2691 distribute_list_delete_hook(rip
->distribute_ctx
, rip_distribute_update
);
2693 /* Make output stream. */
2694 rip
->obuf
= stream_new(1500);
2699 /* Create read and timer thread. */
2700 rip_event(rip
, RIP_READ
, rip
->sock
);
2701 rip_event(rip
, RIP_UPDATE_EVENT
, 1);
2703 /* Link RIP instance to VRF. */
2704 rip
->vrf_id
= vrf
->vrf_id
;
2706 FOR_ALL_INTERFACES (vrf
, ifp
) {
2707 struct rip_interface
*ri
;
2716 /* Sned RIP request to the destination. */
2717 int rip_request_send(struct sockaddr_in
*to
, struct interface
*ifp
,
2718 uint8_t version
, struct connected
*connected
)
2721 struct rip_packet rip_packet
;
2722 struct listnode
*node
, *nnode
;
2724 memset(&rip_packet
, 0, sizeof(rip_packet
));
2726 rip_packet
.command
= RIP_REQUEST
;
2727 rip_packet
.version
= version
;
2728 rte
= rip_packet
.rte
;
2729 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
2733 * connected is only sent for ripv1 case, or when
2734 * interface does not support multicast. Caller loops
2735 * over each connected address for this case.
2737 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2739 != sizeof(rip_packet
))
2742 return sizeof(rip_packet
);
2745 /* send request on each connected network */
2746 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, connected
)) {
2747 struct prefix_ipv4
*p
;
2749 p
= (struct prefix_ipv4
*)connected
->address
;
2751 if (p
->family
!= AF_INET
)
2754 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2756 != sizeof(rip_packet
))
2759 return sizeof(rip_packet
);
2762 static int rip_update_jitter(unsigned long time
)
2764 #define JITTER_BOUND 4
2765 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2766 Given that, we cannot let time be less than JITTER_BOUND seconds.
2767 The RIPv2 RFC says jitter should be small compared to
2768 update_time. We consider 1/JITTER_BOUND to be small.
2771 int jitter_input
= time
;
2774 if (jitter_input
< JITTER_BOUND
)
2775 jitter_input
= JITTER_BOUND
;
2777 jitter
= (((random() % ((jitter_input
* 2) + 1)) - jitter_input
));
2779 return jitter
/ JITTER_BOUND
;
2782 void rip_event(struct rip
*rip
, enum rip_event event
, int sock
)
2789 thread_add_read(master
, rip_read
, rip
, sock
, &rip
->t_read
);
2791 case RIP_UPDATE_EVENT
:
2792 RIP_TIMER_OFF(rip
->t_update
);
2793 jitter
= rip_update_jitter(rip
->update_time
);
2794 thread_add_timer(master
, rip_update
, rip
,
2795 sock
? 2 : rip
->update_time
+ jitter
,
2798 case RIP_TRIGGERED_UPDATE
:
2799 if (rip
->t_triggered_interval
)
2802 thread_add_event(master
, rip_triggered_update
, rip
, 0,
2803 &rip
->t_triggered_update
);
2812 rip_update_default_metric (void)
2814 struct route_node
*np
;
2815 struct rip_info
*rinfo
= NULL
;
2816 struct list
*list
= NULL
;
2817 struct listnode
*listnode
= NULL
;
2819 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
2820 if ((list
= np
->info
) != NULL
)
2821 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
2822 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
2823 rinfo
->metric
= rip
->default_metric
;
2827 struct rip_distance
*rip_distance_new(void)
2829 return XCALLOC(MTYPE_RIP_DISTANCE
, sizeof(struct rip_distance
));
2832 void rip_distance_free(struct rip_distance
*rdistance
)
2834 if (rdistance
->access_list
)
2835 free(rdistance
->access_list
);
2836 XFREE(MTYPE_RIP_DISTANCE
, rdistance
);
2839 static void rip_distance_table_node_cleanup(struct route_table
*table
,
2840 struct route_node
*node
)
2842 struct rip_distance
*rdistance
;
2844 rdistance
= node
->info
;
2846 rip_distance_free(rdistance
);
2849 /* Apply RIP information to distance method. */
2850 uint8_t rip_distance_apply(struct rip
*rip
, struct rip_info
*rinfo
)
2852 struct route_node
*rn
;
2853 struct prefix_ipv4 p
;
2854 struct rip_distance
*rdistance
;
2855 struct access_list
*alist
;
2857 memset(&p
, 0, sizeof(struct prefix_ipv4
));
2859 p
.prefix
= rinfo
->from
;
2860 p
.prefixlen
= IPV4_MAX_BITLEN
;
2862 /* Check source address. */
2863 rn
= route_node_match(rip
->distance_table
, (struct prefix
*)&p
);
2865 rdistance
= rn
->info
;
2866 route_unlock_node(rn
);
2868 if (rdistance
->access_list
) {
2869 alist
= access_list_lookup(AFI_IP
,
2870 rdistance
->access_list
);
2873 if (access_list_apply(alist
, &rinfo
->rp
->p
)
2877 return rdistance
->distance
;
2879 return rdistance
->distance
;
2883 return rip
->distance
;
2888 static void rip_distance_show(struct vty
*vty
, struct rip
*rip
)
2890 struct route_node
*rn
;
2891 struct rip_distance
*rdistance
;
2895 vty_out(vty
, " Distance: (default is %u)\n",
2896 rip
->distance
? rip
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
);
2898 for (rn
= route_top(rip
->distance_table
); rn
; rn
= route_next(rn
))
2899 if ((rdistance
= rn
->info
) != NULL
) {
2902 " Address Distance List\n");
2905 sprintf(buf
, "%s/%d", inet_ntoa(rn
->p
.u
.prefix4
),
2907 vty_out(vty
, " %-20s %4d %s\n", buf
,
2908 rdistance
->distance
,
2909 rdistance
->access_list
? rdistance
->access_list
2914 /* Update ECMP routes to zebra when ECMP is disabled. */
2915 void rip_ecmp_disable(struct rip
*rip
)
2917 struct route_node
*rp
;
2918 struct rip_info
*rinfo
, *tmp_rinfo
;
2920 struct listnode
*node
, *nextnode
;
2922 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2923 if ((list
= rp
->info
) != NULL
&& listcount(list
) > 1) {
2924 rinfo
= listgetdata(listhead(list
));
2925 if (!rip_route_rte(rinfo
))
2928 /* Drop all other entries, except the first one. */
2929 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
2930 if (tmp_rinfo
!= rinfo
) {
2931 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
2933 tmp_rinfo
->t_garbage_collect
);
2934 list_delete_node(list
, node
);
2935 rip_info_free(tmp_rinfo
);
2939 rip_zebra_ipv4_add(rip
, rp
);
2941 /* Set the route change flag. */
2942 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2944 /* Signal the output process to trigger an update. */
2945 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
2949 /* Print out routes update time. */
2950 static void rip_vty_out_uptime(struct vty
*vty
, struct rip_info
*rinfo
)
2955 char timebuf
[TIME_BUF
];
2956 struct thread
*thread
;
2958 if ((thread
= rinfo
->t_timeout
) != NULL
) {
2959 clock
= thread_timer_remain_second(thread
);
2960 tm
= gmtime(&clock
);
2961 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
2962 vty_out(vty
, "%5s", timebuf
);
2963 } else if ((thread
= rinfo
->t_garbage_collect
) != NULL
) {
2964 clock
= thread_timer_remain_second(thread
);
2965 tm
= gmtime(&clock
);
2966 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
2967 vty_out(vty
, "%5s", timebuf
);
2971 static const char *rip_route_type_print(int sub_type
)
2976 case RIP_ROUTE_STATIC
:
2978 case RIP_ROUTE_DEFAULT
:
2980 case RIP_ROUTE_REDISTRIBUTE
:
2982 case RIP_ROUTE_INTERFACE
:
2994 "Show RIP routes\n")
2997 struct route_node
*np
;
2998 struct rip_info
*rinfo
= NULL
;
2999 struct list
*list
= NULL
;
3000 struct listnode
*listnode
= NULL
;
3002 rip
= rip_lookup_by_vrf_id(VRF_DEFAULT
);
3007 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
3009 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
3010 " (i) - interface\n\n"
3011 " Network Next Hop Metric From Tag Time\n");
3013 for (np
= route_top(rip
->table
); np
; np
= route_next(np
))
3014 if ((list
= np
->info
) != NULL
)
3015 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3019 vty
, "%c(%s) %s/%d",
3020 /* np->lock, For debugging. */
3021 zebra_route_char(rinfo
->type
),
3022 rip_route_type_print(rinfo
->sub_type
),
3023 inet_ntoa(np
->p
.u
.prefix4
),
3029 vty_out(vty
, "%*s", len
, " ");
3031 switch (rinfo
->nh
.type
) {
3032 case NEXTHOP_TYPE_IPV4
:
3033 case NEXTHOP_TYPE_IPV4_IFINDEX
:
3034 vty_out(vty
, "%-20s %2d ",
3035 inet_ntoa(rinfo
->nh
.gate
.ipv4
),
3038 case NEXTHOP_TYPE_IFINDEX
:
3043 case NEXTHOP_TYPE_BLACKHOLE
:
3048 case NEXTHOP_TYPE_IPV6
:
3049 case NEXTHOP_TYPE_IPV6_IFINDEX
:
3051 "V6 Address Hidden %2d ",
3056 /* Route which exist in kernel routing table. */
3057 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
)
3058 && (rinfo
->sub_type
== RIP_ROUTE_RTE
)) {
3059 vty_out(vty
, "%-15s ",
3060 inet_ntoa(rinfo
->from
));
3061 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3062 (route_tag_t
)rinfo
->tag
);
3063 rip_vty_out_uptime(vty
, rinfo
);
3064 } else if (rinfo
->metric
3065 == RIP_METRIC_INFINITY
) {
3066 vty_out(vty
, "self ");
3067 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3068 (route_tag_t
)rinfo
->tag
);
3069 rip_vty_out_uptime(vty
, rinfo
);
3071 if (rinfo
->external_metric
) {
3073 vty
, "self (%s:%d)",
3076 rinfo
->external_metric
);
3079 vty_out(vty
, "%*s", len
,
3084 vty_out(vty
, "%3" ROUTE_TAG_PRI
,
3085 (route_tag_t
)rinfo
->tag
);
3093 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3094 DEFUN (show_ip_rip_status
,
3095 show_ip_rip_status_cmd
,
3096 "show ip rip status",
3100 "IP routing protocol process parameters and statistics\n")
3104 struct interface
*ifp
;
3105 struct rip_interface
*ri
;
3106 extern const struct message ri_version_msg
[];
3107 const char *send_version
;
3108 const char *receive_version
;
3110 rip
= rip_lookup_by_vrf_id(VRF_DEFAULT
);
3114 vty_out(vty
, "Routing Protocol is \"rip\"\n");
3115 vty_out(vty
, " Sending updates every %u seconds with +/-50%%,",
3117 vty_out(vty
, " next due in %lu seconds\n",
3118 thread_timer_remain_second(rip
->t_update
));
3119 vty_out(vty
, " Timeout after %u seconds,", rip
->timeout_time
);
3120 vty_out(vty
, " garbage collect after %u seconds\n", rip
->garbage_time
);
3122 /* Filtering status show. */
3123 config_show_distribute(vty
, rip
->distribute_ctx
);
3125 /* Default metric information. */
3126 vty_out(vty
, " Default redistribution metric is %u\n",
3127 rip
->default_metric
);
3129 /* Redistribute information. */
3130 vty_out(vty
, " Redistributing:");
3131 rip_show_redistribute_config(vty
, rip
);
3134 vty_out(vty
, " Default version control: send version %s,",
3135 lookup_msg(ri_version_msg
, rip
->version_send
, NULL
));
3136 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3137 vty_out(vty
, " receive any version \n");
3139 vty_out(vty
, " receive version %s \n",
3140 lookup_msg(ri_version_msg
, rip
->version_recv
, NULL
));
3142 vty_out(vty
, " Interface Send Recv Key-chain\n");
3144 vrf
= vrf_lookup_by_id(rip
->vrf_id
);
3145 FOR_ALL_INTERFACES (vrf
, ifp
) {
3151 if (ri
->enable_network
|| ri
->enable_interface
) {
3152 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3154 lookup_msg(ri_version_msg
,
3155 rip
->version_send
, NULL
);
3157 send_version
= lookup_msg(ri_version_msg
,
3160 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3162 lookup_msg(ri_version_msg
,
3163 rip
->version_recv
, NULL
);
3165 receive_version
= lookup_msg(
3166 ri_version_msg
, ri
->ri_receive
, NULL
);
3168 vty_out(vty
, " %-17s%-3s %-3s %s\n", ifp
->name
,
3169 send_version
, receive_version
,
3170 ri
->key_chain
? ri
->key_chain
: "");
3174 vty_out(vty
, " Routing for Networks:\n");
3175 rip_show_network_config(vty
, rip
);
3178 int found_passive
= 0;
3179 FOR_ALL_INTERFACES (vrf
, ifp
) {
3182 if ((ri
->enable_network
|| ri
->enable_interface
)
3184 if (!found_passive
) {
3186 " Passive Interface(s):\n");
3189 vty_out(vty
, " %s\n", ifp
->name
);
3194 vty_out(vty
, " Routing Information Sources:\n");
3196 " Gateway BadPackets BadRoutes Distance Last Update\n");
3197 rip_peer_display(vty
, rip
);
3199 rip_distance_show(vty
, rip
);
3204 /* RIP configuration write function. */
3205 static int config_write_rip(struct vty
*vty
)
3208 struct lyd_node
*dnode
;
3210 dnode
= yang_dnode_get(running_config
->dnode
,
3211 "/frr-ripd:ripd/instance");
3217 nb_cli_show_dnode_cmds(vty
, dnode
, false);
3219 rip
= rip_lookup_by_vrf_id(VRF_DEFAULT
);
3221 /* Distribute configuration. */
3222 write
+= config_write_distribute(vty
,
3223 rip
->distribute_ctx
);
3225 /* Interface routemap configuration */
3226 write
+= config_write_if_rmap(vty
);
3232 /* RIP node structure. */
3233 static struct cmd_node rip_node
= {RIP_NODE
, "%s(config-router)# ", 1};
3235 /* Distribute-list update functions. */
3236 static void rip_distribute_update(struct distribute_ctx
*ctx
,
3237 struct distribute
*dist
)
3239 struct interface
*ifp
;
3240 struct rip_interface
*ri
;
3241 struct access_list
*alist
;
3242 struct prefix_list
*plist
;
3247 ifp
= if_lookup_by_name(dist
->ifname
, VRF_DEFAULT
);
3253 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
3254 alist
= access_list_lookup(AFI_IP
,
3255 dist
->list
[DISTRIBUTE_V4_IN
]);
3257 ri
->list
[RIP_FILTER_IN
] = alist
;
3259 ri
->list
[RIP_FILTER_IN
] = NULL
;
3261 ri
->list
[RIP_FILTER_IN
] = NULL
;
3263 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
3264 alist
= access_list_lookup(AFI_IP
,
3265 dist
->list
[DISTRIBUTE_V4_OUT
]);
3267 ri
->list
[RIP_FILTER_OUT
] = alist
;
3269 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3271 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3273 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
3274 plist
= prefix_list_lookup(AFI_IP
,
3275 dist
->prefix
[DISTRIBUTE_V4_IN
]);
3277 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3279 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3281 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3283 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
3284 plist
= prefix_list_lookup(AFI_IP
,
3285 dist
->prefix
[DISTRIBUTE_V4_OUT
]);
3287 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3289 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3291 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3294 void rip_distribute_update_interface(struct interface
*ifp
)
3296 struct rip_interface
*ri
= ifp
->info
;
3297 struct rip
*rip
= ri
->rip
;
3298 struct distribute
*dist
;
3302 dist
= distribute_lookup(rip
->distribute_ctx
, ifp
->name
);
3304 rip_distribute_update(rip
->distribute_ctx
, dist
);
3307 /* Update all interface's distribute list. */
3309 static void rip_distribute_update_all(struct prefix_list
*notused
)
3311 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3312 struct interface
*ifp
;
3314 FOR_ALL_INTERFACES (vrf
, ifp
)
3315 rip_distribute_update_interface(ifp
);
3318 static void rip_distribute_update_all_wrapper(struct access_list
*notused
)
3320 rip_distribute_update_all(NULL
);
3323 /* Delete all added rip route. */
3324 void rip_clean(struct rip
*rip
)
3327 struct interface
*ifp
;
3328 struct route_node
*rp
;
3330 /* Clear RIP routes */
3331 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
)) {
3332 struct rip_info
*rinfo
;
3334 struct listnode
*listnode
;
3336 if ((list
= rp
->info
) == NULL
)
3339 rinfo
= listgetdata(listhead(list
));
3340 if (rip_route_rte(rinfo
))
3341 rip_zebra_ipv4_delete(rip
, rp
);
3343 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3344 RIP_TIMER_OFF(rinfo
->t_timeout
);
3345 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
3346 rip_info_free(rinfo
);
3350 route_unlock_node(rp
);
3353 /* Cancel RIP related timers. */
3354 RIP_TIMER_OFF(rip
->t_update
);
3355 RIP_TIMER_OFF(rip
->t_triggered_update
);
3356 RIP_TIMER_OFF(rip
->t_triggered_interval
);
3358 /* Cancel read thread. */
3359 THREAD_READ_OFF(rip
->t_read
);
3361 /* Close RIP socket. */
3362 if (rip
->sock
>= 0) {
3367 stream_free(rip
->obuf
);
3369 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3370 if (rip
->route_map
[i
].name
)
3371 free(rip
->route_map
[i
].name
);
3373 route_table_finish(rip
->table
);
3374 route_table_finish(rip
->neighbor
);
3375 list_delete(&rip
->peer_list
);
3376 distribute_list_delete(&rip
->distribute_ctx
);
3378 rip_clean_network(rip
);
3379 rip_passive_nondefault_clean(rip
);
3380 vector_free(rip
->enable_interface
);
3381 route_table_finish(rip
->enable_network
);
3382 vector_free(rip
->passive_nondefault
);
3383 list_delete(&rip
->offset_list_master
);
3384 rip_interfaces_clean(rip
);
3385 route_table_finish(rip
->distance_table
);
3386 rip_redistribute_clean(rip
);
3388 vrf
= vrf_lookup_by_id(rip
->vrf_id
);
3391 FOR_ALL_INTERFACES (vrf
, ifp
) {
3392 struct rip_interface
*ri
;
3398 XFREE(MTYPE_RIP
, rip
);
3401 static void rip_if_rmap_update(struct if_rmap
*if_rmap
)
3403 struct interface
*ifp
;
3404 struct rip_interface
*ri
;
3405 struct route_map
*rmap
;
3407 ifp
= if_lookup_by_name(if_rmap
->ifname
, VRF_DEFAULT
);
3412 if (if_rmap
->routemap
[IF_RMAP_IN
]) {
3413 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_IN
]);
3415 ri
->routemap
[IF_RMAP_IN
] = rmap
;
3417 ri
->routemap
[IF_RMAP_IN
] = NULL
;
3419 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
3421 if (if_rmap
->routemap
[IF_RMAP_OUT
]) {
3422 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_OUT
]);
3424 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
3426 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
3428 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
3431 void rip_if_rmap_update_interface(struct interface
*ifp
)
3433 struct if_rmap
*if_rmap
;
3435 if_rmap
= if_rmap_lookup(ifp
->name
);
3437 rip_if_rmap_update(if_rmap
);
3440 static void rip_routemap_update_redistribute(struct rip
*rip
)
3442 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3443 if (rip
->route_map
[i
].name
)
3444 rip
->route_map
[i
].map
= route_map_lookup_by_name(
3445 rip
->route_map
[i
].name
);
3450 static void rip_routemap_update(const char *notused
)
3452 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3454 struct interface
*ifp
;
3456 FOR_ALL_INTERFACES (vrf
, ifp
)
3457 rip_if_rmap_update_interface(ifp
);
3461 rip_routemap_update_redistribute(rip
);
3464 /* Allocate new rip structure and set default value. */
3467 /* Install top nodes. */
3468 install_node(&rip_node
, config_write_rip
);
3470 /* Install rip commands. */
3471 install_element(VIEW_NODE
, &show_ip_rip_cmd
);
3472 install_element(VIEW_NODE
, &show_ip_rip_status_cmd
);
3474 install_default(RIP_NODE
);
3476 /* Debug related init. */
3479 /* Access list install. */
3481 access_list_add_hook(rip_distribute_update_all_wrapper
);
3482 access_list_delete_hook(rip_distribute_update_all_wrapper
);
3484 /* Prefix list initialize.*/
3486 prefix_list_add_hook(rip_distribute_update_all
);
3487 prefix_list_delete_hook(rip_distribute_update_all
);
3489 /* Distribute list install. */
3490 distribute_list_init(RIP_NODE
);
3493 rip_route_map_init();
3495 route_map_add_hook(rip_routemap_update
);
3496 route_map_delete_hook(rip_routemap_update
);
3498 if_rmap_init(RIP_NODE
);
3499 if_rmap_hook_add(rip_if_rmap_update
);
3500 if_rmap_hook_delete(rip_if_rmap_update
);