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"
49 #include "ripd/rip_interface.h"
51 /* UDP receive buffer size */
52 #define RIP_UDP_RCV_BUF 41600
55 static void rip_output_process(struct connected
*, struct sockaddr_in
*, int,
57 static int rip_triggered_update(struct thread
*);
58 static int rip_update_jitter(unsigned long);
59 static void rip_distance_table_node_cleanup(struct route_table
*table
,
60 struct route_node
*node
);
61 static void rip_instance_enable(struct rip
*rip
, struct vrf
*vrf
, int sock
);
62 static void rip_instance_disable(struct rip
*rip
);
64 static void rip_distribute_update(struct distribute_ctx
*ctx
,
65 struct distribute
*dist
);
67 static void rip_if_rmap_update(struct if_rmap_ctx
*ctx
,
68 struct if_rmap
*if_rmap
);
70 /* RIP output routes type. */
71 enum { rip_all_route
, rip_changed_route
};
73 /* RIP command strings. */
74 static const struct message rip_msg
[] = {{RIP_REQUEST
, "REQUEST"},
75 {RIP_RESPONSE
, "RESPONSE"},
76 {RIP_TRACEON
, "TRACEON"},
77 {RIP_TRACEOFF
, "TRACEOFF"},
79 {RIP_POLL_ENTRY
, "POLL ENTRY"},
82 /* Generate rb-tree of RIP instances. */
83 static inline int rip_instance_compare(const struct rip
*a
, const struct rip
*b
)
85 return strcmp(a
->vrf_name
, b
->vrf_name
);
87 RB_GENERATE(rip_instance_head
, rip
, entry
, rip_instance_compare
)
89 struct rip_instance_head rip_instances
= RB_INITIALIZER(&rip_instances
);
91 /* Utility function to set boradcast option to the socket. */
92 static int sockopt_broadcast(int sock
)
97 ret
= setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, (char *)&on
,
100 zlog_warn("can't set sockopt SO_BROADCAST to socket %d", sock
);
106 int rip_route_rte(struct rip_info
*rinfo
)
108 return (rinfo
->type
== ZEBRA_ROUTE_RIP
109 && rinfo
->sub_type
== RIP_ROUTE_RTE
);
112 static struct rip_info
*rip_info_new(void)
114 return XCALLOC(MTYPE_RIP_INFO
, sizeof(struct rip_info
));
117 void rip_info_free(struct rip_info
*rinfo
)
119 XFREE(MTYPE_RIP_INFO
, rinfo
);
122 struct rip
*rip_info_get_instance(const struct rip_info
*rinfo
)
124 return route_table_get_info(rinfo
->rp
->table
);
127 /* RIP route garbage collect timer. */
128 static int rip_garbage_collect(struct thread
*t
)
130 struct rip_info
*rinfo
;
131 struct route_node
*rp
;
133 rinfo
= THREAD_ARG(t
);
134 rinfo
->t_garbage_collect
= NULL
;
136 /* Off timeout timer. */
137 RIP_TIMER_OFF(rinfo
->t_timeout
);
139 /* Get route_node pointer. */
142 /* Unlock route_node. */
143 listnode_delete(rp
->info
, rinfo
);
144 if (list_isempty((struct list
*)rp
->info
)) {
145 list_delete((struct list
**)&rp
->info
);
146 route_unlock_node(rp
);
149 /* Free RIP routing information. */
150 rip_info_free(rinfo
);
155 static void rip_timeout_update(struct rip
*rip
, struct rip_info
*rinfo
);
157 /* Add new route to the ECMP list.
158 * RETURN: the new entry added in the list, or NULL if it is not the first
159 * entry and ECMP is not allowed.
161 struct rip_info
*rip_ecmp_add(struct rip
*rip
, struct rip_info
*rinfo_new
)
163 struct route_node
*rp
= rinfo_new
->rp
;
164 struct rip_info
*rinfo
= NULL
;
165 struct list
*list
= NULL
;
167 if (rp
->info
== NULL
)
168 rp
->info
= list_new();
169 list
= (struct list
*)rp
->info
;
171 /* If ECMP is not allowed and some entry already exists in the list,
173 if (listcount(list
) && !rip
->ecmp
)
176 rinfo
= rip_info_new();
177 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
178 listnode_add(list
, rinfo
);
180 if (rip_route_rte(rinfo
)) {
181 rip_timeout_update(rip
, rinfo
);
182 rip_zebra_ipv4_add(rip
, rp
);
185 /* Set the route change flag on the first entry. */
186 rinfo
= listgetdata(listhead(list
));
187 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
189 /* Signal the output process to trigger an update (see section 2.5). */
190 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
195 /* Replace the ECMP list with the new route.
196 * RETURN: the new entry added in the list
198 struct rip_info
*rip_ecmp_replace(struct rip
*rip
, struct rip_info
*rinfo_new
)
200 struct route_node
*rp
= rinfo_new
->rp
;
201 struct list
*list
= (struct list
*)rp
->info
;
202 struct rip_info
*rinfo
= NULL
, *tmp_rinfo
= NULL
;
203 struct listnode
*node
= NULL
, *nextnode
= NULL
;
205 if (list
== NULL
|| listcount(list
) == 0)
206 return rip_ecmp_add(rip
, rinfo_new
);
208 /* Get the first entry */
209 rinfo
= listgetdata(listhead(list
));
211 /* Learnt route replaced by a local one. Delete it from zebra. */
212 if (rip_route_rte(rinfo
) && !rip_route_rte(rinfo_new
))
213 if (CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
214 rip_zebra_ipv4_delete(rip
, rp
);
216 /* Re-use the first entry, and delete the others. */
217 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
218 if (tmp_rinfo
!= rinfo
) {
219 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
220 RIP_TIMER_OFF(tmp_rinfo
->t_garbage_collect
);
221 list_delete_node(list
, node
);
222 rip_info_free(tmp_rinfo
);
225 RIP_TIMER_OFF(rinfo
->t_timeout
);
226 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
227 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
229 if (rip_route_rte(rinfo
)) {
230 rip_timeout_update(rip
, rinfo
);
231 /* The ADD message implies an update. */
232 rip_zebra_ipv4_add(rip
, rp
);
235 /* Set the route change flag. */
236 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
238 /* Signal the output process to trigger an update (see section 2.5). */
239 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
244 /* Delete one route from the ECMP list.
246 * null - the entry is freed, and other entries exist in the list
247 * the entry - the entry is the last one in the list; its metric is set
248 * to INFINITY, and the garbage collector is started for it
250 struct rip_info
*rip_ecmp_delete(struct rip
*rip
, struct rip_info
*rinfo
)
252 struct route_node
*rp
= rinfo
->rp
;
253 struct list
*list
= (struct list
*)rp
->info
;
255 RIP_TIMER_OFF(rinfo
->t_timeout
);
257 if (listcount(list
) > 1) {
258 /* Some other ECMP entries still exist. Just delete this entry.
260 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
261 listnode_delete(list
, rinfo
);
262 if (rip_route_rte(rinfo
)
263 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
264 /* The ADD message implies the update. */
265 rip_zebra_ipv4_add(rip
, rp
);
266 rip_info_free(rinfo
);
269 assert(rinfo
== listgetdata(listhead(list
)));
271 /* This is the only entry left in the list. We must keep it in
272 * the list for garbage collection time, with INFINITY metric.
275 rinfo
->metric
= RIP_METRIC_INFINITY
;
276 RIP_TIMER_ON(rinfo
->t_garbage_collect
, rip_garbage_collect
,
279 if (rip_route_rte(rinfo
)
280 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
281 rip_zebra_ipv4_delete(rip
, rp
);
284 /* Set the route change flag on the first entry. */
285 rinfo
= listgetdata(listhead(list
));
286 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
288 /* Signal the output process to trigger an update (see section 2.5). */
289 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
294 /* Timeout RIP routes. */
295 static int rip_timeout(struct thread
*t
)
297 struct rip_info
*rinfo
= THREAD_ARG(t
);
298 struct rip
*rip
= rip_info_get_instance(rinfo
);
300 rip_ecmp_delete(rip
, rinfo
);
305 static void rip_timeout_update(struct rip
*rip
, struct rip_info
*rinfo
)
307 if (rinfo
->metric
!= RIP_METRIC_INFINITY
) {
308 RIP_TIMER_OFF(rinfo
->t_timeout
);
309 thread_add_timer(master
, rip_timeout
, rinfo
, rip
->timeout_time
,
314 static int rip_filter(int rip_distribute
, struct prefix_ipv4
*p
,
315 struct rip_interface
*ri
)
317 struct distribute
*dist
;
318 struct access_list
*alist
;
319 struct prefix_list
*plist
;
320 int distribute
= rip_distribute
== RIP_FILTER_OUT
? DISTRIBUTE_V4_OUT
322 const char *inout
= rip_distribute
== RIP_FILTER_OUT
? "out" : "in";
324 /* Input distribute-list filtering. */
325 if (ri
->list
[rip_distribute
]) {
326 if (access_list_apply(ri
->list
[rip_distribute
],
329 if (IS_RIP_DEBUG_PACKET
)
330 zlog_debug("%s/%d filtered by distribute %s",
331 inet_ntoa(p
->prefix
), p
->prefixlen
,
336 if (ri
->prefix
[rip_distribute
]) {
337 if (prefix_list_apply(ri
->prefix
[rip_distribute
],
340 if (IS_RIP_DEBUG_PACKET
)
341 zlog_debug("%s/%d filtered by prefix-list %s",
342 inet_ntoa(p
->prefix
), p
->prefixlen
,
348 /* All interface filter check. */
349 dist
= distribute_lookup(ri
->rip
->distribute_ctx
, NULL
);
351 if (dist
->list
[distribute
]) {
352 alist
= access_list_lookup(AFI_IP
,
353 dist
->list
[distribute
]);
356 if (access_list_apply(alist
, (struct prefix
*)p
)
358 if (IS_RIP_DEBUG_PACKET
)
360 "%s/%d filtered by distribute %s",
361 inet_ntoa(p
->prefix
),
362 p
->prefixlen
, inout
);
367 if (dist
->prefix
[distribute
]) {
368 plist
= prefix_list_lookup(AFI_IP
,
369 dist
->prefix
[distribute
]);
372 if (prefix_list_apply(plist
, (struct prefix
*)p
)
374 if (IS_RIP_DEBUG_PACKET
)
376 "%s/%d filtered by prefix-list %s",
377 inet_ntoa(p
->prefix
),
378 p
->prefixlen
, inout
);
387 /* Check nexthop address validity. */
388 static int rip_nexthop_check(struct rip
*rip
, struct in_addr
*addr
)
390 struct interface
*ifp
;
391 struct listnode
*cnode
;
392 struct connected
*ifc
;
395 /* If nexthop address matches local configured address then it is
398 FOR_ALL_INTERFACES (rip
->vrf
, ifp
) {
399 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, ifc
)) {
402 if (p
->family
== AF_INET
403 && IPV4_ADDR_SAME(&p
->u
.prefix4
, addr
))
410 /* RIP add route to routing table. */
411 static void rip_rte_process(struct rte
*rte
, struct sockaddr_in
*from
,
412 struct interface
*ifp
)
416 struct prefix_ipv4 p
;
417 struct route_node
*rp
;
418 struct rip_info
*rinfo
= NULL
, newinfo
;
419 struct rip_interface
*ri
;
420 struct in_addr
*nexthop
;
422 unsigned char old_dist
, new_dist
;
423 struct list
*list
= NULL
;
424 struct listnode
*node
= NULL
;
426 /* Make prefix structure. */
427 memset(&p
, 0, sizeof(struct prefix_ipv4
));
429 p
.prefix
= rte
->prefix
;
430 p
.prefixlen
= ip_masklen(rte
->mask
);
432 /* Make sure mask is applied. */
438 /* Apply input filters. */
439 ret
= rip_filter(RIP_FILTER_IN
, &p
, ri
);
443 memset(&newinfo
, 0, sizeof(newinfo
));
444 newinfo
.type
= ZEBRA_ROUTE_RIP
;
445 newinfo
.sub_type
= RIP_ROUTE_RTE
;
446 newinfo
.nh
.gate
.ipv4
= rte
->nexthop
;
447 newinfo
.from
= from
->sin_addr
;
448 newinfo
.nh
.ifindex
= ifp
->ifindex
;
449 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
450 newinfo
.metric
= rte
->metric
;
451 newinfo
.metric_out
= rte
->metric
; /* XXX */
452 newinfo
.tag
= ntohs(rte
->tag
); /* XXX */
454 /* Modify entry according to the interface routemap. */
455 if (ri
->routemap
[RIP_FILTER_IN
]) {
456 /* The object should be of the type of rip_info */
457 ret
= route_map_apply(ri
->routemap
[RIP_FILTER_IN
],
458 (struct prefix
*)&p
, RMAP_RIP
, &newinfo
);
460 if (ret
== RMAP_DENYMATCH
) {
461 if (IS_RIP_DEBUG_PACKET
)
463 "RIP %s/%d is filtered by route-map in",
464 inet_ntoa(p
.prefix
), p
.prefixlen
);
468 /* Get back the object */
469 rte
->nexthop
= newinfo
.nexthop_out
;
470 rte
->tag
= htons(newinfo
.tag_out
); /* XXX */
471 rte
->metric
= newinfo
.metric_out
; /* XXX: the routemap uses the
475 /* Once the entry has been validated, update the metric by
476 adding the cost of the network on wich the message
477 arrived. If the result is greater than infinity, use infinity
478 (RFC2453 Sec. 3.9.2) */
479 /* Zebra ripd can handle offset-list in. */
480 ret
= rip_offset_list_apply_in(&p
, ifp
, &rte
->metric
);
482 /* If offset-list does not modify the metric use interface's
485 rte
->metric
+= ifp
->metric
? ifp
->metric
: 1;
487 if (rte
->metric
> RIP_METRIC_INFINITY
)
488 rte
->metric
= RIP_METRIC_INFINITY
;
490 /* Set nexthop pointer. */
491 if (rte
->nexthop
.s_addr
== 0)
492 nexthop
= &from
->sin_addr
;
494 nexthop
= &rte
->nexthop
;
496 /* Check if nexthop address is myself, then do nothing. */
497 if (rip_nexthop_check(rip
, nexthop
) < 0) {
498 if (IS_RIP_DEBUG_PACKET
)
499 zlog_debug("Nexthop address %s is myself",
500 inet_ntoa(*nexthop
));
504 /* Get index for the prefix. */
505 rp
= route_node_get(rip
->table
, (struct prefix
*)&p
);
508 newinfo
.nh
.gate
.ipv4
= *nexthop
;
509 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4
;
510 newinfo
.metric
= rte
->metric
;
511 newinfo
.tag
= ntohs(rte
->tag
);
512 newinfo
.distance
= rip_distance_apply(rip
, &newinfo
);
514 new_dist
= newinfo
.distance
? newinfo
.distance
515 : ZEBRA_RIP_DISTANCE_DEFAULT
;
517 /* Check to see whether there is already RIP route on the table. */
518 if ((list
= rp
->info
) != NULL
)
519 for (ALL_LIST_ELEMENTS_RO(list
, node
, rinfo
)) {
520 /* Need to compare with redistributed entry or local
522 if (!rip_route_rte(rinfo
))
525 if (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
526 && IPV4_ADDR_SAME(&rinfo
->nh
.gate
.ipv4
, nexthop
))
529 if (!listnextnode(node
)) {
530 /* Not found in the list */
532 if (rte
->metric
> rinfo
->metric
) {
533 /* New route has a greater metric.
535 route_unlock_node(rp
);
539 if (rte
->metric
< rinfo
->metric
)
540 /* New route has a smaller metric.
541 * Replace the ECMP list
542 * with the new one in below. */
545 /* Metrics are same. We compare the distances.
547 old_dist
= rinfo
->distance
549 : ZEBRA_RIP_DISTANCE_DEFAULT
;
551 if (new_dist
> old_dist
) {
552 /* New route has a greater distance.
554 route_unlock_node(rp
);
558 if (new_dist
< old_dist
)
559 /* New route has a smaller distance.
560 * Replace the ECMP list
561 * with the new one in below. */
564 /* Metrics and distances are both same. Keep
566 * the new route is added in the ECMP list in
572 /* Local static route. */
573 if (rinfo
->type
== ZEBRA_ROUTE_RIP
574 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
575 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))
576 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
577 route_unlock_node(rp
);
581 /* Redistributed route check. */
582 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
583 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
584 old_dist
= rinfo
->distance
;
585 /* Only routes directly connected to an interface
587 * may have a valid NULL distance */
588 if (rinfo
->nh
.gate
.ipv4
.s_addr
!= 0)
591 : ZEBRA_RIP_DISTANCE_DEFAULT
;
592 /* If imported route does not have STRICT precedence,
593 mark it as a ghost */
594 if (new_dist
<= old_dist
595 && rte
->metric
!= RIP_METRIC_INFINITY
)
596 rip_ecmp_replace(rip
, &newinfo
);
598 route_unlock_node(rp
);
605 route_unlock_node(rp
);
607 /* Now, check to see whether there is already an explicit route
608 for the destination prefix. If there is no such route, add
609 this route to the routing table, unless the metric is
610 infinity (there is no point in adding a route which
612 if (rte
->metric
!= RIP_METRIC_INFINITY
)
613 rip_ecmp_add(rip
, &newinfo
);
615 /* Route is there but we are not sure the route is RIP or not.
618 /* If there is an existing route, compare the next hop address
619 to the address of the router from which the datagram came.
620 If this datagram is from the same router as the existing
621 route, reinitialize the timeout. */
622 same
= (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
623 && (rinfo
->nh
.ifindex
== ifp
->ifindex
));
625 old_dist
= rinfo
->distance
? rinfo
->distance
626 : ZEBRA_RIP_DISTANCE_DEFAULT
;
628 /* Next, compare the metrics. If the datagram is from the same
629 router as the existing route, and the new metric is different
630 than the old one; or, if the new metric is lower than the old
631 one, or if the tag has been changed; or if there is a route
632 with a lower administrave distance; or an update of the
633 distance on the actual route; do the following actions: */
634 if ((same
&& rinfo
->metric
!= rte
->metric
)
635 || (rte
->metric
< rinfo
->metric
)
636 || ((same
) && (rinfo
->metric
== rte
->metric
)
637 && (newinfo
.tag
!= rinfo
->tag
))
638 || (old_dist
> new_dist
)
639 || ((old_dist
!= new_dist
) && same
)) {
640 if (listcount(list
) == 1) {
641 if (newinfo
.metric
!= RIP_METRIC_INFINITY
)
642 rip_ecmp_replace(rip
, &newinfo
);
644 rip_ecmp_delete(rip
, rinfo
);
646 if (newinfo
.metric
< rinfo
->metric
)
647 rip_ecmp_replace(rip
, &newinfo
);
648 else if (newinfo
.metric
> rinfo
->metric
)
649 rip_ecmp_delete(rip
, rinfo
);
650 else if (new_dist
< old_dist
)
651 rip_ecmp_replace(rip
, &newinfo
);
652 else if (new_dist
> old_dist
)
653 rip_ecmp_delete(rip
, rinfo
);
655 int update
= CHECK_FLAG(rinfo
->flags
,
660 assert(newinfo
.metric
661 != RIP_METRIC_INFINITY
);
663 RIP_TIMER_OFF(rinfo
->t_timeout
);
664 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
665 memcpy(rinfo
, &newinfo
,
666 sizeof(struct rip_info
));
667 rip_timeout_update(rip
, rinfo
);
670 rip_zebra_ipv4_add(rip
, rp
);
672 /* - Set the route change flag on the
674 rinfo
= listgetdata(listhead(list
));
675 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
676 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
679 } else /* same & no change */
680 rip_timeout_update(rip
, rinfo
);
682 /* Unlock tempolary lock of the route. */
683 route_unlock_node(rp
);
687 /* Dump RIP packet */
688 static void rip_packet_dump(struct rip_packet
*packet
, int size
,
693 const char *command_str
;
694 char pbuf
[BUFSIZ
], nbuf
[BUFSIZ
];
698 /* Set command string. */
699 if (packet
->command
> 0 && packet
->command
< RIP_COMMAND_MAX
)
700 command_str
= lookup_msg(rip_msg
, packet
->command
, NULL
);
702 command_str
= "unknown";
704 /* Dump packet header. */
705 zlog_debug("%s %s version %d packet size %d", sndrcv
, command_str
,
706 packet
->version
, size
);
708 /* Dump each routing table entry. */
711 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
712 if (packet
->version
== RIPv2
) {
713 netmask
= ip_masklen(rte
->mask
);
715 if (rte
->family
== htons(RIP_FAMILY_AUTH
)) {
717 == htons(RIP_AUTH_SIMPLE_PASSWORD
)) {
718 p
= (uint8_t *)&rte
->prefix
;
721 " family 0x%X type %d auth string: %s",
724 } else if (rte
->tag
== htons(RIP_AUTH_MD5
)) {
725 struct rip_md5_info
*md5
;
727 md5
= (struct rip_md5_info
*)&packet
731 " family 0x%X type %d (MD5 authentication)",
735 " RIP-2 packet len %d Key ID %d"
737 ntohs(md5
->packet_len
),
738 md5
->keyid
, md5
->auth_len
);
739 zlog_debug(" Sequence Number %ld",
740 (unsigned long)ntohl(
742 } else if (rte
->tag
== htons(RIP_AUTH_DATA
)) {
743 p
= (uint8_t *)&rte
->prefix
;
746 " family 0x%X type %d (MD5 data)",
750 " MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
751 "%02X%02X%02X%02X%02X%02X%02X%02X",
752 p
[0], p
[1], p
[2], p
[3], p
[4],
753 p
[5], p
[6], p
[7], p
[8], p
[9],
754 p
[10], p
[11], p
[12], p
[13],
758 " family 0x%X type %d (Unknown auth type)",
764 " %s/%d -> %s family %d tag %" ROUTE_TAG_PRI
766 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
,
769 inet_ntop(AF_INET
, &rte
->nexthop
, nbuf
,
772 (route_tag_t
)ntohs(rte
->tag
),
773 (unsigned long)ntohl(rte
->metric
));
776 " %s family %d tag %" ROUTE_TAG_PRI
778 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
780 (route_tag_t
)ntohs(rte
->tag
),
781 (unsigned long)ntohl(rte
->metric
));
786 /* Check if the destination address is valid (unicast; not net 0
787 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
788 check net 0 because we accept default route. */
789 static int rip_destination_check(struct in_addr addr
)
791 uint32_t destination
;
793 /* Convert to host byte order. */
794 destination
= ntohl(addr
.s_addr
);
796 if (IPV4_NET127(destination
))
799 /* Net 0 may match to the default route. */
800 if (IPV4_NET0(destination
) && destination
!= 0)
803 /* Unicast address must belong to class A, B, C. */
804 if (IN_CLASSA(destination
))
806 if (IN_CLASSB(destination
))
808 if (IN_CLASSC(destination
))
814 /* RIP version 2 authentication. */
815 static int rip_auth_simple_password(struct rte
*rte
, struct sockaddr_in
*from
,
816 struct interface
*ifp
)
818 struct rip_interface
*ri
;
819 char *auth_str
= (char *)rte
+ offsetof(struct rte
, prefix
);
822 /* reject passwords with zeros in the middle of the string */
823 for (i
= strnlen(auth_str
, 16); i
< 16; i
++) {
824 if (auth_str
[i
] != '\0')
828 if (IS_RIP_DEBUG_EVENT
)
829 zlog_debug("RIPv2 simple password authentication from %s",
830 inet_ntoa(from
->sin_addr
));
834 if (ri
->auth_type
!= RIP_AUTH_SIMPLE_PASSWORD
835 || rte
->tag
!= htons(RIP_AUTH_SIMPLE_PASSWORD
))
838 /* Simple password authentication. */
840 if (strncmp(auth_str
, ri
->auth_str
, 16) == 0)
844 struct keychain
*keychain
;
847 keychain
= keychain_lookup(ri
->key_chain
);
848 if (keychain
== NULL
|| keychain
->key
== NULL
)
851 key
= key_match_for_accept(keychain
, auth_str
);
858 /* RIP version 2 authentication with MD5. */
859 static int rip_auth_md5(struct rip_packet
*packet
, struct sockaddr_in
*from
,
860 int length
, struct interface
*ifp
)
862 struct rip_interface
*ri
;
863 struct rip_md5_info
*md5
;
864 struct rip_md5_data
*md5data
;
865 struct keychain
*keychain
;
868 uint8_t digest
[RIP_AUTH_MD5_SIZE
];
870 char auth_str
[RIP_AUTH_MD5_SIZE
] = {};
872 if (IS_RIP_DEBUG_EVENT
)
873 zlog_debug("RIPv2 MD5 authentication from %s",
874 inet_ntoa(from
->sin_addr
));
877 md5
= (struct rip_md5_info
*)&packet
->rte
;
879 /* Check auth type. */
880 if (ri
->auth_type
!= RIP_AUTH_MD5
|| md5
->type
!= htons(RIP_AUTH_MD5
))
883 /* If the authentication length is less than 16, then it must be wrong
885 * any interpretation of rfc2082. Some implementations also interpret
886 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka
887 * RIP_AUTH_MD5_COMPAT_SIZE.
889 if (!((md5
->auth_len
== RIP_AUTH_MD5_SIZE
)
890 || (md5
->auth_len
== RIP_AUTH_MD5_COMPAT_SIZE
))) {
891 if (IS_RIP_DEBUG_EVENT
)
893 "RIPv2 MD5 authentication, strange authentication "
899 /* grab and verify check packet length */
900 packet_len
= ntohs(md5
->packet_len
);
902 if (packet_len
> (length
- RIP_HEADER_SIZE
- RIP_AUTH_MD5_SIZE
)) {
903 if (IS_RIP_DEBUG_EVENT
)
905 "RIPv2 MD5 authentication, packet length field %d "
906 "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 memset(&ctx
, 0, sizeof(ctx
));
933 MD5Update(&ctx
, packet
, packet_len
+ RIP_HEADER_SIZE
);
934 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
935 MD5Final(digest
, &ctx
);
937 if (memcmp(md5data
->digest
, digest
, RIP_AUTH_MD5_SIZE
) == 0)
943 /* Pick correct auth string for sends, prepare auth_str buffer for use.
944 * (left justified and padded).
946 * presumes one of ri or key is valid, and that the auth strings they point
947 * to are nul terminated. If neither are present, auth_str will be fully
951 static void rip_auth_prepare_str_send(struct rip_interface
*ri
, struct key
*key
,
952 char *auth_str
, int len
)
956 memset(auth_str
, 0, len
);
957 if (key
&& key
->string
)
958 strlcpy(auth_str
, key
->string
, len
);
959 else if (ri
->auth_str
)
960 strlcpy(auth_str
, ri
->auth_str
, len
);
965 /* Write RIPv2 simple password authentication information
967 * auth_str is presumed to be 2 bytes and correctly prepared
968 * (left justified and zero padded).
970 static void rip_auth_simple_write(struct stream
*s
, char *auth_str
, int len
)
972 assert(s
&& len
== RIP_AUTH_SIMPLE_SIZE
);
974 stream_putw(s
, RIP_FAMILY_AUTH
);
975 stream_putw(s
, RIP_AUTH_SIMPLE_PASSWORD
);
976 stream_put(s
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
981 /* write RIPv2 MD5 "authentication header"
982 * (uses the auth key data field)
984 * Digest offset field is set to 0.
986 * returns: offset of the digest offset field, which must be set when
987 * length to the auth-data MD5 digest is known.
989 static size_t rip_auth_md5_ah_write(struct stream
*s
, struct rip_interface
*ri
,
994 assert(s
&& ri
&& ri
->auth_type
== RIP_AUTH_MD5
);
996 /* MD5 authentication. */
997 stream_putw(s
, RIP_FAMILY_AUTH
);
998 stream_putw(s
, RIP_AUTH_MD5
);
1000 /* MD5 AH digest offset field.
1002 * Set to placeholder value here, to true value when RIP-2 Packet length
1003 * is known. Actual value is set in .....().
1005 doff
= stream_get_endp(s
);
1010 stream_putc(s
, key
->index
% 256);
1014 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
1015 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for
1017 * to be configurable.
1019 stream_putc(s
, ri
->md5_auth_len
);
1021 /* Sequence Number (non-decreasing). */
1022 /* RFC2080: The value used in the sequence number is
1023 arbitrary, but two suggestions are the time of the
1024 message's creation or a simple message counter. */
1025 stream_putl(s
, time(NULL
));
1027 /* Reserved field must be zero. */
1034 /* If authentication is in used, write the appropriate header
1035 * returns stream offset to which length must later be written
1036 * or 0 if this is not required
1038 static size_t rip_auth_header_write(struct stream
*s
, struct rip_interface
*ri
,
1039 struct key
*key
, char *auth_str
, int len
)
1041 assert(ri
->auth_type
!= RIP_NO_AUTH
);
1043 switch (ri
->auth_type
) {
1044 case RIP_AUTH_SIMPLE_PASSWORD
:
1045 rip_auth_prepare_str_send(ri
, key
, auth_str
, len
);
1046 rip_auth_simple_write(s
, auth_str
, len
);
1049 return rip_auth_md5_ah_write(s
, ri
, key
);
1055 /* Write RIPv2 MD5 authentication data trailer */
1056 static void rip_auth_md5_set(struct stream
*s
, struct rip_interface
*ri
,
1057 size_t doff
, char *auth_str
, int authlen
)
1061 unsigned char digest
[RIP_AUTH_MD5_SIZE
];
1063 /* Make it sure this interface is configured as MD5
1065 assert((ri
->auth_type
== RIP_AUTH_MD5
)
1066 && (authlen
== RIP_AUTH_MD5_SIZE
));
1069 /* Get packet length. */
1070 len
= stream_get_endp(s
);
1072 /* Check packet length. */
1073 if (len
< (RIP_HEADER_SIZE
+ RIP_RTE_SIZE
)) {
1076 "rip_auth_md5_set(): packet length %ld is less than minimum length.",
1081 /* Set the digest offset length in the header */
1082 stream_putw_at(s
, doff
, len
);
1084 /* Set authentication data. */
1085 stream_putw(s
, RIP_FAMILY_AUTH
);
1086 stream_putw(s
, RIP_AUTH_DATA
);
1088 /* Generate a digest for the RIP packet. */
1089 memset(&ctx
, 0, sizeof(ctx
));
1091 MD5Update(&ctx
, STREAM_DATA(s
), stream_get_endp(s
));
1092 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1093 MD5Final(digest
, &ctx
);
1095 /* Copy the digest to the packet. */
1096 stream_write(s
, digest
, RIP_AUTH_MD5_SIZE
);
1099 /* RIP routing information. */
1100 static void rip_response_process(struct rip_packet
*packet
, int size
,
1101 struct sockaddr_in
*from
,
1102 struct connected
*ifc
)
1104 struct rip_interface
*ri
= ifc
->ifp
->info
;
1105 struct rip
*rip
= ri
->rip
;
1108 struct prefix_ipv4 ifaddr
;
1109 struct prefix_ipv4 ifaddrclass
;
1112 memset(&ifaddr
, 0, sizeof(ifaddr
));
1113 /* We don't know yet. */
1116 /* The Response must be ignored if it is not from the RIP
1117 port. (RFC2453 - Sec. 3.9.2)*/
1118 if (from
->sin_port
!= htons(RIP_PORT_DEFAULT
)) {
1119 zlog_info("response doesn't come from RIP port: %d",
1121 rip_peer_bad_packet(rip
, from
);
1125 /* The datagram's IPv4 source address should be checked to see
1126 whether the datagram is from a valid neighbor; the source of the
1127 datagram must be on a directly connected network (RFC2453 - Sec.
1129 if (if_lookup_address((void *)&from
->sin_addr
, AF_INET
,
1133 "This datagram doesn't came from a valid neighbor: %s",
1134 inet_ntoa(from
->sin_addr
));
1135 rip_peer_bad_packet(rip
, from
);
1139 /* It is also worth checking to see whether the response is from one
1140 of the router's own addresses. */
1142 ; /* Alredy done in rip_read () */
1144 /* Update RIP peer. */
1145 rip_peer_update(rip
, from
, packet
->version
);
1147 /* Set RTE pointer. */
1150 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
1151 /* RIPv2 authentication check. */
1152 /* If the Address Family Identifier of the first (and only the
1153 first) entry in the message is 0xFFFF, then the remainder of
1154 the entry contains the authentication. */
1155 /* If the packet gets here it means authentication enabled */
1156 /* Check is done in rip_read(). So, just skipping it */
1157 if (packet
->version
== RIPv2
&& rte
== packet
->rte
1158 && rte
->family
== htons(RIP_FAMILY_AUTH
))
1161 if (rte
->family
!= htons(AF_INET
)) {
1162 /* Address family check. RIP only supports AF_INET. */
1163 zlog_info("Unsupported family %d from %s.",
1165 inet_ntoa(from
->sin_addr
));
1169 /* - is the destination address valid (e.g., unicast; not net 0
1171 if (!rip_destination_check(rte
->prefix
)) {
1173 "Network is net 0 or net 127 or it is not unicast network");
1174 rip_peer_bad_route(rip
, from
);
1178 /* Convert metric value to host byte order. */
1179 rte
->metric
= ntohl(rte
->metric
);
1181 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1182 if (!(rte
->metric
>= 1 && rte
->metric
<= 16)) {
1183 zlog_info("Route's metric is not in the 1-16 range.");
1184 rip_peer_bad_route(rip
, from
);
1188 /* RIPv1 does not have nexthop value. */
1189 if (packet
->version
== RIPv1
&& rte
->nexthop
.s_addr
!= 0) {
1190 zlog_info("RIPv1 packet with nexthop value %s",
1191 inet_ntoa(rte
->nexthop
));
1192 rip_peer_bad_route(rip
, from
);
1196 /* That is, if the provided information is ignored, a possibly
1197 sub-optimal, but absolutely valid, route may be taken. If
1198 the received Next Hop is not directly reachable, it should be
1199 treated as 0.0.0.0. */
1200 if (packet
->version
== RIPv2
&& rte
->nexthop
.s_addr
!= 0) {
1203 /* Multicast address check. */
1204 addrval
= ntohl(rte
->nexthop
.s_addr
);
1205 if (IN_CLASSD(addrval
)) {
1207 "Nexthop %s is multicast address, skip this rte",
1208 inet_ntoa(rte
->nexthop
));
1212 if (!if_lookup_address((void *)&rte
->nexthop
, AF_INET
,
1213 rip
->vrf
->vrf_id
)) {
1214 struct route_node
*rn
;
1215 struct rip_info
*rinfo
;
1217 rn
= route_node_match_ipv4(rip
->table
,
1223 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1226 if (IS_RIP_DEBUG_EVENT
)
1228 "Next hop %s is on RIP network. Set nexthop to the packet's originator",
1231 rte
->nexthop
= rinfo
->from
;
1233 if (IS_RIP_DEBUG_EVENT
)
1235 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1238 rte
->nexthop
.s_addr
= 0;
1241 route_unlock_node(rn
);
1243 if (IS_RIP_DEBUG_EVENT
)
1245 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1248 rte
->nexthop
.s_addr
= 0;
1253 /* For RIPv1, there won't be a valid netmask.
1255 This is a best guess at the masks. If everyone was using old
1256 Ciscos before the 'ip subnet zero' option, it would be almost
1259 Cisco summarize ripv1 advertisements to the classful boundary
1260 (/16 for class B's) except when the RIP packet does to inside
1261 the classful network in question. */
1263 if ((packet
->version
== RIPv1
&& rte
->prefix
.s_addr
!= 0)
1264 || (packet
->version
== RIPv2
1265 && (rte
->prefix
.s_addr
!= 0
1266 && rte
->mask
.s_addr
== 0))) {
1267 uint32_t destination
;
1269 if (subnetted
== -1) {
1270 memcpy(&ifaddr
, ifc
->address
,
1271 sizeof(struct prefix_ipv4
));
1272 memcpy(&ifaddrclass
, &ifaddr
,
1273 sizeof(struct prefix_ipv4
));
1274 apply_classful_mask_ipv4(&ifaddrclass
);
1276 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1280 destination
= ntohl(rte
->prefix
.s_addr
);
1282 if (IN_CLASSA(destination
))
1283 masklen2ip(8, &rte
->mask
);
1284 else if (IN_CLASSB(destination
))
1285 masklen2ip(16, &rte
->mask
);
1286 else if (IN_CLASSC(destination
))
1287 masklen2ip(24, &rte
->mask
);
1290 masklen2ip(ifaddrclass
.prefixlen
,
1291 (struct in_addr
*)&destination
);
1292 if ((subnetted
== 1)
1293 && ((rte
->prefix
.s_addr
& destination
)
1294 == ifaddrclass
.prefix
.s_addr
)) {
1295 masklen2ip(ifaddr
.prefixlen
, &rte
->mask
);
1296 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1297 != rte
->prefix
.s_addr
)
1298 masklen2ip(32, &rte
->mask
);
1299 if (IS_RIP_DEBUG_EVENT
)
1300 zlog_debug("Subnetted route %s",
1301 inet_ntoa(rte
->prefix
));
1303 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1304 != rte
->prefix
.s_addr
)
1308 if (IS_RIP_DEBUG_EVENT
) {
1309 zlog_debug("Resultant route %s",
1310 inet_ntoa(rte
->prefix
));
1311 zlog_debug("Resultant mask %s",
1312 inet_ntoa(rte
->mask
));
1316 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1317 ignore the entry. */
1318 if ((packet
->version
== RIPv2
) && (rte
->mask
.s_addr
!= 0)
1319 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1320 != rte
->prefix
.s_addr
)) {
1322 "RIPv2 address %s is not mask /%d applied one",
1323 inet_ntoa(rte
->prefix
), ip_masklen(rte
->mask
));
1324 rip_peer_bad_route(rip
, from
);
1328 /* Default route's netmask is ignored. */
1329 if (packet
->version
== RIPv2
&& (rte
->prefix
.s_addr
== 0)
1330 && (rte
->mask
.s_addr
!= 0)) {
1331 if (IS_RIP_DEBUG_EVENT
)
1333 "Default route with non-zero netmask. Set zero to netmask");
1334 rte
->mask
.s_addr
= 0;
1337 /* Routing table updates. */
1338 rip_rte_process(rte
, from
, ifc
->ifp
);
1342 /* Make socket for RIP protocol. */
1343 int rip_create_socket(struct vrf
*vrf
)
1347 struct sockaddr_in addr
;
1348 const char *vrf_dev
= NULL
;
1350 memset(&addr
, 0, sizeof(struct sockaddr_in
));
1351 addr
.sin_family
= AF_INET
;
1352 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1353 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1354 addr
.sin_len
= sizeof(struct sockaddr_in
);
1355 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1356 /* sending port must always be the RIP port */
1357 addr
.sin_port
= htons(RIP_PORT_DEFAULT
);
1359 /* Make datagram socket. */
1360 if (vrf
->vrf_id
!= VRF_DEFAULT
)
1361 vrf_dev
= vrf
->name
;
1362 frr_elevate_privs(&ripd_privs
) {
1363 sock
= vrf_socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
, vrf
->vrf_id
,
1366 flog_err_sys(EC_LIB_SOCKET
,
1367 "Cannot create UDP socket: %s",
1368 safe_strerror(errno
));
1373 sockopt_broadcast(sock
);
1374 sockopt_reuseaddr(sock
);
1375 sockopt_reuseport(sock
);
1376 setsockopt_ipv4_multicast_loop(sock
, 0);
1377 #ifdef IPTOS_PREC_INTERNETCONTROL
1378 setsockopt_ipv4_tos(sock
, IPTOS_PREC_INTERNETCONTROL
);
1380 setsockopt_so_recvbuf(sock
, RIP_UDP_RCV_BUF
);
1382 frr_elevate_privs(&ripd_privs
) {
1383 if ((ret
= bind(sock
, (struct sockaddr
*)&addr
, sizeof(addr
)))
1385 zlog_err("%s: Can't bind socket %d to %s port %d: %s",
1386 __func__
, sock
, inet_ntoa(addr
.sin_addr
),
1387 (int)ntohs(addr
.sin_port
),
1388 safe_strerror(errno
));
1398 /* RIP packet send to destination address, on interface denoted by
1399 * by connected argument. NULL to argument denotes destination should be
1400 * should be RIP multicast group
1402 static int rip_send_packet(uint8_t *buf
, int size
, struct sockaddr_in
*to
,
1403 struct connected
*ifc
)
1405 struct rip_interface
*ri
;
1408 struct sockaddr_in sin
;
1412 struct cmsghdr
*cmsgptr
;
1413 char adata
[256] = {};
1414 struct in_pktinfo
*pkt
;
1415 #endif /* GNU_LINUX */
1417 assert(ifc
!= NULL
);
1418 ri
= ifc
->ifp
->info
;
1421 if (IS_RIP_DEBUG_PACKET
) {
1422 #define ADDRESS_SIZE 20
1423 char dst
[ADDRESS_SIZE
];
1426 strlcpy(dst
, inet_ntoa(to
->sin_addr
), sizeof(dst
));
1428 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1429 strlcpy(dst
, inet_ntoa(sin
.sin_addr
), sizeof(dst
));
1432 zlog_debug("rip_send_packet %s > %s (%s)",
1433 inet_ntoa(ifc
->address
->u
.prefix4
), dst
,
1437 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
1439 * ZEBRA_IFA_SECONDARY is set on linux when an interface is
1441 * with multiple addresses on the same subnet: the first address
1442 * on the subnet is configured "primary", and all subsequent
1444 * on that subnet are treated as "secondary" addresses.
1445 * In order to avoid routing-table bloat on other rip listeners,
1446 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY
1448 * XXX Since Linux is the only system for which the
1449 * ZEBRA_IFA_SECONDARY
1450 * flag is set, we would end up sending a packet for a
1452 * source address on non-linux systems.
1454 if (IS_RIP_DEBUG_PACKET
)
1455 zlog_debug("duplicate dropped");
1459 /* Make destination address. */
1460 memset(&sin
, 0, sizeof(struct sockaddr_in
));
1461 sin
.sin_family
= AF_INET
;
1462 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1463 sin
.sin_len
= sizeof(struct sockaddr_in
);
1464 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1466 /* When destination is specified, use it's port and address. */
1468 sin
.sin_port
= to
->sin_port
;
1469 sin
.sin_addr
= to
->sin_addr
;
1471 sin
.sin_port
= htons(RIP_PORT_DEFAULT
);
1472 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1474 rip_interface_multicast_set(rip
->sock
, ifc
);
1477 memset(&msg
, 0, sizeof(msg
));
1478 msg
.msg_name
= (void *)&sin
;
1479 msg
.msg_namelen
= sizeof(struct sockaddr_in
);
1486 msg
.msg_control
= (void *)adata
;
1487 msg
.msg_controllen
= CMSG_SPACE(sizeof(struct in_pktinfo
));
1489 cmsgptr
= (struct cmsghdr
*)adata
;
1490 cmsgptr
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
1491 cmsgptr
->cmsg_level
= IPPROTO_IP
;
1492 cmsgptr
->cmsg_type
= IP_PKTINFO
;
1493 pkt
= (struct in_pktinfo
*)CMSG_DATA(cmsgptr
);
1494 pkt
->ipi_ifindex
= ifc
->ifp
->ifindex
;
1495 #endif /* GNU_LINUX */
1497 ret
= sendmsg(rip
->sock
, &msg
, 0);
1499 if (IS_RIP_DEBUG_EVENT
)
1500 zlog_debug("SEND to %s.%d", inet_ntoa(sin
.sin_addr
),
1501 ntohs(sin
.sin_port
));
1504 zlog_warn("can't send packet : %s", safe_strerror(errno
));
1509 /* Add redistributed route to RIP table. */
1510 void rip_redistribute_add(struct rip
*rip
, int type
, int sub_type
,
1511 struct prefix_ipv4
*p
, struct nexthop
*nh
,
1512 unsigned int metric
, unsigned char distance
,
1516 struct route_node
*rp
= NULL
;
1517 struct rip_info
*rinfo
= NULL
, newinfo
;
1518 struct list
*list
= NULL
;
1520 /* Redistribute route */
1521 ret
= rip_destination_check(p
->prefix
);
1525 rp
= route_node_get(rip
->table
, (struct prefix
*)p
);
1527 memset(&newinfo
, 0, sizeof(struct rip_info
));
1528 newinfo
.type
= type
;
1529 newinfo
.sub_type
= sub_type
;
1531 newinfo
.external_metric
= metric
;
1532 newinfo
.distance
= distance
;
1533 if (tag
<= UINT16_MAX
) /* RIP only supports 16 bit tags */
1538 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
1539 rinfo
= listgetdata(listhead(list
));
1541 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
1542 && rinfo
->sub_type
== RIP_ROUTE_INTERFACE
1543 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
1544 route_unlock_node(rp
);
1548 /* Manually configured RIP route check. */
1549 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1550 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
1551 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))) {
1552 if (type
!= ZEBRA_ROUTE_RIP
1553 || ((sub_type
!= RIP_ROUTE_STATIC
)
1554 && (sub_type
!= RIP_ROUTE_DEFAULT
))) {
1555 route_unlock_node(rp
);
1560 (void)rip_ecmp_replace(rip
, &newinfo
);
1561 route_unlock_node(rp
);
1563 (void)rip_ecmp_add(rip
, &newinfo
);
1565 if (IS_RIP_DEBUG_EVENT
) {
1566 zlog_debug("Redistribute new prefix %s/%d",
1567 inet_ntoa(p
->prefix
), p
->prefixlen
);
1570 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
1573 /* Delete redistributed route from RIP table. */
1574 void rip_redistribute_delete(struct rip
*rip
, int type
, int sub_type
,
1575 struct prefix_ipv4
*p
, ifindex_t ifindex
)
1578 struct route_node
*rp
;
1579 struct rip_info
*rinfo
;
1581 ret
= rip_destination_check(p
->prefix
);
1585 rp
= route_node_lookup(rip
->table
, (struct prefix
*)p
);
1587 struct list
*list
= rp
->info
;
1589 if (list
!= NULL
&& listcount(list
) != 0) {
1590 rinfo
= listgetdata(listhead(list
));
1591 if (rinfo
!= NULL
&& rinfo
->type
== type
1592 && rinfo
->sub_type
== sub_type
1593 && rinfo
->nh
.ifindex
== ifindex
) {
1594 /* Perform poisoned reverse. */
1595 rinfo
->metric
= RIP_METRIC_INFINITY
;
1596 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
1597 rip_garbage_collect
,
1599 RIP_TIMER_OFF(rinfo
->t_timeout
);
1600 rinfo
->flags
|= RIP_RTF_CHANGED
;
1602 if (IS_RIP_DEBUG_EVENT
)
1604 "Poison %s/%d on the interface %s with an "
1605 "infinity metric [delete]",
1606 inet_ntoa(p
->prefix
),
1612 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
1615 route_unlock_node(rp
);
1619 /* Response to request called from rip_read ().*/
1620 static void rip_request_process(struct rip_packet
*packet
, int size
,
1621 struct sockaddr_in
*from
, struct connected
*ifc
)
1626 struct prefix_ipv4 p
;
1627 struct route_node
*rp
;
1628 struct rip_info
*rinfo
;
1629 struct rip_interface
*ri
;
1631 /* Does not reponse to the requests on the loopback interfaces */
1632 if (if_is_loopback(ifc
->ifp
))
1635 /* Check RIP process is enabled on this interface. */
1636 ri
= ifc
->ifp
->info
;
1641 /* When passive interface is specified, suppress responses */
1645 /* RIP peer update. */
1646 rip_peer_update(rip
, from
, packet
->version
);
1648 lim
= ((caddr_t
)packet
) + size
;
1651 /* The Request is processed entry by entry. If there are no
1652 entries, no response is given. */
1653 if (lim
== (caddr_t
)rte
)
1656 /* There is one special case. If there is exactly one entry in the
1657 request, and it has an address family identifier of zero and a
1658 metric of infinity (i.e., 16), then this is a request to send the
1659 entire routing table. */
1660 if (lim
== ((caddr_t
)(rte
+ 1)) && ntohs(rte
->family
) == 0
1661 && ntohl(rte
->metric
) == RIP_METRIC_INFINITY
) {
1662 /* All route with split horizon */
1663 rip_output_process(ifc
, from
, rip_all_route
, packet
->version
);
1665 if (ntohs(rte
->family
) != AF_INET
)
1668 /* Examine the list of RTEs in the Request one by one. For each
1669 entry, look up the destination in the router's routing
1670 database and, if there is a route, put that route's metric in
1671 the metric field of the RTE. If there is no explicit route
1672 to the specified destination, put infinity in the metric
1673 field. Once all the entries have been filled in, change the
1674 command from Request to Response and send the datagram back
1675 to the requestor. */
1678 for (; ((caddr_t
)rte
) < lim
; rte
++) {
1679 p
.prefix
= rte
->prefix
;
1680 p
.prefixlen
= ip_masklen(rte
->mask
);
1681 apply_mask_ipv4(&p
);
1683 rp
= route_node_lookup(rip
->table
, (struct prefix
*)&p
);
1685 rinfo
= listgetdata(
1686 listhead((struct list
*)rp
->info
));
1687 rte
->metric
= htonl(rinfo
->metric
);
1688 route_unlock_node(rp
);
1690 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
1692 packet
->command
= RIP_RESPONSE
;
1694 (void)rip_send_packet((uint8_t *)packet
, size
, from
, ifc
);
1696 rip
->counters
.queries
++;
1699 /* First entry point of RIP packet. */
1700 static int rip_read(struct thread
*t
)
1702 struct rip
*rip
= THREAD_ARG(t
);
1706 union rip_buf rip_buf
;
1707 struct rip_packet
*packet
;
1708 struct sockaddr_in from
;
1712 struct interface
*ifp
= NULL
;
1713 struct connected
*ifc
;
1714 struct rip_interface
*ri
;
1717 /* Fetch socket then register myself. */
1718 sock
= THREAD_FD(t
);
1721 /* Add myself to tne next event */
1722 rip_event(rip
, RIP_READ
, sock
);
1724 /* RIPd manages only IPv4. */
1725 memset(&from
, 0, sizeof(struct sockaddr_in
));
1726 fromlen
= sizeof(struct sockaddr_in
);
1728 len
= recvfrom(sock
, (char *)&rip_buf
.buf
, sizeof(rip_buf
.buf
), 0,
1729 (struct sockaddr
*)&from
, &fromlen
);
1731 zlog_info("recvfrom failed (VRF %s): %s", rip
->vrf_name
,
1732 safe_strerror(errno
));
1736 /* Check is this packet comming from myself? */
1737 if (if_check_address(rip
, from
.sin_addr
)) {
1738 if (IS_RIP_DEBUG_PACKET
)
1739 zlog_debug("ignore packet comes from myself (VRF %s)",
1744 /* Which interface is this packet comes from. */
1745 ifc
= if_lookup_address((void *)&from
.sin_addr
, AF_INET
,
1750 /* RIP packet received */
1751 if (IS_RIP_DEBUG_EVENT
)
1752 zlog_debug("RECV packet from %s port %d on %s (VRF %s)",
1753 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1754 ifp
? ifp
->name
: "unknown", rip
->vrf_name
);
1756 /* If this packet come from unknown interface, ignore it. */
1759 "rip_read: cannot find interface for packet from %s port %d (VRF %s)",
1760 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1766 p
.u
.prefix4
= from
.sin_addr
;
1767 p
.prefixlen
= IPV4_MAX_BITLEN
;
1769 ifc
= connected_lookup_prefix(ifp
, &p
);
1773 "rip_read: cannot find connected address for packet from %s "
1774 "port %d on interface %s (VRF %s)",
1775 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1776 ifp
->name
, rip
->vrf_name
);
1780 /* Packet length check. */
1781 if (len
< RIP_PACKET_MINSIZ
) {
1782 zlog_warn("packet size %d is smaller than minimum size %d", len
,
1784 rip_peer_bad_packet(rip
, &from
);
1787 if (len
> RIP_PACKET_MAXSIZ
) {
1788 zlog_warn("packet size %d is larger than max size %d", len
,
1790 rip_peer_bad_packet(rip
, &from
);
1794 /* Packet alignment check. */
1795 if ((len
- RIP_PACKET_MINSIZ
) % 20) {
1796 zlog_warn("packet size %d is wrong for RIP packet alignment",
1798 rip_peer_bad_packet(rip
, &from
);
1802 /* Set RTE number. */
1803 rtenum
= ((len
- RIP_PACKET_MINSIZ
) / 20);
1805 /* For easy to handle. */
1806 packet
= &rip_buf
.rip_packet
;
1808 /* RIP version check. */
1809 if (packet
->version
== 0) {
1810 zlog_info("version 0 with command %d received.",
1812 rip_peer_bad_packet(rip
, &from
);
1816 /* Dump RIP packet. */
1817 if (IS_RIP_DEBUG_RECV
)
1818 rip_packet_dump(packet
, len
, "RECV");
1820 /* RIP version adjust. This code should rethink now. RFC1058 says
1821 that "Version 1 implementations are to ignore this extra data and
1822 process only the fields specified in this document.". So RIPv3
1823 packet should be treated as RIPv1 ignoring must be zero field. */
1824 if (packet
->version
> RIPv2
)
1825 packet
->version
= RIPv2
;
1827 /* Is RIP running or is this RIP neighbor ?*/
1829 if (!ri
->running
&& !rip_neighbor_lookup(rip
, &from
)) {
1830 if (IS_RIP_DEBUG_EVENT
)
1831 zlog_debug("RIP is not enabled on interface %s.",
1833 rip_peer_bad_packet(rip
, &from
);
1837 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1838 vrecv
= ((ri
->ri_receive
== RI_RIP_UNSPEC
) ? rip
->version_recv
1840 if (vrecv
== RI_RIP_VERSION_NONE
1841 || ((packet
->version
== RIPv1
) && !(vrecv
& RIPv1
))
1842 || ((packet
->version
== RIPv2
) && !(vrecv
& RIPv2
))) {
1843 if (IS_RIP_DEBUG_PACKET
)
1845 " packet's v%d doesn't fit to if version spec",
1847 rip_peer_bad_packet(rip
, &from
);
1851 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1852 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1853 accepted; authenticated RIP-2 messages shall be discarded. */
1854 if ((ri
->auth_type
== RIP_NO_AUTH
) && rtenum
1855 && (packet
->version
== RIPv2
)
1856 && (packet
->rte
->family
== htons(RIP_FAMILY_AUTH
))) {
1857 if (IS_RIP_DEBUG_EVENT
)
1859 "packet RIPv%d is dropped because authentication disabled",
1861 ripd_notif_send_auth_type_failure(ifp
->name
);
1862 rip_peer_bad_packet(rip
, &from
);
1867 If the router is configured to authenticate RIP-2 messages, then
1868 RIP-1 messages and RIP-2 messages which pass authentication
1869 testing shall be accepted; unauthenticated and failed
1870 authentication RIP-2 messages shall be discarded. For maximum
1871 security, RIP-1 messages should be ignored when authentication is
1872 in use (see section 4.1); otherwise, the routing information from
1873 authenticated messages will be propagated by RIP-1 routers in an
1874 unauthenticated manner.
1876 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1877 * always reply regardless of authentication settings, because:
1879 * - if there other authorised routers on-link, the REQUESTor can
1880 * passively obtain the routing updates anyway
1881 * - if there are no other authorised routers on-link, RIP can
1882 * easily be disabled for the link to prevent giving out information
1883 * on state of this routers RIP routing table..
1885 * I.e. if RIPv1 has any place anymore these days, it's as a very
1886 * simple way to distribute routing information (e.g. to embedded
1887 * hosts / appliances) and the ability to give out RIPv1
1888 * routing-information freely, while still requiring RIPv2
1889 * authentication for any RESPONSEs might be vaguely useful.
1891 if (ri
->auth_type
!= RIP_NO_AUTH
&& packet
->version
== RIPv1
) {
1892 /* Discard RIPv1 messages other than REQUESTs */
1893 if (packet
->command
!= RIP_REQUEST
) {
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
);
1902 } else if (ri
->auth_type
!= RIP_NO_AUTH
) {
1903 const char *auth_desc
;
1906 /* There definitely is no authentication in the packet.
1908 if (IS_RIP_DEBUG_PACKET
)
1910 "RIPv2 authentication failed: no auth RTE in packet");
1911 ripd_notif_send_auth_type_failure(ifp
->name
);
1912 rip_peer_bad_packet(rip
, &from
);
1916 /* First RTE must be an Authentication Family RTE */
1917 if (packet
->rte
->family
!= htons(RIP_FAMILY_AUTH
)) {
1918 if (IS_RIP_DEBUG_PACKET
)
1921 " dropped because authentication enabled");
1922 ripd_notif_send_auth_type_failure(ifp
->name
);
1923 rip_peer_bad_packet(rip
, &from
);
1927 /* Check RIPv2 authentication. */
1928 switch (ntohs(packet
->rte
->tag
)) {
1929 case RIP_AUTH_SIMPLE_PASSWORD
:
1930 auth_desc
= "simple";
1931 ret
= rip_auth_simple_password(packet
->rte
, &from
, ifp
);
1936 ret
= rip_auth_md5(packet
, &from
, len
, ifp
);
1937 /* Reset RIP packet length to trim MD5 data. */
1943 auth_desc
= "unknown type";
1944 if (IS_RIP_DEBUG_PACKET
)
1946 "RIPv2 Unknown authentication type %d",
1947 ntohs(packet
->rte
->tag
));
1951 if (IS_RIP_DEBUG_PACKET
)
1952 zlog_debug("RIPv2 %s authentication success",
1955 if (IS_RIP_DEBUG_PACKET
)
1956 zlog_debug("RIPv2 %s authentication failure",
1958 ripd_notif_send_auth_failure(ifp
->name
);
1959 rip_peer_bad_packet(rip
, &from
);
1964 /* Process each command. */
1965 switch (packet
->command
) {
1967 rip_response_process(packet
, len
, &from
, ifc
);
1971 rip_request_process(packet
, len
, &from
, ifc
);
1976 "Obsolete command %s received, please sent it to routed",
1977 lookup_msg(rip_msg
, packet
->command
, NULL
));
1978 rip_peer_bad_packet(rip
, &from
);
1980 case RIP_POLL_ENTRY
:
1981 zlog_info("Obsolete command %s received",
1982 lookup_msg(rip_msg
, packet
->command
, NULL
));
1983 rip_peer_bad_packet(rip
, &from
);
1986 zlog_info("Unknown RIP command %d received", packet
->command
);
1987 rip_peer_bad_packet(rip
, &from
);
1994 /* Write routing table entry to the stream and return next index of
1995 the routing table entry in the stream. */
1996 static int rip_write_rte(int num
, struct stream
*s
, struct prefix_ipv4
*p
,
1997 uint8_t version
, struct rip_info
*rinfo
)
1999 struct in_addr mask
;
2001 /* Write routing table entry. */
2002 if (version
== RIPv1
) {
2003 stream_putw(s
, AF_INET
);
2005 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2006 stream_put_ipv4(s
, 0);
2007 stream_put_ipv4(s
, 0);
2008 stream_putl(s
, rinfo
->metric_out
);
2010 masklen2ip(p
->prefixlen
, &mask
);
2012 stream_putw(s
, AF_INET
);
2013 stream_putw(s
, rinfo
->tag_out
);
2014 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2015 stream_put_ipv4(s
, mask
.s_addr
);
2016 stream_put_ipv4(s
, rinfo
->nexthop_out
.s_addr
);
2017 stream_putl(s
, rinfo
->metric_out
);
2023 /* Send update to the ifp or spcified neighbor. */
2024 void rip_output_process(struct connected
*ifc
, struct sockaddr_in
*to
,
2025 int route_type
, uint8_t version
)
2030 struct route_node
*rp
;
2031 struct rip_info
*rinfo
;
2032 struct rip_interface
*ri
;
2033 struct prefix_ipv4
*p
;
2034 struct prefix_ipv4 classfull
;
2035 struct prefix_ipv4 ifaddrclass
;
2036 struct key
*key
= NULL
;
2037 /* this might need to made dynamic if RIP ever supported auth methods
2038 with larger key string sizes */
2039 char auth_str
[RIP_AUTH_SIMPLE_SIZE
];
2040 size_t doff
= 0; /* offset of digest offset field */
2044 struct list
*list
= NULL
;
2045 struct listnode
*listnode
= NULL
;
2047 /* Logging output event. */
2048 if (IS_RIP_DEBUG_EVENT
) {
2050 zlog_debug("update routes to neighbor %s",
2051 inet_ntoa(to
->sin_addr
));
2053 zlog_debug("update routes on interface %s ifindex %d",
2054 ifc
->ifp
->name
, ifc
->ifp
->ifindex
);
2057 /* Get RIP interface. */
2058 ri
= ifc
->ifp
->info
;
2061 /* Set output stream. */
2064 /* Reset stream and RTE counter. */
2066 rtemax
= RIP_MAX_RTE
;
2068 /* If output interface is in simple password authentication mode, we
2069 need space for authentication data. */
2070 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2073 /* If output interface is in MD5 authentication mode, we need space
2074 for authentication header and data. */
2075 if (ri
->auth_type
== RIP_AUTH_MD5
)
2078 /* If output interface is in simple password authentication mode
2079 and string or keychain is specified we need space for auth. data */
2080 if (ri
->auth_type
!= RIP_NO_AUTH
) {
2081 if (ri
->key_chain
) {
2082 struct keychain
*keychain
;
2084 keychain
= keychain_lookup(ri
->key_chain
);
2086 key
= key_lookup_for_send(keychain
);
2088 /* to be passed to auth functions later */
2089 rip_auth_prepare_str_send(ri
, key
, auth_str
, sizeof(auth_str
));
2090 if (strlen(auth_str
) == 0)
2094 if (version
== RIPv1
) {
2095 memcpy(&ifaddrclass
, ifc
->address
, sizeof(struct prefix_ipv4
));
2096 apply_classful_mask_ipv4(&ifaddrclass
);
2098 if (ifc
->address
->prefixlen
> ifaddrclass
.prefixlen
)
2102 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2103 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
2104 rinfo
= listgetdata(listhead(list
));
2105 /* For RIPv1, if we are subnetted, output subnets in our
2107 /* that have the same mask as the output "interface".
2109 /* networks, only the classfull version is output. */
2111 if (version
== RIPv1
) {
2112 p
= (struct prefix_ipv4
*)&rp
->p
;
2114 if (IS_RIP_DEBUG_PACKET
)
2116 "RIPv1 mask check, %s/%d considered for output",
2117 inet_ntoa(rp
->p
.u
.prefix4
),
2122 (struct prefix
*)&ifaddrclass
,
2124 if ((ifc
->address
->prefixlen
2126 && (rp
->p
.prefixlen
!= 32))
2129 memcpy(&classfull
, &rp
->p
,
2130 sizeof(struct prefix_ipv4
));
2131 apply_classful_mask_ipv4(&classfull
);
2132 if (rp
->p
.u
.prefix4
.s_addr
!= 0
2133 && classfull
.prefixlen
2137 if (IS_RIP_DEBUG_PACKET
)
2139 "RIPv1 mask check, %s/%d made it through",
2140 inet_ntoa(rp
->p
.u
.prefix4
),
2143 p
= (struct prefix_ipv4
*)&rp
->p
;
2145 /* Apply output filters. */
2146 ret
= rip_filter(RIP_FILTER_OUT
, p
, ri
);
2150 /* Changed route only output. */
2151 if (route_type
== rip_changed_route
2152 && (!(rinfo
->flags
& RIP_RTF_CHANGED
)))
2155 /* Split horizon. */
2156 /* if (split_horizon == rip_split_horizon) */
2157 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
) {
2159 * We perform split horizon for RIP and
2161 * For rip routes, we want to suppress the route
2163 * end up sending the route back on the
2165 * learned it from, with a higher metric. For
2167 * we suppress the route if the prefix is a
2169 * source address that we are going to use for
2171 * (in order to handle the case when multiple
2173 * configured on the same interface).
2176 struct rip_info
*tmp_rinfo
= NULL
;
2177 struct connected
*tmp_ifc
= NULL
;
2179 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2181 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2182 && tmp_rinfo
->nh
.ifindex
2183 == ifc
->ifp
->ifindex
) {
2189 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2190 for (ALL_LIST_ELEMENTS_RO(
2191 ifc
->ifp
->connected
,
2195 tmp_ifc
->address
)) {
2205 /* Preparation for route-map. */
2206 rinfo
->metric_set
= 0;
2207 rinfo
->nexthop_out
.s_addr
= 0;
2208 rinfo
->metric_out
= rinfo
->metric
;
2209 rinfo
->tag_out
= rinfo
->tag
;
2210 rinfo
->ifindex_out
= ifc
->ifp
->ifindex
;
2212 /* In order to avoid some local loops,
2213 * if the RIP route has a nexthop via this interface,
2215 * otherwise set it to 0. The nexthop should not be
2217 * beyond the local broadcast/multicast area in order
2218 * to avoid an IGP multi-level recursive look-up.
2221 if (rinfo
->nh
.ifindex
== ifc
->ifp
->ifindex
)
2222 rinfo
->nexthop_out
= rinfo
->nh
.gate
.ipv4
;
2224 /* Interface route-map */
2225 if (ri
->routemap
[RIP_FILTER_OUT
]) {
2226 ret
= route_map_apply(
2227 ri
->routemap
[RIP_FILTER_OUT
],
2228 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2230 if (ret
== RMAP_DENYMATCH
) {
2231 if (IS_RIP_DEBUG_PACKET
)
2233 "RIP %s/%d is filtered by route-map out",
2234 inet_ntoa(p
->prefix
),
2240 /* Apply redistribute route map - continue, if deny */
2241 if (rip
->redist
[rinfo
->type
].route_map
.name
2242 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2243 ret
= route_map_apply(
2244 rip
->redist
[rinfo
->type
].route_map
.map
,
2245 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2247 if (ret
== RMAP_DENYMATCH
) {
2248 if (IS_RIP_DEBUG_PACKET
)
2250 "%s/%d is filtered by route-map",
2251 inet_ntoa(p
->prefix
),
2257 /* When route-map does not set metric. */
2258 if (!rinfo
->metric_set
) {
2259 /* If redistribute metric is set. */
2260 if (rip
->redist
[rinfo
->type
].metric_config
2261 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
2263 rip
->redist
[rinfo
->type
].metric
;
2265 /* If the route is not connected or
2267 one, use default-metric value*/
2268 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2270 != ZEBRA_ROUTE_CONNECT
2272 != RIP_METRIC_INFINITY
)
2274 rip
->default_metric
;
2278 /* Apply offset-list */
2279 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2280 rip_offset_list_apply_out(p
, ifc
->ifp
,
2281 &rinfo
->metric_out
);
2283 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2284 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2286 /* Perform split-horizon with poisoned reverse
2287 * for RIP and connected routes.
2289 if (ri
->split_horizon
2290 == RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2292 * We perform split horizon for RIP and
2294 * For rip routes, we want to suppress the route
2296 * end up sending the route back on the
2298 * learned it from, with a higher metric. For
2300 * we suppress the route if the prefix is a
2302 * source address that we are going to use for
2304 * (in order to handle the case when multiple
2306 * configured on the same interface).
2308 struct rip_info
*tmp_rinfo
= NULL
;
2309 struct connected
*tmp_ifc
= NULL
;
2311 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2313 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2314 && tmp_rinfo
->nh
.ifindex
2315 == ifc
->ifp
->ifindex
)
2317 RIP_METRIC_INFINITY
;
2319 if (rinfo
->metric_out
!= RIP_METRIC_INFINITY
2320 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2321 for (ALL_LIST_ELEMENTS_RO(
2322 ifc
->ifp
->connected
,
2326 tmp_ifc
->address
)) {
2328 RIP_METRIC_INFINITY
;
2334 /* Prepare preamble, auth headers, if needs be */
2336 stream_putc(s
, RIP_RESPONSE
);
2337 stream_putc(s
, version
);
2340 /* auth header for !v1 && !no_auth */
2341 if ((ri
->auth_type
!= RIP_NO_AUTH
)
2342 && (version
!= RIPv1
))
2343 doff
= rip_auth_header_write(
2344 s
, ri
, key
, auth_str
,
2345 RIP_AUTH_SIMPLE_SIZE
);
2348 /* Write RTE to the stream. */
2349 num
= rip_write_rte(num
, s
, p
, version
, rinfo
);
2350 if (num
== rtemax
) {
2351 if (version
== RIPv2
2352 && ri
->auth_type
== RIP_AUTH_MD5
)
2353 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2354 RIP_AUTH_SIMPLE_SIZE
);
2356 ret
= rip_send_packet(STREAM_DATA(s
),
2357 stream_get_endp(s
), to
,
2360 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2361 rip_packet_dump((struct rip_packet
*)
2370 /* Flush unwritten RTE. */
2372 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2373 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2374 RIP_AUTH_SIMPLE_SIZE
);
2376 ret
= rip_send_packet(STREAM_DATA(s
), stream_get_endp(s
), to
,
2379 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2380 rip_packet_dump((struct rip_packet
*)STREAM_DATA(s
),
2381 stream_get_endp(s
), "SEND");
2385 /* Statistics updates. */
2389 /* Send RIP packet to the interface. */
2390 static void rip_update_interface(struct connected
*ifc
, uint8_t version
,
2393 struct interface
*ifp
= ifc
->ifp
;
2394 struct rip_interface
*ri
= ifp
->info
;
2395 struct sockaddr_in to
;
2397 /* When RIP version is 2 and multicast enable interface. */
2398 if (version
== RIPv2
&& !ri
->v2_broadcast
&& if_is_multicast(ifp
)) {
2399 if (IS_RIP_DEBUG_EVENT
)
2400 zlog_debug("multicast announce on %s ", ifp
->name
);
2402 rip_output_process(ifc
, NULL
, route_type
, version
);
2406 /* If we can't send multicast packet, send it with unicast. */
2407 if (if_is_broadcast(ifp
) || if_is_pointopoint(ifp
)) {
2408 if (ifc
->address
->family
== AF_INET
) {
2409 /* Destination address and port setting. */
2410 memset(&to
, 0, sizeof(struct sockaddr_in
));
2411 if (ifc
->destination
)
2412 /* use specified broadcast or peer destination
2414 to
.sin_addr
= ifc
->destination
->u
.prefix4
;
2415 else if (ifc
->address
->prefixlen
< IPV4_MAX_PREFIXLEN
)
2416 /* calculate the appropriate broadcast address
2418 to
.sin_addr
.s_addr
= ipv4_broadcast_addr(
2419 ifc
->address
->u
.prefix4
.s_addr
,
2420 ifc
->address
->prefixlen
);
2422 /* do not know where to send the packet */
2424 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2426 if (IS_RIP_DEBUG_EVENT
)
2427 zlog_debug("%s announce to %s on %s",
2428 CONNECTED_PEER(ifc
) ? "unicast"
2430 inet_ntoa(to
.sin_addr
), ifp
->name
);
2432 rip_output_process(ifc
, &to
, route_type
, version
);
2437 /* Update send to all interface and neighbor. */
2438 static void rip_update_process(struct rip
*rip
, int route_type
)
2440 struct listnode
*ifnode
, *ifnnode
;
2441 struct connected
*connected
;
2442 struct interface
*ifp
;
2443 struct rip_interface
*ri
;
2444 struct route_node
*rp
;
2445 struct sockaddr_in to
;
2448 /* Send RIP update to each interface. */
2449 FOR_ALL_INTERFACES (rip
->vrf
, ifp
) {
2450 if (if_is_loopback(ifp
))
2453 if (!if_is_operative(ifp
))
2456 /* Fetch RIP interface information. */
2459 /* When passive interface is specified, suppress announce to the
2466 * If there is no version configuration in the
2468 * use rip's version setting.
2470 int vsend
= ((ri
->ri_send
== RI_RIP_UNSPEC
)
2474 if (IS_RIP_DEBUG_EVENT
)
2475 zlog_debug("SEND UPDATE to %s ifindex %d",
2476 ifp
->name
, ifp
->ifindex
);
2478 /* send update on each connected network */
2479 for (ALL_LIST_ELEMENTS(ifp
->connected
, ifnode
, ifnnode
,
2481 if (connected
->address
->family
== AF_INET
) {
2483 rip_update_interface(
2487 && if_is_multicast(ifp
))
2488 rip_update_interface(
2496 /* RIP send updates to each neighbor. */
2497 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
2498 if (rp
->info
!= NULL
) {
2501 connected
= if_lookup_address(&p
->u
.prefix4
, AF_INET
,
2505 "Neighbor %s doesn't have connected interface!",
2506 inet_ntoa(p
->u
.prefix4
));
2510 /* Set destination address and port */
2511 memset(&to
, 0, sizeof(struct sockaddr_in
));
2512 to
.sin_addr
= p
->u
.prefix4
;
2513 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2515 /* RIP version is rip's configuration. */
2516 rip_output_process(connected
, &to
, route_type
,
2521 /* RIP's periodical timer. */
2522 static int rip_update(struct thread
*t
)
2524 struct rip
*rip
= THREAD_ARG(t
);
2526 /* Clear timer pointer. */
2527 rip
->t_update
= NULL
;
2529 if (IS_RIP_DEBUG_EVENT
)
2530 zlog_debug("update timer fire!");
2532 /* Process update output. */
2533 rip_update_process(rip
, rip_all_route
);
2535 /* Triggered updates may be suppressed if a regular update is due by
2536 the time the triggered update would be sent. */
2537 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2540 /* Register myself. */
2541 rip_event(rip
, RIP_UPDATE_EVENT
, 0);
2546 /* Walk down the RIP routing table then clear changed flag. */
2547 static void rip_clear_changed_flag(struct rip
*rip
)
2549 struct route_node
*rp
;
2550 struct rip_info
*rinfo
= NULL
;
2551 struct list
*list
= NULL
;
2552 struct listnode
*listnode
= NULL
;
2554 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2555 if ((list
= rp
->info
) != NULL
)
2556 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
2557 UNSET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2558 /* This flag can be set only on the first entry.
2564 /* Triggered update interval timer. */
2565 static int rip_triggered_interval(struct thread
*t
)
2567 struct rip
*rip
= THREAD_ARG(t
);
2569 rip
->t_triggered_interval
= NULL
;
2573 rip_triggered_update(t
);
2578 /* Execute triggered update. */
2579 static int rip_triggered_update(struct thread
*t
)
2581 struct rip
*rip
= THREAD_ARG(t
);
2584 /* Clear thred pointer. */
2585 rip
->t_triggered_update
= NULL
;
2587 /* Cancel interval timer. */
2588 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2591 /* Logging triggered update. */
2592 if (IS_RIP_DEBUG_EVENT
)
2593 zlog_debug("triggered update!");
2595 /* Split Horizon processing is done when generating triggered
2596 updates as well as normal updates (see section 2.6). */
2597 rip_update_process(rip
, rip_changed_route
);
2599 /* Once all of the triggered updates have been generated, the route
2600 change flags should be cleared. */
2601 rip_clear_changed_flag(rip
);
2603 /* After a triggered update is sent, a timer should be set for a
2604 random interval between 1 and 5 seconds. If other changes that
2605 would trigger updates occur before the timer expires, a single
2606 update is triggered when the timer expires. */
2607 interval
= (random() % 5) + 1;
2609 rip
->t_triggered_interval
= NULL
;
2610 thread_add_timer(master
, rip_triggered_interval
, rip
, interval
,
2611 &rip
->t_triggered_interval
);
2616 /* Withdraw redistributed route. */
2617 void rip_redistribute_withdraw(struct rip
*rip
, int type
)
2619 struct route_node
*rp
;
2620 struct rip_info
*rinfo
= NULL
;
2621 struct list
*list
= NULL
;
2623 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2624 if ((list
= rp
->info
) != NULL
) {
2625 rinfo
= listgetdata(listhead(list
));
2626 if (rinfo
->type
== type
2627 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2628 /* Perform poisoned reverse. */
2629 rinfo
->metric
= RIP_METRIC_INFINITY
;
2630 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
2631 rip_garbage_collect
,
2633 RIP_TIMER_OFF(rinfo
->t_timeout
);
2634 rinfo
->flags
|= RIP_RTF_CHANGED
;
2636 if (IS_RIP_DEBUG_EVENT
) {
2637 struct prefix_ipv4
*p
=
2638 (struct prefix_ipv4
*)&rp
->p
;
2641 "Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2642 inet_ntoa(p
->prefix
),
2649 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
2654 struct rip
*rip_lookup_by_vrf_id(vrf_id_t vrf_id
)
2658 vrf
= vrf_lookup_by_id(vrf_id
);
2665 struct rip
*rip_lookup_by_vrf_name(const char *vrf_name
)
2669 rip
.vrf_name
= (char *)vrf_name
;
2671 return RB_FIND(rip_instance_head
, &rip_instances
, &rip
);
2674 /* Create new RIP instance and set it to global variable. */
2675 struct rip
*rip_create(const char *vrf_name
, struct vrf
*vrf
, int socket
)
2679 rip
= XCALLOC(MTYPE_RIP
, sizeof(struct rip
));
2680 rip
->vrf_name
= XSTRDUP(MTYPE_RIP_VRF_NAME
, vrf_name
);
2682 /* Set initial value. */
2683 rip
->ecmp
= yang_get_default_bool("%s/allow-ecmp", RIP_INSTANCE
);
2684 rip
->default_metric
=
2685 yang_get_default_uint8("%s/default-metric", RIP_INSTANCE
);
2687 yang_get_default_uint8("%s/distance/default", RIP_INSTANCE
);
2688 rip
->passive_default
=
2689 yang_get_default_bool("%s/passive-default", RIP_INSTANCE
);
2690 rip
->garbage_time
= yang_get_default_uint32("%s/timers/flush-interval",
2692 rip
->timeout_time
= yang_get_default_uint32(
2693 "%s/timers/holddown-interval", RIP_INSTANCE
);
2694 rip
->update_time
= yang_get_default_uint32("%s/timers/update-interval",
2697 yang_get_default_enum("%s/version/send", RIP_INSTANCE
);
2699 yang_get_default_enum("%s/version/receive", RIP_INSTANCE
);
2701 /* Initialize RIP data structures. */
2702 rip
->table
= route_table_init();
2703 route_table_set_info(rip
->table
, rip
);
2704 rip
->neighbor
= route_table_init();
2705 rip
->peer_list
= list_new();
2706 rip
->peer_list
->cmp
= (int (*)(void *, void *))rip_peer_list_cmp
;
2707 rip
->peer_list
->del
= rip_peer_list_del
;
2708 rip
->distance_table
= route_table_init();
2709 rip
->distance_table
->cleanup
= rip_distance_table_node_cleanup
;
2710 rip
->enable_interface
= vector_init(1);
2711 rip
->enable_network
= route_table_init();
2712 rip
->passive_nondefault
= vector_init(1);
2713 rip
->offset_list_master
= list_new();
2714 rip
->offset_list_master
->cmp
= (int (*)(void *, void *))offset_list_cmp
;
2715 rip
->offset_list_master
->del
= (void (*)(void *))offset_list_free
;
2717 /* Distribute list install. */
2718 rip
->distribute_ctx
= distribute_list_ctx_create(vrf
);
2719 distribute_list_add_hook(rip
->distribute_ctx
, rip_distribute_update
);
2720 distribute_list_delete_hook(rip
->distribute_ctx
, rip_distribute_update
);
2722 /* if rmap install. */
2723 rip
->if_rmap_ctx
= if_rmap_ctx_create(vrf_name
);
2724 if_rmap_hook_add(rip
->if_rmap_ctx
, rip_if_rmap_update
);
2725 if_rmap_hook_delete(rip
->if_rmap_ctx
, rip_if_rmap_update
);
2727 /* Make output stream. */
2728 rip
->obuf
= stream_new(1500);
2730 /* Enable the routing instance if possible. */
2731 if (vrf
&& vrf_is_enabled(vrf
))
2732 rip_instance_enable(rip
, vrf
, socket
);
2738 RB_INSERT(rip_instance_head
, &rip_instances
, rip
);
2743 /* Sned RIP request to the destination. */
2744 int rip_request_send(struct sockaddr_in
*to
, struct interface
*ifp
,
2745 uint8_t version
, struct connected
*connected
)
2748 struct rip_packet rip_packet
;
2749 struct listnode
*node
, *nnode
;
2751 memset(&rip_packet
, 0, sizeof(rip_packet
));
2753 rip_packet
.command
= RIP_REQUEST
;
2754 rip_packet
.version
= version
;
2755 rte
= rip_packet
.rte
;
2756 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
2760 * connected is only sent for ripv1 case, or when
2761 * interface does not support multicast. Caller loops
2762 * over each connected address for this case.
2764 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2766 != sizeof(rip_packet
))
2769 return sizeof(rip_packet
);
2772 /* send request on each connected network */
2773 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, connected
)) {
2774 struct prefix_ipv4
*p
;
2776 p
= (struct prefix_ipv4
*)connected
->address
;
2778 if (p
->family
!= AF_INET
)
2781 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2783 != sizeof(rip_packet
))
2786 return sizeof(rip_packet
);
2789 static int rip_update_jitter(unsigned long time
)
2791 #define JITTER_BOUND 4
2792 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2793 Given that, we cannot let time be less than JITTER_BOUND seconds.
2794 The RIPv2 RFC says jitter should be small compared to
2795 update_time. We consider 1/JITTER_BOUND to be small.
2798 int jitter_input
= time
;
2801 if (jitter_input
< JITTER_BOUND
)
2802 jitter_input
= JITTER_BOUND
;
2804 jitter
= (((random() % ((jitter_input
* 2) + 1)) - jitter_input
));
2806 return jitter
/ JITTER_BOUND
;
2809 void rip_event(struct rip
*rip
, enum rip_event event
, int sock
)
2816 thread_add_read(master
, rip_read
, rip
, sock
, &rip
->t_read
);
2818 case RIP_UPDATE_EVENT
:
2819 RIP_TIMER_OFF(rip
->t_update
);
2820 jitter
= rip_update_jitter(rip
->update_time
);
2821 thread_add_timer(master
, rip_update
, rip
,
2822 sock
? 2 : rip
->update_time
+ jitter
,
2825 case RIP_TRIGGERED_UPDATE
:
2826 if (rip
->t_triggered_interval
)
2829 thread_add_event(master
, rip_triggered_update
, rip
, 0,
2830 &rip
->t_triggered_update
);
2839 rip_update_default_metric (void)
2841 struct route_node
*np
;
2842 struct rip_info
*rinfo
= NULL
;
2843 struct list
*list
= NULL
;
2844 struct listnode
*listnode
= NULL
;
2846 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
2847 if ((list
= np
->info
) != NULL
)
2848 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
2849 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
2850 rinfo
->metric
= rip
->default_metric
;
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 sprintf(buf
, "%s/%d", inet_ntoa(rn
->p
.u
.prefix4
),
2934 vty_out(vty
, " %-20s %4d %s\n", buf
,
2935 rdistance
->distance
,
2936 rdistance
->access_list
? rdistance
->access_list
2941 /* Update ECMP routes to zebra when ECMP is disabled. */
2942 void rip_ecmp_disable(struct rip
*rip
)
2944 struct route_node
*rp
;
2945 struct rip_info
*rinfo
, *tmp_rinfo
;
2947 struct listnode
*node
, *nextnode
;
2949 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2950 if ((list
= rp
->info
) != NULL
&& listcount(list
) > 1) {
2951 rinfo
= listgetdata(listhead(list
));
2952 if (!rip_route_rte(rinfo
))
2955 /* Drop all other entries, except the first one. */
2956 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
2957 if (tmp_rinfo
!= rinfo
) {
2958 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
2960 tmp_rinfo
->t_garbage_collect
);
2961 list_delete_node(list
, node
);
2962 rip_info_free(tmp_rinfo
);
2966 rip_zebra_ipv4_add(rip
, rp
);
2968 /* Set the route change flag. */
2969 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2971 /* Signal the output process to trigger an update. */
2972 rip_event(rip
, RIP_TRIGGERED_UPDATE
, 0);
2976 /* Print out routes update time. */
2977 static void rip_vty_out_uptime(struct vty
*vty
, struct rip_info
*rinfo
)
2982 char timebuf
[TIME_BUF
];
2983 struct thread
*thread
;
2985 if ((thread
= rinfo
->t_timeout
) != NULL
) {
2986 clock
= thread_timer_remain_second(thread
);
2987 tm
= gmtime(&clock
);
2988 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
2989 vty_out(vty
, "%5s", timebuf
);
2990 } else if ((thread
= rinfo
->t_garbage_collect
) != NULL
) {
2991 clock
= thread_timer_remain_second(thread
);
2992 tm
= gmtime(&clock
);
2993 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
2994 vty_out(vty
, "%5s", timebuf
);
2998 static const char *rip_route_type_print(int sub_type
)
3003 case RIP_ROUTE_STATIC
:
3005 case RIP_ROUTE_DEFAULT
:
3007 case RIP_ROUTE_REDISTRIBUTE
:
3009 case RIP_ROUTE_INTERFACE
:
3018 "show ip rip [vrf NAME]",
3025 struct route_node
*np
;
3026 struct rip_info
*rinfo
= NULL
;
3027 struct list
*list
= NULL
;
3028 struct listnode
*listnode
= NULL
;
3029 const char *vrf_name
;
3032 if (argv_find(argv
, argc
, "vrf", &idx
))
3033 vrf_name
= argv
[idx
+ 1]->arg
;
3035 vrf_name
= VRF_DEFAULT_NAME
;
3037 rip
= rip_lookup_by_vrf_name(vrf_name
);
3039 vty_out(vty
, "%% RIP instance not found\n");
3042 if (!rip
->enabled
) {
3043 vty_out(vty
, "%% RIP instance is disabled\n");
3048 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
3050 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
3051 " (i) - interface\n\n"
3052 " Network Next Hop Metric From Tag Time\n");
3054 for (np
= route_top(rip
->table
); np
; np
= route_next(np
))
3055 if ((list
= np
->info
) != NULL
)
3056 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3060 vty
, "%c(%s) %s/%d",
3061 /* np->lock, For debugging. */
3062 zebra_route_char(rinfo
->type
),
3063 rip_route_type_print(rinfo
->sub_type
),
3064 inet_ntoa(np
->p
.u
.prefix4
),
3070 vty_out(vty
, "%*s", len
, " ");
3072 switch (rinfo
->nh
.type
) {
3073 case NEXTHOP_TYPE_IPV4
:
3074 case NEXTHOP_TYPE_IPV4_IFINDEX
:
3075 vty_out(vty
, "%-20s %2d ",
3076 inet_ntoa(rinfo
->nh
.gate
.ipv4
),
3079 case NEXTHOP_TYPE_IFINDEX
:
3084 case NEXTHOP_TYPE_BLACKHOLE
:
3089 case NEXTHOP_TYPE_IPV6
:
3090 case NEXTHOP_TYPE_IPV6_IFINDEX
:
3092 "V6 Address Hidden %2d ",
3097 /* Route which exist in kernel routing table. */
3098 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
)
3099 && (rinfo
->sub_type
== RIP_ROUTE_RTE
)) {
3100 vty_out(vty
, "%-15s ",
3101 inet_ntoa(rinfo
->from
));
3102 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3103 (route_tag_t
)rinfo
->tag
);
3104 rip_vty_out_uptime(vty
, rinfo
);
3105 } else if (rinfo
->metric
3106 == RIP_METRIC_INFINITY
) {
3107 vty_out(vty
, "self ");
3108 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3109 (route_tag_t
)rinfo
->tag
);
3110 rip_vty_out_uptime(vty
, rinfo
);
3112 if (rinfo
->external_metric
) {
3114 vty
, "self (%s:%d)",
3117 rinfo
->external_metric
);
3120 vty_out(vty
, "%*s", len
,
3125 vty_out(vty
, "%3" ROUTE_TAG_PRI
,
3126 (route_tag_t
)rinfo
->tag
);
3134 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3135 DEFUN (show_ip_rip_status
,
3136 show_ip_rip_status_cmd
,
3137 "show ip rip [vrf NAME] status",
3142 "IP routing protocol process parameters and statistics\n")
3145 struct interface
*ifp
;
3146 struct rip_interface
*ri
;
3147 extern const struct message ri_version_msg
[];
3148 const char *send_version
;
3149 const char *receive_version
;
3150 const char *vrf_name
;
3153 if (argv_find(argv
, argc
, "vrf", &idx
))
3154 vrf_name
= argv
[idx
+ 1]->arg
;
3156 vrf_name
= VRF_DEFAULT_NAME
;
3158 rip
= rip_lookup_by_vrf_name(vrf_name
);
3160 vty_out(vty
, "%% RIP instance not found\n");
3163 if (!rip
->enabled
) {
3164 vty_out(vty
, "%% RIP instance is disabled\n");
3168 vty_out(vty
, "Routing Protocol is \"rip\"\n");
3169 vty_out(vty
, " Sending updates every %u seconds with +/-50%%,",
3171 vty_out(vty
, " next due in %lu seconds\n",
3172 thread_timer_remain_second(rip
->t_update
));
3173 vty_out(vty
, " Timeout after %u seconds,", rip
->timeout_time
);
3174 vty_out(vty
, " garbage collect after %u seconds\n", rip
->garbage_time
);
3176 /* Filtering status show. */
3177 config_show_distribute(vty
, rip
->distribute_ctx
);
3179 /* Default metric information. */
3180 vty_out(vty
, " Default redistribution metric is %u\n",
3181 rip
->default_metric
);
3183 /* Redistribute information. */
3184 vty_out(vty
, " Redistributing:");
3185 rip_show_redistribute_config(vty
, rip
);
3188 vty_out(vty
, " Default version control: send version %s,",
3189 lookup_msg(ri_version_msg
, rip
->version_send
, NULL
));
3190 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3191 vty_out(vty
, " receive any version \n");
3193 vty_out(vty
, " receive version %s \n",
3194 lookup_msg(ri_version_msg
, rip
->version_recv
, NULL
));
3196 vty_out(vty
, " Interface Send Recv Key-chain\n");
3198 FOR_ALL_INTERFACES (rip
->vrf
, ifp
) {
3204 if (ri
->enable_network
|| ri
->enable_interface
) {
3205 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3207 lookup_msg(ri_version_msg
,
3208 rip
->version_send
, NULL
);
3210 send_version
= lookup_msg(ri_version_msg
,
3213 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3215 lookup_msg(ri_version_msg
,
3216 rip
->version_recv
, NULL
);
3218 receive_version
= lookup_msg(
3219 ri_version_msg
, ri
->ri_receive
, NULL
);
3221 vty_out(vty
, " %-17s%-3s %-3s %s\n", ifp
->name
,
3222 send_version
, receive_version
,
3223 ri
->key_chain
? ri
->key_chain
: "");
3227 vty_out(vty
, " Routing for Networks:\n");
3228 rip_show_network_config(vty
, rip
);
3231 int found_passive
= 0;
3232 FOR_ALL_INTERFACES (rip
->vrf
, ifp
) {
3235 if ((ri
->enable_network
|| ri
->enable_interface
)
3237 if (!found_passive
) {
3239 " Passive Interface(s):\n");
3242 vty_out(vty
, " %s\n", ifp
->name
);
3247 vty_out(vty
, " Routing Information Sources:\n");
3249 " Gateway BadPackets BadRoutes Distance Last Update\n");
3250 rip_peer_display(vty
, rip
);
3252 rip_distance_show(vty
, rip
);
3257 /* RIP configuration write function. */
3258 static int config_write_rip(struct vty
*vty
)
3263 RB_FOREACH(rip
, rip_instance_head
, &rip_instances
) {
3264 char xpath
[XPATH_MAXLEN
];
3265 struct lyd_node
*dnode
;
3267 snprintf(xpath
, sizeof(xpath
),
3268 "/frr-ripd:ripd/instance[vrf='%s']", rip
->vrf_name
);
3270 dnode
= yang_dnode_get(running_config
->dnode
, xpath
);
3273 nb_cli_show_dnode_cmds(vty
, dnode
, false);
3275 /* Distribute configuration. */
3276 config_write_distribute(vty
, rip
->distribute_ctx
);
3278 /* Interface routemap configuration */
3279 config_write_if_rmap(vty
, rip
->if_rmap_ctx
);
3287 /* RIP node structure. */
3288 static struct cmd_node rip_node
= {RIP_NODE
, "%s(config-router)# ", 1};
3290 /* Distribute-list update functions. */
3291 static void rip_distribute_update(struct distribute_ctx
*ctx
,
3292 struct distribute
*dist
)
3294 struct interface
*ifp
;
3295 struct rip_interface
*ri
;
3296 struct access_list
*alist
;
3297 struct prefix_list
*plist
;
3299 if (!ctx
->vrf
|| !dist
->ifname
)
3302 ifp
= if_lookup_by_name(dist
->ifname
, ctx
->vrf
);
3308 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
3309 alist
= access_list_lookup(AFI_IP
,
3310 dist
->list
[DISTRIBUTE_V4_IN
]);
3312 ri
->list
[RIP_FILTER_IN
] = alist
;
3314 ri
->list
[RIP_FILTER_IN
] = NULL
;
3316 ri
->list
[RIP_FILTER_IN
] = NULL
;
3318 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
3319 alist
= access_list_lookup(AFI_IP
,
3320 dist
->list
[DISTRIBUTE_V4_OUT
]);
3322 ri
->list
[RIP_FILTER_OUT
] = alist
;
3324 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3326 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3328 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
3329 plist
= prefix_list_lookup(AFI_IP
,
3330 dist
->prefix
[DISTRIBUTE_V4_IN
]);
3332 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3334 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3336 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3338 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
3339 plist
= prefix_list_lookup(AFI_IP
,
3340 dist
->prefix
[DISTRIBUTE_V4_OUT
]);
3342 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3344 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3346 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3349 void rip_distribute_update_interface(struct interface
*ifp
)
3351 struct rip_interface
*ri
= ifp
->info
;
3352 struct rip
*rip
= ri
->rip
;
3353 struct distribute
*dist
;
3357 dist
= distribute_lookup(rip
->distribute_ctx
, ifp
->name
);
3359 rip_distribute_update(rip
->distribute_ctx
, dist
);
3362 /* Update all interface's distribute list. */
3364 static void rip_distribute_update_all(struct prefix_list
*notused
)
3366 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3367 struct interface
*ifp
;
3369 FOR_ALL_INTERFACES (vrf
, ifp
)
3370 rip_distribute_update_interface(ifp
);
3373 static void rip_distribute_update_all_wrapper(struct access_list
*notused
)
3375 rip_distribute_update_all(NULL
);
3378 /* Delete all added rip route. */
3379 void rip_clean(struct rip
*rip
)
3382 rip_instance_disable(rip
);
3384 stream_free(rip
->obuf
);
3386 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3387 if (rip
->redist
[i
].route_map
.name
)
3388 free(rip
->redist
[i
].route_map
.name
);
3390 route_table_finish(rip
->table
);
3391 route_table_finish(rip
->neighbor
);
3392 list_delete(&rip
->peer_list
);
3393 distribute_list_delete(&rip
->distribute_ctx
);
3394 if_rmap_ctx_delete(rip
->if_rmap_ctx
);
3396 rip_clean_network(rip
);
3397 rip_passive_nondefault_clean(rip
);
3398 vector_free(rip
->enable_interface
);
3399 route_table_finish(rip
->enable_network
);
3400 vector_free(rip
->passive_nondefault
);
3401 list_delete(&rip
->offset_list_master
);
3402 rip_interfaces_clean(rip
);
3403 route_table_finish(rip
->distance_table
);
3405 RB_REMOVE(rip_instance_head
, &rip_instances
, rip
);
3406 XFREE(MTYPE_RIP_VRF_NAME
, rip
->vrf_name
);
3407 XFREE(MTYPE_RIP
, rip
);
3410 static void rip_if_rmap_update(struct if_rmap_ctx
*ctx
,
3411 struct if_rmap
*if_rmap
)
3413 struct interface
*ifp
= NULL
;
3414 struct rip_interface
*ri
;
3415 struct route_map
*rmap
;
3416 struct vrf
*vrf
= NULL
;
3419 vrf
= vrf_lookup_by_name(ctx
->name
);
3421 ifp
= if_lookup_by_name(if_rmap
->ifname
, vrf
);
3426 if (if_rmap
->routemap
[IF_RMAP_IN
]) {
3427 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_IN
]);
3429 ri
->routemap
[IF_RMAP_IN
] = rmap
;
3431 ri
->routemap
[IF_RMAP_IN
] = NULL
;
3433 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
3435 if (if_rmap
->routemap
[IF_RMAP_OUT
]) {
3436 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_OUT
]);
3438 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
3440 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
3442 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
3445 void rip_if_rmap_update_interface(struct interface
*ifp
)
3447 struct rip_interface
*ri
= ifp
->info
;
3448 struct rip
*rip
= ri
->rip
;
3449 struct if_rmap
*if_rmap
;
3450 struct if_rmap_ctx
*ctx
;
3454 if (ifp
->vrf
&& ifp
->vrf
->vrf_id
== VRF_UNKNOWN
)
3456 ctx
= rip
->if_rmap_ctx
;
3459 if_rmap
= if_rmap_lookup(ctx
, ifp
->name
);
3461 rip_if_rmap_update(ctx
, if_rmap
);
3464 static void rip_routemap_update_redistribute(struct rip
*rip
)
3466 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3467 if (rip
->redist
[i
].route_map
.name
) {
3468 rip
->redist
[i
].route_map
.map
= route_map_lookup_by_name(
3469 rip
->redist
[i
].route_map
.name
);
3470 route_map_counter_increment(
3471 rip
->redist
[i
].route_map
.map
);
3477 static void rip_routemap_update(const char *notused
)
3479 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3481 struct interface
*ifp
;
3483 FOR_ALL_INTERFACES (vrf
, ifp
)
3484 rip_if_rmap_update_interface(ifp
);
3488 rip_routemap_update_redistribute(rip
);
3491 /* Link RIP instance to VRF. */
3492 static void rip_vrf_link(struct rip
*rip
, struct vrf
*vrf
)
3494 struct interface
*ifp
;
3497 rip
->distribute_ctx
->vrf
= vrf
;
3500 FOR_ALL_INTERFACES (vrf
, ifp
)
3501 rip_interface_sync(ifp
);
3504 /* Unlink RIP instance from VRF. */
3505 static void rip_vrf_unlink(struct rip
*rip
, struct vrf
*vrf
)
3507 struct interface
*ifp
;
3510 rip
->distribute_ctx
->vrf
= NULL
;
3513 FOR_ALL_INTERFACES (vrf
, ifp
)
3514 rip_interface_sync(ifp
);
3517 static void rip_instance_enable(struct rip
*rip
, struct vrf
*vrf
, int sock
)
3521 rip_vrf_link(rip
, vrf
);
3522 rip
->enabled
= true;
3524 /* Resend all redistribute requests. */
3525 rip_redistribute_enable(rip
);
3527 /* Create read and timer thread. */
3528 rip_event(rip
, RIP_READ
, rip
->sock
);
3529 rip_event(rip
, RIP_UPDATE_EVENT
, 1);
3531 rip_zebra_vrf_register(vrf
);
3534 static void rip_instance_disable(struct rip
*rip
)
3536 struct vrf
*vrf
= rip
->vrf
;
3537 struct route_node
*rp
;
3539 /* Clear RIP routes */
3540 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
)) {
3541 struct rip_info
*rinfo
;
3543 struct listnode
*listnode
;
3545 if ((list
= rp
->info
) == NULL
)
3548 rinfo
= listgetdata(listhead(list
));
3549 if (rip_route_rte(rinfo
))
3550 rip_zebra_ipv4_delete(rip
, rp
);
3552 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3553 RIP_TIMER_OFF(rinfo
->t_timeout
);
3554 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
3555 rip_info_free(rinfo
);
3559 route_unlock_node(rp
);
3562 /* Flush all redistribute requests. */
3563 rip_redistribute_disable(rip
);
3565 /* Cancel RIP related timers. */
3566 RIP_TIMER_OFF(rip
->t_update
);
3567 RIP_TIMER_OFF(rip
->t_triggered_update
);
3568 RIP_TIMER_OFF(rip
->t_triggered_interval
);
3570 /* Cancel read thread. */
3571 THREAD_READ_OFF(rip
->t_read
);
3573 /* Close RIP socket. */
3577 /* Clear existing peers. */
3578 list_delete_all_node(rip
->peer_list
);
3580 rip_zebra_vrf_deregister(vrf
);
3582 rip_vrf_unlink(rip
, vrf
);
3583 rip
->enabled
= false;
3586 static int rip_vrf_new(struct vrf
*vrf
)
3588 if (IS_RIP_DEBUG_EVENT
)
3589 zlog_debug("%s: VRF created: %s(%u)", __func__
, vrf
->name
,
3595 static int rip_vrf_delete(struct vrf
*vrf
)
3597 if (IS_RIP_DEBUG_EVENT
)
3598 zlog_debug("%s: VRF deleted: %s(%u)", __func__
, vrf
->name
,
3604 static int rip_vrf_enable(struct vrf
*vrf
)
3609 rip
= rip_lookup_by_vrf_name(vrf
->name
);
3610 if (!rip
|| rip
->enabled
)
3613 if (IS_RIP_DEBUG_EVENT
)
3614 zlog_debug("%s: VRF %s(%u) enabled", __func__
, vrf
->name
,
3617 /* Activate the VRF RIP instance. */
3618 if (!rip
->enabled
) {
3619 socket
= rip_create_socket(vrf
);
3623 rip_instance_enable(rip
, vrf
, socket
);
3629 static int rip_vrf_disable(struct vrf
*vrf
)
3633 rip
= rip_lookup_by_vrf_name(vrf
->name
);
3634 if (!rip
|| !rip
->enabled
)
3637 if (IS_RIP_DEBUG_EVENT
)
3638 zlog_debug("%s: VRF %s(%u) disabled", __func__
, vrf
->name
,
3641 /* Deactivate the VRF RIP instance. */
3643 rip_instance_disable(rip
);
3648 void rip_vrf_init(void)
3650 vrf_init(rip_vrf_new
, rip_vrf_enable
, rip_vrf_disable
, rip_vrf_delete
,
3654 void rip_vrf_terminate(void)
3659 /* Allocate new rip structure and set default value. */
3662 /* Install top nodes. */
3663 install_node(&rip_node
, config_write_rip
);
3665 /* Install rip commands. */
3666 install_element(VIEW_NODE
, &show_ip_rip_cmd
);
3667 install_element(VIEW_NODE
, &show_ip_rip_status_cmd
);
3669 install_default(RIP_NODE
);
3671 /* Debug related init. */
3674 /* Access list install. */
3676 access_list_add_hook(rip_distribute_update_all_wrapper
);
3677 access_list_delete_hook(rip_distribute_update_all_wrapper
);
3679 /* Prefix list initialize.*/
3681 prefix_list_add_hook(rip_distribute_update_all
);
3682 prefix_list_delete_hook(rip_distribute_update_all
);
3684 /* Distribute list install. */
3685 distribute_list_init(RIP_NODE
);
3688 rip_route_map_init();
3690 route_map_add_hook(rip_routemap_update
);
3691 route_map_delete_hook(rip_routemap_update
);
3693 if_rmap_init(RIP_NODE
);