1 /* RIP version 1 and 2.
2 * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
3 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro <kunihiro@zebra.org>
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "sockunion.h"
39 #include "distribute.h"
43 #include "lib_errors.h"
44 #include "northbound_cli.h"
46 #include "ripd/ripd.h"
47 #include "ripd/rip_debug.h"
48 #include "ripd/rip_errors.h"
50 /* UDP receive buffer size */
51 #define RIP_UDP_RCV_BUF 41600
54 struct rip
*rip
= NULL
;
56 /* RIP neighbor address table. */
57 struct route_table
*rip_neighbor_table
;
59 /* RIP route changes. */
60 long rip_global_route_changes
= 0;
63 long rip_global_queries
= 0;
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);
71 static void rip_distribute_update(struct distribute_ctx
*ctx
,
72 struct distribute
*dist
);
74 static void rip_if_rmap_update(struct if_rmap_ctx
*ctx
,
75 struct if_rmap
*if_rmap
);
77 /* RIP output routes type. */
78 enum { rip_all_route
, rip_changed_route
};
80 /* RIP command strings. */
81 static const struct message rip_msg
[] = {{RIP_REQUEST
, "REQUEST"},
82 {RIP_RESPONSE
, "RESPONSE"},
83 {RIP_TRACEON
, "TRACEON"},
84 {RIP_TRACEOFF
, "TRACEOFF"},
86 {RIP_POLL_ENTRY
, "POLL ENTRY"},
89 /* Utility function to set boradcast option to the socket. */
90 static int sockopt_broadcast(int sock
)
95 ret
= setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, (char *)&on
,
98 zlog_warn("can't set sockopt SO_BROADCAST to socket %d", sock
);
104 int rip_route_rte(struct rip_info
*rinfo
)
106 return (rinfo
->type
== ZEBRA_ROUTE_RIP
107 && rinfo
->sub_type
== RIP_ROUTE_RTE
);
110 static struct rip_info
*rip_info_new(void)
112 return XCALLOC(MTYPE_RIP_INFO
, sizeof(struct rip_info
));
115 void rip_info_free(struct rip_info
*rinfo
)
117 XFREE(MTYPE_RIP_INFO
, rinfo
);
120 /* RIP route garbage collect timer. */
121 static int rip_garbage_collect(struct thread
*t
)
123 struct rip_info
*rinfo
;
124 struct route_node
*rp
;
126 rinfo
= THREAD_ARG(t
);
127 rinfo
->t_garbage_collect
= NULL
;
129 /* Off timeout timer. */
130 RIP_TIMER_OFF(rinfo
->t_timeout
);
132 /* Get route_node pointer. */
135 /* Unlock route_node. */
136 listnode_delete(rp
->info
, rinfo
);
137 if (list_isempty((struct list
*)rp
->info
)) {
138 list_delete((struct list
**)&rp
->info
);
139 route_unlock_node(rp
);
142 /* Free RIP routing information. */
143 rip_info_free(rinfo
);
148 static void rip_timeout_update(struct rip_info
*rinfo
);
150 /* Add new route to the ECMP list.
151 * RETURN: the new entry added in the list, or NULL if it is not the first
152 * entry and ECMP is not allowed.
154 struct rip_info
*rip_ecmp_add(struct rip_info
*rinfo_new
)
156 struct route_node
*rp
= rinfo_new
->rp
;
157 struct rip_info
*rinfo
= NULL
;
158 struct list
*list
= NULL
;
160 if (rp
->info
== NULL
)
161 rp
->info
= list_new();
162 list
= (struct list
*)rp
->info
;
164 /* If ECMP is not allowed and some entry already exists in the list,
166 if (listcount(list
) && !rip
->ecmp
)
169 rinfo
= rip_info_new();
170 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
171 listnode_add(list
, rinfo
);
173 if (rip_route_rte(rinfo
)) {
174 rip_timeout_update(rinfo
);
175 rip_zebra_ipv4_add(rp
);
178 /* Set the route change flag on the first entry. */
179 rinfo
= listgetdata(listhead(list
));
180 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
182 /* Signal the output process to trigger an update (see section 2.5). */
183 rip_event(RIP_TRIGGERED_UPDATE
, 0);
188 /* Replace the ECMP list with the new route.
189 * RETURN: the new entry added in the list
191 struct rip_info
*rip_ecmp_replace(struct rip_info
*rinfo_new
)
193 struct route_node
*rp
= rinfo_new
->rp
;
194 struct list
*list
= (struct list
*)rp
->info
;
195 struct rip_info
*rinfo
= NULL
, *tmp_rinfo
= NULL
;
196 struct listnode
*node
= NULL
, *nextnode
= NULL
;
198 if (list
== NULL
|| listcount(list
) == 0)
199 return rip_ecmp_add(rinfo_new
);
201 /* Get the first entry */
202 rinfo
= listgetdata(listhead(list
));
204 /* Learnt route replaced by a local one. Delete it from zebra. */
205 if (rip_route_rte(rinfo
) && !rip_route_rte(rinfo_new
))
206 if (CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
207 rip_zebra_ipv4_delete(rp
);
209 /* Re-use the first entry, and delete the others. */
210 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
211 if (tmp_rinfo
!= rinfo
) {
212 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
213 RIP_TIMER_OFF(tmp_rinfo
->t_garbage_collect
);
214 list_delete_node(list
, node
);
215 rip_info_free(tmp_rinfo
);
218 RIP_TIMER_OFF(rinfo
->t_timeout
);
219 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
220 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
222 if (rip_route_rte(rinfo
)) {
223 rip_timeout_update(rinfo
);
224 /* The ADD message implies an update. */
225 rip_zebra_ipv4_add(rp
);
228 /* Set the route change flag. */
229 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
231 /* Signal the output process to trigger an update (see section 2.5). */
232 rip_event(RIP_TRIGGERED_UPDATE
, 0);
237 /* Delete one route from the ECMP list.
239 * null - the entry is freed, and other entries exist in the list
240 * the entry - the entry is the last one in the list; its metric is set
241 * to INFINITY, and the garbage collector is started for it
243 struct rip_info
*rip_ecmp_delete(struct rip_info
*rinfo
)
245 struct route_node
*rp
= rinfo
->rp
;
246 struct list
*list
= (struct list
*)rp
->info
;
248 RIP_TIMER_OFF(rinfo
->t_timeout
);
250 if (listcount(list
) > 1) {
251 /* Some other ECMP entries still exist. Just delete this entry.
253 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
254 listnode_delete(list
, rinfo
);
255 if (rip_route_rte(rinfo
)
256 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
257 /* The ADD message implies the update. */
258 rip_zebra_ipv4_add(rp
);
259 rip_info_free(rinfo
);
262 assert(rinfo
== listgetdata(listhead(list
)));
264 /* This is the only entry left in the list. We must keep it in
265 * the list for garbage collection time, with INFINITY metric.
268 rinfo
->metric
= RIP_METRIC_INFINITY
;
269 RIP_TIMER_ON(rinfo
->t_garbage_collect
, rip_garbage_collect
,
272 if (rip_route_rte(rinfo
)
273 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
274 rip_zebra_ipv4_delete(rp
);
277 /* Set the route change flag on the first entry. */
278 rinfo
= listgetdata(listhead(list
));
279 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
281 /* Signal the output process to trigger an update (see section 2.5). */
282 rip_event(RIP_TRIGGERED_UPDATE
, 0);
287 /* Timeout RIP routes. */
288 static int rip_timeout(struct thread
*t
)
290 rip_ecmp_delete((struct rip_info
*)THREAD_ARG(t
));
294 static void rip_timeout_update(struct rip_info
*rinfo
)
296 if (rinfo
->metric
!= RIP_METRIC_INFINITY
) {
297 RIP_TIMER_OFF(rinfo
->t_timeout
);
298 RIP_TIMER_ON(rinfo
->t_timeout
, rip_timeout
, rip
->timeout_time
);
302 static int rip_filter(int rip_distribute
, struct prefix_ipv4
*p
,
303 struct rip_interface
*ri
)
305 struct distribute
*dist
;
306 struct access_list
*alist
;
307 struct prefix_list
*plist
;
308 int distribute
= rip_distribute
== RIP_FILTER_OUT
? DISTRIBUTE_V4_OUT
310 const char *inout
= rip_distribute
== RIP_FILTER_OUT
? "out" : "in";
312 /* Input distribute-list filtering. */
313 if (ri
->list
[rip_distribute
]) {
314 if (access_list_apply(ri
->list
[rip_distribute
],
317 if (IS_RIP_DEBUG_PACKET
)
318 zlog_debug("%s/%d filtered by distribute %s",
319 inet_ntoa(p
->prefix
), p
->prefixlen
,
324 if (ri
->prefix
[rip_distribute
]) {
325 if (prefix_list_apply(ri
->prefix
[rip_distribute
],
328 if (IS_RIP_DEBUG_PACKET
)
329 zlog_debug("%s/%d filtered by prefix-list %s",
330 inet_ntoa(p
->prefix
), p
->prefixlen
,
336 /* All interface filter check. */
337 dist
= distribute_lookup(rip
->distribute_ctx
, NULL
);
339 if (dist
->list
[distribute
]) {
340 alist
= access_list_lookup(AFI_IP
,
341 dist
->list
[distribute
]);
344 if (access_list_apply(alist
, (struct prefix
*)p
)
346 if (IS_RIP_DEBUG_PACKET
)
348 "%s/%d filtered by distribute %s",
349 inet_ntoa(p
->prefix
),
350 p
->prefixlen
, inout
);
355 if (dist
->prefix
[distribute
]) {
356 plist
= prefix_list_lookup(AFI_IP
,
357 dist
->prefix
[distribute
]);
360 if (prefix_list_apply(plist
, (struct prefix
*)p
)
362 if (IS_RIP_DEBUG_PACKET
)
364 "%s/%d filtered by prefix-list %s",
365 inet_ntoa(p
->prefix
),
366 p
->prefixlen
, inout
);
375 /* Check nexthop address validity. */
376 static int rip_nexthop_check(struct in_addr
*addr
)
378 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
379 struct interface
*ifp
;
380 struct listnode
*cnode
;
381 struct connected
*ifc
;
384 /* If nexthop address matches local configured address then it is
387 FOR_ALL_INTERFACES (vrf
, ifp
) {
388 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, ifc
)) {
391 if (p
->family
== AF_INET
392 && IPV4_ADDR_SAME(&p
->u
.prefix4
, addr
))
399 /* RIP add route to routing table. */
400 static void rip_rte_process(struct rte
*rte
, struct sockaddr_in
*from
,
401 struct interface
*ifp
)
404 struct prefix_ipv4 p
;
405 struct route_node
*rp
;
406 struct rip_info
*rinfo
= NULL
, newinfo
;
407 struct rip_interface
*ri
;
408 struct in_addr
*nexthop
;
410 unsigned char old_dist
, new_dist
;
411 struct list
*list
= NULL
;
412 struct listnode
*node
= NULL
;
414 /* Make prefix structure. */
415 memset(&p
, 0, sizeof(struct prefix_ipv4
));
417 p
.prefix
= rte
->prefix
;
418 p
.prefixlen
= ip_masklen(rte
->mask
);
420 /* Make sure mask is applied. */
423 /* Apply input filters. */
426 ret
= rip_filter(RIP_FILTER_IN
, &p
, ri
);
430 memset(&newinfo
, 0, sizeof(newinfo
));
431 newinfo
.type
= ZEBRA_ROUTE_RIP
;
432 newinfo
.sub_type
= RIP_ROUTE_RTE
;
433 newinfo
.nh
.gate
.ipv4
= rte
->nexthop
;
434 newinfo
.from
= from
->sin_addr
;
435 newinfo
.nh
.ifindex
= ifp
->ifindex
;
436 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
437 newinfo
.metric
= rte
->metric
;
438 newinfo
.metric_out
= rte
->metric
; /* XXX */
439 newinfo
.tag
= ntohs(rte
->tag
); /* XXX */
441 /* Modify entry according to the interface routemap. */
442 if (ri
->routemap
[RIP_FILTER_IN
]) {
443 /* The object should be of the type of rip_info */
444 ret
= route_map_apply(ri
->routemap
[RIP_FILTER_IN
],
445 (struct prefix
*)&p
, RMAP_RIP
, &newinfo
);
447 if (ret
== RMAP_DENYMATCH
) {
448 if (IS_RIP_DEBUG_PACKET
)
450 "RIP %s/%d is filtered by route-map in",
451 inet_ntoa(p
.prefix
), p
.prefixlen
);
455 /* Get back the object */
456 rte
->nexthop
= newinfo
.nexthop_out
;
457 rte
->tag
= htons(newinfo
.tag_out
); /* XXX */
458 rte
->metric
= newinfo
.metric_out
; /* XXX: the routemap uses the
462 /* Once the entry has been validated, update the metric by
463 adding the cost of the network on wich the message
464 arrived. If the result is greater than infinity, use infinity
465 (RFC2453 Sec. 3.9.2) */
466 /* Zebra ripd can handle offset-list in. */
467 ret
= rip_offset_list_apply_in(&p
, ifp
, &rte
->metric
);
469 /* If offset-list does not modify the metric use interface's
472 rte
->metric
+= ifp
->metric
? ifp
->metric
: 1;
474 if (rte
->metric
> RIP_METRIC_INFINITY
)
475 rte
->metric
= RIP_METRIC_INFINITY
;
477 /* Set nexthop pointer. */
478 if (rte
->nexthop
.s_addr
== 0)
479 nexthop
= &from
->sin_addr
;
481 nexthop
= &rte
->nexthop
;
483 /* Check if nexthop address is myself, then do nothing. */
484 if (rip_nexthop_check(nexthop
) < 0) {
485 if (IS_RIP_DEBUG_PACKET
)
486 zlog_debug("Nexthop address %s is myself",
487 inet_ntoa(*nexthop
));
491 /* Get index for the prefix. */
492 rp
= route_node_get(rip
->table
, (struct prefix
*)&p
);
495 newinfo
.nh
.gate
.ipv4
= *nexthop
;
496 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4
;
497 newinfo
.metric
= rte
->metric
;
498 newinfo
.tag
= ntohs(rte
->tag
);
499 newinfo
.distance
= rip_distance_apply(&newinfo
);
501 new_dist
= newinfo
.distance
? newinfo
.distance
502 : ZEBRA_RIP_DISTANCE_DEFAULT
;
504 /* Check to see whether there is already RIP route on the table. */
505 if ((list
= rp
->info
) != NULL
)
506 for (ALL_LIST_ELEMENTS_RO(list
, node
, rinfo
)) {
507 /* Need to compare with redistributed entry or local
509 if (!rip_route_rte(rinfo
))
512 if (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
513 && IPV4_ADDR_SAME(&rinfo
->nh
.gate
.ipv4
, nexthop
))
516 if (!listnextnode(node
)) {
517 /* Not found in the list */
519 if (rte
->metric
> rinfo
->metric
) {
520 /* New route has a greater metric.
522 route_unlock_node(rp
);
526 if (rte
->metric
< rinfo
->metric
)
527 /* New route has a smaller metric.
528 * Replace the ECMP list
529 * with the new one in below. */
532 /* Metrics are same. We compare the distances.
534 old_dist
= rinfo
->distance
536 : ZEBRA_RIP_DISTANCE_DEFAULT
;
538 if (new_dist
> old_dist
) {
539 /* New route has a greater distance.
541 route_unlock_node(rp
);
545 if (new_dist
< old_dist
)
546 /* New route has a smaller distance.
547 * Replace the ECMP list
548 * with the new one in below. */
551 /* Metrics and distances are both same. Keep
553 * the new route is added in the ECMP list in
559 /* Local static route. */
560 if (rinfo
->type
== ZEBRA_ROUTE_RIP
561 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
562 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))
563 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
564 route_unlock_node(rp
);
568 /* Redistributed route check. */
569 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
570 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
571 old_dist
= rinfo
->distance
;
572 /* Only routes directly connected to an interface
574 * may have a valid NULL distance */
575 if (rinfo
->nh
.gate
.ipv4
.s_addr
!= 0)
578 : ZEBRA_RIP_DISTANCE_DEFAULT
;
579 /* If imported route does not have STRICT precedence,
580 mark it as a ghost */
581 if (new_dist
<= old_dist
582 && rte
->metric
!= RIP_METRIC_INFINITY
)
583 rip_ecmp_replace(&newinfo
);
585 route_unlock_node(rp
);
592 route_unlock_node(rp
);
594 /* Now, check to see whether there is already an explicit route
595 for the destination prefix. If there is no such route, add
596 this route to the routing table, unless the metric is
597 infinity (there is no point in adding a route which
599 if (rte
->metric
!= RIP_METRIC_INFINITY
)
600 rip_ecmp_add(&newinfo
);
602 /* Route is there but we are not sure the route is RIP or not.
605 /* If there is an existing route, compare the next hop address
606 to the address of the router from which the datagram came.
607 If this datagram is from the same router as the existing
608 route, reinitialize the timeout. */
609 same
= (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
610 && (rinfo
->nh
.ifindex
== ifp
->ifindex
));
612 old_dist
= rinfo
->distance
? rinfo
->distance
613 : ZEBRA_RIP_DISTANCE_DEFAULT
;
615 /* Next, compare the metrics. If the datagram is from the same
616 router as the existing route, and the new metric is different
617 than the old one; or, if the new metric is lower than the old
618 one, or if the tag has been changed; or if there is a route
619 with a lower administrave distance; or an update of the
620 distance on the actual route; do the following actions: */
621 if ((same
&& rinfo
->metric
!= rte
->metric
)
622 || (rte
->metric
< rinfo
->metric
)
623 || ((same
) && (rinfo
->metric
== rte
->metric
)
624 && (newinfo
.tag
!= rinfo
->tag
))
625 || (old_dist
> new_dist
)
626 || ((old_dist
!= new_dist
) && same
)) {
627 if (listcount(list
) == 1) {
628 if (newinfo
.metric
!= RIP_METRIC_INFINITY
)
629 rip_ecmp_replace(&newinfo
);
631 rip_ecmp_delete(rinfo
);
633 if (newinfo
.metric
< rinfo
->metric
)
634 rip_ecmp_replace(&newinfo
);
635 else if (newinfo
.metric
> rinfo
->metric
)
636 rip_ecmp_delete(rinfo
);
637 else if (new_dist
< old_dist
)
638 rip_ecmp_replace(&newinfo
);
639 else if (new_dist
> old_dist
)
640 rip_ecmp_delete(rinfo
);
642 int update
= CHECK_FLAG(rinfo
->flags
,
647 assert(newinfo
.metric
648 != RIP_METRIC_INFINITY
);
650 RIP_TIMER_OFF(rinfo
->t_timeout
);
651 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
652 memcpy(rinfo
, &newinfo
,
653 sizeof(struct rip_info
));
654 rip_timeout_update(rinfo
);
657 rip_zebra_ipv4_add(rp
);
659 /* - Set the route change flag on the
661 rinfo
= listgetdata(listhead(list
));
662 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
663 rip_event(RIP_TRIGGERED_UPDATE
, 0);
666 } else /* same & no change */
667 rip_timeout_update(rinfo
);
669 /* Unlock tempolary lock of the route. */
670 route_unlock_node(rp
);
674 /* Dump RIP packet */
675 static void rip_packet_dump(struct rip_packet
*packet
, int size
,
680 const char *command_str
;
681 char pbuf
[BUFSIZ
], nbuf
[BUFSIZ
];
685 /* Set command string. */
686 if (packet
->command
> 0 && packet
->command
< RIP_COMMAND_MAX
)
687 command_str
= lookup_msg(rip_msg
, packet
->command
, NULL
);
689 command_str
= "unknown";
691 /* Dump packet header. */
692 zlog_debug("%s %s version %d packet size %d", sndrcv
, command_str
,
693 packet
->version
, size
);
695 /* Dump each routing table entry. */
698 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
699 if (packet
->version
== RIPv2
) {
700 netmask
= ip_masklen(rte
->mask
);
702 if (rte
->family
== htons(RIP_FAMILY_AUTH
)) {
704 == htons(RIP_AUTH_SIMPLE_PASSWORD
)) {
705 p
= (uint8_t *)&rte
->prefix
;
708 " family 0x%X type %d auth string: %s",
711 } else if (rte
->tag
== htons(RIP_AUTH_MD5
)) {
712 struct rip_md5_info
*md5
;
714 md5
= (struct rip_md5_info
*)&packet
718 " family 0x%X type %d (MD5 authentication)",
722 " RIP-2 packet len %d Key ID %d"
724 ntohs(md5
->packet_len
),
725 md5
->keyid
, md5
->auth_len
);
726 zlog_debug(" Sequence Number %ld",
727 (unsigned long)ntohl(
729 } else if (rte
->tag
== htons(RIP_AUTH_DATA
)) {
730 p
= (uint8_t *)&rte
->prefix
;
733 " family 0x%X type %d (MD5 data)",
737 " MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
738 "%02X%02X%02X%02X%02X%02X%02X%02X",
739 p
[0], p
[1], p
[2], p
[3], p
[4],
740 p
[5], p
[6], p
[7], p
[8], p
[9],
741 p
[10], p
[11], p
[12], p
[13],
745 " family 0x%X type %d (Unknown auth type)",
751 " %s/%d -> %s family %d tag %" ROUTE_TAG_PRI
753 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
,
756 inet_ntop(AF_INET
, &rte
->nexthop
, nbuf
,
759 (route_tag_t
)ntohs(rte
->tag
),
760 (unsigned long)ntohl(rte
->metric
));
763 " %s family %d tag %" ROUTE_TAG_PRI
765 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
767 (route_tag_t
)ntohs(rte
->tag
),
768 (unsigned long)ntohl(rte
->metric
));
773 /* Check if the destination address is valid (unicast; not net 0
774 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
775 check net 0 because we accept default route. */
776 static int rip_destination_check(struct in_addr addr
)
778 uint32_t destination
;
780 /* Convert to host byte order. */
781 destination
= ntohl(addr
.s_addr
);
783 if (IPV4_NET127(destination
))
786 /* Net 0 may match to the default route. */
787 if (IPV4_NET0(destination
) && destination
!= 0)
790 /* Unicast address must belong to class A, B, C. */
791 if (IN_CLASSA(destination
))
793 if (IN_CLASSB(destination
))
795 if (IN_CLASSC(destination
))
801 /* RIP version 2 authentication. */
802 static int rip_auth_simple_password(struct rte
*rte
, struct sockaddr_in
*from
,
803 struct interface
*ifp
)
805 struct rip_interface
*ri
;
806 char *auth_str
= (char *)rte
+ offsetof(struct rte
, prefix
);
809 /* reject passwords with zeros in the middle of the string */
810 for (i
= strnlen(auth_str
, 16); i
< 16; i
++) {
811 if (auth_str
[i
] != '\0')
815 if (IS_RIP_DEBUG_EVENT
)
816 zlog_debug("RIPv2 simple password authentication from %s",
817 inet_ntoa(from
->sin_addr
));
821 if (ri
->auth_type
!= RIP_AUTH_SIMPLE_PASSWORD
822 || rte
->tag
!= htons(RIP_AUTH_SIMPLE_PASSWORD
))
825 /* Simple password authentication. */
827 if (strncmp(auth_str
, ri
->auth_str
, 16) == 0)
831 struct keychain
*keychain
;
834 keychain
= keychain_lookup(ri
->key_chain
);
835 if (keychain
== NULL
|| keychain
->key
== NULL
)
838 key
= key_match_for_accept(keychain
, auth_str
);
845 /* RIP version 2 authentication with MD5. */
846 static int rip_auth_md5(struct rip_packet
*packet
, struct sockaddr_in
*from
,
847 int length
, struct interface
*ifp
)
849 struct rip_interface
*ri
;
850 struct rip_md5_info
*md5
;
851 struct rip_md5_data
*md5data
;
852 struct keychain
*keychain
;
855 uint8_t digest
[RIP_AUTH_MD5_SIZE
];
857 char auth_str
[RIP_AUTH_MD5_SIZE
] = {};
859 if (IS_RIP_DEBUG_EVENT
)
860 zlog_debug("RIPv2 MD5 authentication from %s",
861 inet_ntoa(from
->sin_addr
));
864 md5
= (struct rip_md5_info
*)&packet
->rte
;
866 /* Check auth type. */
867 if (ri
->auth_type
!= RIP_AUTH_MD5
|| md5
->type
!= htons(RIP_AUTH_MD5
))
870 /* If the authentication length is less than 16, then it must be wrong
872 * any interpretation of rfc2082. Some implementations also interpret
873 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka
874 * RIP_AUTH_MD5_COMPAT_SIZE.
876 if (!((md5
->auth_len
== RIP_AUTH_MD5_SIZE
)
877 || (md5
->auth_len
== RIP_AUTH_MD5_COMPAT_SIZE
))) {
878 if (IS_RIP_DEBUG_EVENT
)
880 "RIPv2 MD5 authentication, strange authentication "
886 /* grab and verify check packet length */
887 packet_len
= ntohs(md5
->packet_len
);
889 if (packet_len
> (length
- RIP_HEADER_SIZE
- RIP_AUTH_MD5_SIZE
)) {
890 if (IS_RIP_DEBUG_EVENT
)
892 "RIPv2 MD5 authentication, packet length field %d "
893 "greater than received length %d!",
894 md5
->packet_len
, length
);
898 /* retrieve authentication data */
899 md5data
= (struct rip_md5_data
*)(((uint8_t *)packet
) + packet_len
);
902 keychain
= keychain_lookup(ri
->key_chain
);
903 if (keychain
== NULL
)
906 key
= key_lookup_for_accept(keychain
, md5
->keyid
);
907 if (key
== NULL
|| key
->string
== NULL
)
910 strlcpy(auth_str
, key
->string
, sizeof(auth_str
));
911 } else if (ri
->auth_str
)
912 strlcpy(auth_str
, ri
->auth_str
, sizeof(auth_str
));
914 if (auth_str
[0] == 0)
917 /* MD5 digest authentication. */
918 memset(&ctx
, 0, sizeof(ctx
));
920 MD5Update(&ctx
, packet
, packet_len
+ RIP_HEADER_SIZE
);
921 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
922 MD5Final(digest
, &ctx
);
924 if (memcmp(md5data
->digest
, digest
, RIP_AUTH_MD5_SIZE
) == 0)
930 /* Pick correct auth string for sends, prepare auth_str buffer for use.
931 * (left justified and padded).
933 * presumes one of ri or key is valid, and that the auth strings they point
934 * to are nul terminated. If neither are present, auth_str will be fully
938 static void rip_auth_prepare_str_send(struct rip_interface
*ri
, struct key
*key
,
939 char *auth_str
, int len
)
943 memset(auth_str
, 0, len
);
944 if (key
&& key
->string
)
945 strlcpy(auth_str
, key
->string
, len
);
946 else if (ri
->auth_str
)
947 strlcpy(auth_str
, ri
->auth_str
, len
);
952 /* Write RIPv2 simple password authentication information
954 * auth_str is presumed to be 2 bytes and correctly prepared
955 * (left justified and zero padded).
957 static void rip_auth_simple_write(struct stream
*s
, char *auth_str
, int len
)
959 assert(s
&& len
== RIP_AUTH_SIMPLE_SIZE
);
961 stream_putw(s
, RIP_FAMILY_AUTH
);
962 stream_putw(s
, RIP_AUTH_SIMPLE_PASSWORD
);
963 stream_put(s
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
968 /* write RIPv2 MD5 "authentication header"
969 * (uses the auth key data field)
971 * Digest offset field is set to 0.
973 * returns: offset of the digest offset field, which must be set when
974 * length to the auth-data MD5 digest is known.
976 static size_t rip_auth_md5_ah_write(struct stream
*s
, struct rip_interface
*ri
,
981 assert(s
&& ri
&& ri
->auth_type
== RIP_AUTH_MD5
);
983 /* MD5 authentication. */
984 stream_putw(s
, RIP_FAMILY_AUTH
);
985 stream_putw(s
, RIP_AUTH_MD5
);
987 /* MD5 AH digest offset field.
989 * Set to placeholder value here, to true value when RIP-2 Packet length
990 * is known. Actual value is set in .....().
992 doff
= stream_get_endp(s
);
997 stream_putc(s
, key
->index
% 256);
1001 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
1002 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for
1004 * to be configurable.
1006 stream_putc(s
, ri
->md5_auth_len
);
1008 /* Sequence Number (non-decreasing). */
1009 /* RFC2080: The value used in the sequence number is
1010 arbitrary, but two suggestions are the time of the
1011 message's creation or a simple message counter. */
1012 stream_putl(s
, time(NULL
));
1014 /* Reserved field must be zero. */
1021 /* If authentication is in used, write the appropriate header
1022 * returns stream offset to which length must later be written
1023 * or 0 if this is not required
1025 static size_t rip_auth_header_write(struct stream
*s
, struct rip_interface
*ri
,
1026 struct key
*key
, char *auth_str
, int len
)
1028 assert(ri
->auth_type
!= RIP_NO_AUTH
);
1030 switch (ri
->auth_type
) {
1031 case RIP_AUTH_SIMPLE_PASSWORD
:
1032 rip_auth_prepare_str_send(ri
, key
, auth_str
, len
);
1033 rip_auth_simple_write(s
, auth_str
, len
);
1036 return rip_auth_md5_ah_write(s
, ri
, key
);
1042 /* Write RIPv2 MD5 authentication data trailer */
1043 static void rip_auth_md5_set(struct stream
*s
, struct rip_interface
*ri
,
1044 size_t doff
, char *auth_str
, int authlen
)
1048 unsigned char digest
[RIP_AUTH_MD5_SIZE
];
1050 /* Make it sure this interface is configured as MD5
1052 assert((ri
->auth_type
== RIP_AUTH_MD5
)
1053 && (authlen
== RIP_AUTH_MD5_SIZE
));
1056 /* Get packet length. */
1057 len
= stream_get_endp(s
);
1059 /* Check packet length. */
1060 if (len
< (RIP_HEADER_SIZE
+ RIP_RTE_SIZE
)) {
1063 "rip_auth_md5_set(): packet length %ld is less than minimum length.",
1068 /* Set the digest offset length in the header */
1069 stream_putw_at(s
, doff
, len
);
1071 /* Set authentication data. */
1072 stream_putw(s
, RIP_FAMILY_AUTH
);
1073 stream_putw(s
, RIP_AUTH_DATA
);
1075 /* Generate a digest for the RIP packet. */
1076 memset(&ctx
, 0, sizeof(ctx
));
1078 MD5Update(&ctx
, STREAM_DATA(s
), stream_get_endp(s
));
1079 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1080 MD5Final(digest
, &ctx
);
1082 /* Copy the digest to the packet. */
1083 stream_write(s
, digest
, RIP_AUTH_MD5_SIZE
);
1086 /* RIP routing information. */
1087 static void rip_response_process(struct rip_packet
*packet
, int size
,
1088 struct sockaddr_in
*from
,
1089 struct connected
*ifc
)
1093 struct prefix_ipv4 ifaddr
;
1094 struct prefix_ipv4 ifaddrclass
;
1097 memset(&ifaddr
, 0, sizeof(ifaddr
));
1098 /* We don't know yet. */
1101 /* The Response must be ignored if it is not from the RIP
1102 port. (RFC2453 - Sec. 3.9.2)*/
1103 if (from
->sin_port
!= htons(RIP_PORT_DEFAULT
)) {
1104 zlog_info("response doesn't come from RIP port: %d",
1106 rip_peer_bad_packet(from
);
1110 /* The datagram's IPv4 source address should be checked to see
1111 whether the datagram is from a valid neighbor; the source of the
1112 datagram must be on a directly connected network (RFC2453 - Sec.
1114 if (if_lookup_address((void *)&from
->sin_addr
, AF_INET
, VRF_DEFAULT
)
1117 "This datagram doesn't came from a valid neighbor: %s",
1118 inet_ntoa(from
->sin_addr
));
1119 rip_peer_bad_packet(from
);
1123 /* It is also worth checking to see whether the response is from one
1124 of the router's own addresses. */
1126 ; /* Alredy done in rip_read () */
1128 /* Update RIP peer. */
1129 rip_peer_update(from
, packet
->version
);
1131 /* Set RTE pointer. */
1134 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
1135 /* RIPv2 authentication check. */
1136 /* If the Address Family Identifier of the first (and only the
1137 first) entry in the message is 0xFFFF, then the remainder of
1138 the entry contains the authentication. */
1139 /* If the packet gets here it means authentication enabled */
1140 /* Check is done in rip_read(). So, just skipping it */
1141 if (packet
->version
== RIPv2
&& rte
== packet
->rte
1142 && rte
->family
== htons(RIP_FAMILY_AUTH
))
1145 if (rte
->family
!= htons(AF_INET
)) {
1146 /* Address family check. RIP only supports AF_INET. */
1147 zlog_info("Unsupported family %d from %s.",
1149 inet_ntoa(from
->sin_addr
));
1153 /* - is the destination address valid (e.g., unicast; not net 0
1155 if (!rip_destination_check(rte
->prefix
)) {
1157 "Network is net 0 or net 127 or it is not unicast network");
1158 rip_peer_bad_route(from
);
1162 /* Convert metric value to host byte order. */
1163 rte
->metric
= ntohl(rte
->metric
);
1165 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1166 if (!(rte
->metric
>= 1 && rte
->metric
<= 16)) {
1167 zlog_info("Route's metric is not in the 1-16 range.");
1168 rip_peer_bad_route(from
);
1172 /* RIPv1 does not have nexthop value. */
1173 if (packet
->version
== RIPv1
&& rte
->nexthop
.s_addr
!= 0) {
1174 zlog_info("RIPv1 packet with nexthop value %s",
1175 inet_ntoa(rte
->nexthop
));
1176 rip_peer_bad_route(from
);
1180 /* That is, if the provided information is ignored, a possibly
1181 sub-optimal, but absolutely valid, route may be taken. If
1182 the received Next Hop is not directly reachable, it should be
1183 treated as 0.0.0.0. */
1184 if (packet
->version
== RIPv2
&& rte
->nexthop
.s_addr
!= 0) {
1187 /* Multicast address check. */
1188 addrval
= ntohl(rte
->nexthop
.s_addr
);
1189 if (IN_CLASSD(addrval
)) {
1191 "Nexthop %s is multicast address, skip this rte",
1192 inet_ntoa(rte
->nexthop
));
1196 if (!if_lookup_address((void *)&rte
->nexthop
, AF_INET
,
1198 struct route_node
*rn
;
1199 struct rip_info
*rinfo
;
1201 rn
= route_node_match_ipv4(rip
->table
,
1207 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1210 if (IS_RIP_DEBUG_EVENT
)
1212 "Next hop %s is on RIP network. Set nexthop to the packet's originator",
1215 rte
->nexthop
= rinfo
->from
;
1217 if (IS_RIP_DEBUG_EVENT
)
1219 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1222 rte
->nexthop
.s_addr
= 0;
1225 route_unlock_node(rn
);
1227 if (IS_RIP_DEBUG_EVENT
)
1229 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1232 rte
->nexthop
.s_addr
= 0;
1237 /* For RIPv1, there won't be a valid netmask.
1239 This is a best guess at the masks. If everyone was using old
1240 Ciscos before the 'ip subnet zero' option, it would be almost
1243 Cisco summarize ripv1 advertisements to the classful boundary
1244 (/16 for class B's) except when the RIP packet does to inside
1245 the classful network in question. */
1247 if ((packet
->version
== RIPv1
&& rte
->prefix
.s_addr
!= 0)
1248 || (packet
->version
== RIPv2
1249 && (rte
->prefix
.s_addr
!= 0
1250 && rte
->mask
.s_addr
== 0))) {
1251 uint32_t destination
;
1253 if (subnetted
== -1) {
1254 memcpy(&ifaddr
, ifc
->address
,
1255 sizeof(struct prefix_ipv4
));
1256 memcpy(&ifaddrclass
, &ifaddr
,
1257 sizeof(struct prefix_ipv4
));
1258 apply_classful_mask_ipv4(&ifaddrclass
);
1260 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1264 destination
= ntohl(rte
->prefix
.s_addr
);
1266 if (IN_CLASSA(destination
))
1267 masklen2ip(8, &rte
->mask
);
1268 else if (IN_CLASSB(destination
))
1269 masklen2ip(16, &rte
->mask
);
1270 else if (IN_CLASSC(destination
))
1271 masklen2ip(24, &rte
->mask
);
1274 masklen2ip(ifaddrclass
.prefixlen
,
1275 (struct in_addr
*)&destination
);
1276 if ((subnetted
== 1)
1277 && ((rte
->prefix
.s_addr
& destination
)
1278 == ifaddrclass
.prefix
.s_addr
)) {
1279 masklen2ip(ifaddr
.prefixlen
, &rte
->mask
);
1280 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1281 != rte
->prefix
.s_addr
)
1282 masklen2ip(32, &rte
->mask
);
1283 if (IS_RIP_DEBUG_EVENT
)
1284 zlog_debug("Subnetted route %s",
1285 inet_ntoa(rte
->prefix
));
1287 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1288 != rte
->prefix
.s_addr
)
1292 if (IS_RIP_DEBUG_EVENT
) {
1293 zlog_debug("Resultant route %s",
1294 inet_ntoa(rte
->prefix
));
1295 zlog_debug("Resultant mask %s",
1296 inet_ntoa(rte
->mask
));
1300 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1301 ignore the entry. */
1302 if ((packet
->version
== RIPv2
) && (rte
->mask
.s_addr
!= 0)
1303 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1304 != rte
->prefix
.s_addr
)) {
1306 "RIPv2 address %s is not mask /%d applied one",
1307 inet_ntoa(rte
->prefix
), ip_masklen(rte
->mask
));
1308 rip_peer_bad_route(from
);
1312 /* Default route's netmask is ignored. */
1313 if (packet
->version
== RIPv2
&& (rte
->prefix
.s_addr
== 0)
1314 && (rte
->mask
.s_addr
!= 0)) {
1315 if (IS_RIP_DEBUG_EVENT
)
1317 "Default route with non-zero netmask. Set zero to netmask");
1318 rte
->mask
.s_addr
= 0;
1321 /* Routing table updates. */
1322 rip_rte_process(rte
, from
, ifc
->ifp
);
1326 /* Make socket for RIP protocol. */
1327 int rip_create_socket(void)
1331 struct sockaddr_in addr
;
1333 memset(&addr
, 0, sizeof(struct sockaddr_in
));
1334 addr
.sin_family
= AF_INET
;
1335 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1336 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1337 addr
.sin_len
= sizeof(struct sockaddr_in
);
1338 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1339 /* sending port must always be the RIP port */
1340 addr
.sin_port
= htons(RIP_PORT_DEFAULT
);
1342 /* Make datagram socket. */
1343 sock
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
1345 flog_err_sys(EC_LIB_SOCKET
, "Cannot create UDP socket: %s",
1346 safe_strerror(errno
));
1350 sockopt_broadcast(sock
);
1351 sockopt_reuseaddr(sock
);
1352 sockopt_reuseport(sock
);
1353 setsockopt_ipv4_multicast_loop(sock
, 0);
1355 setsockopt_pktinfo(sock
);
1356 #endif /* RIP_RECVMSG */
1357 #ifdef IPTOS_PREC_INTERNETCONTROL
1358 setsockopt_ipv4_tos(sock
, IPTOS_PREC_INTERNETCONTROL
);
1361 frr_elevate_privs(&ripd_privs
) {
1362 setsockopt_so_recvbuf(sock
, RIP_UDP_RCV_BUF
);
1363 if ((ret
= bind(sock
, (struct sockaddr
*)&addr
, sizeof(addr
)))
1365 zlog_err("%s: Can't bind socket %d to %s port %d: %s",
1366 __func__
, sock
, inet_ntoa(addr
.sin_addr
),
1367 (int)ntohs(addr
.sin_port
),
1368 safe_strerror(errno
));
1378 /* RIP packet send to destination address, on interface denoted by
1379 * by connected argument. NULL to argument denotes destination should be
1380 * should be RIP multicast group
1382 static int rip_send_packet(uint8_t *buf
, int size
, struct sockaddr_in
*to
,
1383 struct connected
*ifc
)
1386 struct sockaddr_in sin
;
1388 assert(ifc
!= NULL
);
1390 if (IS_RIP_DEBUG_PACKET
) {
1391 #define ADDRESS_SIZE 20
1392 char dst
[ADDRESS_SIZE
];
1395 strlcpy(dst
, inet_ntoa(to
->sin_addr
), sizeof(dst
));
1397 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1398 strlcpy(dst
, inet_ntoa(sin
.sin_addr
), sizeof(dst
));
1401 zlog_debug("rip_send_packet %s > %s (%s)",
1402 inet_ntoa(ifc
->address
->u
.prefix4
), dst
,
1406 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
1408 * ZEBRA_IFA_SECONDARY is set on linux when an interface is
1410 * with multiple addresses on the same subnet: the first address
1411 * on the subnet is configured "primary", and all subsequent
1413 * on that subnet are treated as "secondary" addresses.
1414 * In order to avoid routing-table bloat on other rip listeners,
1415 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY
1417 * XXX Since Linux is the only system for which the
1418 * ZEBRA_IFA_SECONDARY
1419 * flag is set, we would end up sending a packet for a
1421 * source address on non-linux systems.
1423 if (IS_RIP_DEBUG_PACKET
)
1424 zlog_debug("duplicate dropped");
1428 /* Make destination address. */
1429 memset(&sin
, 0, sizeof(struct sockaddr_in
));
1430 sin
.sin_family
= AF_INET
;
1431 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1432 sin
.sin_len
= sizeof(struct sockaddr_in
);
1433 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1435 /* When destination is specified, use it's port and address. */
1437 sin
.sin_port
= to
->sin_port
;
1438 sin
.sin_addr
= to
->sin_addr
;
1440 sin
.sin_port
= htons(RIP_PORT_DEFAULT
);
1441 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1443 rip_interface_multicast_set(rip
->sock
, ifc
);
1446 ret
= sendto(rip
->sock
, buf
, size
, 0, (struct sockaddr
*)&sin
,
1447 sizeof(struct sockaddr_in
));
1449 if (IS_RIP_DEBUG_EVENT
)
1450 zlog_debug("SEND to %s.%d", inet_ntoa(sin
.sin_addr
),
1451 ntohs(sin
.sin_port
));
1454 zlog_warn("can't send packet : %s", safe_strerror(errno
));
1459 /* Add redistributed route to RIP table. */
1460 void rip_redistribute_add(int type
, int sub_type
, struct prefix_ipv4
*p
,
1461 struct nexthop
*nh
, unsigned int metric
,
1462 unsigned char distance
, route_tag_t tag
)
1465 struct route_node
*rp
= NULL
;
1466 struct rip_info
*rinfo
= NULL
, newinfo
;
1467 struct list
*list
= NULL
;
1469 /* Redistribute route */
1470 ret
= rip_destination_check(p
->prefix
);
1474 rp
= route_node_get(rip
->table
, (struct prefix
*)p
);
1476 memset(&newinfo
, 0, sizeof(struct rip_info
));
1477 newinfo
.type
= type
;
1478 newinfo
.sub_type
= sub_type
;
1480 newinfo
.external_metric
= metric
;
1481 newinfo
.distance
= distance
;
1482 if (tag
<= UINT16_MAX
) /* RIP only supports 16 bit tags */
1487 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
1488 rinfo
= listgetdata(listhead(list
));
1490 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
1491 && rinfo
->sub_type
== RIP_ROUTE_INTERFACE
1492 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
1493 route_unlock_node(rp
);
1497 /* Manually configured RIP route check. */
1498 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1499 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
1500 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))) {
1501 if (type
!= ZEBRA_ROUTE_RIP
1502 || ((sub_type
!= RIP_ROUTE_STATIC
)
1503 && (sub_type
!= RIP_ROUTE_DEFAULT
))) {
1504 route_unlock_node(rp
);
1509 (void)rip_ecmp_replace(&newinfo
);
1510 route_unlock_node(rp
);
1512 (void)rip_ecmp_add(&newinfo
);
1514 if (IS_RIP_DEBUG_EVENT
) {
1515 zlog_debug("Redistribute new prefix %s/%d",
1516 inet_ntoa(p
->prefix
), p
->prefixlen
);
1519 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1522 /* Delete redistributed route from RIP table. */
1523 void rip_redistribute_delete(int type
, int sub_type
, struct prefix_ipv4
*p
,
1527 struct route_node
*rp
;
1528 struct rip_info
*rinfo
;
1530 ret
= rip_destination_check(p
->prefix
);
1534 rp
= route_node_lookup(rip
->table
, (struct prefix
*)p
);
1536 struct list
*list
= rp
->info
;
1538 if (list
!= NULL
&& listcount(list
) != 0) {
1539 rinfo
= listgetdata(listhead(list
));
1540 if (rinfo
!= NULL
&& rinfo
->type
== type
1541 && rinfo
->sub_type
== sub_type
1542 && rinfo
->nh
.ifindex
== ifindex
) {
1543 /* Perform poisoned reverse. */
1544 rinfo
->metric
= RIP_METRIC_INFINITY
;
1545 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
1546 rip_garbage_collect
,
1548 RIP_TIMER_OFF(rinfo
->t_timeout
);
1549 rinfo
->flags
|= RIP_RTF_CHANGED
;
1551 if (IS_RIP_DEBUG_EVENT
)
1553 "Poison %s/%d on the interface %s with an "
1554 "infinity metric [delete]",
1555 inet_ntoa(p
->prefix
),
1557 ifindex2ifname(ifindex
,
1560 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1563 route_unlock_node(rp
);
1567 /* Response to request called from rip_read ().*/
1568 static void rip_request_process(struct rip_packet
*packet
, int size
,
1569 struct sockaddr_in
*from
, struct connected
*ifc
)
1573 struct prefix_ipv4 p
;
1574 struct route_node
*rp
;
1575 struct rip_info
*rinfo
;
1576 struct rip_interface
*ri
;
1578 /* Does not reponse to the requests on the loopback interfaces */
1579 if (if_is_loopback(ifc
->ifp
))
1582 /* Check RIP process is enabled on this interface. */
1583 ri
= ifc
->ifp
->info
;
1587 /* When passive interface is specified, suppress responses */
1591 /* RIP peer update. */
1592 rip_peer_update(from
, packet
->version
);
1594 lim
= ((caddr_t
)packet
) + size
;
1597 /* The Request is processed entry by entry. If there are no
1598 entries, no response is given. */
1599 if (lim
== (caddr_t
)rte
)
1602 /* There is one special case. If there is exactly one entry in the
1603 request, and it has an address family identifier of zero and a
1604 metric of infinity (i.e., 16), then this is a request to send the
1605 entire routing table. */
1606 if (lim
== ((caddr_t
)(rte
+ 1)) && ntohs(rte
->family
) == 0
1607 && ntohl(rte
->metric
) == RIP_METRIC_INFINITY
) {
1608 /* All route with split horizon */
1609 rip_output_process(ifc
, from
, rip_all_route
, packet
->version
);
1611 if (ntohs(rte
->family
) != AF_INET
)
1614 /* Examine the list of RTEs in the Request one by one. For each
1615 entry, look up the destination in the router's routing
1616 database and, if there is a route, put that route's metric in
1617 the metric field of the RTE. If there is no explicit route
1618 to the specified destination, put infinity in the metric
1619 field. Once all the entries have been filled in, change the
1620 command from Request to Response and send the datagram back
1621 to the requestor. */
1624 for (; ((caddr_t
)rte
) < lim
; rte
++) {
1625 p
.prefix
= rte
->prefix
;
1626 p
.prefixlen
= ip_masklen(rte
->mask
);
1627 apply_mask_ipv4(&p
);
1629 rp
= route_node_lookup(rip
->table
, (struct prefix
*)&p
);
1631 rinfo
= listgetdata(
1632 listhead((struct list
*)rp
->info
));
1633 rte
->metric
= htonl(rinfo
->metric
);
1634 route_unlock_node(rp
);
1636 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
1638 packet
->command
= RIP_RESPONSE
;
1640 (void)rip_send_packet((uint8_t *)packet
, size
, from
, ifc
);
1642 rip_global_queries
++;
1646 /* Set IPv6 packet info to the socket. */
1647 static int setsockopt_pktinfo(int sock
)
1652 ret
= setsockopt(sock
, IPPROTO_IP
, IP_PKTINFO
, &val
, sizeof(val
));
1654 zlog_warn("Can't setsockopt IP_PKTINFO : %s",
1655 safe_strerror(errno
));
1659 /* Read RIP packet by recvmsg function. */
1660 int rip_recvmsg(int sock
, uint8_t *buf
, int size
, struct sockaddr_in
*from
,
1666 struct cmsghdr
*ptr
;
1669 memset(&msg
, 0, sizeof(msg
));
1670 msg
.msg_name
= (void *)from
;
1671 msg
.msg_namelen
= sizeof(struct sockaddr_in
);
1674 msg
.msg_control
= (void *)adata
;
1675 msg
.msg_controllen
= sizeof adata
;
1679 ret
= recvmsg(sock
, &msg
, 0);
1683 for (ptr
= ZCMSG_FIRSTHDR(&msg
); ptr
!= NULL
;
1684 ptr
= CMSG_NXTHDR(&msg
, ptr
))
1685 if (ptr
->cmsg_level
== IPPROTO_IP
1686 && ptr
->cmsg_type
== IP_PKTINFO
) {
1687 struct in_pktinfo
*pktinfo
;
1690 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(ptr
);
1691 i
= pktinfo
->ipi_ifindex
;
1696 /* RIP packet read function. */
1697 int rip_read_new(struct thread
*t
)
1701 char buf
[RIP_PACKET_MAXSIZ
];
1702 struct sockaddr_in from
;
1705 /* Fetch socket then register myself. */
1706 sock
= THREAD_FD(t
);
1707 rip_event(RIP_READ
, sock
);
1709 /* Read RIP packet. */
1710 ret
= rip_recvmsg(sock
, buf
, RIP_PACKET_MAXSIZ
, &from
, (int *)&ifindex
);
1712 zlog_warn("Can't read RIP packet: %s", safe_strerror(errno
));
1718 #endif /* RIP_RECVMSG */
1720 /* First entry point of RIP packet. */
1721 static int rip_read(struct thread
*t
)
1726 union rip_buf rip_buf
;
1727 struct rip_packet
*packet
;
1728 struct sockaddr_in from
;
1732 struct interface
*ifp
= NULL
;
1733 struct connected
*ifc
;
1734 struct rip_interface
*ri
;
1737 /* Fetch socket then register myself. */
1738 sock
= THREAD_FD(t
);
1741 /* Add myself to tne next event */
1742 rip_event(RIP_READ
, sock
);
1744 /* RIPd manages only IPv4. */
1745 memset(&from
, 0, sizeof(struct sockaddr_in
));
1746 fromlen
= sizeof(struct sockaddr_in
);
1748 len
= recvfrom(sock
, (char *)&rip_buf
.buf
, sizeof(rip_buf
.buf
), 0,
1749 (struct sockaddr
*)&from
, &fromlen
);
1751 zlog_info("recvfrom failed: %s", safe_strerror(errno
));
1755 /* Check is this packet comming from myself? */
1756 if (if_check_address(from
.sin_addr
)) {
1757 if (IS_RIP_DEBUG_PACKET
)
1758 zlog_debug("ignore packet comes from myself");
1762 /* Which interface is this packet comes from. */
1763 ifc
= if_lookup_address((void *)&from
.sin_addr
, AF_INET
, VRF_DEFAULT
);
1767 /* RIP packet received */
1768 if (IS_RIP_DEBUG_EVENT
)
1769 zlog_debug("RECV packet from %s port %d on %s",
1770 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1771 ifp
? ifp
->name
: "unknown");
1773 /* If this packet come from unknown interface, ignore it. */
1776 "rip_read: cannot find interface for packet from %s port %d",
1777 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
));
1782 p
.u
.prefix4
= from
.sin_addr
;
1783 p
.prefixlen
= IPV4_MAX_BITLEN
;
1785 ifc
= connected_lookup_prefix(ifp
, &p
);
1789 "rip_read: cannot find connected address for packet from %s "
1790 "port %d on interface %s",
1791 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1796 /* Packet length check. */
1797 if (len
< RIP_PACKET_MINSIZ
) {
1798 zlog_warn("packet size %d is smaller than minimum size %d", len
,
1800 rip_peer_bad_packet(&from
);
1803 if (len
> RIP_PACKET_MAXSIZ
) {
1804 zlog_warn("packet size %d is larger than max size %d", len
,
1806 rip_peer_bad_packet(&from
);
1810 /* Packet alignment check. */
1811 if ((len
- RIP_PACKET_MINSIZ
) % 20) {
1812 zlog_warn("packet size %d is wrong for RIP packet alignment",
1814 rip_peer_bad_packet(&from
);
1818 /* Set RTE number. */
1819 rtenum
= ((len
- RIP_PACKET_MINSIZ
) / 20);
1821 /* For easy to handle. */
1822 packet
= &rip_buf
.rip_packet
;
1824 /* RIP version check. */
1825 if (packet
->version
== 0) {
1826 zlog_info("version 0 with command %d received.",
1828 rip_peer_bad_packet(&from
);
1832 /* Dump RIP packet. */
1833 if (IS_RIP_DEBUG_RECV
)
1834 rip_packet_dump(packet
, len
, "RECV");
1836 /* RIP version adjust. This code should rethink now. RFC1058 says
1837 that "Version 1 implementations are to ignore this extra data and
1838 process only the fields specified in this document.". So RIPv3
1839 packet should be treated as RIPv1 ignoring must be zero field. */
1840 if (packet
->version
> RIPv2
)
1841 packet
->version
= RIPv2
;
1843 /* Is RIP running or is this RIP neighbor ?*/
1845 if (!ri
->running
&& !rip_neighbor_lookup(&from
)) {
1846 if (IS_RIP_DEBUG_EVENT
)
1847 zlog_debug("RIP is not enabled on interface %s.",
1849 rip_peer_bad_packet(&from
);
1853 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1854 vrecv
= ((ri
->ri_receive
== RI_RIP_UNSPEC
) ? rip
->version_recv
1856 if (vrecv
== RI_RIP_VERSION_NONE
1857 || ((packet
->version
== RIPv1
) && !(vrecv
& RIPv1
))
1858 || ((packet
->version
== RIPv2
) && !(vrecv
& RIPv2
))) {
1859 if (IS_RIP_DEBUG_PACKET
)
1861 " packet's v%d doesn't fit to if version spec",
1863 rip_peer_bad_packet(&from
);
1867 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1868 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1869 accepted; authenticated RIP-2 messages shall be discarded. */
1870 if ((ri
->auth_type
== RIP_NO_AUTH
) && rtenum
1871 && (packet
->version
== RIPv2
)
1872 && (packet
->rte
->family
== htons(RIP_FAMILY_AUTH
))) {
1873 if (IS_RIP_DEBUG_EVENT
)
1875 "packet RIPv%d is dropped because authentication disabled",
1877 ripd_notif_send_auth_type_failure(ifp
->name
);
1878 rip_peer_bad_packet(&from
);
1883 If the router is configured to authenticate RIP-2 messages, then
1884 RIP-1 messages and RIP-2 messages which pass authentication
1885 testing shall be accepted; unauthenticated and failed
1886 authentication RIP-2 messages shall be discarded. For maximum
1887 security, RIP-1 messages should be ignored when authentication is
1888 in use (see section 4.1); otherwise, the routing information from
1889 authenticated messages will be propagated by RIP-1 routers in an
1890 unauthenticated manner.
1892 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1893 * always reply regardless of authentication settings, because:
1895 * - if there other authorised routers on-link, the REQUESTor can
1896 * passively obtain the routing updates anyway
1897 * - if there are no other authorised routers on-link, RIP can
1898 * easily be disabled for the link to prevent giving out information
1899 * on state of this routers RIP routing table..
1901 * I.e. if RIPv1 has any place anymore these days, it's as a very
1902 * simple way to distribute routing information (e.g. to embedded
1903 * hosts / appliances) and the ability to give out RIPv1
1904 * routing-information freely, while still requiring RIPv2
1905 * authentication for any RESPONSEs might be vaguely useful.
1907 if (ri
->auth_type
!= RIP_NO_AUTH
&& packet
->version
== RIPv1
) {
1908 /* Discard RIPv1 messages other than REQUESTs */
1909 if (packet
->command
!= RIP_REQUEST
) {
1910 if (IS_RIP_DEBUG_PACKET
)
1913 " dropped because authentication enabled");
1914 ripd_notif_send_auth_type_failure(ifp
->name
);
1915 rip_peer_bad_packet(&from
);
1918 } else if (ri
->auth_type
!= RIP_NO_AUTH
) {
1919 const char *auth_desc
;
1922 /* There definitely is no authentication in the packet.
1924 if (IS_RIP_DEBUG_PACKET
)
1926 "RIPv2 authentication failed: no auth RTE in packet");
1927 ripd_notif_send_auth_type_failure(ifp
->name
);
1928 rip_peer_bad_packet(&from
);
1932 /* First RTE must be an Authentication Family RTE */
1933 if (packet
->rte
->family
!= htons(RIP_FAMILY_AUTH
)) {
1934 if (IS_RIP_DEBUG_PACKET
)
1937 " dropped because authentication enabled");
1938 ripd_notif_send_auth_type_failure(ifp
->name
);
1939 rip_peer_bad_packet(&from
);
1943 /* Check RIPv2 authentication. */
1944 switch (ntohs(packet
->rte
->tag
)) {
1945 case RIP_AUTH_SIMPLE_PASSWORD
:
1946 auth_desc
= "simple";
1947 ret
= rip_auth_simple_password(packet
->rte
, &from
, ifp
);
1952 ret
= rip_auth_md5(packet
, &from
, len
, ifp
);
1953 /* Reset RIP packet length to trim MD5 data. */
1959 auth_desc
= "unknown type";
1960 if (IS_RIP_DEBUG_PACKET
)
1962 "RIPv2 Unknown authentication type %d",
1963 ntohs(packet
->rte
->tag
));
1967 if (IS_RIP_DEBUG_PACKET
)
1968 zlog_debug("RIPv2 %s authentication success",
1971 if (IS_RIP_DEBUG_PACKET
)
1972 zlog_debug("RIPv2 %s authentication failure",
1974 ripd_notif_send_auth_failure(ifp
->name
);
1975 rip_peer_bad_packet(&from
);
1980 /* Process each command. */
1981 switch (packet
->command
) {
1983 rip_response_process(packet
, len
, &from
, ifc
);
1987 rip_request_process(packet
, len
, &from
, ifc
);
1992 "Obsolete command %s received, please sent it to routed",
1993 lookup_msg(rip_msg
, packet
->command
, NULL
));
1994 rip_peer_bad_packet(&from
);
1996 case RIP_POLL_ENTRY
:
1997 zlog_info("Obsolete command %s received",
1998 lookup_msg(rip_msg
, packet
->command
, NULL
));
1999 rip_peer_bad_packet(&from
);
2002 zlog_info("Unknown RIP command %d received", packet
->command
);
2003 rip_peer_bad_packet(&from
);
2010 /* Write routing table entry to the stream and return next index of
2011 the routing table entry in the stream. */
2012 static int rip_write_rte(int num
, struct stream
*s
, struct prefix_ipv4
*p
,
2013 uint8_t version
, struct rip_info
*rinfo
)
2015 struct in_addr mask
;
2017 /* Write routing table entry. */
2018 if (version
== RIPv1
) {
2019 stream_putw(s
, AF_INET
);
2021 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2022 stream_put_ipv4(s
, 0);
2023 stream_put_ipv4(s
, 0);
2024 stream_putl(s
, rinfo
->metric_out
);
2026 masklen2ip(p
->prefixlen
, &mask
);
2028 stream_putw(s
, AF_INET
);
2029 stream_putw(s
, rinfo
->tag_out
);
2030 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2031 stream_put_ipv4(s
, mask
.s_addr
);
2032 stream_put_ipv4(s
, rinfo
->nexthop_out
.s_addr
);
2033 stream_putl(s
, rinfo
->metric_out
);
2039 /* Send update to the ifp or spcified neighbor. */
2040 void rip_output_process(struct connected
*ifc
, struct sockaddr_in
*to
,
2041 int route_type
, uint8_t version
)
2045 struct route_node
*rp
;
2046 struct rip_info
*rinfo
;
2047 struct rip_interface
*ri
;
2048 struct prefix_ipv4
*p
;
2049 struct prefix_ipv4 classfull
;
2050 struct prefix_ipv4 ifaddrclass
;
2051 struct key
*key
= NULL
;
2052 /* this might need to made dynamic if RIP ever supported auth methods
2053 with larger key string sizes */
2054 char auth_str
[RIP_AUTH_SIMPLE_SIZE
];
2055 size_t doff
= 0; /* offset of digest offset field */
2059 struct list
*list
= NULL
;
2060 struct listnode
*listnode
= NULL
;
2062 /* Logging output event. */
2063 if (IS_RIP_DEBUG_EVENT
) {
2065 zlog_debug("update routes to neighbor %s",
2066 inet_ntoa(to
->sin_addr
));
2068 zlog_debug("update routes on interface %s ifindex %d",
2069 ifc
->ifp
->name
, ifc
->ifp
->ifindex
);
2072 /* Set output stream. */
2075 /* Reset stream and RTE counter. */
2077 rtemax
= RIP_MAX_RTE
;
2079 /* Get RIP interface. */
2080 ri
= ifc
->ifp
->info
;
2082 /* If output interface is in simple password authentication mode, we
2083 need space for authentication data. */
2084 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2087 /* If output interface is in MD5 authentication mode, we need space
2088 for authentication header and data. */
2089 if (ri
->auth_type
== RIP_AUTH_MD5
)
2092 /* If output interface is in simple password authentication mode
2093 and string or keychain is specified we need space for auth. data */
2094 if (ri
->auth_type
!= RIP_NO_AUTH
) {
2095 if (ri
->key_chain
) {
2096 struct keychain
*keychain
;
2098 keychain
= keychain_lookup(ri
->key_chain
);
2100 key
= key_lookup_for_send(keychain
);
2102 /* to be passed to auth functions later */
2103 rip_auth_prepare_str_send(ri
, key
, auth_str
, sizeof(auth_str
));
2104 if (strlen(auth_str
) == 0)
2108 if (version
== RIPv1
) {
2109 memcpy(&ifaddrclass
, ifc
->address
, sizeof(struct prefix_ipv4
));
2110 apply_classful_mask_ipv4(&ifaddrclass
);
2112 if (ifc
->address
->prefixlen
> ifaddrclass
.prefixlen
)
2116 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2117 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
2118 rinfo
= listgetdata(listhead(list
));
2119 /* For RIPv1, if we are subnetted, output subnets in our
2121 /* that have the same mask as the output "interface".
2123 /* networks, only the classfull version is output. */
2125 if (version
== RIPv1
) {
2126 p
= (struct prefix_ipv4
*)&rp
->p
;
2128 if (IS_RIP_DEBUG_PACKET
)
2130 "RIPv1 mask check, %s/%d considered for output",
2131 inet_ntoa(rp
->p
.u
.prefix4
),
2136 (struct prefix
*)&ifaddrclass
,
2138 if ((ifc
->address
->prefixlen
2140 && (rp
->p
.prefixlen
!= 32))
2143 memcpy(&classfull
, &rp
->p
,
2144 sizeof(struct prefix_ipv4
));
2145 apply_classful_mask_ipv4(&classfull
);
2146 if (rp
->p
.u
.prefix4
.s_addr
!= 0
2147 && classfull
.prefixlen
2151 if (IS_RIP_DEBUG_PACKET
)
2153 "RIPv1 mask check, %s/%d made it through",
2154 inet_ntoa(rp
->p
.u
.prefix4
),
2157 p
= (struct prefix_ipv4
*)&rp
->p
;
2159 /* Apply output filters. */
2160 ret
= rip_filter(RIP_FILTER_OUT
, p
, ri
);
2164 /* Changed route only output. */
2165 if (route_type
== rip_changed_route
2166 && (!(rinfo
->flags
& RIP_RTF_CHANGED
)))
2169 /* Split horizon. */
2170 /* if (split_horizon == rip_split_horizon) */
2171 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
) {
2173 * We perform split horizon for RIP and
2175 * For rip routes, we want to suppress the route
2177 * end up sending the route back on the
2179 * learned it from, with a higher metric. For
2181 * we suppress the route if the prefix is a
2183 * source address that we are going to use for
2185 * (in order to handle the case when multiple
2187 * configured on the same interface).
2190 struct rip_info
*tmp_rinfo
= NULL
;
2191 struct connected
*tmp_ifc
= NULL
;
2193 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2195 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2196 && tmp_rinfo
->nh
.ifindex
2197 == ifc
->ifp
->ifindex
) {
2203 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2204 for (ALL_LIST_ELEMENTS_RO(
2205 ifc
->ifp
->connected
,
2209 tmp_ifc
->address
)) {
2219 /* Preparation for route-map. */
2220 rinfo
->metric_set
= 0;
2221 rinfo
->nexthop_out
.s_addr
= 0;
2222 rinfo
->metric_out
= rinfo
->metric
;
2223 rinfo
->tag_out
= rinfo
->tag
;
2224 rinfo
->ifindex_out
= ifc
->ifp
->ifindex
;
2226 /* In order to avoid some local loops,
2227 * if the RIP route has a nexthop via this interface,
2229 * otherwise set it to 0. The nexthop should not be
2231 * beyond the local broadcast/multicast area in order
2232 * to avoid an IGP multi-level recursive look-up.
2235 if (rinfo
->nh
.ifindex
== ifc
->ifp
->ifindex
)
2236 rinfo
->nexthop_out
= rinfo
->nh
.gate
.ipv4
;
2238 /* Interface route-map */
2239 if (ri
->routemap
[RIP_FILTER_OUT
]) {
2240 ret
= route_map_apply(
2241 ri
->routemap
[RIP_FILTER_OUT
],
2242 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2244 if (ret
== RMAP_DENYMATCH
) {
2245 if (IS_RIP_DEBUG_PACKET
)
2247 "RIP %s/%d is filtered by route-map out",
2248 inet_ntoa(p
->prefix
),
2254 /* Apply redistribute route map - continue, if deny */
2255 if (rip
->route_map
[rinfo
->type
].name
2256 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2257 ret
= route_map_apply(
2258 rip
->route_map
[rinfo
->type
].map
,
2259 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2261 if (ret
== RMAP_DENYMATCH
) {
2262 if (IS_RIP_DEBUG_PACKET
)
2264 "%s/%d is filtered by route-map",
2265 inet_ntoa(p
->prefix
),
2271 /* When route-map does not set metric. */
2272 if (!rinfo
->metric_set
) {
2273 /* If redistribute metric is set. */
2274 if (rip
->route_map
[rinfo
->type
].metric_config
2275 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
2277 rip
->route_map
[rinfo
->type
]
2280 /* If the route is not connected or
2282 one, use default-metric value*/
2283 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2285 != ZEBRA_ROUTE_CONNECT
2287 != RIP_METRIC_INFINITY
)
2289 rip
->default_metric
;
2293 /* Apply offset-list */
2294 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2295 rip_offset_list_apply_out(p
, ifc
->ifp
,
2296 &rinfo
->metric_out
);
2298 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2299 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2301 /* Perform split-horizon with poisoned reverse
2302 * for RIP and connected routes.
2304 if (ri
->split_horizon
2305 == RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2307 * We perform split horizon for RIP and
2309 * For rip routes, we want to suppress the route
2311 * end up sending the route back on the
2313 * learned it from, with a higher metric. For
2315 * we suppress the route if the prefix is a
2317 * source address that we are going to use for
2319 * (in order to handle the case when multiple
2321 * configured on the same interface).
2323 struct rip_info
*tmp_rinfo
= NULL
;
2324 struct connected
*tmp_ifc
= NULL
;
2326 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2328 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2329 && tmp_rinfo
->nh
.ifindex
2330 == ifc
->ifp
->ifindex
)
2332 RIP_METRIC_INFINITY
;
2334 if (rinfo
->metric_out
!= RIP_METRIC_INFINITY
2335 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2336 for (ALL_LIST_ELEMENTS_RO(
2337 ifc
->ifp
->connected
,
2341 tmp_ifc
->address
)) {
2343 RIP_METRIC_INFINITY
;
2349 /* Prepare preamble, auth headers, if needs be */
2351 stream_putc(s
, RIP_RESPONSE
);
2352 stream_putc(s
, version
);
2355 /* auth header for !v1 && !no_auth */
2356 if ((ri
->auth_type
!= RIP_NO_AUTH
)
2357 && (version
!= RIPv1
))
2358 doff
= rip_auth_header_write(
2359 s
, ri
, key
, auth_str
,
2360 RIP_AUTH_SIMPLE_SIZE
);
2363 /* Write RTE to the stream. */
2364 num
= rip_write_rte(num
, s
, p
, version
, rinfo
);
2365 if (num
== rtemax
) {
2366 if (version
== RIPv2
2367 && ri
->auth_type
== RIP_AUTH_MD5
)
2368 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2369 RIP_AUTH_SIMPLE_SIZE
);
2371 ret
= rip_send_packet(STREAM_DATA(s
),
2372 stream_get_endp(s
), to
,
2375 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2376 rip_packet_dump((struct rip_packet
*)
2385 /* Flush unwritten RTE. */
2387 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2388 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2389 RIP_AUTH_SIMPLE_SIZE
);
2391 ret
= rip_send_packet(STREAM_DATA(s
), stream_get_endp(s
), to
,
2394 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2395 rip_packet_dump((struct rip_packet
*)STREAM_DATA(s
),
2396 stream_get_endp(s
), "SEND");
2400 /* Statistics updates. */
2404 /* Send RIP packet to the interface. */
2405 static void rip_update_interface(struct connected
*ifc
, uint8_t version
,
2408 struct interface
*ifp
= ifc
->ifp
;
2409 struct rip_interface
*ri
= ifp
->info
;
2410 struct sockaddr_in to
;
2412 /* When RIP version is 2 and multicast enable interface. */
2413 if (version
== RIPv2
&& !ri
->v2_broadcast
&& if_is_multicast(ifp
)) {
2414 if (IS_RIP_DEBUG_EVENT
)
2415 zlog_debug("multicast announce on %s ", ifp
->name
);
2417 rip_output_process(ifc
, NULL
, route_type
, version
);
2421 /* If we can't send multicast packet, send it with unicast. */
2422 if (if_is_broadcast(ifp
) || if_is_pointopoint(ifp
)) {
2423 if (ifc
->address
->family
== AF_INET
) {
2424 /* Destination address and port setting. */
2425 memset(&to
, 0, sizeof(struct sockaddr_in
));
2426 if (ifc
->destination
)
2427 /* use specified broadcast or peer destination
2429 to
.sin_addr
= ifc
->destination
->u
.prefix4
;
2430 else if (ifc
->address
->prefixlen
< IPV4_MAX_PREFIXLEN
)
2431 /* calculate the appropriate broadcast address
2433 to
.sin_addr
.s_addr
= ipv4_broadcast_addr(
2434 ifc
->address
->u
.prefix4
.s_addr
,
2435 ifc
->address
->prefixlen
);
2437 /* do not know where to send the packet */
2439 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2441 if (IS_RIP_DEBUG_EVENT
)
2442 zlog_debug("%s announce to %s on %s",
2443 CONNECTED_PEER(ifc
) ? "unicast"
2445 inet_ntoa(to
.sin_addr
), ifp
->name
);
2447 rip_output_process(ifc
, &to
, route_type
, version
);
2452 /* Update send to all interface and neighbor. */
2453 static void rip_update_process(int route_type
)
2455 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2456 struct listnode
*ifnode
, *ifnnode
;
2457 struct connected
*connected
;
2458 struct interface
*ifp
;
2459 struct rip_interface
*ri
;
2460 struct route_node
*rp
;
2461 struct sockaddr_in to
;
2464 /* Send RIP update to each interface. */
2465 FOR_ALL_INTERFACES (vrf
, ifp
) {
2466 if (if_is_loopback(ifp
))
2469 if (!if_is_operative(ifp
))
2472 /* Fetch RIP interface information. */
2475 /* When passive interface is specified, suppress announce to the
2482 * If there is no version configuration in the
2484 * use rip's version setting.
2486 int vsend
= ((ri
->ri_send
== RI_RIP_UNSPEC
)
2490 if (IS_RIP_DEBUG_EVENT
)
2491 zlog_debug("SEND UPDATE to %s ifindex %d",
2492 ifp
->name
, ifp
->ifindex
);
2494 /* send update on each connected network */
2495 for (ALL_LIST_ELEMENTS(ifp
->connected
, ifnode
, ifnnode
,
2497 if (connected
->address
->family
== AF_INET
) {
2499 rip_update_interface(
2503 && if_is_multicast(ifp
))
2504 rip_update_interface(
2512 /* RIP send updates to each neighbor. */
2513 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
2514 if (rp
->info
!= NULL
) {
2517 connected
= if_lookup_address(&p
->u
.prefix4
, AF_INET
,
2521 "Neighbor %s doesn't have connected interface!",
2522 inet_ntoa(p
->u
.prefix4
));
2526 /* Set destination address and port */
2527 memset(&to
, 0, sizeof(struct sockaddr_in
));
2528 to
.sin_addr
= p
->u
.prefix4
;
2529 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2531 /* RIP version is rip's configuration. */
2532 rip_output_process(connected
, &to
, route_type
,
2537 /* RIP's periodical timer. */
2538 static int rip_update(struct thread
*t
)
2540 /* Clear timer pointer. */
2541 rip
->t_update
= NULL
;
2543 if (IS_RIP_DEBUG_EVENT
)
2544 zlog_debug("update timer fire!");
2546 /* Process update output. */
2547 rip_update_process(rip_all_route
);
2549 /* Triggered updates may be suppressed if a regular update is due by
2550 the time the triggered update would be sent. */
2551 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2554 /* Register myself. */
2555 rip_event(RIP_UPDATE_EVENT
, 0);
2560 /* Walk down the RIP routing table then clear changed flag. */
2561 static void rip_clear_changed_flag(void)
2563 struct route_node
*rp
;
2564 struct rip_info
*rinfo
= NULL
;
2565 struct list
*list
= NULL
;
2566 struct listnode
*listnode
= NULL
;
2568 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2569 if ((list
= rp
->info
) != NULL
)
2570 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
2571 UNSET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2572 /* This flag can be set only on the first entry.
2578 /* Triggered update interval timer. */
2579 static int rip_triggered_interval(struct thread
*t
)
2581 int rip_triggered_update(struct thread
*);
2583 rip
->t_triggered_interval
= NULL
;
2587 rip_triggered_update(t
);
2592 /* Execute triggered update. */
2593 static int rip_triggered_update(struct thread
*t
)
2597 /* Clear thred pointer. */
2598 rip
->t_triggered_update
= NULL
;
2600 /* Cancel interval timer. */
2601 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2604 /* Logging triggered update. */
2605 if (IS_RIP_DEBUG_EVENT
)
2606 zlog_debug("triggered update!");
2608 /* Split Horizon processing is done when generating triggered
2609 updates as well as normal updates (see section 2.6). */
2610 rip_update_process(rip_changed_route
);
2612 /* Once all of the triggered updates have been generated, the route
2613 change flags should be cleared. */
2614 rip_clear_changed_flag();
2616 /* After a triggered update is sent, a timer should be set for a
2617 random interval between 1 and 5 seconds. If other changes that
2618 would trigger updates occur before the timer expires, a single
2619 update is triggered when the timer expires. */
2620 interval
= (random() % 5) + 1;
2622 rip
->t_triggered_interval
= NULL
;
2623 thread_add_timer(master
, rip_triggered_interval
, NULL
, interval
,
2624 &rip
->t_triggered_interval
);
2629 /* Withdraw redistributed route. */
2630 void rip_redistribute_withdraw(int type
)
2632 struct route_node
*rp
;
2633 struct rip_info
*rinfo
= NULL
;
2634 struct list
*list
= NULL
;
2639 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2640 if ((list
= rp
->info
) != NULL
) {
2641 rinfo
= listgetdata(listhead(list
));
2642 if (rinfo
->type
== type
2643 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2644 /* Perform poisoned reverse. */
2645 rinfo
->metric
= RIP_METRIC_INFINITY
;
2646 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
2647 rip_garbage_collect
,
2649 RIP_TIMER_OFF(rinfo
->t_timeout
);
2650 rinfo
->flags
|= RIP_RTF_CHANGED
;
2652 if (IS_RIP_DEBUG_EVENT
) {
2653 struct prefix_ipv4
*p
=
2654 (struct prefix_ipv4
*)&rp
->p
;
2657 "Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2658 inet_ntoa(p
->prefix
),
2665 rip_event(RIP_TRIGGERED_UPDATE
, 0);
2670 /* Create new RIP instance and set it to global variable. */
2671 int rip_create(int socket
)
2673 rip
= XCALLOC(MTYPE_RIP
, sizeof(struct rip
));
2675 /* Set initial value. */
2676 rip
->ecmp
= yang_get_default_bool("%s/allow-ecmp", RIP_INSTANCE
);
2677 rip
->default_metric
=
2678 yang_get_default_uint8("%s/default-metric", RIP_INSTANCE
);
2680 yang_get_default_uint8("%s/distance/default", RIP_INSTANCE
);
2681 rip
->passive_default
=
2682 yang_get_default_bool("%s/passive-default", RIP_INSTANCE
);
2683 rip
->garbage_time
= yang_get_default_uint32("%s/timers/flush-interval",
2685 rip
->timeout_time
= yang_get_default_uint32(
2686 "%s/timers/holddown-interval", RIP_INSTANCE
);
2687 rip
->update_time
= yang_get_default_uint32("%s/timers/update-interval",
2690 yang_get_default_enum("%s/version/send", RIP_INSTANCE
);
2692 yang_get_default_enum("%s/version/receive", RIP_INSTANCE
);
2694 /* Initialize RIP routig table. */
2695 rip
->table
= route_table_init();
2696 rip
->neighbor
= route_table_init();
2698 /* Make output stream. */
2699 rip
->obuf
= stream_new(1500);
2704 /* Create read and timer thread. */
2705 rip_event(RIP_READ
, rip
->sock
);
2706 rip_event(RIP_UPDATE_EVENT
, 1);
2707 /* Distribute list install. */
2708 rip
->distribute_ctx
= distribute_list_ctx_create(
2709 vrf_lookup_by_id(VRF_DEFAULT
));
2710 distribute_list_add_hook(rip
->distribute_ctx
,
2711 rip_distribute_update
);
2712 distribute_list_delete_hook(rip
->distribute_ctx
,
2713 rip_distribute_update
);
2715 /* if rmap install. */
2716 rip
->if_rmap_ctx
= if_rmap_ctx_create(VRF_DEFAULT_NAME
);
2717 if_rmap_hook_add(rip
->if_rmap_ctx
, rip_if_rmap_update
);
2718 if_rmap_hook_delete(rip
->if_rmap_ctx
, rip_if_rmap_update
);
2723 /* Sned RIP request to the destination. */
2724 int rip_request_send(struct sockaddr_in
*to
, struct interface
*ifp
,
2725 uint8_t version
, struct connected
*connected
)
2728 struct rip_packet rip_packet
;
2729 struct listnode
*node
, *nnode
;
2731 memset(&rip_packet
, 0, sizeof(rip_packet
));
2733 rip_packet
.command
= RIP_REQUEST
;
2734 rip_packet
.version
= version
;
2735 rte
= rip_packet
.rte
;
2736 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
2740 * connected is only sent for ripv1 case, or when
2741 * interface does not support multicast. Caller loops
2742 * over each connected address for this case.
2744 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2746 != sizeof(rip_packet
))
2749 return sizeof(rip_packet
);
2752 /* send request on each connected network */
2753 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, connected
)) {
2754 struct prefix_ipv4
*p
;
2756 p
= (struct prefix_ipv4
*)connected
->address
;
2758 if (p
->family
!= AF_INET
)
2761 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2763 != sizeof(rip_packet
))
2766 return sizeof(rip_packet
);
2769 static int rip_update_jitter(unsigned long time
)
2771 #define JITTER_BOUND 4
2772 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2773 Given that, we cannot let time be less than JITTER_BOUND seconds.
2774 The RIPv2 RFC says jitter should be small compared to
2775 update_time. We consider 1/JITTER_BOUND to be small.
2778 int jitter_input
= time
;
2781 if (jitter_input
< JITTER_BOUND
)
2782 jitter_input
= JITTER_BOUND
;
2784 jitter
= (((random() % ((jitter_input
* 2) + 1)) - jitter_input
));
2786 return jitter
/ JITTER_BOUND
;
2789 void rip_event(enum rip_event event
, int sock
)
2796 thread_add_read(master
, rip_read
, NULL
, sock
, &rip
->t_read
);
2798 case RIP_UPDATE_EVENT
:
2799 RIP_TIMER_OFF(rip
->t_update
);
2800 jitter
= rip_update_jitter(rip
->update_time
);
2801 thread_add_timer(master
, rip_update
, NULL
,
2802 sock
? 2 : rip
->update_time
+ jitter
,
2805 case RIP_TRIGGERED_UPDATE
:
2806 if (rip
->t_triggered_interval
)
2809 thread_add_event(master
, rip_triggered_update
, NULL
, 0,
2810 &rip
->t_triggered_update
);
2819 rip_update_default_metric (void)
2821 struct route_node
*np
;
2822 struct rip_info
*rinfo
= NULL
;
2823 struct list
*list
= NULL
;
2824 struct listnode
*listnode
= NULL
;
2826 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
2827 if ((list
= np
->info
) != NULL
)
2828 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
2829 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
2830 rinfo
->metric
= rip
->default_metric
;
2835 struct route_table
*rip_distance_table
;
2837 struct rip_distance
*rip_distance_new(void)
2839 return XCALLOC(MTYPE_RIP_DISTANCE
, sizeof(struct rip_distance
));
2842 void rip_distance_free(struct rip_distance
*rdistance
)
2844 XFREE(MTYPE_RIP_DISTANCE
, rdistance
);
2847 static void rip_distance_reset(void)
2849 struct route_node
*rn
;
2850 struct rip_distance
*rdistance
;
2852 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
2853 if ((rdistance
= rn
->info
) != NULL
) {
2854 if (rdistance
->access_list
)
2855 free(rdistance
->access_list
);
2856 rip_distance_free(rdistance
);
2858 route_unlock_node(rn
);
2862 /* Apply RIP information to distance method. */
2863 uint8_t rip_distance_apply(struct rip_info
*rinfo
)
2865 struct route_node
*rn
;
2866 struct prefix_ipv4 p
;
2867 struct rip_distance
*rdistance
;
2868 struct access_list
*alist
;
2873 memset(&p
, 0, sizeof(struct prefix_ipv4
));
2875 p
.prefix
= rinfo
->from
;
2876 p
.prefixlen
= IPV4_MAX_BITLEN
;
2878 /* Check source address. */
2879 rn
= route_node_match(rip_distance_table
, (struct prefix
*)&p
);
2881 rdistance
= rn
->info
;
2882 route_unlock_node(rn
);
2884 if (rdistance
->access_list
) {
2885 alist
= access_list_lookup(AFI_IP
,
2886 rdistance
->access_list
);
2889 if (access_list_apply(alist
, &rinfo
->rp
->p
)
2893 return rdistance
->distance
;
2895 return rdistance
->distance
;
2899 return rip
->distance
;
2904 static void rip_distance_show(struct vty
*vty
)
2906 struct route_node
*rn
;
2907 struct rip_distance
*rdistance
;
2911 vty_out(vty
, " Distance: (default is %u)\n",
2912 rip
->distance
? rip
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
);
2914 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
2915 if ((rdistance
= rn
->info
) != NULL
) {
2918 " Address Distance List\n");
2921 sprintf(buf
, "%s/%d", inet_ntoa(rn
->p
.u
.prefix4
),
2923 vty_out(vty
, " %-20s %4d %s\n", buf
,
2924 rdistance
->distance
,
2925 rdistance
->access_list
? rdistance
->access_list
2930 /* Update ECMP routes to zebra when ECMP is disabled. */
2931 void rip_ecmp_disable(void)
2933 struct route_node
*rp
;
2934 struct rip_info
*rinfo
, *tmp_rinfo
;
2936 struct listnode
*node
, *nextnode
;
2941 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2942 if ((list
= rp
->info
) != NULL
&& listcount(list
) > 1) {
2943 rinfo
= listgetdata(listhead(list
));
2944 if (!rip_route_rte(rinfo
))
2947 /* Drop all other entries, except the first one. */
2948 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
2949 if (tmp_rinfo
!= rinfo
) {
2950 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
2952 tmp_rinfo
->t_garbage_collect
);
2953 list_delete_node(list
, node
);
2954 rip_info_free(tmp_rinfo
);
2958 rip_zebra_ipv4_add(rp
);
2960 /* Set the route change flag. */
2961 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2963 /* Signal the output process to trigger an update. */
2964 rip_event(RIP_TRIGGERED_UPDATE
, 0);
2968 /* Print out routes update time. */
2969 static void rip_vty_out_uptime(struct vty
*vty
, struct rip_info
*rinfo
)
2974 char timebuf
[TIME_BUF
];
2975 struct thread
*thread
;
2977 if ((thread
= rinfo
->t_timeout
) != NULL
) {
2978 clock
= thread_timer_remain_second(thread
);
2979 tm
= gmtime(&clock
);
2980 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
2981 vty_out(vty
, "%5s", timebuf
);
2982 } else if ((thread
= rinfo
->t_garbage_collect
) != NULL
) {
2983 clock
= thread_timer_remain_second(thread
);
2984 tm
= gmtime(&clock
);
2985 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
2986 vty_out(vty
, "%5s", timebuf
);
2990 static const char *rip_route_type_print(int sub_type
)
2995 case RIP_ROUTE_STATIC
:
2997 case RIP_ROUTE_DEFAULT
:
2999 case RIP_ROUTE_REDISTRIBUTE
:
3001 case RIP_ROUTE_INTERFACE
:
3013 "Show RIP routes\n")
3015 struct route_node
*np
;
3016 struct rip_info
*rinfo
= NULL
;
3017 struct list
*list
= NULL
;
3018 struct listnode
*listnode
= NULL
;
3024 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
3026 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
3027 " (i) - interface\n\n"
3028 " Network Next Hop Metric From Tag Time\n");
3030 for (np
= route_top(rip
->table
); np
; np
= route_next(np
))
3031 if ((list
= np
->info
) != NULL
)
3032 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3036 vty
, "%c(%s) %s/%d",
3037 /* np->lock, For debugging. */
3038 zebra_route_char(rinfo
->type
),
3039 rip_route_type_print(rinfo
->sub_type
),
3040 inet_ntoa(np
->p
.u
.prefix4
),
3046 vty_out(vty
, "%*s", len
, " ");
3048 switch (rinfo
->nh
.type
) {
3049 case NEXTHOP_TYPE_IPV4
:
3050 case NEXTHOP_TYPE_IPV4_IFINDEX
:
3051 vty_out(vty
, "%-20s %2d ",
3052 inet_ntoa(rinfo
->nh
.gate
.ipv4
),
3055 case NEXTHOP_TYPE_IFINDEX
:
3060 case NEXTHOP_TYPE_BLACKHOLE
:
3065 case NEXTHOP_TYPE_IPV6
:
3066 case NEXTHOP_TYPE_IPV6_IFINDEX
:
3068 "V6 Address Hidden %2d ",
3073 /* Route which exist in kernel routing table. */
3074 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
)
3075 && (rinfo
->sub_type
== RIP_ROUTE_RTE
)) {
3076 vty_out(vty
, "%-15s ",
3077 inet_ntoa(rinfo
->from
));
3078 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3079 (route_tag_t
)rinfo
->tag
);
3080 rip_vty_out_uptime(vty
, rinfo
);
3081 } else if (rinfo
->metric
3082 == RIP_METRIC_INFINITY
) {
3083 vty_out(vty
, "self ");
3084 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3085 (route_tag_t
)rinfo
->tag
);
3086 rip_vty_out_uptime(vty
, rinfo
);
3088 if (rinfo
->external_metric
) {
3090 vty
, "self (%s:%d)",
3093 rinfo
->external_metric
);
3096 vty_out(vty
, "%*s", len
,
3101 vty_out(vty
, "%3" ROUTE_TAG_PRI
,
3102 (route_tag_t
)rinfo
->tag
);
3110 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3111 DEFUN (show_ip_rip_status
,
3112 show_ip_rip_status_cmd
,
3113 "show ip rip status",
3117 "IP routing protocol process parameters and statistics\n")
3119 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3120 struct interface
*ifp
;
3121 struct rip_interface
*ri
;
3122 extern const struct message ri_version_msg
[];
3123 const char *send_version
;
3124 const char *receive_version
;
3129 vty_out(vty
, "Routing Protocol is \"rip\"\n");
3130 vty_out(vty
, " Sending updates every %u seconds with +/-50%%,",
3132 vty_out(vty
, " next due in %lu seconds\n",
3133 thread_timer_remain_second(rip
->t_update
));
3134 vty_out(vty
, " Timeout after %u seconds,", rip
->timeout_time
);
3135 vty_out(vty
, " garbage collect after %u seconds\n", rip
->garbage_time
);
3137 /* Filtering status show. */
3138 config_show_distribute(vty
, rip
->distribute_ctx
);
3140 /* Default metric information. */
3141 vty_out(vty
, " Default redistribution metric is %u\n",
3142 rip
->default_metric
);
3144 /* Redistribute information. */
3145 vty_out(vty
, " Redistributing:");
3146 rip_show_redistribute_config(vty
);
3149 vty_out(vty
, " Default version control: send version %s,",
3150 lookup_msg(ri_version_msg
, rip
->version_send
, NULL
));
3151 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3152 vty_out(vty
, " receive any version \n");
3154 vty_out(vty
, " receive version %s \n",
3155 lookup_msg(ri_version_msg
, rip
->version_recv
, NULL
));
3157 vty_out(vty
, " Interface Send Recv Key-chain\n");
3159 FOR_ALL_INTERFACES (vrf
, ifp
) {
3165 if (ri
->enable_network
|| ri
->enable_interface
) {
3166 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3168 lookup_msg(ri_version_msg
,
3169 rip
->version_send
, NULL
);
3171 send_version
= lookup_msg(ri_version_msg
,
3174 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3176 lookup_msg(ri_version_msg
,
3177 rip
->version_recv
, NULL
);
3179 receive_version
= lookup_msg(
3180 ri_version_msg
, ri
->ri_receive
, NULL
);
3182 vty_out(vty
, " %-17s%-3s %-3s %s\n", ifp
->name
,
3183 send_version
, receive_version
,
3184 ri
->key_chain
? ri
->key_chain
: "");
3188 vty_out(vty
, " Routing for Networks:\n");
3189 rip_show_network_config(vty
);
3192 int found_passive
= 0;
3193 FOR_ALL_INTERFACES (vrf
, ifp
) {
3196 if ((ri
->enable_network
|| ri
->enable_interface
)
3198 if (!found_passive
) {
3200 " Passive Interface(s):\n");
3203 vty_out(vty
, " %s\n", ifp
->name
);
3208 vty_out(vty
, " Routing Information Sources:\n");
3210 " Gateway BadPackets BadRoutes Distance Last Update\n");
3211 rip_peer_display(vty
);
3213 rip_distance_show(vty
);
3218 /* RIP configuration write function. */
3219 static int config_write_rip(struct vty
*vty
)
3222 struct lyd_node
*dnode
;
3224 dnode
= yang_dnode_get(running_config
->dnode
,
3225 "/frr-ripd:ripd/instance");
3229 nb_cli_show_dnode_cmds(vty
, dnode
, false);
3231 /* Distribute configuration. */
3232 write
+= config_write_distribute(vty
,
3233 rip
->distribute_ctx
);
3235 /* Interface routemap configuration */
3236 write
+= config_write_if_rmap(vty
, rip
->if_rmap_ctx
);
3241 /* RIP node structure. */
3242 static struct cmd_node rip_node
= {RIP_NODE
, "%s(config-router)# ", 1};
3244 /* Distribute-list update functions. */
3245 static void rip_distribute_update(struct distribute_ctx
*ctx
,
3246 struct distribute
*dist
)
3248 struct interface
*ifp
;
3249 struct rip_interface
*ri
;
3250 struct access_list
*alist
;
3251 struct prefix_list
*plist
;
3256 ifp
= if_lookup_by_name(dist
->ifname
, VRF_DEFAULT
);
3262 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
3263 alist
= access_list_lookup(AFI_IP
,
3264 dist
->list
[DISTRIBUTE_V4_IN
]);
3266 ri
->list
[RIP_FILTER_IN
] = alist
;
3268 ri
->list
[RIP_FILTER_IN
] = NULL
;
3270 ri
->list
[RIP_FILTER_IN
] = NULL
;
3272 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
3273 alist
= access_list_lookup(AFI_IP
,
3274 dist
->list
[DISTRIBUTE_V4_OUT
]);
3276 ri
->list
[RIP_FILTER_OUT
] = alist
;
3278 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3280 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3282 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
3283 plist
= prefix_list_lookup(AFI_IP
,
3284 dist
->prefix
[DISTRIBUTE_V4_IN
]);
3286 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3288 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3290 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3292 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
3293 plist
= prefix_list_lookup(AFI_IP
,
3294 dist
->prefix
[DISTRIBUTE_V4_OUT
]);
3296 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3298 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3300 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3303 void rip_distribute_update_interface(struct interface
*ifp
)
3305 struct distribute
*dist
;
3309 dist
= distribute_lookup(rip
->distribute_ctx
, ifp
->name
);
3311 rip_distribute_update(rip
->distribute_ctx
, dist
);
3314 /* Update all interface's distribute list. */
3316 static void rip_distribute_update_all(struct prefix_list
*notused
)
3318 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3319 struct interface
*ifp
;
3321 FOR_ALL_INTERFACES (vrf
, ifp
)
3322 rip_distribute_update_interface(ifp
);
3325 static void rip_distribute_update_all_wrapper(struct access_list
*notused
)
3327 rip_distribute_update_all(NULL
);
3330 /* Delete all added rip route. */
3331 void rip_clean(void)
3334 struct route_node
*rp
;
3335 struct rip_info
*rinfo
= NULL
;
3336 struct list
*list
= NULL
;
3337 struct listnode
*listnode
= NULL
;
3340 /* Clear RIP routes */
3341 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3342 if ((list
= rp
->info
) != NULL
) {
3343 rinfo
= listgetdata(listhead(list
));
3344 if (rip_route_rte(rinfo
))
3345 rip_zebra_ipv4_delete(rp
);
3347 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
3349 RIP_TIMER_OFF(rinfo
->t_timeout
);
3350 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
3351 rip_info_free(rinfo
);
3355 route_unlock_node(rp
);
3358 /* Cancel RIP related timers. */
3359 RIP_TIMER_OFF(rip
->t_update
);
3360 RIP_TIMER_OFF(rip
->t_triggered_update
);
3361 RIP_TIMER_OFF(rip
->t_triggered_interval
);
3363 /* Cancel read thread. */
3364 THREAD_READ_OFF(rip
->t_read
);
3366 /* Close RIP socket. */
3367 if (rip
->sock
>= 0) {
3372 stream_free(rip
->obuf
);
3374 /* RIP neighbor configuration. */
3375 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
3378 route_unlock_node(rp
);
3381 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3382 if (rip
->route_map
[i
].name
)
3383 free(rip
->route_map
[i
].name
);
3385 route_table_finish(rip
->table
);
3386 route_table_finish(rip
->neighbor
);
3388 distribute_list_delete(&rip
->distribute_ctx
);
3390 if_rmap_ctx_delete(rip
->if_rmap_ctx
);
3392 XFREE(MTYPE_RIP
, rip
);
3395 rip_clean_network();
3396 rip_passive_nondefault_clean();
3398 rip_interfaces_clean();
3399 rip_distance_reset();
3400 rip_redistribute_clean();
3401 if_rmap_terminate();
3404 static void rip_if_rmap_update(struct if_rmap_ctx
*ctx
,
3405 struct if_rmap
*if_rmap
)
3407 struct interface
*ifp
= NULL
;
3408 struct rip_interface
*ri
;
3409 struct route_map
*rmap
;
3410 struct vrf
*vrf
= NULL
;
3413 vrf
= vrf_lookup_by_name(ctx
->name
);
3415 ifp
= if_lookup_by_name(if_rmap
->ifname
, vrf
->vrf_id
);
3420 if (if_rmap
->routemap
[IF_RMAP_IN
]) {
3421 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_IN
]);
3423 ri
->routemap
[IF_RMAP_IN
] = rmap
;
3425 ri
->routemap
[IF_RMAP_IN
] = NULL
;
3427 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
3429 if (if_rmap
->routemap
[IF_RMAP_OUT
]) {
3430 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_OUT
]);
3432 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
3434 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
3436 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
3439 void rip_if_rmap_update_interface(struct interface
*ifp
)
3441 struct if_rmap
*if_rmap
;
3442 struct if_rmap_ctx
*ctx
;
3446 if (ifp
->vrf_id
!= VRF_DEFAULT
)
3448 ctx
= rip
->if_rmap_ctx
;
3451 if_rmap
= if_rmap_lookup(ctx
, ifp
->name
);
3453 rip_if_rmap_update(ctx
, if_rmap
);
3456 static void rip_routemap_update_redistribute(void)
3461 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3462 if (rip
->route_map
[i
].name
) {
3463 rip
->route_map
[i
].map
=
3464 route_map_lookup_by_name(
3465 rip
->route_map
[i
].name
);
3466 route_map_counter_increment(
3467 rip
->route_map
[i
].map
);
3474 static void rip_routemap_update(const char *notused
)
3476 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3477 struct interface
*ifp
;
3479 FOR_ALL_INTERFACES (vrf
, ifp
)
3480 rip_if_rmap_update_interface(ifp
);
3482 rip_routemap_update_redistribute();
3485 /* Allocate new rip structure and set default value. */
3488 /* Install top nodes. */
3489 install_node(&rip_node
, config_write_rip
);
3491 /* Install rip commands. */
3492 install_element(VIEW_NODE
, &show_ip_rip_cmd
);
3493 install_element(VIEW_NODE
, &show_ip_rip_status_cmd
);
3495 install_default(RIP_NODE
);
3497 /* Debug related init. */
3500 /* Access list install. */
3502 access_list_add_hook(rip_distribute_update_all_wrapper
);
3503 access_list_delete_hook(rip_distribute_update_all_wrapper
);
3505 /* Prefix list initialize.*/
3507 prefix_list_add_hook(rip_distribute_update_all
);
3508 prefix_list_delete_hook(rip_distribute_update_all
);
3510 /* Distribute list install. */
3511 distribute_list_init(RIP_NODE
);
3514 rip_route_map_init();
3517 route_map_add_hook(rip_routemap_update
);
3518 route_map_delete_hook(rip_routemap_update
);
3520 if_rmap_init(RIP_NODE
);
3522 /* Distance control. */
3523 rip_distance_table
= route_table_init();