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"
40 #ifdef CRYPTO_INTERNAL
45 #include "lib_errors.h"
46 #include "northbound_cli.h"
48 #include "lib/printfrr.h"
50 #include "ripd/ripd.h"
51 #include "ripd/rip_nb.h"
52 #include "ripd/rip_debug.h"
53 #include "ripd/rip_errors.h"
54 #include "ripd/rip_interface.h"
56 /* UDP receive buffer size */
57 #define RIP_UDP_RCV_BUF 41600
59 DEFINE_MGROUP(RIPD
, "ripd");
60 DEFINE_MTYPE_STATIC(RIPD
, RIP
, "RIP structure");
61 DEFINE_MTYPE_STATIC(RIPD
, RIP_VRF_NAME
, "RIP VRF name");
62 DEFINE_MTYPE_STATIC(RIPD
, RIP_INFO
, "RIP route info");
63 DEFINE_MTYPE_STATIC(RIPD
, RIP_DISTANCE
, "RIP distance");
66 static void rip_output_process(struct connected
*, struct sockaddr_in
*, int,
68 static int rip_triggered_update(struct thread
*);
69 static int rip_update_jitter(unsigned long);
70 static void rip_distance_table_node_cleanup(struct route_table
*table
,
71 struct route_node
*node
);
72 static void rip_instance_enable(struct rip
*rip
, struct vrf
*vrf
, int sock
);
73 static void rip_instance_disable(struct rip
*rip
);
75 static void rip_distribute_update(struct distribute_ctx
*ctx
,
76 struct distribute
*dist
);
78 static void rip_if_rmap_update(struct if_rmap_ctx
*ctx
,
79 struct if_rmap
*if_rmap
);
81 /* RIP output routes type. */
82 enum { rip_all_route
, rip_changed_route
};
84 /* RIP command strings. */
85 static const struct message rip_msg
[] = {{RIP_REQUEST
, "REQUEST"},
86 {RIP_RESPONSE
, "RESPONSE"},
87 {RIP_TRACEON
, "TRACEON"},
88 {RIP_TRACEOFF
, "TRACEOFF"},
90 {RIP_POLL_ENTRY
, "POLL ENTRY"},
93 /* Generate rb-tree of RIP instances. */
94 static inline int rip_instance_compare(const struct rip
*a
, const struct rip
*b
)
96 return strcmp(a
->vrf_name
, b
->vrf_name
);
98 RB_GENERATE(rip_instance_head
, rip
, entry
, rip_instance_compare
)
100 struct rip_instance_head rip_instances
= RB_INITIALIZER(&rip_instances
);
102 /* Utility function to set boradcast option to the socket. */
103 static int sockopt_broadcast(int sock
)
108 ret
= setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, (char *)&on
,
111 zlog_warn("can't set sockopt SO_BROADCAST to socket %d", sock
);
117 int rip_route_rte(struct rip_info
*rinfo
)
119 return (rinfo
->type
== ZEBRA_ROUTE_RIP
120 && rinfo
->sub_type
== RIP_ROUTE_RTE
);
123 static struct rip_info
*rip_info_new(void)
125 return XCALLOC(MTYPE_RIP_INFO
, sizeof(struct rip_info
));
128 void rip_info_free(struct rip_info
*rinfo
)
130 XFREE(MTYPE_RIP_INFO
, rinfo
);
133 struct rip
*rip_info_get_instance(const struct rip_info
*rinfo
)
135 return route_table_get_info(rinfo
->rp
->table
);
138 /* RIP route garbage collect timer. */
139 static int rip_garbage_collect(struct thread
*t
)
141 struct rip_info
*rinfo
;
142 struct route_node
*rp
;
144 rinfo
= THREAD_ARG(t
);
145 rinfo
->t_garbage_collect
= NULL
;
147 /* Off timeout timer. */
148 RIP_TIMER_OFF(rinfo
->t_timeout
);
150 /* Get route_node pointer. */
153 /* Unlock route_node. */
154 listnode_delete(rp
->info
, rinfo
);
155 if (list_isempty((struct list
*)rp
->info
)) {
156 list_delete((struct list
**)&rp
->info
);
157 route_unlock_node(rp
);
160 /* Free RIP routing information. */
161 rip_info_free(rinfo
);
166 static void rip_timeout_update(struct rip
*rip
, struct rip_info
*rinfo
);
168 /* Add new route to the ECMP list.
169 * RETURN: the new entry added in the list, or NULL if it is not the first
170 * entry and ECMP is not allowed.
172 struct rip_info
*rip_ecmp_add(struct rip
*rip
, struct rip_info
*rinfo_new
)
174 struct route_node
*rp
= rinfo_new
->rp
;
175 struct rip_info
*rinfo
= NULL
;
176 struct list
*list
= NULL
;
178 if (rp
->info
== NULL
)
179 rp
->info
= list_new();
180 list
= (struct list
*)rp
->info
;
182 /* If ECMP is not allowed and some entry already exists in the list,
184 if (listcount(list
) && !rip
->ecmp
)
187 rinfo
= rip_info_new();
188 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
189 listnode_add(list
, rinfo
);
191 if (rip_route_rte(rinfo
)) {
192 rip_timeout_update(rip
, rinfo
);
193 rip_zebra_ipv4_add(rip
, rp
);
196 /* Set the route change flag on the first entry. */
197 rinfo
= listgetdata(listhead(list
));
198 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
200 /* Signal the output process to trigger an update (see section 2.5). */
201 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
206 /* Replace the ECMP list with the new route.
207 * RETURN: the new entry added in the list
209 struct rip_info
*rip_ecmp_replace(struct rip
*rip
, struct rip_info
*rinfo_new
)
211 struct route_node
*rp
= rinfo_new
->rp
;
212 struct list
*list
= (struct list
*)rp
->info
;
213 struct rip_info
*rinfo
= NULL
, *tmp_rinfo
= NULL
;
214 struct listnode
*node
= NULL
, *nextnode
= NULL
;
216 if (list
== NULL
|| listcount(list
) == 0)
217 return rip_ecmp_add(rip
, rinfo_new
);
219 /* Get the first entry */
220 rinfo
= listgetdata(listhead(list
));
222 /* Learnt route replaced by a local one. Delete it from zebra. */
223 if (rip_route_rte(rinfo
) && !rip_route_rte(rinfo_new
))
224 if (CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
225 rip_zebra_ipv4_delete(rip
, rp
);
227 /* Re-use the first entry, and delete the others. */
228 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
229 if (tmp_rinfo
!= rinfo
) {
230 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
231 RIP_TIMER_OFF(tmp_rinfo
->t_garbage_collect
);
232 list_delete_node(list
, node
);
233 rip_info_free(tmp_rinfo
);
236 RIP_TIMER_OFF(rinfo
->t_timeout
);
237 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
238 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
240 if (rip_route_rte(rinfo
)) {
241 rip_timeout_update(rip
, rinfo
);
242 /* The ADD message implies an update. */
243 rip_zebra_ipv4_add(rip
, rp
);
246 /* Set the route change flag. */
247 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
249 /* Signal the output process to trigger an update (see section 2.5). */
250 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
255 /* Delete one route from the ECMP list.
257 * null - the entry is freed, and other entries exist in the list
258 * the entry - the entry is the last one in the list; its metric is set
259 * to INFINITY, and the garbage collector is started for it
261 struct rip_info
*rip_ecmp_delete(struct rip
*rip
, struct rip_info
*rinfo
)
263 struct route_node
*rp
= rinfo
->rp
;
264 struct list
*list
= (struct list
*)rp
->info
;
266 RIP_TIMER_OFF(rinfo
->t_timeout
);
268 if (listcount(list
) > 1) {
269 /* Some other ECMP entries still exist. Just delete this entry.
271 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
272 listnode_delete(list
, rinfo
);
273 if (rip_route_rte(rinfo
)
274 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
275 /* The ADD message implies the update. */
276 rip_zebra_ipv4_add(rip
, rp
);
277 rip_info_free(rinfo
);
280 assert(rinfo
== listgetdata(listhead(list
)));
282 /* This is the only entry left in the list. We must keep it in
283 * the list for garbage collection time, with INFINITY metric.
286 rinfo
->metric
= RIP_METRIC_INFINITY
;
287 RIP_TIMER_ON(rinfo
->t_garbage_collect
, rip_garbage_collect
,
290 if (rip_route_rte(rinfo
)
291 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
292 rip_zebra_ipv4_delete(rip
, rp
);
295 /* Set the route change flag on the first entry. */
296 rinfo
= listgetdata(listhead(list
));
297 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
299 /* Signal the output process to trigger an update (see section 2.5). */
300 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
305 /* Timeout RIP routes. */
306 static int rip_timeout(struct thread
*t
)
308 struct rip_info
*rinfo
= THREAD_ARG(t
);
309 struct rip
*rip
= rip_info_get_instance(rinfo
);
311 rip_ecmp_delete(rip
, rinfo
);
316 static void rip_timeout_update(struct rip
*rip
, struct rip_info
*rinfo
)
318 if (rinfo
->metric
!= RIP_METRIC_INFINITY
) {
319 RIP_TIMER_OFF(rinfo
->t_timeout
);
320 thread_add_timer(master
, rip_timeout
, rinfo
, rip
->timeout_time
,
325 static int rip_filter(int rip_distribute
, struct prefix_ipv4
*p
,
326 struct rip_interface
*ri
)
328 struct distribute
*dist
;
329 struct access_list
*alist
;
330 struct prefix_list
*plist
;
331 int distribute
= rip_distribute
== RIP_FILTER_OUT
? DISTRIBUTE_V4_OUT
333 const char *inout
= rip_distribute
== RIP_FILTER_OUT
? "out" : "in";
335 /* Input distribute-list filtering. */
336 if (ri
->list
[rip_distribute
]) {
337 if (access_list_apply(ri
->list
[rip_distribute
],
340 if (IS_RIP_DEBUG_PACKET
)
341 zlog_debug("%pFX filtered by distribute %s", p
,
346 if (ri
->prefix
[rip_distribute
]) {
347 if (prefix_list_apply(ri
->prefix
[rip_distribute
],
350 if (IS_RIP_DEBUG_PACKET
)
351 zlog_debug("%pFX filtered by prefix-list %s", p
,
357 /* All interface filter check. */
358 dist
= distribute_lookup(ri
->rip
->distribute_ctx
, NULL
);
360 if (dist
->list
[distribute
]) {
361 alist
= access_list_lookup(AFI_IP
,
362 dist
->list
[distribute
]);
365 if (access_list_apply(alist
, (struct prefix
*)p
)
367 if (IS_RIP_DEBUG_PACKET
)
369 "%pFX filtered by distribute %s",
375 if (dist
->prefix
[distribute
]) {
376 plist
= prefix_list_lookup(AFI_IP
,
377 dist
->prefix
[distribute
]);
380 if (prefix_list_apply(plist
, (struct prefix
*)p
)
382 if (IS_RIP_DEBUG_PACKET
)
384 "%pFX filtered by prefix-list %s",
394 /* Check nexthop address validity. */
395 static int rip_nexthop_check(struct rip
*rip
, struct in_addr
*addr
)
397 struct interface
*ifp
;
398 struct listnode
*cnode
;
399 struct connected
*ifc
;
402 /* If nexthop address matches local configured address then it is
405 FOR_ALL_INTERFACES (rip
->vrf
, ifp
) {
406 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, ifc
)) {
409 if (p
->family
== AF_INET
410 && IPV4_ADDR_SAME(&p
->u
.prefix4
, addr
))
417 /* RIP add route to routing table. */
418 static void rip_rte_process(struct rte
*rte
, struct sockaddr_in
*from
,
419 struct interface
*ifp
)
423 struct prefix_ipv4 p
;
424 struct route_node
*rp
;
425 struct rip_info
*rinfo
= NULL
, newinfo
;
426 struct rip_interface
*ri
;
427 struct in_addr
*nexthop
;
429 unsigned char old_dist
, new_dist
;
430 struct list
*list
= NULL
;
431 struct listnode
*node
= NULL
;
433 /* Make prefix structure. */
434 memset(&p
, 0, sizeof(struct prefix_ipv4
));
436 p
.prefix
= rte
->prefix
;
437 p
.prefixlen
= ip_masklen(rte
->mask
);
439 /* Make sure mask is applied. */
445 /* Apply input filters. */
446 ret
= rip_filter(RIP_FILTER_IN
, &p
, ri
);
450 memset(&newinfo
, 0, sizeof(newinfo
));
451 newinfo
.type
= ZEBRA_ROUTE_RIP
;
452 newinfo
.sub_type
= RIP_ROUTE_RTE
;
453 newinfo
.nh
.gate
.ipv4
= rte
->nexthop
;
454 newinfo
.from
= from
->sin_addr
;
455 newinfo
.nh
.ifindex
= ifp
->ifindex
;
456 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
457 newinfo
.metric
= rte
->metric
;
458 newinfo
.metric_out
= rte
->metric
; /* XXX */
459 newinfo
.tag
= ntohs(rte
->tag
); /* XXX */
461 /* Modify entry according to the interface routemap. */
462 if (ri
->routemap
[RIP_FILTER_IN
]) {
463 /* The object should be of the type of rip_info */
464 ret
= route_map_apply(ri
->routemap
[RIP_FILTER_IN
],
465 (struct prefix
*)&p
, &newinfo
);
467 if (ret
== RMAP_DENYMATCH
) {
468 if (IS_RIP_DEBUG_PACKET
)
470 "RIP %pFX is filtered by route-map in",
475 /* Get back the object */
476 rte
->nexthop
= newinfo
.nexthop_out
;
477 rte
->tag
= htons(newinfo
.tag_out
); /* XXX */
478 rte
->metric
= newinfo
.metric_out
; /* XXX: the routemap uses the
482 /* Once the entry has been validated, update the metric by
483 adding the cost of the network on wich the message
484 arrived. If the result is greater than infinity, use infinity
485 (RFC2453 Sec. 3.9.2) */
486 /* Zebra ripd can handle offset-list in. */
487 ret
= rip_offset_list_apply_in(&p
, ifp
, &rte
->metric
);
489 /* If offset-list does not modify the metric use interface's
492 rte
->metric
+= ifp
->metric
? ifp
->metric
: 1;
494 if (rte
->metric
> RIP_METRIC_INFINITY
)
495 rte
->metric
= RIP_METRIC_INFINITY
;
497 /* Set nexthop pointer. */
498 if (rte
->nexthop
.s_addr
== INADDR_ANY
)
499 nexthop
= &from
->sin_addr
;
501 nexthop
= &rte
->nexthop
;
503 /* Check if nexthop address is myself, then do nothing. */
504 if (rip_nexthop_check(rip
, nexthop
) < 0) {
505 if (IS_RIP_DEBUG_PACKET
)
506 zlog_debug("Nexthop address %pI4 is myself",
511 /* Get index for the prefix. */
512 rp
= route_node_get(rip
->table
, (struct prefix
*)&p
);
515 newinfo
.nh
.gate
.ipv4
= *nexthop
;
516 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4
;
517 newinfo
.metric
= rte
->metric
;
518 newinfo
.tag
= ntohs(rte
->tag
);
519 newinfo
.distance
= rip_distance_apply(rip
, &newinfo
);
521 new_dist
= newinfo
.distance
? newinfo
.distance
522 : ZEBRA_RIP_DISTANCE_DEFAULT
;
524 /* Check to see whether there is already RIP route on the table. */
525 if ((list
= rp
->info
) != NULL
)
526 for (ALL_LIST_ELEMENTS_RO(list
, node
, rinfo
)) {
527 /* Need to compare with redistributed entry or local
529 if (!rip_route_rte(rinfo
))
532 if (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
533 && IPV4_ADDR_SAME(&rinfo
->nh
.gate
.ipv4
, nexthop
))
536 if (!listnextnode(node
)) {
537 /* Not found in the list */
539 if (rte
->metric
> rinfo
->metric
) {
540 /* New route has a greater metric.
542 route_unlock_node(rp
);
546 if (rte
->metric
< rinfo
->metric
)
547 /* New route has a smaller metric.
548 * Replace the ECMP list
549 * with the new one in below. */
552 /* Metrics are same. We compare the distances.
554 old_dist
= rinfo
->distance
556 : ZEBRA_RIP_DISTANCE_DEFAULT
;
558 if (new_dist
> old_dist
) {
559 /* New route has a greater distance.
561 route_unlock_node(rp
);
565 if (new_dist
< old_dist
)
566 /* New route has a smaller distance.
567 * Replace the ECMP list
568 * with the new one in below. */
571 /* Metrics and distances are both same. Keep
573 * the new route is added in the ECMP list in
579 /* Local static route. */
580 if (rinfo
->type
== ZEBRA_ROUTE_RIP
581 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
582 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))
583 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
584 route_unlock_node(rp
);
588 /* Redistributed route check. */
589 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
590 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
591 old_dist
= rinfo
->distance
;
592 /* Only routes directly connected to an interface
594 * may have a valid NULL distance */
595 if (rinfo
->nh
.gate
.ipv4
.s_addr
!= INADDR_ANY
)
598 : ZEBRA_RIP_DISTANCE_DEFAULT
;
599 /* If imported route does not have STRICT precedence,
600 mark it as a ghost */
601 if (new_dist
<= old_dist
602 && rte
->metric
!= RIP_METRIC_INFINITY
)
603 rip_ecmp_replace(rip
, &newinfo
);
605 route_unlock_node(rp
);
612 route_unlock_node(rp
);
614 /* Now, check to see whether there is already an explicit route
615 for the destination prefix. If there is no such route, add
616 this route to the routing table, unless the metric is
617 infinity (there is no point in adding a route which
619 if (rte
->metric
!= RIP_METRIC_INFINITY
)
620 rip_ecmp_add(rip
, &newinfo
);
622 /* Route is there but we are not sure the route is RIP or not.
625 /* If there is an existing route, compare the next hop address
626 to the address of the router from which the datagram came.
627 If this datagram is from the same router as the existing
628 route, reinitialize the timeout. */
629 same
= (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
630 && (rinfo
->nh
.ifindex
== ifp
->ifindex
));
632 old_dist
= rinfo
->distance
? rinfo
->distance
633 : ZEBRA_RIP_DISTANCE_DEFAULT
;
635 /* Next, compare the metrics. If the datagram is from the same
636 router as the existing route, and the new metric is different
637 than the old one; or, if the new metric is lower than the old
638 one, or if the tag has been changed; or if there is a route
639 with a lower administrave distance; or an update of the
640 distance on the actual route; do the following actions: */
641 if ((same
&& rinfo
->metric
!= rte
->metric
)
642 || (rte
->metric
< rinfo
->metric
)
643 || ((same
) && (rinfo
->metric
== rte
->metric
)
644 && (newinfo
.tag
!= rinfo
->tag
))
645 || (old_dist
> new_dist
)
646 || ((old_dist
!= new_dist
) && same
)) {
647 if (listcount(list
) == 1) {
648 if (newinfo
.metric
!= RIP_METRIC_INFINITY
)
649 rip_ecmp_replace(rip
, &newinfo
);
651 rip_ecmp_delete(rip
, rinfo
);
653 if (newinfo
.metric
< rinfo
->metric
)
654 rip_ecmp_replace(rip
, &newinfo
);
655 else if (newinfo
.metric
> rinfo
->metric
)
656 rip_ecmp_delete(rip
, rinfo
);
657 else if (new_dist
< old_dist
)
658 rip_ecmp_replace(rip
, &newinfo
);
659 else if (new_dist
> old_dist
)
660 rip_ecmp_delete(rip
, rinfo
);
662 int update
= CHECK_FLAG(rinfo
->flags
,
667 assert(newinfo
.metric
668 != RIP_METRIC_INFINITY
);
670 RIP_TIMER_OFF(rinfo
->t_timeout
);
671 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
672 memcpy(rinfo
, &newinfo
,
673 sizeof(struct rip_info
));
674 rip_timeout_update(rip
, rinfo
);
677 rip_zebra_ipv4_add(rip
, rp
);
679 /* - Set the route change flag on the
681 rinfo
= listgetdata(listhead(list
));
682 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
683 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
686 } else /* same & no change */
687 rip_timeout_update(rip
, rinfo
);
689 /* Unlock tempolary lock of the route. */
690 route_unlock_node(rp
);
694 /* Dump RIP packet */
695 static void rip_packet_dump(struct rip_packet
*packet
, int size
,
700 const char *command_str
;
704 /* Set command string. */
705 if (packet
->command
> 0 && packet
->command
< RIP_COMMAND_MAX
)
706 command_str
= lookup_msg(rip_msg
, packet
->command
, NULL
);
708 command_str
= "unknown";
710 /* Dump packet header. */
711 zlog_debug("%s %s version %d packet size %d", sndrcv
, command_str
,
712 packet
->version
, size
);
714 /* Dump each routing table entry. */
717 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
718 if (packet
->version
== RIPv2
) {
719 netmask
= ip_masklen(rte
->mask
);
721 if (rte
->family
== htons(RIP_FAMILY_AUTH
)) {
723 == htons(RIP_AUTH_SIMPLE_PASSWORD
)) {
724 p
= (uint8_t *)&rte
->prefix
;
727 " family 0x%X type %d auth string: %s",
730 } else if (rte
->tag
== htons(RIP_AUTH_MD5
)) {
731 struct rip_md5_info
*md5
;
733 md5
= (struct rip_md5_info
*)&packet
737 " family 0x%X type %d (MD5 authentication)",
741 " RIP-2 packet len %d Key ID %d Auth Data len %d",
742 ntohs(md5
->packet_len
),
743 md5
->keyid
, md5
->auth_len
);
744 zlog_debug(" Sequence Number %ld",
745 (unsigned long)ntohl(
747 } else if (rte
->tag
== htons(RIP_AUTH_DATA
)) {
748 p
= (uint8_t *)&rte
->prefix
;
751 " family 0x%X type %d (MD5 data)",
755 " MD5: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
756 p
[0], p
[1], p
[2], p
[3], p
[4],
757 p
[5], p
[6], p
[7], p
[8], p
[9],
758 p
[10], p
[11], p
[12], p
[13],
762 " family 0x%X type %d (Unknown auth type)",
768 " %pI4/%d -> %pI4 family %d tag %" ROUTE_TAG_PRI
770 &rte
->prefix
, netmask
, &rte
->nexthop
,
772 (route_tag_t
)ntohs(rte
->tag
),
773 (unsigned long)ntohl(rte
->metric
));
775 zlog_debug(" %pI4 family %d tag %" ROUTE_TAG_PRI
777 &rte
->prefix
, ntohs(rte
->family
),
778 (route_tag_t
)ntohs(rte
->tag
),
779 (unsigned long)ntohl(rte
->metric
));
784 /* Check if the destination address is valid (unicast; not net 0
785 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
786 check net 0 because we accept default route. */
787 static int rip_destination_check(struct in_addr addr
)
789 uint32_t destination
;
791 /* Convert to host byte order. */
792 destination
= ntohl(addr
.s_addr
);
794 if (IPV4_NET127(destination
))
797 /* Net 0 may match to the default route. */
798 if (IPV4_NET0(destination
) && destination
!= 0)
801 /* Unicast address must belong to class A, B, C. */
802 if (IN_CLASSA(destination
))
804 if (IN_CLASSB(destination
))
806 if (IN_CLASSC(destination
))
812 /* RIP version 2 authentication. */
813 static int rip_auth_simple_password(struct rte
*rte
, struct sockaddr_in
*from
,
814 struct interface
*ifp
)
816 struct rip_interface
*ri
;
817 char *auth_str
= (char *)rte
+ offsetof(struct rte
, prefix
);
820 /* reject passwords with zeros in the middle of the string */
821 for (i
= strnlen(auth_str
, 16); i
< 16; i
++) {
822 if (auth_str
[i
] != '\0')
826 if (IS_RIP_DEBUG_EVENT
)
827 zlog_debug("RIPv2 simple password authentication from %pI4",
832 if (ri
->auth_type
!= RIP_AUTH_SIMPLE_PASSWORD
833 || rte
->tag
!= htons(RIP_AUTH_SIMPLE_PASSWORD
))
836 /* Simple password authentication. */
838 if (strncmp(auth_str
, ri
->auth_str
, 16) == 0)
842 struct keychain
*keychain
;
845 keychain
= keychain_lookup(ri
->key_chain
);
846 if (keychain
== NULL
|| keychain
->key
== NULL
)
849 key
= key_match_for_accept(keychain
, auth_str
);
856 /* RIP version 2 authentication with MD5. */
857 static int rip_auth_md5(struct rip_packet
*packet
, struct sockaddr_in
*from
,
858 int length
, struct interface
*ifp
)
860 struct rip_interface
*ri
;
861 struct rip_md5_info
*md5
;
862 struct rip_md5_data
*md5data
;
863 struct keychain
*keychain
;
865 #ifdef CRYPTO_OPENSSL
867 #elif CRYPTO_INTERNAL
870 uint8_t digest
[RIP_AUTH_MD5_SIZE
];
872 char auth_str
[RIP_AUTH_MD5_SIZE
] = {};
874 if (IS_RIP_DEBUG_EVENT
)
875 zlog_debug("RIPv2 MD5 authentication from %pI4",
879 md5
= (struct rip_md5_info
*)&packet
->rte
;
881 /* Check auth type. */
882 if (ri
->auth_type
!= RIP_AUTH_MD5
|| md5
->type
!= htons(RIP_AUTH_MD5
))
885 /* If the authentication length is less than 16, then it must be wrong
887 * any interpretation of rfc2082. Some implementations also interpret
888 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka
889 * RIP_AUTH_MD5_COMPAT_SIZE.
891 if (!((md5
->auth_len
== RIP_AUTH_MD5_SIZE
)
892 || (md5
->auth_len
== RIP_AUTH_MD5_COMPAT_SIZE
))) {
893 if (IS_RIP_DEBUG_EVENT
)
895 "RIPv2 MD5 authentication, strange authentication length field %d",
900 /* grab and verify check packet length */
901 packet_len
= ntohs(md5
->packet_len
);
903 if (packet_len
> (length
- RIP_HEADER_SIZE
- RIP_AUTH_MD5_SIZE
)) {
904 if (IS_RIP_DEBUG_EVENT
)
906 "RIPv2 MD5 authentication, packet length field %d greater than received length %d!",
907 md5
->packet_len
, length
);
911 /* retrieve authentication data */
912 md5data
= (struct rip_md5_data
*)(((uint8_t *)packet
) + packet_len
);
915 keychain
= keychain_lookup(ri
->key_chain
);
916 if (keychain
== NULL
)
919 key
= key_lookup_for_accept(keychain
, md5
->keyid
);
920 if (key
== NULL
|| key
->string
== NULL
)
923 strlcpy(auth_str
, key
->string
, sizeof(auth_str
));
924 } else if (ri
->auth_str
)
925 strlcpy(auth_str
, ri
->auth_str
, sizeof(auth_str
));
927 if (auth_str
[0] == 0)
930 /* MD5 digest authentication. */
931 #ifdef CRYPTO_OPENSSL
932 unsigned int md5_size
= RIP_AUTH_MD5_SIZE
;
933 ctx
= EVP_MD_CTX_new();
934 EVP_DigestInit(ctx
, EVP_md5());
935 EVP_DigestUpdate(ctx
, packet
, packet_len
+ RIP_HEADER_SIZE
);
936 EVP_DigestUpdate(ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
937 EVP_DigestFinal(ctx
, digest
, &md5_size
);
938 EVP_MD_CTX_free(ctx
);
939 #elif CRYPTO_INTERNAL
940 memset(&ctx
, 0, sizeof(ctx
));
942 MD5Update(&ctx
, packet
, packet_len
+ RIP_HEADER_SIZE
);
943 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
944 MD5Final(digest
, &ctx
);
947 if (memcmp(md5data
->digest
, digest
, RIP_AUTH_MD5_SIZE
) == 0)
953 /* Pick correct auth string for sends, prepare auth_str buffer for use.
954 * (left justified and padded).
956 * presumes one of ri or key is valid, and that the auth strings they point
957 * to are nul terminated. If neither are present, auth_str will be fully
961 static void rip_auth_prepare_str_send(struct rip_interface
*ri
, struct key
*key
,
962 char *auth_str
, int len
)
966 memset(auth_str
, 0, len
);
967 if (key
&& key
->string
)
968 strlcpy(auth_str
, key
->string
, len
);
969 else if (ri
->auth_str
)
970 strlcpy(auth_str
, ri
->auth_str
, len
);
975 /* Write RIPv2 simple password authentication information
977 * auth_str is presumed to be 2 bytes and correctly prepared
978 * (left justified and zero padded).
980 static void rip_auth_simple_write(struct stream
*s
, char *auth_str
, int len
)
982 assert(s
&& len
== RIP_AUTH_SIMPLE_SIZE
);
984 stream_putw(s
, RIP_FAMILY_AUTH
);
985 stream_putw(s
, RIP_AUTH_SIMPLE_PASSWORD
);
986 stream_put(s
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
991 /* write RIPv2 MD5 "authentication header"
992 * (uses the auth key data field)
994 * Digest offset field is set to 0.
996 * returns: offset of the digest offset field, which must be set when
997 * length to the auth-data MD5 digest is known.
999 static size_t rip_auth_md5_ah_write(struct stream
*s
, struct rip_interface
*ri
,
1004 assert(s
&& ri
&& ri
->auth_type
== RIP_AUTH_MD5
);
1006 /* MD5 authentication. */
1007 stream_putw(s
, RIP_FAMILY_AUTH
);
1008 stream_putw(s
, RIP_AUTH_MD5
);
1010 /* MD5 AH digest offset field.
1012 * Set to placeholder value here, to true value when RIP-2 Packet length
1013 * is known. Actual value is set in .....().
1015 doff
= stream_get_endp(s
);
1020 stream_putc(s
, key
->index
% 256);
1024 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
1025 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for
1027 * to be configurable.
1029 stream_putc(s
, ri
->md5_auth_len
);
1031 /* Sequence Number (non-decreasing). */
1032 /* RFC2080: The value used in the sequence number is
1033 arbitrary, but two suggestions are the time of the
1034 message's creation or a simple message counter. */
1035 stream_putl(s
, time(NULL
));
1037 /* Reserved field must be zero. */
1044 /* If authentication is in used, write the appropriate header
1045 * returns stream offset to which length must later be written
1046 * or 0 if this is not required
1048 static size_t rip_auth_header_write(struct stream
*s
, struct rip_interface
*ri
,
1049 struct key
*key
, char *auth_str
, int len
)
1051 assert(ri
->auth_type
!= RIP_NO_AUTH
);
1053 switch (ri
->auth_type
) {
1054 case RIP_AUTH_SIMPLE_PASSWORD
:
1055 rip_auth_prepare_str_send(ri
, key
, auth_str
, len
);
1056 rip_auth_simple_write(s
, auth_str
, len
);
1059 return rip_auth_md5_ah_write(s
, ri
, key
);
1065 /* Write RIPv2 MD5 authentication data trailer */
1066 static void rip_auth_md5_set(struct stream
*s
, struct rip_interface
*ri
,
1067 size_t doff
, char *auth_str
, int authlen
)
1070 #ifdef CRYPTO_OPENSSL
1072 #elif CRYPTO_INTERNAL
1075 unsigned char digest
[RIP_AUTH_MD5_SIZE
];
1077 /* Make it sure this interface is configured as MD5
1079 assert((ri
->auth_type
== RIP_AUTH_MD5
)
1080 && (authlen
== RIP_AUTH_MD5_SIZE
));
1083 /* Get packet length. */
1084 len
= stream_get_endp(s
);
1086 /* Check packet length. */
1087 if (len
< (RIP_HEADER_SIZE
+ RIP_RTE_SIZE
)) {
1090 "rip_auth_md5_set(): packet length %ld is less than minimum length.",
1095 /* Set the digest offset length in the header */
1096 stream_putw_at(s
, doff
, len
);
1098 /* Set authentication data. */
1099 stream_putw(s
, RIP_FAMILY_AUTH
);
1100 stream_putw(s
, RIP_AUTH_DATA
);
1102 /* Generate a digest for the RIP packet. */
1103 #ifdef CRYPTO_OPENSSL
1104 unsigned int md5_size
= RIP_AUTH_MD5_SIZE
;
1105 ctx
= EVP_MD_CTX_new();
1106 EVP_DigestInit(ctx
, EVP_md5());
1107 EVP_DigestUpdate(ctx
, STREAM_DATA(s
), stream_get_endp(s
));
1108 EVP_DigestUpdate(ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1109 EVP_DigestFinal(ctx
, digest
, &md5_size
);
1110 EVP_MD_CTX_free(ctx
);
1111 #elif CRYPTO_INTERNAL
1112 memset(&ctx
, 0, sizeof(ctx
));
1114 MD5Update(&ctx
, STREAM_DATA(s
), stream_get_endp(s
));
1115 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1116 MD5Final(digest
, &ctx
);
1119 /* Copy the digest to the packet. */
1120 stream_write(s
, digest
, RIP_AUTH_MD5_SIZE
);
1123 /* RIP routing information. */
1124 static void rip_response_process(struct rip_packet
*packet
, int size
,
1125 struct sockaddr_in
*from
,
1126 struct connected
*ifc
)
1128 struct rip_interface
*ri
= ifc
->ifp
->info
;
1129 struct rip
*rip
= ri
->rip
;
1132 struct prefix_ipv4 ifaddr
;
1133 struct prefix_ipv4 ifaddrclass
;
1136 memset(&ifaddr
, 0, sizeof(ifaddr
));
1137 /* We don't know yet. */
1140 /* The Response must be ignored if it is not from the RIP
1141 port. (RFC2453 - Sec. 3.9.2)*/
1142 if (from
->sin_port
!= htons(RIP_PORT_DEFAULT
)) {
1143 zlog_info("response doesn't come from RIP port: %d",
1145 rip_peer_bad_packet(rip
, from
);
1149 /* The datagram's IPv4 source address should be checked to see
1150 whether the datagram is from a valid neighbor; the source of the
1151 datagram must be on a directly connected network (RFC2453 - Sec.
1153 if (if_lookup_address((void *)&from
->sin_addr
, AF_INET
,
1157 "This datagram doesn't come from a valid neighbor: %pI4",
1159 rip_peer_bad_packet(rip
, from
);
1163 /* It is also worth checking to see whether the response is from one
1164 of the router's own addresses. */
1166 ; /* Alredy done in rip_read () */
1168 /* Update RIP peer. */
1169 rip_peer_update(rip
, from
, packet
->version
);
1171 /* Set RTE pointer. */
1174 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
1175 /* RIPv2 authentication check. */
1176 /* If the Address Family Identifier of the first (and only the
1177 first) entry in the message is 0xFFFF, then the remainder of
1178 the entry contains the authentication. */
1179 /* If the packet gets here it means authentication enabled */
1180 /* Check is done in rip_read(). So, just skipping it */
1181 if (packet
->version
== RIPv2
&& rte
== packet
->rte
1182 && rte
->family
== htons(RIP_FAMILY_AUTH
))
1185 if (rte
->family
!= htons(AF_INET
)) {
1186 /* Address family check. RIP only supports AF_INET. */
1187 zlog_info("Unsupported family %d from %pI4",
1193 /* - is the destination address valid (e.g., unicast; not net 0
1195 if (!rip_destination_check(rte
->prefix
)) {
1197 "Network is net 0 or net 127 or it is not unicast network");
1198 rip_peer_bad_route(rip
, from
);
1202 /* Convert metric value to host byte order. */
1203 rte
->metric
= ntohl(rte
->metric
);
1205 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1206 if (!(rte
->metric
>= 1 && rte
->metric
<= 16)) {
1207 zlog_info("Route's metric is not in the 1-16 range.");
1208 rip_peer_bad_route(rip
, from
);
1212 /* RIPv1 does not have nexthop value. */
1213 if (packet
->version
== RIPv1
1214 && rte
->nexthop
.s_addr
!= INADDR_ANY
) {
1215 zlog_info("RIPv1 packet with nexthop value %pI4",
1217 rip_peer_bad_route(rip
, from
);
1221 /* That is, if the provided information is ignored, a possibly
1222 sub-optimal, but absolutely valid, route may be taken. If
1223 the received Next Hop is not directly reachable, it should be
1224 treated as 0.0.0.0. */
1225 if (packet
->version
== RIPv2
1226 && rte
->nexthop
.s_addr
!= INADDR_ANY
) {
1229 /* Multicast address check. */
1230 addrval
= ntohl(rte
->nexthop
.s_addr
);
1231 if (IN_CLASSD(addrval
)) {
1233 "Nexthop %pI4 is multicast address, skip this rte",
1238 if (!if_lookup_address((void *)&rte
->nexthop
, AF_INET
,
1239 rip
->vrf
->vrf_id
)) {
1240 struct route_node
*rn
;
1241 struct rip_info
*rinfo
;
1243 rn
= route_node_match_ipv4(rip
->table
,
1249 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1252 if (IS_RIP_DEBUG_EVENT
)
1254 "Next hop %pI4 is on RIP network. Set nexthop to the packet's originator",
1256 rte
->nexthop
= rinfo
->from
;
1258 if (IS_RIP_DEBUG_EVENT
)
1260 "Next hop %pI4 is not directly reachable. Treat it as 0.0.0.0",
1262 rte
->nexthop
.s_addr
=
1266 route_unlock_node(rn
);
1268 if (IS_RIP_DEBUG_EVENT
)
1270 "Next hop %pI4 is not directly reachable. Treat it as 0.0.0.0",
1272 rte
->nexthop
.s_addr
= INADDR_ANY
;
1277 /* For RIPv1, there won't be a valid netmask.
1279 This is a best guess at the masks. If everyone was using old
1280 Ciscos before the 'ip subnet zero' option, it would be almost
1283 Cisco summarize ripv1 advertisements to the classful boundary
1284 (/16 for class B's) except when the RIP packet does to inside
1285 the classful network in question. */
1287 if ((packet
->version
== RIPv1
1288 && rte
->prefix
.s_addr
!= INADDR_ANY
)
1289 || (packet
->version
== RIPv2
1290 && (rte
->prefix
.s_addr
!= INADDR_ANY
1291 && rte
->mask
.s_addr
== INADDR_ANY
))) {
1292 uint32_t destination
;
1294 if (subnetted
== -1) {
1295 memcpy(&ifaddr
, ifc
->address
,
1296 sizeof(struct prefix_ipv4
));
1297 memcpy(&ifaddrclass
, &ifaddr
,
1298 sizeof(struct prefix_ipv4
));
1299 apply_classful_mask_ipv4(&ifaddrclass
);
1301 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1305 destination
= ntohl(rte
->prefix
.s_addr
);
1307 if (IN_CLASSA(destination
))
1308 masklen2ip(8, &rte
->mask
);
1309 else if (IN_CLASSB(destination
))
1310 masklen2ip(16, &rte
->mask
);
1311 else if (IN_CLASSC(destination
))
1312 masklen2ip(24, &rte
->mask
);
1315 masklen2ip(ifaddrclass
.prefixlen
,
1316 (struct in_addr
*)&destination
);
1317 if ((subnetted
== 1)
1318 && ((rte
->prefix
.s_addr
& destination
)
1319 == ifaddrclass
.prefix
.s_addr
)) {
1320 masklen2ip(ifaddr
.prefixlen
, &rte
->mask
);
1321 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1322 != rte
->prefix
.s_addr
)
1323 masklen2ip(32, &rte
->mask
);
1324 if (IS_RIP_DEBUG_EVENT
)
1325 zlog_debug("Subnetted route %pI4",
1328 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1329 != rte
->prefix
.s_addr
)
1333 if (IS_RIP_DEBUG_EVENT
) {
1334 zlog_debug("Resultant route %pI4",
1336 zlog_debug("Resultant mask %pI4",
1341 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1342 ignore the entry. */
1343 if ((packet
->version
== RIPv2
)
1344 && (rte
->mask
.s_addr
!= INADDR_ANY
)
1345 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1346 != rte
->prefix
.s_addr
)) {
1348 "RIPv2 address %pI4 is not mask /%d applied one",
1349 &rte
->prefix
, ip_masklen(rte
->mask
));
1350 rip_peer_bad_route(rip
, from
);
1354 /* Default route's netmask is ignored. */
1355 if (packet
->version
== RIPv2
1356 && (rte
->prefix
.s_addr
== INADDR_ANY
)
1357 && (rte
->mask
.s_addr
!= INADDR_ANY
)) {
1358 if (IS_RIP_DEBUG_EVENT
)
1360 "Default route with non-zero netmask. Set zero to netmask");
1361 rte
->mask
.s_addr
= INADDR_ANY
;
1364 /* Routing table updates. */
1365 rip_rte_process(rte
, from
, ifc
->ifp
);
1369 /* Make socket for RIP protocol. */
1370 int rip_create_socket(struct vrf
*vrf
)
1374 struct sockaddr_in addr
;
1375 const char *vrf_dev
= NULL
;
1377 memset(&addr
, 0, sizeof(struct sockaddr_in
));
1378 addr
.sin_family
= AF_INET
;
1379 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1380 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1381 addr
.sin_len
= sizeof(struct sockaddr_in
);
1382 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1383 /* sending port must always be the RIP port */
1384 addr
.sin_port
= htons(RIP_PORT_DEFAULT
);
1386 /* Make datagram socket. */
1387 if (vrf
->vrf_id
!= VRF_DEFAULT
)
1388 vrf_dev
= vrf
->name
;
1389 frr_with_privs(&ripd_privs
) {
1390 sock
= vrf_socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
, vrf
->vrf_id
,
1393 flog_err_sys(EC_LIB_SOCKET
,
1394 "Cannot create UDP socket: %s",
1395 safe_strerror(errno
));
1400 sockopt_broadcast(sock
);
1401 sockopt_reuseaddr(sock
);
1402 sockopt_reuseport(sock
);
1403 setsockopt_ipv4_multicast_loop(sock
, 0);
1404 #ifdef IPTOS_PREC_INTERNETCONTROL
1405 setsockopt_ipv4_tos(sock
, IPTOS_PREC_INTERNETCONTROL
);
1407 setsockopt_so_recvbuf(sock
, RIP_UDP_RCV_BUF
);
1409 frr_with_privs(&ripd_privs
) {
1410 if ((ret
= bind(sock
, (struct sockaddr
*)&addr
, sizeof(addr
)))
1412 zlog_err("%s: Can't bind socket %d to %pI4 port %d: %s",
1413 __func__
, sock
, &addr
.sin_addr
,
1414 (int)ntohs(addr
.sin_port
),
1415 safe_strerror(errno
));
1425 /* RIP packet send to destination address, on interface denoted by
1426 * by connected argument. NULL to argument denotes destination should be
1427 * should be RIP multicast group
1429 static int rip_send_packet(uint8_t *buf
, int size
, struct sockaddr_in
*to
,
1430 struct connected
*ifc
)
1432 struct rip_interface
*ri
;
1435 struct sockaddr_in sin
;
1439 struct cmsghdr
*cmsgptr
;
1440 char adata
[256] = {};
1441 struct in_pktinfo
*pkt
;
1442 #endif /* GNU_LINUX */
1444 assert(ifc
!= NULL
);
1445 ri
= ifc
->ifp
->info
;
1448 if (IS_RIP_DEBUG_PACKET
) {
1449 #define ADDRESS_SIZE 20
1450 char dst
[ADDRESS_SIZE
];
1453 inet_ntop(AF_INET
, &to
->sin_addr
, dst
, sizeof(dst
));
1455 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1456 inet_ntop(AF_INET
, &sin
.sin_addr
, dst
, sizeof(dst
));
1459 zlog_debug("rip_send_packet %pI4 > %s (%s)",
1460 &ifc
->address
->u
.prefix4
, dst
,
1464 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
1466 * ZEBRA_IFA_SECONDARY is set on linux when an interface is
1468 * with multiple addresses on the same subnet: the first address
1469 * on the subnet is configured "primary", and all subsequent
1471 * on that subnet are treated as "secondary" addresses.
1472 * In order to avoid routing-table bloat on other rip listeners,
1473 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY
1475 * XXX Since Linux is the only system for which the
1476 * ZEBRA_IFA_SECONDARY
1477 * flag is set, we would end up sending a packet for a
1479 * source address on non-linux systems.
1481 if (IS_RIP_DEBUG_PACKET
)
1482 zlog_debug("duplicate dropped");
1486 /* Make destination address. */
1487 memset(&sin
, 0, sizeof(struct sockaddr_in
));
1488 sin
.sin_family
= AF_INET
;
1489 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1490 sin
.sin_len
= sizeof(struct sockaddr_in
);
1491 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1493 /* When destination is specified, use it's port and address. */
1495 sin
.sin_port
= to
->sin_port
;
1496 sin
.sin_addr
= to
->sin_addr
;
1498 sin
.sin_port
= htons(RIP_PORT_DEFAULT
);
1499 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1501 rip_interface_multicast_set(rip
->sock
, ifc
);
1504 memset(&msg
, 0, sizeof(msg
));
1505 msg
.msg_name
= (void *)&sin
;
1506 msg
.msg_namelen
= sizeof(struct sockaddr_in
);
1513 msg
.msg_control
= (void *)adata
;
1514 msg
.msg_controllen
= CMSG_SPACE(sizeof(struct in_pktinfo
));
1516 cmsgptr
= (struct cmsghdr
*)adata
;
1517 cmsgptr
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
1518 cmsgptr
->cmsg_level
= IPPROTO_IP
;
1519 cmsgptr
->cmsg_type
= IP_PKTINFO
;
1520 pkt
= (struct in_pktinfo
*)CMSG_DATA(cmsgptr
);
1521 pkt
->ipi_ifindex
= ifc
->ifp
->ifindex
;
1522 #endif /* GNU_LINUX */
1524 ret
= sendmsg(rip
->sock
, &msg
, 0);
1526 if (IS_RIP_DEBUG_EVENT
)
1527 zlog_debug("SEND to %pI4%d", &sin
.sin_addr
,
1528 ntohs(sin
.sin_port
));
1531 zlog_warn("can't send packet : %s", safe_strerror(errno
));
1536 /* Add redistributed route to RIP table. */
1537 void rip_redistribute_add(struct rip
*rip
, int type
, int sub_type
,
1538 struct prefix_ipv4
*p
, struct nexthop
*nh
,
1539 unsigned int metric
, unsigned char distance
,
1543 struct route_node
*rp
= NULL
;
1544 struct rip_info
*rinfo
= NULL
, newinfo
;
1545 struct list
*list
= NULL
;
1547 /* Redistribute route */
1548 ret
= rip_destination_check(p
->prefix
);
1552 rp
= route_node_get(rip
->table
, (struct prefix
*)p
);
1554 memset(&newinfo
, 0, sizeof(struct rip_info
));
1555 newinfo
.type
= type
;
1556 newinfo
.sub_type
= sub_type
;
1558 newinfo
.external_metric
= metric
;
1559 newinfo
.distance
= distance
;
1560 if (tag
<= UINT16_MAX
) /* RIP only supports 16 bit tags */
1565 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
1566 rinfo
= listgetdata(listhead(list
));
1568 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
1569 && rinfo
->sub_type
== RIP_ROUTE_INTERFACE
1570 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
1571 route_unlock_node(rp
);
1575 /* Manually configured RIP route check. */
1576 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1577 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
1578 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))) {
1579 if (type
!= ZEBRA_ROUTE_RIP
1580 || ((sub_type
!= RIP_ROUTE_STATIC
)
1581 && (sub_type
!= RIP_ROUTE_DEFAULT
))) {
1582 route_unlock_node(rp
);
1587 (void)rip_ecmp_replace(rip
, &newinfo
);
1588 route_unlock_node(rp
);
1590 (void)rip_ecmp_add(rip
, &newinfo
);
1592 if (IS_RIP_DEBUG_EVENT
) {
1593 zlog_debug("Redistribute new prefix %pFX", p
);
1596 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
1599 /* Delete redistributed route from RIP table. */
1600 void rip_redistribute_delete(struct rip
*rip
, int type
, int sub_type
,
1601 struct prefix_ipv4
*p
, ifindex_t ifindex
)
1604 struct route_node
*rp
;
1605 struct rip_info
*rinfo
;
1607 ret
= rip_destination_check(p
->prefix
);
1611 rp
= route_node_lookup(rip
->table
, (struct prefix
*)p
);
1613 struct list
*list
= rp
->info
;
1615 if (list
!= NULL
&& listcount(list
) != 0) {
1616 rinfo
= listgetdata(listhead(list
));
1617 if (rinfo
!= NULL
&& rinfo
->type
== type
1618 && rinfo
->sub_type
== sub_type
1619 && rinfo
->nh
.ifindex
== ifindex
) {
1620 /* Perform poisoned reverse. */
1621 rinfo
->metric
= RIP_METRIC_INFINITY
;
1622 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
1623 rip_garbage_collect
,
1625 RIP_TIMER_OFF(rinfo
->t_timeout
);
1626 rinfo
->flags
|= RIP_RTF_CHANGED
;
1628 if (IS_RIP_DEBUG_EVENT
)
1630 "Poison %pFX on the interface %s with an infinity metric [delete]",
1636 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
1639 route_unlock_node(rp
);
1643 /* Response to request called from rip_read ().*/
1644 static void rip_request_process(struct rip_packet
*packet
, int size
,
1645 struct sockaddr_in
*from
, struct connected
*ifc
)
1650 struct prefix_ipv4 p
;
1651 struct route_node
*rp
;
1652 struct rip_info
*rinfo
;
1653 struct rip_interface
*ri
;
1655 /* Does not reponse to the requests on the loopback interfaces */
1656 if (if_is_loopback(ifc
->ifp
))
1659 /* Check RIP process is enabled on this interface. */
1660 ri
= ifc
->ifp
->info
;
1665 /* When passive interface is specified, suppress responses */
1669 /* RIP peer update. */
1670 rip_peer_update(rip
, from
, packet
->version
);
1672 lim
= ((caddr_t
)packet
) + size
;
1675 /* The Request is processed entry by entry. If there are no
1676 entries, no response is given. */
1677 if (lim
== (caddr_t
)rte
)
1680 /* There is one special case. If there is exactly one entry in the
1681 request, and it has an address family identifier of zero and a
1682 metric of infinity (i.e., 16), then this is a request to send the
1683 entire routing table. */
1684 if (lim
== ((caddr_t
)(rte
+ 1)) && ntohs(rte
->family
) == 0
1685 && ntohl(rte
->metric
) == RIP_METRIC_INFINITY
) {
1686 /* All route with split horizon */
1687 rip_output_process(ifc
, from
, rip_all_route
, packet
->version
);
1689 if (ntohs(rte
->family
) != AF_INET
)
1692 /* Examine the list of RTEs in the Request one by one. For each
1693 entry, look up the destination in the router's routing
1694 database and, if there is a route, put that route's metric in
1695 the metric field of the RTE. If there is no explicit route
1696 to the specified destination, put infinity in the metric
1697 field. Once all the entries have been filled in, change the
1698 command from Request to Response and send the datagram back
1699 to the requestor. */
1702 for (; ((caddr_t
)rte
) < lim
; rte
++) {
1703 p
.prefix
= rte
->prefix
;
1704 p
.prefixlen
= ip_masklen(rte
->mask
);
1705 apply_mask_ipv4(&p
);
1707 rp
= route_node_lookup(rip
->table
, (struct prefix
*)&p
);
1709 rinfo
= listgetdata(
1710 listhead((struct list
*)rp
->info
));
1711 rte
->metric
= htonl(rinfo
->metric
);
1712 route_unlock_node(rp
);
1714 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
1716 packet
->command
= RIP_RESPONSE
;
1718 (void)rip_send_packet((uint8_t *)packet
, size
, from
, ifc
);
1720 rip
->counters
.queries
++;
1723 /* First entry point of RIP packet. */
1724 static int rip_read(struct thread
*t
)
1726 struct rip
*rip
= THREAD_ARG(t
);
1730 union rip_buf rip_buf
;
1731 struct rip_packet
*packet
;
1732 struct sockaddr_in from
;
1736 struct interface
*ifp
= NULL
;
1737 struct connected
*ifc
;
1738 struct rip_interface
*ri
;
1741 /* Fetch socket then register myself. */
1742 sock
= THREAD_FD(t
);
1745 /* Add myself to tne next event */
1746 rip_event(rip
, RIP_READ
, sock
);
1748 /* RIPd manages only IPv4. */
1749 memset(&from
, 0, sizeof(struct sockaddr_in
));
1750 fromlen
= sizeof(struct sockaddr_in
);
1752 len
= recvfrom(sock
, (char *)&rip_buf
.buf
, sizeof(rip_buf
.buf
), 0,
1753 (struct sockaddr
*)&from
, &fromlen
);
1755 zlog_info("recvfrom failed (VRF %s): %s", rip
->vrf_name
,
1756 safe_strerror(errno
));
1760 /* Check is this packet comming from myself? */
1761 if (if_check_address(rip
, from
.sin_addr
)) {
1762 if (IS_RIP_DEBUG_PACKET
)
1763 zlog_debug("ignore packet comes from myself (VRF %s)",
1768 /* Which interface is this packet comes from. */
1769 ifc
= if_lookup_address((void *)&from
.sin_addr
, AF_INET
,
1774 /* RIP packet received */
1775 if (IS_RIP_DEBUG_EVENT
)
1776 zlog_debug("RECV packet from %pI4 port %d on %s (VRF %s)",
1777 &from
.sin_addr
, ntohs(from
.sin_port
),
1778 ifp
? ifp
->name
: "unknown", rip
->vrf_name
);
1780 /* If this packet come from unknown interface, ignore it. */
1783 "rip_read: cannot find interface for packet from %pI4 port %d (VRF %s)",
1784 &from
.sin_addr
, ntohs(from
.sin_port
),
1790 p
.u
.prefix4
= from
.sin_addr
;
1791 p
.prefixlen
= IPV4_MAX_BITLEN
;
1793 ifc
= connected_lookup_prefix(ifp
, &p
);
1797 "rip_read: cannot find connected address for packet from %pI4 port %d on interface %s (VRF %s)",
1798 &from
.sin_addr
, ntohs(from
.sin_port
),
1799 ifp
->name
, rip
->vrf_name
);
1803 /* Packet length check. */
1804 if (len
< RIP_PACKET_MINSIZ
) {
1805 zlog_warn("packet size %d is smaller than minimum size %d", len
,
1807 rip_peer_bad_packet(rip
, &from
);
1810 if (len
> RIP_PACKET_MAXSIZ
) {
1811 zlog_warn("packet size %d is larger than max size %d", len
,
1813 rip_peer_bad_packet(rip
, &from
);
1817 /* Packet alignment check. */
1818 if ((len
- RIP_PACKET_MINSIZ
) % 20) {
1819 zlog_warn("packet size %d is wrong for RIP packet alignment",
1821 rip_peer_bad_packet(rip
, &from
);
1825 /* Set RTE number. */
1826 rtenum
= ((len
- RIP_PACKET_MINSIZ
) / 20);
1828 /* For easy to handle. */
1829 packet
= &rip_buf
.rip_packet
;
1831 /* RIP version check. */
1832 if (packet
->version
== 0) {
1833 zlog_info("version 0 with command %d received.",
1835 rip_peer_bad_packet(rip
, &from
);
1839 /* Dump RIP packet. */
1840 if (IS_RIP_DEBUG_RECV
)
1841 rip_packet_dump(packet
, len
, "RECV");
1843 /* RIP version adjust. This code should rethink now. RFC1058 says
1844 that "Version 1 implementations are to ignore this extra data and
1845 process only the fields specified in this document.". So RIPv3
1846 packet should be treated as RIPv1 ignoring must be zero field. */
1847 if (packet
->version
> RIPv2
)
1848 packet
->version
= RIPv2
;
1850 /* Is RIP running or is this RIP neighbor ?*/
1852 if (!ri
->running
&& !rip_neighbor_lookup(rip
, &from
)) {
1853 if (IS_RIP_DEBUG_EVENT
)
1854 zlog_debug("RIP is not enabled on interface %s.",
1856 rip_peer_bad_packet(rip
, &from
);
1860 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1861 vrecv
= ((ri
->ri_receive
== RI_RIP_UNSPEC
) ? rip
->version_recv
1863 if (vrecv
== RI_RIP_VERSION_NONE
1864 || ((packet
->version
== RIPv1
) && !(vrecv
& RIPv1
))
1865 || ((packet
->version
== RIPv2
) && !(vrecv
& RIPv2
))) {
1866 if (IS_RIP_DEBUG_PACKET
)
1868 " packet's v%d doesn't fit to if version spec",
1870 rip_peer_bad_packet(rip
, &from
);
1874 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1875 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1876 accepted; authenticated RIP-2 messages shall be discarded. */
1877 if ((ri
->auth_type
== RIP_NO_AUTH
) && rtenum
1878 && (packet
->version
== RIPv2
)
1879 && (packet
->rte
->family
== htons(RIP_FAMILY_AUTH
))) {
1880 if (IS_RIP_DEBUG_EVENT
)
1882 "packet RIPv%d is dropped because authentication disabled",
1884 ripd_notif_send_auth_type_failure(ifp
->name
);
1885 rip_peer_bad_packet(rip
, &from
);
1890 If the router is configured to authenticate RIP-2 messages, then
1891 RIP-1 messages and RIP-2 messages which pass authentication
1892 testing shall be accepted; unauthenticated and failed
1893 authentication RIP-2 messages shall be discarded. For maximum
1894 security, RIP-1 messages should be ignored when authentication is
1895 in use (see section 4.1); otherwise, the routing information from
1896 authenticated messages will be propagated by RIP-1 routers in an
1897 unauthenticated manner.
1899 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1900 * always reply regardless of authentication settings, because:
1902 * - if there other authorised routers on-link, the REQUESTor can
1903 * passively obtain the routing updates anyway
1904 * - if there are no other authorised routers on-link, RIP can
1905 * easily be disabled for the link to prevent giving out information
1906 * on state of this routers RIP routing table..
1908 * I.e. if RIPv1 has any place anymore these days, it's as a very
1909 * simple way to distribute routing information (e.g. to embedded
1910 * hosts / appliances) and the ability to give out RIPv1
1911 * routing-information freely, while still requiring RIPv2
1912 * authentication for any RESPONSEs might be vaguely useful.
1914 if (ri
->auth_type
!= RIP_NO_AUTH
&& packet
->version
== RIPv1
) {
1915 /* Discard RIPv1 messages other than REQUESTs */
1916 if (packet
->command
!= RIP_REQUEST
) {
1917 if (IS_RIP_DEBUG_PACKET
)
1919 "RIPv1 dropped because authentication enabled");
1920 ripd_notif_send_auth_type_failure(ifp
->name
);
1921 rip_peer_bad_packet(rip
, &from
);
1924 } else if (ri
->auth_type
!= RIP_NO_AUTH
) {
1925 const char *auth_desc
;
1928 /* There definitely is no authentication in the packet.
1930 if (IS_RIP_DEBUG_PACKET
)
1932 "RIPv2 authentication failed: no auth RTE in packet");
1933 ripd_notif_send_auth_type_failure(ifp
->name
);
1934 rip_peer_bad_packet(rip
, &from
);
1938 /* First RTE must be an Authentication Family RTE */
1939 if (packet
->rte
->family
!= htons(RIP_FAMILY_AUTH
)) {
1940 if (IS_RIP_DEBUG_PACKET
)
1942 "RIPv2 dropped because authentication enabled");
1943 ripd_notif_send_auth_type_failure(ifp
->name
);
1944 rip_peer_bad_packet(rip
, &from
);
1948 /* Check RIPv2 authentication. */
1949 switch (ntohs(packet
->rte
->tag
)) {
1950 case RIP_AUTH_SIMPLE_PASSWORD
:
1951 auth_desc
= "simple";
1952 ret
= rip_auth_simple_password(packet
->rte
, &from
, ifp
);
1957 ret
= rip_auth_md5(packet
, &from
, len
, ifp
);
1958 /* Reset RIP packet length to trim MD5 data. */
1964 auth_desc
= "unknown type";
1965 if (IS_RIP_DEBUG_PACKET
)
1967 "RIPv2 Unknown authentication type %d",
1968 ntohs(packet
->rte
->tag
));
1972 if (IS_RIP_DEBUG_PACKET
)
1973 zlog_debug("RIPv2 %s authentication success",
1976 if (IS_RIP_DEBUG_PACKET
)
1977 zlog_debug("RIPv2 %s authentication failure",
1979 ripd_notif_send_auth_failure(ifp
->name
);
1980 rip_peer_bad_packet(rip
, &from
);
1985 /* Process each command. */
1986 switch (packet
->command
) {
1988 rip_response_process(packet
, len
, &from
, ifc
);
1992 rip_request_process(packet
, len
, &from
, ifc
);
1997 "Obsolete command %s received, please sent it to routed",
1998 lookup_msg(rip_msg
, packet
->command
, NULL
));
1999 rip_peer_bad_packet(rip
, &from
);
2001 case RIP_POLL_ENTRY
:
2002 zlog_info("Obsolete command %s received",
2003 lookup_msg(rip_msg
, packet
->command
, NULL
));
2004 rip_peer_bad_packet(rip
, &from
);
2007 zlog_info("Unknown RIP command %d received", packet
->command
);
2008 rip_peer_bad_packet(rip
, &from
);
2015 /* Write routing table entry to the stream and return next index of
2016 the routing table entry in the stream. */
2017 static int rip_write_rte(int num
, struct stream
*s
, struct prefix_ipv4
*p
,
2018 uint8_t version
, struct rip_info
*rinfo
)
2020 struct in_addr mask
;
2022 /* Write routing table entry. */
2023 if (version
== RIPv1
) {
2024 stream_putw(s
, AF_INET
);
2026 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2027 stream_put_ipv4(s
, 0);
2028 stream_put_ipv4(s
, 0);
2029 stream_putl(s
, rinfo
->metric_out
);
2031 masklen2ip(p
->prefixlen
, &mask
);
2033 stream_putw(s
, AF_INET
);
2034 stream_putw(s
, rinfo
->tag_out
);
2035 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2036 stream_put_ipv4(s
, mask
.s_addr
);
2037 stream_put_ipv4(s
, rinfo
->nexthop_out
.s_addr
);
2038 stream_putl(s
, rinfo
->metric_out
);
2044 /* Send update to the ifp or spcified neighbor. */
2045 void rip_output_process(struct connected
*ifc
, struct sockaddr_in
*to
,
2046 int route_type
, uint8_t version
)
2051 struct route_node
*rp
;
2052 struct rip_info
*rinfo
;
2053 struct rip_interface
*ri
;
2054 struct prefix_ipv4
*p
;
2055 struct prefix_ipv4 classfull
;
2056 struct prefix_ipv4 ifaddrclass
;
2057 struct key
*key
= NULL
;
2058 /* this might need to made dynamic if RIP ever supported auth methods
2059 with larger key string sizes */
2060 char auth_str
[RIP_AUTH_SIMPLE_SIZE
];
2061 size_t doff
= 0; /* offset of digest offset field */
2065 struct list
*list
= NULL
;
2066 struct listnode
*listnode
= NULL
;
2068 /* Logging output event. */
2069 if (IS_RIP_DEBUG_EVENT
) {
2071 zlog_debug("update routes to neighbor %pI4",
2074 zlog_debug("update routes on interface %s ifindex %d",
2075 ifc
->ifp
->name
, ifc
->ifp
->ifindex
);
2078 /* Get RIP interface. */
2079 ri
= ifc
->ifp
->info
;
2082 /* Set output stream. */
2085 /* Reset stream and RTE counter. */
2087 rtemax
= RIP_MAX_RTE
;
2089 /* If output interface is in simple password authentication mode, we
2090 need space for authentication data. */
2091 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2094 /* If output interface is in MD5 authentication mode, we need space
2095 for authentication header and data. */
2096 if (ri
->auth_type
== RIP_AUTH_MD5
)
2099 /* If output interface is in simple password authentication mode
2100 and string or keychain is specified we need space for auth. data */
2101 if (ri
->auth_type
!= RIP_NO_AUTH
) {
2102 if (ri
->key_chain
) {
2103 struct keychain
*keychain
;
2105 keychain
= keychain_lookup(ri
->key_chain
);
2107 key
= key_lookup_for_send(keychain
);
2109 /* to be passed to auth functions later */
2110 rip_auth_prepare_str_send(ri
, key
, auth_str
, sizeof(auth_str
));
2111 if (strlen(auth_str
) == 0)
2115 if (version
== RIPv1
) {
2116 memcpy(&ifaddrclass
, ifc
->address
, sizeof(struct prefix_ipv4
));
2117 apply_classful_mask_ipv4(&ifaddrclass
);
2119 if (ifc
->address
->prefixlen
> ifaddrclass
.prefixlen
)
2123 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2124 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
2125 rinfo
= listgetdata(listhead(list
));
2126 /* For RIPv1, if we are subnetted, output subnets in our
2128 /* that have the same mask as the output "interface".
2130 /* networks, only the classfull version is output. */
2132 if (version
== RIPv1
) {
2133 p
= (struct prefix_ipv4
*)&rp
->p
;
2135 if (IS_RIP_DEBUG_PACKET
)
2137 "RIPv1 mask check, %pFX considered for output",
2142 (struct prefix
*)&ifaddrclass
,
2144 if ((ifc
->address
->prefixlen
2146 && (rp
->p
.prefixlen
!= 32))
2149 memcpy(&classfull
, &rp
->p
,
2150 sizeof(struct prefix_ipv4
));
2151 apply_classful_mask_ipv4(&classfull
);
2152 if (rp
->p
.u
.prefix4
.s_addr
!= INADDR_ANY
2153 && classfull
.prefixlen
2157 if (IS_RIP_DEBUG_PACKET
)
2159 "RIPv1 mask check, %pFX made it through",
2162 p
= (struct prefix_ipv4
*)&rp
->p
;
2164 /* Apply output filters. */
2165 ret
= rip_filter(RIP_FILTER_OUT
, p
, ri
);
2169 /* Changed route only output. */
2170 if (route_type
== rip_changed_route
2171 && (!(rinfo
->flags
& RIP_RTF_CHANGED
)))
2174 /* Split horizon. */
2175 /* if (split_horizon == rip_split_horizon) */
2176 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
) {
2178 * We perform split horizon for RIP and
2180 * For rip routes, we want to suppress the route
2182 * end up sending the route back on the
2184 * learned it from, with a higher metric. For
2186 * we suppress the route if the prefix is a
2188 * source address that we are going to use for
2190 * (in order to handle the case when multiple
2192 * configured on the same interface).
2195 struct rip_info
*tmp_rinfo
= NULL
;
2196 struct connected
*tmp_ifc
= NULL
;
2198 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2200 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2201 && tmp_rinfo
->nh
.ifindex
2202 == ifc
->ifp
->ifindex
) {
2208 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2209 for (ALL_LIST_ELEMENTS_RO(
2210 ifc
->ifp
->connected
,
2214 tmp_ifc
->address
)) {
2224 /* Preparation for route-map. */
2225 rinfo
->metric_set
= 0;
2226 rinfo
->nexthop_out
.s_addr
= 0;
2227 rinfo
->metric_out
= rinfo
->metric
;
2228 rinfo
->tag_out
= rinfo
->tag
;
2229 rinfo
->ifindex_out
= ifc
->ifp
->ifindex
;
2231 /* In order to avoid some local loops,
2232 * if the RIP route has a nexthop via this interface,
2234 * otherwise set it to 0. The nexthop should not be
2236 * beyond the local broadcast/multicast area in order
2237 * to avoid an IGP multi-level recursive look-up.
2240 if (rinfo
->nh
.ifindex
== ifc
->ifp
->ifindex
)
2241 rinfo
->nexthop_out
= rinfo
->nh
.gate
.ipv4
;
2243 /* Interface route-map */
2244 if (ri
->routemap
[RIP_FILTER_OUT
]) {
2245 ret
= route_map_apply(
2246 ri
->routemap
[RIP_FILTER_OUT
],
2247 (struct prefix
*)p
, rinfo
);
2249 if (ret
== RMAP_DENYMATCH
) {
2250 if (IS_RIP_DEBUG_PACKET
)
2252 "RIP %pFX is filtered by route-map out",
2258 /* Apply redistribute route map - continue, if deny */
2259 if (rip
->redist
[rinfo
->type
].route_map
.name
2260 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2261 ret
= route_map_apply(
2262 rip
->redist
[rinfo
->type
].route_map
.map
,
2263 (struct prefix
*)p
, rinfo
);
2265 if (ret
== RMAP_DENYMATCH
) {
2266 if (IS_RIP_DEBUG_PACKET
)
2268 "%pFX is filtered by route-map",
2274 /* When route-map does not set metric. */
2275 if (!rinfo
->metric_set
) {
2276 /* If redistribute metric is set. */
2277 if (rip
->redist
[rinfo
->type
].metric_config
2278 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
2280 rip
->redist
[rinfo
->type
].metric
;
2282 /* If the route is not connected or
2284 one, use default-metric value*/
2285 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2287 != ZEBRA_ROUTE_CONNECT
2289 != RIP_METRIC_INFINITY
)
2291 rip
->default_metric
;
2295 /* Apply offset-list */
2296 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2297 rip_offset_list_apply_out(p
, ifc
->ifp
,
2298 &rinfo
->metric_out
);
2300 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2301 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2303 /* Perform split-horizon with poisoned reverse
2304 * for RIP and connected routes.
2306 if (ri
->split_horizon
2307 == RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2309 * We perform split horizon for RIP and
2311 * For rip routes, we want to suppress the route
2313 * end up sending the route back on the
2315 * learned it from, with a higher metric. For
2317 * we suppress the route if the prefix is a
2319 * source address that we are going to use for
2321 * (in order to handle the case when multiple
2323 * configured on the same interface).
2325 struct rip_info
*tmp_rinfo
= NULL
;
2326 struct connected
*tmp_ifc
= NULL
;
2328 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2330 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2331 && tmp_rinfo
->nh
.ifindex
2332 == ifc
->ifp
->ifindex
)
2334 RIP_METRIC_INFINITY
;
2336 if (rinfo
->metric_out
!= RIP_METRIC_INFINITY
2337 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2338 for (ALL_LIST_ELEMENTS_RO(
2339 ifc
->ifp
->connected
,
2343 tmp_ifc
->address
)) {
2345 RIP_METRIC_INFINITY
;
2351 /* Prepare preamble, auth headers, if needs be */
2353 stream_putc(s
, RIP_RESPONSE
);
2354 stream_putc(s
, version
);
2357 /* auth header for !v1 && !no_auth */
2358 if ((ri
->auth_type
!= RIP_NO_AUTH
)
2359 && (version
!= RIPv1
))
2360 doff
= rip_auth_header_write(
2361 s
, ri
, key
, auth_str
,
2362 RIP_AUTH_SIMPLE_SIZE
);
2365 /* Write RTE to the stream. */
2366 num
= rip_write_rte(num
, s
, p
, version
, rinfo
);
2367 if (num
== rtemax
) {
2368 if (version
== RIPv2
2369 && ri
->auth_type
== RIP_AUTH_MD5
)
2370 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2371 RIP_AUTH_SIMPLE_SIZE
);
2373 ret
= rip_send_packet(STREAM_DATA(s
),
2374 stream_get_endp(s
), to
,
2377 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2378 rip_packet_dump((struct rip_packet
*)
2387 /* Flush unwritten RTE. */
2389 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2390 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2391 RIP_AUTH_SIMPLE_SIZE
);
2393 ret
= rip_send_packet(STREAM_DATA(s
), stream_get_endp(s
), to
,
2396 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2397 rip_packet_dump((struct rip_packet
*)STREAM_DATA(s
),
2398 stream_get_endp(s
), "SEND");
2402 /* Statistics updates. */
2406 /* Send RIP packet to the interface. */
2407 static void rip_update_interface(struct connected
*ifc
, uint8_t version
,
2410 struct interface
*ifp
= ifc
->ifp
;
2411 struct rip_interface
*ri
= ifp
->info
;
2412 struct sockaddr_in to
;
2414 /* When RIP version is 2 and multicast enable interface. */
2415 if (version
== RIPv2
&& !ri
->v2_broadcast
&& if_is_multicast(ifp
)) {
2416 if (IS_RIP_DEBUG_EVENT
)
2417 zlog_debug("multicast announce on %s ", ifp
->name
);
2419 rip_output_process(ifc
, NULL
, route_type
, version
);
2423 /* If we can't send multicast packet, send it with unicast. */
2424 if (if_is_broadcast(ifp
) || if_is_pointopoint(ifp
)) {
2425 if (ifc
->address
->family
== AF_INET
) {
2426 /* Destination address and port setting. */
2427 memset(&to
, 0, sizeof(struct sockaddr_in
));
2428 if (ifc
->destination
)
2429 /* use specified broadcast or peer destination
2431 to
.sin_addr
= ifc
->destination
->u
.prefix4
;
2432 else if (ifc
->address
->prefixlen
< IPV4_MAX_PREFIXLEN
)
2433 /* calculate the appropriate broadcast address
2435 to
.sin_addr
.s_addr
= ipv4_broadcast_addr(
2436 ifc
->address
->u
.prefix4
.s_addr
,
2437 ifc
->address
->prefixlen
);
2439 /* do not know where to send the packet */
2441 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2443 if (IS_RIP_DEBUG_EVENT
)
2444 zlog_debug("%s announce to %pI4 on %s",
2445 CONNECTED_PEER(ifc
) ? "unicast"
2447 &to
.sin_addr
, ifp
->name
);
2449 rip_output_process(ifc
, &to
, route_type
, version
);
2454 /* Update send to all interface and neighbor. */
2455 static void rip_update_process(struct rip
*rip
, int route_type
)
2457 struct listnode
*ifnode
, *ifnnode
;
2458 struct connected
*connected
;
2459 struct interface
*ifp
;
2460 struct rip_interface
*ri
;
2461 struct route_node
*rp
;
2462 struct sockaddr_in to
;
2465 /* Send RIP update to each interface. */
2466 FOR_ALL_INTERFACES (rip
->vrf
, ifp
) {
2467 if (if_is_loopback(ifp
))
2470 if (!if_is_operative(ifp
))
2473 /* Fetch RIP interface information. */
2476 /* When passive interface is specified, suppress announce to the
2483 * If there is no version configuration in the
2485 * use rip's version setting.
2487 int vsend
= ((ri
->ri_send
== RI_RIP_UNSPEC
)
2491 if (IS_RIP_DEBUG_EVENT
)
2492 zlog_debug("SEND UPDATE to %s ifindex %d",
2493 ifp
->name
, ifp
->ifindex
);
2495 /* send update on each connected network */
2496 for (ALL_LIST_ELEMENTS(ifp
->connected
, ifnode
, ifnnode
,
2498 if (connected
->address
->family
== AF_INET
) {
2500 rip_update_interface(
2504 && if_is_multicast(ifp
))
2505 rip_update_interface(
2513 /* RIP send updates to each neighbor. */
2514 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
2515 if (rp
->info
!= NULL
) {
2518 connected
= if_lookup_address(&p
->u
.prefix4
, AF_INET
,
2522 "Neighbor %pI4 doesn't have connected interface!",
2527 /* Set destination address and port */
2528 memset(&to
, 0, sizeof(struct sockaddr_in
));
2529 to
.sin_addr
= p
->u
.prefix4
;
2530 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2532 /* RIP version is rip's configuration. */
2533 rip_output_process(connected
, &to
, route_type
,
2538 /* RIP's periodical timer. */
2539 static int rip_update(struct thread
*t
)
2541 struct rip
*rip
= THREAD_ARG(t
);
2543 /* Clear timer pointer. */
2544 rip
->t_update
= NULL
;
2546 if (IS_RIP_DEBUG_EVENT
)
2547 zlog_debug("update timer fire!");
2549 /* Process update output. */
2550 rip_update_process(rip
, rip_all_route
);
2552 /* Triggered updates may be suppressed if a regular update is due by
2553 the time the triggered update would be sent. */
2554 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2557 /* Register myself. */
2558 rip_event(rip
, RIP_UPDATE_EVENT
, 0);
2563 /* Walk down the RIP routing table then clear changed flag. */
2564 static void rip_clear_changed_flag(struct rip
*rip
)
2566 struct route_node
*rp
;
2567 struct rip_info
*rinfo
= NULL
;
2568 struct list
*list
= NULL
;
2569 struct listnode
*listnode
= NULL
;
2571 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2572 if ((list
= rp
->info
) != NULL
)
2573 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
2574 UNSET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2575 /* This flag can be set only on the first entry.
2581 /* Triggered update interval timer. */
2582 static int rip_triggered_interval(struct thread
*t
)
2584 struct rip
*rip
= THREAD_ARG(t
);
2586 rip
->t_triggered_interval
= NULL
;
2590 rip_triggered_update(t
);
2595 /* Execute triggered update. */
2596 static int rip_triggered_update(struct thread
*t
)
2598 struct rip
*rip
= THREAD_ARG(t
);
2601 /* Clear thred pointer. */
2602 rip
->t_triggered_update
= NULL
;
2604 /* Cancel interval timer. */
2605 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2608 /* Logging triggered update. */
2609 if (IS_RIP_DEBUG_EVENT
)
2610 zlog_debug("triggered update!");
2612 /* Split Horizon processing is done when generating triggered
2613 updates as well as normal updates (see section 2.6). */
2614 rip_update_process(rip
, rip_changed_route
);
2616 /* Once all of the triggered updates have been generated, the route
2617 change flags should be cleared. */
2618 rip_clear_changed_flag(rip
);
2620 /* After a triggered update is sent, a timer should be set for a
2621 random interval between 1 and 5 seconds. If other changes that
2622 would trigger updates occur before the timer expires, a single
2623 update is triggered when the timer expires. */
2624 interval
= (frr_weak_random() % 5) + 1;
2626 rip
->t_triggered_interval
= NULL
;
2627 thread_add_timer(master
, rip_triggered_interval
, rip
, interval
,
2628 &rip
->t_triggered_interval
);
2633 /* Withdraw redistributed route. */
2634 void rip_redistribute_withdraw(struct rip
*rip
, int type
)
2636 struct route_node
*rp
;
2637 struct rip_info
*rinfo
= NULL
;
2638 struct list
*list
= NULL
;
2640 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2641 if ((list
= rp
->info
) != NULL
) {
2642 rinfo
= listgetdata(listhead(list
));
2643 if (rinfo
->type
== type
2644 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2645 /* Perform poisoned reverse. */
2646 rinfo
->metric
= RIP_METRIC_INFINITY
;
2647 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
2648 rip_garbage_collect
,
2650 RIP_TIMER_OFF(rinfo
->t_timeout
);
2651 rinfo
->flags
|= RIP_RTF_CHANGED
;
2653 if (IS_RIP_DEBUG_EVENT
) {
2654 struct prefix_ipv4
*p
=
2655 (struct prefix_ipv4
*)&rp
->p
;
2658 "Poisone %pFX on the interface %s with an infinity metric [withdraw]",
2665 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
2670 struct rip
*rip_lookup_by_vrf_id(vrf_id_t vrf_id
)
2674 vrf
= vrf_lookup_by_id(vrf_id
);
2681 struct rip
*rip_lookup_by_vrf_name(const char *vrf_name
)
2685 rip
.vrf_name
= (char *)vrf_name
;
2687 return RB_FIND(rip_instance_head
, &rip_instances
, &rip
);
2690 /* Create new RIP instance and set it to global variable. */
2691 struct rip
*rip_create(const char *vrf_name
, struct vrf
*vrf
, int socket
)
2695 rip
= XCALLOC(MTYPE_RIP
, sizeof(struct rip
));
2696 rip
->vrf_name
= XSTRDUP(MTYPE_RIP_VRF_NAME
, vrf_name
);
2698 /* Set initial value. */
2699 rip
->ecmp
= yang_get_default_bool("%s/allow-ecmp", RIP_INSTANCE
);
2700 rip
->default_metric
=
2701 yang_get_default_uint8("%s/default-metric", RIP_INSTANCE
);
2703 yang_get_default_uint8("%s/distance/default", RIP_INSTANCE
);
2704 rip
->passive_default
=
2705 yang_get_default_bool("%s/passive-default", RIP_INSTANCE
);
2706 rip
->garbage_time
= yang_get_default_uint32("%s/timers/flush-interval",
2708 rip
->timeout_time
= yang_get_default_uint32(
2709 "%s/timers/holddown-interval", RIP_INSTANCE
);
2710 rip
->update_time
= yang_get_default_uint32("%s/timers/update-interval",
2713 yang_get_default_enum("%s/version/send", RIP_INSTANCE
);
2715 yang_get_default_enum("%s/version/receive", RIP_INSTANCE
);
2717 /* Initialize RIP data structures. */
2718 rip
->table
= route_table_init();
2719 route_table_set_info(rip
->table
, rip
);
2720 rip
->neighbor
= route_table_init();
2721 rip
->peer_list
= list_new();
2722 rip
->peer_list
->cmp
= (int (*)(void *, void *))rip_peer_list_cmp
;
2723 rip
->peer_list
->del
= rip_peer_list_del
;
2724 rip
->distance_table
= route_table_init();
2725 rip
->distance_table
->cleanup
= rip_distance_table_node_cleanup
;
2726 rip
->enable_interface
= vector_init(1);
2727 rip
->enable_network
= route_table_init();
2728 rip
->passive_nondefault
= vector_init(1);
2729 rip
->offset_list_master
= list_new();
2730 rip
->offset_list_master
->cmp
= (int (*)(void *, void *))offset_list_cmp
;
2731 rip
->offset_list_master
->del
= (void (*)(void *))offset_list_free
;
2733 /* Distribute list install. */
2734 rip
->distribute_ctx
= distribute_list_ctx_create(vrf
);
2735 distribute_list_add_hook(rip
->distribute_ctx
, rip_distribute_update
);
2736 distribute_list_delete_hook(rip
->distribute_ctx
, rip_distribute_update
);
2738 /* if rmap install. */
2739 rip
->if_rmap_ctx
= if_rmap_ctx_create(vrf_name
);
2740 if_rmap_hook_add(rip
->if_rmap_ctx
, rip_if_rmap_update
);
2741 if_rmap_hook_delete(rip
->if_rmap_ctx
, rip_if_rmap_update
);
2743 /* Make output stream. */
2744 rip
->obuf
= stream_new(1500);
2746 /* Enable the routing instance if possible. */
2747 if (vrf
&& vrf_is_enabled(vrf
))
2748 rip_instance_enable(rip
, vrf
, socket
);
2754 RB_INSERT(rip_instance_head
, &rip_instances
, rip
);
2759 /* Sned RIP request to the destination. */
2760 int rip_request_send(struct sockaddr_in
*to
, struct interface
*ifp
,
2761 uint8_t version
, struct connected
*connected
)
2764 struct rip_packet rip_packet
;
2765 struct listnode
*node
, *nnode
;
2767 memset(&rip_packet
, 0, sizeof(rip_packet
));
2769 rip_packet
.command
= RIP_REQUEST
;
2770 rip_packet
.version
= version
;
2771 rte
= rip_packet
.rte
;
2772 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
2776 * connected is only sent for ripv1 case, or when
2777 * interface does not support multicast. Caller loops
2778 * over each connected address for this case.
2780 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2782 != sizeof(rip_packet
))
2785 return sizeof(rip_packet
);
2788 /* send request on each connected network */
2789 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, connected
)) {
2790 struct prefix_ipv4
*p
;
2792 p
= (struct prefix_ipv4
*)connected
->address
;
2794 if (p
->family
!= AF_INET
)
2797 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2799 != sizeof(rip_packet
))
2802 return sizeof(rip_packet
);
2805 static int rip_update_jitter(unsigned long time
)
2807 #define JITTER_BOUND 4
2808 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2809 Given that, we cannot let time be less than JITTER_BOUND seconds.
2810 The RIPv2 RFC says jitter should be small compared to
2811 update_time. We consider 1/JITTER_BOUND to be small.
2814 int jitter_input
= time
;
2817 if (jitter_input
< JITTER_BOUND
)
2818 jitter_input
= JITTER_BOUND
;
2820 jitter
= (((frr_weak_random() % ((jitter_input
* 2) + 1))
2823 return jitter
/ JITTER_BOUND
;
2826 void rip_event(struct rip
*rip
, enum rip_event event
, int sock
)
2833 thread_add_read(master
, rip_read
, rip
, sock
, &rip
->t_read
);
2835 case RIP_UPDATE_EVENT
:
2836 RIP_TIMER_OFF(rip
->t_update
);
2837 jitter
= rip_update_jitter(rip
->update_time
);
2838 thread_add_timer(master
, rip_update
, rip
,
2839 sock
? 2 : rip
->update_time
+ jitter
,
2842 case RIP_TRIGGERED_UPDATE
:
2843 if (rip
->t_triggered_interval
)
2846 thread_add_event(master
, rip_triggered_update
, rip
, 0,
2847 &rip
->t_triggered_update
);
2854 struct rip_distance
*rip_distance_new(void)
2856 return XCALLOC(MTYPE_RIP_DISTANCE
, sizeof(struct rip_distance
));
2859 void rip_distance_free(struct rip_distance
*rdistance
)
2861 if (rdistance
->access_list
)
2862 free(rdistance
->access_list
);
2863 XFREE(MTYPE_RIP_DISTANCE
, rdistance
);
2866 static void rip_distance_table_node_cleanup(struct route_table
*table
,
2867 struct route_node
*node
)
2869 struct rip_distance
*rdistance
;
2871 rdistance
= node
->info
;
2873 rip_distance_free(rdistance
);
2876 /* Apply RIP information to distance method. */
2877 uint8_t rip_distance_apply(struct rip
*rip
, struct rip_info
*rinfo
)
2879 struct route_node
*rn
;
2880 struct prefix_ipv4 p
;
2881 struct rip_distance
*rdistance
;
2882 struct access_list
*alist
;
2884 memset(&p
, 0, sizeof(struct prefix_ipv4
));
2886 p
.prefix
= rinfo
->from
;
2887 p
.prefixlen
= IPV4_MAX_BITLEN
;
2889 /* Check source address. */
2890 rn
= route_node_match(rip
->distance_table
, (struct prefix
*)&p
);
2892 rdistance
= rn
->info
;
2893 route_unlock_node(rn
);
2895 if (rdistance
->access_list
) {
2896 alist
= access_list_lookup(AFI_IP
,
2897 rdistance
->access_list
);
2900 if (access_list_apply(alist
, &rinfo
->rp
->p
)
2904 return rdistance
->distance
;
2906 return rdistance
->distance
;
2910 return rip
->distance
;
2915 static void rip_distance_show(struct vty
*vty
, struct rip
*rip
)
2917 struct route_node
*rn
;
2918 struct rip_distance
*rdistance
;
2922 vty_out(vty
, " Distance: (default is %u)\n",
2923 rip
->distance
? rip
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
);
2925 for (rn
= route_top(rip
->distance_table
); rn
; rn
= route_next(rn
))
2926 if ((rdistance
= rn
->info
) != NULL
) {
2929 " Address Distance List\n");
2932 snprintfrr(buf
, sizeof(buf
), "%pFX", &rn
->p
);
2933 vty_out(vty
, " %-20s %4d %s\n", buf
,
2934 rdistance
->distance
,
2935 rdistance
->access_list
? rdistance
->access_list
2940 /* Update ECMP routes to zebra when ECMP is disabled. */
2941 void rip_ecmp_disable(struct rip
*rip
)
2943 struct route_node
*rp
;
2944 struct rip_info
*rinfo
, *tmp_rinfo
;
2946 struct listnode
*node
, *nextnode
;
2948 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2949 if ((list
= rp
->info
) != NULL
&& listcount(list
) > 1) {
2950 rinfo
= listgetdata(listhead(list
));
2951 if (!rip_route_rte(rinfo
))
2954 /* Drop all other entries, except the first one. */
2955 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
2956 if (tmp_rinfo
!= rinfo
) {
2957 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
2959 tmp_rinfo
->t_garbage_collect
);
2960 list_delete_node(list
, node
);
2961 rip_info_free(tmp_rinfo
);
2965 rip_zebra_ipv4_add(rip
, rp
);
2967 /* Set the route change flag. */
2968 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2970 /* Signal the output process to trigger an update. */
2971 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
2975 /* Print out routes update time. */
2976 static void rip_vty_out_uptime(struct vty
*vty
, struct rip_info
*rinfo
)
2981 char timebuf
[TIME_BUF
];
2982 struct thread
*thread
;
2984 if ((thread
= rinfo
->t_timeout
) != NULL
) {
2985 clock
= thread_timer_remain_second(thread
);
2986 gmtime_r(&clock
, &tm
);
2987 strftime(timebuf
, TIME_BUF
, "%M:%S", &tm
);
2988 vty_out(vty
, "%5s", timebuf
);
2989 } else if ((thread
= rinfo
->t_garbage_collect
) != NULL
) {
2990 clock
= thread_timer_remain_second(thread
);
2991 gmtime_r(&clock
, &tm
);
2992 strftime(timebuf
, TIME_BUF
, "%M:%S", &tm
);
2993 vty_out(vty
, "%5s", timebuf
);
2997 static const char *rip_route_type_print(int sub_type
)
3002 case RIP_ROUTE_STATIC
:
3004 case RIP_ROUTE_DEFAULT
:
3006 case RIP_ROUTE_REDISTRIBUTE
:
3008 case RIP_ROUTE_INTERFACE
:
3017 "show ip rip [vrf NAME]",
3024 struct route_node
*np
;
3025 struct rip_info
*rinfo
= NULL
;
3026 struct list
*list
= NULL
;
3027 struct listnode
*listnode
= NULL
;
3028 const char *vrf_name
;
3031 if (argv_find(argv
, argc
, "vrf", &idx
))
3032 vrf_name
= argv
[idx
+ 1]->arg
;
3034 vrf_name
= VRF_DEFAULT_NAME
;
3036 rip
= rip_lookup_by_vrf_name(vrf_name
);
3038 vty_out(vty
, "%% RIP instance not found\n");
3041 if (!rip
->enabled
) {
3042 vty_out(vty
, "%% RIP instance is disabled\n");
3047 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
3049 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
3050 " (i) - interface\n\n"
3051 " Network Next Hop Metric From Tag Time\n");
3053 for (np
= route_top(rip
->table
); np
; np
= route_next(np
))
3054 if ((list
= np
->info
) != NULL
)
3055 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3060 /* np->lock, For debugging. */
3061 zebra_route_char(rinfo
->type
),
3062 rip_route_type_print(rinfo
->sub_type
),
3068 vty_out(vty
, "%*s", len
, " ");
3070 switch (rinfo
->nh
.type
) {
3071 case NEXTHOP_TYPE_IPV4
:
3072 case NEXTHOP_TYPE_IPV4_IFINDEX
:
3073 vty_out(vty
, "%-20pI4 %2d ",
3074 &rinfo
->nh
.gate
.ipv4
,
3077 case NEXTHOP_TYPE_IFINDEX
:
3082 case NEXTHOP_TYPE_BLACKHOLE
:
3087 case NEXTHOP_TYPE_IPV6
:
3088 case NEXTHOP_TYPE_IPV6_IFINDEX
:
3090 "V6 Address Hidden %2d ",
3095 /* Route which exist in kernel routing table. */
3096 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
)
3097 && (rinfo
->sub_type
== RIP_ROUTE_RTE
)) {
3098 vty_out(vty
, "%-15pI4 ",
3100 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3101 (route_tag_t
)rinfo
->tag
);
3102 rip_vty_out_uptime(vty
, rinfo
);
3103 } else if (rinfo
->metric
3104 == RIP_METRIC_INFINITY
) {
3105 vty_out(vty
, "self ");
3106 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3107 (route_tag_t
)rinfo
->tag
);
3108 rip_vty_out_uptime(vty
, rinfo
);
3110 if (rinfo
->external_metric
) {
3112 vty
, "self (%s:%d)",
3115 rinfo
->external_metric
);
3118 vty_out(vty
, "%*s", len
,
3123 vty_out(vty
, "%3" ROUTE_TAG_PRI
,
3124 (route_tag_t
)rinfo
->tag
);
3132 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3133 DEFUN (show_ip_rip_status
,
3134 show_ip_rip_status_cmd
,
3135 "show ip rip [vrf NAME] status",
3140 "IP routing protocol process parameters and statistics\n")
3143 struct interface
*ifp
;
3144 struct rip_interface
*ri
;
3145 extern const struct message ri_version_msg
[];
3146 const char *send_version
;
3147 const char *receive_version
;
3148 const char *vrf_name
;
3151 if (argv_find(argv
, argc
, "vrf", &idx
))
3152 vrf_name
= argv
[idx
+ 1]->arg
;
3154 vrf_name
= VRF_DEFAULT_NAME
;
3156 rip
= rip_lookup_by_vrf_name(vrf_name
);
3158 vty_out(vty
, "%% RIP instance not found\n");
3161 if (!rip
->enabled
) {
3162 vty_out(vty
, "%% RIP instance is disabled\n");
3166 vty_out(vty
, "Routing Protocol is \"rip\"\n");
3167 vty_out(vty
, " Sending updates every %u seconds with +/-50%%,",
3169 vty_out(vty
, " next due in %lu seconds\n",
3170 thread_timer_remain_second(rip
->t_update
));
3171 vty_out(vty
, " Timeout after %u seconds,", rip
->timeout_time
);
3172 vty_out(vty
, " garbage collect after %u seconds\n", rip
->garbage_time
);
3174 /* Filtering status show. */
3175 config_show_distribute(vty
, rip
->distribute_ctx
);
3177 /* Default metric information. */
3178 vty_out(vty
, " Default redistribution metric is %u\n",
3179 rip
->default_metric
);
3181 /* Redistribute information. */
3182 vty_out(vty
, " Redistributing:");
3183 rip_show_redistribute_config(vty
, rip
);
3186 vty_out(vty
, " Default version control: send version %s,",
3187 lookup_msg(ri_version_msg
, rip
->version_send
, NULL
));
3188 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3189 vty_out(vty
, " receive any version \n");
3191 vty_out(vty
, " receive version %s \n",
3192 lookup_msg(ri_version_msg
, rip
->version_recv
, NULL
));
3194 vty_out(vty
, " Interface Send Recv Key-chain\n");
3196 FOR_ALL_INTERFACES (rip
->vrf
, ifp
) {
3202 if (ri
->enable_network
|| ri
->enable_interface
) {
3203 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3205 lookup_msg(ri_version_msg
,
3206 rip
->version_send
, NULL
);
3208 send_version
= lookup_msg(ri_version_msg
,
3211 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3213 lookup_msg(ri_version_msg
,
3214 rip
->version_recv
, NULL
);
3216 receive_version
= lookup_msg(
3217 ri_version_msg
, ri
->ri_receive
, NULL
);
3219 vty_out(vty
, " %-17s%-3s %-3s %s\n", ifp
->name
,
3220 send_version
, receive_version
,
3221 ri
->key_chain
? ri
->key_chain
: "");
3225 vty_out(vty
, " Routing for Networks:\n");
3226 rip_show_network_config(vty
, rip
);
3229 int found_passive
= 0;
3230 FOR_ALL_INTERFACES (rip
->vrf
, ifp
) {
3233 if ((ri
->enable_network
|| ri
->enable_interface
)
3235 if (!found_passive
) {
3237 " Passive Interface(s):\n");
3240 vty_out(vty
, " %s\n", ifp
->name
);
3245 vty_out(vty
, " Routing Information Sources:\n");
3247 " Gateway BadPackets BadRoutes Distance Last Update\n");
3248 rip_peer_display(vty
, rip
);
3250 rip_distance_show(vty
, rip
);
3255 /* RIP configuration write function. */
3256 static int config_write_rip(struct vty
*vty
)
3261 RB_FOREACH(rip
, rip_instance_head
, &rip_instances
) {
3262 char xpath
[XPATH_MAXLEN
];
3263 struct lyd_node
*dnode
;
3265 snprintf(xpath
, sizeof(xpath
),
3266 "/frr-ripd:ripd/instance[vrf='%s']", rip
->vrf_name
);
3268 dnode
= yang_dnode_get(running_config
->dnode
, xpath
);
3271 nb_cli_show_dnode_cmds(vty
, dnode
, false);
3273 /* Distribute configuration. */
3274 config_write_distribute(vty
, rip
->distribute_ctx
);
3276 /* Interface routemap configuration */
3277 config_write_if_rmap(vty
, rip
->if_rmap_ctx
);
3285 static int config_write_rip(struct vty
*vty
);
3286 /* RIP node structure. */
3287 static struct cmd_node rip_node
= {
3290 .parent_node
= CONFIG_NODE
,
3291 .prompt
= "%s(config-router)# ",
3292 .config_write
= config_write_rip
,
3295 /* Distribute-list update functions. */
3296 static void rip_distribute_update(struct distribute_ctx
*ctx
,
3297 struct distribute
*dist
)
3299 struct interface
*ifp
;
3300 struct rip_interface
*ri
;
3301 struct access_list
*alist
;
3302 struct prefix_list
*plist
;
3304 if (!ctx
->vrf
|| !dist
->ifname
)
3307 ifp
= if_lookup_by_name(dist
->ifname
, ctx
->vrf
->vrf_id
);
3313 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
3314 alist
= access_list_lookup(AFI_IP
,
3315 dist
->list
[DISTRIBUTE_V4_IN
]);
3317 ri
->list
[RIP_FILTER_IN
] = alist
;
3319 ri
->list
[RIP_FILTER_IN
] = NULL
;
3321 ri
->list
[RIP_FILTER_IN
] = NULL
;
3323 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
3324 alist
= access_list_lookup(AFI_IP
,
3325 dist
->list
[DISTRIBUTE_V4_OUT
]);
3327 ri
->list
[RIP_FILTER_OUT
] = alist
;
3329 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3331 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3333 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
3334 plist
= prefix_list_lookup(AFI_IP
,
3335 dist
->prefix
[DISTRIBUTE_V4_IN
]);
3337 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3339 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3341 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3343 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
3344 plist
= prefix_list_lookup(AFI_IP
,
3345 dist
->prefix
[DISTRIBUTE_V4_OUT
]);
3347 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3349 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3351 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3354 void rip_distribute_update_interface(struct interface
*ifp
)
3356 struct rip_interface
*ri
= ifp
->info
;
3357 struct rip
*rip
= ri
->rip
;
3358 struct distribute
*dist
;
3362 dist
= distribute_lookup(rip
->distribute_ctx
, ifp
->name
);
3364 rip_distribute_update(rip
->distribute_ctx
, dist
);
3367 /* Update all interface's distribute list. */
3369 static void rip_distribute_update_all(struct prefix_list
*notused
)
3371 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3372 struct interface
*ifp
;
3374 FOR_ALL_INTERFACES (vrf
, ifp
)
3375 rip_distribute_update_interface(ifp
);
3378 static void rip_distribute_update_all_wrapper(struct access_list
*notused
)
3380 rip_distribute_update_all(NULL
);
3383 /* Delete all added rip route. */
3384 void rip_clean(struct rip
*rip
)
3386 rip_interfaces_clean(rip
);
3389 rip_instance_disable(rip
);
3391 stream_free(rip
->obuf
);
3393 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3394 if (rip
->redist
[i
].route_map
.name
)
3395 free(rip
->redist
[i
].route_map
.name
);
3397 route_table_finish(rip
->table
);
3398 route_table_finish(rip
->neighbor
);
3399 list_delete(&rip
->peer_list
);
3400 distribute_list_delete(&rip
->distribute_ctx
);
3401 if_rmap_ctx_delete(rip
->if_rmap_ctx
);
3403 rip_clean_network(rip
);
3404 rip_passive_nondefault_clean(rip
);
3405 vector_free(rip
->enable_interface
);
3406 route_table_finish(rip
->enable_network
);
3407 vector_free(rip
->passive_nondefault
);
3408 list_delete(&rip
->offset_list_master
);
3409 route_table_finish(rip
->distance_table
);
3411 RB_REMOVE(rip_instance_head
, &rip_instances
, rip
);
3412 XFREE(MTYPE_RIP_VRF_NAME
, rip
->vrf_name
);
3413 XFREE(MTYPE_RIP
, rip
);
3416 static void rip_if_rmap_update(struct if_rmap_ctx
*ctx
,
3417 struct if_rmap
*if_rmap
)
3419 struct interface
*ifp
= NULL
;
3420 struct rip_interface
*ri
;
3421 struct route_map
*rmap
;
3422 struct vrf
*vrf
= NULL
;
3425 vrf
= vrf_lookup_by_name(ctx
->name
);
3427 ifp
= if_lookup_by_name(if_rmap
->ifname
, vrf
->vrf_id
);
3432 if (if_rmap
->routemap
[IF_RMAP_IN
]) {
3433 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_IN
]);
3435 ri
->routemap
[IF_RMAP_IN
] = rmap
;
3437 ri
->routemap
[IF_RMAP_IN
] = NULL
;
3439 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
3441 if (if_rmap
->routemap
[IF_RMAP_OUT
]) {
3442 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_OUT
]);
3444 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
3446 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
3448 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
3451 void rip_if_rmap_update_interface(struct interface
*ifp
)
3453 struct rip_interface
*ri
= ifp
->info
;
3454 struct rip
*rip
= ri
->rip
;
3455 struct if_rmap
*if_rmap
;
3456 struct if_rmap_ctx
*ctx
;
3460 ctx
= rip
->if_rmap_ctx
;
3463 if_rmap
= if_rmap_lookup(ctx
, ifp
->name
);
3465 rip_if_rmap_update(ctx
, if_rmap
);
3468 static void rip_routemap_update_redistribute(struct rip
*rip
)
3470 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3471 if (rip
->redist
[i
].route_map
.name
) {
3472 rip
->redist
[i
].route_map
.map
= route_map_lookup_by_name(
3473 rip
->redist
[i
].route_map
.name
);
3474 route_map_counter_increment(
3475 rip
->redist
[i
].route_map
.map
);
3481 static void rip_routemap_update(const char *notused
)
3483 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3485 struct interface
*ifp
;
3487 FOR_ALL_INTERFACES (vrf
, ifp
)
3488 rip_if_rmap_update_interface(ifp
);
3492 rip_routemap_update_redistribute(rip
);
3495 /* Link RIP instance to VRF. */
3496 static void rip_vrf_link(struct rip
*rip
, struct vrf
*vrf
)
3498 struct interface
*ifp
;
3501 rip
->distribute_ctx
->vrf
= vrf
;
3504 FOR_ALL_INTERFACES (vrf
, ifp
)
3505 rip_interface_sync(ifp
);
3508 /* Unlink RIP instance from VRF. */
3509 static void rip_vrf_unlink(struct rip
*rip
, struct vrf
*vrf
)
3511 struct interface
*ifp
;
3514 rip
->distribute_ctx
->vrf
= NULL
;
3517 FOR_ALL_INTERFACES (vrf
, ifp
)
3518 rip_interface_sync(ifp
);
3521 static void rip_instance_enable(struct rip
*rip
, struct vrf
*vrf
, int sock
)
3525 rip_vrf_link(rip
, vrf
);
3526 rip
->enabled
= true;
3528 /* Resend all redistribute requests. */
3529 rip_redistribute_enable(rip
);
3531 /* Create read and timer thread. */
3532 rip_event(rip
, RIP_READ
, rip
->sock
);
3533 rip_event(rip
, RIP_UPDATE_EVENT
, 1);
3535 rip_zebra_vrf_register(vrf
);
3538 static void rip_instance_disable(struct rip
*rip
)
3540 struct vrf
*vrf
= rip
->vrf
;
3541 struct route_node
*rp
;
3543 /* Clear RIP routes */
3544 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
)) {
3545 struct rip_info
*rinfo
;
3547 struct listnode
*listnode
;
3549 if ((list
= rp
->info
) == NULL
)
3552 rinfo
= listgetdata(listhead(list
));
3553 if (rip_route_rte(rinfo
))
3554 rip_zebra_ipv4_delete(rip
, rp
);
3556 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3557 RIP_TIMER_OFF(rinfo
->t_timeout
);
3558 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
3559 rip_info_free(rinfo
);
3563 route_unlock_node(rp
);
3566 /* Flush all redistribute requests. */
3567 rip_redistribute_disable(rip
);
3569 /* Cancel RIP related timers. */
3570 RIP_TIMER_OFF(rip
->t_update
);
3571 RIP_TIMER_OFF(rip
->t_triggered_update
);
3572 RIP_TIMER_OFF(rip
->t_triggered_interval
);
3574 /* Cancel read thread. */
3575 thread_cancel(&rip
->t_read
);
3577 /* Close RIP socket. */
3581 /* Clear existing peers. */
3582 list_delete_all_node(rip
->peer_list
);
3584 rip_zebra_vrf_deregister(vrf
);
3586 rip_vrf_unlink(rip
, vrf
);
3587 rip
->enabled
= false;
3590 static int rip_vrf_new(struct vrf
*vrf
)
3592 if (IS_RIP_DEBUG_EVENT
)
3593 zlog_debug("%s: VRF created: %s(%u)", __func__
, vrf
->name
,
3599 static int rip_vrf_delete(struct vrf
*vrf
)
3601 if (IS_RIP_DEBUG_EVENT
)
3602 zlog_debug("%s: VRF deleted: %s(%u)", __func__
, vrf
->name
,
3608 static int rip_vrf_enable(struct vrf
*vrf
)
3613 rip
= rip_lookup_by_vrf_name(vrf
->name
);
3615 char *old_vrf_name
= NULL
;
3617 rip
= (struct rip
*)vrf
->info
;
3620 /* update vrf name */
3622 old_vrf_name
= rip
->vrf_name
;
3623 rip
->vrf_name
= XSTRDUP(MTYPE_RIP_VRF_NAME
, vrf
->name
);
3625 * HACK: Change the RIP VRF in the running configuration directly,
3626 * bypassing the northbound layer. This is necessary to avoid deleting
3627 * the RIP and readding it in the new VRF, which would have
3628 * several implications.
3630 if (yang_module_find("frr-ripd") && old_vrf_name
) {
3631 struct lyd_node
*rip_dnode
;
3632 char oldpath
[XPATH_MAXLEN
];
3633 char newpath
[XPATH_MAXLEN
];
3635 rip_dnode
= yang_dnode_get(
3636 running_config
->dnode
,
3637 "/frr-ripd:ripd/instance[vrf='%s']/vrf",
3640 yang_dnode_get_path(rip_dnode
->parent
, oldpath
,
3642 yang_dnode_change_leaf(rip_dnode
, vrf
->name
);
3643 yang_dnode_get_path(rip_dnode
->parent
, newpath
,
3645 nb_running_move_tree(oldpath
, newpath
);
3646 running_config
->version
++;
3649 XFREE(MTYPE_RIP_VRF_NAME
, old_vrf_name
);
3651 if (!rip
|| rip
->enabled
)
3654 if (IS_RIP_DEBUG_EVENT
)
3655 zlog_debug("%s: VRF %s(%u) enabled", __func__
, vrf
->name
,
3658 /* Activate the VRF RIP instance. */
3659 if (!rip
->enabled
) {
3660 socket
= rip_create_socket(vrf
);
3664 rip_instance_enable(rip
, vrf
, socket
);
3670 static int rip_vrf_disable(struct vrf
*vrf
)
3674 rip
= rip_lookup_by_vrf_name(vrf
->name
);
3675 if (!rip
|| !rip
->enabled
)
3678 if (IS_RIP_DEBUG_EVENT
)
3679 zlog_debug("%s: VRF %s(%u) disabled", __func__
, vrf
->name
,
3682 /* Deactivate the VRF RIP instance. */
3684 rip_instance_disable(rip
);
3689 void rip_vrf_init(void)
3691 vrf_init(rip_vrf_new
, rip_vrf_enable
, rip_vrf_disable
, rip_vrf_delete
,
3695 void rip_vrf_terminate(void)
3700 /* Allocate new rip structure and set default value. */
3703 /* Install top nodes. */
3704 install_node(&rip_node
);
3706 /* Install rip commands. */
3707 install_element(VIEW_NODE
, &show_ip_rip_cmd
);
3708 install_element(VIEW_NODE
, &show_ip_rip_status_cmd
);
3710 install_default(RIP_NODE
);
3712 /* Debug related init. */
3715 /* Access list install. */
3717 access_list_add_hook(rip_distribute_update_all_wrapper
);
3718 access_list_delete_hook(rip_distribute_update_all_wrapper
);
3720 /* Prefix list initialize.*/
3722 prefix_list_add_hook(rip_distribute_update_all
);
3723 prefix_list_delete_hook(rip_distribute_update_all
);
3726 rip_route_map_init();
3728 route_map_add_hook(rip_routemap_update
);
3729 route_map_delete_hook(rip_routemap_update
);
3731 if_rmap_init(RIP_NODE
);