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 /* RIP output routes type. */
72 enum { rip_all_route
, rip_changed_route
};
74 /* RIP command strings. */
75 static const struct message rip_msg
[] = {{RIP_REQUEST
, "REQUEST"},
76 {RIP_RESPONSE
, "RESPONSE"},
77 {RIP_TRACEON
, "TRACEON"},
78 {RIP_TRACEOFF
, "TRACEOFF"},
80 {RIP_POLL_ENTRY
, "POLL ENTRY"},
83 /* Utility function to set boradcast option to the socket. */
84 static int sockopt_broadcast(int sock
)
89 ret
= setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, (char *)&on
,
92 zlog_warn("can't set sockopt SO_BROADCAST to socket %d", sock
);
98 int rip_route_rte(struct rip_info
*rinfo
)
100 return (rinfo
->type
== ZEBRA_ROUTE_RIP
101 && rinfo
->sub_type
== RIP_ROUTE_RTE
);
104 static struct rip_info
*rip_info_new(void)
106 return XCALLOC(MTYPE_RIP_INFO
, sizeof(struct rip_info
));
109 void rip_info_free(struct rip_info
*rinfo
)
111 XFREE(MTYPE_RIP_INFO
, rinfo
);
114 /* RIP route garbage collect timer. */
115 static int rip_garbage_collect(struct thread
*t
)
117 struct rip_info
*rinfo
;
118 struct route_node
*rp
;
120 rinfo
= THREAD_ARG(t
);
121 rinfo
->t_garbage_collect
= NULL
;
123 /* Off timeout timer. */
124 RIP_TIMER_OFF(rinfo
->t_timeout
);
126 /* Get route_node pointer. */
129 /* Unlock route_node. */
130 listnode_delete(rp
->info
, rinfo
);
131 if (list_isempty((struct list
*)rp
->info
)) {
132 list_delete((struct list
**)&rp
->info
);
133 route_unlock_node(rp
);
136 /* Free RIP routing information. */
137 rip_info_free(rinfo
);
142 static void rip_timeout_update(struct rip_info
*rinfo
);
144 /* Add new route to the ECMP list.
145 * RETURN: the new entry added in the list, or NULL if it is not the first
146 * entry and ECMP is not allowed.
148 struct rip_info
*rip_ecmp_add(struct rip_info
*rinfo_new
)
150 struct route_node
*rp
= rinfo_new
->rp
;
151 struct rip_info
*rinfo
= NULL
;
152 struct list
*list
= NULL
;
154 if (rp
->info
== NULL
)
155 rp
->info
= list_new();
156 list
= (struct list
*)rp
->info
;
158 /* If ECMP is not allowed and some entry already exists in the list,
160 if (listcount(list
) && !rip
->ecmp
)
163 rinfo
= rip_info_new();
164 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
165 listnode_add(list
, rinfo
);
167 if (rip_route_rte(rinfo
)) {
168 rip_timeout_update(rinfo
);
169 rip_zebra_ipv4_add(rp
);
172 /* Set the route change flag on the first entry. */
173 rinfo
= listgetdata(listhead(list
));
174 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
176 /* Signal the output process to trigger an update (see section 2.5). */
177 rip_event(RIP_TRIGGERED_UPDATE
, 0);
182 /* Replace the ECMP list with the new route.
183 * RETURN: the new entry added in the list
185 struct rip_info
*rip_ecmp_replace(struct rip_info
*rinfo_new
)
187 struct route_node
*rp
= rinfo_new
->rp
;
188 struct list
*list
= (struct list
*)rp
->info
;
189 struct rip_info
*rinfo
= NULL
, *tmp_rinfo
= NULL
;
190 struct listnode
*node
= NULL
, *nextnode
= NULL
;
192 if (list
== NULL
|| listcount(list
) == 0)
193 return rip_ecmp_add(rinfo_new
);
195 /* Get the first entry */
196 rinfo
= listgetdata(listhead(list
));
198 /* Learnt route replaced by a local one. Delete it from zebra. */
199 if (rip_route_rte(rinfo
) && !rip_route_rte(rinfo_new
))
200 if (CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
201 rip_zebra_ipv4_delete(rp
);
203 /* Re-use the first entry, and delete the others. */
204 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
205 if (tmp_rinfo
!= rinfo
) {
206 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
207 RIP_TIMER_OFF(tmp_rinfo
->t_garbage_collect
);
208 list_delete_node(list
, node
);
209 rip_info_free(tmp_rinfo
);
212 RIP_TIMER_OFF(rinfo
->t_timeout
);
213 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
214 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
216 if (rip_route_rte(rinfo
)) {
217 rip_timeout_update(rinfo
);
218 /* The ADD message implies an update. */
219 rip_zebra_ipv4_add(rp
);
222 /* Set the route change flag. */
223 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
225 /* Signal the output process to trigger an update (see section 2.5). */
226 rip_event(RIP_TRIGGERED_UPDATE
, 0);
231 /* Delete one route from the ECMP list.
233 * null - the entry is freed, and other entries exist in the list
234 * the entry - the entry is the last one in the list; its metric is set
235 * to INFINITY, and the garbage collector is started for it
237 struct rip_info
*rip_ecmp_delete(struct rip_info
*rinfo
)
239 struct route_node
*rp
= rinfo
->rp
;
240 struct list
*list
= (struct list
*)rp
->info
;
242 RIP_TIMER_OFF(rinfo
->t_timeout
);
244 if (listcount(list
) > 1) {
245 /* Some other ECMP entries still exist. Just delete this entry.
247 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
248 listnode_delete(list
, rinfo
);
249 if (rip_route_rte(rinfo
)
250 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
251 /* The ADD message implies the update. */
252 rip_zebra_ipv4_add(rp
);
253 rip_info_free(rinfo
);
256 assert(rinfo
== listgetdata(listhead(list
)));
258 /* This is the only entry left in the list. We must keep it in
259 * the list for garbage collection time, with INFINITY metric.
262 rinfo
->metric
= RIP_METRIC_INFINITY
;
263 RIP_TIMER_ON(rinfo
->t_garbage_collect
, rip_garbage_collect
,
266 if (rip_route_rte(rinfo
)
267 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
268 rip_zebra_ipv4_delete(rp
);
271 /* Set the route change flag on the first entry. */
272 rinfo
= listgetdata(listhead(list
));
273 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
275 /* Signal the output process to trigger an update (see section 2.5). */
276 rip_event(RIP_TRIGGERED_UPDATE
, 0);
281 /* Timeout RIP routes. */
282 static int rip_timeout(struct thread
*t
)
284 rip_ecmp_delete((struct rip_info
*)THREAD_ARG(t
));
288 static void rip_timeout_update(struct rip_info
*rinfo
)
290 if (rinfo
->metric
!= RIP_METRIC_INFINITY
) {
291 RIP_TIMER_OFF(rinfo
->t_timeout
);
292 RIP_TIMER_ON(rinfo
->t_timeout
, rip_timeout
, rip
->timeout_time
);
296 static int rip_filter(int rip_distribute
, struct prefix_ipv4
*p
,
297 struct rip_interface
*ri
)
299 struct distribute
*dist
;
300 struct access_list
*alist
;
301 struct prefix_list
*plist
;
302 int distribute
= rip_distribute
== RIP_FILTER_OUT
? DISTRIBUTE_V4_OUT
304 const char *inout
= rip_distribute
== RIP_FILTER_OUT
? "out" : "in";
306 /* Input distribute-list filtering. */
307 if (ri
->list
[rip_distribute
]) {
308 if (access_list_apply(ri
->list
[rip_distribute
],
311 if (IS_RIP_DEBUG_PACKET
)
312 zlog_debug("%s/%d filtered by distribute %s",
313 inet_ntoa(p
->prefix
), p
->prefixlen
,
318 if (ri
->prefix
[rip_distribute
]) {
319 if (prefix_list_apply(ri
->prefix
[rip_distribute
],
322 if (IS_RIP_DEBUG_PACKET
)
323 zlog_debug("%s/%d filtered by prefix-list %s",
324 inet_ntoa(p
->prefix
), p
->prefixlen
,
330 /* All interface filter check. */
331 dist
= distribute_lookup(NULL
);
333 if (dist
->list
[distribute
]) {
334 alist
= access_list_lookup(AFI_IP
,
335 dist
->list
[distribute
]);
338 if (access_list_apply(alist
, (struct prefix
*)p
)
340 if (IS_RIP_DEBUG_PACKET
)
342 "%s/%d filtered by distribute %s",
343 inet_ntoa(p
->prefix
),
344 p
->prefixlen
, inout
);
349 if (dist
->prefix
[distribute
]) {
350 plist
= prefix_list_lookup(AFI_IP
,
351 dist
->prefix
[distribute
]);
354 if (prefix_list_apply(plist
, (struct prefix
*)p
)
356 if (IS_RIP_DEBUG_PACKET
)
358 "%s/%d filtered by prefix-list %s",
359 inet_ntoa(p
->prefix
),
360 p
->prefixlen
, inout
);
369 /* Check nexthop address validity. */
370 static int rip_nexthop_check(struct in_addr
*addr
)
372 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
373 struct interface
*ifp
;
374 struct listnode
*cnode
;
375 struct connected
*ifc
;
378 /* If nexthop address matches local configured address then it is
381 FOR_ALL_INTERFACES (vrf
, ifp
) {
382 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, ifc
)) {
385 if (p
->family
== AF_INET
386 && IPV4_ADDR_SAME(&p
->u
.prefix4
, addr
))
393 /* RIP add route to routing table. */
394 static void rip_rte_process(struct rte
*rte
, struct sockaddr_in
*from
,
395 struct interface
*ifp
)
398 struct prefix_ipv4 p
;
399 struct route_node
*rp
;
400 struct rip_info
*rinfo
= NULL
, newinfo
;
401 struct rip_interface
*ri
;
402 struct in_addr
*nexthop
;
404 unsigned char old_dist
, new_dist
;
405 struct list
*list
= NULL
;
406 struct listnode
*node
= NULL
;
408 /* Make prefix structure. */
409 memset(&p
, 0, sizeof(struct prefix_ipv4
));
411 p
.prefix
= rte
->prefix
;
412 p
.prefixlen
= ip_masklen(rte
->mask
);
414 /* Make sure mask is applied. */
417 /* Apply input filters. */
420 ret
= rip_filter(RIP_FILTER_IN
, &p
, ri
);
424 memset(&newinfo
, 0, sizeof(newinfo
));
425 newinfo
.type
= ZEBRA_ROUTE_RIP
;
426 newinfo
.sub_type
= RIP_ROUTE_RTE
;
427 newinfo
.nh
.gate
.ipv4
= rte
->nexthop
;
428 newinfo
.from
= from
->sin_addr
;
429 newinfo
.nh
.ifindex
= ifp
->ifindex
;
430 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
431 newinfo
.metric
= rte
->metric
;
432 newinfo
.metric_out
= rte
->metric
; /* XXX */
433 newinfo
.tag
= ntohs(rte
->tag
); /* XXX */
435 /* Modify entry according to the interface routemap. */
436 if (ri
->routemap
[RIP_FILTER_IN
]) {
437 /* The object should be of the type of rip_info */
438 ret
= route_map_apply(ri
->routemap
[RIP_FILTER_IN
],
439 (struct prefix
*)&p
, RMAP_RIP
, &newinfo
);
441 if (ret
== RMAP_DENYMATCH
) {
442 if (IS_RIP_DEBUG_PACKET
)
444 "RIP %s/%d is filtered by route-map in",
445 inet_ntoa(p
.prefix
), p
.prefixlen
);
449 /* Get back the object */
450 rte
->nexthop
= newinfo
.nexthop_out
;
451 rte
->tag
= htons(newinfo
.tag_out
); /* XXX */
452 rte
->metric
= newinfo
.metric_out
; /* XXX: the routemap uses the
456 /* Once the entry has been validated, update the metric by
457 adding the cost of the network on wich the message
458 arrived. If the result is greater than infinity, use infinity
459 (RFC2453 Sec. 3.9.2) */
460 /* Zebra ripd can handle offset-list in. */
461 ret
= rip_offset_list_apply_in(&p
, ifp
, &rte
->metric
);
463 /* If offset-list does not modify the metric use interface's
466 rte
->metric
+= ifp
->metric
? ifp
->metric
: 1;
468 if (rte
->metric
> RIP_METRIC_INFINITY
)
469 rte
->metric
= RIP_METRIC_INFINITY
;
471 /* Set nexthop pointer. */
472 if (rte
->nexthop
.s_addr
== 0)
473 nexthop
= &from
->sin_addr
;
475 nexthop
= &rte
->nexthop
;
477 /* Check if nexthop address is myself, then do nothing. */
478 if (rip_nexthop_check(nexthop
) < 0) {
479 if (IS_RIP_DEBUG_PACKET
)
480 zlog_debug("Nexthop address %s is myself",
481 inet_ntoa(*nexthop
));
485 /* Get index for the prefix. */
486 rp
= route_node_get(rip
->table
, (struct prefix
*)&p
);
489 newinfo
.nh
.gate
.ipv4
= *nexthop
;
490 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4
;
491 newinfo
.metric
= rte
->metric
;
492 newinfo
.tag
= ntohs(rte
->tag
);
493 newinfo
.distance
= rip_distance_apply(&newinfo
);
495 new_dist
= newinfo
.distance
? newinfo
.distance
496 : ZEBRA_RIP_DISTANCE_DEFAULT
;
498 /* Check to see whether there is already RIP route on the table. */
499 if ((list
= rp
->info
) != NULL
)
500 for (ALL_LIST_ELEMENTS_RO(list
, node
, rinfo
)) {
501 /* Need to compare with redistributed entry or local
503 if (!rip_route_rte(rinfo
))
506 if (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
507 && IPV4_ADDR_SAME(&rinfo
->nh
.gate
.ipv4
, nexthop
))
510 if (!listnextnode(node
)) {
511 /* Not found in the list */
513 if (rte
->metric
> rinfo
->metric
) {
514 /* New route has a greater metric.
516 route_unlock_node(rp
);
520 if (rte
->metric
< rinfo
->metric
)
521 /* New route has a smaller metric.
522 * Replace the ECMP list
523 * with the new one in below. */
526 /* Metrics are same. We compare the distances.
528 old_dist
= rinfo
->distance
530 : ZEBRA_RIP_DISTANCE_DEFAULT
;
532 if (new_dist
> old_dist
) {
533 /* New route has a greater distance.
535 route_unlock_node(rp
);
539 if (new_dist
< old_dist
)
540 /* New route has a smaller distance.
541 * Replace the ECMP list
542 * with the new one in below. */
545 /* Metrics and distances are both same. Keep
547 * the new route is added in the ECMP list in
553 /* Local static route. */
554 if (rinfo
->type
== ZEBRA_ROUTE_RIP
555 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
556 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))
557 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
558 route_unlock_node(rp
);
562 /* Redistributed route check. */
563 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
564 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
565 old_dist
= rinfo
->distance
;
566 /* Only routes directly connected to an interface
568 * may have a valid NULL distance */
569 if (rinfo
->nh
.gate
.ipv4
.s_addr
!= 0)
572 : ZEBRA_RIP_DISTANCE_DEFAULT
;
573 /* If imported route does not have STRICT precedence,
574 mark it as a ghost */
575 if (new_dist
<= old_dist
576 && rte
->metric
!= RIP_METRIC_INFINITY
)
577 rip_ecmp_replace(&newinfo
);
579 route_unlock_node(rp
);
586 route_unlock_node(rp
);
588 /* Now, check to see whether there is already an explicit route
589 for the destination prefix. If there is no such route, add
590 this route to the routing table, unless the metric is
591 infinity (there is no point in adding a route which
593 if (rte
->metric
!= RIP_METRIC_INFINITY
)
594 rip_ecmp_add(&newinfo
);
596 /* Route is there but we are not sure the route is RIP or not.
599 /* If there is an existing route, compare the next hop address
600 to the address of the router from which the datagram came.
601 If this datagram is from the same router as the existing
602 route, reinitialize the timeout. */
603 same
= (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
604 && (rinfo
->nh
.ifindex
== ifp
->ifindex
));
606 old_dist
= rinfo
->distance
? rinfo
->distance
607 : ZEBRA_RIP_DISTANCE_DEFAULT
;
609 /* Next, compare the metrics. If the datagram is from the same
610 router as the existing route, and the new metric is different
611 than the old one; or, if the new metric is lower than the old
612 one, or if the tag has been changed; or if there is a route
613 with a lower administrave distance; or an update of the
614 distance on the actual route; do the following actions: */
615 if ((same
&& rinfo
->metric
!= rte
->metric
)
616 || (rte
->metric
< rinfo
->metric
)
617 || ((same
) && (rinfo
->metric
== rte
->metric
)
618 && (newinfo
.tag
!= rinfo
->tag
))
619 || (old_dist
> new_dist
)
620 || ((old_dist
!= new_dist
) && same
)) {
621 if (listcount(list
) == 1) {
622 if (newinfo
.metric
!= RIP_METRIC_INFINITY
)
623 rip_ecmp_replace(&newinfo
);
625 rip_ecmp_delete(rinfo
);
627 if (newinfo
.metric
< rinfo
->metric
)
628 rip_ecmp_replace(&newinfo
);
629 else if (newinfo
.metric
> rinfo
->metric
)
630 rip_ecmp_delete(rinfo
);
631 else if (new_dist
< old_dist
)
632 rip_ecmp_replace(&newinfo
);
633 else if (new_dist
> old_dist
)
634 rip_ecmp_delete(rinfo
);
636 int update
= CHECK_FLAG(rinfo
->flags
,
641 assert(newinfo
.metric
642 != RIP_METRIC_INFINITY
);
644 RIP_TIMER_OFF(rinfo
->t_timeout
);
645 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
646 memcpy(rinfo
, &newinfo
,
647 sizeof(struct rip_info
));
648 rip_timeout_update(rinfo
);
651 rip_zebra_ipv4_add(rp
);
653 /* - Set the route change flag on the
655 rinfo
= listgetdata(listhead(list
));
656 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
657 rip_event(RIP_TRIGGERED_UPDATE
, 0);
660 } else /* same & no change */
661 rip_timeout_update(rinfo
);
663 /* Unlock tempolary lock of the route. */
664 route_unlock_node(rp
);
668 /* Dump RIP packet */
669 static void rip_packet_dump(struct rip_packet
*packet
, int size
,
674 const char *command_str
;
675 char pbuf
[BUFSIZ
], nbuf
[BUFSIZ
];
679 /* Set command string. */
680 if (packet
->command
> 0 && packet
->command
< RIP_COMMAND_MAX
)
681 command_str
= lookup_msg(rip_msg
, packet
->command
, NULL
);
683 command_str
= "unknown";
685 /* Dump packet header. */
686 zlog_debug("%s %s version %d packet size %d", sndrcv
, command_str
,
687 packet
->version
, size
);
689 /* Dump each routing table entry. */
692 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
693 if (packet
->version
== RIPv2
) {
694 netmask
= ip_masklen(rte
->mask
);
696 if (rte
->family
== htons(RIP_FAMILY_AUTH
)) {
698 == htons(RIP_AUTH_SIMPLE_PASSWORD
)) {
699 p
= (uint8_t *)&rte
->prefix
;
702 " family 0x%X type %d auth string: %s",
705 } else if (rte
->tag
== htons(RIP_AUTH_MD5
)) {
706 struct rip_md5_info
*md5
;
708 md5
= (struct rip_md5_info
*)&packet
712 " family 0x%X type %d (MD5 authentication)",
716 " RIP-2 packet len %d Key ID %d"
718 ntohs(md5
->packet_len
),
719 md5
->keyid
, md5
->auth_len
);
720 zlog_debug(" Sequence Number %ld",
721 (unsigned long)ntohl(
723 } else if (rte
->tag
== htons(RIP_AUTH_DATA
)) {
724 p
= (uint8_t *)&rte
->prefix
;
727 " family 0x%X type %d (MD5 data)",
731 " MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
732 "%02X%02X%02X%02X%02X%02X%02X%02X",
733 p
[0], p
[1], p
[2], p
[3], p
[4],
734 p
[5], p
[6], p
[7], p
[8], p
[9],
735 p
[10], p
[11], p
[12], p
[13],
739 " family 0x%X type %d (Unknown auth type)",
745 " %s/%d -> %s family %d tag %" ROUTE_TAG_PRI
747 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
,
750 inet_ntop(AF_INET
, &rte
->nexthop
, nbuf
,
753 (route_tag_t
)ntohs(rte
->tag
),
754 (unsigned long)ntohl(rte
->metric
));
757 " %s family %d tag %" ROUTE_TAG_PRI
759 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
761 (route_tag_t
)ntohs(rte
->tag
),
762 (unsigned long)ntohl(rte
->metric
));
767 /* Check if the destination address is valid (unicast; not net 0
768 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
769 check net 0 because we accept default route. */
770 static int rip_destination_check(struct in_addr addr
)
772 uint32_t destination
;
774 /* Convert to host byte order. */
775 destination
= ntohl(addr
.s_addr
);
777 if (IPV4_NET127(destination
))
780 /* Net 0 may match to the default route. */
781 if (IPV4_NET0(destination
) && destination
!= 0)
784 /* Unicast address must belong to class A, B, C. */
785 if (IN_CLASSA(destination
))
787 if (IN_CLASSB(destination
))
789 if (IN_CLASSC(destination
))
795 /* RIP version 2 authentication. */
796 static int rip_auth_simple_password(struct rte
*rte
, struct sockaddr_in
*from
,
797 struct interface
*ifp
)
799 struct rip_interface
*ri
;
800 char *auth_str
= (char *)rte
+ offsetof(struct rte
, prefix
);
803 /* reject passwords with zeros in the middle of the string */
804 for (i
= strnlen(auth_str
, 16); i
< 16; i
++) {
805 if (auth_str
[i
] != '\0')
809 if (IS_RIP_DEBUG_EVENT
)
810 zlog_debug("RIPv2 simple password authentication from %s",
811 inet_ntoa(from
->sin_addr
));
815 if (ri
->auth_type
!= RIP_AUTH_SIMPLE_PASSWORD
816 || rte
->tag
!= htons(RIP_AUTH_SIMPLE_PASSWORD
))
819 /* Simple password authentication. */
821 if (strncmp(auth_str
, ri
->auth_str
, 16) == 0)
825 struct keychain
*keychain
;
828 keychain
= keychain_lookup(ri
->key_chain
);
829 if (keychain
== NULL
|| keychain
->key
== NULL
)
832 key
= key_match_for_accept(keychain
, auth_str
);
839 /* RIP version 2 authentication with MD5. */
840 static int rip_auth_md5(struct rip_packet
*packet
, struct sockaddr_in
*from
,
841 int length
, struct interface
*ifp
)
843 struct rip_interface
*ri
;
844 struct rip_md5_info
*md5
;
845 struct rip_md5_data
*md5data
;
846 struct keychain
*keychain
;
849 uint8_t digest
[RIP_AUTH_MD5_SIZE
];
851 char auth_str
[RIP_AUTH_MD5_SIZE
];
853 if (IS_RIP_DEBUG_EVENT
)
854 zlog_debug("RIPv2 MD5 authentication from %s",
855 inet_ntoa(from
->sin_addr
));
858 md5
= (struct rip_md5_info
*)&packet
->rte
;
860 /* Check auth type. */
861 if (ri
->auth_type
!= RIP_AUTH_MD5
|| md5
->type
!= htons(RIP_AUTH_MD5
))
864 /* If the authentication length is less than 16, then it must be wrong
866 * any interpretation of rfc2082. Some implementations also interpret
867 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka
868 * RIP_AUTH_MD5_COMPAT_SIZE.
870 if (!((md5
->auth_len
== RIP_AUTH_MD5_SIZE
)
871 || (md5
->auth_len
== RIP_AUTH_MD5_COMPAT_SIZE
))) {
872 if (IS_RIP_DEBUG_EVENT
)
874 "RIPv2 MD5 authentication, strange authentication "
880 /* grab and verify check packet length */
881 packet_len
= ntohs(md5
->packet_len
);
883 if (packet_len
> (length
- RIP_HEADER_SIZE
- RIP_AUTH_MD5_SIZE
)) {
884 if (IS_RIP_DEBUG_EVENT
)
886 "RIPv2 MD5 authentication, packet length field %d "
887 "greater than received length %d!",
888 md5
->packet_len
, length
);
892 /* retrieve authentication data */
893 md5data
= (struct rip_md5_data
*)(((uint8_t *)packet
) + packet_len
);
895 memset(auth_str
, 0, RIP_AUTH_MD5_SIZE
);
898 keychain
= keychain_lookup(ri
->key_chain
);
899 if (keychain
== NULL
)
902 key
= key_lookup_for_accept(keychain
, md5
->keyid
);
903 if (key
== NULL
|| key
->string
== NULL
)
906 strncpy(auth_str
, key
->string
, RIP_AUTH_MD5_SIZE
);
907 } else if (ri
->auth_str
)
908 strncpy(auth_str
, ri
->auth_str
, RIP_AUTH_MD5_SIZE
);
910 if (auth_str
[0] == 0)
913 /* MD5 digest authentication. */
914 memset(&ctx
, 0, sizeof(ctx
));
916 MD5Update(&ctx
, packet
, packet_len
+ RIP_HEADER_SIZE
);
917 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
918 MD5Final(digest
, &ctx
);
920 if (memcmp(md5data
->digest
, digest
, RIP_AUTH_MD5_SIZE
) == 0)
926 /* Pick correct auth string for sends, prepare auth_str buffer for use.
927 * (left justified and padded).
929 * presumes one of ri or key is valid, and that the auth strings they point
930 * to are nul terminated. If neither are present, auth_str will be fully
934 static void rip_auth_prepare_str_send(struct rip_interface
*ri
, struct key
*key
,
935 char *auth_str
, int len
)
939 memset(auth_str
, 0, len
);
940 if (key
&& key
->string
)
941 strncpy(auth_str
, key
->string
, len
);
942 else if (ri
->auth_str
)
943 strncpy(auth_str
, ri
->auth_str
, len
);
948 /* Write RIPv2 simple password authentication information
950 * auth_str is presumed to be 2 bytes and correctly prepared
951 * (left justified and zero padded).
953 static void rip_auth_simple_write(struct stream
*s
, char *auth_str
, int len
)
955 assert(s
&& len
== RIP_AUTH_SIMPLE_SIZE
);
957 stream_putw(s
, RIP_FAMILY_AUTH
);
958 stream_putw(s
, RIP_AUTH_SIMPLE_PASSWORD
);
959 stream_put(s
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
964 /* write RIPv2 MD5 "authentication header"
965 * (uses the auth key data field)
967 * Digest offset field is set to 0.
969 * returns: offset of the digest offset field, which must be set when
970 * length to the auth-data MD5 digest is known.
972 static size_t rip_auth_md5_ah_write(struct stream
*s
, struct rip_interface
*ri
,
977 assert(s
&& ri
&& ri
->auth_type
== RIP_AUTH_MD5
);
979 /* MD5 authentication. */
980 stream_putw(s
, RIP_FAMILY_AUTH
);
981 stream_putw(s
, RIP_AUTH_MD5
);
983 /* MD5 AH digest offset field.
985 * Set to placeholder value here, to true value when RIP-2 Packet length
986 * is known. Actual value is set in .....().
988 doff
= stream_get_endp(s
);
993 stream_putc(s
, key
->index
% 256);
997 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
998 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for
1000 * to be configurable.
1002 stream_putc(s
, ri
->md5_auth_len
);
1004 /* Sequence Number (non-decreasing). */
1005 /* RFC2080: The value used in the sequence number is
1006 arbitrary, but two suggestions are the time of the
1007 message's creation or a simple message counter. */
1008 stream_putl(s
, time(NULL
));
1010 /* Reserved field must be zero. */
1017 /* If authentication is in used, write the appropriate header
1018 * returns stream offset to which length must later be written
1019 * or 0 if this is not required
1021 static size_t rip_auth_header_write(struct stream
*s
, struct rip_interface
*ri
,
1022 struct key
*key
, char *auth_str
, int len
)
1024 assert(ri
->auth_type
!= RIP_NO_AUTH
);
1026 switch (ri
->auth_type
) {
1027 case RIP_AUTH_SIMPLE_PASSWORD
:
1028 rip_auth_prepare_str_send(ri
, key
, auth_str
, len
);
1029 rip_auth_simple_write(s
, auth_str
, len
);
1032 return rip_auth_md5_ah_write(s
, ri
, key
);
1038 /* Write RIPv2 MD5 authentication data trailer */
1039 static void rip_auth_md5_set(struct stream
*s
, struct rip_interface
*ri
,
1040 size_t doff
, char *auth_str
, int authlen
)
1044 unsigned char digest
[RIP_AUTH_MD5_SIZE
];
1046 /* Make it sure this interface is configured as MD5
1048 assert((ri
->auth_type
== RIP_AUTH_MD5
)
1049 && (authlen
== RIP_AUTH_MD5_SIZE
));
1052 /* Get packet length. */
1053 len
= stream_get_endp(s
);
1055 /* Check packet length. */
1056 if (len
< (RIP_HEADER_SIZE
+ RIP_RTE_SIZE
)) {
1059 "rip_auth_md5_set(): packet length %ld is less than minimum length.",
1064 /* Set the digest offset length in the header */
1065 stream_putw_at(s
, doff
, len
);
1067 /* Set authentication data. */
1068 stream_putw(s
, RIP_FAMILY_AUTH
);
1069 stream_putw(s
, RIP_AUTH_DATA
);
1071 /* Generate a digest for the RIP packet. */
1072 memset(&ctx
, 0, sizeof(ctx
));
1074 MD5Update(&ctx
, STREAM_DATA(s
), stream_get_endp(s
));
1075 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1076 MD5Final(digest
, &ctx
);
1078 /* Copy the digest to the packet. */
1079 stream_write(s
, digest
, RIP_AUTH_MD5_SIZE
);
1082 /* RIP routing information. */
1083 static void rip_response_process(struct rip_packet
*packet
, int size
,
1084 struct sockaddr_in
*from
,
1085 struct connected
*ifc
)
1089 struct prefix_ipv4 ifaddr
;
1090 struct prefix_ipv4 ifaddrclass
;
1093 memset(&ifaddr
, 0, sizeof(ifaddr
));
1094 /* We don't know yet. */
1097 /* The Response must be ignored if it is not from the RIP
1098 port. (RFC2453 - Sec. 3.9.2)*/
1099 if (from
->sin_port
!= htons(RIP_PORT_DEFAULT
)) {
1100 zlog_info("response doesn't come from RIP port: %d",
1102 rip_peer_bad_packet(from
);
1106 /* The datagram's IPv4 source address should be checked to see
1107 whether the datagram is from a valid neighbor; the source of the
1108 datagram must be on a directly connected network (RFC2453 - Sec.
1110 if (if_lookup_address((void *)&from
->sin_addr
, AF_INET
, VRF_DEFAULT
)
1113 "This datagram doesn't came from a valid neighbor: %s",
1114 inet_ntoa(from
->sin_addr
));
1115 rip_peer_bad_packet(from
);
1119 /* It is also worth checking to see whether the response is from one
1120 of the router's own addresses. */
1122 ; /* Alredy done in rip_read () */
1124 /* Update RIP peer. */
1125 rip_peer_update(from
, packet
->version
);
1127 /* Set RTE pointer. */
1130 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
1131 /* RIPv2 authentication check. */
1132 /* If the Address Family Identifier of the first (and only the
1133 first) entry in the message is 0xFFFF, then the remainder of
1134 the entry contains the authentication. */
1135 /* If the packet gets here it means authentication enabled */
1136 /* Check is done in rip_read(). So, just skipping it */
1137 if (packet
->version
== RIPv2
&& rte
== packet
->rte
1138 && rte
->family
== htons(RIP_FAMILY_AUTH
))
1141 if (rte
->family
!= htons(AF_INET
)) {
1142 /* Address family check. RIP only supports AF_INET. */
1143 zlog_info("Unsupported family %d from %s.",
1145 inet_ntoa(from
->sin_addr
));
1149 /* - is the destination address valid (e.g., unicast; not net 0
1151 if (!rip_destination_check(rte
->prefix
)) {
1153 "Network is net 0 or net 127 or it is not unicast network");
1154 rip_peer_bad_route(from
);
1158 /* Convert metric value to host byte order. */
1159 rte
->metric
= ntohl(rte
->metric
);
1161 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1162 if (!(rte
->metric
>= 1 && rte
->metric
<= 16)) {
1163 zlog_info("Route's metric is not in the 1-16 range.");
1164 rip_peer_bad_route(from
);
1168 /* RIPv1 does not have nexthop value. */
1169 if (packet
->version
== RIPv1
&& rte
->nexthop
.s_addr
!= 0) {
1170 zlog_info("RIPv1 packet with nexthop value %s",
1171 inet_ntoa(rte
->nexthop
));
1172 rip_peer_bad_route(from
);
1176 /* That is, if the provided information is ignored, a possibly
1177 sub-optimal, but absolutely valid, route may be taken. If
1178 the received Next Hop is not directly reachable, it should be
1179 treated as 0.0.0.0. */
1180 if (packet
->version
== RIPv2
&& rte
->nexthop
.s_addr
!= 0) {
1183 /* Multicast address check. */
1184 addrval
= ntohl(rte
->nexthop
.s_addr
);
1185 if (IN_CLASSD(addrval
)) {
1187 "Nexthop %s is multicast address, skip this rte",
1188 inet_ntoa(rte
->nexthop
));
1192 if (!if_lookup_address((void *)&rte
->nexthop
, AF_INET
,
1194 struct route_node
*rn
;
1195 struct rip_info
*rinfo
;
1197 rn
= route_node_match_ipv4(rip
->table
,
1203 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1206 if (IS_RIP_DEBUG_EVENT
)
1208 "Next hop %s is on RIP network. Set nexthop to the packet's originator",
1211 rte
->nexthop
= rinfo
->from
;
1213 if (IS_RIP_DEBUG_EVENT
)
1215 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1218 rte
->nexthop
.s_addr
= 0;
1221 route_unlock_node(rn
);
1223 if (IS_RIP_DEBUG_EVENT
)
1225 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1228 rte
->nexthop
.s_addr
= 0;
1233 /* For RIPv1, there won't be a valid netmask.
1235 This is a best guess at the masks. If everyone was using old
1236 Ciscos before the 'ip subnet zero' option, it would be almost
1239 Cisco summarize ripv1 advertisements to the classful boundary
1240 (/16 for class B's) except when the RIP packet does to inside
1241 the classful network in question. */
1243 if ((packet
->version
== RIPv1
&& rte
->prefix
.s_addr
!= 0)
1244 || (packet
->version
== RIPv2
1245 && (rte
->prefix
.s_addr
!= 0
1246 && rte
->mask
.s_addr
== 0))) {
1247 uint32_t destination
;
1249 if (subnetted
== -1) {
1250 memcpy(&ifaddr
, ifc
->address
,
1251 sizeof(struct prefix_ipv4
));
1252 memcpy(&ifaddrclass
, &ifaddr
,
1253 sizeof(struct prefix_ipv4
));
1254 apply_classful_mask_ipv4(&ifaddrclass
);
1256 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1260 destination
= ntohl(rte
->prefix
.s_addr
);
1262 if (IN_CLASSA(destination
))
1263 masklen2ip(8, &rte
->mask
);
1264 else if (IN_CLASSB(destination
))
1265 masklen2ip(16, &rte
->mask
);
1266 else if (IN_CLASSC(destination
))
1267 masklen2ip(24, &rte
->mask
);
1270 masklen2ip(ifaddrclass
.prefixlen
,
1271 (struct in_addr
*)&destination
);
1272 if ((subnetted
== 1)
1273 && ((rte
->prefix
.s_addr
& destination
)
1274 == ifaddrclass
.prefix
.s_addr
)) {
1275 masklen2ip(ifaddr
.prefixlen
, &rte
->mask
);
1276 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1277 != rte
->prefix
.s_addr
)
1278 masklen2ip(32, &rte
->mask
);
1279 if (IS_RIP_DEBUG_EVENT
)
1280 zlog_debug("Subnetted route %s",
1281 inet_ntoa(rte
->prefix
));
1283 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1284 != rte
->prefix
.s_addr
)
1288 if (IS_RIP_DEBUG_EVENT
) {
1289 zlog_debug("Resultant route %s",
1290 inet_ntoa(rte
->prefix
));
1291 zlog_debug("Resultant mask %s",
1292 inet_ntoa(rte
->mask
));
1296 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1297 ignore the entry. */
1298 if ((packet
->version
== RIPv2
) && (rte
->mask
.s_addr
!= 0)
1299 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1300 != rte
->prefix
.s_addr
)) {
1302 "RIPv2 address %s is not mask /%d applied one",
1303 inet_ntoa(rte
->prefix
), ip_masklen(rte
->mask
));
1304 rip_peer_bad_route(from
);
1308 /* Default route's netmask is ignored. */
1309 if (packet
->version
== RIPv2
&& (rte
->prefix
.s_addr
== 0)
1310 && (rte
->mask
.s_addr
!= 0)) {
1311 if (IS_RIP_DEBUG_EVENT
)
1313 "Default route with non-zero netmask. Set zero to netmask");
1314 rte
->mask
.s_addr
= 0;
1317 /* Routing table updates. */
1318 rip_rte_process(rte
, from
, ifc
->ifp
);
1322 /* Make socket for RIP protocol. */
1323 int rip_create_socket(void)
1327 struct sockaddr_in addr
;
1329 memset(&addr
, 0, sizeof(struct sockaddr_in
));
1330 addr
.sin_family
= AF_INET
;
1331 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1332 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1333 addr
.sin_len
= sizeof(struct sockaddr_in
);
1334 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1335 /* sending port must always be the RIP port */
1336 addr
.sin_port
= htons(RIP_PORT_DEFAULT
);
1338 /* Make datagram socket. */
1339 sock
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
1341 flog_err_sys(EC_LIB_SOCKET
, "Cannot create UDP socket: %s",
1342 safe_strerror(errno
));
1346 sockopt_broadcast(sock
);
1347 sockopt_reuseaddr(sock
);
1348 sockopt_reuseport(sock
);
1349 setsockopt_ipv4_multicast_loop(sock
, 0);
1351 setsockopt_pktinfo(sock
);
1352 #endif /* RIP_RECVMSG */
1353 #ifdef IPTOS_PREC_INTERNETCONTROL
1354 setsockopt_ipv4_tos(sock
, IPTOS_PREC_INTERNETCONTROL
);
1357 frr_elevate_privs(&ripd_privs
) {
1358 setsockopt_so_recvbuf(sock
, RIP_UDP_RCV_BUF
);
1359 if ((ret
= bind(sock
, (struct sockaddr
*)&addr
, sizeof(addr
)))
1361 zlog_err("%s: Can't bind socket %d to %s port %d: %s",
1362 __func__
, sock
, inet_ntoa(addr
.sin_addr
),
1363 (int)ntohs(addr
.sin_port
),
1364 safe_strerror(errno
));
1374 /* RIP packet send to destination address, on interface denoted by
1375 * by connected argument. NULL to argument denotes destination should be
1376 * should be RIP multicast group
1378 static int rip_send_packet(uint8_t *buf
, int size
, struct sockaddr_in
*to
,
1379 struct connected
*ifc
)
1382 struct sockaddr_in sin
;
1384 assert(ifc
!= NULL
);
1386 if (IS_RIP_DEBUG_PACKET
) {
1387 #define ADDRESS_SIZE 20
1388 char dst
[ADDRESS_SIZE
];
1389 dst
[ADDRESS_SIZE
- 1] = '\0';
1392 strncpy(dst
, inet_ntoa(to
->sin_addr
), ADDRESS_SIZE
- 1);
1394 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1395 strncpy(dst
, inet_ntoa(sin
.sin_addr
), ADDRESS_SIZE
- 1);
1398 zlog_debug("rip_send_packet %s > %s (%s)",
1399 inet_ntoa(ifc
->address
->u
.prefix4
), dst
,
1403 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
1405 * ZEBRA_IFA_SECONDARY is set on linux when an interface is
1407 * with multiple addresses on the same subnet: the first address
1408 * on the subnet is configured "primary", and all subsequent
1410 * on that subnet are treated as "secondary" addresses.
1411 * In order to avoid routing-table bloat on other rip listeners,
1412 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY
1414 * XXX Since Linux is the only system for which the
1415 * ZEBRA_IFA_SECONDARY
1416 * flag is set, we would end up sending a packet for a
1418 * source address on non-linux systems.
1420 if (IS_RIP_DEBUG_PACKET
)
1421 zlog_debug("duplicate dropped");
1425 /* Make destination address. */
1426 memset(&sin
, 0, sizeof(struct sockaddr_in
));
1427 sin
.sin_family
= AF_INET
;
1428 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1429 sin
.sin_len
= sizeof(struct sockaddr_in
);
1430 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1432 /* When destination is specified, use it's port and address. */
1434 sin
.sin_port
= to
->sin_port
;
1435 sin
.sin_addr
= to
->sin_addr
;
1437 sin
.sin_port
= htons(RIP_PORT_DEFAULT
);
1438 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1440 rip_interface_multicast_set(rip
->sock
, ifc
);
1443 ret
= sendto(rip
->sock
, buf
, size
, 0, (struct sockaddr
*)&sin
,
1444 sizeof(struct sockaddr_in
));
1446 if (IS_RIP_DEBUG_EVENT
)
1447 zlog_debug("SEND to %s.%d", inet_ntoa(sin
.sin_addr
),
1448 ntohs(sin
.sin_port
));
1451 zlog_warn("can't send packet : %s", safe_strerror(errno
));
1456 /* Add redistributed route to RIP table. */
1457 void rip_redistribute_add(int type
, int sub_type
, struct prefix_ipv4
*p
,
1458 struct nexthop
*nh
, unsigned int metric
,
1459 unsigned char distance
, route_tag_t tag
)
1462 struct route_node
*rp
= NULL
;
1463 struct rip_info
*rinfo
= NULL
, newinfo
;
1464 struct list
*list
= NULL
;
1466 /* Redistribute route */
1467 ret
= rip_destination_check(p
->prefix
);
1471 rp
= route_node_get(rip
->table
, (struct prefix
*)p
);
1473 memset(&newinfo
, 0, sizeof(struct rip_info
));
1474 newinfo
.type
= type
;
1475 newinfo
.sub_type
= sub_type
;
1477 newinfo
.external_metric
= metric
;
1478 newinfo
.distance
= distance
;
1479 if (tag
<= UINT16_MAX
) /* RIP only supports 16 bit tags */
1484 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
1485 rinfo
= listgetdata(listhead(list
));
1487 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
1488 && rinfo
->sub_type
== RIP_ROUTE_INTERFACE
1489 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
1490 route_unlock_node(rp
);
1494 /* Manually configured RIP route check. */
1495 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1496 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
1497 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))) {
1498 if (type
!= ZEBRA_ROUTE_RIP
1499 || ((sub_type
!= RIP_ROUTE_STATIC
)
1500 && (sub_type
!= RIP_ROUTE_DEFAULT
))) {
1501 route_unlock_node(rp
);
1506 (void)rip_ecmp_replace(&newinfo
);
1507 route_unlock_node(rp
);
1509 (void)rip_ecmp_add(&newinfo
);
1511 if (IS_RIP_DEBUG_EVENT
) {
1512 zlog_debug("Redistribute new prefix %s/%d",
1513 inet_ntoa(p
->prefix
), p
->prefixlen
);
1516 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1519 /* Delete redistributed route from RIP table. */
1520 void rip_redistribute_delete(int type
, int sub_type
, struct prefix_ipv4
*p
,
1524 struct route_node
*rp
;
1525 struct rip_info
*rinfo
;
1527 ret
= rip_destination_check(p
->prefix
);
1531 rp
= route_node_lookup(rip
->table
, (struct prefix
*)p
);
1533 struct list
*list
= rp
->info
;
1535 if (list
!= NULL
&& listcount(list
) != 0) {
1536 rinfo
= listgetdata(listhead(list
));
1537 if (rinfo
!= NULL
&& rinfo
->type
== type
1538 && rinfo
->sub_type
== sub_type
1539 && rinfo
->nh
.ifindex
== ifindex
) {
1540 /* Perform poisoned reverse. */
1541 rinfo
->metric
= RIP_METRIC_INFINITY
;
1542 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
1543 rip_garbage_collect
,
1545 RIP_TIMER_OFF(rinfo
->t_timeout
);
1546 rinfo
->flags
|= RIP_RTF_CHANGED
;
1548 if (IS_RIP_DEBUG_EVENT
)
1550 "Poison %s/%d on the interface %s with an "
1551 "infinity metric [delete]",
1552 inet_ntoa(p
->prefix
),
1554 ifindex2ifname(ifindex
,
1557 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1560 route_unlock_node(rp
);
1564 /* Response to request called from rip_read ().*/
1565 static void rip_request_process(struct rip_packet
*packet
, int size
,
1566 struct sockaddr_in
*from
, struct connected
*ifc
)
1570 struct prefix_ipv4 p
;
1571 struct route_node
*rp
;
1572 struct rip_info
*rinfo
;
1573 struct rip_interface
*ri
;
1575 /* Does not reponse to the requests on the loopback interfaces */
1576 if (if_is_loopback(ifc
->ifp
))
1579 /* Check RIP process is enabled on this interface. */
1580 ri
= ifc
->ifp
->info
;
1584 /* When passive interface is specified, suppress responses */
1588 /* RIP peer update. */
1589 rip_peer_update(from
, packet
->version
);
1591 lim
= ((caddr_t
)packet
) + size
;
1594 /* The Request is processed entry by entry. If there are no
1595 entries, no response is given. */
1596 if (lim
== (caddr_t
)rte
)
1599 /* There is one special case. If there is exactly one entry in the
1600 request, and it has an address family identifier of zero and a
1601 metric of infinity (i.e., 16), then this is a request to send the
1602 entire routing table. */
1603 if (lim
== ((caddr_t
)(rte
+ 1)) && ntohs(rte
->family
) == 0
1604 && ntohl(rte
->metric
) == RIP_METRIC_INFINITY
) {
1605 /* All route with split horizon */
1606 rip_output_process(ifc
, from
, rip_all_route
, packet
->version
);
1608 if (ntohs(rte
->family
) != AF_INET
)
1611 /* Examine the list of RTEs in the Request one by one. For each
1612 entry, look up the destination in the router's routing
1613 database and, if there is a route, put that route's metric in
1614 the metric field of the RTE. If there is no explicit route
1615 to the specified destination, put infinity in the metric
1616 field. Once all the entries have been filled in, change the
1617 command from Request to Response and send the datagram back
1618 to the requestor. */
1621 for (; ((caddr_t
)rte
) < lim
; rte
++) {
1622 p
.prefix
= rte
->prefix
;
1623 p
.prefixlen
= ip_masklen(rte
->mask
);
1624 apply_mask_ipv4(&p
);
1626 rp
= route_node_lookup(rip
->table
, (struct prefix
*)&p
);
1628 rinfo
= listgetdata(
1629 listhead((struct list
*)rp
->info
));
1630 rte
->metric
= htonl(rinfo
->metric
);
1631 route_unlock_node(rp
);
1633 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
1635 packet
->command
= RIP_RESPONSE
;
1637 (void)rip_send_packet((uint8_t *)packet
, size
, from
, ifc
);
1639 rip_global_queries
++;
1643 /* Set IPv6 packet info to the socket. */
1644 static int setsockopt_pktinfo(int sock
)
1649 ret
= setsockopt(sock
, IPPROTO_IP
, IP_PKTINFO
, &val
, sizeof(val
));
1651 zlog_warn("Can't setsockopt IP_PKTINFO : %s",
1652 safe_strerror(errno
));
1656 /* Read RIP packet by recvmsg function. */
1657 int rip_recvmsg(int sock
, uint8_t *buf
, int size
, struct sockaddr_in
*from
,
1663 struct cmsghdr
*ptr
;
1666 memset(&msg
, 0, sizeof(msg
));
1667 msg
.msg_name
= (void *)from
;
1668 msg
.msg_namelen
= sizeof(struct sockaddr_in
);
1671 msg
.msg_control
= (void *)adata
;
1672 msg
.msg_controllen
= sizeof adata
;
1676 ret
= recvmsg(sock
, &msg
, 0);
1680 for (ptr
= ZCMSG_FIRSTHDR(&msg
); ptr
!= NULL
;
1681 ptr
= CMSG_NXTHDR(&msg
, ptr
))
1682 if (ptr
->cmsg_level
== IPPROTO_IP
1683 && ptr
->cmsg_type
== IP_PKTINFO
) {
1684 struct in_pktinfo
*pktinfo
;
1687 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(ptr
);
1688 i
= pktinfo
->ipi_ifindex
;
1693 /* RIP packet read function. */
1694 int rip_read_new(struct thread
*t
)
1698 char buf
[RIP_PACKET_MAXSIZ
];
1699 struct sockaddr_in from
;
1702 /* Fetch socket then register myself. */
1703 sock
= THREAD_FD(t
);
1704 rip_event(RIP_READ
, sock
);
1706 /* Read RIP packet. */
1707 ret
= rip_recvmsg(sock
, buf
, RIP_PACKET_MAXSIZ
, &from
, (int *)&ifindex
);
1709 zlog_warn("Can't read RIP packet: %s", safe_strerror(errno
));
1715 #endif /* RIP_RECVMSG */
1717 /* First entry point of RIP packet. */
1718 static int rip_read(struct thread
*t
)
1723 union rip_buf rip_buf
;
1724 struct rip_packet
*packet
;
1725 struct sockaddr_in from
;
1729 struct interface
*ifp
= NULL
;
1730 struct connected
*ifc
;
1731 struct rip_interface
*ri
;
1734 /* Fetch socket then register myself. */
1735 sock
= THREAD_FD(t
);
1738 /* Add myself to tne next event */
1739 rip_event(RIP_READ
, sock
);
1741 /* RIPd manages only IPv4. */
1742 memset(&from
, 0, sizeof(struct sockaddr_in
));
1743 fromlen
= sizeof(struct sockaddr_in
);
1745 len
= recvfrom(sock
, (char *)&rip_buf
.buf
, sizeof(rip_buf
.buf
), 0,
1746 (struct sockaddr
*)&from
, &fromlen
);
1748 zlog_info("recvfrom failed: %s", safe_strerror(errno
));
1752 /* Check is this packet comming from myself? */
1753 if (if_check_address(from
.sin_addr
)) {
1754 if (IS_RIP_DEBUG_PACKET
)
1755 zlog_debug("ignore packet comes from myself");
1759 /* Which interface is this packet comes from. */
1760 ifc
= if_lookup_address((void *)&from
.sin_addr
, AF_INET
, VRF_DEFAULT
);
1764 /* RIP packet received */
1765 if (IS_RIP_DEBUG_EVENT
)
1766 zlog_debug("RECV packet from %s port %d on %s",
1767 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1768 ifp
? ifp
->name
: "unknown");
1770 /* If this packet come from unknown interface, ignore it. */
1773 "rip_read: cannot find interface for packet from %s port %d",
1774 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
));
1779 p
.u
.prefix4
= from
.sin_addr
;
1780 p
.prefixlen
= IPV4_MAX_BITLEN
;
1782 ifc
= connected_lookup_prefix(ifp
, &p
);
1786 "rip_read: cannot find connected address for packet from %s "
1787 "port %d on interface %s",
1788 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1793 /* Packet length check. */
1794 if (len
< RIP_PACKET_MINSIZ
) {
1795 zlog_warn("packet size %d is smaller than minimum size %d", len
,
1797 rip_peer_bad_packet(&from
);
1800 if (len
> RIP_PACKET_MAXSIZ
) {
1801 zlog_warn("packet size %d is larger than max size %d", len
,
1803 rip_peer_bad_packet(&from
);
1807 /* Packet alignment check. */
1808 if ((len
- RIP_PACKET_MINSIZ
) % 20) {
1809 zlog_warn("packet size %d is wrong for RIP packet alignment",
1811 rip_peer_bad_packet(&from
);
1815 /* Set RTE number. */
1816 rtenum
= ((len
- RIP_PACKET_MINSIZ
) / 20);
1818 /* For easy to handle. */
1819 packet
= &rip_buf
.rip_packet
;
1821 /* RIP version check. */
1822 if (packet
->version
== 0) {
1823 zlog_info("version 0 with command %d received.",
1825 rip_peer_bad_packet(&from
);
1829 /* Dump RIP packet. */
1830 if (IS_RIP_DEBUG_RECV
)
1831 rip_packet_dump(packet
, len
, "RECV");
1833 /* RIP version adjust. This code should rethink now. RFC1058 says
1834 that "Version 1 implementations are to ignore this extra data and
1835 process only the fields specified in this document.". So RIPv3
1836 packet should be treated as RIPv1 ignoring must be zero field. */
1837 if (packet
->version
> RIPv2
)
1838 packet
->version
= RIPv2
;
1840 /* Is RIP running or is this RIP neighbor ?*/
1842 if (!ri
->running
&& !rip_neighbor_lookup(&from
)) {
1843 if (IS_RIP_DEBUG_EVENT
)
1844 zlog_debug("RIP is not enabled on interface %s.",
1846 rip_peer_bad_packet(&from
);
1850 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1851 vrecv
= ((ri
->ri_receive
== RI_RIP_UNSPEC
) ? rip
->version_recv
1853 if (vrecv
== RI_RIP_VERSION_NONE
1854 || ((packet
->version
== RIPv1
) && !(vrecv
& RIPv1
))
1855 || ((packet
->version
== RIPv2
) && !(vrecv
& RIPv2
))) {
1856 if (IS_RIP_DEBUG_PACKET
)
1858 " packet's v%d doesn't fit to if version spec",
1860 rip_peer_bad_packet(&from
);
1864 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1865 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1866 accepted; authenticated RIP-2 messages shall be discarded. */
1867 if ((ri
->auth_type
== RIP_NO_AUTH
) && rtenum
1868 && (packet
->version
== RIPv2
)
1869 && (packet
->rte
->family
== htons(RIP_FAMILY_AUTH
))) {
1870 if (IS_RIP_DEBUG_EVENT
)
1872 "packet RIPv%d is dropped because authentication disabled",
1874 ripd_notif_send_auth_type_failure(ifp
->name
);
1875 rip_peer_bad_packet(&from
);
1880 If the router is configured to authenticate RIP-2 messages, then
1881 RIP-1 messages and RIP-2 messages which pass authentication
1882 testing shall be accepted; unauthenticated and failed
1883 authentication RIP-2 messages shall be discarded. For maximum
1884 security, RIP-1 messages should be ignored when authentication is
1885 in use (see section 4.1); otherwise, the routing information from
1886 authenticated messages will be propagated by RIP-1 routers in an
1887 unauthenticated manner.
1889 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1890 * always reply regardless of authentication settings, because:
1892 * - if there other authorised routers on-link, the REQUESTor can
1893 * passively obtain the routing updates anyway
1894 * - if there are no other authorised routers on-link, RIP can
1895 * easily be disabled for the link to prevent giving out information
1896 * on state of this routers RIP routing table..
1898 * I.e. if RIPv1 has any place anymore these days, it's as a very
1899 * simple way to distribute routing information (e.g. to embedded
1900 * hosts / appliances) and the ability to give out RIPv1
1901 * routing-information freely, while still requiring RIPv2
1902 * authentication for any RESPONSEs might be vaguely useful.
1904 if (ri
->auth_type
!= RIP_NO_AUTH
&& packet
->version
== RIPv1
) {
1905 /* Discard RIPv1 messages other than REQUESTs */
1906 if (packet
->command
!= RIP_REQUEST
) {
1907 if (IS_RIP_DEBUG_PACKET
)
1910 " dropped because authentication enabled");
1911 ripd_notif_send_auth_type_failure(ifp
->name
);
1912 rip_peer_bad_packet(&from
);
1915 } else if (ri
->auth_type
!= RIP_NO_AUTH
) {
1916 const char *auth_desc
;
1919 /* There definitely is no authentication in the packet.
1921 if (IS_RIP_DEBUG_PACKET
)
1923 "RIPv2 authentication failed: no auth RTE in packet");
1924 ripd_notif_send_auth_type_failure(ifp
->name
);
1925 rip_peer_bad_packet(&from
);
1929 /* First RTE must be an Authentication Family RTE */
1930 if (packet
->rte
->family
!= htons(RIP_FAMILY_AUTH
)) {
1931 if (IS_RIP_DEBUG_PACKET
)
1934 " dropped because authentication enabled");
1935 ripd_notif_send_auth_type_failure(ifp
->name
);
1936 rip_peer_bad_packet(&from
);
1940 /* Check RIPv2 authentication. */
1941 switch (ntohs(packet
->rte
->tag
)) {
1942 case RIP_AUTH_SIMPLE_PASSWORD
:
1943 auth_desc
= "simple";
1944 ret
= rip_auth_simple_password(packet
->rte
, &from
, ifp
);
1949 ret
= rip_auth_md5(packet
, &from
, len
, ifp
);
1950 /* Reset RIP packet length to trim MD5 data. */
1956 auth_desc
= "unknown type";
1957 if (IS_RIP_DEBUG_PACKET
)
1959 "RIPv2 Unknown authentication type %d",
1960 ntohs(packet
->rte
->tag
));
1964 if (IS_RIP_DEBUG_PACKET
)
1965 zlog_debug("RIPv2 %s authentication success",
1968 if (IS_RIP_DEBUG_PACKET
)
1969 zlog_debug("RIPv2 %s authentication failure",
1971 ripd_notif_send_auth_failure(ifp
->name
);
1972 rip_peer_bad_packet(&from
);
1977 /* Process each command. */
1978 switch (packet
->command
) {
1980 rip_response_process(packet
, len
, &from
, ifc
);
1984 rip_request_process(packet
, len
, &from
, ifc
);
1989 "Obsolete command %s received, please sent it to routed",
1990 lookup_msg(rip_msg
, packet
->command
, NULL
));
1991 rip_peer_bad_packet(&from
);
1993 case RIP_POLL_ENTRY
:
1994 zlog_info("Obsolete command %s received",
1995 lookup_msg(rip_msg
, packet
->command
, NULL
));
1996 rip_peer_bad_packet(&from
);
1999 zlog_info("Unknown RIP command %d received", packet
->command
);
2000 rip_peer_bad_packet(&from
);
2007 /* Write routing table entry to the stream and return next index of
2008 the routing table entry in the stream. */
2009 static int rip_write_rte(int num
, struct stream
*s
, struct prefix_ipv4
*p
,
2010 uint8_t version
, struct rip_info
*rinfo
)
2012 struct in_addr mask
;
2014 /* Write routing table entry. */
2015 if (version
== RIPv1
) {
2016 stream_putw(s
, AF_INET
);
2018 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2019 stream_put_ipv4(s
, 0);
2020 stream_put_ipv4(s
, 0);
2021 stream_putl(s
, rinfo
->metric_out
);
2023 masklen2ip(p
->prefixlen
, &mask
);
2025 stream_putw(s
, AF_INET
);
2026 stream_putw(s
, rinfo
->tag_out
);
2027 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2028 stream_put_ipv4(s
, mask
.s_addr
);
2029 stream_put_ipv4(s
, rinfo
->nexthop_out
.s_addr
);
2030 stream_putl(s
, rinfo
->metric_out
);
2036 /* Send update to the ifp or spcified neighbor. */
2037 void rip_output_process(struct connected
*ifc
, struct sockaddr_in
*to
,
2038 int route_type
, uint8_t version
)
2042 struct route_node
*rp
;
2043 struct rip_info
*rinfo
;
2044 struct rip_interface
*ri
;
2045 struct prefix_ipv4
*p
;
2046 struct prefix_ipv4 classfull
;
2047 struct prefix_ipv4 ifaddrclass
;
2048 struct key
*key
= NULL
;
2049 /* this might need to made dynamic if RIP ever supported auth methods
2050 with larger key string sizes */
2051 char auth_str
[RIP_AUTH_SIMPLE_SIZE
];
2052 size_t doff
= 0; /* offset of digest offset field */
2056 struct list
*list
= NULL
;
2057 struct listnode
*listnode
= NULL
;
2059 /* Logging output event. */
2060 if (IS_RIP_DEBUG_EVENT
) {
2062 zlog_debug("update routes to neighbor %s",
2063 inet_ntoa(to
->sin_addr
));
2065 zlog_debug("update routes on interface %s ifindex %d",
2066 ifc
->ifp
->name
, ifc
->ifp
->ifindex
);
2069 /* Set output stream. */
2072 /* Reset stream and RTE counter. */
2074 rtemax
= RIP_MAX_RTE
;
2076 /* Get RIP interface. */
2077 ri
= ifc
->ifp
->info
;
2079 /* If output interface is in simple password authentication mode, we
2080 need space for authentication data. */
2081 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2084 /* If output interface is in MD5 authentication mode, we need space
2085 for authentication header and data. */
2086 if (ri
->auth_type
== RIP_AUTH_MD5
)
2089 /* If output interface is in simple password authentication mode
2090 and string or keychain is specified we need space for auth. data */
2091 if (ri
->auth_type
!= RIP_NO_AUTH
) {
2092 if (ri
->key_chain
) {
2093 struct keychain
*keychain
;
2095 keychain
= keychain_lookup(ri
->key_chain
);
2097 key
= key_lookup_for_send(keychain
);
2099 /* to be passed to auth functions later */
2100 rip_auth_prepare_str_send(ri
, key
, auth_str
,
2101 RIP_AUTH_SIMPLE_SIZE
);
2102 if (strlen(auth_str
) == 0)
2106 if (version
== RIPv1
) {
2107 memcpy(&ifaddrclass
, ifc
->address
, sizeof(struct prefix_ipv4
));
2108 apply_classful_mask_ipv4(&ifaddrclass
);
2110 if (ifc
->address
->prefixlen
> ifaddrclass
.prefixlen
)
2114 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2115 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
2116 rinfo
= listgetdata(listhead(list
));
2117 /* For RIPv1, if we are subnetted, output subnets in our
2119 /* that have the same mask as the output "interface".
2121 /* networks, only the classfull version is output. */
2123 if (version
== RIPv1
) {
2124 p
= (struct prefix_ipv4
*)&rp
->p
;
2126 if (IS_RIP_DEBUG_PACKET
)
2128 "RIPv1 mask check, %s/%d considered for output",
2129 inet_ntoa(rp
->p
.u
.prefix4
),
2134 (struct prefix
*)&ifaddrclass
,
2136 if ((ifc
->address
->prefixlen
2138 && (rp
->p
.prefixlen
!= 32))
2141 memcpy(&classfull
, &rp
->p
,
2142 sizeof(struct prefix_ipv4
));
2143 apply_classful_mask_ipv4(&classfull
);
2144 if (rp
->p
.u
.prefix4
.s_addr
!= 0
2145 && classfull
.prefixlen
2149 if (IS_RIP_DEBUG_PACKET
)
2151 "RIPv1 mask check, %s/%d made it through",
2152 inet_ntoa(rp
->p
.u
.prefix4
),
2155 p
= (struct prefix_ipv4
*)&rp
->p
;
2157 /* Apply output filters. */
2158 ret
= rip_filter(RIP_FILTER_OUT
, p
, ri
);
2162 /* Changed route only output. */
2163 if (route_type
== rip_changed_route
2164 && (!(rinfo
->flags
& RIP_RTF_CHANGED
)))
2167 /* Split horizon. */
2168 /* if (split_horizon == rip_split_horizon) */
2169 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
) {
2171 * We perform split horizon for RIP and
2173 * For rip routes, we want to suppress the route
2175 * end up sending the route back on the
2177 * learned it from, with a higher metric. For
2179 * we suppress the route if the prefix is a
2181 * source address that we are going to use for
2183 * (in order to handle the case when multiple
2185 * configured on the same interface).
2188 struct rip_info
*tmp_rinfo
= NULL
;
2189 struct connected
*tmp_ifc
= NULL
;
2191 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2193 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2194 && tmp_rinfo
->nh
.ifindex
2195 == ifc
->ifp
->ifindex
) {
2201 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2202 for (ALL_LIST_ELEMENTS_RO(
2203 ifc
->ifp
->connected
,
2207 tmp_ifc
->address
)) {
2217 /* Preparation for route-map. */
2218 rinfo
->metric_set
= 0;
2219 rinfo
->nexthop_out
.s_addr
= 0;
2220 rinfo
->metric_out
= rinfo
->metric
;
2221 rinfo
->tag_out
= rinfo
->tag
;
2222 rinfo
->ifindex_out
= ifc
->ifp
->ifindex
;
2224 /* In order to avoid some local loops,
2225 * if the RIP route has a nexthop via this interface,
2227 * otherwise set it to 0. The nexthop should not be
2229 * beyond the local broadcast/multicast area in order
2230 * to avoid an IGP multi-level recursive look-up.
2233 if (rinfo
->nh
.ifindex
== ifc
->ifp
->ifindex
)
2234 rinfo
->nexthop_out
= rinfo
->nh
.gate
.ipv4
;
2236 /* Interface route-map */
2237 if (ri
->routemap
[RIP_FILTER_OUT
]) {
2238 ret
= route_map_apply(
2239 ri
->routemap
[RIP_FILTER_OUT
],
2240 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2242 if (ret
== RMAP_DENYMATCH
) {
2243 if (IS_RIP_DEBUG_PACKET
)
2245 "RIP %s/%d is filtered by route-map out",
2246 inet_ntoa(p
->prefix
),
2252 /* Apply redistribute route map - continue, if deny */
2253 if (rip
->route_map
[rinfo
->type
].name
2254 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2255 ret
= route_map_apply(
2256 rip
->route_map
[rinfo
->type
].map
,
2257 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2259 if (ret
== RMAP_DENYMATCH
) {
2260 if (IS_RIP_DEBUG_PACKET
)
2262 "%s/%d is filtered by route-map",
2263 inet_ntoa(p
->prefix
),
2269 /* When route-map does not set metric. */
2270 if (!rinfo
->metric_set
) {
2271 /* If redistribute metric is set. */
2272 if (rip
->route_map
[rinfo
->type
].metric_config
2273 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
2275 rip
->route_map
[rinfo
->type
]
2278 /* If the route is not connected or
2280 one, use default-metric value*/
2281 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2283 != ZEBRA_ROUTE_CONNECT
2285 != RIP_METRIC_INFINITY
)
2287 rip
->default_metric
;
2291 /* Apply offset-list */
2292 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2293 rip_offset_list_apply_out(p
, ifc
->ifp
,
2294 &rinfo
->metric_out
);
2296 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2297 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2299 /* Perform split-horizon with poisoned reverse
2300 * for RIP and connected routes.
2302 if (ri
->split_horizon
2303 == RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2305 * We perform split horizon for RIP and
2307 * For rip routes, we want to suppress the route
2309 * end up sending the route back on the
2311 * learned it from, with a higher metric. For
2313 * we suppress the route if the prefix is a
2315 * source address that we are going to use for
2317 * (in order to handle the case when multiple
2319 * configured on the same interface).
2321 struct rip_info
*tmp_rinfo
= NULL
;
2322 struct connected
*tmp_ifc
= NULL
;
2324 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2326 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2327 && tmp_rinfo
->nh
.ifindex
2328 == ifc
->ifp
->ifindex
)
2330 RIP_METRIC_INFINITY
;
2332 if (rinfo
->metric_out
!= RIP_METRIC_INFINITY
2333 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2334 for (ALL_LIST_ELEMENTS_RO(
2335 ifc
->ifp
->connected
,
2339 tmp_ifc
->address
)) {
2341 RIP_METRIC_INFINITY
;
2347 /* Prepare preamble, auth headers, if needs be */
2349 stream_putc(s
, RIP_RESPONSE
);
2350 stream_putc(s
, version
);
2353 /* auth header for !v1 && !no_auth */
2354 if ((ri
->auth_type
!= RIP_NO_AUTH
)
2355 && (version
!= RIPv1
))
2356 doff
= rip_auth_header_write(
2357 s
, ri
, key
, auth_str
,
2358 RIP_AUTH_SIMPLE_SIZE
);
2361 /* Write RTE to the stream. */
2362 num
= rip_write_rte(num
, s
, p
, version
, rinfo
);
2363 if (num
== rtemax
) {
2364 if (version
== RIPv2
2365 && ri
->auth_type
== RIP_AUTH_MD5
)
2366 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2367 RIP_AUTH_SIMPLE_SIZE
);
2369 ret
= rip_send_packet(STREAM_DATA(s
),
2370 stream_get_endp(s
), to
,
2373 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2374 rip_packet_dump((struct rip_packet
*)
2383 /* Flush unwritten RTE. */
2385 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2386 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2387 RIP_AUTH_SIMPLE_SIZE
);
2389 ret
= rip_send_packet(STREAM_DATA(s
), stream_get_endp(s
), to
,
2392 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2393 rip_packet_dump((struct rip_packet
*)STREAM_DATA(s
),
2394 stream_get_endp(s
), "SEND");
2398 /* Statistics updates. */
2402 /* Send RIP packet to the interface. */
2403 static void rip_update_interface(struct connected
*ifc
, uint8_t version
,
2406 struct interface
*ifp
= ifc
->ifp
;
2407 struct rip_interface
*ri
= ifp
->info
;
2408 struct sockaddr_in to
;
2410 /* When RIP version is 2 and multicast enable interface. */
2411 if (version
== RIPv2
&& !ri
->v2_broadcast
&& if_is_multicast(ifp
)) {
2412 if (IS_RIP_DEBUG_EVENT
)
2413 zlog_debug("multicast announce on %s ", ifp
->name
);
2415 rip_output_process(ifc
, NULL
, route_type
, version
);
2419 /* If we can't send multicast packet, send it with unicast. */
2420 if (if_is_broadcast(ifp
) || if_is_pointopoint(ifp
)) {
2421 if (ifc
->address
->family
== AF_INET
) {
2422 /* Destination address and port setting. */
2423 memset(&to
, 0, sizeof(struct sockaddr_in
));
2424 if (ifc
->destination
)
2425 /* use specified broadcast or peer destination
2427 to
.sin_addr
= ifc
->destination
->u
.prefix4
;
2428 else if (ifc
->address
->prefixlen
< IPV4_MAX_PREFIXLEN
)
2429 /* calculate the appropriate broadcast address
2431 to
.sin_addr
.s_addr
= ipv4_broadcast_addr(
2432 ifc
->address
->u
.prefix4
.s_addr
,
2433 ifc
->address
->prefixlen
);
2435 /* do not know where to send the packet */
2437 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2439 if (IS_RIP_DEBUG_EVENT
)
2440 zlog_debug("%s announce to %s on %s",
2441 CONNECTED_PEER(ifc
) ? "unicast"
2443 inet_ntoa(to
.sin_addr
), ifp
->name
);
2445 rip_output_process(ifc
, &to
, route_type
, version
);
2450 /* Update send to all interface and neighbor. */
2451 static void rip_update_process(int route_type
)
2453 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2454 struct listnode
*ifnode
, *ifnnode
;
2455 struct connected
*connected
;
2456 struct interface
*ifp
;
2457 struct rip_interface
*ri
;
2458 struct route_node
*rp
;
2459 struct sockaddr_in to
;
2462 /* Send RIP update to each interface. */
2463 FOR_ALL_INTERFACES (vrf
, ifp
) {
2464 if (if_is_loopback(ifp
))
2467 if (!if_is_operative(ifp
))
2470 /* Fetch RIP interface information. */
2473 /* When passive interface is specified, suppress announce to the
2480 * If there is no version configuration in the
2482 * use rip's version setting.
2484 int vsend
= ((ri
->ri_send
== RI_RIP_UNSPEC
)
2488 if (IS_RIP_DEBUG_EVENT
)
2489 zlog_debug("SEND UPDATE to %s ifindex %d",
2490 ifp
->name
, ifp
->ifindex
);
2492 /* send update on each connected network */
2493 for (ALL_LIST_ELEMENTS(ifp
->connected
, ifnode
, ifnnode
,
2495 if (connected
->address
->family
== AF_INET
) {
2497 rip_update_interface(
2501 && if_is_multicast(ifp
))
2502 rip_update_interface(
2510 /* RIP send updates to each neighbor. */
2511 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
2512 if (rp
->info
!= NULL
) {
2515 connected
= if_lookup_address(&p
->u
.prefix4
, AF_INET
,
2519 "Neighbor %s doesn't have connected interface!",
2520 inet_ntoa(p
->u
.prefix4
));
2524 /* Set destination address and port */
2525 memset(&to
, 0, sizeof(struct sockaddr_in
));
2526 to
.sin_addr
= p
->u
.prefix4
;
2527 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2529 /* RIP version is rip's configuration. */
2530 rip_output_process(connected
, &to
, route_type
,
2535 /* RIP's periodical timer. */
2536 static int rip_update(struct thread
*t
)
2538 /* Clear timer pointer. */
2539 rip
->t_update
= NULL
;
2541 if (IS_RIP_DEBUG_EVENT
)
2542 zlog_debug("update timer fire!");
2544 /* Process update output. */
2545 rip_update_process(rip_all_route
);
2547 /* Triggered updates may be suppressed if a regular update is due by
2548 the time the triggered update would be sent. */
2549 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2552 /* Register myself. */
2553 rip_event(RIP_UPDATE_EVENT
, 0);
2558 /* Walk down the RIP routing table then clear changed flag. */
2559 static void rip_clear_changed_flag(void)
2561 struct route_node
*rp
;
2562 struct rip_info
*rinfo
= NULL
;
2563 struct list
*list
= NULL
;
2564 struct listnode
*listnode
= NULL
;
2566 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2567 if ((list
= rp
->info
) != NULL
)
2568 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
2569 UNSET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2570 /* This flag can be set only on the first entry.
2576 /* Triggered update interval timer. */
2577 static int rip_triggered_interval(struct thread
*t
)
2579 int rip_triggered_update(struct thread
*);
2581 rip
->t_triggered_interval
= NULL
;
2585 rip_triggered_update(t
);
2590 /* Execute triggered update. */
2591 static int rip_triggered_update(struct thread
*t
)
2595 /* Clear thred pointer. */
2596 rip
->t_triggered_update
= NULL
;
2598 /* Cancel interval timer. */
2599 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2602 /* Logging triggered update. */
2603 if (IS_RIP_DEBUG_EVENT
)
2604 zlog_debug("triggered update!");
2606 /* Split Horizon processing is done when generating triggered
2607 updates as well as normal updates (see section 2.6). */
2608 rip_update_process(rip_changed_route
);
2610 /* Once all of the triggered updates have been generated, the route
2611 change flags should be cleared. */
2612 rip_clear_changed_flag();
2614 /* After a triggered update is sent, a timer should be set for a
2615 random interval between 1 and 5 seconds. If other changes that
2616 would trigger updates occur before the timer expires, a single
2617 update is triggered when the timer expires. */
2618 interval
= (random() % 5) + 1;
2620 rip
->t_triggered_interval
= NULL
;
2621 thread_add_timer(master
, rip_triggered_interval
, NULL
, interval
,
2622 &rip
->t_triggered_interval
);
2627 /* Withdraw redistributed route. */
2628 void rip_redistribute_withdraw(int type
)
2630 struct route_node
*rp
;
2631 struct rip_info
*rinfo
= NULL
;
2632 struct list
*list
= NULL
;
2637 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2638 if ((list
= rp
->info
) != NULL
) {
2639 rinfo
= listgetdata(listhead(list
));
2640 if (rinfo
->type
== type
2641 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2642 /* Perform poisoned reverse. */
2643 rinfo
->metric
= RIP_METRIC_INFINITY
;
2644 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
2645 rip_garbage_collect
,
2647 RIP_TIMER_OFF(rinfo
->t_timeout
);
2648 rinfo
->flags
|= RIP_RTF_CHANGED
;
2650 if (IS_RIP_DEBUG_EVENT
) {
2651 struct prefix_ipv4
*p
=
2652 (struct prefix_ipv4
*)&rp
->p
;
2655 "Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2656 inet_ntoa(p
->prefix
),
2663 rip_event(RIP_TRIGGERED_UPDATE
, 0);
2668 /* Create new RIP instance and set it to global variable. */
2669 int rip_create(int socket
)
2671 rip
= XCALLOC(MTYPE_RIP
, sizeof(struct rip
));
2673 /* Set initial value. */
2674 rip
->ecmp
= yang_get_default_bool("%s/allow-ecmp", RIP_INSTANCE
);
2675 rip
->default_metric
=
2676 yang_get_default_uint8("%s/default-metric", RIP_INSTANCE
);
2678 yang_get_default_uint8("%s/distance/default", RIP_INSTANCE
);
2679 rip
->passive_default
=
2680 yang_get_default_bool("%s/passive-default", RIP_INSTANCE
);
2681 rip
->garbage_time
= yang_get_default_uint32("%s/timers/flush-interval",
2683 rip
->timeout_time
= yang_get_default_uint32(
2684 "%s/timers/holddown-interval", RIP_INSTANCE
);
2685 rip
->update_time
= yang_get_default_uint32("%s/timers/update-interval",
2688 yang_get_default_enum("%s/version/send", RIP_INSTANCE
);
2690 yang_get_default_enum("%s/version/receive", RIP_INSTANCE
);
2692 /* Initialize RIP routig table. */
2693 rip
->table
= route_table_init();
2694 rip
->neighbor
= route_table_init();
2696 /* Make output stream. */
2697 rip
->obuf
= stream_new(1500);
2702 /* Create read and timer thread. */
2703 rip_event(RIP_READ
, rip
->sock
);
2704 rip_event(RIP_UPDATE_EVENT
, 1);
2709 /* Sned RIP request to the destination. */
2710 int rip_request_send(struct sockaddr_in
*to
, struct interface
*ifp
,
2711 uint8_t version
, struct connected
*connected
)
2714 struct rip_packet rip_packet
;
2715 struct listnode
*node
, *nnode
;
2717 memset(&rip_packet
, 0, sizeof(rip_packet
));
2719 rip_packet
.command
= RIP_REQUEST
;
2720 rip_packet
.version
= version
;
2721 rte
= rip_packet
.rte
;
2722 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
2726 * connected is only sent for ripv1 case, or when
2727 * interface does not support multicast. Caller loops
2728 * over each connected address for this case.
2730 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2732 != sizeof(rip_packet
))
2735 return sizeof(rip_packet
);
2738 /* send request on each connected network */
2739 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, connected
)) {
2740 struct prefix_ipv4
*p
;
2742 p
= (struct prefix_ipv4
*)connected
->address
;
2744 if (p
->family
!= AF_INET
)
2747 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2749 != sizeof(rip_packet
))
2752 return sizeof(rip_packet
);
2755 static int rip_update_jitter(unsigned long time
)
2757 #define JITTER_BOUND 4
2758 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2759 Given that, we cannot let time be less than JITTER_BOUND seconds.
2760 The RIPv2 RFC says jitter should be small compared to
2761 update_time. We consider 1/JITTER_BOUND to be small.
2764 int jitter_input
= time
;
2767 if (jitter_input
< JITTER_BOUND
)
2768 jitter_input
= JITTER_BOUND
;
2770 jitter
= (((random() % ((jitter_input
* 2) + 1)) - jitter_input
));
2772 return jitter
/ JITTER_BOUND
;
2775 void rip_event(enum rip_event event
, int sock
)
2782 thread_add_read(master
, rip_read
, NULL
, sock
, &rip
->t_read
);
2784 case RIP_UPDATE_EVENT
:
2785 RIP_TIMER_OFF(rip
->t_update
);
2786 jitter
= rip_update_jitter(rip
->update_time
);
2787 thread_add_timer(master
, rip_update
, NULL
,
2788 sock
? 2 : rip
->update_time
+ jitter
,
2791 case RIP_TRIGGERED_UPDATE
:
2792 if (rip
->t_triggered_interval
)
2795 thread_add_event(master
, rip_triggered_update
, NULL
, 0,
2796 &rip
->t_triggered_update
);
2805 rip_update_default_metric (void)
2807 struct route_node
*np
;
2808 struct rip_info
*rinfo
= NULL
;
2809 struct list
*list
= NULL
;
2810 struct listnode
*listnode
= NULL
;
2812 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
2813 if ((list
= np
->info
) != NULL
)
2814 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
2815 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
2816 rinfo
->metric
= rip
->default_metric
;
2821 struct route_table
*rip_distance_table
;
2823 struct rip_distance
*rip_distance_new(void)
2825 return XCALLOC(MTYPE_RIP_DISTANCE
, sizeof(struct rip_distance
));
2828 void rip_distance_free(struct rip_distance
*rdistance
)
2830 XFREE(MTYPE_RIP_DISTANCE
, rdistance
);
2833 static void rip_distance_reset(void)
2835 struct route_node
*rn
;
2836 struct rip_distance
*rdistance
;
2838 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
2839 if ((rdistance
= rn
->info
) != NULL
) {
2840 if (rdistance
->access_list
)
2841 free(rdistance
->access_list
);
2842 rip_distance_free(rdistance
);
2844 route_unlock_node(rn
);
2848 /* Apply RIP information to distance method. */
2849 uint8_t rip_distance_apply(struct rip_info
*rinfo
)
2851 struct route_node
*rn
;
2852 struct prefix_ipv4 p
;
2853 struct rip_distance
*rdistance
;
2854 struct access_list
*alist
;
2859 memset(&p
, 0, sizeof(struct prefix_ipv4
));
2861 p
.prefix
= rinfo
->from
;
2862 p
.prefixlen
= IPV4_MAX_BITLEN
;
2864 /* Check source address. */
2865 rn
= route_node_match(rip_distance_table
, (struct prefix
*)&p
);
2867 rdistance
= rn
->info
;
2868 route_unlock_node(rn
);
2870 if (rdistance
->access_list
) {
2871 alist
= access_list_lookup(AFI_IP
,
2872 rdistance
->access_list
);
2875 if (access_list_apply(alist
, &rinfo
->rp
->p
)
2879 return rdistance
->distance
;
2881 return rdistance
->distance
;
2885 return rip
->distance
;
2890 static void rip_distance_show(struct vty
*vty
)
2892 struct route_node
*rn
;
2893 struct rip_distance
*rdistance
;
2897 vty_out(vty
, " Distance: (default is %u)\n",
2898 rip
->distance
? rip
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
);
2900 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
2901 if ((rdistance
= rn
->info
) != NULL
) {
2904 " Address Distance List\n");
2907 sprintf(buf
, "%s/%d", inet_ntoa(rn
->p
.u
.prefix4
),
2909 vty_out(vty
, " %-20s %4d %s\n", buf
,
2910 rdistance
->distance
,
2911 rdistance
->access_list
? rdistance
->access_list
2916 /* Update ECMP routes to zebra when ECMP is disabled. */
2917 void rip_ecmp_disable(void)
2919 struct route_node
*rp
;
2920 struct rip_info
*rinfo
, *tmp_rinfo
;
2922 struct listnode
*node
, *nextnode
;
2927 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2928 if ((list
= rp
->info
) != NULL
&& listcount(list
) > 1) {
2929 rinfo
= listgetdata(listhead(list
));
2930 if (!rip_route_rte(rinfo
))
2933 /* Drop all other entries, except the first one. */
2934 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
2935 if (tmp_rinfo
!= rinfo
) {
2936 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
2938 tmp_rinfo
->t_garbage_collect
);
2939 list_delete_node(list
, node
);
2940 rip_info_free(tmp_rinfo
);
2944 rip_zebra_ipv4_add(rp
);
2946 /* Set the route change flag. */
2947 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2949 /* Signal the output process to trigger an update. */
2950 rip_event(RIP_TRIGGERED_UPDATE
, 0);
2954 /* Print out routes update time. */
2955 static void rip_vty_out_uptime(struct vty
*vty
, struct rip_info
*rinfo
)
2960 char timebuf
[TIME_BUF
];
2961 struct thread
*thread
;
2963 if ((thread
= rinfo
->t_timeout
) != NULL
) {
2964 clock
= thread_timer_remain_second(thread
);
2965 tm
= gmtime(&clock
);
2966 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
2967 vty_out(vty
, "%5s", timebuf
);
2968 } else if ((thread
= rinfo
->t_garbage_collect
) != NULL
) {
2969 clock
= thread_timer_remain_second(thread
);
2970 tm
= gmtime(&clock
);
2971 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
2972 vty_out(vty
, "%5s", timebuf
);
2976 static const char *rip_route_type_print(int sub_type
)
2981 case RIP_ROUTE_STATIC
:
2983 case RIP_ROUTE_DEFAULT
:
2985 case RIP_ROUTE_REDISTRIBUTE
:
2987 case RIP_ROUTE_INTERFACE
:
2999 "Show RIP routes\n")
3001 struct route_node
*np
;
3002 struct rip_info
*rinfo
= NULL
;
3003 struct list
*list
= NULL
;
3004 struct listnode
*listnode
= NULL
;
3010 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
3012 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
3013 " (i) - interface\n\n"
3014 " Network Next Hop Metric From Tag Time\n");
3016 for (np
= route_top(rip
->table
); np
; np
= route_next(np
))
3017 if ((list
= np
->info
) != NULL
)
3018 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3022 vty
, "%c(%s) %s/%d",
3023 /* np->lock, For debugging. */
3024 zebra_route_char(rinfo
->type
),
3025 rip_route_type_print(rinfo
->sub_type
),
3026 inet_ntoa(np
->p
.u
.prefix4
),
3032 vty_out(vty
, "%*s", len
, " ");
3034 switch (rinfo
->nh
.type
) {
3035 case NEXTHOP_TYPE_IPV4
:
3036 case NEXTHOP_TYPE_IPV4_IFINDEX
:
3037 vty_out(vty
, "%-20s %2d ",
3038 inet_ntoa(rinfo
->nh
.gate
.ipv4
),
3041 case NEXTHOP_TYPE_IFINDEX
:
3046 case NEXTHOP_TYPE_BLACKHOLE
:
3051 case NEXTHOP_TYPE_IPV6
:
3052 case NEXTHOP_TYPE_IPV6_IFINDEX
:
3054 "V6 Address Hidden %2d ",
3059 /* Route which exist in kernel routing table. */
3060 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
)
3061 && (rinfo
->sub_type
== RIP_ROUTE_RTE
)) {
3062 vty_out(vty
, "%-15s ",
3063 inet_ntoa(rinfo
->from
));
3064 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3065 (route_tag_t
)rinfo
->tag
);
3066 rip_vty_out_uptime(vty
, rinfo
);
3067 } else if (rinfo
->metric
3068 == RIP_METRIC_INFINITY
) {
3069 vty_out(vty
, "self ");
3070 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3071 (route_tag_t
)rinfo
->tag
);
3072 rip_vty_out_uptime(vty
, rinfo
);
3074 if (rinfo
->external_metric
) {
3076 vty
, "self (%s:%d)",
3079 rinfo
->external_metric
);
3082 vty_out(vty
, "%*s", len
,
3087 vty_out(vty
, "%3" ROUTE_TAG_PRI
,
3088 (route_tag_t
)rinfo
->tag
);
3096 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3097 DEFUN (show_ip_rip_status
,
3098 show_ip_rip_status_cmd
,
3099 "show ip rip status",
3103 "IP routing protocol process parameters and statistics\n")
3105 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3106 struct interface
*ifp
;
3107 struct rip_interface
*ri
;
3108 extern const struct message ri_version_msg
[];
3109 const char *send_version
;
3110 const char *receive_version
;
3115 vty_out(vty
, "Routing Protocol is \"rip\"\n");
3116 vty_out(vty
, " Sending updates every %u seconds with +/-50%%,",
3118 vty_out(vty
, " next due in %lu seconds\n",
3119 thread_timer_remain_second(rip
->t_update
));
3120 vty_out(vty
, " Timeout after %u seconds,", rip
->timeout_time
);
3121 vty_out(vty
, " garbage collect after %u seconds\n", rip
->garbage_time
);
3123 /* Filtering status show. */
3124 config_show_distribute(vty
);
3126 /* Default metric information. */
3127 vty_out(vty
, " Default redistribution metric is %u\n",
3128 rip
->default_metric
);
3130 /* Redistribute information. */
3131 vty_out(vty
, " Redistributing:");
3132 rip_show_redistribute_config(vty
);
3135 vty_out(vty
, " Default version control: send version %s,",
3136 lookup_msg(ri_version_msg
, rip
->version_send
, NULL
));
3137 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3138 vty_out(vty
, " receive any version \n");
3140 vty_out(vty
, " receive version %s \n",
3141 lookup_msg(ri_version_msg
, rip
->version_recv
, NULL
));
3143 vty_out(vty
, " Interface Send Recv Key-chain\n");
3145 FOR_ALL_INTERFACES (vrf
, ifp
) {
3151 if (ri
->enable_network
|| ri
->enable_interface
) {
3152 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3154 lookup_msg(ri_version_msg
,
3155 rip
->version_send
, NULL
);
3157 send_version
= lookup_msg(ri_version_msg
,
3160 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3162 lookup_msg(ri_version_msg
,
3163 rip
->version_recv
, NULL
);
3165 receive_version
= lookup_msg(
3166 ri_version_msg
, ri
->ri_receive
, NULL
);
3168 vty_out(vty
, " %-17s%-3s %-3s %s\n", ifp
->name
,
3169 send_version
, receive_version
,
3170 ri
->key_chain
? ri
->key_chain
: "");
3174 vty_out(vty
, " Routing for Networks:\n");
3175 rip_show_network_config(vty
);
3178 int found_passive
= 0;
3179 FOR_ALL_INTERFACES (vrf
, ifp
) {
3182 if ((ri
->enable_network
|| ri
->enable_interface
)
3184 if (!found_passive
) {
3186 " Passive Interface(s):\n");
3189 vty_out(vty
, " %s\n", ifp
->name
);
3194 vty_out(vty
, " Routing Information Sources:\n");
3196 " Gateway BadPackets BadRoutes Distance Last Update\n");
3197 rip_peer_display(vty
);
3199 rip_distance_show(vty
);
3204 /* RIP configuration write function. */
3205 static int config_write_rip(struct vty
*vty
)
3208 struct lyd_node
*dnode
;
3210 dnode
= yang_dnode_get(running_config
->dnode
,
3211 "/frr-ripd:ripd/instance");
3215 nb_cli_show_dnode_cmds(vty
, dnode
, false);
3217 /* Distribute configuration. */
3218 write
+= config_write_distribute(vty
);
3220 /* Interface routemap configuration */
3221 write
+= config_write_if_rmap(vty
);
3226 /* RIP node structure. */
3227 static struct cmd_node rip_node
= {RIP_NODE
, "%s(config-router)# ", 1};
3229 /* Distribute-list update functions. */
3230 static void rip_distribute_update(struct distribute
*dist
)
3232 struct interface
*ifp
;
3233 struct rip_interface
*ri
;
3234 struct access_list
*alist
;
3235 struct prefix_list
*plist
;
3240 ifp
= if_lookup_by_name(dist
->ifname
, VRF_DEFAULT
);
3246 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
3247 alist
= access_list_lookup(AFI_IP
,
3248 dist
->list
[DISTRIBUTE_V4_IN
]);
3250 ri
->list
[RIP_FILTER_IN
] = alist
;
3252 ri
->list
[RIP_FILTER_IN
] = NULL
;
3254 ri
->list
[RIP_FILTER_IN
] = NULL
;
3256 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
3257 alist
= access_list_lookup(AFI_IP
,
3258 dist
->list
[DISTRIBUTE_V4_OUT
]);
3260 ri
->list
[RIP_FILTER_OUT
] = alist
;
3262 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3264 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3266 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
3267 plist
= prefix_list_lookup(AFI_IP
,
3268 dist
->prefix
[DISTRIBUTE_V4_IN
]);
3270 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3272 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3274 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3276 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
3277 plist
= prefix_list_lookup(AFI_IP
,
3278 dist
->prefix
[DISTRIBUTE_V4_OUT
]);
3280 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3282 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3284 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3287 void rip_distribute_update_interface(struct interface
*ifp
)
3289 struct distribute
*dist
;
3291 dist
= distribute_lookup(ifp
->name
);
3293 rip_distribute_update(dist
);
3296 /* Update all interface's distribute list. */
3298 static void rip_distribute_update_all(struct prefix_list
*notused
)
3300 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3301 struct interface
*ifp
;
3303 FOR_ALL_INTERFACES (vrf
, ifp
)
3304 rip_distribute_update_interface(ifp
);
3307 static void rip_distribute_update_all_wrapper(struct access_list
*notused
)
3309 rip_distribute_update_all(NULL
);
3312 /* Delete all added rip route. */
3313 void rip_clean(void)
3316 struct route_node
*rp
;
3317 struct rip_info
*rinfo
= NULL
;
3318 struct list
*list
= NULL
;
3319 struct listnode
*listnode
= NULL
;
3322 /* Clear RIP routes */
3323 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3324 if ((list
= rp
->info
) != NULL
) {
3325 rinfo
= listgetdata(listhead(list
));
3326 if (rip_route_rte(rinfo
))
3327 rip_zebra_ipv4_delete(rp
);
3329 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
3331 RIP_TIMER_OFF(rinfo
->t_timeout
);
3332 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
3333 rip_info_free(rinfo
);
3337 route_unlock_node(rp
);
3340 /* Cancel RIP related timers. */
3341 RIP_TIMER_OFF(rip
->t_update
);
3342 RIP_TIMER_OFF(rip
->t_triggered_update
);
3343 RIP_TIMER_OFF(rip
->t_triggered_interval
);
3345 /* Cancel read thread. */
3346 THREAD_READ_OFF(rip
->t_read
);
3348 /* Close RIP socket. */
3349 if (rip
->sock
>= 0) {
3354 stream_free(rip
->obuf
);
3356 /* RIP neighbor configuration. */
3357 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
3360 route_unlock_node(rp
);
3363 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3364 if (rip
->route_map
[i
].name
)
3365 free(rip
->route_map
[i
].name
);
3367 route_table_finish(rip
->table
);
3368 route_table_finish(rip
->neighbor
);
3370 XFREE(MTYPE_RIP
, rip
);
3374 rip_clean_network();
3375 rip_passive_nondefault_clean();
3377 rip_interfaces_clean();
3378 rip_distance_reset();
3379 rip_redistribute_clean();
3382 static void rip_if_rmap_update(struct if_rmap
*if_rmap
)
3384 struct interface
*ifp
;
3385 struct rip_interface
*ri
;
3386 struct route_map
*rmap
;
3388 ifp
= if_lookup_by_name(if_rmap
->ifname
, VRF_DEFAULT
);
3394 if (if_rmap
->routemap
[IF_RMAP_IN
]) {
3395 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_IN
]);
3397 ri
->routemap
[IF_RMAP_IN
] = rmap
;
3399 ri
->routemap
[IF_RMAP_IN
] = NULL
;
3401 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
3403 if (if_rmap
->routemap
[IF_RMAP_OUT
]) {
3404 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_OUT
]);
3406 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
3408 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
3410 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
3413 void rip_if_rmap_update_interface(struct interface
*ifp
)
3415 struct if_rmap
*if_rmap
;
3417 if_rmap
= if_rmap_lookup(ifp
->name
);
3419 rip_if_rmap_update(if_rmap
);
3422 static void rip_routemap_update_redistribute(void)
3427 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3428 if (rip
->route_map
[i
].name
)
3429 rip
->route_map
[i
].map
=
3430 route_map_lookup_by_name(
3431 rip
->route_map
[i
].name
);
3437 static void rip_routemap_update(const char *notused
)
3439 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3440 struct interface
*ifp
;
3442 FOR_ALL_INTERFACES (vrf
, ifp
)
3443 rip_if_rmap_update_interface(ifp
);
3445 rip_routemap_update_redistribute();
3448 /* Allocate new rip structure and set default value. */
3451 /* Install top nodes. */
3452 install_node(&rip_node
, config_write_rip
);
3454 /* Install rip commands. */
3455 install_element(VIEW_NODE
, &show_ip_rip_cmd
);
3456 install_element(VIEW_NODE
, &show_ip_rip_status_cmd
);
3458 install_default(RIP_NODE
);
3460 /* Debug related init. */
3463 /* Access list install. */
3465 access_list_add_hook(rip_distribute_update_all_wrapper
);
3466 access_list_delete_hook(rip_distribute_update_all_wrapper
);
3468 /* Prefix list initialize.*/
3470 prefix_list_add_hook(rip_distribute_update_all
);
3471 prefix_list_delete_hook(rip_distribute_update_all
);
3473 /* Distribute list install. */
3474 distribute_list_init(RIP_NODE
);
3475 distribute_list_add_hook(rip_distribute_update
);
3476 distribute_list_delete_hook(rip_distribute_update
);
3479 rip_route_map_init();
3482 route_map_add_hook(rip_routemap_update
);
3483 route_map_delete_hook(rip_routemap_update
);
3485 if_rmap_init(RIP_NODE
);
3486 if_rmap_hook_add(rip_if_rmap_update
);
3487 if_rmap_hook_delete(rip_if_rmap_update
);
3489 /* Distance control. */
3490 rip_distance_table
= route_table_init();