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"
44 #include "ripd/ripd.h"
45 #include "ripd/rip_debug.h"
49 /* UDP receive buffer size */
50 #define RIP_UDP_RCV_BUF 41600
53 struct rip
*rip
= NULL
;
55 /* RIP neighbor address table. */
56 struct route_table
*rip_neighbor_table
;
58 /* RIP route changes. */
59 long rip_global_route_changes
= 0;
62 long rip_global_queries
= 0;
65 static void rip_event(enum rip_event
, int);
66 static void rip_output_process(struct connected
*, struct sockaddr_in
*, int,
68 static int rip_triggered_update(struct thread
*);
69 static int rip_update_jitter(unsigned long);
71 /* RIP output routes type. */
72 enum { rip_all_route
, rip_changed_route
};
74 /* RIP command strings. */
75 static const struct message rip_msg
[] = {{RIP_REQUEST
, "REQUEST"},
76 {RIP_RESPONSE
, "RESPONSE"},
77 {RIP_TRACEON
, "TRACEON"},
78 {RIP_TRACEOFF
, "TRACEOFF"},
80 {RIP_POLL_ENTRY
, "POLL ENTRY"},
83 /* Utility function to set boradcast option to the socket. */
84 static int sockopt_broadcast(int sock
)
89 ret
= setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, (char *)&on
,
92 zlog_warn("can't set sockopt SO_BROADCAST to socket %d", sock
);
98 static int rip_route_rte(struct rip_info
*rinfo
)
100 return (rinfo
->type
== ZEBRA_ROUTE_RIP
101 && rinfo
->sub_type
== RIP_ROUTE_RTE
);
104 static struct rip_info
*rip_info_new(void)
106 return XCALLOC(MTYPE_RIP_INFO
, sizeof(struct rip_info
));
109 void rip_info_free(struct rip_info
*rinfo
)
111 XFREE(MTYPE_RIP_INFO
, rinfo
);
114 /* RIP route garbage collect timer. */
115 static int rip_garbage_collect(struct thread
*t
)
117 struct rip_info
*rinfo
;
118 struct route_node
*rp
;
120 rinfo
= THREAD_ARG(t
);
121 rinfo
->t_garbage_collect
= NULL
;
123 /* Off timeout timer. */
124 RIP_TIMER_OFF(rinfo
->t_timeout
);
126 /* Get route_node pointer. */
129 /* Unlock route_node. */
130 listnode_delete(rp
->info
, rinfo
);
131 if (list_isempty((struct list
*)rp
->info
)) {
132 list_delete_and_null((struct list
**)&rp
->info
);
133 route_unlock_node(rp
);
136 /* Free RIP routing information. */
137 rip_info_free(rinfo
);
142 static void rip_timeout_update(struct rip_info
*rinfo
);
144 /* Add new route to the ECMP list.
145 * RETURN: the new entry added in the list, or NULL if it is not the first
146 * entry and ECMP is not allowed.
148 struct rip_info
*rip_ecmp_add(struct rip_info
*rinfo_new
)
150 struct route_node
*rp
= rinfo_new
->rp
;
151 struct rip_info
*rinfo
= NULL
;
152 struct list
*list
= NULL
;
154 if (rp
->info
== NULL
)
155 rp
->info
= list_new();
156 list
= (struct list
*)rp
->info
;
158 /* If ECMP is not allowed and some entry already exists in the list,
160 if (listcount(list
) && !rip
->ecmp
)
163 rinfo
= rip_info_new();
164 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
165 listnode_add(list
, rinfo
);
167 if (rip_route_rte(rinfo
)) {
168 rip_timeout_update(rinfo
);
169 rip_zebra_ipv4_add(rp
);
172 /* Set the route change flag on the first entry. */
173 rinfo
= listgetdata(listhead(list
));
174 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
176 /* Signal the output process to trigger an update (see section 2.5). */
177 rip_event(RIP_TRIGGERED_UPDATE
, 0);
182 /* Replace the ECMP list with the new route.
183 * RETURN: the new entry added in the list
185 struct rip_info
*rip_ecmp_replace(struct rip_info
*rinfo_new
)
187 struct route_node
*rp
= rinfo_new
->rp
;
188 struct list
*list
= (struct list
*)rp
->info
;
189 struct rip_info
*rinfo
= NULL
, *tmp_rinfo
= NULL
;
190 struct listnode
*node
= NULL
, *nextnode
= NULL
;
192 if (list
== NULL
|| listcount(list
) == 0)
193 return rip_ecmp_add(rinfo_new
);
195 /* Get the first entry */
196 rinfo
= listgetdata(listhead(list
));
198 /* Learnt route replaced by a local one. Delete it from zebra. */
199 if (rip_route_rte(rinfo
) && !rip_route_rte(rinfo_new
))
200 if (CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
201 rip_zebra_ipv4_delete(rp
);
203 /* Re-use the first entry, and delete the others. */
204 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
205 if (tmp_rinfo
!= rinfo
) {
206 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
207 RIP_TIMER_OFF(tmp_rinfo
->t_garbage_collect
);
208 list_delete_node(list
, node
);
209 rip_info_free(tmp_rinfo
);
212 RIP_TIMER_OFF(rinfo
->t_timeout
);
213 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
214 memcpy(rinfo
, rinfo_new
, sizeof(struct rip_info
));
216 if (rip_route_rte(rinfo
)) {
217 rip_timeout_update(rinfo
);
218 /* The ADD message implies an update. */
219 rip_zebra_ipv4_add(rp
);
222 /* Set the route change flag. */
223 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
225 /* Signal the output process to trigger an update (see section 2.5). */
226 rip_event(RIP_TRIGGERED_UPDATE
, 0);
231 /* Delete one route from the ECMP list.
233 * null - the entry is freed, and other entries exist in the list
234 * the entry - the entry is the last one in the list; its metric is set
235 * to INFINITY, and the garbage collector is started for it
237 struct rip_info
*rip_ecmp_delete(struct rip_info
*rinfo
)
239 struct route_node
*rp
= rinfo
->rp
;
240 struct list
*list
= (struct list
*)rp
->info
;
242 RIP_TIMER_OFF(rinfo
->t_timeout
);
244 if (listcount(list
) > 1) {
245 /* Some other ECMP entries still exist. Just delete this entry.
247 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
248 listnode_delete(list
, rinfo
);
249 if (rip_route_rte(rinfo
)
250 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
251 /* The ADD message implies the update. */
252 rip_zebra_ipv4_add(rp
);
253 rip_info_free(rinfo
);
256 assert(rinfo
== listgetdata(listhead(list
)));
258 /* This is the only entry left in the list. We must keep it in
259 * the list for garbage collection time, with INFINITY metric.
262 rinfo
->metric
= RIP_METRIC_INFINITY
;
263 RIP_TIMER_ON(rinfo
->t_garbage_collect
, rip_garbage_collect
,
266 if (rip_route_rte(rinfo
)
267 && CHECK_FLAG(rinfo
->flags
, RIP_RTF_FIB
))
268 rip_zebra_ipv4_delete(rp
);
271 /* Set the route change flag on the first entry. */
272 rinfo
= listgetdata(listhead(list
));
273 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
275 /* Signal the output process to trigger an update (see section 2.5). */
276 rip_event(RIP_TRIGGERED_UPDATE
, 0);
281 /* Timeout RIP routes. */
282 static int rip_timeout(struct thread
*t
)
284 rip_ecmp_delete((struct rip_info
*)THREAD_ARG(t
));
288 static void rip_timeout_update(struct rip_info
*rinfo
)
290 if (rinfo
->metric
!= RIP_METRIC_INFINITY
) {
291 RIP_TIMER_OFF(rinfo
->t_timeout
);
292 RIP_TIMER_ON(rinfo
->t_timeout
, rip_timeout
, rip
->timeout_time
);
296 static int rip_filter(int rip_distribute
, struct prefix_ipv4
*p
,
297 struct rip_interface
*ri
)
299 struct distribute
*dist
;
300 struct access_list
*alist
;
301 struct prefix_list
*plist
;
302 int distribute
= rip_distribute
== RIP_FILTER_OUT
? DISTRIBUTE_V4_OUT
304 const char *inout
= rip_distribute
== RIP_FILTER_OUT
? "out" : "in";
306 /* Input distribute-list filtering. */
307 if (ri
->list
[rip_distribute
]) {
308 if (access_list_apply(ri
->list
[rip_distribute
],
311 if (IS_RIP_DEBUG_PACKET
)
312 zlog_debug("%s/%d filtered by distribute %s",
313 inet_ntoa(p
->prefix
), p
->prefixlen
,
318 if (ri
->prefix
[rip_distribute
]) {
319 if (prefix_list_apply(ri
->prefix
[rip_distribute
],
322 if (IS_RIP_DEBUG_PACKET
)
323 zlog_debug("%s/%d filtered by prefix-list %s",
324 inet_ntoa(p
->prefix
), p
->prefixlen
,
330 /* All interface filter check. */
331 dist
= distribute_lookup(NULL
);
333 if (dist
->list
[distribute
]) {
334 alist
= access_list_lookup(AFI_IP
,
335 dist
->list
[distribute
]);
338 if (access_list_apply(alist
, (struct prefix
*)p
)
340 if (IS_RIP_DEBUG_PACKET
)
342 "%s/%d filtered by distribute %s",
343 inet_ntoa(p
->prefix
),
344 p
->prefixlen
, inout
);
349 if (dist
->prefix
[distribute
]) {
350 plist
= prefix_list_lookup(AFI_IP
,
351 dist
->prefix
[distribute
]);
354 if (prefix_list_apply(plist
, (struct prefix
*)p
)
356 if (IS_RIP_DEBUG_PACKET
)
358 "%s/%d filtered by prefix-list %s",
359 inet_ntoa(p
->prefix
),
360 p
->prefixlen
, inout
);
369 /* Check nexthop address validity. */
370 static int rip_nexthop_check(struct in_addr
*addr
)
372 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
373 struct interface
*ifp
;
374 struct listnode
*cnode
;
375 struct connected
*ifc
;
378 /* If nexthop address matches local configured address then it is
381 FOR_ALL_INTERFACES (vrf
, ifp
) {
382 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, ifc
)) {
385 if (p
->family
== AF_INET
386 && IPV4_ADDR_SAME(&p
->u
.prefix4
, addr
))
393 /* RIP add route to routing table. */
394 static void rip_rte_process(struct rte
*rte
, struct sockaddr_in
*from
,
395 struct interface
*ifp
)
398 struct prefix_ipv4 p
;
399 struct route_node
*rp
;
400 struct rip_info
*rinfo
= NULL
, newinfo
;
401 struct rip_interface
*ri
;
402 struct in_addr
*nexthop
;
404 unsigned char old_dist
, new_dist
;
405 struct list
*list
= NULL
;
406 struct listnode
*node
= NULL
;
408 /* Make prefix structure. */
409 memset(&p
, 0, sizeof(struct prefix_ipv4
));
411 p
.prefix
= rte
->prefix
;
412 p
.prefixlen
= ip_masklen(rte
->mask
);
414 /* Make sure mask is applied. */
417 /* Apply input filters. */
420 ret
= rip_filter(RIP_FILTER_IN
, &p
, ri
);
424 memset(&newinfo
, 0, sizeof(newinfo
));
425 newinfo
.type
= ZEBRA_ROUTE_RIP
;
426 newinfo
.sub_type
= RIP_ROUTE_RTE
;
427 newinfo
.nh
.gate
.ipv4
= rte
->nexthop
;
428 newinfo
.from
= from
->sin_addr
;
429 newinfo
.nh
.ifindex
= ifp
->ifindex
;
430 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
431 newinfo
.metric
= rte
->metric
;
432 newinfo
.metric_out
= rte
->metric
; /* XXX */
433 newinfo
.tag
= ntohs(rte
->tag
); /* XXX */
435 /* Modify entry according to the interface routemap. */
436 if (ri
->routemap
[RIP_FILTER_IN
]) {
439 /* The object should be of the type of rip_info */
440 ret
= route_map_apply(ri
->routemap
[RIP_FILTER_IN
],
441 (struct prefix
*)&p
, RMAP_RIP
, &newinfo
);
443 if (ret
== RMAP_DENYMATCH
) {
444 if (IS_RIP_DEBUG_PACKET
)
446 "RIP %s/%d is filtered by route-map in",
447 inet_ntoa(p
.prefix
), p
.prefixlen
);
451 /* Get back the object */
452 rte
->nexthop
= newinfo
.nexthop_out
;
453 rte
->tag
= htons(newinfo
.tag_out
); /* XXX */
454 rte
->metric
= newinfo
.metric_out
; /* XXX: the routemap uses the
458 /* Once the entry has been validated, update the metric by
459 adding the cost of the network on wich the message
460 arrived. If the result is greater than infinity, use infinity
461 (RFC2453 Sec. 3.9.2) */
462 /* Zebra ripd can handle offset-list in. */
463 ret
= rip_offset_list_apply_in(&p
, ifp
, &rte
->metric
);
465 /* If offset-list does not modify the metric use interface's
468 rte
->metric
+= ifp
->metric
? ifp
->metric
: 1;
470 if (rte
->metric
> RIP_METRIC_INFINITY
)
471 rte
->metric
= RIP_METRIC_INFINITY
;
473 /* Set nexthop pointer. */
474 if (rte
->nexthop
.s_addr
== 0)
475 nexthop
= &from
->sin_addr
;
477 nexthop
= &rte
->nexthop
;
479 /* Check if nexthop address is myself, then do nothing. */
480 if (rip_nexthop_check(nexthop
) < 0) {
481 if (IS_RIP_DEBUG_PACKET
)
482 zlog_debug("Nexthop address %s is myself",
483 inet_ntoa(*nexthop
));
487 /* Get index for the prefix. */
488 rp
= route_node_get(rip
->table
, (struct prefix
*)&p
);
491 newinfo
.nh
.gate
.ipv4
= *nexthop
;
492 newinfo
.nh
.type
= NEXTHOP_TYPE_IPV4
;
493 newinfo
.metric
= rte
->metric
;
494 newinfo
.tag
= ntohs(rte
->tag
);
495 newinfo
.distance
= rip_distance_apply(&newinfo
);
497 new_dist
= newinfo
.distance
? newinfo
.distance
498 : ZEBRA_RIP_DISTANCE_DEFAULT
;
500 /* Check to see whether there is already RIP route on the table. */
501 if ((list
= rp
->info
) != NULL
)
502 for (ALL_LIST_ELEMENTS_RO(list
, node
, rinfo
)) {
503 /* Need to compare with redistributed entry or local
505 if (!rip_route_rte(rinfo
))
508 if (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
509 && IPV4_ADDR_SAME(&rinfo
->nh
.gate
.ipv4
, nexthop
))
512 if (!listnextnode(node
)) {
513 /* Not found in the list */
515 if (rte
->metric
> rinfo
->metric
) {
516 /* New route has a greater metric.
518 route_unlock_node(rp
);
522 if (rte
->metric
< rinfo
->metric
)
523 /* New route has a smaller metric.
524 * Replace the ECMP list
525 * with the new one in below. */
528 /* Metrics are same. We compare the distances.
530 old_dist
= rinfo
->distance
532 : ZEBRA_RIP_DISTANCE_DEFAULT
;
534 if (new_dist
> old_dist
) {
535 /* New route has a greater distance.
537 route_unlock_node(rp
);
541 if (new_dist
< old_dist
)
542 /* New route has a smaller distance.
543 * Replace the ECMP list
544 * with the new one in below. */
547 /* Metrics and distances are both same. Keep
549 * the new route is added in the ECMP list in
555 /* Local static route. */
556 if (rinfo
->type
== ZEBRA_ROUTE_RIP
557 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
558 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))
559 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
560 route_unlock_node(rp
);
564 /* Redistributed route check. */
565 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
566 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
567 old_dist
= rinfo
->distance
;
568 /* Only routes directly connected to an interface
570 * may have a valid NULL distance */
571 if (rinfo
->nh
.gate
.ipv4
.s_addr
!= 0)
574 : ZEBRA_RIP_DISTANCE_DEFAULT
;
575 /* If imported route does not have STRICT precedence,
576 mark it as a ghost */
577 if (new_dist
<= old_dist
578 && rte
->metric
!= RIP_METRIC_INFINITY
)
579 rip_ecmp_replace(&newinfo
);
581 route_unlock_node(rp
);
588 route_unlock_node(rp
);
590 /* Now, check to see whether there is already an explicit route
591 for the destination prefix. If there is no such route, add
592 this route to the routing table, unless the metric is
593 infinity (there is no point in adding a route which
595 if (rte
->metric
!= RIP_METRIC_INFINITY
)
596 rip_ecmp_add(&newinfo
);
598 /* Route is there but we are not sure the route is RIP or not.
601 /* If there is an existing route, compare the next hop address
602 to the address of the router from which the datagram came.
603 If this datagram is from the same router as the existing
604 route, reinitialize the timeout. */
605 same
= (IPV4_ADDR_SAME(&rinfo
->from
, &from
->sin_addr
)
606 && (rinfo
->nh
.ifindex
== ifp
->ifindex
));
608 old_dist
= rinfo
->distance
? rinfo
->distance
609 : ZEBRA_RIP_DISTANCE_DEFAULT
;
611 /* Next, compare the metrics. If the datagram is from the same
612 router as the existing route, and the new metric is different
613 than the old one; or, if the new metric is lower than the old
614 one, or if the tag has been changed; or if there is a route
615 with a lower administrave distance; or an update of the
616 distance on the actual route; do the following actions: */
617 if ((same
&& rinfo
->metric
!= rte
->metric
)
618 || (rte
->metric
< rinfo
->metric
)
619 || ((same
) && (rinfo
->metric
== rte
->metric
)
620 && (newinfo
.tag
!= rinfo
->tag
))
621 || (old_dist
> new_dist
)
622 || ((old_dist
!= new_dist
) && same
)) {
623 if (listcount(list
) == 1) {
624 if (newinfo
.metric
!= RIP_METRIC_INFINITY
)
625 rip_ecmp_replace(&newinfo
);
627 rip_ecmp_delete(rinfo
);
629 if (newinfo
.metric
< rinfo
->metric
)
630 rip_ecmp_replace(&newinfo
);
631 else if (newinfo
.metric
> rinfo
->metric
)
632 rip_ecmp_delete(rinfo
);
633 else if (new_dist
< old_dist
)
634 rip_ecmp_replace(&newinfo
);
635 else if (new_dist
> old_dist
)
636 rip_ecmp_delete(rinfo
);
638 int update
= CHECK_FLAG(rinfo
->flags
,
643 assert(newinfo
.metric
644 != RIP_METRIC_INFINITY
);
646 RIP_TIMER_OFF(rinfo
->t_timeout
);
647 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
648 memcpy(rinfo
, &newinfo
,
649 sizeof(struct rip_info
));
650 rip_timeout_update(rinfo
);
653 rip_zebra_ipv4_add(rp
);
655 /* - Set the route change flag on the
657 rinfo
= listgetdata(listhead(list
));
658 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
659 rip_event(RIP_TRIGGERED_UPDATE
, 0);
662 } else /* same & no change */
663 rip_timeout_update(rinfo
);
665 /* Unlock tempolary lock of the route. */
666 route_unlock_node(rp
);
670 /* Dump RIP packet */
671 static void rip_packet_dump(struct rip_packet
*packet
, int size
,
676 const char *command_str
;
677 char pbuf
[BUFSIZ
], nbuf
[BUFSIZ
];
681 /* Set command string. */
682 if (packet
->command
> 0 && packet
->command
< RIP_COMMAND_MAX
)
683 command_str
= lookup_msg(rip_msg
, packet
->command
, NULL
);
685 command_str
= "unknown";
687 /* Dump packet header. */
688 zlog_debug("%s %s version %d packet size %d", sndrcv
, command_str
,
689 packet
->version
, size
);
691 /* Dump each routing table entry. */
694 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
695 if (packet
->version
== RIPv2
) {
696 netmask
= ip_masklen(rte
->mask
);
698 if (rte
->family
== htons(RIP_FAMILY_AUTH
)) {
700 == htons(RIP_AUTH_SIMPLE_PASSWORD
)) {
701 p
= (u_char
*)&rte
->prefix
;
704 " family 0x%X type %d auth string: %s",
707 } else if (rte
->tag
== htons(RIP_AUTH_MD5
)) {
708 struct rip_md5_info
*md5
;
710 md5
= (struct rip_md5_info
*)&packet
714 " family 0x%X type %d (MD5 authentication)",
718 " RIP-2 packet len %d Key ID %d"
720 ntohs(md5
->packet_len
),
721 md5
->keyid
, md5
->auth_len
);
723 " Sequence Number %ld",
724 (u_long
)ntohl(md5
->sequence
));
725 } else if (rte
->tag
== htons(RIP_AUTH_DATA
)) {
726 p
= (u_char
*)&rte
->prefix
;
729 " family 0x%X type %d (MD5 data)",
733 " MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
734 "%02X%02X%02X%02X%02X%02X%02X%02X",
735 p
[0], p
[1], p
[2], p
[3], p
[4],
736 p
[5], p
[6], p
[7], p
[8], p
[9],
737 p
[10], p
[11], p
[12], p
[13],
741 " family 0x%X type %d (Unknown auth type)",
747 " %s/%d -> %s family %d tag %" ROUTE_TAG_PRI
749 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
,
752 inet_ntop(AF_INET
, &rte
->nexthop
, nbuf
,
755 (route_tag_t
)ntohs(rte
->tag
),
756 (u_long
)ntohl(rte
->metric
));
759 " %s family %d tag %" ROUTE_TAG_PRI
761 inet_ntop(AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
763 (route_tag_t
)ntohs(rte
->tag
),
764 (u_long
)ntohl(rte
->metric
));
769 /* Check if the destination address is valid (unicast; not net 0
770 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
771 check net 0 because we accept default route. */
772 static int rip_destination_check(struct in_addr addr
)
774 u_int32_t destination
;
776 /* Convert to host byte order. */
777 destination
= ntohl(addr
.s_addr
);
779 if (IPV4_NET127(destination
))
782 /* Net 0 may match to the default route. */
783 if (IPV4_NET0(destination
) && destination
!= 0)
786 /* Unicast address must belong to class A, B, C. */
787 if (IN_CLASSA(destination
))
789 if (IN_CLASSB(destination
))
791 if (IN_CLASSC(destination
))
797 /* RIP version 2 authentication. */
798 static int rip_auth_simple_password(struct rte
*rte
, struct sockaddr_in
*from
,
799 struct interface
*ifp
)
801 struct rip_interface
*ri
;
802 char *auth_str
= (char *)&rte
->prefix
;
805 /* reject passwords with zeros in the middle of the string */
806 for (i
= strlen(auth_str
); i
< 16; i
++) {
807 if (auth_str
[i
] != '\0')
811 if (IS_RIP_DEBUG_EVENT
)
812 zlog_debug("RIPv2 simple password authentication from %s",
813 inet_ntoa(from
->sin_addr
));
817 if (ri
->auth_type
!= RIP_AUTH_SIMPLE_PASSWORD
818 || rte
->tag
!= htons(RIP_AUTH_SIMPLE_PASSWORD
))
821 /* Simple password authentication. */
823 if (strncmp(auth_str
, ri
->auth_str
, 16) == 0)
827 struct keychain
*keychain
;
830 keychain
= keychain_lookup(ri
->key_chain
);
831 if (keychain
== NULL
)
834 key
= key_match_for_accept(keychain
, auth_str
);
841 /* RIP version 2 authentication with MD5. */
842 static int rip_auth_md5(struct rip_packet
*packet
, struct sockaddr_in
*from
,
843 int length
, struct interface
*ifp
)
845 struct rip_interface
*ri
;
846 struct rip_md5_info
*md5
;
847 struct rip_md5_data
*md5data
;
848 struct keychain
*keychain
;
851 u_char digest
[RIP_AUTH_MD5_SIZE
];
852 u_int16_t packet_len
;
853 char auth_str
[RIP_AUTH_MD5_SIZE
];
855 if (IS_RIP_DEBUG_EVENT
)
856 zlog_debug("RIPv2 MD5 authentication from %s",
857 inet_ntoa(from
->sin_addr
));
860 md5
= (struct rip_md5_info
*)&packet
->rte
;
862 /* Check auth type. */
863 if (ri
->auth_type
!= RIP_AUTH_MD5
|| md5
->type
!= htons(RIP_AUTH_MD5
))
866 /* If the authentication length is less than 16, then it must be wrong
868 * any interpretation of rfc2082. Some implementations also interpret
869 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka
870 * RIP_AUTH_MD5_COMPAT_SIZE.
872 if (!((md5
->auth_len
== RIP_AUTH_MD5_SIZE
)
873 || (md5
->auth_len
== RIP_AUTH_MD5_COMPAT_SIZE
))) {
874 if (IS_RIP_DEBUG_EVENT
)
876 "RIPv2 MD5 authentication, strange authentication "
882 /* grab and verify check packet length */
883 packet_len
= ntohs(md5
->packet_len
);
885 if (packet_len
> (length
- RIP_HEADER_SIZE
- RIP_AUTH_MD5_SIZE
)) {
886 if (IS_RIP_DEBUG_EVENT
)
888 "RIPv2 MD5 authentication, packet length field %d "
889 "greater than received length %d!",
890 md5
->packet_len
, length
);
894 /* retrieve authentication data */
895 md5data
= (struct rip_md5_data
*)(((u_char
*)packet
) + packet_len
);
897 memset(auth_str
, 0, RIP_AUTH_MD5_SIZE
);
900 keychain
= keychain_lookup(ri
->key_chain
);
901 if (keychain
== NULL
)
904 key
= key_lookup_for_accept(keychain
, md5
->keyid
);
908 strncpy(auth_str
, key
->string
, RIP_AUTH_MD5_SIZE
);
909 } else if (ri
->auth_str
)
910 strncpy(auth_str
, ri
->auth_str
, RIP_AUTH_MD5_SIZE
);
912 if (auth_str
[0] == 0)
915 /* MD5 digest authentication. */
916 memset(&ctx
, 0, sizeof(ctx
));
918 MD5Update(&ctx
, packet
, packet_len
+ RIP_HEADER_SIZE
);
919 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
920 MD5Final(digest
, &ctx
);
922 if (memcmp(md5data
->digest
, digest
, RIP_AUTH_MD5_SIZE
) == 0)
928 /* Pick correct auth string for sends, prepare auth_str buffer for use.
929 * (left justified and padded).
931 * presumes one of ri or key is valid, and that the auth strings they point
932 * to are nul terminated. If neither are present, auth_str will be fully
936 static void rip_auth_prepare_str_send(struct rip_interface
*ri
, struct key
*key
,
937 char *auth_str
, int len
)
941 memset(auth_str
, 0, len
);
942 if (key
&& key
->string
)
943 strncpy(auth_str
, key
->string
, len
);
944 else if (ri
->auth_str
)
945 strncpy(auth_str
, ri
->auth_str
, len
);
950 /* Write RIPv2 simple password authentication information
952 * auth_str is presumed to be 2 bytes and correctly prepared
953 * (left justified and zero padded).
955 static void rip_auth_simple_write(struct stream
*s
, char *auth_str
, int len
)
957 assert(s
&& len
== RIP_AUTH_SIMPLE_SIZE
);
959 stream_putw(s
, RIP_FAMILY_AUTH
);
960 stream_putw(s
, RIP_AUTH_SIMPLE_PASSWORD
);
961 stream_put(s
, auth_str
, RIP_AUTH_SIMPLE_SIZE
);
966 /* write RIPv2 MD5 "authentication header"
967 * (uses the auth key data field)
969 * Digest offset field is set to 0.
971 * returns: offset of the digest offset field, which must be set when
972 * length to the auth-data MD5 digest is known.
974 static size_t rip_auth_md5_ah_write(struct stream
*s
, struct rip_interface
*ri
,
979 assert(s
&& ri
&& ri
->auth_type
== RIP_AUTH_MD5
);
981 /* MD5 authentication. */
982 stream_putw(s
, RIP_FAMILY_AUTH
);
983 stream_putw(s
, RIP_AUTH_MD5
);
985 /* MD5 AH digest offset field.
987 * Set to placeholder value here, to true value when RIP-2 Packet length
988 * is known. Actual value is set in .....().
990 doff
= stream_get_endp(s
);
995 stream_putc(s
, key
->index
% 256);
999 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
1000 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for
1002 * to be configurable.
1004 stream_putc(s
, ri
->md5_auth_len
);
1006 /* Sequence Number (non-decreasing). */
1007 /* RFC2080: The value used in the sequence number is
1008 arbitrary, but two suggestions are the time of the
1009 message's creation or a simple message counter. */
1010 stream_putl(s
, time(NULL
));
1012 /* Reserved field must be zero. */
1019 /* If authentication is in used, write the appropriate header
1020 * returns stream offset to which length must later be written
1021 * or 0 if this is not required
1023 static size_t rip_auth_header_write(struct stream
*s
, struct rip_interface
*ri
,
1024 struct key
*key
, char *auth_str
, int len
)
1026 assert(ri
->auth_type
!= RIP_NO_AUTH
);
1028 switch (ri
->auth_type
) {
1029 case RIP_AUTH_SIMPLE_PASSWORD
:
1030 rip_auth_prepare_str_send(ri
, key
, auth_str
, len
);
1031 rip_auth_simple_write(s
, auth_str
, len
);
1034 return rip_auth_md5_ah_write(s
, ri
, key
);
1040 /* Write RIPv2 MD5 authentication data trailer */
1041 static void rip_auth_md5_set(struct stream
*s
, struct rip_interface
*ri
,
1042 size_t doff
, char *auth_str
, int authlen
)
1046 unsigned char digest
[RIP_AUTH_MD5_SIZE
];
1048 /* Make it sure this interface is configured as MD5
1050 assert((ri
->auth_type
== RIP_AUTH_MD5
)
1051 && (authlen
== RIP_AUTH_MD5_SIZE
));
1054 /* Get packet length. */
1055 len
= stream_get_endp(s
);
1057 /* Check packet length. */
1058 if (len
< (RIP_HEADER_SIZE
+ RIP_RTE_SIZE
)) {
1060 "rip_auth_md5_set(): packet length %ld is less than minimum length.",
1065 /* Set the digest offset length in the header */
1066 stream_putw_at(s
, doff
, len
);
1068 /* Set authentication data. */
1069 stream_putw(s
, RIP_FAMILY_AUTH
);
1070 stream_putw(s
, RIP_AUTH_DATA
);
1072 /* Generate a digest for the RIP packet. */
1073 memset(&ctx
, 0, sizeof(ctx
));
1075 MD5Update(&ctx
, STREAM_DATA(s
), stream_get_endp(s
));
1076 MD5Update(&ctx
, auth_str
, RIP_AUTH_MD5_SIZE
);
1077 MD5Final(digest
, &ctx
);
1079 /* Copy the digest to the packet. */
1080 stream_write(s
, digest
, RIP_AUTH_MD5_SIZE
);
1083 /* RIP routing information. */
1084 static void rip_response_process(struct rip_packet
*packet
, int size
,
1085 struct sockaddr_in
*from
,
1086 struct connected
*ifc
)
1090 struct prefix_ipv4 ifaddr
;
1091 struct prefix_ipv4 ifaddrclass
;
1094 memset(&ifaddr
, 0, sizeof(ifaddr
));
1095 /* We don't know yet. */
1098 /* The Response must be ignored if it is not from the RIP
1099 port. (RFC2453 - Sec. 3.9.2)*/
1100 if (from
->sin_port
!= htons(RIP_PORT_DEFAULT
)) {
1101 zlog_info("response doesn't come from RIP port: %d",
1103 rip_peer_bad_packet(from
);
1107 /* The datagram's IPv4 source address should be checked to see
1108 whether the datagram is from a valid neighbor; the source of the
1109 datagram must be on a directly connected network (RFC2453 - Sec.
1111 if (if_lookup_address((void *)&from
->sin_addr
, AF_INET
, VRF_DEFAULT
)
1114 "This datagram doesn't came from a valid neighbor: %s",
1115 inet_ntoa(from
->sin_addr
));
1116 rip_peer_bad_packet(from
);
1120 /* It is also worth checking to see whether the response is from one
1121 of the router's own addresses. */
1123 ; /* Alredy done in rip_read () */
1125 /* Update RIP peer. */
1126 rip_peer_update(from
, packet
->version
);
1128 /* Set RTE pointer. */
1131 for (lim
= (caddr_t
)packet
+ size
; (caddr_t
)rte
< lim
; rte
++) {
1132 /* RIPv2 authentication check. */
1133 /* If the Address Family Identifier of the first (and only the
1134 first) entry in the message is 0xFFFF, then the remainder of
1135 the entry contains the authentication. */
1136 /* If the packet gets here it means authentication enabled */
1137 /* Check is done in rip_read(). So, just skipping it */
1138 if (packet
->version
== RIPv2
&& rte
== packet
->rte
1139 && rte
->family
== htons(RIP_FAMILY_AUTH
))
1142 if (rte
->family
!= htons(AF_INET
)) {
1143 /* Address family check. RIP only supports AF_INET. */
1144 zlog_info("Unsupported family %d from %s.",
1146 inet_ntoa(from
->sin_addr
));
1150 /* - is the destination address valid (e.g., unicast; not net 0
1152 if (!rip_destination_check(rte
->prefix
)) {
1154 "Network is net 0 or net 127 or it is not unicast network");
1155 rip_peer_bad_route(from
);
1159 /* Convert metric value to host byte order. */
1160 rte
->metric
= ntohl(rte
->metric
);
1162 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1163 if (!(rte
->metric
>= 1 && rte
->metric
<= 16)) {
1164 zlog_info("Route's metric is not in the 1-16 range.");
1165 rip_peer_bad_route(from
);
1169 /* RIPv1 does not have nexthop value. */
1170 if (packet
->version
== RIPv1
&& rte
->nexthop
.s_addr
!= 0) {
1171 zlog_info("RIPv1 packet with nexthop value %s",
1172 inet_ntoa(rte
->nexthop
));
1173 rip_peer_bad_route(from
);
1177 /* That is, if the provided information is ignored, a possibly
1178 sub-optimal, but absolutely valid, route may be taken. If
1179 the received Next Hop is not directly reachable, it should be
1180 treated as 0.0.0.0. */
1181 if (packet
->version
== RIPv2
&& rte
->nexthop
.s_addr
!= 0) {
1184 /* Multicast address check. */
1185 addrval
= ntohl(rte
->nexthop
.s_addr
);
1186 if (IN_CLASSD(addrval
)) {
1188 "Nexthop %s is multicast address, skip this rte",
1189 inet_ntoa(rte
->nexthop
));
1193 if (!if_lookup_address((void *)&rte
->nexthop
, AF_INET
,
1195 struct route_node
*rn
;
1196 struct rip_info
*rinfo
;
1198 rn
= route_node_match_ipv4(rip
->table
,
1204 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1207 if (IS_RIP_DEBUG_EVENT
)
1209 "Next hop %s is on RIP network. Set nexthop to the packet's originator",
1212 rte
->nexthop
= rinfo
->from
;
1214 if (IS_RIP_DEBUG_EVENT
)
1216 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1219 rte
->nexthop
.s_addr
= 0;
1222 route_unlock_node(rn
);
1224 if (IS_RIP_DEBUG_EVENT
)
1226 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1229 rte
->nexthop
.s_addr
= 0;
1234 /* For RIPv1, there won't be a valid netmask.
1236 This is a best guess at the masks. If everyone was using old
1237 Ciscos before the 'ip subnet zero' option, it would be almost
1240 Cisco summarize ripv1 advertisments to the classful boundary
1241 (/16 for class B's) except when the RIP packet does to inside
1242 the classful network in question. */
1244 if ((packet
->version
== RIPv1
&& rte
->prefix
.s_addr
!= 0)
1245 || (packet
->version
== RIPv2
1246 && (rte
->prefix
.s_addr
!= 0
1247 && rte
->mask
.s_addr
== 0))) {
1248 u_int32_t destination
;
1250 if (subnetted
== -1) {
1251 memcpy(&ifaddr
, ifc
->address
,
1252 sizeof(struct prefix_ipv4
));
1253 memcpy(&ifaddrclass
, &ifaddr
,
1254 sizeof(struct prefix_ipv4
));
1255 apply_classful_mask_ipv4(&ifaddrclass
);
1257 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1261 destination
= ntohl(rte
->prefix
.s_addr
);
1263 if (IN_CLASSA(destination
))
1264 masklen2ip(8, &rte
->mask
);
1265 else if (IN_CLASSB(destination
))
1266 masklen2ip(16, &rte
->mask
);
1267 else if (IN_CLASSC(destination
))
1268 masklen2ip(24, &rte
->mask
);
1271 masklen2ip(ifaddrclass
.prefixlen
,
1272 (struct in_addr
*)&destination
);
1273 if ((subnetted
== 1)
1274 && ((rte
->prefix
.s_addr
& destination
)
1275 == ifaddrclass
.prefix
.s_addr
)) {
1276 masklen2ip(ifaddr
.prefixlen
, &rte
->mask
);
1277 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1278 != rte
->prefix
.s_addr
)
1279 masklen2ip(32, &rte
->mask
);
1280 if (IS_RIP_DEBUG_EVENT
)
1281 zlog_debug("Subnetted route %s",
1282 inet_ntoa(rte
->prefix
));
1284 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1285 != rte
->prefix
.s_addr
)
1289 if (IS_RIP_DEBUG_EVENT
) {
1290 zlog_debug("Resultant route %s",
1291 inet_ntoa(rte
->prefix
));
1292 zlog_debug("Resultant mask %s",
1293 inet_ntoa(rte
->mask
));
1297 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1298 ignore the entry. */
1299 if ((packet
->version
== RIPv2
) && (rte
->mask
.s_addr
!= 0)
1300 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
)
1301 != rte
->prefix
.s_addr
)) {
1303 "RIPv2 address %s is not mask /%d applied one",
1304 inet_ntoa(rte
->prefix
), ip_masklen(rte
->mask
));
1305 rip_peer_bad_route(from
);
1309 /* Default route's netmask is ignored. */
1310 if (packet
->version
== RIPv2
&& (rte
->prefix
.s_addr
== 0)
1311 && (rte
->mask
.s_addr
!= 0)) {
1312 if (IS_RIP_DEBUG_EVENT
)
1314 "Default route with non-zero netmask. Set zero to netmask");
1315 rte
->mask
.s_addr
= 0;
1318 /* Routing table updates. */
1319 rip_rte_process(rte
, from
, ifc
->ifp
);
1323 /* Make socket for RIP protocol. */
1324 static int rip_create_socket(void)
1328 struct sockaddr_in addr
;
1330 memset(&addr
, 0, sizeof(struct sockaddr_in
));
1331 addr
.sin_family
= AF_INET
;
1332 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1333 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1334 addr
.sin_len
= sizeof(struct sockaddr_in
);
1335 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1336 /* sending port must always be the RIP port */
1337 addr
.sin_port
= htons(RIP_PORT_DEFAULT
);
1339 /* Make datagram socket. */
1340 sock
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
1342 zlog_err("Cannot create UDP socket: %s", safe_strerror(errno
));
1346 sockopt_broadcast(sock
);
1347 sockopt_reuseaddr(sock
);
1348 sockopt_reuseport(sock
);
1349 setsockopt_ipv4_multicast_loop(sock
, 0);
1351 setsockopt_pktinfo(sock
);
1352 #endif /* RIP_RECVMSG */
1353 #ifdef IPTOS_PREC_INTERNETCONTROL
1354 setsockopt_ipv4_tos(sock
, IPTOS_PREC_INTERNETCONTROL
);
1357 if (ripd_privs
.change(ZPRIVS_RAISE
))
1358 zlog_err("rip_create_socket: could not raise privs");
1359 setsockopt_so_recvbuf(sock
, RIP_UDP_RCV_BUF
);
1360 if ((ret
= bind(sock
, (struct sockaddr
*)&addr
, sizeof(addr
))) < 0)
1363 int save_errno
= errno
;
1364 if (ripd_privs
.change(ZPRIVS_LOWER
))
1365 zlog_err("rip_create_socket: could not lower privs");
1367 zlog_err("%s: Can't bind socket %d to %s port %d: %s", __func__
,
1368 sock
, inet_ntoa(addr
.sin_addr
),
1369 (int)ntohs(addr
.sin_port
), safe_strerror(save_errno
));
1375 if (ripd_privs
.change(ZPRIVS_LOWER
))
1376 zlog_err("rip_create_socket: could not lower privs");
1381 /* RIP packet send to destination address, on interface denoted by
1382 * by connected argument. NULL to argument denotes destination should be
1383 * should be RIP multicast group
1385 static int rip_send_packet(u_char
*buf
, int size
, struct sockaddr_in
*to
,
1386 struct connected
*ifc
)
1389 struct sockaddr_in sin
;
1391 assert(ifc
!= NULL
);
1393 if (IS_RIP_DEBUG_PACKET
) {
1394 #define ADDRESS_SIZE 20
1395 char dst
[ADDRESS_SIZE
];
1396 dst
[ADDRESS_SIZE
- 1] = '\0';
1399 strncpy(dst
, inet_ntoa(to
->sin_addr
), ADDRESS_SIZE
- 1);
1401 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1402 strncpy(dst
, inet_ntoa(sin
.sin_addr
), ADDRESS_SIZE
- 1);
1405 zlog_debug("rip_send_packet %s > %s (%s)",
1406 inet_ntoa(ifc
->address
->u
.prefix4
), dst
,
1410 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
1412 * ZEBRA_IFA_SECONDARY is set on linux when an interface is
1414 * with multiple addresses on the same subnet: the first address
1415 * on the subnet is configured "primary", and all subsequent
1417 * on that subnet are treated as "secondary" addresses.
1418 * In order to avoid routing-table bloat on other rip listeners,
1419 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY
1421 * XXX Since Linux is the only system for which the
1422 * ZEBRA_IFA_SECONDARY
1423 * flag is set, we would end up sending a packet for a
1425 * source address on non-linux systems.
1427 if (IS_RIP_DEBUG_PACKET
)
1428 zlog_debug("duplicate dropped");
1432 /* Make destination address. */
1433 memset(&sin
, 0, sizeof(struct sockaddr_in
));
1434 sin
.sin_family
= AF_INET
;
1435 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1436 sin
.sin_len
= sizeof(struct sockaddr_in
);
1437 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1439 /* When destination is specified, use it's port and address. */
1441 sin
.sin_port
= to
->sin_port
;
1442 sin
.sin_addr
= to
->sin_addr
;
1444 sin
.sin_port
= htons(RIP_PORT_DEFAULT
);
1445 sin
.sin_addr
.s_addr
= htonl(INADDR_RIP_GROUP
);
1447 rip_interface_multicast_set(rip
->sock
, ifc
);
1450 ret
= sendto(rip
->sock
, buf
, size
, 0, (struct sockaddr
*)&sin
,
1451 sizeof(struct sockaddr_in
));
1453 if (IS_RIP_DEBUG_EVENT
)
1454 zlog_debug("SEND to %s.%d", inet_ntoa(sin
.sin_addr
),
1455 ntohs(sin
.sin_port
));
1458 zlog_warn("can't send packet : %s", safe_strerror(errno
));
1463 /* Add redistributed route to RIP table. */
1464 void rip_redistribute_add(int type
, int sub_type
, struct prefix_ipv4
*p
,
1465 struct nexthop
*nh
, unsigned int metric
,
1466 unsigned char distance
, route_tag_t tag
)
1469 struct route_node
*rp
= NULL
;
1470 struct rip_info
*rinfo
= NULL
, newinfo
;
1471 struct list
*list
= NULL
;
1473 /* Redistribute route */
1474 ret
= rip_destination_check(p
->prefix
);
1478 rp
= route_node_get(rip
->table
, (struct prefix
*)p
);
1480 memset(&newinfo
, 0, sizeof(struct rip_info
));
1481 newinfo
.type
= type
;
1482 newinfo
.sub_type
= sub_type
;
1484 newinfo
.external_metric
= metric
;
1485 newinfo
.distance
= distance
;
1486 if (tag
<= UINT16_MAX
) /* RIP only supports 16 bit tags */
1491 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
1492 rinfo
= listgetdata(listhead(list
));
1494 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
1495 && rinfo
->sub_type
== RIP_ROUTE_INTERFACE
1496 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
1497 route_unlock_node(rp
);
1501 /* Manually configured RIP route check. */
1502 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1503 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
)
1504 || (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))) {
1505 if (type
!= ZEBRA_ROUTE_RIP
1506 || ((sub_type
!= RIP_ROUTE_STATIC
)
1507 && (sub_type
!= RIP_ROUTE_DEFAULT
))) {
1508 route_unlock_node(rp
);
1513 (void)rip_ecmp_replace(&newinfo
);
1514 route_unlock_node(rp
);
1516 (void)rip_ecmp_add(&newinfo
);
1518 if (IS_RIP_DEBUG_EVENT
) {
1519 zlog_debug("Redistribute new prefix %s/%d",
1520 inet_ntoa(p
->prefix
), p
->prefixlen
);
1523 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1526 /* Delete redistributed route from RIP table. */
1527 void rip_redistribute_delete(int type
, int sub_type
, struct prefix_ipv4
*p
,
1531 struct route_node
*rp
;
1532 struct rip_info
*rinfo
;
1534 ret
= rip_destination_check(p
->prefix
);
1538 rp
= route_node_lookup(rip
->table
, (struct prefix
*)p
);
1540 struct list
*list
= rp
->info
;
1542 if (list
!= NULL
&& listcount(list
) != 0) {
1543 rinfo
= listgetdata(listhead(list
));
1544 if (rinfo
!= NULL
&& rinfo
->type
== type
1545 && rinfo
->sub_type
== sub_type
1546 && rinfo
->nh
.ifindex
== ifindex
) {
1547 /* Perform poisoned reverse. */
1548 rinfo
->metric
= RIP_METRIC_INFINITY
;
1549 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
1550 rip_garbage_collect
,
1552 RIP_TIMER_OFF(rinfo
->t_timeout
);
1553 rinfo
->flags
|= RIP_RTF_CHANGED
;
1555 if (IS_RIP_DEBUG_EVENT
)
1557 "Poison %s/%d on the interface %s with an "
1558 "infinity metric [delete]",
1559 inet_ntoa(p
->prefix
),
1561 ifindex2ifname(ifindex
,
1564 rip_event(RIP_TRIGGERED_UPDATE
, 0);
1567 route_unlock_node(rp
);
1571 /* Response to request called from rip_read ().*/
1572 static void rip_request_process(struct rip_packet
*packet
, int size
,
1573 struct sockaddr_in
*from
, struct connected
*ifc
)
1577 struct prefix_ipv4 p
;
1578 struct route_node
*rp
;
1579 struct rip_info
*rinfo
;
1580 struct rip_interface
*ri
;
1582 /* Does not reponse to the requests on the loopback interfaces */
1583 if (if_is_loopback(ifc
->ifp
))
1586 /* Check RIP process is enabled on this interface. */
1587 ri
= ifc
->ifp
->info
;
1591 /* When passive interface is specified, suppress responses */
1595 /* RIP peer update. */
1596 rip_peer_update(from
, packet
->version
);
1598 lim
= ((caddr_t
)packet
) + size
;
1601 /* The Request is processed entry by entry. If there are no
1602 entries, no response is given. */
1603 if (lim
== (caddr_t
)rte
)
1606 /* There is one special case. If there is exactly one entry in the
1607 request, and it has an address family identifier of zero and a
1608 metric of infinity (i.e., 16), then this is a request to send the
1609 entire routing table. */
1610 if (lim
== ((caddr_t
)(rte
+ 1)) && ntohs(rte
->family
) == 0
1611 && ntohl(rte
->metric
) == RIP_METRIC_INFINITY
) {
1612 /* All route with split horizon */
1613 rip_output_process(ifc
, from
, rip_all_route
, packet
->version
);
1615 if (ntohs(rte
->family
) != AF_INET
)
1618 /* Examine the list of RTEs in the Request one by one. For each
1619 entry, look up the destination in the router's routing
1620 database and, if there is a route, put that route's metric in
1621 the metric field of the RTE. If there is no explicit route
1622 to the specified destination, put infinity in the metric
1623 field. Once all the entries have been filled in, change the
1624 command from Request to Response and send the datagram back
1625 to the requestor. */
1628 for (; ((caddr_t
)rte
) < lim
; rte
++) {
1629 p
.prefix
= rte
->prefix
;
1630 p
.prefixlen
= ip_masklen(rte
->mask
);
1631 apply_mask_ipv4(&p
);
1633 rp
= route_node_lookup(rip
->table
, (struct prefix
*)&p
);
1635 rinfo
= listgetdata(
1636 listhead((struct list
*)rp
->info
));
1637 rte
->metric
= htonl(rinfo
->metric
);
1638 route_unlock_node(rp
);
1640 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
1642 packet
->command
= RIP_RESPONSE
;
1644 rip_send_packet((u_char
*)packet
, size
, from
, ifc
);
1646 rip_global_queries
++;
1650 /* Set IPv6 packet info to the socket. */
1651 static int setsockopt_pktinfo(int sock
)
1656 ret
= setsockopt(sock
, IPPROTO_IP
, IP_PKTINFO
, &val
, sizeof(val
));
1658 zlog_warn("Can't setsockopt IP_PKTINFO : %s",
1659 safe_strerror(errno
));
1663 /* Read RIP packet by recvmsg function. */
1664 int rip_recvmsg(int sock
, u_char
*buf
, int size
, struct sockaddr_in
*from
,
1670 struct cmsghdr
*ptr
;
1673 memset(&msg
, 0, sizeof(msg
));
1674 msg
.msg_name
= (void *)from
;
1675 msg
.msg_namelen
= sizeof(struct sockaddr_in
);
1678 msg
.msg_control
= (void *)adata
;
1679 msg
.msg_controllen
= sizeof adata
;
1683 ret
= recvmsg(sock
, &msg
, 0);
1687 for (ptr
= ZCMSG_FIRSTHDR(&msg
); ptr
!= NULL
;
1688 ptr
= CMSG_NXTHDR(&msg
, ptr
))
1689 if (ptr
->cmsg_level
== IPPROTO_IP
1690 && ptr
->cmsg_type
== IP_PKTINFO
) {
1691 struct in_pktinfo
*pktinfo
;
1694 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(ptr
);
1695 i
= pktinfo
->ipi_ifindex
;
1700 /* RIP packet read function. */
1701 int rip_read_new(struct thread
*t
)
1705 char buf
[RIP_PACKET_MAXSIZ
];
1706 struct sockaddr_in from
;
1709 /* Fetch socket then register myself. */
1710 sock
= THREAD_FD(t
);
1711 rip_event(RIP_READ
, sock
);
1713 /* Read RIP packet. */
1714 ret
= rip_recvmsg(sock
, buf
, RIP_PACKET_MAXSIZ
, &from
, (int *)&ifindex
);
1716 zlog_warn("Can't read RIP packet: %s", safe_strerror(errno
));
1722 #endif /* RIP_RECVMSG */
1724 /* First entry point of RIP packet. */
1725 static int rip_read(struct thread
*t
)
1730 union rip_buf rip_buf
;
1731 struct rip_packet
*packet
;
1732 struct sockaddr_in from
;
1736 struct interface
*ifp
= NULL
;
1737 struct connected
*ifc
;
1738 struct rip_interface
*ri
;
1741 /* Fetch socket then register myself. */
1742 sock
= THREAD_FD(t
);
1745 /* Add myself to tne next event */
1746 rip_event(RIP_READ
, sock
);
1748 /* RIPd manages only IPv4. */
1749 memset(&from
, 0, sizeof(struct sockaddr_in
));
1750 fromlen
= sizeof(struct sockaddr_in
);
1752 len
= recvfrom(sock
, (char *)&rip_buf
.buf
, sizeof(rip_buf
.buf
), 0,
1753 (struct sockaddr
*)&from
, &fromlen
);
1755 zlog_info("recvfrom failed: %s", safe_strerror(errno
));
1759 /* Check is this packet comming from myself? */
1760 if (if_check_address(from
.sin_addr
)) {
1761 if (IS_RIP_DEBUG_PACKET
)
1762 zlog_debug("ignore packet comes from myself");
1766 /* Which interface is this packet comes from. */
1767 ifc
= if_lookup_address((void *)&from
.sin_addr
, AF_INET
, VRF_DEFAULT
);
1771 /* RIP packet received */
1772 if (IS_RIP_DEBUG_EVENT
)
1773 zlog_debug("RECV packet from %s port %d on %s",
1774 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1775 ifp
? ifp
->name
: "unknown");
1777 /* If this packet come from unknown interface, ignore it. */
1780 "rip_read: cannot find interface for packet from %s port %d",
1781 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
));
1786 p
.u
.prefix4
= from
.sin_addr
;
1787 p
.prefixlen
= IPV4_MAX_BITLEN
;
1789 ifc
= connected_lookup_prefix(ifp
, &p
);
1793 "rip_read: cannot find connected address for packet from %s "
1794 "port %d on interface %s",
1795 inet_ntoa(from
.sin_addr
), ntohs(from
.sin_port
),
1800 /* Packet length check. */
1801 if (len
< RIP_PACKET_MINSIZ
) {
1802 zlog_warn("packet size %d is smaller than minimum size %d", len
,
1804 rip_peer_bad_packet(&from
);
1807 if (len
> RIP_PACKET_MAXSIZ
) {
1808 zlog_warn("packet size %d is larger than max size %d", len
,
1810 rip_peer_bad_packet(&from
);
1814 /* Packet alignment check. */
1815 if ((len
- RIP_PACKET_MINSIZ
) % 20) {
1816 zlog_warn("packet size %d is wrong for RIP packet alignment",
1818 rip_peer_bad_packet(&from
);
1822 /* Set RTE number. */
1823 rtenum
= ((len
- RIP_PACKET_MINSIZ
) / 20);
1825 /* For easy to handle. */
1826 packet
= &rip_buf
.rip_packet
;
1828 /* RIP version check. */
1829 if (packet
->version
== 0) {
1830 zlog_info("version 0 with command %d received.",
1832 rip_peer_bad_packet(&from
);
1836 /* Dump RIP packet. */
1837 if (IS_RIP_DEBUG_RECV
)
1838 rip_packet_dump(packet
, len
, "RECV");
1840 /* RIP version adjust. This code should rethink now. RFC1058 says
1841 that "Version 1 implementations are to ignore this extra data and
1842 process only the fields specified in this document.". So RIPv3
1843 packet should be treated as RIPv1 ignoring must be zero field. */
1844 if (packet
->version
> RIPv2
)
1845 packet
->version
= RIPv2
;
1847 /* Is RIP running or is this RIP neighbor ?*/
1849 if (!ri
->running
&& !rip_neighbor_lookup(&from
)) {
1850 if (IS_RIP_DEBUG_EVENT
)
1851 zlog_debug("RIP is not enabled on interface %s.",
1853 rip_peer_bad_packet(&from
);
1857 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1858 vrecv
= ((ri
->ri_receive
== RI_RIP_UNSPEC
) ? rip
->version_recv
1860 if (vrecv
== RI_RIP_VERSION_NONE
1861 || ((packet
->version
== RIPv1
) && !(vrecv
& RIPv1
))
1862 || ((packet
->version
== RIPv2
) && !(vrecv
& RIPv2
))) {
1863 if (IS_RIP_DEBUG_PACKET
)
1865 " packet's v%d doesn't fit to if version spec",
1867 rip_peer_bad_packet(&from
);
1871 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1872 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1873 accepted; authenticated RIP-2 messages shall be discarded. */
1874 if ((ri
->auth_type
== RIP_NO_AUTH
) && rtenum
1875 && (packet
->version
== RIPv2
)
1876 && (packet
->rte
->family
== htons(RIP_FAMILY_AUTH
))) {
1877 if (IS_RIP_DEBUG_EVENT
)
1879 "packet RIPv%d is dropped because authentication disabled",
1881 rip_peer_bad_packet(&from
);
1886 If the router is configured to authenticate RIP-2 messages, then
1887 RIP-1 messages and RIP-2 messages which pass authentication
1888 testing shall be accepted; unauthenticated and failed
1889 authentication RIP-2 messages shall be discarded. For maximum
1890 security, RIP-1 messages should be ignored when authentication is
1891 in use (see section 4.1); otherwise, the routing information from
1892 authenticated messages will be propagated by RIP-1 routers in an
1893 unauthenticated manner.
1895 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1896 * always reply regardless of authentication settings, because:
1898 * - if there other authorised routers on-link, the REQUESTor can
1899 * passively obtain the routing updates anyway
1900 * - if there are no other authorised routers on-link, RIP can
1901 * easily be disabled for the link to prevent giving out information
1902 * on state of this routers RIP routing table..
1904 * I.e. if RIPv1 has any place anymore these days, it's as a very
1905 * simple way to distribute routing information (e.g. to embedded
1906 * hosts / appliances) and the ability to give out RIPv1
1907 * routing-information freely, while still requiring RIPv2
1908 * authentication for any RESPONSEs might be vaguely useful.
1910 if (ri
->auth_type
!= RIP_NO_AUTH
&& packet
->version
== RIPv1
) {
1911 /* Discard RIPv1 messages other than REQUESTs */
1912 if (packet
->command
!= RIP_REQUEST
) {
1913 if (IS_RIP_DEBUG_PACKET
)
1916 " dropped because authentication enabled");
1917 rip_peer_bad_packet(&from
);
1920 } else if (ri
->auth_type
!= RIP_NO_AUTH
) {
1921 const char *auth_desc
;
1924 /* There definitely is no authentication in the packet.
1926 if (IS_RIP_DEBUG_PACKET
)
1928 "RIPv2 authentication failed: no auth RTE in packet");
1929 rip_peer_bad_packet(&from
);
1933 /* First RTE must be an Authentication Family RTE */
1934 if (packet
->rte
->family
!= htons(RIP_FAMILY_AUTH
)) {
1935 if (IS_RIP_DEBUG_PACKET
)
1938 " dropped because authentication enabled");
1939 rip_peer_bad_packet(&from
);
1943 /* Check RIPv2 authentication. */
1944 switch (ntohs(packet
->rte
->tag
)) {
1945 case RIP_AUTH_SIMPLE_PASSWORD
:
1946 auth_desc
= "simple";
1947 ret
= rip_auth_simple_password(packet
->rte
, &from
, ifp
);
1952 ret
= rip_auth_md5(packet
, &from
, len
, ifp
);
1953 /* Reset RIP packet length to trim MD5 data. */
1959 auth_desc
= "unknown type";
1960 if (IS_RIP_DEBUG_PACKET
)
1962 "RIPv2 Unknown authentication type %d",
1963 ntohs(packet
->rte
->tag
));
1967 if (IS_RIP_DEBUG_PACKET
)
1968 zlog_debug("RIPv2 %s authentication success",
1971 if (IS_RIP_DEBUG_PACKET
)
1972 zlog_debug("RIPv2 %s authentication failure",
1974 rip_peer_bad_packet(&from
);
1979 /* Process each command. */
1980 switch (packet
->command
) {
1982 rip_response_process(packet
, len
, &from
, ifc
);
1986 rip_request_process(packet
, len
, &from
, ifc
);
1991 "Obsolete command %s received, please sent it to routed",
1992 lookup_msg(rip_msg
, packet
->command
, NULL
));
1993 rip_peer_bad_packet(&from
);
1995 case RIP_POLL_ENTRY
:
1996 zlog_info("Obsolete command %s received",
1997 lookup_msg(rip_msg
, packet
->command
, NULL
));
1998 rip_peer_bad_packet(&from
);
2001 zlog_info("Unknown RIP command %d received", packet
->command
);
2002 rip_peer_bad_packet(&from
);
2009 /* Write routing table entry to the stream and return next index of
2010 the routing table entry in the stream. */
2011 static int rip_write_rte(int num
, struct stream
*s
, struct prefix_ipv4
*p
,
2012 u_char version
, struct rip_info
*rinfo
)
2014 struct in_addr mask
;
2016 /* Write routing table entry. */
2017 if (version
== RIPv1
) {
2018 stream_putw(s
, AF_INET
);
2020 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2021 stream_put_ipv4(s
, 0);
2022 stream_put_ipv4(s
, 0);
2023 stream_putl(s
, rinfo
->metric_out
);
2025 masklen2ip(p
->prefixlen
, &mask
);
2027 stream_putw(s
, AF_INET
);
2028 stream_putw(s
, rinfo
->tag_out
);
2029 stream_put_ipv4(s
, p
->prefix
.s_addr
);
2030 stream_put_ipv4(s
, mask
.s_addr
);
2031 stream_put_ipv4(s
, rinfo
->nexthop_out
.s_addr
);
2032 stream_putl(s
, rinfo
->metric_out
);
2038 /* Send update to the ifp or spcified neighbor. */
2039 void rip_output_process(struct connected
*ifc
, struct sockaddr_in
*to
,
2040 int route_type
, u_char version
)
2044 struct route_node
*rp
;
2045 struct rip_info
*rinfo
;
2046 struct rip_interface
*ri
;
2047 struct prefix_ipv4
*p
;
2048 struct prefix_ipv4 classfull
;
2049 struct prefix_ipv4 ifaddrclass
;
2050 struct key
*key
= NULL
;
2051 /* this might need to made dynamic if RIP ever supported auth methods
2052 with larger key string sizes */
2053 char auth_str
[RIP_AUTH_SIMPLE_SIZE
];
2054 size_t doff
= 0; /* offset of digest offset field */
2058 struct list
*list
= NULL
;
2059 struct listnode
*listnode
= NULL
;
2061 /* Logging output event. */
2062 if (IS_RIP_DEBUG_EVENT
) {
2064 zlog_debug("update routes to neighbor %s",
2065 inet_ntoa(to
->sin_addr
));
2067 zlog_debug("update routes on interface %s ifindex %d",
2068 ifc
->ifp
->name
, ifc
->ifp
->ifindex
);
2071 /* Set output stream. */
2074 /* Reset stream and RTE counter. */
2076 rtemax
= RIP_MAX_RTE
;
2078 /* Get RIP interface. */
2079 ri
= ifc
->ifp
->info
;
2081 /* If output interface is in simple password authentication mode, we
2082 need space for authentication data. */
2083 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2086 /* If output interface is in MD5 authentication mode, we need space
2087 for authentication header and data. */
2088 if (ri
->auth_type
== RIP_AUTH_MD5
)
2091 /* If output interface is in simple password authentication mode
2092 and string or keychain is specified we need space for auth. data */
2093 if (ri
->auth_type
!= RIP_NO_AUTH
) {
2094 if (ri
->key_chain
) {
2095 struct keychain
*keychain
;
2097 keychain
= keychain_lookup(ri
->key_chain
);
2099 key
= key_lookup_for_send(keychain
);
2101 /* to be passed to auth functions later */
2102 rip_auth_prepare_str_send(ri
, key
, auth_str
,
2103 RIP_AUTH_SIMPLE_SIZE
);
2106 if (version
== RIPv1
) {
2107 memcpy(&ifaddrclass
, ifc
->address
, sizeof(struct prefix_ipv4
));
2108 apply_classful_mask_ipv4(&ifaddrclass
);
2110 if (ifc
->address
->prefixlen
> ifaddrclass
.prefixlen
)
2114 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2115 if ((list
= rp
->info
) != NULL
&& listcount(list
) != 0) {
2116 rinfo
= listgetdata(listhead(list
));
2117 /* For RIPv1, if we are subnetted, output subnets in our
2119 /* that have the same mask as the output "interface".
2121 /* networks, only the classfull version is output. */
2123 if (version
== RIPv1
) {
2124 p
= (struct prefix_ipv4
*)&rp
->p
;
2126 if (IS_RIP_DEBUG_PACKET
)
2128 "RIPv1 mask check, %s/%d considered for output",
2129 inet_ntoa(rp
->p
.u
.prefix4
),
2134 (struct prefix
*)&ifaddrclass
,
2136 if ((ifc
->address
->prefixlen
2138 && (rp
->p
.prefixlen
!= 32))
2141 memcpy(&classfull
, &rp
->p
,
2142 sizeof(struct prefix_ipv4
));
2143 apply_classful_mask_ipv4(&classfull
);
2144 if (rp
->p
.u
.prefix4
.s_addr
!= 0
2145 && classfull
.prefixlen
2149 if (IS_RIP_DEBUG_PACKET
)
2151 "RIPv1 mask check, %s/%d made it through",
2152 inet_ntoa(rp
->p
.u
.prefix4
),
2155 p
= (struct prefix_ipv4
*)&rp
->p
;
2157 /* Apply output filters. */
2158 ret
= rip_filter(RIP_FILTER_OUT
, p
, ri
);
2162 /* Changed route only output. */
2163 if (route_type
== rip_changed_route
2164 && (!(rinfo
->flags
& RIP_RTF_CHANGED
)))
2167 /* Split horizon. */
2168 /* if (split_horizon == rip_split_horizon) */
2169 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
) {
2171 * We perform split horizon for RIP and
2173 * For rip routes, we want to suppress the route
2175 * end up sending the route back on the
2177 * learned it from, with a higher metric. For
2179 * we suppress the route if the prefix is a
2181 * source address that we are going to use for
2183 * (in order to handle the case when multiple
2185 * configured on the same interface).
2188 struct rip_info
*tmp_rinfo
= NULL
;
2189 struct connected
*tmp_ifc
= NULL
;
2191 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2193 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2194 && tmp_rinfo
->nh
.ifindex
2195 == ifc
->ifp
->ifindex
) {
2201 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2202 for (ALL_LIST_ELEMENTS_RO(
2203 ifc
->ifp
->connected
,
2207 tmp_ifc
->address
)) {
2217 /* Preparation for route-map. */
2218 rinfo
->metric_set
= 0;
2219 rinfo
->nexthop_out
.s_addr
= 0;
2220 rinfo
->metric_out
= rinfo
->metric
;
2221 rinfo
->tag_out
= rinfo
->tag
;
2222 rinfo
->ifindex_out
= ifc
->ifp
->ifindex
;
2224 /* In order to avoid some local loops,
2225 * if the RIP route has a nexthop via this interface,
2227 * otherwise set it to 0. The nexthop should not be
2229 * beyond the local broadcast/multicast area in order
2230 * to avoid an IGP multi-level recursive look-up.
2233 if (rinfo
->nh
.ifindex
== ifc
->ifp
->ifindex
)
2234 rinfo
->nexthop_out
= rinfo
->nh
.gate
.ipv4
;
2236 /* Interface route-map */
2237 if (ri
->routemap
[RIP_FILTER_OUT
]) {
2238 ret
= route_map_apply(
2239 ri
->routemap
[RIP_FILTER_OUT
],
2240 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2242 if (ret
== RMAP_DENYMATCH
) {
2243 if (IS_RIP_DEBUG_PACKET
)
2245 "RIP %s/%d is filtered by route-map out",
2246 inet_ntoa(p
->prefix
),
2252 /* Apply redistribute route map - continue, if deny */
2253 if (rip
->route_map
[rinfo
->type
].name
2254 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2255 ret
= route_map_apply(
2256 rip
->route_map
[rinfo
->type
].map
,
2257 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2259 if (ret
== RMAP_DENYMATCH
) {
2260 if (IS_RIP_DEBUG_PACKET
)
2262 "%s/%d is filtered by route-map",
2263 inet_ntoa(p
->prefix
),
2269 /* When route-map does not set metric. */
2270 if (!rinfo
->metric_set
) {
2271 /* If redistribute metric is set. */
2272 if (rip
->route_map
[rinfo
->type
].metric_config
2273 && rinfo
->metric
!= RIP_METRIC_INFINITY
) {
2275 rip
->route_map
[rinfo
->type
]
2278 /* If the route is not connected or
2280 one, use default-metric value*/
2281 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2283 != ZEBRA_ROUTE_CONNECT
2285 != RIP_METRIC_INFINITY
)
2287 rip
->default_metric
;
2291 /* Apply offset-list */
2292 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2293 rip_offset_list_apply_out(p
, ifc
->ifp
,
2294 &rinfo
->metric_out
);
2296 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2297 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2299 /* Perform split-horizon with poisoned reverse
2300 * for RIP and connected routes.
2302 if (ri
->split_horizon
2303 == RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2305 * We perform split horizon for RIP and
2307 * For rip routes, we want to suppress the route
2309 * end up sending the route back on the
2311 * learned it from, with a higher metric. For
2313 * we suppress the route if the prefix is a
2315 * source address that we are going to use for
2317 * (in order to handle the case when multiple
2319 * configured on the same interface).
2321 struct rip_info
*tmp_rinfo
= NULL
;
2322 struct connected
*tmp_ifc
= NULL
;
2324 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
2326 if (tmp_rinfo
->type
== ZEBRA_ROUTE_RIP
2327 && tmp_rinfo
->nh
.ifindex
2328 == ifc
->ifp
->ifindex
)
2330 RIP_METRIC_INFINITY
;
2332 if (rinfo
->metric_out
!= RIP_METRIC_INFINITY
2333 && rinfo
->type
== ZEBRA_ROUTE_CONNECT
) {
2334 for (ALL_LIST_ELEMENTS_RO(
2335 ifc
->ifp
->connected
,
2339 tmp_ifc
->address
)) {
2341 RIP_METRIC_INFINITY
;
2347 /* Prepare preamble, auth headers, if needs be */
2349 stream_putc(s
, RIP_RESPONSE
);
2350 stream_putc(s
, version
);
2353 /* auth header for !v1 && !no_auth */
2354 if ((ri
->auth_type
!= RIP_NO_AUTH
)
2355 && (version
!= RIPv1
))
2356 doff
= rip_auth_header_write(
2357 s
, ri
, key
, auth_str
,
2358 RIP_AUTH_SIMPLE_SIZE
);
2361 /* Write RTE to the stream. */
2362 num
= rip_write_rte(num
, s
, p
, version
, rinfo
);
2363 if (num
== rtemax
) {
2364 if (version
== RIPv2
2365 && ri
->auth_type
== RIP_AUTH_MD5
)
2366 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2367 RIP_AUTH_SIMPLE_SIZE
);
2369 ret
= rip_send_packet(STREAM_DATA(s
),
2370 stream_get_endp(s
), to
,
2373 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2374 rip_packet_dump((struct rip_packet
*)
2383 /* Flush unwritten RTE. */
2385 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2386 rip_auth_md5_set(s
, ri
, doff
, auth_str
,
2387 RIP_AUTH_SIMPLE_SIZE
);
2389 ret
= rip_send_packet(STREAM_DATA(s
), stream_get_endp(s
), to
,
2392 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2393 rip_packet_dump((struct rip_packet
*)STREAM_DATA(s
),
2394 stream_get_endp(s
), "SEND");
2398 /* Statistics updates. */
2402 /* Send RIP packet to the interface. */
2403 static void rip_update_interface(struct connected
*ifc
, u_char version
,
2406 struct interface
*ifp
= ifc
->ifp
;
2407 struct rip_interface
*ri
= ifp
->info
;
2408 struct sockaddr_in to
;
2410 /* When RIP version is 2 and multicast enable interface. */
2411 if (version
== RIPv2
&& !ri
->v2_broadcast
&& if_is_multicast(ifp
)) {
2412 if (IS_RIP_DEBUG_EVENT
)
2413 zlog_debug("multicast announce on %s ", ifp
->name
);
2415 rip_output_process(ifc
, NULL
, route_type
, version
);
2419 /* If we can't send multicast packet, send it with unicast. */
2420 if (if_is_broadcast(ifp
) || if_is_pointopoint(ifp
)) {
2421 if (ifc
->address
->family
== AF_INET
) {
2422 /* Destination address and port setting. */
2423 memset(&to
, 0, sizeof(struct sockaddr_in
));
2424 if (ifc
->destination
)
2425 /* use specified broadcast or peer destination
2427 to
.sin_addr
= ifc
->destination
->u
.prefix4
;
2428 else if (ifc
->address
->prefixlen
< IPV4_MAX_PREFIXLEN
)
2429 /* calculate the appropriate broadcast address
2431 to
.sin_addr
.s_addr
= ipv4_broadcast_addr(
2432 ifc
->address
->u
.prefix4
.s_addr
,
2433 ifc
->address
->prefixlen
);
2435 /* do not know where to send the packet */
2437 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2439 if (IS_RIP_DEBUG_EVENT
)
2440 zlog_debug("%s announce to %s on %s",
2441 CONNECTED_PEER(ifc
) ? "unicast"
2443 inet_ntoa(to
.sin_addr
), ifp
->name
);
2445 rip_output_process(ifc
, &to
, route_type
, version
);
2450 /* Update send to all interface and neighbor. */
2451 static void rip_update_process(int route_type
)
2453 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
2454 struct listnode
*ifnode
, *ifnnode
;
2455 struct connected
*connected
;
2456 struct interface
*ifp
;
2457 struct rip_interface
*ri
;
2458 struct route_node
*rp
;
2459 struct sockaddr_in to
;
2462 /* Send RIP update to each interface. */
2463 FOR_ALL_INTERFACES (vrf
, ifp
) {
2464 if (if_is_loopback(ifp
))
2467 if (!if_is_operative(ifp
))
2470 /* Fetch RIP interface information. */
2473 /* When passive interface is specified, suppress announce to the
2480 * If there is no version configuration in the
2482 * use rip's version setting.
2484 int vsend
= ((ri
->ri_send
== RI_RIP_UNSPEC
)
2488 if (IS_RIP_DEBUG_EVENT
)
2489 zlog_debug("SEND UPDATE to %s ifindex %d",
2490 ifp
->name
, ifp
->ifindex
);
2492 /* send update on each connected network */
2493 for (ALL_LIST_ELEMENTS(ifp
->connected
, ifnode
, ifnnode
,
2495 if (connected
->address
->family
== AF_INET
) {
2497 rip_update_interface(
2501 && if_is_multicast(ifp
))
2502 rip_update_interface(
2510 /* RIP send updates to each neighbor. */
2511 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
2512 if (rp
->info
!= NULL
) {
2515 connected
= if_lookup_address(&p
->u
.prefix4
, AF_INET
,
2519 "Neighbor %s doesnt have connected interface!",
2520 inet_ntoa(p
->u
.prefix4
));
2524 /* Set destination address and port */
2525 memset(&to
, 0, sizeof(struct sockaddr_in
));
2526 to
.sin_addr
= p
->u
.prefix4
;
2527 to
.sin_port
= htons(RIP_PORT_DEFAULT
);
2529 /* RIP version is rip's configuration. */
2530 rip_output_process(connected
, &to
, route_type
,
2535 /* RIP's periodical timer. */
2536 static int rip_update(struct thread
*t
)
2538 /* Clear timer pointer. */
2539 rip
->t_update
= NULL
;
2541 if (IS_RIP_DEBUG_EVENT
)
2542 zlog_debug("update timer fire!");
2544 /* Process update output. */
2545 rip_update_process(rip_all_route
);
2547 /* Triggered updates may be suppressed if a regular update is due by
2548 the time the triggered update would be sent. */
2549 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2552 /* Register myself. */
2553 rip_event(RIP_UPDATE_EVENT
, 0);
2558 /* Walk down the RIP routing table then clear changed flag. */
2559 static void rip_clear_changed_flag(void)
2561 struct route_node
*rp
;
2562 struct rip_info
*rinfo
= NULL
;
2563 struct list
*list
= NULL
;
2564 struct listnode
*listnode
= NULL
;
2566 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2567 if ((list
= rp
->info
) != NULL
)
2568 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
2569 UNSET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
2570 /* This flag can be set only on the first entry.
2576 /* Triggered update interval timer. */
2577 static int rip_triggered_interval(struct thread
*t
)
2579 int rip_triggered_update(struct thread
*);
2581 rip
->t_triggered_interval
= NULL
;
2585 rip_triggered_update(t
);
2590 /* Execute triggered update. */
2591 static int rip_triggered_update(struct thread
*t
)
2595 /* Clear thred pointer. */
2596 rip
->t_triggered_update
= NULL
;
2598 /* Cancel interval timer. */
2599 RIP_TIMER_OFF(rip
->t_triggered_interval
);
2602 /* Logging triggered update. */
2603 if (IS_RIP_DEBUG_EVENT
)
2604 zlog_debug("triggered update!");
2606 /* Split Horizon processing is done when generating triggered
2607 updates as well as normal updates (see section 2.6). */
2608 rip_update_process(rip_changed_route
);
2610 /* Once all of the triggered updates have been generated, the route
2611 change flags should be cleared. */
2612 rip_clear_changed_flag();
2614 /* After a triggered update is sent, a timer should be set for a
2615 random interval between 1 and 5 seconds. If other changes that
2616 would trigger updates occur before the timer expires, a single
2617 update is triggered when the timer expires. */
2618 interval
= (random() % 5) + 1;
2620 rip
->t_triggered_interval
= NULL
;
2621 thread_add_timer(master
, rip_triggered_interval
, NULL
, interval
,
2622 &rip
->t_triggered_interval
);
2627 /* Withdraw redistributed route. */
2628 void rip_redistribute_withdraw(int type
)
2630 struct route_node
*rp
;
2631 struct rip_info
*rinfo
= NULL
;
2632 struct list
*list
= NULL
;
2637 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
2638 if ((list
= rp
->info
) != NULL
) {
2639 rinfo
= listgetdata(listhead(list
));
2640 if (rinfo
->type
== type
2641 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
) {
2642 /* Perform poisoned reverse. */
2643 rinfo
->metric
= RIP_METRIC_INFINITY
;
2644 RIP_TIMER_ON(rinfo
->t_garbage_collect
,
2645 rip_garbage_collect
,
2647 RIP_TIMER_OFF(rinfo
->t_timeout
);
2648 rinfo
->flags
|= RIP_RTF_CHANGED
;
2650 if (IS_RIP_DEBUG_EVENT
) {
2651 struct prefix_ipv4
*p
=
2652 (struct prefix_ipv4
*)&rp
->p
;
2655 "Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2656 inet_ntoa(p
->prefix
),
2663 rip_event(RIP_TRIGGERED_UPDATE
, 0);
2668 /* Create new RIP instance and set it to global variable. */
2669 static int rip_create(void)
2671 rip
= XCALLOC(MTYPE_RIP
, sizeof(struct rip
));
2673 /* Set initial value. */
2674 rip
->version_send
= RI_RIP_VERSION_2
;
2675 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2676 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
2677 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
2678 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
2679 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2681 /* Initialize RIP routig table. */
2682 rip
->table
= route_table_init();
2683 rip
->route
= route_table_init();
2684 rip
->neighbor
= route_table_init();
2686 /* Make output stream. */
2687 rip
->obuf
= stream_new(1500);
2690 rip
->sock
= rip_create_socket();
2694 /* Create read and timer thread. */
2695 rip_event(RIP_READ
, rip
->sock
);
2696 rip_event(RIP_UPDATE_EVENT
, 1);
2703 /* Sned RIP request to the destination. */
2704 int rip_request_send(struct sockaddr_in
*to
, struct interface
*ifp
,
2705 u_char version
, struct connected
*connected
)
2708 struct rip_packet rip_packet
;
2709 struct listnode
*node
, *nnode
;
2711 memset(&rip_packet
, 0, sizeof(rip_packet
));
2713 rip_packet
.command
= RIP_REQUEST
;
2714 rip_packet
.version
= version
;
2715 rte
= rip_packet
.rte
;
2716 rte
->metric
= htonl(RIP_METRIC_INFINITY
);
2720 * connected is only sent for ripv1 case, or when
2721 * interface does not support multicast. Caller loops
2722 * over each connected address for this case.
2724 if (rip_send_packet((u_char
*)&rip_packet
, sizeof(rip_packet
),
2726 != sizeof(rip_packet
))
2729 return sizeof(rip_packet
);
2732 /* send request on each connected network */
2733 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, connected
)) {
2734 struct prefix_ipv4
*p
;
2736 p
= (struct prefix_ipv4
*)connected
->address
;
2738 if (p
->family
!= AF_INET
)
2741 if (rip_send_packet((u_char
*)&rip_packet
, sizeof(rip_packet
),
2743 != sizeof(rip_packet
))
2746 return sizeof(rip_packet
);
2749 static int rip_update_jitter(unsigned long time
)
2751 #define JITTER_BOUND 4
2752 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2753 Given that, we cannot let time be less than JITTER_BOUND seconds.
2754 The RIPv2 RFC says jitter should be small compared to
2755 update_time. We consider 1/JITTER_BOUND to be small.
2758 int jitter_input
= time
;
2761 if (jitter_input
< JITTER_BOUND
)
2762 jitter_input
= JITTER_BOUND
;
2764 jitter
= (((random() % ((jitter_input
* 2) + 1)) - jitter_input
));
2766 return jitter
/ JITTER_BOUND
;
2769 void rip_event(enum rip_event event
, int sock
)
2776 thread_add_read(master
, rip_read
, NULL
, sock
, &rip
->t_read
);
2778 case RIP_UPDATE_EVENT
:
2779 RIP_TIMER_OFF(rip
->t_update
);
2780 jitter
= rip_update_jitter(rip
->update_time
);
2781 thread_add_timer(master
, rip_update
, NULL
,
2782 sock
? 2 : rip
->update_time
+ jitter
,
2785 case RIP_TRIGGERED_UPDATE
:
2786 if (rip
->t_triggered_interval
)
2789 thread_add_event(master
, rip_triggered_update
, NULL
, 0,
2790 &rip
->t_triggered_update
);
2797 DEFUN_NOSH (router_rip
,
2800 "Enable a routing process\n"
2801 "Routing Information Protocol (RIP)\n")
2805 /* If rip is not enabled before. */
2809 zlog_info("Can't create RIP");
2810 return CMD_WARNING_CONFIG_FAILED
;
2813 VTY_PUSH_CONTEXT(RIP_NODE
, rip
);
2818 DEFUN (no_router_rip
,
2822 "Enable a routing process\n"
2823 "Routing Information Protocol (RIP)\n")
2833 "Set routing protocol version\n"
2839 version
= atoi(argv
[idx_number
]->arg
);
2840 if (version
!= RIPv1
&& version
!= RIPv2
) {
2841 vty_out(vty
, "invalid rip version %d\n", version
);
2842 return CMD_WARNING_CONFIG_FAILED
;
2844 rip
->version_send
= version
;
2845 rip
->version_recv
= version
;
2850 DEFUN (no_rip_version
,
2852 "no version [(1-2)]",
2854 "Set routing protocol version\n"
2857 /* Set RIP version to the default. */
2858 rip
->version_send
= RI_RIP_VERSION_2
;
2859 rip
->version_recv
= RI_RIP_VERSION_1_AND_2
;
2868 "RIP static route configuration\n"
2869 "IP prefix <network>/<length>\n")
2871 int idx_ipv4_prefixlen
= 1;
2874 struct prefix_ipv4 p
;
2875 struct route_node
*node
;
2877 memset(&nh
, 0, sizeof(nh
));
2878 nh
.type
= NEXTHOP_TYPE_IPV4
;
2880 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
2882 vty_out(vty
, "Malformed address\n");
2883 return CMD_WARNING_CONFIG_FAILED
;
2885 apply_mask_ipv4(&p
);
2887 /* For router rip configuration. */
2888 node
= route_node_get(rip
->route
, (struct prefix
*)&p
);
2891 vty_out(vty
, "There is already same static route.\n");
2892 route_unlock_node(node
);
2896 node
->info
= (void *)1;
2898 rip_redistribute_add(ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, &nh
, 0, 0,
2904 DEFUN (no_rip_route
,
2906 "no route A.B.C.D/M",
2908 "RIP static route configuration\n"
2909 "IP prefix <network>/<length>\n")
2911 int idx_ipv4_prefixlen
= 2;
2913 struct prefix_ipv4 p
;
2914 struct route_node
*node
;
2916 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
2918 vty_out(vty
, "Malformed address\n");
2919 return CMD_WARNING_CONFIG_FAILED
;
2921 apply_mask_ipv4(&p
);
2923 /* For router rip configuration. */
2924 node
= route_node_lookup(rip
->route
, (struct prefix
*)&p
);
2926 vty_out(vty
, "Can't find route %s.\n",
2927 argv
[idx_ipv4_prefixlen
]->arg
);
2928 return CMD_WARNING_CONFIG_FAILED
;
2931 rip_redistribute_delete(ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0);
2932 route_unlock_node(node
);
2935 route_unlock_node(node
);
2942 rip_update_default_metric (void)
2944 struct route_node
*np
;
2945 struct rip_info
*rinfo
= NULL
;
2946 struct list
*list
= NULL
;
2947 struct listnode
*listnode
= NULL
;
2949 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
2950 if ((list
= np
->info
) != NULL
)
2951 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
2952 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
2953 rinfo
->metric
= rip
->default_metric
;
2957 DEFUN (rip_default_metric
,
2958 rip_default_metric_cmd
,
2959 "default-metric (1-16)",
2960 "Set a metric of redistribute routes\n"
2965 rip
->default_metric
= atoi(argv
[idx_number
]->arg
);
2966 /* rip_update_default_metric (); */
2971 DEFUN (no_rip_default_metric
,
2972 no_rip_default_metric_cmd
,
2973 "no default-metric [(1-16)]",
2975 "Set a metric of redistribute routes\n"
2979 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2980 /* rip_update_default_metric (); */
2988 "timers basic (5-2147483647) (5-2147483647) (5-2147483647)",
2989 "Adjust routing timers\n"
2990 "Basic routing protocol update timers\n"
2991 "Routing table update timer value in second. Default is 30.\n"
2992 "Routing information timeout timer. Default is 180.\n"
2993 "Garbage collection timer. Default is 120.\n")
2996 int idx_number_2
= 3;
2997 int idx_number_3
= 4;
2998 unsigned long update
;
2999 unsigned long timeout
;
3000 unsigned long garbage
;
3001 char *endptr
= NULL
;
3002 unsigned long RIP_TIMER_MAX
= 2147483647;
3003 unsigned long RIP_TIMER_MIN
= 5;
3005 update
= strtoul(argv
[idx_number
]->arg
, &endptr
, 10);
3006 if (update
> RIP_TIMER_MAX
|| update
< RIP_TIMER_MIN
3007 || *endptr
!= '\0') {
3008 vty_out(vty
, "update timer value error\n");
3009 return CMD_WARNING_CONFIG_FAILED
;
3012 timeout
= strtoul(argv
[idx_number_2
]->arg
, &endptr
, 10);
3013 if (timeout
> RIP_TIMER_MAX
|| timeout
< RIP_TIMER_MIN
3014 || *endptr
!= '\0') {
3015 vty_out(vty
, "timeout timer value error\n");
3016 return CMD_WARNING_CONFIG_FAILED
;
3019 garbage
= strtoul(argv
[idx_number_3
]->arg
, &endptr
, 10);
3020 if (garbage
> RIP_TIMER_MAX
|| garbage
< RIP_TIMER_MIN
3021 || *endptr
!= '\0') {
3022 vty_out(vty
, "garbage timer value error\n");
3023 return CMD_WARNING_CONFIG_FAILED
;
3026 /* Set each timer value. */
3027 rip
->update_time
= update
;
3028 rip
->timeout_time
= timeout
;
3029 rip
->garbage_time
= garbage
;
3031 /* Reset update timer thread. */
3032 rip_event(RIP_UPDATE_EVENT
, 0);
3037 DEFUN (no_rip_timers
,
3039 "no timers basic [(0-65535) (0-65535) (0-65535)]",
3041 "Adjust routing timers\n"
3042 "Basic routing protocol update timers\n"
3043 "Routing table update timer value in second. Default is 30.\n"
3044 "Routing information timeout timer. Default is 180.\n"
3045 "Garbage collection timer. Default is 120.\n")
3047 /* Set each timer value to the default. */
3048 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
3049 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
3050 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
3052 /* Reset update timer thread. */
3053 rip_event(RIP_UPDATE_EVENT
, 0);
3059 struct route_table
*rip_distance_table
;
3061 struct rip_distance
{
3062 /* Distance value for the IP source prefix. */
3065 /* Name of the access-list to be matched. */
3069 static struct rip_distance
*rip_distance_new(void)
3071 return XCALLOC(MTYPE_RIP_DISTANCE
, sizeof(struct rip_distance
));
3074 static void rip_distance_free(struct rip_distance
*rdistance
)
3076 XFREE(MTYPE_RIP_DISTANCE
, rdistance
);
3079 static int rip_distance_set(struct vty
*vty
, const char *distance_str
,
3080 const char *ip_str
, const char *access_list_str
)
3083 struct prefix_ipv4 p
;
3085 struct route_node
*rn
;
3086 struct rip_distance
*rdistance
;
3088 ret
= str2prefix_ipv4(ip_str
, &p
);
3090 vty_out(vty
, "Malformed prefix\n");
3091 return CMD_WARNING_CONFIG_FAILED
;
3094 distance
= atoi(distance_str
);
3096 /* Get RIP distance node. */
3097 rn
= route_node_get(rip_distance_table
, (struct prefix
*)&p
);
3099 rdistance
= rn
->info
;
3100 route_unlock_node(rn
);
3102 rdistance
= rip_distance_new();
3103 rn
->info
= rdistance
;
3106 /* Set distance value. */
3107 rdistance
->distance
= distance
;
3109 /* Reset access-list configuration. */
3110 if (rdistance
->access_list
) {
3111 free(rdistance
->access_list
);
3112 rdistance
->access_list
= NULL
;
3114 if (access_list_str
)
3115 rdistance
->access_list
= strdup(access_list_str
);
3120 static int rip_distance_unset(struct vty
*vty
, const char *distance_str
,
3121 const char *ip_str
, const char *access_list_str
)
3124 struct prefix_ipv4 p
;
3125 struct route_node
*rn
;
3126 struct rip_distance
*rdistance
;
3128 ret
= str2prefix_ipv4(ip_str
, &p
);
3130 vty_out(vty
, "Malformed prefix\n");
3131 return CMD_WARNING_CONFIG_FAILED
;
3134 rn
= route_node_lookup(rip_distance_table
, (struct prefix
*)&p
);
3136 vty_out(vty
, "Can't find specified prefix\n");
3137 return CMD_WARNING_CONFIG_FAILED
;
3140 rdistance
= rn
->info
;
3142 if (rdistance
->access_list
)
3143 free(rdistance
->access_list
);
3144 rip_distance_free(rdistance
);
3147 route_unlock_node(rn
);
3148 route_unlock_node(rn
);
3153 static void rip_distance_reset(void)
3155 struct route_node
*rn
;
3156 struct rip_distance
*rdistance
;
3158 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
3159 if ((rdistance
= rn
->info
) != NULL
) {
3160 if (rdistance
->access_list
)
3161 free(rdistance
->access_list
);
3162 rip_distance_free(rdistance
);
3164 route_unlock_node(rn
);
3168 /* Apply RIP information to distance method. */
3169 u_char
rip_distance_apply(struct rip_info
*rinfo
)
3171 struct route_node
*rn
;
3172 struct prefix_ipv4 p
;
3173 struct rip_distance
*rdistance
;
3174 struct access_list
*alist
;
3179 memset(&p
, 0, sizeof(struct prefix_ipv4
));
3181 p
.prefix
= rinfo
->from
;
3182 p
.prefixlen
= IPV4_MAX_BITLEN
;
3184 /* Check source address. */
3185 rn
= route_node_match(rip_distance_table
, (struct prefix
*)&p
);
3187 rdistance
= rn
->info
;
3188 route_unlock_node(rn
);
3190 if (rdistance
->access_list
) {
3191 alist
= access_list_lookup(AFI_IP
,
3192 rdistance
->access_list
);
3195 if (access_list_apply(alist
, &rinfo
->rp
->p
)
3199 return rdistance
->distance
;
3201 return rdistance
->distance
;
3205 return rip
->distance
;
3210 static void rip_distance_show(struct vty
*vty
)
3212 struct route_node
*rn
;
3213 struct rip_distance
*rdistance
;
3217 vty_out(vty
, " Distance: (default is %d)\n",
3218 rip
->distance
? rip
->distance
: ZEBRA_RIP_DISTANCE_DEFAULT
);
3220 for (rn
= route_top(rip_distance_table
); rn
; rn
= route_next(rn
))
3221 if ((rdistance
= rn
->info
) != NULL
) {
3224 " Address Distance List\n");
3227 sprintf(buf
, "%s/%d", inet_ntoa(rn
->p
.u
.prefix4
),
3229 vty_out(vty
, " %-20s %4d %s\n", buf
,
3230 rdistance
->distance
,
3231 rdistance
->access_list
? rdistance
->access_list
3236 DEFUN (rip_distance
,
3239 "Administrative distance\n"
3243 rip
->distance
= atoi(argv
[idx_number
]->arg
);
3247 DEFUN (no_rip_distance
,
3248 no_rip_distance_cmd
,
3249 "no distance (1-255)",
3251 "Administrative distance\n"
3258 DEFUN (rip_distance_source
,
3259 rip_distance_source_cmd
,
3260 "distance (1-255) A.B.C.D/M",
3261 "Administrative distance\n"
3263 "IP source prefix\n")
3266 int idx_ipv4_prefixlen
= 2;
3267 rip_distance_set(vty
, argv
[idx_number
]->arg
,
3268 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
3272 DEFUN (no_rip_distance_source
,
3273 no_rip_distance_source_cmd
,
3274 "no distance (1-255) A.B.C.D/M",
3276 "Administrative distance\n"
3278 "IP source prefix\n")
3281 int idx_ipv4_prefixlen
= 3;
3282 rip_distance_unset(vty
, argv
[idx_number
]->arg
,
3283 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
3287 DEFUN (rip_distance_source_access_list
,
3288 rip_distance_source_access_list_cmd
,
3289 "distance (1-255) A.B.C.D/M WORD",
3290 "Administrative distance\n"
3292 "IP source prefix\n"
3293 "Access list name\n")
3296 int idx_ipv4_prefixlen
= 2;
3298 rip_distance_set(vty
, argv
[idx_number
]->arg
,
3299 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
3303 DEFUN (no_rip_distance_source_access_list
,
3304 no_rip_distance_source_access_list_cmd
,
3305 "no distance (1-255) A.B.C.D/M WORD",
3307 "Administrative distance\n"
3309 "IP source prefix\n"
3310 "Access list name\n")
3313 int idx_ipv4_prefixlen
= 3;
3315 rip_distance_unset(vty
, argv
[idx_number
]->arg
,
3316 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
3320 /* Update ECMP routes to zebra when ECMP is disabled. */
3321 static void rip_ecmp_disable(void)
3323 struct route_node
*rp
;
3324 struct rip_info
*rinfo
, *tmp_rinfo
;
3326 struct listnode
*node
, *nextnode
;
3331 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3332 if ((list
= rp
->info
) != NULL
&& listcount(list
) > 1) {
3333 rinfo
= listgetdata(listhead(list
));
3334 if (!rip_route_rte(rinfo
))
3337 /* Drop all other entries, except the first one. */
3338 for (ALL_LIST_ELEMENTS(list
, node
, nextnode
, tmp_rinfo
))
3339 if (tmp_rinfo
!= rinfo
) {
3340 RIP_TIMER_OFF(tmp_rinfo
->t_timeout
);
3342 tmp_rinfo
->t_garbage_collect
);
3343 list_delete_node(list
, node
);
3344 rip_info_free(tmp_rinfo
);
3348 rip_zebra_ipv4_add(rp
);
3350 /* Set the route change flag. */
3351 SET_FLAG(rinfo
->flags
, RIP_RTF_CHANGED
);
3353 /* Signal the output process to trigger an update. */
3354 rip_event(RIP_TRIGGERED_UPDATE
, 0);
3358 DEFUN (rip_allow_ecmp
,
3361 "Allow Equal Cost MultiPath\n")
3364 vty_out(vty
, "ECMP is already enabled.\n");
3369 zlog_info("ECMP is enabled.");
3373 DEFUN (no_rip_allow_ecmp
,
3374 no_rip_allow_ecmp_cmd
,
3377 "Allow Equal Cost MultiPath\n")
3380 vty_out(vty
, "ECMP is already disabled.\n");
3385 zlog_info("ECMP is disabled.");
3390 /* Print out routes update time. */
3391 static void rip_vty_out_uptime(struct vty
*vty
, struct rip_info
*rinfo
)
3396 char timebuf
[TIME_BUF
];
3397 struct thread
*thread
;
3399 if ((thread
= rinfo
->t_timeout
) != NULL
) {
3400 clock
= thread_timer_remain_second(thread
);
3401 tm
= gmtime(&clock
);
3402 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
3403 vty_out(vty
, "%5s", timebuf
);
3404 } else if ((thread
= rinfo
->t_garbage_collect
) != NULL
) {
3405 clock
= thread_timer_remain_second(thread
);
3406 tm
= gmtime(&clock
);
3407 strftime(timebuf
, TIME_BUF
, "%M:%S", tm
);
3408 vty_out(vty
, "%5s", timebuf
);
3412 static const char *rip_route_type_print(int sub_type
)
3417 case RIP_ROUTE_STATIC
:
3419 case RIP_ROUTE_DEFAULT
:
3421 case RIP_ROUTE_REDISTRIBUTE
:
3423 case RIP_ROUTE_INTERFACE
:
3435 "Show RIP routes\n")
3437 struct route_node
*np
;
3438 struct rip_info
*rinfo
= NULL
;
3439 struct list
*list
= NULL
;
3440 struct listnode
*listnode
= NULL
;
3446 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
3448 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
3449 " (i) - interface\n\n"
3450 " Network Next Hop Metric From Tag Time\n");
3452 for (np
= route_top(rip
->table
); np
; np
= route_next(np
))
3453 if ((list
= np
->info
) != NULL
)
3454 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
3458 vty
, "%c(%s) %s/%d",
3459 /* np->lock, For debugging. */
3460 zebra_route_char(rinfo
->type
),
3461 rip_route_type_print(rinfo
->sub_type
),
3462 inet_ntoa(np
->p
.u
.prefix4
),
3468 vty_out(vty
, "%*s", len
, " ");
3470 switch (rinfo
->nh
.type
) {
3471 case NEXTHOP_TYPE_IPV4
:
3472 case NEXTHOP_TYPE_IPV4_IFINDEX
:
3473 vty_out(vty
, "%-20s %2d ",
3474 inet_ntoa(rinfo
->nh
.gate
.ipv4
),
3477 case NEXTHOP_TYPE_IFINDEX
:
3482 case NEXTHOP_TYPE_BLACKHOLE
:
3487 case NEXTHOP_TYPE_IPV6
:
3488 case NEXTHOP_TYPE_IPV6_IFINDEX
:
3490 "V6 Address Hidden %2d ",
3495 /* Route which exist in kernel routing table. */
3496 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
)
3497 && (rinfo
->sub_type
== RIP_ROUTE_RTE
)) {
3498 vty_out(vty
, "%-15s ",
3499 inet_ntoa(rinfo
->from
));
3500 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3501 (route_tag_t
)rinfo
->tag
);
3502 rip_vty_out_uptime(vty
, rinfo
);
3503 } else if (rinfo
->metric
3504 == RIP_METRIC_INFINITY
) {
3505 vty_out(vty
, "self ");
3506 vty_out(vty
, "%3" ROUTE_TAG_PRI
" ",
3507 (route_tag_t
)rinfo
->tag
);
3508 rip_vty_out_uptime(vty
, rinfo
);
3510 if (rinfo
->external_metric
) {
3512 vty
, "self (%s:%d)",
3515 rinfo
->external_metric
);
3518 vty_out(vty
, "%*s", len
,
3523 vty_out(vty
, "%3" ROUTE_TAG_PRI
,
3524 (route_tag_t
)rinfo
->tag
);
3532 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3533 DEFUN (show_ip_rip_status
,
3534 show_ip_rip_status_cmd
,
3535 "show ip rip status",
3539 "IP routing protocol process parameters and statistics\n")
3541 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3542 struct interface
*ifp
;
3543 struct rip_interface
*ri
;
3544 extern const struct message ri_version_msg
[];
3545 const char *send_version
;
3546 const char *receive_version
;
3551 vty_out(vty
, "Routing Protocol is \"rip\"\n");
3552 vty_out(vty
, " Sending updates every %ld seconds with +/-50%%,",
3554 vty_out(vty
, " next due in %lu seconds\n",
3555 thread_timer_remain_second(rip
->t_update
));
3556 vty_out(vty
, " Timeout after %ld seconds,", rip
->timeout_time
);
3557 vty_out(vty
, " garbage collect after %ld seconds\n", rip
->garbage_time
);
3559 /* Filtering status show. */
3560 config_show_distribute(vty
);
3562 /* Default metric information. */
3563 vty_out(vty
, " Default redistribution metric is %d\n",
3564 rip
->default_metric
);
3566 /* Redistribute information. */
3567 vty_out(vty
, " Redistributing:");
3568 config_write_rip_redistribute(vty
, 0);
3571 vty_out(vty
, " Default version control: send version %s,",
3572 lookup_msg(ri_version_msg
, rip
->version_send
, NULL
));
3573 if (rip
->version_recv
== RI_RIP_VERSION_1_AND_2
)
3574 vty_out(vty
, " receive any version \n");
3576 vty_out(vty
, " receive version %s \n",
3577 lookup_msg(ri_version_msg
, rip
->version_recv
, NULL
));
3579 vty_out(vty
, " Interface Send Recv Key-chain\n");
3581 FOR_ALL_INTERFACES (vrf
, ifp
) {
3587 if (ri
->enable_network
|| ri
->enable_interface
) {
3588 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3590 lookup_msg(ri_version_msg
,
3591 rip
->version_send
, NULL
);
3593 send_version
= lookup_msg(ri_version_msg
,
3596 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3598 lookup_msg(ri_version_msg
,
3599 rip
->version_recv
, NULL
);
3601 receive_version
= lookup_msg(
3602 ri_version_msg
, ri
->ri_receive
, NULL
);
3604 vty_out(vty
, " %-17s%-3s %-3s %s\n", ifp
->name
,
3605 send_version
, receive_version
,
3606 ri
->key_chain
? ri
->key_chain
: "");
3610 vty_out(vty
, " Routing for Networks:\n");
3611 config_write_rip_network(vty
, 0);
3614 int found_passive
= 0;
3615 FOR_ALL_INTERFACES (vrf
, ifp
) {
3618 if ((ri
->enable_network
|| ri
->enable_interface
)
3620 if (!found_passive
) {
3622 " Passive Interface(s):\n");
3625 vty_out(vty
, " %s\n", ifp
->name
);
3630 vty_out(vty
, " Routing Information Sources:\n");
3632 " Gateway BadPackets BadRoutes Distance Last Update\n");
3633 rip_peer_display(vty
);
3635 rip_distance_show(vty
);
3640 /* RIP configuration write function. */
3641 static int config_write_rip(struct vty
*vty
)
3644 struct route_node
*rn
;
3645 struct rip_distance
*rdistance
;
3648 /* Router RIP statement. */
3649 vty_out(vty
, "router rip\n");
3652 /* RIP version statement. Default is RIP version 2. */
3653 if (rip
->version_send
!= RI_RIP_VERSION_2
3654 || rip
->version_recv
!= RI_RIP_VERSION_1_AND_2
)
3655 vty_out(vty
, " version %d\n", rip
->version_send
);
3657 /* RIP timer configuration. */
3658 if (rip
->update_time
!= RIP_UPDATE_TIMER_DEFAULT
3659 || rip
->timeout_time
!= RIP_TIMEOUT_TIMER_DEFAULT
3660 || rip
->garbage_time
!= RIP_GARBAGE_TIMER_DEFAULT
)
3661 vty_out(vty
, " timers basic %lu %lu %lu\n",
3662 rip
->update_time
, rip
->timeout_time
,
3665 /* Default information configuration. */
3666 if (rip
->default_information
) {
3667 if (rip
->default_information_route_map
)
3669 " default-information originate route-map %s\n",
3670 rip
->default_information_route_map
);
3673 " default-information originate\n");
3676 /* Redistribute configuration. */
3677 config_write_rip_redistribute(vty
, 1);
3679 /* RIP offset-list configuration. */
3680 config_write_rip_offset_list(vty
);
3682 /* RIP enabled network and interface configuration. */
3683 config_write_rip_network(vty
, 1);
3685 /* RIP default metric configuration */
3686 if (rip
->default_metric
!= RIP_DEFAULT_METRIC_DEFAULT
)
3687 vty_out(vty
, " default-metric %d\n",
3688 rip
->default_metric
);
3690 /* Distribute configuration. */
3691 write
+= config_write_distribute(vty
);
3693 /* Interface routemap configuration */
3694 write
+= config_write_if_rmap(vty
);
3696 /* Distance configuration. */
3698 vty_out(vty
, " distance %d\n", rip
->distance
);
3700 /* RIP source IP prefix distance configuration. */
3701 for (rn
= route_top(rip_distance_table
); rn
;
3702 rn
= route_next(rn
))
3703 if ((rdistance
= rn
->info
) != NULL
)
3704 vty_out(vty
, " distance %d %s/%d %s\n",
3705 rdistance
->distance
,
3706 inet_ntoa(rn
->p
.u
.prefix4
),
3708 rdistance
->access_list
3709 ? rdistance
->access_list
3712 /* ECMP configuration. */
3714 vty_out(vty
, " allow-ecmp\n");
3716 /* RIP static route configuration. */
3717 for (rn
= route_top(rip
->route
); rn
; rn
= route_next(rn
))
3719 vty_out(vty
, " route %s/%d\n",
3720 inet_ntoa(rn
->p
.u
.prefix4
),
3726 /* RIP node structure. */
3727 static struct cmd_node rip_node
= {RIP_NODE
, "%s(config-router)# ", 1};
3729 /* Distribute-list update functions. */
3730 static void rip_distribute_update(struct distribute
*dist
)
3732 struct interface
*ifp
;
3733 struct rip_interface
*ri
;
3734 struct access_list
*alist
;
3735 struct prefix_list
*plist
;
3740 ifp
= if_lookup_by_name(dist
->ifname
, VRF_DEFAULT
);
3746 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
3747 alist
= access_list_lookup(AFI_IP
,
3748 dist
->list
[DISTRIBUTE_V4_IN
]);
3750 ri
->list
[RIP_FILTER_IN
] = alist
;
3752 ri
->list
[RIP_FILTER_IN
] = NULL
;
3754 ri
->list
[RIP_FILTER_IN
] = NULL
;
3756 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
3757 alist
= access_list_lookup(AFI_IP
,
3758 dist
->list
[DISTRIBUTE_V4_OUT
]);
3760 ri
->list
[RIP_FILTER_OUT
] = alist
;
3762 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3764 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3766 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
3767 plist
= prefix_list_lookup(AFI_IP
,
3768 dist
->prefix
[DISTRIBUTE_V4_IN
]);
3770 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3772 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3774 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3776 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
3777 plist
= prefix_list_lookup(AFI_IP
,
3778 dist
->prefix
[DISTRIBUTE_V4_OUT
]);
3780 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3782 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3784 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3787 void rip_distribute_update_interface(struct interface
*ifp
)
3789 struct distribute
*dist
;
3791 dist
= distribute_lookup(ifp
->name
);
3793 rip_distribute_update(dist
);
3796 /* Update all interface's distribute list. */
3798 static void rip_distribute_update_all(struct prefix_list
*notused
)
3800 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3801 struct interface
*ifp
;
3803 FOR_ALL_INTERFACES (vrf
, ifp
)
3804 rip_distribute_update_interface(ifp
);
3807 static void rip_distribute_update_all_wrapper(struct access_list
*notused
)
3809 rip_distribute_update_all(NULL
);
3812 /* Delete all added rip route. */
3813 void rip_clean(void)
3816 struct route_node
*rp
;
3817 struct rip_info
*rinfo
= NULL
;
3818 struct list
*list
= NULL
;
3819 struct listnode
*listnode
= NULL
;
3824 /* Clear RIP routes */
3825 for (rp
= route_top(rip
->table
); rp
; rp
= route_next(rp
))
3826 if ((list
= rp
->info
) != NULL
) {
3827 rinfo
= listgetdata(listhead(list
));
3828 if (rip_route_rte(rinfo
))
3829 rip_zebra_ipv4_delete(rp
);
3831 for (ALL_LIST_ELEMENTS_RO(list
, listnode
,
3833 RIP_TIMER_OFF(rinfo
->t_timeout
);
3834 RIP_TIMER_OFF(rinfo
->t_garbage_collect
);
3835 rip_info_free(rinfo
);
3837 list_delete_and_null(&list
);
3839 route_unlock_node(rp
);
3842 /* Cancel RIP related timers. */
3843 RIP_TIMER_OFF(rip
->t_update
);
3844 RIP_TIMER_OFF(rip
->t_triggered_update
);
3845 RIP_TIMER_OFF(rip
->t_triggered_interval
);
3847 /* Cancel read thread. */
3848 THREAD_READ_OFF(rip
->t_read
);
3850 /* Close RIP socket. */
3851 if (rip
->sock
>= 0) {
3856 stream_free(rip
->obuf
);
3857 /* Static RIP route configuration. */
3858 for (rp
= route_top(rip
->route
); rp
; rp
= route_next(rp
))
3861 route_unlock_node(rp
);
3864 /* RIP neighbor configuration. */
3865 for (rp
= route_top(rip
->neighbor
); rp
; rp
= route_next(rp
))
3868 route_unlock_node(rp
);
3871 /* Redistribute related clear. */
3872 if (rip
->default_information_route_map
)
3873 free(rip
->default_information_route_map
);
3875 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3876 if (rip
->route_map
[i
].name
)
3877 free(rip
->route_map
[i
].name
);
3879 XFREE(MTYPE_ROUTE_TABLE
, rip
->table
);
3880 XFREE(MTYPE_ROUTE_TABLE
, rip
->route
);
3881 XFREE(MTYPE_ROUTE_TABLE
, rip
->neighbor
);
3883 XFREE(MTYPE_RIP
, rip
);
3887 rip_clean_network();
3888 rip_passive_nondefault_clean();
3890 rip_interfaces_clean();
3891 rip_distance_reset();
3892 rip_redistribute_clean();
3895 /* Reset all values to the default settings. */
3896 void rip_reset(void)
3898 /* Reset global counters. */
3899 rip_global_route_changes
= 0;
3900 rip_global_queries
= 0;
3902 /* Call ripd related reset functions. */
3904 rip_route_map_reset();
3906 /* Call library reset functions. */
3908 access_list_reset();
3909 prefix_list_reset();
3911 distribute_list_reset();
3913 rip_interfaces_reset();
3914 rip_distance_reset();
3916 rip_zclient_reset();
3919 static void rip_if_rmap_update(struct if_rmap
*if_rmap
)
3921 struct interface
*ifp
;
3922 struct rip_interface
*ri
;
3923 struct route_map
*rmap
;
3925 ifp
= if_lookup_by_name(if_rmap
->ifname
, VRF_DEFAULT
);
3931 if (if_rmap
->routemap
[IF_RMAP_IN
]) {
3932 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_IN
]);
3934 ri
->routemap
[IF_RMAP_IN
] = rmap
;
3936 ri
->routemap
[IF_RMAP_IN
] = NULL
;
3938 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
3940 if (if_rmap
->routemap
[IF_RMAP_OUT
]) {
3941 rmap
= route_map_lookup_by_name(if_rmap
->routemap
[IF_RMAP_OUT
]);
3943 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
3945 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
3947 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
3950 void rip_if_rmap_update_interface(struct interface
*ifp
)
3952 struct if_rmap
*if_rmap
;
3954 if_rmap
= if_rmap_lookup(ifp
->name
);
3956 rip_if_rmap_update(if_rmap
);
3959 static void rip_routemap_update_redistribute(void)
3964 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3965 if (rip
->route_map
[i
].name
)
3966 rip
->route_map
[i
].map
=
3967 route_map_lookup_by_name(
3968 rip
->route_map
[i
].name
);
3974 static void rip_routemap_update(const char *notused
)
3976 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
3977 struct interface
*ifp
;
3979 FOR_ALL_INTERFACES (vrf
, ifp
)
3980 rip_if_rmap_update_interface(ifp
);
3982 rip_routemap_update_redistribute();
3985 /* Allocate new rip structure and set default value. */
3988 /* Install top nodes. */
3989 install_node(&rip_node
, config_write_rip
);
3991 /* Install rip commands. */
3992 install_element(VIEW_NODE
, &show_ip_rip_cmd
);
3993 install_element(VIEW_NODE
, &show_ip_rip_status_cmd
);
3994 install_element(CONFIG_NODE
, &router_rip_cmd
);
3995 install_element(CONFIG_NODE
, &no_router_rip_cmd
);
3997 install_default(RIP_NODE
);
3998 install_element(RIP_NODE
, &rip_version_cmd
);
3999 install_element(RIP_NODE
, &no_rip_version_cmd
);
4000 install_element(RIP_NODE
, &rip_default_metric_cmd
);
4001 install_element(RIP_NODE
, &no_rip_default_metric_cmd
);
4002 install_element(RIP_NODE
, &rip_timers_cmd
);
4003 install_element(RIP_NODE
, &no_rip_timers_cmd
);
4004 install_element(RIP_NODE
, &rip_route_cmd
);
4005 install_element(RIP_NODE
, &no_rip_route_cmd
);
4006 install_element(RIP_NODE
, &rip_distance_cmd
);
4007 install_element(RIP_NODE
, &no_rip_distance_cmd
);
4008 install_element(RIP_NODE
, &rip_distance_source_cmd
);
4009 install_element(RIP_NODE
, &no_rip_distance_source_cmd
);
4010 install_element(RIP_NODE
, &rip_distance_source_access_list_cmd
);
4011 install_element(RIP_NODE
, &no_rip_distance_source_access_list_cmd
);
4012 install_element(RIP_NODE
, &rip_allow_ecmp_cmd
);
4013 install_element(RIP_NODE
, &no_rip_allow_ecmp_cmd
);
4015 /* Debug related init. */
4018 /* Access list install. */
4020 access_list_add_hook(rip_distribute_update_all_wrapper
);
4021 access_list_delete_hook(rip_distribute_update_all_wrapper
);
4023 /* Prefix list initialize.*/
4025 prefix_list_add_hook(rip_distribute_update_all
);
4026 prefix_list_delete_hook(rip_distribute_update_all
);
4028 /* Distribute list install. */
4029 distribute_list_init(RIP_NODE
);
4030 distribute_list_add_hook(rip_distribute_update
);
4031 distribute_list_delete_hook(rip_distribute_update
);
4034 rip_route_map_init();
4037 route_map_add_hook(rip_routemap_update
);
4038 route_map_delete_hook(rip_routemap_update
);
4040 if_rmap_init(RIP_NODE
);
4041 if_rmap_hook_add(rip_if_rmap_update
);
4042 if_rmap_hook_delete(rip_if_rmap_update
);
4044 /* Distance control. */
4045 rip_distance_table
= route_table_init();