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"
52 /* UDP receive buffer size */
53 #define RIP_UDP_RCV_BUF 41600
56 struct rip
*rip
= NULL
;
58 /* RIP neighbor address table. */
59 struct route_table
*rip_neighbor_table
;
61 /* RIP route changes. */
62 long rip_global_route_changes
= 0;
65 long rip_global_queries
= 0;
68 static void rip_event(enum rip_event
, int);
69 static void rip_output_process(struct connected
*, struct sockaddr_in
*, int,
71 static int rip_triggered_update(struct thread
*);
72 static int rip_update_jitter(unsigned long);
74 /* RIP output routes type. */
75 enum { rip_all_route
, rip_changed_route
};
77 /* RIP command strings. */
78 static const struct message rip_msg
[] = {{RIP_REQUEST
, "REQUEST"},
79 {RIP_RESPONSE
, "RESPONSE"},
80 {RIP_TRACEON
, "TRACEON"},
81 {RIP_TRACEOFF
, "TRACEOFF"},
83 {RIP_POLL_ENTRY
, "POLL ENTRY"},
86 /* Utility function to set boradcast option to the socket. */
87 static int sockopt_broadcast(int sock
)
92 ret
= setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, (char *)&on
,
95 zlog_warn("can't set sockopt SO_BROADCAST to socket %d", sock
);
101 static int rip_route_rte(struct rip_info
*rinfo
)
103 return (rinfo
->type
== ZEBRA_ROUTE_RIP
104 && rinfo
->sub_type
== RIP_ROUTE_RTE
);
107 static struct rip_info
*rip_info_new(void)
109 return XCALLOC(MTYPE_RIP_INFO
, sizeof(struct rip_info
));
112 void rip_info_free(struct rip_info
*rinfo
)
114 XFREE(MTYPE_RIP_INFO
, rinfo
);
117 /* RIP route garbage collect timer. */
118 static int rip_garbage_collect(struct thread
*t
)
120 struct rip_info
*rinfo
;
121 struct route_node
*rp
;
123 rinfo
= THREAD_ARG(t
);
124 rinfo
->t_garbage_collect
= NULL
;
126 /* Off timeout timer. */
127 RIP_TIMER_OFF(rinfo
->t_timeout
);
129 /* Get route_node pointer. */
132 /* Unlock route_node. */
133 listnode_delete(rp
->info
, rinfo
);
134 if (list_isempty((struct list
*)rp
->info
)) {
135 list_delete((struct list
**)&rp
->info
);
136 route_unlock_node(rp
);
139 /* Free RIP routing information. */
140 rip_info_free(rinfo
);
145 static void rip_timeout_update(struct rip_info
*rinfo
);
147 /* Add new route to the ECMP list.
148 * RETURN: the new entry added in the list, or NULL if it is not the first
149 * entry and ECMP is not allowed.
151 struct rip_info
*rip_ecmp_add(struct rip_info
*rinfo_new
)
153 struct route_node
*rp
= rinfo_new
->rp
;
154 struct rip_info
*rinfo
= NULL
;
155 struct list
*list
= NULL
;
157 if (rp
->info
== NULL
)
158 rp
->info
= list_new();
159 list
= (struct list
*)rp
->info
;
161 /* If ECMP is not allowed and some entry already exists in the list,
163 if (listcount(list
) && !rip
->ecmp
)
166 rinfo
= rip_info_new();
167 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
168 listnode_add(list
, rinfo
);
170 if (rip_route_rte(rinfo
)) {
171 rip_timeout_update(rinfo
);
172 rip_zebra_ipv4_add(rp
);
175 /* Set the route change flag on the first entry. */
176 rinfo
= listgetdata(listhead(list
));
177 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
179 /* Signal the output process to trigger an update (see section 2.5). */
180 rip_event(RIP_TRIGGERED_UPDATE
, 0);
185 /* Replace the ECMP list with the new route.
186 * RETURN: the new entry added in the list
188 struct rip_info
*rip_ecmp_replace(struct rip_info
*rinfo_new
)
190 struct route_node
*rp
= rinfo_new
->rp
;
191 struct list
*list
= (struct list
*)rp
->info
;
192 struct rip_info
*rinfo
= NULL
, *tmp_rinfo
= NULL
;
193 struct listnode
*node
= NULL
, *nextnode
= NULL
;
195 if (list
== NULL
|| listcount(list
) == 0)
196 return rip_ecmp_add(rinfo_new
);
198 /* Get the first entry */
199 rinfo
= listgetdata(listhead(list
));
201 /* Learnt route replaced by a local one. Delete it from zebra. */
202 if (rip_route_rte(rinfo
) && !rip_route_rte(rinfo_new
))
203 if (CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
204 rip_zebra_ipv4_delete(rp
);
206 /* Re-use the first entry, and delete the others. */
207 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
208 if (tmp_rinfo
!= rinfo
) {
209 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
210 RIP_TIMER_OFF(tmp_rinfo
->t_garbage_collect
);
211 list_delete_node(list
, node
);
212 rip_info_free(tmp_rinfo
);
215 RIP_TIMER_OFF(rinfo
->t_timeout
);
216 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
217 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
219 if (rip_route_rte(rinfo
)) {
220 rip_timeout_update(rinfo
);
221 /* The ADD message implies an update. */
222 rip_zebra_ipv4_add(rp
);
225 /* Set the route change flag. */
226 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
228 /* Signal the output process to trigger an update (see section 2.5). */
229 rip_event(RIP_TRIGGERED_UPDATE
, 0);
234 /* Delete one route from the ECMP list.
236 * null - the entry is freed, and other entries exist in the list
237 * the entry - the entry is the last one in the list; its metric is set
238 * to INFINITY, and the garbage collector is started for it
240 struct rip_info
*rip_ecmp_delete(struct rip_info
*rinfo
)
242 struct route_node
*rp
= rinfo
->rp
;
243 struct list
*list
= (struct list
*)rp
->info
;
245 RIP_TIMER_OFF(rinfo
->t_timeout
);
247 if (listcount(list
) > 1) {
248 /* Some other ECMP entries still exist. Just delete this entry.
250 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
251 listnode_delete(list
, rinfo
);
252 if (rip_route_rte(rinfo
)
253 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
254 /* The ADD message implies the update. */
255 rip_zebra_ipv4_add(rp
);
256 rip_info_free(rinfo
);
259 assert(rinfo
== listgetdata(listhead(list
)));
261 /* This is the only entry left in the list. We must keep it in
262 * the list for garbage collection time, with INFINITY metric.
265 rinfo
->metric
= RIP_METRIC_INFINITY
;
266 RIP_TIMER_ON(rinfo
->t_garbage_collect
, rip_garbage_collect
,
269 if (rip_route_rte(rinfo
)
270 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
271 rip_zebra_ipv4_delete(rp
);
274 /* Set the route change flag on the first entry. */
275 rinfo
= listgetdata(listhead(list
));
276 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
278 /* Signal the output process to trigger an update (see section 2.5). */
279 rip_event(RIP_TRIGGERED_UPDATE
, 0);
284 /* Timeout RIP routes. */
285 static int rip_timeout(struct thread
*t
)
287 rip_ecmp_delete((struct rip_info
*)THREAD_ARG(t
));
291 static void rip_timeout_update(struct rip_info
*rinfo
)
293 if (rinfo
->metric
!= RIP_METRIC_INFINITY
) {
294 RIP_TIMER_OFF(rinfo
->t_timeout
);
295 RIP_TIMER_ON(rinfo
->t_timeout
, rip_timeout
, rip
->timeout_time
);
299 static int rip_filter(int rip_distribute
, struct prefix_ipv4
*p
,
300 struct rip_interface
*ri
)
302 struct distribute
*dist
;
303 struct access_list
*alist
;
304 struct prefix_list
*plist
;
305 int distribute
= rip_distribute
== RIP_FILTER_OUT
? DISTRIBUTE_V4_OUT
307 const char *inout
= rip_distribute
== RIP_FILTER_OUT
? "out" : "in";
309 /* Input distribute-list filtering. */
310 if (ri
->list
[rip_distribute
]) {
311 if (access_list_apply(ri
->list
[rip_distribute
],
314 if (IS_RIP_DEBUG_PACKET
)
315 zlog_debug("%s/%d filtered by distribute %s",
316 inet_ntoa(p
->prefix
), p
->prefixlen
,
321 if (ri
->prefix
[rip_distribute
]) {
322 if (prefix_list_apply(ri
->prefix
[rip_distribute
],
325 if (IS_RIP_DEBUG_PACKET
)
326 zlog_debug("%s/%d filtered by prefix-list %s",
327 inet_ntoa(p
->prefix
), p
->prefixlen
,
333 /* All interface filter check. */
334 dist
= distribute_lookup(NULL
);
336 if (dist
->list
[distribute
]) {
337 alist
= access_list_lookup(AFI_IP
,
338 dist
->list
[distribute
]);
341 if (access_list_apply(alist
, (struct prefix
*)p
)
343 if (IS_RIP_DEBUG_PACKET
)
345 "%s/%d filtered by distribute %s",
346 inet_ntoa(p
->prefix
),
347 p
->prefixlen
, inout
);
352 if (dist
->prefix
[distribute
]) {
353 plist
= prefix_list_lookup(AFI_IP
,
354 dist
->prefix
[distribute
]);
357 if (prefix_list_apply(plist
, (struct prefix
*)p
)
359 if (IS_RIP_DEBUG_PACKET
)
361 "%s/%d filtered by prefix-list %s",
362 inet_ntoa(p
->prefix
),
363 p
->prefixlen
, inout
);
372 /* Check nexthop address validity. */
373 static int rip_nexthop_check(struct in_addr
*addr
)
375 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
376 struct interface
*ifp
;
377 struct listnode
*cnode
;
378 struct connected
*ifc
;
381 /* If nexthop address matches local configured address then it is
384 FOR_ALL_INTERFACES (vrf
, ifp
) {
385 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, ifc
)) {
388 if (p
->family
== AF_INET
389 && IPV4_ADDR_SAME(&p
->u
.prefix4
, addr
))
396 /* RIP add route to routing table. */
397 static void rip_rte_process(struct rte
*rte
, struct sockaddr_in
*from
,
398 struct interface
*ifp
)
401 struct prefix_ipv4 p
;
402 struct route_node
*rp
;
403 struct rip_info
*rinfo
= NULL
, newinfo
;
404 struct rip_interface
*ri
;
405 struct in_addr
*nexthop
;
407 unsigned char old_dist
, new_dist
;
408 struct list
*list
= NULL
;
409 struct listnode
*node
= NULL
;
411 /* Make prefix structure. */
412 memset(&p
, 0, sizeof(struct prefix_ipv4
));
414 p
.prefix
= rte
->prefix
;
415 p
.prefixlen
= ip_masklen(rte
->mask
);
417 /* Make sure mask is applied. */
420 /* Apply input filters. */
423 ret
= rip_filter(RIP_FILTER_IN
, &p
, ri
);
427 memset(&newinfo
, 0, sizeof(newinfo
));
428 newinfo
.type
= ZEBRA_ROUTE_RIP
;
429 newinfo
.sub_type
= RIP_ROUTE_RTE
;
430 newinfo
.nh
.gate
.ipv4
= rte
->nexthop
;
431 newinfo
.from
= from
->sin_addr
;
432 newinfo
.nh
.ifindex
= ifp
->ifindex
;
433 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
434 newinfo
.metric
= rte
->metric
;
435 newinfo
.metric_out
= rte
->metric
; /* XXX */
436 newinfo
.tag
= ntohs(rte
->tag
); /* XXX */
438 /* Modify entry according to the interface routemap. */
439 if (ri
->routemap
[RIP_FILTER_IN
]) {
440 /* The object should be of the type of rip_info */
441 ret
= route_map_apply(ri
->routemap
[RIP_FILTER_IN
],
442 (struct prefix
*)&p
, RMAP_RIP
, &newinfo
);
444 if (ret
== RMAP_DENYMATCH
) {
445 if (IS_RIP_DEBUG_PACKET
)
447 "RIP %s/%d is filtered by route-map in",
448 inet_ntoa(p
.prefix
), p
.prefixlen
);
452 /* Get back the object */
453 rte
->nexthop
= newinfo
.nexthop_out
;
454 rte
->tag
= htons(newinfo
.tag_out
); /* XXX */
455 rte
->metric
= newinfo
.metric_out
; /* XXX: the routemap uses the
459 /* Once the entry has been validated, update the metric by
460 adding the cost of the network on wich the message
461 arrived. If the result is greater than infinity, use infinity
462 (RFC2453 Sec. 3.9.2) */
463 /* Zebra ripd can handle offset-list in. */
464 ret
= rip_offset_list_apply_in(&p
, ifp
, &rte
->metric
);
466 /* If offset-list does not modify the metric use interface's
469 rte
->metric
+= ifp
->metric
? ifp
->metric
: 1;
471 if (rte
->metric
> RIP_METRIC_INFINITY
)
472 rte
->metric
= RIP_METRIC_INFINITY
;
474 /* Set nexthop pointer. */
475 if (rte
->nexthop
.s_addr
== 0)
476 nexthop
= &from
->sin_addr
;
478 nexthop
= &rte
->nexthop
;
480 /* Check if nexthop address is myself, then do nothing. */
481 if (rip_nexthop_check(nexthop
) < 0) {
482 if (IS_RIP_DEBUG_PACKET
)
483 zlog_debug("Nexthop address %s is myself",
484 inet_ntoa(*nexthop
));
488 /* Get index for the prefix. */
489 rp
= route_node_get(rip
->table
, (struct prefix
*)&p
);
492 newinfo
.nh
.gate
.ipv4
= *nexthop
;
493 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4
;
494 newinfo
.metric
= rte
->metric
;
495 newinfo
.tag
= ntohs(rte
->tag
);
496 newinfo
.distance
= rip_distance_apply(&newinfo
);
498 new_dist
= newinfo
.distance
? newinfo
.distance
499 : ZEBRA_RIP_DISTANCE_DEFAULT
;
501 /* Check to see whether there is already RIP route on the table. */
502 if ((list
= rp
->info
) != NULL
)
503 for (ALL_LIST_ELEMENTS_RO(list
, node
, rinfo
)) {
504 /* Need to compare with redistributed entry or local
506 if (!rip_route_rte(rinfo
))
509 if (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
510 && IPV4_ADDR_SAME(&rinfo
->nh
.gate
.ipv4
, nexthop
))
513 if (!listnextnode(node
)) {
514 /* Not found in the list */
516 if (rte
->metric
> rinfo
->metric
) {
517 /* New route has a greater metric.
519 route_unlock_node(rp
);
523 if (rte
->metric
< rinfo
->metric
)
524 /* New route has a smaller metric.
525 * Replace the ECMP list
526 * with the new one in below. */
529 /* Metrics are same. We compare the distances.
531 old_dist
= rinfo
->distance
533 : ZEBRA_RIP_DISTANCE_DEFAULT
;
535 if (new_dist
> old_dist
) {
536 /* New route has a greater distance.
538 route_unlock_node(rp
);
542 if (new_dist
< old_dist
)
543 /* New route has a smaller distance.
544 * Replace the ECMP list
545 * with the new one in below. */
548 /* Metrics and distances are both same. Keep
550 * the new route is added in the ECMP list in
556 /* Local static route. */
557 if (rinfo
->type
== ZEBRA_ROUTE_RIP
558 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
559 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))
560 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
561 route_unlock_node(rp
);
565 /* Redistributed route check. */
566 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
567 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
568 old_dist
= rinfo
->distance
;
569 /* Only routes directly connected to an interface
571 * may have a valid NULL distance */
572 if (rinfo
->nh
.gate
.ipv4
.s_addr
!= 0)
575 : ZEBRA_RIP_DISTANCE_DEFAULT
;
576 /* If imported route does not have STRICT precedence,
577 mark it as a ghost */
578 if (new_dist
<= old_dist
579 && rte
->metric
!= RIP_METRIC_INFINITY
)
580 rip_ecmp_replace(&newinfo
);
582 route_unlock_node(rp
);
589 route_unlock_node(rp
);
591 /* Now, check to see whether there is already an explicit route
592 for the destination prefix. If there is no such route, add
593 this route to the routing table, unless the metric is
594 infinity (there is no point in adding a route which
596 if (rte
->metric
!= RIP_METRIC_INFINITY
)
597 rip_ecmp_add(&newinfo
);
599 /* Route is there but we are not sure the route is RIP or not.
602 /* If there is an existing route, compare the next hop address
603 to the address of the router from which the datagram came.
604 If this datagram is from the same router as the existing
605 route, reinitialize the timeout. */
606 same
= (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
607 && (rinfo
->nh
.ifindex
== ifp
->ifindex
));
609 old_dist
= rinfo
->distance
? rinfo
->distance
610 : ZEBRA_RIP_DISTANCE_DEFAULT
;
612 /* Next, compare the metrics. If the datagram is from the same
613 router as the existing route, and the new metric is different
614 than the old one; or, if the new metric is lower than the old
615 one, or if the tag has been changed; or if there is a route
616 with a lower administrave distance; or an update of the
617 distance on the actual route; do the following actions: */
618 if ((same
&& rinfo
->metric
!= rte
->metric
)
619 || (rte
->metric
< rinfo
->metric
)
620 || ((same
) && (rinfo
->metric
== rte
->metric
)
621 && (newinfo
.tag
!= rinfo
->tag
))
622 || (old_dist
> new_dist
)
623 || ((old_dist
!= new_dist
) && same
)) {
624 if (listcount(list
) == 1) {
625 if (newinfo
.metric
!= RIP_METRIC_INFINITY
)
626 rip_ecmp_replace(&newinfo
);
628 rip_ecmp_delete(rinfo
);
630 if (newinfo
.metric
< rinfo
->metric
)
631 rip_ecmp_replace(&newinfo
);
632 else if (newinfo
.metric
> rinfo
->metric
)
633 rip_ecmp_delete(rinfo
);
634 else if (new_dist
< old_dist
)
635 rip_ecmp_replace(&newinfo
);
636 else if (new_dist
> old_dist
)
637 rip_ecmp_delete(rinfo
);
639 int update
= CHECK_FLAG(rinfo
->flags
,
644 assert(newinfo
.metric
645 != RIP_METRIC_INFINITY
);
647 RIP_TIMER_OFF(rinfo
->t_timeout
);
648 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
649 memcpy(rinfo
, &newinfo
,
650 sizeof(struct rip_info
));
651 rip_timeout_update(rinfo
);
654 rip_zebra_ipv4_add(rp
);
656 /* - Set the route change flag on the
658 rinfo
= listgetdata(listhead(list
));
659 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
660 rip_event(RIP_TRIGGERED_UPDATE
, 0);
663 } else /* same & no change */
664 rip_timeout_update(rinfo
);
666 /* Unlock tempolary lock of the route. */
667 route_unlock_node(rp
);
671 /* Dump RIP packet */
672 static void rip_packet_dump(struct rip_packet
*packet
, int size
,
677 const char *command_str
;
678 char pbuf
[BUFSIZ
], nbuf
[BUFSIZ
];
682 /* Set command string. */
683 if (packet
->command
> 0 && packet
->command
< RIP_COMMAND_MAX
)
684 command_str
= lookup_msg(rip_msg
, packet
->command
, NULL
);
686 command_str
= "unknown";
688 /* Dump packet header. */
689 zlog_debug("%s %s version %d packet size %d", sndrcv
, command_str
,
690 packet
->version
, size
);
692 /* Dump each routing table entry. */
695 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
696 if (packet
->version
== RIPv2
) {
697 netmask
= ip_masklen(rte
->mask
);
699 if (rte
->family
== htons(RIP_FAMILY_AUTH
)) {
701 == htons(RIP_AUTH_SIMPLE_PASSWORD
)) {
702 p
= (uint8_t *)&rte
->prefix
;
705 " family 0x%X type %d auth string: %s",
708 } else if (rte
->tag
== htons(RIP_AUTH_MD5
)) {
709 struct rip_md5_info
*md5
;
711 md5
= (struct rip_md5_info
*)&packet
715 " family 0x%X type %d (MD5 authentication)",
719 " RIP-2 packet len %d Key ID %d"
721 ntohs(md5
->packet_len
),
722 md5
->keyid
, md5
->auth_len
);
723 zlog_debug(" Sequence Number %ld",
724 (unsigned long)ntohl(
726 } else if (rte
->tag
== htons(RIP_AUTH_DATA
)) {
727 p
= (uint8_t *)&rte
->prefix
;
730 " family 0x%X type %d (MD5 data)",
734 " MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
735 "%02X%02X%02X%02X%02X%02X%02X%02X",
736 p
[0], p
[1], p
[2], p
[3], p
[4],
737 p
[5], p
[6], p
[7], p
[8], p
[9],
738 p
[10], p
[11], p
[12], p
[13],
742 " family 0x%X type %d (Unknown auth type)",
748 " %s/%d -> %s family %d tag %" ROUTE_TAG_PRI
750 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
,
753 inet_ntop(AF_INET
, &rte
->nexthop
, nbuf
,
756 (route_tag_t
)ntohs(rte
->tag
),
757 (unsigned long)ntohl(rte
->metric
));
760 " %s family %d tag %" ROUTE_TAG_PRI
762 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
764 (route_tag_t
)ntohs(rte
->tag
),
765 (unsigned long)ntohl(rte
->metric
));
770 /* Check if the destination address is valid (unicast; not net 0
771 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
772 check net 0 because we accept default route. */
773 static int rip_destination_check(struct in_addr addr
)
775 uint32_t destination
;
777 /* Convert to host byte order. */
778 destination
= ntohl(addr
.s_addr
);
780 if (IPV4_NET127(destination
))
783 /* Net 0 may match to the default route. */
784 if (IPV4_NET0(destination
) && destination
!= 0)
787 /* Unicast address must belong to class A, B, C. */
788 if (IN_CLASSA(destination
))
790 if (IN_CLASSB(destination
))
792 if (IN_CLASSC(destination
))
798 /* RIP version 2 authentication. */
799 static int rip_auth_simple_password(struct rte
*rte
, struct sockaddr_in
*from
,
800 struct interface
*ifp
)
802 struct rip_interface
*ri
;
803 char *auth_str
= (char *)rte
+ offsetof(struct rte
, prefix
);
806 /* reject passwords with zeros in the middle of the string */
807 for (i
= strnlen(auth_str
, 16); i
< 16; i
++) {
808 if (auth_str
[i
] != '\0')
812 if (IS_RIP_DEBUG_EVENT
)
813 zlog_debug("RIPv2 simple password authentication from %s",
814 inet_ntoa(from
->sin_addr
));
818 if (ri
->auth_type
!= RIP_AUTH_SIMPLE_PASSWORD
819 || rte
->tag
!= htons(RIP_AUTH_SIMPLE_PASSWORD
))
822 /* Simple password authentication. */
824 if (strncmp(auth_str
, ri
->auth_str
, 16) == 0)
828 struct keychain
*keychain
;
831 keychain
= keychain_lookup(ri
->key_chain
);
832 if (keychain
== NULL
|| keychain
->key
== NULL
)
835 key
= key_match_for_accept(keychain
, auth_str
);
842 /* RIP version 2 authentication with MD5. */
843 static int rip_auth_md5(struct rip_packet
*packet
, struct sockaddr_in
*from
,
844 int length
, struct interface
*ifp
)
846 struct rip_interface
*ri
;
847 struct rip_md5_info
*md5
;
848 struct rip_md5_data
*md5data
;
849 struct keychain
*keychain
;
852 uint8_t digest
[RIP_AUTH_MD5_SIZE
];
854 char auth_str
[RIP_AUTH_MD5_SIZE
];
856 if (IS_RIP_DEBUG_EVENT
)
857 zlog_debug("RIPv2 MD5 authentication from %s",
858 inet_ntoa(from
->sin_addr
));
861 md5
= (struct rip_md5_info
*)&packet
->rte
;
863 /* Check auth type. */
864 if (ri
->auth_type
!= RIP_AUTH_MD5
|| md5
->type
!= htons(RIP_AUTH_MD5
))
867 /* If the authentication length is less than 16, then it must be wrong
869 * any interpretation of rfc2082. Some implementations also interpret
870 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka
871 * RIP_AUTH_MD5_COMPAT_SIZE.
873 if (!((md5
->auth_len
== RIP_AUTH_MD5_SIZE
)
874 || (md5
->auth_len
== RIP_AUTH_MD5_COMPAT_SIZE
))) {
875 if (IS_RIP_DEBUG_EVENT
)
877 "RIPv2 MD5 authentication, strange authentication "
883 /* grab and verify check packet length */
884 packet_len
= ntohs(md5
->packet_len
);
886 if (packet_len
> (length
- RIP_HEADER_SIZE
- RIP_AUTH_MD5_SIZE
)) {
887 if (IS_RIP_DEBUG_EVENT
)
889 "RIPv2 MD5 authentication, packet length field %d "
890 "greater than received length %d!",
891 md5
->packet_len
, length
);
895 /* retrieve authentication data */
896 md5data
= (struct rip_md5_data
*)(((uint8_t *)packet
) + packet_len
);
898 memset(auth_str
, 0, RIP_AUTH_MD5_SIZE
);
901 keychain
= keychain_lookup(ri
->key_chain
);
902 if (keychain
== NULL
)
905 key
= key_lookup_for_accept(keychain
, md5
->keyid
);
906 if (key
== NULL
|| key
->string
== NULL
)
909 strncpy(auth_str
, key
->string
, RIP_AUTH_MD5_SIZE
);
910 } else if (ri
->auth_str
)
911 strncpy(auth_str
, ri
->auth_str
, RIP_AUTH_MD5_SIZE
);
913 if (auth_str
[0] == 0)
916 /* MD5 digest authentication. */
917 memset(&ctx
, 0, sizeof(ctx
));
919 MD5Update(&ctx
, packet
, packet_len
+ RIP_HEADER_SIZE
);
920 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
921 MD5Final(digest
, &ctx
);
923 if (memcmp(md5data
->digest
, digest
, RIP_AUTH_MD5_SIZE
) == 0)
929 /* Pick correct auth string for sends, prepare auth_str buffer for use.
930 * (left justified and padded).
932 * presumes one of ri or key is valid, and that the auth strings they point
933 * to are nul terminated. If neither are present, auth_str will be fully
937 static void rip_auth_prepare_str_send(struct rip_interface
*ri
, struct key
*key
,
938 char *auth_str
, int len
)
942 memset(auth_str
, 0, len
);
943 if (key
&& key
->string
)
944 strncpy(auth_str
, key
->string
, len
);
945 else if (ri
->auth_str
)
946 strncpy(auth_str
, ri
->auth_str
, len
);
951 /* Write RIPv2 simple password authentication information
953 * auth_str is presumed to be 2 bytes and correctly prepared
954 * (left justified and zero padded).
956 static void rip_auth_simple_write(struct stream
*s
, char *auth_str
, int len
)
958 assert(s
&& len
== RIP_AUTH_SIMPLE_SIZE
);
960 stream_putw(s
, RIP_FAMILY_AUTH
);
961 stream_putw(s
, RIP_AUTH_SIMPLE_PASSWORD
);
962 stream_put(s
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
967 /* write RIPv2 MD5 "authentication header"
968 * (uses the auth key data field)
970 * Digest offset field is set to 0.
972 * returns: offset of the digest offset field, which must be set when
973 * length to the auth-data MD5 digest is known.
975 static size_t rip_auth_md5_ah_write(struct stream
*s
, struct rip_interface
*ri
,
980 assert(s
&& ri
&& ri
->auth_type
== RIP_AUTH_MD5
);
982 /* MD5 authentication. */
983 stream_putw(s
, RIP_FAMILY_AUTH
);
984 stream_putw(s
, RIP_AUTH_MD5
);
986 /* MD5 AH digest offset field.
988 * Set to placeholder value here, to true value when RIP-2 Packet length
989 * is known. Actual value is set in .....().
991 doff
= stream_get_endp(s
);
996 stream_putc(s
, key
->index
% 256);
1000 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
1001 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for
1003 * to be configurable.
1005 stream_putc(s
, ri
->md5_auth_len
);
1007 /* Sequence Number (non-decreasing). */
1008 /* RFC2080: The value used in the sequence number is
1009 arbitrary, but two suggestions are the time of the
1010 message's creation or a simple message counter. */
1011 stream_putl(s
, time(NULL
));
1013 /* Reserved field must be zero. */
1020 /* If authentication is in used, write the appropriate header
1021 * returns stream offset to which length must later be written
1022 * or 0 if this is not required
1024 static size_t rip_auth_header_write(struct stream
*s
, struct rip_interface
*ri
,
1025 struct key
*key
, char *auth_str
, int len
)
1027 assert(ri
->auth_type
!= RIP_NO_AUTH
);
1029 switch (ri
->auth_type
) {
1030 case RIP_AUTH_SIMPLE_PASSWORD
:
1031 rip_auth_prepare_str_send(ri
, key
, auth_str
, len
);
1032 rip_auth_simple_write(s
, auth_str
, len
);
1035 return rip_auth_md5_ah_write(s
, ri
, key
);
1041 /* Write RIPv2 MD5 authentication data trailer */
1042 static void rip_auth_md5_set(struct stream
*s
, struct rip_interface
*ri
,
1043 size_t doff
, char *auth_str
, int authlen
)
1047 unsigned char digest
[RIP_AUTH_MD5_SIZE
];
1049 /* Make it sure this interface is configured as MD5
1051 assert((ri
->auth_type
== RIP_AUTH_MD5
)
1052 && (authlen
== RIP_AUTH_MD5_SIZE
));
1055 /* Get packet length. */
1056 len
= stream_get_endp(s
);
1058 /* Check packet length. */
1059 if (len
< (RIP_HEADER_SIZE
+ RIP_RTE_SIZE
)) {
1062 "rip_auth_md5_set(): packet length %ld is less than minimum length.",
1067 /* Set the digest offset length in the header */
1068 stream_putw_at(s
, doff
, len
);
1070 /* Set authentication data. */
1071 stream_putw(s
, RIP_FAMILY_AUTH
);
1072 stream_putw(s
, RIP_AUTH_DATA
);
1074 /* Generate a digest for the RIP packet. */
1075 memset(&ctx
, 0, sizeof(ctx
));
1077 MD5Update(&ctx
, STREAM_DATA(s
), stream_get_endp(s
));
1078 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1079 MD5Final(digest
, &ctx
);
1081 /* Copy the digest to the packet. */
1082 stream_write(s
, digest
, RIP_AUTH_MD5_SIZE
);
1085 /* RIP routing information. */
1086 static void rip_response_process(struct rip_packet
*packet
, int size
,
1087 struct sockaddr_in
*from
,
1088 struct connected
*ifc
)
1092 struct prefix_ipv4 ifaddr
;
1093 struct prefix_ipv4 ifaddrclass
;
1096 memset(&ifaddr
, 0, sizeof(ifaddr
));
1097 /* We don't know yet. */
1100 /* The Response must be ignored if it is not from the RIP
1101 port. (RFC2453 - Sec. 3.9.2)*/
1102 if (from
->sin_port
!= htons(RIP_PORT_DEFAULT
)) {
1103 zlog_info("response doesn't come from RIP port: %d",
1105 rip_peer_bad_packet(from
);
1109 /* The datagram's IPv4 source address should be checked to see
1110 whether the datagram is from a valid neighbor; the source of the
1111 datagram must be on a directly connected network (RFC2453 - Sec.
1113 if (if_lookup_address((void *)&from
->sin_addr
, AF_INET
, VRF_DEFAULT
)
1116 "This datagram doesn't came from a valid neighbor: %s",
1117 inet_ntoa(from
->sin_addr
));
1118 rip_peer_bad_packet(from
);
1122 /* It is also worth checking to see whether the response is from one
1123 of the router's own addresses. */
1125 ; /* Alredy done in rip_read () */
1127 /* Update RIP peer. */
1128 rip_peer_update(from
, packet
->version
);
1130 /* Set RTE pointer. */
1133 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
1134 /* RIPv2 authentication check. */
1135 /* If the Address Family Identifier of the first (and only the
1136 first) entry in the message is 0xFFFF, then the remainder of
1137 the entry contains the authentication. */
1138 /* If the packet gets here it means authentication enabled */
1139 /* Check is done in rip_read(). So, just skipping it */
1140 if (packet
->version
== RIPv2
&& rte
== packet
->rte
1141 && rte
->family
== htons(RIP_FAMILY_AUTH
))
1144 if (rte
->family
!= htons(AF_INET
)) {
1145 /* Address family check. RIP only supports AF_INET. */
1146 zlog_info("Unsupported family %d from %s.",
1148 inet_ntoa(from
->sin_addr
));
1152 /* - is the destination address valid (e.g., unicast; not net 0
1154 if (!rip_destination_check(rte
->prefix
)) {
1156 "Network is net 0 or net 127 or it is not unicast network");
1157 rip_peer_bad_route(from
);
1161 /* Convert metric value to host byte order. */
1162 rte
->metric
= ntohl(rte
->metric
);
1164 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1165 if (!(rte
->metric
>= 1 && rte
->metric
<= 16)) {
1166 zlog_info("Route's metric is not in the 1-16 range.");
1167 rip_peer_bad_route(from
);
1171 /* RIPv1 does not have nexthop value. */
1172 if (packet
->version
== RIPv1
&& rte
->nexthop
.s_addr
!= 0) {
1173 zlog_info("RIPv1 packet with nexthop value %s",
1174 inet_ntoa(rte
->nexthop
));
1175 rip_peer_bad_route(from
);
1179 /* That is, if the provided information is ignored, a possibly
1180 sub-optimal, but absolutely valid, route may be taken. If
1181 the received Next Hop is not directly reachable, it should be
1182 treated as 0.0.0.0. */
1183 if (packet
->version
== RIPv2
&& rte
->nexthop
.s_addr
!= 0) {
1186 /* Multicast address check. */
1187 addrval
= ntohl(rte
->nexthop
.s_addr
);
1188 if (IN_CLASSD(addrval
)) {
1190 "Nexthop %s is multicast address, skip this rte",
1191 inet_ntoa(rte
->nexthop
));
1195 if (!if_lookup_address((void *)&rte
->nexthop
, AF_INET
,
1197 struct route_node
*rn
;
1198 struct rip_info
*rinfo
;
1200 rn
= route_node_match_ipv4(rip
->table
,
1206 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1209 if (IS_RIP_DEBUG_EVENT
)
1211 "Next hop %s is on RIP network. Set nexthop to the packet's originator",
1214 rte
->nexthop
= rinfo
->from
;
1216 if (IS_RIP_DEBUG_EVENT
)
1218 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1221 rte
->nexthop
.s_addr
= 0;
1224 route_unlock_node(rn
);
1226 if (IS_RIP_DEBUG_EVENT
)
1228 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1231 rte
->nexthop
.s_addr
= 0;
1236 /* For RIPv1, there won't be a valid netmask.
1238 This is a best guess at the masks. If everyone was using old
1239 Ciscos before the 'ip subnet zero' option, it would be almost
1242 Cisco summarize ripv1 advertisements to the classful boundary
1243 (/16 for class B's) except when the RIP packet does to inside
1244 the classful network in question. */
1246 if ((packet
->version
== RIPv1
&& rte
->prefix
.s_addr
!= 0)
1247 || (packet
->version
== RIPv2
1248 && (rte
->prefix
.s_addr
!= 0
1249 && rte
->mask
.s_addr
== 0))) {
1250 uint32_t destination
;
1252 if (subnetted
== -1) {
1253 memcpy(&ifaddr
, ifc
->address
,
1254 sizeof(struct prefix_ipv4
));
1255 memcpy(&ifaddrclass
, &ifaddr
,
1256 sizeof(struct prefix_ipv4
));
1257 apply_classful_mask_ipv4(&ifaddrclass
);
1259 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1263 destination
= ntohl(rte
->prefix
.s_addr
);
1265 if (IN_CLASSA(destination
))
1266 masklen2ip(8, &rte
->mask
);
1267 else if (IN_CLASSB(destination
))
1268 masklen2ip(16, &rte
->mask
);
1269 else if (IN_CLASSC(destination
))
1270 masklen2ip(24, &rte
->mask
);
1273 masklen2ip(ifaddrclass
.prefixlen
,
1274 (struct in_addr
*)&destination
);
1275 if ((subnetted
== 1)
1276 && ((rte
->prefix
.s_addr
& destination
)
1277 == ifaddrclass
.prefix
.s_addr
)) {
1278 masklen2ip(ifaddr
.prefixlen
, &rte
->mask
);
1279 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1280 != rte
->prefix
.s_addr
)
1281 masklen2ip(32, &rte
->mask
);
1282 if (IS_RIP_DEBUG_EVENT
)
1283 zlog_debug("Subnetted route %s",
1284 inet_ntoa(rte
->prefix
));
1286 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1287 != rte
->prefix
.s_addr
)
1291 if (IS_RIP_DEBUG_EVENT
) {
1292 zlog_debug("Resultant route %s",
1293 inet_ntoa(rte
->prefix
));
1294 zlog_debug("Resultant mask %s",
1295 inet_ntoa(rte
->mask
));
1299 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1300 ignore the entry. */
1301 if ((packet
->version
== RIPv2
) && (rte
->mask
.s_addr
!= 0)
1302 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1303 != rte
->prefix
.s_addr
)) {
1305 "RIPv2 address %s is not mask /%d applied one",
1306 inet_ntoa(rte
->prefix
), ip_masklen(rte
->mask
));
1307 rip_peer_bad_route(from
);
1311 /* Default route's netmask is ignored. */
1312 if (packet
->version
== RIPv2
&& (rte
->prefix
.s_addr
== 0)
1313 && (rte
->mask
.s_addr
!= 0)) {
1314 if (IS_RIP_DEBUG_EVENT
)
1316 "Default route with non-zero netmask. Set zero to netmask");
1317 rte
->mask
.s_addr
= 0;
1320 /* Routing table updates. */
1321 rip_rte_process(rte
, from
, ifc
->ifp
);
1325 /* Make socket for RIP protocol. */
1326 int rip_create_socket(void)
1330 struct sockaddr_in addr
;
1332 memset(&addr
, 0, sizeof(struct sockaddr_in
));
1333 addr
.sin_family
= AF_INET
;
1334 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1335 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1336 addr
.sin_len
= sizeof(struct sockaddr_in
);
1337 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1338 /* sending port must always be the RIP port */
1339 addr
.sin_port
= htons(RIP_PORT_DEFAULT
);
1341 /* Make datagram socket. */
1342 sock
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
1344 flog_err_sys(EC_LIB_SOCKET
, "Cannot create UDP socket: %s",
1345 safe_strerror(errno
));
1349 sockopt_broadcast(sock
);
1350 sockopt_reuseaddr(sock
);
1351 sockopt_reuseport(sock
);
1352 setsockopt_ipv4_multicast_loop(sock
, 0);
1354 setsockopt_pktinfo(sock
);
1355 #endif /* RIP_RECVMSG */
1356 #ifdef IPTOS_PREC_INTERNETCONTROL
1357 setsockopt_ipv4_tos(sock
, IPTOS_PREC_INTERNETCONTROL
);
1360 frr_elevate_privs(&ripd_privs
) {
1361 setsockopt_so_recvbuf(sock
, RIP_UDP_RCV_BUF
);
1362 if ((ret
= bind(sock
, (struct sockaddr
*)&addr
, sizeof(addr
)))
1364 zlog_err("%s: Can't bind socket %d to %s port %d: %s",
1365 __func__
, sock
, inet_ntoa(addr
.sin_addr
),
1366 (int)ntohs(addr
.sin_port
),
1367 safe_strerror(errno
));
1377 /* RIP packet send to destination address, on interface denoted by
1378 * by connected argument. NULL to argument denotes destination should be
1379 * should be RIP multicast group
1381 static int rip_send_packet(uint8_t *buf
, int size
, struct sockaddr_in
*to
,
1382 struct connected
*ifc
)
1385 struct sockaddr_in sin
;
1387 assert(ifc
!= NULL
);
1389 if (IS_RIP_DEBUG_PACKET
) {
1390 #define ADDRESS_SIZE 20
1391 char dst
[ADDRESS_SIZE
];
1392 dst
[ADDRESS_SIZE
- 1] = '\0';
1395 strncpy(dst
, inet_ntoa(to
->sin_addr
), ADDRESS_SIZE
- 1);
1397 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1398 strncpy(dst
, inet_ntoa(sin
.sin_addr
), ADDRESS_SIZE
- 1);
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 rip_peer_bad_packet(&from
);
1882 If the router is configured to authenticate RIP-2 messages, then
1883 RIP-1 messages and RIP-2 messages which pass authentication
1884 testing shall be accepted; unauthenticated and failed
1885 authentication RIP-2 messages shall be discarded. For maximum
1886 security, RIP-1 messages should be ignored when authentication is
1887 in use (see section 4.1); otherwise, the routing information from
1888 authenticated messages will be propagated by RIP-1 routers in an
1889 unauthenticated manner.
1891 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1892 * always reply regardless of authentication settings, because:
1894 * - if there other authorised routers on-link, the REQUESTor can
1895 * passively obtain the routing updates anyway
1896 * - if there are no other authorised routers on-link, RIP can
1897 * easily be disabled for the link to prevent giving out information
1898 * on state of this routers RIP routing table..
1900 * I.e. if RIPv1 has any place anymore these days, it's as a very
1901 * simple way to distribute routing information (e.g. to embedded
1902 * hosts / appliances) and the ability to give out RIPv1
1903 * routing-information freely, while still requiring RIPv2
1904 * authentication for any RESPONSEs might be vaguely useful.
1906 if (ri
->auth_type
!= RIP_NO_AUTH
&& packet
->version
== RIPv1
) {
1907 /* Discard RIPv1 messages other than REQUESTs */
1908 if (packet
->command
!= RIP_REQUEST
) {
1909 if (IS_RIP_DEBUG_PACKET
)
1912 " dropped because authentication enabled");
1913 rip_peer_bad_packet(&from
);
1916 } else if (ri
->auth_type
!= RIP_NO_AUTH
) {
1917 const char *auth_desc
;
1920 /* There definitely is no authentication in the packet.
1922 if (IS_RIP_DEBUG_PACKET
)
1924 "RIPv2 authentication failed: no auth RTE in packet");
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 rip_peer_bad_packet(&from
);
1939 /* Check RIPv2 authentication. */
1940 switch (ntohs(packet
->rte
->tag
)) {
1941 case RIP_AUTH_SIMPLE_PASSWORD
:
1942 auth_desc
= "simple";
1943 ret
= rip_auth_simple_password(packet
->rte
, &from
, ifp
);
1948 ret
= rip_auth_md5(packet
, &from
, len
, ifp
);
1949 /* Reset RIP packet length to trim MD5 data. */
1955 auth_desc
= "unknown type";
1956 if (IS_RIP_DEBUG_PACKET
)
1958 "RIPv2 Unknown authentication type %d",
1959 ntohs(packet
->rte
->tag
));
1963 if (IS_RIP_DEBUG_PACKET
)
1964 zlog_debug("RIPv2 %s authentication success",
1967 if (IS_RIP_DEBUG_PACKET
)
1968 zlog_debug("RIPv2 %s authentication failure",
1970 rip_peer_bad_packet(&from
);
1975 /* Process each command. */
1976 switch (packet
->command
) {
1978 rip_response_process(packet
, len
, &from
, ifc
);
1982 rip_request_process(packet
, len
, &from
, ifc
);
1987 "Obsolete command %s received, please sent it to routed",
1988 lookup_msg(rip_msg
, packet
->command
, NULL
));
1989 rip_peer_bad_packet(&from
);
1991 case RIP_POLL_ENTRY
:
1992 zlog_info("Obsolete command %s received",
1993 lookup_msg(rip_msg
, packet
->command
, NULL
));
1994 rip_peer_bad_packet(&from
);
1997 zlog_info("Unknown RIP command %d received", packet
->command
);
1998 rip_peer_bad_packet(&from
);
2005 /* Write routing table entry to the stream and return next index of
2006 the routing table entry in the stream. */
2007 static int rip_write_rte(int num
, struct stream
*s
, struct prefix_ipv4
*p
,
2008 uint8_t version
, struct rip_info
*rinfo
)
2010 struct in_addr mask
;
2012 /* Write routing table entry. */
2013 if (version
== RIPv1
) {
2014 stream_putw(s
, AF_INET
);
2016 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2017 stream_put_ipv4(s
, 0);
2018 stream_put_ipv4(s
, 0);
2019 stream_putl(s
, rinfo
->metric_out
);
2021 masklen2ip(p
->prefixlen
, &mask
);
2023 stream_putw(s
, AF_INET
);
2024 stream_putw(s
, rinfo
->tag_out
);
2025 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2026 stream_put_ipv4(s
, mask
.s_addr
);
2027 stream_put_ipv4(s
, rinfo
->nexthop_out
.s_addr
);
2028 stream_putl(s
, rinfo
->metric_out
);
2034 /* Send update to the ifp or spcified neighbor. */
2035 void rip_output_process(struct connected
*ifc
, struct sockaddr_in
*to
,
2036 int route_type
, uint8_t version
)
2040 struct route_node
*rp
;
2041 struct rip_info
*rinfo
;
2042 struct rip_interface
*ri
;
2043 struct prefix_ipv4
*p
;
2044 struct prefix_ipv4 classfull
;
2045 struct prefix_ipv4 ifaddrclass
;
2046 struct key
*key
= NULL
;
2047 /* this might need to made dynamic if RIP ever supported auth methods
2048 with larger key string sizes */
2049 char auth_str
[RIP_AUTH_SIMPLE_SIZE
];
2050 size_t doff
= 0; /* offset of digest offset field */
2054 struct list
*list
= NULL
;
2055 struct listnode
*listnode
= NULL
;
2057 /* Logging output event. */
2058 if (IS_RIP_DEBUG_EVENT
) {
2060 zlog_debug("update routes to neighbor %s",
2061 inet_ntoa(to
->sin_addr
));
2063 zlog_debug("update routes on interface %s ifindex %d",
2064 ifc
->ifp
->name
, ifc
->ifp
->ifindex
);
2067 /* Set output stream. */
2070 /* Reset stream and RTE counter. */
2072 rtemax
= RIP_MAX_RTE
;
2074 /* Get RIP interface. */
2075 ri
= ifc
->ifp
->info
;
2077 /* If output interface is in simple password authentication mode, we
2078 need space for authentication data. */
2079 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2082 /* If output interface is in MD5 authentication mode, we need space
2083 for authentication header and data. */
2084 if (ri
->auth_type
== RIP_AUTH_MD5
)
2087 /* If output interface is in simple password authentication mode
2088 and string or keychain is specified we need space for auth. data */
2089 if (ri
->auth_type
!= RIP_NO_AUTH
) {
2090 if (ri
->key_chain
) {
2091 struct keychain
*keychain
;
2093 keychain
= keychain_lookup(ri
->key_chain
);
2095 key
= key_lookup_for_send(keychain
);
2097 /* to be passed to auth functions later */
2098 rip_auth_prepare_str_send(ri
, key
, auth_str
,
2099 RIP_AUTH_SIMPLE_SIZE
);
2100 if (strlen(auth_str
) == 0)
2104 if (version
== RIPv1
) {
2105 memcpy(&ifaddrclass
, ifc
->address
, sizeof(struct prefix_ipv4
));
2106 apply_classful_mask_ipv4(&ifaddrclass
);
2108 if (ifc
->address
->prefixlen
> ifaddrclass
.prefixlen
)
2112 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2113 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
2114 rinfo
= listgetdata(listhead(list
));
2115 /* For RIPv1, if we are subnetted, output subnets in our
2117 /* that have the same mask as the output "interface".
2119 /* networks, only the classfull version is output. */
2121 if (version
== RIPv1
) {
2122 p
= (struct prefix_ipv4
*)&rp
->p
;
2124 if (IS_RIP_DEBUG_PACKET
)
2126 "RIPv1 mask check, %s/%d considered for output",
2127 inet_ntoa(rp
->p
.u
.prefix4
),
2132 (struct prefix
*)&ifaddrclass
,
2134 if ((ifc
->address
->prefixlen
2136 && (rp
->p
.prefixlen
!= 32))
2139 memcpy(&classfull
, &rp
->p
,
2140 sizeof(struct prefix_ipv4
));
2141 apply_classful_mask_ipv4(&classfull
);
2142 if (rp
->p
.u
.prefix4
.s_addr
!= 0
2143 && classfull
.prefixlen
2147 if (IS_RIP_DEBUG_PACKET
)
2149 "RIPv1 mask check, %s/%d made it through",
2150 inet_ntoa(rp
->p
.u
.prefix4
),
2153 p
= (struct prefix_ipv4
*)&rp
->p
;
2155 /* Apply output filters. */
2156 ret
= rip_filter(RIP_FILTER_OUT
, p
, ri
);
2160 /* Changed route only output. */
2161 if (route_type
== rip_changed_route
2162 && (!(rinfo
->flags
& RIP_RTF_CHANGED
)))
2165 /* Split horizon. */
2166 /* if (split_horizon == rip_split_horizon) */
2167 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
) {
2169 * We perform split horizon for RIP and
2171 * For rip routes, we want to suppress the route
2173 * end up sending the route back on the
2175 * learned it from, with a higher metric. For
2177 * we suppress the route if the prefix is a
2179 * source address that we are going to use for
2181 * (in order to handle the case when multiple
2183 * configured on the same interface).
2186 struct rip_info
*tmp_rinfo
= NULL
;
2187 struct connected
*tmp_ifc
= NULL
;
2189 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2191 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2192 && tmp_rinfo
->nh
.ifindex
2193 == ifc
->ifp
->ifindex
) {
2199 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2200 for (ALL_LIST_ELEMENTS_RO(
2201 ifc
->ifp
->connected
,
2205 tmp_ifc
->address
)) {
2215 /* Preparation for route-map. */
2216 rinfo
->metric_set
= 0;
2217 rinfo
->nexthop_out
.s_addr
= 0;
2218 rinfo
->metric_out
= rinfo
->metric
;
2219 rinfo
->tag_out
= rinfo
->tag
;
2220 rinfo
->ifindex_out
= ifc
->ifp
->ifindex
;
2222 /* In order to avoid some local loops,
2223 * if the RIP route has a nexthop via this interface,
2225 * otherwise set it to 0. The nexthop should not be
2227 * beyond the local broadcast/multicast area in order
2228 * to avoid an IGP multi-level recursive look-up.
2231 if (rinfo
->nh
.ifindex
== ifc
->ifp
->ifindex
)
2232 rinfo
->nexthop_out
= rinfo
->nh
.gate
.ipv4
;
2234 /* Interface route-map */
2235 if (ri
->routemap
[RIP_FILTER_OUT
]) {
2236 ret
= route_map_apply(
2237 ri
->routemap
[RIP_FILTER_OUT
],
2238 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2240 if (ret
== RMAP_DENYMATCH
) {
2241 if (IS_RIP_DEBUG_PACKET
)
2243 "RIP %s/%d is filtered by route-map out",
2244 inet_ntoa(p
->prefix
),
2250 /* Apply redistribute route map - continue, if deny */
2251 if (rip
->route_map
[rinfo
->type
].name
2252 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2253 ret
= route_map_apply(
2254 rip
->route_map
[rinfo
->type
].map
,
2255 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2257 if (ret
== RMAP_DENYMATCH
) {
2258 if (IS_RIP_DEBUG_PACKET
)
2260 "%s/%d is filtered by route-map",
2261 inet_ntoa(p
->prefix
),
2267 /* When route-map does not set metric. */
2268 if (!rinfo
->metric_set
) {
2269 /* If redistribute metric is set. */
2270 if (rip
->route_map
[rinfo
->type
].metric_config
2271 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
2273 rip
->route_map
[rinfo
->type
]
2276 /* If the route is not connected or
2278 one, use default-metric value*/
2279 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2281 != ZEBRA_ROUTE_CONNECT
2283 != RIP_METRIC_INFINITY
)
2285 rip
->default_metric
;
2289 /* Apply offset-list */
2290 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2291 rip_offset_list_apply_out(p
, ifc
->ifp
,
2292 &rinfo
->metric_out
);
2294 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2295 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2297 /* Perform split-horizon with poisoned reverse
2298 * for RIP and connected routes.
2300 if (ri
->split_horizon
2301 == RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2303 * We perform split horizon for RIP and
2305 * For rip routes, we want to suppress the route
2307 * end up sending the route back on the
2309 * learned it from, with a higher metric. For
2311 * we suppress the route if the prefix is a
2313 * source address that we are going to use for
2315 * (in order to handle the case when multiple
2317 * configured on the same interface).
2319 struct rip_info
*tmp_rinfo
= NULL
;
2320 struct connected
*tmp_ifc
= NULL
;
2322 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2324 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2325 && tmp_rinfo
->nh
.ifindex
2326 == ifc
->ifp
->ifindex
)
2328 RIP_METRIC_INFINITY
;
2330 if (rinfo
->metric_out
!= RIP_METRIC_INFINITY
2331 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2332 for (ALL_LIST_ELEMENTS_RO(
2333 ifc
->ifp
->connected
,
2337 tmp_ifc
->address
)) {
2339 RIP_METRIC_INFINITY
;
2345 /* Prepare preamble, auth headers, if needs be */
2347 stream_putc(s
, RIP_RESPONSE
);
2348 stream_putc(s
, version
);
2351 /* auth header for !v1 && !no_auth */
2352 if ((ri
->auth_type
!= RIP_NO_AUTH
)
2353 && (version
!= RIPv1
))
2354 doff
= rip_auth_header_write(
2355 s
, ri
, key
, auth_str
,
2356 RIP_AUTH_SIMPLE_SIZE
);
2359 /* Write RTE to the stream. */
2360 num
= rip_write_rte(num
, s
, p
, version
, rinfo
);
2361 if (num
== rtemax
) {
2362 if (version
== RIPv2
2363 && ri
->auth_type
== RIP_AUTH_MD5
)
2364 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2365 RIP_AUTH_SIMPLE_SIZE
);
2367 ret
= rip_send_packet(STREAM_DATA(s
),
2368 stream_get_endp(s
), to
,
2371 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2372 rip_packet_dump((struct rip_packet
*)
2381 /* Flush unwritten RTE. */
2383 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2384 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2385 RIP_AUTH_SIMPLE_SIZE
);
2387 ret
= rip_send_packet(STREAM_DATA(s
), stream_get_endp(s
), to
,
2390 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2391 rip_packet_dump((struct rip_packet
*)STREAM_DATA(s
),
2392 stream_get_endp(s
), "SEND");
2396 /* Statistics updates. */
2400 /* Send RIP packet to the interface. */
2401 static void rip_update_interface(struct connected
*ifc
, uint8_t version
,
2404 struct interface
*ifp
= ifc
->ifp
;
2405 struct rip_interface
*ri
= ifp
->info
;
2406 struct sockaddr_in to
;
2408 /* When RIP version is 2 and multicast enable interface. */
2409 if (version
== RIPv2
&& !ri
->v2_broadcast
&& if_is_multicast(ifp
)) {
2410 if (IS_RIP_DEBUG_EVENT
)
2411 zlog_debug("multicast announce on %s ", ifp
->name
);
2413 rip_output_process(ifc
, NULL
, route_type
, version
);
2417 /* If we can't send multicast packet, send it with unicast. */
2418 if (if_is_broadcast(ifp
) || if_is_pointopoint(ifp
)) {
2419 if (ifc
->address
->family
== AF_INET
) {
2420 /* Destination address and port setting. */
2421 memset(&to
, 0, sizeof(struct sockaddr_in
));
2422 if (ifc
->destination
)
2423 /* use specified broadcast or peer destination
2425 to
.sin_addr
= ifc
->destination
->u
.prefix4
;
2426 else if (ifc
->address
->prefixlen
< IPV4_MAX_PREFIXLEN
)
2427 /* calculate the appropriate broadcast address
2429 to
.sin_addr
.s_addr
= ipv4_broadcast_addr(
2430 ifc
->address
->u
.prefix4
.s_addr
,
2431 ifc
->address
->prefixlen
);
2433 /* do not know where to send the packet */
2435 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2437 if (IS_RIP_DEBUG_EVENT
)
2438 zlog_debug("%s announce to %s on %s",
2439 CONNECTED_PEER(ifc
) ? "unicast"
2441 inet_ntoa(to
.sin_addr
), ifp
->name
);
2443 rip_output_process(ifc
, &to
, route_type
, version
);
2448 /* Update send to all interface and neighbor. */
2449 static void rip_update_process(int route_type
)
2451 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2452 struct listnode
*ifnode
, *ifnnode
;
2453 struct connected
*connected
;
2454 struct interface
*ifp
;
2455 struct rip_interface
*ri
;
2456 struct route_node
*rp
;
2457 struct sockaddr_in to
;
2460 /* Send RIP update to each interface. */
2461 FOR_ALL_INTERFACES (vrf
, ifp
) {
2462 if (if_is_loopback(ifp
))
2465 if (!if_is_operative(ifp
))
2468 /* Fetch RIP interface information. */
2471 /* When passive interface is specified, suppress announce to the
2478 * If there is no version configuration in the
2480 * use rip's version setting.
2482 int vsend
= ((ri
->ri_send
== RI_RIP_UNSPEC
)
2486 if (IS_RIP_DEBUG_EVENT
)
2487 zlog_debug("SEND UPDATE to %s ifindex %d",
2488 ifp
->name
, ifp
->ifindex
);
2490 /* send update on each connected network */
2491 for (ALL_LIST_ELEMENTS(ifp
->connected
, ifnode
, ifnnode
,
2493 if (connected
->address
->family
== AF_INET
) {
2495 rip_update_interface(
2499 && if_is_multicast(ifp
))
2500 rip_update_interface(
2508 /* RIP send updates to each neighbor. */
2509 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
2510 if (rp
->info
!= NULL
) {
2513 connected
= if_lookup_address(&p
->u
.prefix4
, AF_INET
,
2517 "Neighbor %s doesn't have connected interface!",
2518 inet_ntoa(p
->u
.prefix4
));
2522 /* Set destination address and port */
2523 memset(&to
, 0, sizeof(struct sockaddr_in
));
2524 to
.sin_addr
= p
->u
.prefix4
;
2525 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2527 /* RIP version is rip's configuration. */
2528 rip_output_process(connected
, &to
, route_type
,
2533 /* RIP's periodical timer. */
2534 static int rip_update(struct thread
*t
)
2536 /* Clear timer pointer. */
2537 rip
->t_update
= NULL
;
2539 if (IS_RIP_DEBUG_EVENT
)
2540 zlog_debug("update timer fire!");
2542 /* Process update output. */
2543 rip_update_process(rip_all_route
);
2545 /* Triggered updates may be suppressed if a regular update is due by
2546 the time the triggered update would be sent. */
2547 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2550 /* Register myself. */
2551 rip_event(RIP_UPDATE_EVENT
, 0);
2556 /* Walk down the RIP routing table then clear changed flag. */
2557 static void rip_clear_changed_flag(void)
2559 struct route_node
*rp
;
2560 struct rip_info
*rinfo
= NULL
;
2561 struct list
*list
= NULL
;
2562 struct listnode
*listnode
= NULL
;
2564 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2565 if ((list
= rp
->info
) != NULL
)
2566 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
2567 UNSET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2568 /* This flag can be set only on the first entry.
2574 /* Triggered update interval timer. */
2575 static int rip_triggered_interval(struct thread
*t
)
2577 int rip_triggered_update(struct thread
*);
2579 rip
->t_triggered_interval
= NULL
;
2583 rip_triggered_update(t
);
2588 /* Execute triggered update. */
2589 static int rip_triggered_update(struct thread
*t
)
2593 /* Clear thred pointer. */
2594 rip
->t_triggered_update
= NULL
;
2596 /* Cancel interval timer. */
2597 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2600 /* Logging triggered update. */
2601 if (IS_RIP_DEBUG_EVENT
)
2602 zlog_debug("triggered update!");
2604 /* Split Horizon processing is done when generating triggered
2605 updates as well as normal updates (see section 2.6). */
2606 rip_update_process(rip_changed_route
);
2608 /* Once all of the triggered updates have been generated, the route
2609 change flags should be cleared. */
2610 rip_clear_changed_flag();
2612 /* After a triggered update is sent, a timer should be set for a
2613 random interval between 1 and 5 seconds. If other changes that
2614 would trigger updates occur before the timer expires, a single
2615 update is triggered when the timer expires. */
2616 interval
= (random() % 5) + 1;
2618 rip
->t_triggered_interval
= NULL
;
2619 thread_add_timer(master
, rip_triggered_interval
, NULL
, interval
,
2620 &rip
->t_triggered_interval
);
2625 /* Withdraw redistributed route. */
2626 void rip_redistribute_withdraw(int type
)
2628 struct route_node
*rp
;
2629 struct rip_info
*rinfo
= NULL
;
2630 struct list
*list
= NULL
;
2635 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2636 if ((list
= rp
->info
) != NULL
) {
2637 rinfo
= listgetdata(listhead(list
));
2638 if (rinfo
->type
== type
2639 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2640 /* Perform poisoned reverse. */
2641 rinfo
->metric
= RIP_METRIC_INFINITY
;
2642 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
2643 rip_garbage_collect
,
2645 RIP_TIMER_OFF(rinfo
->t_timeout
);
2646 rinfo
->flags
|= RIP_RTF_CHANGED
;
2648 if (IS_RIP_DEBUG_EVENT
) {
2649 struct prefix_ipv4
*p
=
2650 (struct prefix_ipv4
*)&rp
->p
;
2653 "Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2654 inet_ntoa(p
->prefix
),
2661 rip_event(RIP_TRIGGERED_UPDATE
, 0);
2666 /* Create new RIP instance and set it to global variable. */
2667 int rip_create(int socket
)
2669 rip
= XCALLOC(MTYPE_RIP
, sizeof(struct rip
));
2671 /* Set initial value. */
2672 rip
->ecmp
= yang_get_default_bool("%s/allow-ecmp", RIP_INSTANCE
);
2673 rip
->default_metric
=
2674 yang_get_default_uint8("%s/default-metric", RIP_INSTANCE
);
2676 yang_get_default_uint8("%s/distance/default", RIP_INSTANCE
);
2677 rip
->garbage_time
= yang_get_default_uint32("%s/timers/flush-interval",
2679 rip
->timeout_time
= yang_get_default_uint32(
2680 "%s/timers/holddown-interval", RIP_INSTANCE
);
2681 rip
->update_time
= yang_get_default_uint32("%s/timers/update-interval",
2684 yang_get_default_enum("%s/version/send", RIP_INSTANCE
);
2686 yang_get_default_enum("%s/version/receive", RIP_INSTANCE
);
2688 /* Initialize RIP routig table. */
2689 rip
->table
= route_table_init();
2690 rip
->route
= route_table_init();
2691 rip
->neighbor
= route_table_init();
2693 /* Make output stream. */
2694 rip
->obuf
= stream_new(1500);
2699 /* Create read and timer thread. */
2700 rip_event(RIP_READ
, rip
->sock
);
2701 rip_event(RIP_UPDATE_EVENT
, 1);
2708 /* Sned RIP request to the destination. */
2709 int rip_request_send(struct sockaddr_in
*to
, struct interface
*ifp
,
2710 uint8_t version
, struct connected
*connected
)
2713 struct rip_packet rip_packet
;
2714 struct listnode
*node
, *nnode
;
2716 memset(&rip_packet
, 0, sizeof(rip_packet
));
2718 rip_packet
.command
= RIP_REQUEST
;
2719 rip_packet
.version
= version
;
2720 rte
= rip_packet
.rte
;
2721 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
2725 * connected is only sent for ripv1 case, or when
2726 * interface does not support multicast. Caller loops
2727 * over each connected address for this case.
2729 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2731 != sizeof(rip_packet
))
2734 return sizeof(rip_packet
);
2737 /* send request on each connected network */
2738 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, connected
)) {
2739 struct prefix_ipv4
*p
;
2741 p
= (struct prefix_ipv4
*)connected
->address
;
2743 if (p
->family
!= AF_INET
)
2746 if (rip_send_packet((uint8_t *)&rip_packet
, sizeof(rip_packet
),
2748 != sizeof(rip_packet
))
2751 return sizeof(rip_packet
);
2754 static int rip_update_jitter(unsigned long time
)
2756 #define JITTER_BOUND 4
2757 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2758 Given that, we cannot let time be less than JITTER_BOUND seconds.
2759 The RIPv2 RFC says jitter should be small compared to
2760 update_time. We consider 1/JITTER_BOUND to be small.
2763 int jitter_input
= time
;
2766 if (jitter_input
< JITTER_BOUND
)
2767 jitter_input
= JITTER_BOUND
;
2769 jitter
= (((random() % ((jitter_input
* 2) + 1)) - jitter_input
));
2771 return jitter
/ JITTER_BOUND
;
2774 void rip_event(enum rip_event event
, int sock
)
2781 thread_add_read(master
, rip_read
, NULL
, sock
, &rip
->t_read
);
2783 case RIP_UPDATE_EVENT
:
2784 RIP_TIMER_OFF(rip
->t_update
);
2785 jitter
= rip_update_jitter(rip
->update_time
);
2786 thread_add_timer(master
, rip_update
, NULL
,
2787 sock
? 2 : rip
->update_time
+ jitter
,
2790 case RIP_TRIGGERED_UPDATE
:
2791 if (rip
->t_triggered_interval
)
2794 thread_add_event(master
, rip_triggered_update
, NULL
, 0,
2795 &rip
->t_triggered_update
);
2805 "Set routing protocol version\n"
2811 version
= atoi(argv
[idx_number
]->arg
);
2812 if (version
!= RIPv1
&& version
!= RIPv2
) {
2813 vty_out(vty
, "invalid rip version %d\n", version
);
2814 return CMD_WARNING_CONFIG_FAILED
;
2816 rip
->version_send
= version
;
2817 rip
->version_recv
= version
;
2822 DEFUN (no_rip_version
,
2824 "no version [(1-2)]",
2826 "Set routing protocol version\n"
2829 /* Set RIP version to the default. */
2830 rip
->version_send
= RI_RIP_VERSION_2
;
2831 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2840 "RIP static route configuration\n"
2841 "IP prefix <network>/<length>\n")
2843 int idx_ipv4_prefixlen
= 1;
2846 struct prefix_ipv4 p
;
2847 struct route_node
*node
;
2849 memset(&nh
, 0, sizeof(nh
));
2850 nh
.type
= NEXTHOP_TYPE_IPV4
;
2852 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
2854 vty_out(vty
, "Malformed address\n");
2855 return CMD_WARNING_CONFIG_FAILED
;
2857 apply_mask_ipv4(&p
);
2859 /* For router rip configuration. */
2860 node
= route_node_get(rip
->route
, (struct prefix
*)&p
);
2863 vty_out(vty
, "There is already same static route.\n");
2864 route_unlock_node(node
);
2868 node
->info
= (void *)1;
2870 rip_redistribute_add(ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, &nh
, 0, 0,
2876 DEFUN (no_rip_route
,
2878 "no route A.B.C.D/M",
2880 "RIP static route configuration\n"
2881 "IP prefix <network>/<length>\n")
2883 int idx_ipv4_prefixlen
= 2;
2885 struct prefix_ipv4 p
;
2886 struct route_node
*node
;
2888 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
2890 vty_out(vty
, "Malformed address\n");
2891 return CMD_WARNING_CONFIG_FAILED
;
2893 apply_mask_ipv4(&p
);
2895 /* For router rip configuration. */
2896 node
= route_node_lookup(rip
->route
, (struct prefix
*)&p
);
2898 vty_out(vty
, "Can't find route %s.\n",
2899 argv
[idx_ipv4_prefixlen
]->arg
);
2900 return CMD_WARNING_CONFIG_FAILED
;
2903 rip_redistribute_delete(ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0);
2904 route_unlock_node(node
);
2907 route_unlock_node(node
);
2914 rip_update_default_metric (void)
2916 struct route_node
*np
;
2917 struct rip_info
*rinfo
= NULL
;
2918 struct list
*list
= NULL
;
2919 struct listnode
*listnode
= NULL
;
2921 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
2922 if ((list
= np
->info
) != NULL
)
2923 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
2924 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
2925 rinfo
->metric
= rip
->default_metric
;
2931 "timers basic (5-2147483647) (5-2147483647) (5-2147483647)",
2932 "Adjust routing timers\n"
2933 "Basic routing protocol update timers\n"
2934 "Routing table update timer value in second. Default is 30.\n"
2935 "Routing information timeout timer. Default is 180.\n"
2936 "Garbage collection timer. Default is 120.\n")
2939 int idx_number_2
= 3;
2940 int idx_number_3
= 4;
2941 unsigned long update
;
2942 unsigned long timeout
;
2943 unsigned long garbage
;
2944 char *endptr
= NULL
;
2945 unsigned long RIP_TIMER_MAX
= 2147483647;
2946 unsigned long RIP_TIMER_MIN
= 5;
2948 update
= strtoul(argv
[idx_number
]->arg
, &endptr
, 10);
2949 if (update
> RIP_TIMER_MAX
|| update
< RIP_TIMER_MIN
2950 || *endptr
!= '\0') {
2951 vty_out(vty
, "update timer value error\n");
2952 return CMD_WARNING_CONFIG_FAILED
;
2955 timeout
= strtoul(argv
[idx_number_2
]->arg
, &endptr
, 10);
2956 if (timeout
> RIP_TIMER_MAX
|| timeout
< RIP_TIMER_MIN
2957 || *endptr
!= '\0') {
2958 vty_out(vty
, "timeout timer value error\n");
2959 return CMD_WARNING_CONFIG_FAILED
;
2962 garbage
= strtoul(argv
[idx_number_3
]->arg
, &endptr
, 10);
2963 if (garbage
> RIP_TIMER_MAX
|| garbage
< RIP_TIMER_MIN
2964 || *endptr
!= '\0') {
2965 vty_out(vty
, "garbage timer value error\n");
2966 return CMD_WARNING_CONFIG_FAILED
;
2969 /* Set each timer value. */
2970 rip
->update_time
= update
;
2971 rip
->timeout_time
= timeout
;
2972 rip
->garbage_time
= garbage
;
2974 /* Reset update timer thread. */
2975 rip_event(RIP_UPDATE_EVENT
, 0);
2980 DEFUN (no_rip_timers
,
2982 "no timers basic [(0-65535) (0-65535) (0-65535)]",
2984 "Adjust routing timers\n"
2985 "Basic routing protocol update timers\n"
2986 "Routing table update timer value in second. Default is 30.\n"
2987 "Routing information timeout timer. Default is 180.\n"
2988 "Garbage collection timer. Default is 120.\n")
2990 /* Set each timer value to the default. */
2991 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
2992 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
2993 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
2995 /* Reset update timer thread. */
2996 rip_event(RIP_UPDATE_EVENT
, 0);
3002 struct route_table
*rip_distance_table
;
3004 struct rip_distance
{
3005 /* Distance value for the IP source prefix. */
3008 /* Name of the access-list to be matched. */
3012 static struct rip_distance
*rip_distance_new(void)
3014 return XCALLOC(MTYPE_RIP_DISTANCE
, sizeof(struct rip_distance
));
3017 static void rip_distance_free(struct rip_distance
*rdistance
)
3019 XFREE(MTYPE_RIP_DISTANCE
, rdistance
);
3022 static int rip_distance_set(struct vty
*vty
, const char *distance_str
,
3023 const char *ip_str
, const char *access_list_str
)
3026 struct prefix_ipv4 p
;
3028 struct route_node
*rn
;
3029 struct rip_distance
*rdistance
;
3031 ret
= str2prefix_ipv4(ip_str
, &p
);
3033 vty_out(vty
, "Malformed prefix\n");
3034 return CMD_WARNING_CONFIG_FAILED
;
3037 distance
= atoi(distance_str
);
3039 /* Get RIP distance node. */
3040 rn
= route_node_get(rip_distance_table
, (struct prefix
*)&p
);
3042 rdistance
= rn
->info
;
3043 route_unlock_node(rn
);
3045 rdistance
= rip_distance_new();
3046 rn
->info
= rdistance
;
3049 /* Set distance value. */
3050 rdistance
->distance
= distance
;
3052 /* Reset access-list configuration. */
3053 if (rdistance
->access_list
) {
3054 free(rdistance
->access_list
);
3055 rdistance
->access_list
= NULL
;
3057 if (access_list_str
)
3058 rdistance
->access_list
= strdup(access_list_str
);
3063 static int rip_distance_unset(struct vty
*vty
, const char *distance_str
,
3064 const char *ip_str
, const char *access_list_str
)
3067 struct prefix_ipv4 p
;
3068 struct route_node
*rn
;
3069 struct rip_distance
*rdistance
;
3071 ret
= str2prefix_ipv4(ip_str
, &p
);
3073 vty_out(vty
, "Malformed prefix\n");
3074 return CMD_WARNING_CONFIG_FAILED
;
3077 rn
= route_node_lookup(rip_distance_table
, (struct prefix
*)&p
);
3079 vty_out(vty
, "Can't find specified prefix\n");
3080 return CMD_WARNING_CONFIG_FAILED
;
3083 rdistance
= rn
->info
;
3085 if (rdistance
->access_list
)
3086 free(rdistance
->access_list
);
3087 rip_distance_free(rdistance
);
3090 route_unlock_node(rn
);
3091 route_unlock_node(rn
);
3096 static void rip_distance_reset(void)
3098 struct route_node
*rn
;
3099 struct rip_distance
*rdistance
;
3101 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
3102 if ((rdistance
= rn
->info
) != NULL
) {
3103 if (rdistance
->access_list
)
3104 free(rdistance
->access_list
);
3105 rip_distance_free(rdistance
);
3107 route_unlock_node(rn
);
3111 /* Apply RIP information to distance method. */
3112 uint8_t rip_distance_apply(struct rip_info
*rinfo
)
3114 struct route_node
*rn
;
3115 struct prefix_ipv4 p
;
3116 struct rip_distance
*rdistance
;
3117 struct access_list
*alist
;
3122 memset(&p
, 0, sizeof(struct prefix_ipv4
));
3124 p
.prefix
= rinfo
->from
;
3125 p
.prefixlen
= IPV4_MAX_BITLEN
;
3127 /* Check source address. */
3128 rn
= route_node_match(rip_distance_table
, (struct prefix
*)&p
);
3130 rdistance
= rn
->info
;
3131 route_unlock_node(rn
);
3133 if (rdistance
->access_list
) {
3134 alist
= access_list_lookup(AFI_IP
,
3135 rdistance
->access_list
);
3138 if (access_list_apply(alist
, &rinfo
->rp
->p
)
3142 return rdistance
->distance
;
3144 return rdistance
->distance
;
3148 return rip
->distance
;
3153 static void rip_distance_show(struct vty
*vty
)
3155 struct route_node
*rn
;
3156 struct rip_distance
*rdistance
;
3160 vty_out(vty
, " Distance: (default is %u)\n",
3161 rip
->distance
? rip
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
);
3163 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
3164 if ((rdistance
= rn
->info
) != NULL
) {
3167 " Address Distance List\n");
3170 sprintf(buf
, "%s/%d", inet_ntoa(rn
->p
.u
.prefix4
),
3172 vty_out(vty
, " %-20s %4d %s\n", buf
,
3173 rdistance
->distance
,
3174 rdistance
->access_list
? rdistance
->access_list
3179 DEFUN (rip_distance_source
,
3180 rip_distance_source_cmd
,
3181 "distance (1-255) A.B.C.D/M",
3182 "Administrative distance\n"
3184 "IP source prefix\n")
3187 int idx_ipv4_prefixlen
= 2;
3188 rip_distance_set(vty
, argv
[idx_number
]->arg
,
3189 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
3193 DEFUN (no_rip_distance_source
,
3194 no_rip_distance_source_cmd
,
3195 "no distance (1-255) A.B.C.D/M",
3197 "Administrative distance\n"
3199 "IP source prefix\n")
3202 int idx_ipv4_prefixlen
= 3;
3203 rip_distance_unset(vty
, argv
[idx_number
]->arg
,
3204 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
3208 DEFUN (rip_distance_source_access_list
,
3209 rip_distance_source_access_list_cmd
,
3210 "distance (1-255) A.B.C.D/M WORD",
3211 "Administrative distance\n"
3213 "IP source prefix\n"
3214 "Access list name\n")
3217 int idx_ipv4_prefixlen
= 2;
3219 rip_distance_set(vty
, argv
[idx_number
]->arg
,
3220 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
3224 DEFUN (no_rip_distance_source_access_list
,
3225 no_rip_distance_source_access_list_cmd
,
3226 "no distance (1-255) A.B.C.D/M WORD",
3228 "Administrative distance\n"
3230 "IP source prefix\n"
3231 "Access list name\n")
3234 int idx_ipv4_prefixlen
= 3;
3236 rip_distance_unset(vty
, argv
[idx_number
]->arg
,
3237 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
3241 /* Update ECMP routes to zebra when ECMP is disabled. */
3242 void rip_ecmp_disable(void)
3244 struct route_node
*rp
;
3245 struct rip_info
*rinfo
, *tmp_rinfo
;
3247 struct listnode
*node
, *nextnode
;
3252 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3253 if ((list
= rp
->info
) != NULL
&& listcount(list
) > 1) {
3254 rinfo
= listgetdata(listhead(list
));
3255 if (!rip_route_rte(rinfo
))
3258 /* Drop all other entries, except the first one. */
3259 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
3260 if (tmp_rinfo
!= rinfo
) {
3261 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
3263 tmp_rinfo
->t_garbage_collect
);
3264 list_delete_node(list
, node
);
3265 rip_info_free(tmp_rinfo
);
3269 rip_zebra_ipv4_add(rp
);
3271 /* Set the route change flag. */
3272 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
3274 /* Signal the output process to trigger an update. */
3275 rip_event(RIP_TRIGGERED_UPDATE
, 0);
3279 /* Print out routes update time. */
3280 static void rip_vty_out_uptime(struct vty
*vty
, struct rip_info
*rinfo
)
3285 char timebuf
[TIME_BUF
];
3286 struct thread
*thread
;
3288 if ((thread
= rinfo
->t_timeout
) != NULL
) {
3289 clock
= thread_timer_remain_second(thread
);
3290 tm
= gmtime(&clock
);
3291 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
3292 vty_out(vty
, "%5s", timebuf
);
3293 } else if ((thread
= rinfo
->t_garbage_collect
) != NULL
) {
3294 clock
= thread_timer_remain_second(thread
);
3295 tm
= gmtime(&clock
);
3296 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
3297 vty_out(vty
, "%5s", timebuf
);
3301 static const char *rip_route_type_print(int sub_type
)
3306 case RIP_ROUTE_STATIC
:
3308 case RIP_ROUTE_DEFAULT
:
3310 case RIP_ROUTE_REDISTRIBUTE
:
3312 case RIP_ROUTE_INTERFACE
:
3324 "Show RIP routes\n")
3326 struct route_node
*np
;
3327 struct rip_info
*rinfo
= NULL
;
3328 struct list
*list
= NULL
;
3329 struct listnode
*listnode
= NULL
;
3335 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
3337 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
3338 " (i) - interface\n\n"
3339 " Network Next Hop Metric From Tag Time\n");
3341 for (np
= route_top(rip
->table
); np
; np
= route_next(np
))
3342 if ((list
= np
->info
) != NULL
)
3343 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3347 vty
, "%c(%s) %s/%d",
3348 /* np->lock, For debugging. */
3349 zebra_route_char(rinfo
->type
),
3350 rip_route_type_print(rinfo
->sub_type
),
3351 inet_ntoa(np
->p
.u
.prefix4
),
3357 vty_out(vty
, "%*s", len
, " ");
3359 switch (rinfo
->nh
.type
) {
3360 case NEXTHOP_TYPE_IPV4
:
3361 case NEXTHOP_TYPE_IPV4_IFINDEX
:
3362 vty_out(vty
, "%-20s %2d ",
3363 inet_ntoa(rinfo
->nh
.gate
.ipv4
),
3366 case NEXTHOP_TYPE_IFINDEX
:
3371 case NEXTHOP_TYPE_BLACKHOLE
:
3376 case NEXTHOP_TYPE_IPV6
:
3377 case NEXTHOP_TYPE_IPV6_IFINDEX
:
3379 "V6 Address Hidden %2d ",
3384 /* Route which exist in kernel routing table. */
3385 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
)
3386 && (rinfo
->sub_type
== RIP_ROUTE_RTE
)) {
3387 vty_out(vty
, "%-15s ",
3388 inet_ntoa(rinfo
->from
));
3389 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3390 (route_tag_t
)rinfo
->tag
);
3391 rip_vty_out_uptime(vty
, rinfo
);
3392 } else if (rinfo
->metric
3393 == RIP_METRIC_INFINITY
) {
3394 vty_out(vty
, "self ");
3395 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3396 (route_tag_t
)rinfo
->tag
);
3397 rip_vty_out_uptime(vty
, rinfo
);
3399 if (rinfo
->external_metric
) {
3401 vty
, "self (%s:%d)",
3404 rinfo
->external_metric
);
3407 vty_out(vty
, "%*s", len
,
3412 vty_out(vty
, "%3" ROUTE_TAG_PRI
,
3413 (route_tag_t
)rinfo
->tag
);
3421 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3422 DEFUN (show_ip_rip_status
,
3423 show_ip_rip_status_cmd
,
3424 "show ip rip status",
3428 "IP routing protocol process parameters and statistics\n")
3430 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3431 struct interface
*ifp
;
3432 struct rip_interface
*ri
;
3433 extern const struct message ri_version_msg
[];
3434 const char *send_version
;
3435 const char *receive_version
;
3440 vty_out(vty
, "Routing Protocol is \"rip\"\n");
3441 vty_out(vty
, " Sending updates every %ld seconds with +/-50%%,",
3443 vty_out(vty
, " next due in %lu seconds\n",
3444 thread_timer_remain_second(rip
->t_update
));
3445 vty_out(vty
, " Timeout after %ld seconds,", rip
->timeout_time
);
3446 vty_out(vty
, " garbage collect after %ld seconds\n", rip
->garbage_time
);
3448 /* Filtering status show. */
3449 config_show_distribute(vty
);
3451 /* Default metric information. */
3452 vty_out(vty
, " Default redistribution metric is %u\n",
3453 rip
->default_metric
);
3455 /* Redistribute information. */
3456 vty_out(vty
, " Redistributing:");
3457 config_write_rip_redistribute(vty
, 0);
3460 vty_out(vty
, " Default version control: send version %s,",
3461 lookup_msg(ri_version_msg
, rip
->version_send
, NULL
));
3462 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3463 vty_out(vty
, " receive any version \n");
3465 vty_out(vty
, " receive version %s \n",
3466 lookup_msg(ri_version_msg
, rip
->version_recv
, NULL
));
3468 vty_out(vty
, " Interface Send Recv Key-chain\n");
3470 FOR_ALL_INTERFACES (vrf
, ifp
) {
3476 if (ri
->enable_network
|| ri
->enable_interface
) {
3477 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3479 lookup_msg(ri_version_msg
,
3480 rip
->version_send
, NULL
);
3482 send_version
= lookup_msg(ri_version_msg
,
3485 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3487 lookup_msg(ri_version_msg
,
3488 rip
->version_recv
, NULL
);
3490 receive_version
= lookup_msg(
3491 ri_version_msg
, ri
->ri_receive
, NULL
);
3493 vty_out(vty
, " %-17s%-3s %-3s %s\n", ifp
->name
,
3494 send_version
, receive_version
,
3495 ri
->key_chain
? ri
->key_chain
: "");
3499 vty_out(vty
, " Routing for Networks:\n");
3500 config_write_rip_network(vty
, 0);
3503 int found_passive
= 0;
3504 FOR_ALL_INTERFACES (vrf
, ifp
) {
3507 if ((ri
->enable_network
|| ri
->enable_interface
)
3509 if (!found_passive
) {
3511 " Passive Interface(s):\n");
3514 vty_out(vty
, " %s\n", ifp
->name
);
3519 vty_out(vty
, " Routing Information Sources:\n");
3521 " Gateway BadPackets BadRoutes Distance Last Update\n");
3522 rip_peer_display(vty
);
3524 rip_distance_show(vty
);
3529 /* RIP configuration write function. */
3530 static int config_write_rip(struct vty
*vty
)
3533 struct route_node
*rn
;
3534 struct rip_distance
*rdistance
;
3535 struct lyd_node
*dnode
;
3537 dnode
= yang_dnode_get(running_config
->dnode
,
3538 "/frr-ripd:ripd/instance");
3542 nb_cli_show_dnode_cmds(vty
, dnode
, false);
3544 /* RIP version statement. Default is RIP version 2. */
3545 if (rip
->version_send
!= RI_RIP_VERSION_2
3546 || rip
->version_recv
!= RI_RIP_VERSION_1_AND_2
)
3547 vty_out(vty
, " version %d\n", rip
->version_send
);
3549 /* RIP timer configuration. */
3550 if (rip
->update_time
!= RIP_UPDATE_TIMER_DEFAULT
3551 || rip
->timeout_time
!= RIP_TIMEOUT_TIMER_DEFAULT
3552 || rip
->garbage_time
!= RIP_GARBAGE_TIMER_DEFAULT
)
3553 vty_out(vty
, " timers basic %lu %lu %lu\n",
3554 rip
->update_time
, rip
->timeout_time
,
3557 /* Redistribute configuration. */
3558 config_write_rip_redistribute(vty
, 1);
3560 /* RIP offset-list configuration. */
3561 config_write_rip_offset_list(vty
);
3563 /* RIP enabled network and interface configuration. */
3564 config_write_rip_network(vty
, 1);
3566 /* Distribute configuration. */
3567 write
+= config_write_distribute(vty
);
3569 /* Interface routemap configuration */
3570 write
+= config_write_if_rmap(vty
);
3572 /* RIP source IP prefix distance configuration. */
3573 for (rn
= route_top(rip_distance_table
); rn
;
3574 rn
= route_next(rn
))
3575 if ((rdistance
= rn
->info
) != NULL
)
3576 vty_out(vty
, " distance %d %s/%d %s\n",
3577 rdistance
->distance
,
3578 inet_ntoa(rn
->p
.u
.prefix4
),
3580 rdistance
->access_list
3581 ? rdistance
->access_list
3584 /* RIP static route configuration. */
3585 for (rn
= route_top(rip
->route
); rn
; rn
= route_next(rn
))
3587 vty_out(vty
, " route %s/%d\n",
3588 inet_ntoa(rn
->p
.u
.prefix4
),
3594 /* RIP node structure. */
3595 static struct cmd_node rip_node
= {RIP_NODE
, "%s(config-router)# ", 1};
3597 /* Distribute-list update functions. */
3598 static void rip_distribute_update(struct distribute
*dist
)
3600 struct interface
*ifp
;
3601 struct rip_interface
*ri
;
3602 struct access_list
*alist
;
3603 struct prefix_list
*plist
;
3608 ifp
= if_lookup_by_name(dist
->ifname
, VRF_DEFAULT
);
3614 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
3615 alist
= access_list_lookup(AFI_IP
,
3616 dist
->list
[DISTRIBUTE_V4_IN
]);
3618 ri
->list
[RIP_FILTER_IN
] = alist
;
3620 ri
->list
[RIP_FILTER_IN
] = NULL
;
3622 ri
->list
[RIP_FILTER_IN
] = NULL
;
3624 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
3625 alist
= access_list_lookup(AFI_IP
,
3626 dist
->list
[DISTRIBUTE_V4_OUT
]);
3628 ri
->list
[RIP_FILTER_OUT
] = alist
;
3630 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3632 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3634 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
3635 plist
= prefix_list_lookup(AFI_IP
,
3636 dist
->prefix
[DISTRIBUTE_V4_IN
]);
3638 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3640 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3642 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3644 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
3645 plist
= prefix_list_lookup(AFI_IP
,
3646 dist
->prefix
[DISTRIBUTE_V4_OUT
]);
3648 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3650 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3652 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3655 void rip_distribute_update_interface(struct interface
*ifp
)
3657 struct distribute
*dist
;
3659 dist
= distribute_lookup(ifp
->name
);
3661 rip_distribute_update(dist
);
3664 /* Update all interface's distribute list. */
3666 static void rip_distribute_update_all(struct prefix_list
*notused
)
3668 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3669 struct interface
*ifp
;
3671 FOR_ALL_INTERFACES (vrf
, ifp
)
3672 rip_distribute_update_interface(ifp
);
3675 static void rip_distribute_update_all_wrapper(struct access_list
*notused
)
3677 rip_distribute_update_all(NULL
);
3680 /* Delete all added rip route. */
3681 void rip_clean(void)
3684 struct route_node
*rp
;
3685 struct rip_info
*rinfo
= NULL
;
3686 struct list
*list
= NULL
;
3687 struct listnode
*listnode
= NULL
;
3692 /* Clear RIP routes */
3693 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3694 if ((list
= rp
->info
) != NULL
) {
3695 rinfo
= listgetdata(listhead(list
));
3696 if (rip_route_rte(rinfo
))
3697 rip_zebra_ipv4_delete(rp
);
3699 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
3701 RIP_TIMER_OFF(rinfo
->t_timeout
);
3702 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
3703 rip_info_free(rinfo
);
3707 route_unlock_node(rp
);
3710 /* Cancel RIP related timers. */
3711 RIP_TIMER_OFF(rip
->t_update
);
3712 RIP_TIMER_OFF(rip
->t_triggered_update
);
3713 RIP_TIMER_OFF(rip
->t_triggered_interval
);
3715 /* Cancel read thread. */
3716 THREAD_READ_OFF(rip
->t_read
);
3718 /* Close RIP socket. */
3719 if (rip
->sock
>= 0) {
3724 stream_free(rip
->obuf
);
3725 /* Static RIP route configuration. */
3726 for (rp
= route_top(rip
->route
); rp
; rp
= route_next(rp
))
3729 route_unlock_node(rp
);
3732 /* RIP neighbor configuration. */
3733 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
3736 route_unlock_node(rp
);
3739 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3740 if (rip
->route_map
[i
].name
)
3741 free(rip
->route_map
[i
].name
);
3743 XFREE(MTYPE_ROUTE_TABLE
, rip
->table
);
3744 XFREE(MTYPE_ROUTE_TABLE
, rip
->route
);
3745 XFREE(MTYPE_ROUTE_TABLE
, rip
->neighbor
);
3747 XFREE(MTYPE_RIP
, rip
);
3751 rip_clean_network();
3752 rip_passive_nondefault_clean();
3754 rip_interfaces_clean();
3755 rip_distance_reset();
3756 rip_redistribute_clean();
3759 /* Reset all values to the default settings. */
3760 void rip_reset(void)
3762 /* Reset global counters. */
3763 rip_global_route_changes
= 0;
3764 rip_global_queries
= 0;
3766 /* Call ripd related reset functions. */
3768 rip_route_map_reset();
3770 /* Call library reset functions. */
3772 access_list_reset();
3773 prefix_list_reset();
3775 distribute_list_reset();
3777 rip_interfaces_reset();
3778 rip_distance_reset();
3780 rip_zclient_reset();
3783 static void rip_if_rmap_update(struct if_rmap
*if_rmap
)
3785 struct interface
*ifp
;
3786 struct rip_interface
*ri
;
3787 struct route_map
*rmap
;
3789 ifp
= if_lookup_by_name(if_rmap
->ifname
, VRF_DEFAULT
);
3795 if (if_rmap
->routemap
[IF_RMAP_IN
]) {
3796 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_IN
]);
3798 ri
->routemap
[IF_RMAP_IN
] = rmap
;
3800 ri
->routemap
[IF_RMAP_IN
] = NULL
;
3802 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
3804 if (if_rmap
->routemap
[IF_RMAP_OUT
]) {
3805 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_OUT
]);
3807 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
3809 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
3811 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
3814 void rip_if_rmap_update_interface(struct interface
*ifp
)
3816 struct if_rmap
*if_rmap
;
3818 if_rmap
= if_rmap_lookup(ifp
->name
);
3820 rip_if_rmap_update(if_rmap
);
3823 static void rip_routemap_update_redistribute(void)
3828 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3829 if (rip
->route_map
[i
].name
)
3830 rip
->route_map
[i
].map
=
3831 route_map_lookup_by_name(
3832 rip
->route_map
[i
].name
);
3838 static void rip_routemap_update(const char *notused
)
3840 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3841 struct interface
*ifp
;
3843 FOR_ALL_INTERFACES (vrf
, ifp
)
3844 rip_if_rmap_update_interface(ifp
);
3846 rip_routemap_update_redistribute();
3849 /* Allocate new rip structure and set default value. */
3852 /* Install top nodes. */
3853 install_node(&rip_node
, config_write_rip
);
3855 /* Install rip commands. */
3856 install_element(VIEW_NODE
, &show_ip_rip_cmd
);
3857 install_element(VIEW_NODE
, &show_ip_rip_status_cmd
);
3859 install_default(RIP_NODE
);
3860 install_element(RIP_NODE
, &rip_version_cmd
);
3861 install_element(RIP_NODE
, &no_rip_version_cmd
);
3862 install_element(RIP_NODE
, &rip_timers_cmd
);
3863 install_element(RIP_NODE
, &no_rip_timers_cmd
);
3864 install_element(RIP_NODE
, &rip_route_cmd
);
3865 install_element(RIP_NODE
, &no_rip_route_cmd
);
3866 install_element(RIP_NODE
, &rip_distance_source_cmd
);
3867 install_element(RIP_NODE
, &no_rip_distance_source_cmd
);
3868 install_element(RIP_NODE
, &rip_distance_source_access_list_cmd
);
3869 install_element(RIP_NODE
, &no_rip_distance_source_access_list_cmd
);
3871 /* Debug related init. */
3874 /* Access list install. */
3876 access_list_add_hook(rip_distribute_update_all_wrapper
);
3877 access_list_delete_hook(rip_distribute_update_all_wrapper
);
3879 /* Prefix list initialize.*/
3881 prefix_list_add_hook(rip_distribute_update_all
);
3882 prefix_list_delete_hook(rip_distribute_update_all
);
3884 /* Distribute list install. */
3885 distribute_list_init(RIP_NODE
);
3886 distribute_list_add_hook(rip_distribute_update
);
3887 distribute_list_delete_hook(rip_distribute_update
);
3890 rip_route_map_init();
3893 route_map_add_hook(rip_routemap_update
);
3894 route_map_delete_hook(rip_routemap_update
);
3896 if_rmap_init(RIP_NODE
);
3897 if_rmap_hook_add(rip_if_rmap_update
);
3898 if_rmap_hook_delete(rip_if_rmap_update
);
3900 /* Distance control. */
3901 rip_distance_table
= route_table_init();