1 /* RIP version 1 and 2.
2 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro <kunihiro@zebra.org>
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
33 #include "sockunion.h"
37 #include "distribute.h"
42 #include "ripd/ripd.h"
43 #include "ripd/rip_debug.h"
45 extern struct zebra_privs_t ripd_privs
;
48 struct rip
*rip
= NULL
;
50 /* RIP neighbor address table. */
51 struct route_table
*rip_neighbor_table
;
53 /* RIP route changes. */
54 long rip_global_route_changes
= 0;
57 long rip_global_queries
= 0;
60 void rip_event (enum rip_event
, int);
62 void rip_output_process (struct interface
*, struct prefix
*,
63 struct sockaddr_in
*, int, u_char
);
65 /* RIP output routes type. */
72 /* RIP command strings. */
73 struct message rip_msg
[] =
75 {RIP_REQUEST
, "REQUEST"},
76 {RIP_RESPONSE
, "RESPONSE"},
77 {RIP_TRACEON
, "TRACEON"},
78 {RIP_TRACEOFF
, "TRACEOFF"},
80 {RIP_POLL_ENTRY
, "POLL ENTRY"},
84 /* Each route type's strings and default preference. */
92 { ZEBRA_ROUTE_SYSTEM
, "X", "system"},
93 { ZEBRA_ROUTE_KERNEL
, "K", "kernel"},
94 { ZEBRA_ROUTE_CONNECT
, "C", "connected"},
95 { ZEBRA_ROUTE_STATIC
, "S", "static"},
96 { ZEBRA_ROUTE_RIP
, "R", "rip"},
97 { ZEBRA_ROUTE_RIPNG
, "R", "ripng"},
98 { ZEBRA_ROUTE_OSPF
, "O", "ospf"},
99 { ZEBRA_ROUTE_OSPF6
, "O", "ospf6"},
100 { ZEBRA_ROUTE_BGP
, "B", "bgp"}
103 /* Utility function to set boradcast option to the socket. */
105 sockopt_broadcast (int sock
)
110 ret
= setsockopt (sock
, SOL_SOCKET
, SO_BROADCAST
, (char *) &on
, sizeof on
);
113 zlog_warn ("can't set sockopt SO_BROADCAST to socket %d", sock
);
120 rip_route_rte (struct rip_info
*rinfo
)
122 return (rinfo
->type
== ZEBRA_ROUTE_RIP
&& rinfo
->sub_type
== RIP_ROUTE_RTE
);
128 struct rip_info
*new;
130 new = XMALLOC (MTYPE_RIP_INFO
, sizeof (struct rip_info
));
131 memset (new, 0, sizeof (struct rip_info
));
136 rip_info_free (struct rip_info
*rinfo
)
138 XFREE (MTYPE_RIP_INFO
, rinfo
);
141 /* RIP route garbage collect timer. */
143 rip_garbage_collect (struct thread
*t
)
145 struct rip_info
*rinfo
;
146 struct route_node
*rp
;
148 rinfo
= THREAD_ARG (t
);
149 rinfo
->t_garbage_collect
= NULL
;
151 /* Off timeout timer. */
152 RIP_TIMER_OFF (rinfo
->t_timeout
);
154 /* Get route_node pointer. */
157 /* Unlock route_node. */
159 route_unlock_node (rp
);
161 /* Free RIP routing information. */
162 rip_info_free (rinfo
);
167 /* Timeout RIP routes. */
169 rip_timeout (struct thread
*t
)
171 struct rip_info
*rinfo
;
172 struct route_node
*rn
;
174 rinfo
= THREAD_ARG (t
);
175 rinfo
->t_timeout
= NULL
;
179 /* - The garbage-collection timer is set for 120 seconds. */
180 RIP_TIMER_ON (rinfo
->t_garbage_collect
, rip_garbage_collect
,
183 rip_zebra_ipv4_delete ((struct prefix_ipv4
*)&rn
->p
, &rinfo
->nexthop
,
185 /* - The metric for the route is set to 16 (infinity). This causes
186 the route to be removed from service. */
187 rinfo
->metric
= RIP_METRIC_INFINITY
;
188 rinfo
->flags
&= ~RIP_RTF_FIB
;
190 /* - The route change flag is to indicate that this entry has been
192 rinfo
->flags
|= RIP_RTF_CHANGED
;
194 /* - The output process is signalled to trigger a response. */
195 rip_event (RIP_TRIGGERED_UPDATE
, 0);
201 rip_timeout_update (struct rip_info
*rinfo
)
203 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
205 RIP_TIMER_OFF (rinfo
->t_timeout
);
206 RIP_TIMER_ON (rinfo
->t_timeout
, rip_timeout
, rip
->timeout_time
);
211 rip_incoming_filter (struct prefix_ipv4
*p
, struct rip_interface
*ri
)
213 struct distribute
*dist
;
214 struct access_list
*alist
;
215 struct prefix_list
*plist
;
217 /* Input distribute-list filtering. */
218 if (ri
->list
[RIP_FILTER_IN
])
220 if (access_list_apply (ri
->list
[RIP_FILTER_IN
],
221 (struct prefix
*) p
) == FILTER_DENY
)
223 if (IS_RIP_DEBUG_PACKET
)
224 zlog_info ("%s/%d filtered by distribute in",
225 inet_ntoa (p
->prefix
), p
->prefixlen
);
229 if (ri
->prefix
[RIP_FILTER_IN
])
231 if (prefix_list_apply (ri
->prefix
[RIP_FILTER_IN
],
232 (struct prefix
*) p
) == PREFIX_DENY
)
234 if (IS_RIP_DEBUG_PACKET
)
235 zlog_info ("%s/%d filtered by prefix-list in",
236 inet_ntoa (p
->prefix
), p
->prefixlen
);
241 /* All interface filter check. */
242 dist
= distribute_lookup (NULL
);
245 if (dist
->list
[DISTRIBUTE_IN
])
247 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_IN
]);
251 if (access_list_apply (alist
,
252 (struct prefix
*) p
) == FILTER_DENY
)
254 if (IS_RIP_DEBUG_PACKET
)
255 zlog_info ("%s/%d filtered by distribute in",
256 inet_ntoa (p
->prefix
), p
->prefixlen
);
261 if (dist
->prefix
[DISTRIBUTE_IN
])
263 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_IN
]);
267 if (prefix_list_apply (plist
,
268 (struct prefix
*) p
) == PREFIX_DENY
)
270 if (IS_RIP_DEBUG_PACKET
)
271 zlog_info ("%s/%d filtered by prefix-list in",
272 inet_ntoa (p
->prefix
), p
->prefixlen
);
282 rip_outgoing_filter (struct prefix_ipv4
*p
, struct rip_interface
*ri
)
284 struct distribute
*dist
;
285 struct access_list
*alist
;
286 struct prefix_list
*plist
;
288 if (ri
->list
[RIP_FILTER_OUT
])
290 if (access_list_apply (ri
->list
[RIP_FILTER_OUT
],
291 (struct prefix
*) p
) == FILTER_DENY
)
293 if (IS_RIP_DEBUG_PACKET
)
294 zlog_info ("%s/%d is filtered by distribute out",
295 inet_ntoa (p
->prefix
), p
->prefixlen
);
299 if (ri
->prefix
[RIP_FILTER_OUT
])
301 if (prefix_list_apply (ri
->prefix
[RIP_FILTER_OUT
],
302 (struct prefix
*) p
) == PREFIX_DENY
)
304 if (IS_RIP_DEBUG_PACKET
)
305 zlog_info ("%s/%d is filtered by prefix-list out",
306 inet_ntoa (p
->prefix
), p
->prefixlen
);
311 /* All interface filter check. */
312 dist
= distribute_lookup (NULL
);
315 if (dist
->list
[DISTRIBUTE_OUT
])
317 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_OUT
]);
321 if (access_list_apply (alist
,
322 (struct prefix
*) p
) == FILTER_DENY
)
324 if (IS_RIP_DEBUG_PACKET
)
325 zlog_info ("%s/%d filtered by distribute out",
326 inet_ntoa (p
->prefix
), p
->prefixlen
);
331 if (dist
->prefix
[DISTRIBUTE_OUT
])
333 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_OUT
]);
337 if (prefix_list_apply (plist
,
338 (struct prefix
*) p
) == PREFIX_DENY
)
340 if (IS_RIP_DEBUG_PACKET
)
341 zlog_info ("%s/%d filtered by prefix-list out",
342 inet_ntoa (p
->prefix
), p
->prefixlen
);
351 /* Check nexthop address validity. */
353 rip_nexthop_check (struct in_addr
*addr
)
357 struct interface
*ifp
;
358 struct connected
*ifc
;
361 /* If nexthop address matches local configured address then it is
363 for (node
= listhead (iflist
); node
; nextnode (node
))
365 ifp
= getdata (node
);
367 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
369 ifc
= getdata (cnode
);
372 if (p
->family
== AF_INET
373 && IPV4_ADDR_SAME (&p
->u
.prefix4
, addr
))
380 /* RIP add route to routing table. */
382 rip_rte_process (struct rte
*rte
, struct sockaddr_in
*from
,
383 struct interface
*ifp
)
387 struct prefix_ipv4 p
;
388 struct route_node
*rp
;
389 struct rip_info
*rinfo
;
390 struct rip_interface
*ri
;
391 struct in_addr
*nexthop
;
395 /* Make prefix structure. */
396 memset (&p
, 0, sizeof (struct prefix_ipv4
));
398 p
.prefix
= rte
->prefix
;
399 p
.prefixlen
= ip_masklen (rte
->mask
);
401 /* Make sure mask is applied. */
402 apply_mask_ipv4 (&p
);
404 /* Apply input filters. */
407 ret
= rip_incoming_filter (&p
, ri
);
411 /* Modify entry according to the interface routemap. */
412 if (ri
->routemap
[RIP_FILTER_IN
])
415 struct rip_info newinfo
;
417 memset (&newinfo
, 0, sizeof (newinfo
));
418 newinfo
.type
= ZEBRA_ROUTE_RIP
;
419 newinfo
.sub_type
= RIP_ROUTE_RTE
;
420 newinfo
.nexthop
= rte
->nexthop
;
421 newinfo
.from
= from
->sin_addr
;
422 newinfo
.ifindex
= ifp
->ifindex
;
423 newinfo
.metric
= rte
->metric
;
424 newinfo
.metric_out
= rte
->metric
; /* XXX */
425 newinfo
.tag
= ntohs(rte
->tag
); /* XXX */
427 /* The object should be of the type of rip_info */
428 ret
= route_map_apply (ri
->routemap
[RIP_FILTER_IN
],
429 (struct prefix
*)&p
, RMAP_RIP
, &newinfo
);
431 if (ret
== RMAP_DENYMATCH
)
433 if (IS_RIP_DEBUG_PACKET
)
434 zlog_info ("RIP %s/%d is filtered by route-map in",
435 inet_ntoa (p
.prefix
), p
.prefixlen
);
439 /* Get back the object */
440 rte
->nexthop
= newinfo
.nexthop_out
;
441 rte
->tag
= htons(newinfo
.tag_out
); /* XXX */
442 rte
->metric
= newinfo
.metric_out
; /* XXX: the routemap uses the metric_out field */
445 /* Once the entry has been validated, update the metric by
446 adding the cost of the network on wich the message
447 arrived. If the result is greater than infinity, use infinity
448 (RFC2453 Sec. 3.9.2) */
449 /* Zebra ripd can handle offset-list in. */
450 ret
= rip_offset_list_apply_in (&p
, ifp
, &rte
->metric
);
452 /* If offset-list does not modify the metric use interface's
455 rte
->metric
+= ifp
->metric
;
457 if (rte
->metric
> RIP_METRIC_INFINITY
)
458 rte
->metric
= RIP_METRIC_INFINITY
;
460 /* Set nexthop pointer. */
461 if (rte
->nexthop
.s_addr
== 0)
462 nexthop
= &from
->sin_addr
;
464 nexthop
= &rte
->nexthop
;
466 /* Check if nexthop address is myself, then do nothing. */
467 if (rip_nexthop_check (nexthop
) < 0)
469 if (IS_RIP_DEBUG_PACKET
)
470 zlog_info ("Nexthop address %s is myself", inet_ntoa (*nexthop
));
474 /* Get index for the prefix. */
475 rp
= route_node_get (rip
->table
, (struct prefix
*) &p
);
477 /* Check to see whether there is already RIP route on the table. */
482 /* Redistributed route check. */
483 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
484 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
487 /* Local static route. */
488 if (rinfo
->type
== ZEBRA_ROUTE_RIP
489 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
) ||
490 (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
))
491 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
497 /* Now, check to see whether there is already an explicit route
498 for the destination prefix. If there is no such route, add
499 this route to the routing table, unless the metric is
500 infinity (there is no point in adding a route which
502 if (rte
->metric
!= RIP_METRIC_INFINITY
)
504 rinfo
= rip_info_new ();
506 /* - Setting the destination prefix and length to those in
510 /* - Setting the metric to the newly calculated metric (as
512 rinfo
->metric
= rte
->metric
;
513 rinfo
->tag
= ntohs (rte
->tag
);
515 /* - Set the next hop address to be the address of the router
516 from which the datagram came or the next hop address
517 specified by a next hop RTE. */
518 IPV4_ADDR_COPY (&rinfo
->nexthop
, nexthop
);
519 IPV4_ADDR_COPY (&rinfo
->from
, &from
->sin_addr
);
520 rinfo
->ifindex
= ifp
->ifindex
;
522 /* - Initialize the timeout for the route. If the
523 garbage-collection timer is running for this route, stop it
524 (see section 2.3 for a discussion of the timers). */
525 rip_timeout_update (rinfo
);
527 /* - Set the route change flag. */
528 rinfo
->flags
|= RIP_RTF_CHANGED
;
530 /* - Signal the output process to trigger an update (see section
532 rip_event (RIP_TRIGGERED_UPDATE
, 0);
534 /* Finally, route goes into the kernel. */
535 rinfo
->type
= ZEBRA_ROUTE_RIP
;
536 rinfo
->sub_type
= RIP_ROUTE_RTE
;
538 /* Set distance value. */
539 rinfo
->distance
= rip_distance_apply (rinfo
);
542 rip_zebra_ipv4_add (&p
, &rinfo
->nexthop
, rinfo
->metric
,
544 rinfo
->flags
|= RIP_RTF_FIB
;
549 /* Route is there but we are not sure the route is RIP or not. */
552 /* If there is an existing route, compare the next hop address
553 to the address of the router from which the datagram came.
554 If this datagram is from the same router as the existing
555 route, reinitialize the timeout. */
556 same
= (IPV4_ADDR_SAME (&rinfo
->from
, &from
->sin_addr
)
557 && (rinfo
->ifindex
== ifp
->ifindex
));
560 rip_timeout_update (rinfo
);
562 /* Next, compare the metrics. If the datagram is from the same
563 router as the existing route, and the new metric is different
564 than the old one; or, if the new metric is lower than the old
565 one, or if the tag has been changed; do the following actions: */
566 if ((same
&& rinfo
->metric
!= rte
->metric
) ||
567 (rte
->metric
< rinfo
->metric
) ||
568 (same
&& (rinfo
->metric
== rte
->metric
) && ntohs(rte
->tag
) != rinfo
->tag
))
570 /* - Adopt the route from the datagram. That is, put the
571 new metric in, and adjust the next hop address (if
573 oldmetric
= rinfo
->metric
;
574 rinfo
->metric
= rte
->metric
;
575 rinfo
->tag
= ntohs (rte
->tag
);
576 IPV4_ADDR_COPY (&rinfo
->from
, &from
->sin_addr
);
577 rinfo
->ifindex
= ifp
->ifindex
;
578 rinfo
->distance
= rip_distance_apply (rinfo
);
580 /* Should a new route to this network be established
581 while the garbage-collection timer is running, the
582 new route will replace the one that is about to be
583 deleted. In this case the garbage-collection timer
586 if (oldmetric
== RIP_METRIC_INFINITY
&&
587 rinfo
->metric
< RIP_METRIC_INFINITY
)
589 rinfo
->type
= ZEBRA_ROUTE_RIP
;
590 rinfo
->sub_type
= RIP_ROUTE_RTE
;
592 RIP_TIMER_OFF (rinfo
->t_garbage_collect
);
594 if (! IPV4_ADDR_SAME (&rinfo
->nexthop
, nexthop
))
595 IPV4_ADDR_COPY (&rinfo
->nexthop
, nexthop
);
597 rip_zebra_ipv4_add (&p
, nexthop
, rinfo
->metric
,
599 rinfo
->flags
|= RIP_RTF_FIB
;
602 /* Update nexthop and/or metric value. */
603 if (oldmetric
!= RIP_METRIC_INFINITY
)
605 rip_zebra_ipv4_delete (&p
, &rinfo
->nexthop
, oldmetric
);
606 rip_zebra_ipv4_add (&p
, nexthop
, rinfo
->metric
,
608 rinfo
->flags
|= RIP_RTF_FIB
;
610 if (! IPV4_ADDR_SAME (&rinfo
->nexthop
, nexthop
))
611 IPV4_ADDR_COPY (&rinfo
->nexthop
, nexthop
);
614 /* - Set the route change flag and signal the output process
615 to trigger an update. */
616 rinfo
->flags
|= RIP_RTF_CHANGED
;
617 rip_event (RIP_TRIGGERED_UPDATE
, 0);
619 /* - If the new metric is infinity, start the deletion
620 process (described above); */
621 if (rinfo
->metric
== RIP_METRIC_INFINITY
)
623 /* If the new metric is infinity, the deletion process
624 begins for the route, which is no longer used for
625 routing packets. Note that the deletion process is
626 started only when the metric is first set to
627 infinity. If the metric was already infinity, then a
628 new deletion process is not started. */
629 if (oldmetric
!= RIP_METRIC_INFINITY
)
631 /* - The garbage-collection timer is set for 120 seconds. */
632 RIP_TIMER_ON (rinfo
->t_garbage_collect
,
633 rip_garbage_collect
, rip
->garbage_time
);
634 RIP_TIMER_OFF (rinfo
->t_timeout
);
636 /* - The metric for the route is set to 16
637 (infinity). This causes the route to be removed
639 rip_zebra_ipv4_delete (&p
, &rinfo
->nexthop
, oldmetric
);
640 rinfo
->flags
&= ~RIP_RTF_FIB
;
642 /* - The route change flag is to indicate that this
643 entry has been changed. */
644 /* - The output process is signalled to trigger a
646 ; /* Above processes are already done previously. */
651 /* otherwise, re-initialize the timeout. */
652 rip_timeout_update (rinfo
);
655 /* Unlock tempolary lock of the route. */
656 route_unlock_node (rp
);
660 /* Dump RIP packet */
662 rip_packet_dump (struct rip_packet
*packet
, int size
, char *sndrcv
)
667 char pbuf
[BUFSIZ
], nbuf
[BUFSIZ
];
671 /* Set command string. */
672 if (packet
->command
> 0 && packet
->command
< RIP_COMMAND_MAX
)
673 command_str
= lookup (rip_msg
, packet
->command
);
675 command_str
= "unknown";
677 /* Dump packet header. */
678 zlog_info ("%s %s version %d packet size %d",
679 sndrcv
, command_str
, packet
->version
, size
);
681 /* Dump each routing table entry. */
684 for (lim
= (caddr_t
) packet
+ size
; (caddr_t
) rte
< lim
; rte
++)
686 if (packet
->version
== RIPv2
)
688 netmask
= ip_masklen (rte
->mask
);
690 if (ntohs (rte
->family
) == 0xffff)
692 if (ntohs (rte
->tag
) == RIP_AUTH_SIMPLE_PASSWORD
)
694 p
= (u_char
*)&rte
->prefix
;
696 zlog_info (" family 0x%X type %d auth string: %s",
697 ntohs (rte
->family
), ntohs (rte
->tag
), p
);
699 else if (ntohs (rte
->tag
) == RIP_AUTH_MD5
)
701 struct rip_md5_info
*md5
;
703 md5
= (struct rip_md5_info
*) &packet
->rte
;
705 zlog_info (" family 0x%X type %d (MD5 authentication)",
706 ntohs (md5
->family
), ntohs (md5
->type
));
707 zlog_info (" RIP-2 packet len %d Key ID %d"
708 " Auth Data len %d", ntohs (md5
->packet_len
),
709 md5
->keyid
, md5
->auth_len
);
710 zlog_info (" Sequence Number %ld", (u_long
)ntohl (md5
->sequence
));
712 else if (ntohs (rte
->tag
) == RIP_AUTH_DATA
)
714 p
= (u_char
*)&rte
->prefix
;
716 zlog_info (" family 0x%X type %d (MD5 data)",
717 ntohs (rte
->family
), ntohs (rte
->tag
));
718 zlog_info (" MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
719 "%02X%02X%02X%02X%02X%02X%02X",
720 p
[0],p
[1],p
[2],p
[3],p
[4],p
[5],p
[6],p
[7],
721 p
[9],p
[10],p
[11],p
[12],p
[13],p
[14],p
[15]);
725 zlog_info (" family 0x%X type %d (Unknown auth type)",
726 ntohs (rte
->family
), ntohs (rte
->tag
));
730 zlog_info (" %s/%d -> %s family %d tag %d metric %ld",
731 inet_ntop (AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),netmask
,
732 inet_ntop (AF_INET
, &rte
->nexthop
, nbuf
, BUFSIZ
),
733 ntohs (rte
->family
), ntohs (rte
->tag
),
734 (u_long
)ntohl (rte
->metric
));
738 zlog_info (" %s family %d tag %d metric %ld",
739 inet_ntop (AF_INET
, &rte
->prefix
, pbuf
, BUFSIZ
),
740 ntohs (rte
->family
), ntohs (rte
->tag
),
741 (u_long
)ntohl (rte
->metric
));
746 /* Check if the destination address is valid (unicast; not net 0
747 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
748 check net 0 because we accept default route. */
750 rip_destination_check (struct in_addr addr
)
752 u_int32_t destination
;
754 /* Convert to host byte order. */
755 destination
= ntohl (addr
.s_addr
);
757 if (IPV4_NET127 (destination
))
760 /* Net 0 may match to the default route. */
761 if (IPV4_NET0 (destination
) && destination
!= 0)
764 /* Unicast address must belong to class A, B, C. */
765 if (IN_CLASSA (destination
))
767 if (IN_CLASSB (destination
))
769 if (IN_CLASSC (destination
))
775 /* RIP version 2 authentication. */
777 rip_auth_simple_password (struct rte
*rte
, struct sockaddr_in
*from
,
778 struct interface
*ifp
)
780 struct rip_interface
*ri
;
783 if (IS_RIP_DEBUG_EVENT
)
784 zlog_info ("RIPv2 simple password authentication from %s",
785 inet_ntoa (from
->sin_addr
));
789 if (ri
->auth_type
!= RIP_AUTH_SIMPLE_PASSWORD
790 || ntohs (rte
->tag
) != RIP_AUTH_SIMPLE_PASSWORD
)
793 /* Simple password authentication. */
796 auth_str
= (char *) &rte
->prefix
;
798 if (strncmp (auth_str
, ri
->auth_str
, 16) == 0)
803 struct keychain
*keychain
;
806 keychain
= keychain_lookup (ri
->key_chain
);
807 if (keychain
== NULL
)
810 key
= key_match_for_accept (keychain
, (char *) &rte
->prefix
);
817 /* RIP version 2 authentication with MD5. */
819 rip_auth_md5 (struct rip_packet
*packet
, struct sockaddr_in
*from
,
820 struct interface
*ifp
)
822 struct rip_interface
*ri
;
823 struct rip_md5_info
*md5
;
824 struct rip_md5_data
*md5data
;
825 struct keychain
*keychain
;
828 u_char pdigest
[RIP_AUTH_MD5_SIZE
];
829 u_char digest
[RIP_AUTH_MD5_SIZE
];
830 u_int16_t packet_len
;
831 char *auth_str
= NULL
;
833 if (IS_RIP_DEBUG_EVENT
)
834 zlog_info ("RIPv2 MD5 authentication from %s", inet_ntoa (from
->sin_addr
));
837 md5
= (struct rip_md5_info
*) &packet
->rte
;
839 /* Check auth type. */
840 if (ri
->auth_type
!= RIP_AUTH_MD5
|| ntohs (md5
->type
) != RIP_AUTH_MD5
)
843 if (md5
->auth_len
!= RIP_HEADER_SIZE
+ RIP_AUTH_MD5_SIZE
)
848 keychain
= keychain_lookup (ri
->key_chain
);
849 if (keychain
== NULL
)
852 key
= key_lookup_for_accept (keychain
, md5
->keyid
);
856 auth_str
= key
->string
;
860 auth_str
= ri
->auth_str
;
865 /* MD5 digest authentication. */
866 packet_len
= ntohs (md5
->packet_len
);
867 md5data
= (struct rip_md5_data
*)(((u_char
*) packet
) + packet_len
);
869 /* Save digest to pdigest. */
870 memcpy (pdigest
, md5data
->digest
, RIP_AUTH_MD5_SIZE
);
872 /* Overwrite digest by my secret. */
873 memset (md5data
->digest
, 0, RIP_AUTH_MD5_SIZE
);
874 strncpy (md5data
->digest
, auth_str
, RIP_AUTH_MD5_SIZE
);
877 md5_process_bytes (packet
, packet_len
+ md5
->auth_len
, &ctx
);
878 md5_finish_ctx (&ctx
, digest
);
880 if (memcmp (pdigest
, digest
, RIP_AUTH_MD5_SIZE
) == 0)
887 rip_auth_md5_set (struct stream
*s
, struct interface
*ifp
)
889 struct rip_interface
*ri
;
890 struct keychain
*keychain
= NULL
;
891 struct key
*key
= NULL
;
894 unsigned char secret
[RIP_AUTH_MD5_SIZE
];
895 unsigned char digest
[RIP_AUTH_MD5_SIZE
];
896 char *auth_str
= NULL
;
900 /* Make it sure this interface is configured as MD5
902 if (ri
->auth_type
!= RIP_AUTH_MD5
)
905 /* Lookup key chain. */
908 keychain
= keychain_lookup (ri
->key_chain
);
909 if (keychain
== NULL
)
913 key
= key_lookup_for_send (keychain
);
917 auth_str
= key
->string
;
921 auth_str
= ri
->auth_str
;
926 /* Get packet length. */
929 /* Check packet length. */
930 if (len
< (RIP_HEADER_SIZE
+ RIP_RTE_SIZE
))
932 zlog_err ("rip_auth_md5_set(): packet length %ld is less than minimum length.", len
);
937 memmove (s
->data
+ RIP_HEADER_SIZE
+ RIP_RTE_SIZE
,
938 s
->data
+ RIP_HEADER_SIZE
,
939 len
- RIP_HEADER_SIZE
);
941 /* Set pointer to authentication header. */
942 stream_set_putp (s
, RIP_HEADER_SIZE
);
945 /* MD5 authentication. */
946 stream_putw (s
, 0xffff);
947 stream_putw (s
, RIP_AUTH_MD5
);
949 /* RIP-2 Packet length. Actual value is filled in
950 rip_auth_md5_set(). */
951 stream_putw (s
, len
);
955 stream_putc (s
, key
->index
% 256);
959 /* Auth Data Len. Set 16 for MD5 authentication
961 stream_putc (s
, RIP_AUTH_MD5_SIZE
+ RIP_HEADER_SIZE
);
963 /* Sequence Number (non-decreasing). */
964 /* RFC2080: The value used in the sequence number is
965 arbitrary, but two suggestions are the time of the
966 message's creation or a simple message counter. */
967 stream_putl (s
, time (NULL
));
969 /* Reserved field must be zero. */
973 /* Set pointer to authentication data. */
974 stream_set_putp (s
, len
);
976 /* Set authentication data. */
977 stream_putw (s
, 0xffff);
978 stream_putw (s
, 0x01);
980 /* Generate a digest for the RIP packet. */
981 memset (secret
, 0, RIP_AUTH_MD5_SIZE
);
982 strncpy (secret
, auth_str
, RIP_AUTH_MD5_SIZE
);
984 md5_process_bytes (s
->data
, s
->endp
, &ctx
);
985 md5_process_bytes (secret
, RIP_AUTH_MD5_SIZE
, &ctx
);
986 md5_finish_ctx (&ctx
, digest
);
988 /* Copy the digest to the packet. */
989 stream_write (s
, digest
, RIP_AUTH_MD5_SIZE
);
992 /* RIP routing information. */
994 rip_response_process (struct rip_packet
*packet
, int size
,
995 struct sockaddr_in
*from
, struct interface
*ifp
)
999 struct prefix_ipv4 ifaddr
;
1000 struct prefix_ipv4 ifaddrclass
;
1001 struct connected
*c
;
1004 /* We don't know yet. */
1007 /* The Response must be ignored if it is not from the RIP
1008 port. (RFC2453 - Sec. 3.9.2)*/
1009 if (ntohs (from
->sin_port
) != RIP_PORT_DEFAULT
)
1011 zlog_info ("response doesn't come from RIP port: %d",
1013 rip_peer_bad_packet (from
);
1017 /* The datagram's IPv4 source address should be checked to see
1018 whether the datagram is from a valid neighbor; the source of the
1019 datagram must be on a directly connected network */
1020 if (if_lookup_address (from
->sin_addr
) == NULL
)
1022 zlog_info ("This datagram doesn't came from a valid neighbor: %s",
1023 inet_ntoa (from
->sin_addr
));
1024 rip_peer_bad_packet (from
);
1028 /* It is also worth checking to see whether the response is from one
1029 of the router's own addresses. */
1031 ; /* Alredy done in rip_read () */
1033 /* Update RIP peer. */
1034 rip_peer_update (from
, packet
->version
);
1036 /* Set RTE pointer. */
1039 for (lim
= (caddr_t
) packet
+ size
; (caddr_t
) rte
< lim
; rte
++)
1041 /* RIPv2 authentication check. */
1042 /* If the Address Family Identifier of the first (and only the
1043 first) entry in the message is 0xFFFF, then the remainder of
1044 the entry contains the authentication. */
1045 /* If the packet gets here it means authentication enabled */
1046 /* Check is done in rip_read(). So, just skipping it */
1047 if (packet
->version
== RIPv2
&&
1048 rte
== packet
->rte
&&
1049 rte
->family
== 0xffff)
1052 if (ntohs (rte
->family
) != AF_INET
)
1054 /* Address family check. RIP only supports AF_INET. */
1055 zlog_info ("Unsupported family %d from %s.",
1056 ntohs (rte
->family
), inet_ntoa (from
->sin_addr
));
1060 /* - is the destination address valid (e.g., unicast; not net 0
1062 if (! rip_destination_check (rte
->prefix
))
1064 zlog_info ("Network is net 0 or net 127 or it is not unicast network");
1065 rip_peer_bad_route (from
);
1069 /* Convert metric value to host byte order. */
1070 rte
->metric
= ntohl (rte
->metric
);
1072 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1073 if (! (rte
->metric
>= 1 && rte
->metric
<= 16))
1075 zlog_info ("Route's metric is not in the 1-16 range.");
1076 rip_peer_bad_route (from
);
1080 /* RIPv1 does not have nexthop value. */
1081 if (packet
->version
== RIPv1
&& rte
->nexthop
.s_addr
!= 0)
1083 zlog_info ("RIPv1 packet with nexthop value %s",
1084 inet_ntoa (rte
->nexthop
));
1085 rip_peer_bad_route (from
);
1089 /* That is, if the provided information is ignored, a possibly
1090 sub-optimal, but absolutely valid, route may be taken. If
1091 the received Next Hop is not directly reachable, it should be
1092 treated as 0.0.0.0. */
1093 if (packet
->version
== RIPv2
&& rte
->nexthop
.s_addr
!= 0)
1097 /* Multicast address check. */
1098 addrval
= ntohl (rte
->nexthop
.s_addr
);
1099 if (IN_CLASSD (addrval
))
1101 zlog_info ("Nexthop %s is multicast address, skip this rte",
1102 inet_ntoa (rte
->nexthop
));
1106 if (! if_lookup_address (rte
->nexthop
))
1108 struct route_node
*rn
;
1109 struct rip_info
*rinfo
;
1111 rn
= route_node_match_ipv4 (rip
->table
, &rte
->nexthop
);
1117 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1118 && rinfo
->sub_type
== RIP_ROUTE_RTE
)
1120 if (IS_RIP_DEBUG_EVENT
)
1121 zlog_info ("Next hop %s is on RIP network. Set nexthop to the packet's originator", inet_ntoa (rte
->nexthop
));
1122 rte
->nexthop
= rinfo
->from
;
1126 if (IS_RIP_DEBUG_EVENT
)
1127 zlog_info ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte
->nexthop
));
1128 rte
->nexthop
.s_addr
= 0;
1131 route_unlock_node (rn
);
1135 if (IS_RIP_DEBUG_EVENT
)
1136 zlog_info ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte
->nexthop
));
1137 rte
->nexthop
.s_addr
= 0;
1143 /* For RIPv1, there won't be a valid netmask.
1145 This is a best guess at the masks. If everyone was using old
1146 Ciscos before the 'ip subnet zero' option, it would be almost
1149 Cisco summarize ripv1 advertisments to the classful boundary
1150 (/16 for class B's) except when the RIP packet does to inside
1151 the classful network in question. */
1153 if ((packet
->version
== RIPv1
&& rte
->prefix
.s_addr
!= 0)
1154 || (packet
->version
== RIPv2
1155 && (rte
->prefix
.s_addr
!= 0 && rte
->mask
.s_addr
== 0)))
1157 u_int32_t destination
;
1159 if (subnetted
== -1)
1161 c
= connected_lookup_address (ifp
, from
->sin_addr
);
1164 memcpy (&ifaddr
, c
->address
, sizeof (struct prefix_ipv4
));
1165 memcpy (&ifaddrclass
, &ifaddr
, sizeof (struct prefix_ipv4
));
1166 apply_classful_mask_ipv4 (&ifaddrclass
);
1168 if (ifaddr
.prefixlen
> ifaddrclass
.prefixlen
)
1173 destination
= ntohl (rte
->prefix
.s_addr
);
1175 if (IN_CLASSA (destination
))
1176 masklen2ip (8, &rte
->mask
);
1177 else if (IN_CLASSB (destination
))
1178 masklen2ip (16, &rte
->mask
);
1179 else if (IN_CLASSC (destination
))
1180 masklen2ip (24, &rte
->mask
);
1183 masklen2ip (ifaddrclass
.prefixlen
,
1184 (struct in_addr
*) &destination
);
1185 if ((subnetted
== 1) && ((rte
->prefix
.s_addr
& destination
) ==
1186 ifaddrclass
.prefix
.s_addr
))
1188 masklen2ip (ifaddr
.prefixlen
, &rte
->mask
);
1189 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
) != rte
->prefix
.s_addr
)
1190 masklen2ip (32, &rte
->mask
);
1191 if (IS_RIP_DEBUG_EVENT
)
1192 zlog_info ("Subnetted route %s", inet_ntoa (rte
->prefix
));
1196 if ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
) != rte
->prefix
.s_addr
)
1200 if (IS_RIP_DEBUG_EVENT
)
1202 zlog_info ("Resultant route %s", inet_ntoa (rte
->prefix
));
1203 zlog_info ("Resultant mask %s", inet_ntoa (rte
->mask
));
1207 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1208 ignore the entry. */
1209 if ((packet
->version
== RIPv2
)
1210 && (rte
->mask
.s_addr
!= 0)
1211 && ((rte
->prefix
.s_addr
& rte
->mask
.s_addr
) != rte
->prefix
.s_addr
))
1213 zlog_warn ("RIPv2 address %s is not mask /%d applied one",
1214 inet_ntoa (rte
->prefix
), ip_masklen (rte
->mask
));
1215 rip_peer_bad_route (from
);
1219 /* Default route's netmask is ignored. */
1220 if (packet
->version
== RIPv2
1221 && (rte
->prefix
.s_addr
== 0)
1222 && (rte
->mask
.s_addr
!= 0))
1224 if (IS_RIP_DEBUG_EVENT
)
1225 zlog_info ("Default route with non-zero netmask. Set zero to netmask");
1226 rte
->mask
.s_addr
= 0;
1229 /* Routing table updates. */
1230 rip_rte_process (rte
, from
, ifp
);
1234 /* RIP packet send to destination address. */
1236 rip_send_packet (caddr_t buf
, int size
, struct sockaddr_in
*to
,
1237 struct interface
*ifp
)
1240 struct sockaddr_in sin
;
1243 /* Make destination address. */
1244 memset (&sin
, 0, sizeof (struct sockaddr_in
));
1245 sin
.sin_family
= AF_INET
;
1247 sin
.sin_len
= sizeof (struct sockaddr_in
);
1248 #endif /* HAVE_SIN_LEN */
1250 /* When destination is specified, use it's port and address. */
1255 sin
.sin_port
= to
->sin_port
;
1256 sin
.sin_addr
= to
->sin_addr
;
1260 sock
= socket (AF_INET
, SOCK_DGRAM
, 0);
1262 sockopt_broadcast (sock
);
1263 sockopt_reuseaddr (sock
);
1264 sockopt_reuseport (sock
);
1266 sin
.sin_port
= htons (RIP_PORT_DEFAULT
);
1267 sin
.sin_addr
.s_addr
= htonl (INADDR_RIP_GROUP
);
1269 /* Set multicast interface. */
1270 rip_interface_multicast_set (sock
, ifp
);
1273 ret
= sendto (sock
, buf
, size
, 0, (struct sockaddr
*)&sin
,
1274 sizeof (struct sockaddr_in
));
1276 if (IS_RIP_DEBUG_EVENT
)
1277 zlog_info ("SEND to socket %d port %d addr %s",
1278 sock
, ntohs (sin
.sin_port
), inet_ntoa(sin
.sin_addr
));
1281 zlog_warn ("can't send packet : %s", strerror (errno
));
1289 /* Add redistributed route to RIP table. */
1291 rip_redistribute_add (int type
, int sub_type
, struct prefix_ipv4
*p
,
1292 unsigned int ifindex
, struct in_addr
*nexthop
)
1295 struct route_node
*rp
;
1296 struct rip_info
*rinfo
;
1298 /* Redistribute route */
1299 ret
= rip_destination_check (p
->prefix
);
1303 rp
= route_node_get (rip
->table
, (struct prefix
*) p
);
1309 if (rinfo
->type
== ZEBRA_ROUTE_CONNECT
1310 && rinfo
->sub_type
== RIP_ROUTE_INTERFACE
1311 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
1313 route_unlock_node (rp
);
1317 /* Manually configured RIP route check. */
1318 if (rinfo
->type
== ZEBRA_ROUTE_RIP
1319 && ((rinfo
->sub_type
== RIP_ROUTE_STATIC
) ||
1320 (rinfo
->sub_type
== RIP_ROUTE_DEFAULT
)) )
1322 if (type
!= ZEBRA_ROUTE_RIP
|| ((sub_type
!= RIP_ROUTE_STATIC
) &&
1323 (sub_type
!= RIP_ROUTE_DEFAULT
)))
1325 route_unlock_node (rp
);
1330 RIP_TIMER_OFF (rinfo
->t_timeout
);
1331 RIP_TIMER_OFF (rinfo
->t_garbage_collect
);
1333 if (rip_route_rte (rinfo
))
1334 rip_zebra_ipv4_delete ((struct prefix_ipv4
*)&rp
->p
, &rinfo
->nexthop
,
1337 rip_info_free (rinfo
);
1339 route_unlock_node (rp
);
1342 rinfo
= rip_info_new ();
1345 rinfo
->sub_type
= sub_type
;
1346 rinfo
->ifindex
= ifindex
;
1351 rinfo
->nexthop
= *nexthop
;
1353 rinfo
->flags
|= RIP_RTF_FIB
;
1356 rinfo
->flags
|= RIP_RTF_CHANGED
;
1358 if (IS_RIP_DEBUG_EVENT
) {
1360 zlog_info ("Redistribute new prefix %s/%d on the interface %s",
1361 inet_ntoa(p
->prefix
), p
->prefixlen
,
1362 ifindex2ifname(ifindex
));
1364 zlog_info ("Redistribute new prefix %s/%d with nexthop %s on the interface %s",
1365 inet_ntoa(p
->prefix
), p
->prefixlen
, inet_ntoa(rinfo
->nexthop
),
1366 ifindex2ifname(ifindex
));
1370 rip_event (RIP_TRIGGERED_UPDATE
, 0);
1373 /* Delete redistributed route from RIP table. */
1375 rip_redistribute_delete (int type
, int sub_type
, struct prefix_ipv4
*p
,
1376 unsigned int ifindex
)
1379 struct route_node
*rp
;
1380 struct rip_info
*rinfo
;
1382 ret
= rip_destination_check (p
->prefix
);
1386 rp
= route_node_lookup (rip
->table
, (struct prefix
*) p
);
1392 && rinfo
->type
== type
1393 && rinfo
->sub_type
== sub_type
1394 && rinfo
->ifindex
== ifindex
)
1396 /* Perform poisoned reverse. */
1397 rinfo
->metric
= RIP_METRIC_INFINITY
;
1398 RIP_TIMER_ON (rinfo
->t_garbage_collect
,
1399 rip_garbage_collect
, rip
->garbage_time
);
1400 RIP_TIMER_OFF (rinfo
->t_timeout
);
1401 rinfo
->flags
|= RIP_RTF_CHANGED
;
1403 if (IS_RIP_DEBUG_EVENT
)
1404 zlog_info ("Poisone %s/%d on the interface %s with an infinity metric [delete]",
1405 inet_ntoa(p
->prefix
), p
->prefixlen
,
1406 ifindex2ifname(ifindex
));
1408 rip_event (RIP_TRIGGERED_UPDATE
, 0);
1413 /* Response to request called from rip_read ().*/
1415 rip_request_process (struct rip_packet
*packet
, int size
,
1416 struct sockaddr_in
*from
, struct interface
*ifp
)
1420 struct prefix_ipv4 p
;
1421 struct route_node
*rp
;
1422 struct rip_info
*rinfo
;
1423 struct rip_interface
*ri
;
1425 /* Does not reponse to the requests on the loopback interfaces */
1426 if (if_is_loopback (ifp
))
1429 /* Check RIPng process is enabled on this interface. */
1434 /* When passive interface is specified, suppress responses */
1438 /* RIP peer update. */
1439 rip_peer_update (from
, packet
->version
);
1441 lim
= ((caddr_t
) packet
) + size
;
1444 /* The Request is processed entry by entry. If there are no
1445 entries, no response is given. */
1446 if (lim
== (caddr_t
) rte
)
1449 /* There is one special case. If there is exactly one entry in the
1450 request, and it has an address family identifier of zero and a
1451 metric of infinity (i.e., 16), then this is a request to send the
1452 entire routing table. */
1453 if (lim
== ((caddr_t
) (rte
+ 1)) &&
1454 ntohs (rte
->family
) == 0 &&
1455 ntohl (rte
->metric
) == RIP_METRIC_INFINITY
)
1457 /* All route with split horizon */
1458 rip_output_process (ifp
, NULL
, from
, rip_all_route
, packet
->version
);
1462 /* Examine the list of RTEs in the Request one by one. For each
1463 entry, look up the destination in the router's routing
1464 database and, if there is a route, put that route's metric in
1465 the metric field of the RTE. If there is no explicit route
1466 to the specified destination, put infinity in the metric
1467 field. Once all the entries have been filled in, change the
1468 command from Request to Response and send the datagram back
1469 to the requestor. */
1472 for (; ((caddr_t
) rte
) < lim
; rte
++)
1474 p
.prefix
= rte
->prefix
;
1475 p
.prefixlen
= ip_masklen (rte
->mask
);
1476 apply_mask_ipv4 (&p
);
1478 rp
= route_node_lookup (rip
->table
, (struct prefix
*) &p
);
1482 rte
->metric
= htonl (rinfo
->metric
);
1483 route_unlock_node (rp
);
1486 rte
->metric
= htonl (RIP_METRIC_INFINITY
);
1488 packet
->command
= RIP_RESPONSE
;
1490 rip_send_packet ((caddr_t
) packet
, size
, from
, ifp
);
1492 rip_global_queries
++;
1496 /* Set IPv6 packet info to the socket. */
1498 setsockopt_pktinfo (int sock
)
1503 ret
= setsockopt(sock
, IPPROTO_IP
, IP_PKTINFO
, &val
, sizeof(val
));
1505 zlog_warn ("Can't setsockopt IP_PKTINFO : %s", strerror (errno
));
1509 /* Read RIP packet by recvmsg function. */
1511 rip_recvmsg (int sock
, u_char
*buf
, int size
, struct sockaddr_in
*from
,
1517 struct cmsghdr
*ptr
;
1520 msg
.msg_name
= (void *) from
;
1521 msg
.msg_namelen
= sizeof (struct sockaddr_in
);
1524 msg
.msg_control
= (void *) adata
;
1525 msg
.msg_controllen
= sizeof adata
;
1529 ret
= recvmsg (sock
, &msg
, 0);
1533 for (ptr
= CMSG_FIRSTHDR(&msg
); ptr
!= NULL
; ptr
= CMSG_NXTHDR(&msg
, ptr
))
1534 if (ptr
->cmsg_level
== IPPROTO_IP
&& ptr
->cmsg_type
== IP_PKTINFO
)
1536 struct in_pktinfo
*pktinfo
;
1539 pktinfo
= (struct in_pktinfo
*) CMSG_DATA (ptr
);
1540 i
= pktinfo
->ipi_ifindex
;
1545 /* RIP packet read function. */
1547 rip_read_new (struct thread
*t
)
1551 char buf
[RIP_PACKET_MAXSIZ
];
1552 struct sockaddr_in from
;
1553 unsigned int ifindex
;
1555 /* Fetch socket then register myself. */
1556 sock
= THREAD_FD (t
);
1557 rip_event (RIP_READ
, sock
);
1559 /* Read RIP packet. */
1560 ret
= rip_recvmsg (sock
, buf
, RIP_PACKET_MAXSIZ
, &from
, (int *)&ifindex
);
1563 zlog_warn ("Can't read RIP packet: %s", strerror (errno
));
1569 #endif /* RIP_RECVMSG */
1571 /* First entry point of RIP packet. */
1573 rip_read (struct thread
*t
)
1578 union rip_buf rip_buf
;
1579 struct rip_packet
*packet
;
1580 struct sockaddr_in from
;
1582 struct interface
*ifp
;
1583 struct rip_interface
*ri
;
1585 /* Fetch socket then register myself. */
1586 sock
= THREAD_FD (t
);
1589 /* Add myself to tne next event */
1590 rip_event (RIP_READ
, sock
);
1592 /* RIPd manages only IPv4. */
1593 memset (&from
, 0, sizeof (struct sockaddr_in
));
1594 fromlen
= sizeof (struct sockaddr_in
);
1596 len
= recvfrom (sock
, (char *)&rip_buf
.buf
, sizeof (rip_buf
.buf
), 0,
1597 (struct sockaddr
*) &from
, &fromlen
);
1600 zlog_info ("recvfrom failed: %s", strerror (errno
));
1604 /* Check is this packet comming from myself? */
1605 if (if_lookup_exact_address (from
.sin_addr
))
1607 if (IS_RIP_DEBUG_PACKET
)
1608 zlog_warn ("ignore packet comes from myself");
1612 /* Which interface is this packet comes from. */
1613 ifp
= if_lookup_address (from
.sin_addr
);
1615 /* RIP packet received */
1616 if (IS_RIP_DEBUG_EVENT
)
1617 zlog_info ("RECV packet from %s port %d on %s",
1618 inet_ntoa (from
.sin_addr
), ntohs (from
.sin_port
),
1619 ifp
? ifp
->name
: "unknown");
1621 /* If this packet come from unknown interface, ignore it. */
1624 zlog_info ("packet comes from unknown interface");
1628 /* Packet length check. */
1629 if (len
< RIP_PACKET_MINSIZ
)
1631 zlog_warn ("packet size %d is smaller than minimum size %d",
1632 len
, RIP_PACKET_MINSIZ
);
1633 rip_peer_bad_packet (&from
);
1636 if (len
> RIP_PACKET_MAXSIZ
)
1638 zlog_warn ("packet size %d is larger than max size %d",
1639 len
, RIP_PACKET_MAXSIZ
);
1640 rip_peer_bad_packet (&from
);
1644 /* Packet alignment check. */
1645 if ((len
- RIP_PACKET_MINSIZ
) % 20)
1647 zlog_warn ("packet size %d is wrong for RIP packet alignment", len
);
1648 rip_peer_bad_packet (&from
);
1652 /* Set RTE number. */
1653 rtenum
= ((len
- RIP_PACKET_MINSIZ
) / 20);
1655 /* For easy to handle. */
1656 packet
= &rip_buf
.rip_packet
;
1658 /* RIP version check. */
1659 if (packet
->version
== 0)
1661 zlog_info ("version 0 with command %d received.", packet
->command
);
1662 rip_peer_bad_packet (&from
);
1666 /* Dump RIP packet. */
1667 if (IS_RIP_DEBUG_RECV
)
1668 rip_packet_dump (packet
, len
, "RECV");
1670 /* RIP version adjust. This code should rethink now. RFC1058 says
1671 that "Version 1 implementations are to ignore this extra data and
1672 process only the fields specified in this document.". So RIPv3
1673 packet should be treated as RIPv1 ignoring must be zero field. */
1674 if (packet
->version
> RIPv2
)
1675 packet
->version
= RIPv2
;
1677 /* Is RIP running or is this RIP neighbor ?*/
1679 if (! ri
->running
&& ! rip_neighbor_lookup (&from
))
1681 if (IS_RIP_DEBUG_EVENT
)
1682 zlog_info ("RIP is not enabled on interface %s.", ifp
->name
);
1683 rip_peer_bad_packet (&from
);
1687 /* RIP Version check. */
1688 if (packet
->command
== RIP_RESPONSE
)
1690 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
1692 if (packet
->version
!= rip
->version
)
1694 if (IS_RIP_DEBUG_PACKET
)
1695 zlog_warn (" packet's v%d doesn't fit to my version %d",
1696 packet
->version
, rip
->version
);
1697 rip_peer_bad_packet (&from
);
1703 if (packet
->version
== RIPv1
)
1704 if (! (ri
->ri_receive
& RIPv1
))
1706 if (IS_RIP_DEBUG_PACKET
)
1707 zlog_warn (" packet's v%d doesn't fit to if version spec",
1709 rip_peer_bad_packet (&from
);
1712 if (packet
->version
== RIPv2
)
1713 if (! (ri
->ri_receive
& RIPv2
))
1715 if (IS_RIP_DEBUG_PACKET
)
1716 zlog_warn (" packet's v%d doesn't fit to if version spec",
1718 rip_peer_bad_packet (&from
);
1724 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1725 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1726 accepted; authenticated RIP-2 messages shall be discarded. */
1728 if ((ri
->auth_type
== RIP_NO_AUTH
)
1730 && (packet
->version
== RIPv2
) && (packet
->rte
->family
== 0xffff))
1732 if (IS_RIP_DEBUG_EVENT
)
1733 zlog_warn ("packet RIPv%d is dropped because authentication disabled",
1735 rip_peer_bad_packet (&from
);
1739 /* If the router is configured to authenticate RIP-2 messages, then
1740 RIP-1 messages and RIP-2 messages which pass authentication
1741 testing shall be accepted; unauthenticated and failed
1742 authentication RIP-2 messages shall be discarded. For maximum
1743 security, RIP-1 messages should be ignored when authentication is
1744 in use (see section 4.1); otherwise, the routing information from
1745 authenticated messages will be propagated by RIP-1 routers in an
1746 unauthenticated manner. */
1748 if ((ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
1749 || ri
->auth_type
== RIP_AUTH_MD5
)
1752 /* We follow maximum security. */
1753 if (packet
->version
== RIPv1
&& packet
->rte
->family
== 0xffff)
1755 if (IS_RIP_DEBUG_PACKET
)
1756 zlog_warn ("packet RIPv%d is dropped because authentication enabled", packet
->version
);
1757 rip_peer_bad_packet (&from
);
1761 /* Check RIPv2 authentication. */
1762 if (packet
->version
== RIPv2
)
1764 if (packet
->rte
->family
== 0xffff)
1766 if (ntohs (packet
->rte
->tag
) == RIP_AUTH_SIMPLE_PASSWORD
)
1768 ret
= rip_auth_simple_password (packet
->rte
, &from
, ifp
);
1771 if (IS_RIP_DEBUG_EVENT
)
1772 zlog_warn ("RIPv2 simple password authentication failed");
1773 rip_peer_bad_packet (&from
);
1778 if (IS_RIP_DEBUG_EVENT
)
1779 zlog_info ("RIPv2 simple password authentication success");
1782 else if (ntohs (packet
->rte
->tag
) == RIP_AUTH_MD5
)
1784 ret
= rip_auth_md5 (packet
, &from
, ifp
);
1787 if (IS_RIP_DEBUG_EVENT
)
1788 zlog_warn ("RIPv2 MD5 authentication failed");
1789 rip_peer_bad_packet (&from
);
1794 if (IS_RIP_DEBUG_EVENT
)
1795 zlog_info ("RIPv2 MD5 authentication success");
1797 /* Reset RIP packet length to trim MD5 data. */
1802 if (IS_RIP_DEBUG_EVENT
)
1803 zlog_warn ("Unknown authentication type %d",
1804 ntohs (packet
->rte
->tag
));
1805 rip_peer_bad_packet (&from
);
1811 /* There is no authentication in the packet. */
1812 if (ri
->auth_str
|| ri
->key_chain
)
1814 if (IS_RIP_DEBUG_EVENT
)
1815 zlog_warn ("RIPv2 authentication failed: no authentication in packet");
1816 rip_peer_bad_packet (&from
);
1823 /* Process each command. */
1824 switch (packet
->command
)
1827 rip_response_process (packet
, len
, &from
, ifp
);
1831 rip_request_process (packet
, len
, &from
, ifp
);
1835 zlog_info ("Obsolete command %s received, please sent it to routed",
1836 lookup (rip_msg
, packet
->command
));
1837 rip_peer_bad_packet (&from
);
1839 case RIP_POLL_ENTRY
:
1840 zlog_info ("Obsolete command %s received",
1841 lookup (rip_msg
, packet
->command
));
1842 rip_peer_bad_packet (&from
);
1845 zlog_info ("Unknown RIP command %d received", packet
->command
);
1846 rip_peer_bad_packet (&from
);
1853 /* Make socket for RIP protocol. */
1855 rip_create_socket ()
1859 struct sockaddr_in addr
;
1862 memset (&addr
, 0, sizeof (struct sockaddr_in
));
1865 sp
= getservbyname ("router", "udp");
1867 addr
.sin_port
= sp
->s_port
;
1869 addr
.sin_port
= htons (RIP_PORT_DEFAULT
);
1871 /* Address shoud be any address. */
1872 addr
.sin_family
= AF_INET
;
1873 addr
.sin_addr
.s_addr
= INADDR_ANY
;
1875 /* Make datagram socket. */
1876 sock
= socket (AF_INET
, SOCK_DGRAM
, 0);
1883 sockopt_broadcast (sock
);
1884 sockopt_reuseaddr (sock
);
1885 sockopt_reuseport (sock
);
1887 setsockopt_pktinfo (sock
);
1888 #endif /* RIP_RECVMSG */
1890 if (ripd_privs
.change (ZPRIVS_RAISE
))
1891 zlog_err ("rip_create_socket: could not raise privs");
1892 ret
= bind (sock
, (struct sockaddr
*) & addr
, sizeof (addr
));
1898 if (ripd_privs
.change (ZPRIVS_LOWER
))
1899 zlog_err ("rip_create_socket: could not lower privs");
1904 /* Write routing table entry to the stream and return next index of
1905 the routing table entry in the stream. */
1907 rip_write_rte (int num
, struct stream
*s
, struct prefix_ipv4
*p
,
1908 u_char version
, struct rip_info
*rinfo
, struct interface
*ifp
)
1910 struct in_addr mask
;
1911 struct rip_interface
*ri
;
1913 /* RIP packet header. */
1916 stream_putc (s
, RIP_RESPONSE
);
1917 stream_putc (s
, version
);
1920 /* In case of we need RIPv2 authentication. */
1921 if (version
== RIPv2
&& ifp
)
1925 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
1929 stream_putw (s
, 0xffff);
1930 stream_putw (s
, RIP_AUTH_SIMPLE_PASSWORD
);
1932 memset ((s
->data
+ s
->putp
), 0, 16);
1933 strncpy ((s
->data
+ s
->putp
), ri
->auth_str
, 16);
1934 stream_set_putp (s
, s
->putp
+ 16);
1940 struct keychain
*keychain
;
1943 keychain
= keychain_lookup (ri
->key_chain
);
1947 key
= key_lookup_for_send (keychain
);
1951 stream_putw (s
, 0xffff);
1952 stream_putw (s
, RIP_AUTH_SIMPLE_PASSWORD
);
1954 memset ((s
->data
+ s
->putp
), 0, 16);
1955 strncpy ((s
->data
+ s
->putp
), key
->string
, 16);
1956 stream_set_putp (s
, s
->putp
+ 16);
1966 /* Write routing table entry. */
1967 if (version
== RIPv1
)
1969 stream_putw (s
, AF_INET
);
1971 stream_put_ipv4 (s
, p
->prefix
.s_addr
);
1972 stream_put_ipv4 (s
, 0);
1973 stream_put_ipv4 (s
, 0);
1974 stream_putl (s
, rinfo
->metric_out
);
1978 masklen2ip (p
->prefixlen
, &mask
);
1980 stream_putw (s
, AF_INET
);
1981 stream_putw (s
, rinfo
->tag_out
);
1982 stream_put_ipv4 (s
, p
->prefix
.s_addr
);
1983 stream_put_ipv4 (s
, mask
.s_addr
);
1984 stream_put_ipv4 (s
, rinfo
->nexthop_out
.s_addr
);
1985 stream_putl (s
, rinfo
->metric_out
);
1991 /* Send update to the ifp or spcified neighbor. */
1993 rip_output_process (struct interface
*ifp
, struct prefix
*ifaddr
,
1994 struct sockaddr_in
*to
, int route_type
, u_char version
)
1998 struct route_node
*rp
;
1999 struct rip_info
*rinfo
;
2000 struct rip_interface
*ri
;
2001 struct prefix_ipv4
*p
;
2002 struct prefix_ipv4 classfull
;
2003 struct prefix_ipv4 ifaddrclass
;
2004 struct connected
*c
;
2009 /* Logging output event. */
2010 if (IS_RIP_DEBUG_EVENT
)
2013 zlog_info ("update routes to neighbor %s", inet_ntoa (to
->sin_addr
));
2015 zlog_info ("update routes on interface %s ifindex %d",
2016 ifp
->name
, ifp
->ifindex
);
2019 /* Set output stream. */
2022 /* Reset stream and RTE counter. */
2025 rtemax
= (RIP_PACKET_MAXSIZ
- 4) / 20;
2027 /* Get RIP interface. */
2030 /* If output interface is in simple password authentication mode, we
2031 need space for authentication data. */
2032 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2035 /* If output interface is in MD5 authentication mode, we need space
2036 for authentication header and data. */
2037 if (ri
->auth_type
== RIP_AUTH_MD5
)
2040 /* If output interface is in simple password authentication mode
2041 and string or keychain is specified we need space for auth. data */
2042 if (ri
->auth_type
== RIP_AUTH_SIMPLE_PASSWORD
)
2046 struct keychain
*keychain
;
2048 keychain
= keychain_lookup (ri
->key_chain
);
2050 if (key_lookup_for_send (keychain
))
2058 if (version
== RIPv1
)
2062 c
= connected_lookup_address (ifp
, to
->sin_addr
);
2064 ifaddr
= c
->address
;
2068 zlog_warn ("cannot find source address for packets to neighbor %s",
2069 inet_ntoa (to
->sin_addr
));
2072 memcpy (&ifaddrclass
, ifaddr
, sizeof (struct prefix_ipv4
));
2073 apply_classful_mask_ipv4 (&ifaddrclass
);
2075 if (ifaddr
->prefixlen
> ifaddrclass
.prefixlen
)
2079 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
2080 if ((rinfo
= rp
->info
) != NULL
)
2082 /* For RIPv1, if we are subnetted, output subnets in our network */
2083 /* that have the same mask as the output "interface". For other */
2084 /* networks, only the classfull version is output. */
2086 if (version
== RIPv1
)
2088 p
= (struct prefix_ipv4
*) &rp
->p
;
2090 if (IS_RIP_DEBUG_PACKET
)
2091 zlog_info("RIPv1 mask check, %s/%d considered for output",
2092 inet_ntoa (rp
->p
.u
.prefix4
), rp
->p
.prefixlen
);
2095 prefix_match ((struct prefix
*) &ifaddrclass
, &rp
->p
))
2097 if ((ifaddr
->prefixlen
!= rp
->p
.prefixlen
) &&
2098 (rp
->p
.prefixlen
!= 32))
2103 memcpy (&classfull
, &rp
->p
, sizeof(struct prefix_ipv4
));
2104 apply_classful_mask_ipv4(&classfull
);
2105 if (rp
->p
.u
.prefix4
.s_addr
!= 0 &&
2106 classfull
.prefixlen
!= rp
->p
.prefixlen
)
2109 if (IS_RIP_DEBUG_PACKET
)
2110 zlog_info("RIPv1 mask check, %s/%d made it through",
2111 inet_ntoa (rp
->p
.u
.prefix4
), rp
->p
.prefixlen
);
2114 p
= (struct prefix_ipv4
*) &rp
->p
;
2116 /* Apply output filters. */
2117 ret
= rip_outgoing_filter (p
, ri
);
2121 /* Changed route only output. */
2122 if (route_type
== rip_changed_route
&&
2123 (! (rinfo
->flags
& RIP_RTF_CHANGED
)))
2126 /* Split horizon. */
2127 /* if (split_horizon == rip_split_horizon) */
2128 if (ri
->split_horizon
== RIP_SPLIT_HORIZON
)
2130 /* We perform split horizon for RIP and connected route. */
2131 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
||
2132 rinfo
->type
== ZEBRA_ROUTE_CONNECT
) &&
2133 rinfo
->ifindex
== ifp
->ifindex
)
2137 /* Preparation for route-map. */
2138 rinfo
->metric_set
= 0;
2139 rinfo
->nexthop_out
.s_addr
= 0;
2140 rinfo
->metric_out
= rinfo
->metric
;
2141 rinfo
->tag_out
= rinfo
->tag
;
2142 rinfo
->ifindex_out
= ifp
->ifindex
;
2144 /* In order to avoid some local loops,
2145 * if the RIP route has a nexthop via this interface, keep the nexthop,
2146 * otherwise set it to 0. The nexthop should not be propagated
2147 * beyond the local broadcast/multicast area in order
2148 * to avoid an IGP multi-level recursive look-up.
2151 if (rinfo
->ifindex
== ifp
->ifindex
)
2152 rinfo
->nexthop_out
= rinfo
->nexthop
;
2154 /* Interface route-map */
2155 if (ri
->routemap
[RIP_FILTER_OUT
])
2157 ret
= route_map_apply (ri
->routemap
[RIP_FILTER_OUT
],
2158 (struct prefix
*) p
, RMAP_RIP
,
2161 if (ret
== RMAP_DENYMATCH
)
2163 if (IS_RIP_DEBUG_PACKET
)
2164 zlog_info ("RIP %s/%d is filtered by route-map out",
2165 inet_ntoa (p
->prefix
), p
->prefixlen
);
2170 /* Apply redistribute route map - continue, if deny */
2171 if (rip
->route_map
[rinfo
->type
].name
2172 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
)
2174 ret
= route_map_apply (rip
->route_map
[rinfo
->type
].map
,
2175 (struct prefix
*)p
, RMAP_RIP
, rinfo
);
2177 if (ret
== RMAP_DENYMATCH
)
2179 if (IS_RIP_DEBUG_PACKET
)
2180 zlog_info ("%s/%d is filtered by route-map",
2181 inet_ntoa (p
->prefix
), p
->prefixlen
);
2186 /* When route-map does not set metric. */
2187 if (! rinfo
->metric_set
)
2189 /* If redistribute metric is set. */
2190 if (rip
->route_map
[rinfo
->type
].metric_config
2191 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
2193 rinfo
->metric_out
= rip
->route_map
[rinfo
->type
].metric
;
2197 /* If the route is not connected or localy generated
2198 one, use default-metric value*/
2199 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
2200 && rinfo
->type
!= ZEBRA_ROUTE_CONNECT
2201 && rinfo
->metric
!= RIP_METRIC_INFINITY
)
2202 rinfo
->metric_out
= rip
->default_metric
;
2206 /* Apply offset-list */
2207 if (rinfo
->metric
!= RIP_METRIC_INFINITY
)
2208 rip_offset_list_apply_out (p
, ifp
, &rinfo
->metric_out
);
2210 if (rinfo
->metric_out
> RIP_METRIC_INFINITY
)
2211 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2213 /* Perform split-horizon with poisoned reverse
2214 * for RIP and connected routes.
2216 if (ri
->split_horizon
== RIP_SPLIT_HORIZON_POISONED_REVERSE
) {
2217 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
||
2218 rinfo
->type
== ZEBRA_ROUTE_CONNECT
) &&
2219 rinfo
->ifindex
== ifp
->ifindex
)
2220 rinfo
->metric_out
= RIP_METRIC_INFINITY
;
2223 /* Write RTE to the stream. */
2224 num
= rip_write_rte (num
, s
, p
, version
, rinfo
, to
? NULL
: ifp
);
2227 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2228 rip_auth_md5_set (s
, ifp
);
2230 ret
= rip_send_packet (STREAM_DATA (s
), stream_get_endp (s
),
2233 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2234 rip_packet_dump ((struct rip_packet
*)STREAM_DATA (s
),
2235 stream_get_endp(s
), "SEND");
2241 /* Flush unwritten RTE. */
2244 if (version
== RIPv2
&& ri
->auth_type
== RIP_AUTH_MD5
)
2245 rip_auth_md5_set (s
, ifp
);
2247 ret
= rip_send_packet (STREAM_DATA (s
), stream_get_endp (s
), to
, ifp
);
2249 if (ret
>= 0 && IS_RIP_DEBUG_SEND
)
2250 rip_packet_dump ((struct rip_packet
*)STREAM_DATA (s
),
2251 stream_get_endp (s
), "SEND");
2256 /* Statistics updates. */
2260 /* Send RIP packet to the interface. */
2262 rip_update_interface (struct interface
*ifp
, u_char version
, int route_type
)
2264 struct prefix_ipv4
*p
;
2265 struct connected
*connected
;
2267 struct sockaddr_in to
;
2269 /* When RIP version is 2 and multicast enable interface. */
2270 if (version
== RIPv2
&& if_is_multicast (ifp
))
2272 if (IS_RIP_DEBUG_EVENT
)
2273 zlog_info ("multicast announce on %s ", ifp
->name
);
2275 rip_output_process (ifp
, NULL
, NULL
, route_type
, version
);
2279 /* If we can't send multicast packet, send it with unicast. */
2280 if (if_is_broadcast (ifp
) || if_is_pointopoint (ifp
))
2282 for (node
= listhead (ifp
->connected
); node
; nextnode (node
))
2284 connected
= getdata (node
);
2286 /* Fetch broadcast address or poin-to-point destination
2288 p
= (struct prefix_ipv4
*) connected
->destination
;
2290 if (p
->family
== AF_INET
)
2292 /* Destination address and port setting. */
2293 memset (&to
, 0, sizeof (struct sockaddr_in
));
2294 to
.sin_addr
= p
->prefix
;
2295 to
.sin_port
= htons (RIP_PORT_DEFAULT
);
2297 if (IS_RIP_DEBUG_EVENT
)
2298 zlog_info ("%s announce to %s on %s",
2299 if_is_pointopoint (ifp
) ? "unicast" : "broadcast",
2300 inet_ntoa (to
.sin_addr
), ifp
->name
);
2302 rip_output_process (ifp
, connected
->address
, &to
, route_type
,
2309 /* Update send to all interface and neighbor. */
2311 rip_update_process (int route_type
)
2314 struct interface
*ifp
;
2315 struct rip_interface
*ri
;
2316 struct route_node
*rp
;
2317 struct sockaddr_in to
;
2318 struct prefix_ipv4
*p
;
2320 /* Send RIP update to each interface. */
2321 for (node
= listhead (iflist
); node
; nextnode (node
))
2323 ifp
= getdata (node
);
2325 if (if_is_loopback (ifp
))
2328 if (! if_is_operative (ifp
))
2331 /* Fetch RIP interface information. */
2334 /* When passive interface is specified, suppress announce to the
2341 if (IS_RIP_DEBUG_EVENT
)
2344 zlog_info ("SEND UPDATE to %s ifindex %d",
2345 ifp
->name
, ifp
->ifindex
);
2347 zlog_info ("SEND UPDATE to _unknown_ ifindex %d",
2351 /* If there is no version configuration in the interface,
2352 use rip's version setting. */
2353 if (ri
->ri_send
== RI_RIP_UNSPEC
)
2355 if (rip
->version
== RIPv1
)
2356 rip_update_interface (ifp
, RIPv1
, route_type
);
2358 rip_update_interface (ifp
, RIPv2
, route_type
);
2360 /* If interface has RIP version configuration use it. */
2363 if (ri
->ri_send
& RIPv1
)
2364 rip_update_interface (ifp
, RIPv1
, route_type
);
2365 if (ri
->ri_send
& RIPv2
)
2366 rip_update_interface (ifp
, RIPv2
, route_type
);
2371 /* RIP send updates to each neighbor. */
2372 for (rp
= route_top (rip
->neighbor
); rp
; rp
= route_next (rp
))
2373 if (rp
->info
!= NULL
)
2375 p
= (struct prefix_ipv4
*) &rp
->p
;
2377 ifp
= if_lookup_address (p
->prefix
);
2380 zlog_warn ("Neighbor %s doesn't exist direct connected network",
2381 inet_ntoa (p
->prefix
));
2385 /* Set destination address and port */
2386 memset (&to
, 0, sizeof (struct sockaddr_in
));
2387 to
.sin_addr
= p
->prefix
;
2388 to
.sin_port
= htons (RIP_PORT_DEFAULT
);
2390 /* RIP version is rip's configuration. */
2391 rip_output_process (ifp
, NULL
, &to
, route_type
, rip
->version
);
2395 /* RIP's periodical timer. */
2397 rip_update (struct thread
*t
)
2399 /* Clear timer pointer. */
2400 rip
->t_update
= NULL
;
2402 if (IS_RIP_DEBUG_EVENT
)
2403 zlog_info ("update timer fire!");
2405 /* Process update output. */
2406 rip_update_process (rip_all_route
);
2408 /* Triggered updates may be suppressed if a regular update is due by
2409 the time the triggered update would be sent. */
2410 if (rip
->t_triggered_interval
)
2412 thread_cancel (rip
->t_triggered_interval
);
2413 rip
->t_triggered_interval
= NULL
;
2417 /* Register myself. */
2418 rip_event (RIP_UPDATE_EVENT
, 0);
2423 /* Walk down the RIP routing table then clear changed flag. */
2425 rip_clear_changed_flag ()
2427 struct route_node
*rp
;
2428 struct rip_info
*rinfo
;
2430 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
2431 if ((rinfo
= rp
->info
) != NULL
)
2432 if (rinfo
->flags
& RIP_RTF_CHANGED
)
2433 rinfo
->flags
&= ~RIP_RTF_CHANGED
;
2436 /* Triggered update interval timer. */
2438 rip_triggered_interval (struct thread
*t
)
2440 int rip_triggered_update (struct thread
*);
2442 rip
->t_triggered_interval
= NULL
;
2447 rip_triggered_update (t
);
2452 /* Execute triggered update. */
2454 rip_triggered_update (struct thread
*t
)
2458 /* Clear thred pointer. */
2459 rip
->t_triggered_update
= NULL
;
2461 /* Cancel interval timer. */
2462 if (rip
->t_triggered_interval
)
2464 thread_cancel (rip
->t_triggered_interval
);
2465 rip
->t_triggered_interval
= NULL
;
2469 /* Logging triggered update. */
2470 if (IS_RIP_DEBUG_EVENT
)
2471 zlog_info ("triggered update!");
2473 /* Split Horizon processing is done when generating triggered
2474 updates as well as normal updates (see section 2.6). */
2475 rip_update_process (rip_changed_route
);
2477 /* Once all of the triggered updates have been generated, the route
2478 change flags should be cleared. */
2479 rip_clear_changed_flag ();
2481 /* After a triggered update is sent, a timer should be set for a
2482 random interval between 1 and 5 seconds. If other changes that
2483 would trigger updates occur before the timer expires, a single
2484 update is triggered when the timer expires. */
2485 interval
= (random () % 5) + 1;
2487 rip
->t_triggered_interval
=
2488 thread_add_timer (master
, rip_triggered_interval
, NULL
, interval
);
2493 /* Withdraw redistributed route. */
2495 rip_redistribute_withdraw (int type
)
2497 struct route_node
*rp
;
2498 struct rip_info
*rinfo
;
2503 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
2504 if ((rinfo
= rp
->info
) != NULL
)
2506 if (rinfo
->type
== type
2507 && rinfo
->sub_type
!= RIP_ROUTE_INTERFACE
)
2509 /* Perform poisoned reverse. */
2510 rinfo
->metric
= RIP_METRIC_INFINITY
;
2511 RIP_TIMER_ON (rinfo
->t_garbage_collect
,
2512 rip_garbage_collect
, rip
->garbage_time
);
2513 RIP_TIMER_OFF (rinfo
->t_timeout
);
2514 rinfo
->flags
|= RIP_RTF_CHANGED
;
2516 if (IS_RIP_DEBUG_EVENT
) {
2517 struct prefix_ipv4
*p
= (struct prefix_ipv4
*) &rp
->p
;
2519 zlog_info ("Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2520 inet_ntoa(p
->prefix
), p
->prefixlen
,
2521 ifindex2ifname(rinfo
->ifindex
));
2524 rip_event (RIP_TRIGGERED_UPDATE
, 0);
2529 /* Create new RIP instance and set it to global variable. */
2533 rip
= XMALLOC (MTYPE_RIP
, sizeof (struct rip
));
2534 memset (rip
, 0, sizeof (struct rip
));
2536 /* Set initial value. */
2537 rip
->version
= RIPv2
;
2538 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
2539 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
2540 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
2541 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2543 /* Initialize RIP routig table. */
2544 rip
->table
= route_table_init ();
2545 rip
->route
= route_table_init ();
2546 rip
->neighbor
= route_table_init ();
2548 /* Make output stream. */
2549 rip
->obuf
= stream_new (1500);
2552 rip
->sock
= rip_create_socket ();
2556 /* Create read and timer thread. */
2557 rip_event (RIP_READ
, rip
->sock
);
2558 rip_event (RIP_UPDATE_EVENT
, 1);
2563 /* Sned RIP request to the destination. */
2565 rip_request_send (struct sockaddr_in
*to
, struct interface
*ifp
,
2569 struct rip_packet rip_packet
;
2571 memset (&rip_packet
, 0, sizeof (rip_packet
));
2573 rip_packet
.command
= RIP_REQUEST
;
2574 rip_packet
.version
= version
;
2575 rte
= rip_packet
.rte
;
2576 rte
->metric
= htonl (RIP_METRIC_INFINITY
);
2578 return rip_send_packet ((caddr_t
) &rip_packet
, sizeof (rip_packet
), to
, ifp
);
2582 rip_update_jitter (unsigned long time
)
2584 return ((rand () % (time
+ 1)) - (time
/ 2));
2588 rip_event (enum rip_event event
, int sock
)
2595 rip
->t_read
= thread_add_read (master
, rip_read
, NULL
, sock
);
2597 case RIP_UPDATE_EVENT
:
2600 thread_cancel (rip
->t_update
);
2601 rip
->t_update
= NULL
;
2603 jitter
= rip_update_jitter (rip
->update_time
);
2605 thread_add_timer (master
, rip_update
, NULL
,
2606 sock
? 2 : rip
->update_time
+ jitter
);
2608 case RIP_TRIGGERED_UPDATE
:
2609 if (rip
->t_triggered_interval
)
2611 else if (! rip
->t_triggered_update
)
2612 rip
->t_triggered_update
=
2613 thread_add_event (master
, rip_triggered_update
, NULL
, 0);
2623 "Enable a routing process\n"
2624 "Routing Information Protocol (RIP)\n")
2628 /* If rip is not enabled before. */
2631 ret
= rip_create ();
2634 zlog_info ("Can't create RIP");
2638 vty
->node
= RIP_NODE
;
2644 DEFUN (no_router_rip
,
2648 "Enable a routing process\n"
2649 "Routing Information Protocol (RIP)\n")
2659 "Set routing protocol version\n"
2664 version
= atoi (argv
[0]);
2665 if (version
!= RIPv1
&& version
!= RIPv2
)
2667 vty_out (vty
, "invalid rip version %d%s", version
,
2671 rip
->version
= version
;
2676 DEFUN (no_rip_version
,
2680 "Set routing protocol version\n")
2682 /* Set RIP version to the default. */
2683 rip
->version
= RIPv2
;
2688 ALIAS (no_rip_version
,
2689 no_rip_version_val_cmd
,
2692 "Set routing protocol version\n"
2698 "RIP static route configuration\n"
2699 "IP prefix <network>/<length>\n")
2702 struct prefix_ipv4 p
;
2703 struct route_node
*node
;
2705 ret
= str2prefix_ipv4 (argv
[0], &p
);
2708 vty_out (vty
, "Malformed address%s", VTY_NEWLINE
);
2711 apply_mask_ipv4 (&p
);
2713 /* For router rip configuration. */
2714 node
= route_node_get (rip
->route
, (struct prefix
*) &p
);
2718 vty_out (vty
, "There is already same static route.%s", VTY_NEWLINE
);
2719 route_unlock_node (node
);
2723 node
->info
= "static";
2725 rip_redistribute_add (ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0, NULL
);
2730 DEFUN (no_rip_route
,
2732 "no route A.B.C.D/M",
2734 "RIP static route configuration\n"
2735 "IP prefix <network>/<length>\n")
2738 struct prefix_ipv4 p
;
2739 struct route_node
*node
;
2741 ret
= str2prefix_ipv4 (argv
[0], &p
);
2744 vty_out (vty
, "Malformed address%s", VTY_NEWLINE
);
2747 apply_mask_ipv4 (&p
);
2749 /* For router rip configuration. */
2750 node
= route_node_lookup (rip
->route
, (struct prefix
*) &p
);
2753 vty_out (vty
, "Can't find route %s.%s", argv
[0],
2758 rip_redistribute_delete (ZEBRA_ROUTE_RIP
, RIP_ROUTE_STATIC
, &p
, 0);
2759 route_unlock_node (node
);
2762 route_unlock_node (node
);
2768 rip_update_default_metric ()
2770 struct route_node
*np
;
2771 struct rip_info
*rinfo
;
2773 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
2774 if ((rinfo
= np
->info
) != NULL
)
2775 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
&& rinfo
->type
!= ZEBRA_ROUTE_CONNECT
)
2776 rinfo
->metric
= rip
->default_metric
;
2779 DEFUN (rip_default_metric
,
2780 rip_default_metric_cmd
,
2781 "default-metric <1-16>",
2782 "Set a metric of redistribute routes\n"
2787 rip
->default_metric
= atoi (argv
[0]);
2788 /* rip_update_default_metric (); */
2793 DEFUN (no_rip_default_metric
,
2794 no_rip_default_metric_cmd
,
2795 "no default-metric",
2797 "Set a metric of redistribute routes\n"
2802 rip
->default_metric
= RIP_DEFAULT_METRIC_DEFAULT
;
2803 /* rip_update_default_metric (); */
2808 ALIAS (no_rip_default_metric
,
2809 no_rip_default_metric_val_cmd
,
2810 "no default-metric <1-16>",
2812 "Set a metric of redistribute routes\n"
2817 "timers basic <5-2147483647> <5-2147483647> <5-2147483647>",
2818 "Adjust routing timers\n"
2819 "Basic routing protocol update timers\n"
2820 "Routing table update timer value in second. Default is 30.\n"
2821 "Routing information timeout timer. Default is 180.\n"
2822 "Garbage collection timer. Default is 120.\n")
2824 unsigned long update
;
2825 unsigned long timeout
;
2826 unsigned long garbage
;
2827 char *endptr
= NULL
;
2828 unsigned long RIP_TIMER_MAX
= 2147483647;
2829 unsigned long RIP_TIMER_MIN
= 5;
2831 update
= strtoul (argv
[0], &endptr
, 10);
2832 if (update
> RIP_TIMER_MAX
|| update
< RIP_TIMER_MIN
|| *endptr
!= '\0')
2834 vty_out (vty
, "update timer value error%s", VTY_NEWLINE
);
2838 timeout
= strtoul (argv
[1], &endptr
, 10);
2839 if (timeout
> RIP_TIMER_MAX
|| timeout
< RIP_TIMER_MIN
|| *endptr
!= '\0')
2841 vty_out (vty
, "timeout timer value error%s", VTY_NEWLINE
);
2845 garbage
= strtoul (argv
[2], &endptr
, 10);
2846 if (garbage
> RIP_TIMER_MAX
|| garbage
< RIP_TIMER_MIN
|| *endptr
!= '\0')
2848 vty_out (vty
, "garbage timer value error%s", VTY_NEWLINE
);
2852 /* Set each timer value. */
2853 rip
->update_time
= update
;
2854 rip
->timeout_time
= timeout
;
2855 rip
->garbage_time
= garbage
;
2857 /* Reset update timer thread. */
2858 rip_event (RIP_UPDATE_EVENT
, 0);
2863 DEFUN (no_rip_timers
,
2867 "Adjust routing timers\n"
2868 "Basic routing protocol update timers\n")
2870 /* Set each timer value to the default. */
2871 rip
->update_time
= RIP_UPDATE_TIMER_DEFAULT
;
2872 rip
->timeout_time
= RIP_TIMEOUT_TIMER_DEFAULT
;
2873 rip
->garbage_time
= RIP_GARBAGE_TIMER_DEFAULT
;
2875 /* Reset update timer thread. */
2876 rip_event (RIP_UPDATE_EVENT
, 0);
2881 ALIAS (no_rip_timers
,
2882 no_rip_timers_val_cmd
,
2883 "no timers basic <0-65535> <0-65535> <0-65535>",
2885 "Adjust routing timers\n"
2886 "Basic routing protocol update timers\n"
2887 "Routing table update timer value in second. Default is 30.\n"
2888 "Routing information timeout timer. Default is 180.\n"
2889 "Garbage collection timer. Default is 120.\n")
2892 struct route_table
*rip_distance_table
;
2896 /* Distance value for the IP source prefix. */
2899 /* Name of the access-list to be matched. */
2903 struct rip_distance
*
2906 struct rip_distance
*new;
2907 new = XMALLOC (MTYPE_RIP_DISTANCE
, sizeof (struct rip_distance
));
2908 memset (new, 0, sizeof (struct rip_distance
));
2913 rip_distance_free (struct rip_distance
*rdistance
)
2915 XFREE (MTYPE_RIP_DISTANCE
, rdistance
);
2919 rip_distance_set (struct vty
*vty
, char *distance_str
, char *ip_str
,
2920 char *access_list_str
)
2923 struct prefix_ipv4 p
;
2925 struct route_node
*rn
;
2926 struct rip_distance
*rdistance
;
2928 ret
= str2prefix_ipv4 (ip_str
, &p
);
2931 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
2935 distance
= atoi (distance_str
);
2937 /* Get RIP distance node. */
2938 rn
= route_node_get (rip_distance_table
, (struct prefix
*) &p
);
2941 rdistance
= rn
->info
;
2942 route_unlock_node (rn
);
2946 rdistance
= rip_distance_new ();
2947 rn
->info
= rdistance
;
2950 /* Set distance value. */
2951 rdistance
->distance
= distance
;
2953 /* Reset access-list configuration. */
2954 if (rdistance
->access_list
)
2956 free (rdistance
->access_list
);
2957 rdistance
->access_list
= NULL
;
2959 if (access_list_str
)
2960 rdistance
->access_list
= strdup (access_list_str
);
2966 rip_distance_unset (struct vty
*vty
, char *distance_str
, char *ip_str
,
2967 char *access_list_str
)
2970 struct prefix_ipv4 p
;
2972 struct route_node
*rn
;
2973 struct rip_distance
*rdistance
;
2975 ret
= str2prefix_ipv4 (ip_str
, &p
);
2978 vty_out (vty
, "Malformed prefix%s", VTY_NEWLINE
);
2982 distance
= atoi (distance_str
);
2984 rn
= route_node_lookup (rip_distance_table
, (struct prefix
*)&p
);
2987 vty_out (vty
, "Can't find specified prefix%s", VTY_NEWLINE
);
2991 rdistance
= rn
->info
;
2993 if (rdistance
->access_list
)
2994 free (rdistance
->access_list
);
2995 rip_distance_free (rdistance
);
2998 route_unlock_node (rn
);
2999 route_unlock_node (rn
);
3005 rip_distance_reset ()
3007 struct route_node
*rn
;
3008 struct rip_distance
*rdistance
;
3010 for (rn
= route_top (rip_distance_table
); rn
; rn
= route_next (rn
))
3011 if ((rdistance
= rn
->info
) != NULL
)
3013 if (rdistance
->access_list
)
3014 free (rdistance
->access_list
);
3015 rip_distance_free (rdistance
);
3017 route_unlock_node (rn
);
3021 /* Apply RIP information to distance method. */
3023 rip_distance_apply (struct rip_info
*rinfo
)
3025 struct route_node
*rn
;
3026 struct prefix_ipv4 p
;
3027 struct rip_distance
*rdistance
;
3028 struct access_list
*alist
;
3033 memset (&p
, 0, sizeof (struct prefix_ipv4
));
3035 p
.prefix
= rinfo
->from
;
3036 p
.prefixlen
= IPV4_MAX_BITLEN
;
3038 /* Check source address. */
3039 rn
= route_node_match (rip_distance_table
, (struct prefix
*) &p
);
3042 rdistance
= rn
->info
;
3043 route_unlock_node (rn
);
3045 if (rdistance
->access_list
)
3047 alist
= access_list_lookup (AFI_IP
, rdistance
->access_list
);
3050 if (access_list_apply (alist
, &rinfo
->rp
->p
) == FILTER_DENY
)
3053 return rdistance
->distance
;
3056 return rdistance
->distance
;
3060 return rip
->distance
;
3066 rip_distance_show (struct vty
*vty
)
3068 struct route_node
*rn
;
3069 struct rip_distance
*rdistance
;
3073 vty_out (vty
, " Distance: (default is %d)%s",
3074 rip
->distance
? rip
->distance
:ZEBRA_RIP_DISTANCE_DEFAULT
,
3077 for (rn
= route_top (rip_distance_table
); rn
; rn
= route_next (rn
))
3078 if ((rdistance
= rn
->info
) != NULL
)
3082 vty_out (vty
, " Address Distance List%s",
3086 sprintf (buf
, "%s/%d", inet_ntoa (rn
->p
.u
.prefix4
), rn
->p
.prefixlen
);
3087 vty_out (vty
, " %-20s %4d %s%s",
3088 buf
, rdistance
->distance
,
3089 rdistance
->access_list
? rdistance
->access_list
: "",
3094 DEFUN (rip_distance
,
3097 "Administrative distance\n"
3100 rip
->distance
= atoi (argv
[0]);
3104 DEFUN (no_rip_distance
,
3105 no_rip_distance_cmd
,
3106 "no distance <1-255>",
3108 "Administrative distance\n"
3115 DEFUN (rip_distance_source
,
3116 rip_distance_source_cmd
,
3117 "distance <1-255> A.B.C.D/M",
3118 "Administrative distance\n"
3120 "IP source prefix\n")
3122 rip_distance_set (vty
, argv
[0], argv
[1], NULL
);
3126 DEFUN (no_rip_distance_source
,
3127 no_rip_distance_source_cmd
,
3128 "no distance <1-255> A.B.C.D/M",
3130 "Administrative distance\n"
3132 "IP source prefix\n")
3134 rip_distance_unset (vty
, argv
[0], argv
[1], NULL
);
3138 DEFUN (rip_distance_source_access_list
,
3139 rip_distance_source_access_list_cmd
,
3140 "distance <1-255> A.B.C.D/M WORD",
3141 "Administrative distance\n"
3143 "IP source prefix\n"
3144 "Access list name\n")
3146 rip_distance_set (vty
, argv
[0], argv
[1], argv
[2]);
3150 DEFUN (no_rip_distance_source_access_list
,
3151 no_rip_distance_source_access_list_cmd
,
3152 "no distance <1-255> A.B.C.D/M WORD",
3154 "Administrative distance\n"
3156 "IP source prefix\n"
3157 "Access list name\n")
3159 rip_distance_unset (vty
, argv
[0], argv
[1], argv
[2]);
3163 /* Print out routes update time. */
3165 rip_vty_out_uptime (struct vty
*vty
, struct rip_info
*rinfo
)
3167 struct timeval timer_now
;
3171 char timebuf
[TIME_BUF
];
3172 struct thread
*thread
;
3174 gettimeofday (&timer_now
, NULL
);
3176 if ((thread
= rinfo
->t_timeout
) != NULL
)
3178 clock
= thread
->u
.sands
.tv_sec
- timer_now
.tv_sec
;
3179 tm
= gmtime (&clock
);
3180 strftime (timebuf
, TIME_BUF
, "%M:%S", tm
);
3181 vty_out (vty
, "%5s", timebuf
);
3183 else if ((thread
= rinfo
->t_garbage_collect
) != NULL
)
3185 clock
= thread
->u
.sands
.tv_sec
- timer_now
.tv_sec
;
3186 tm
= gmtime (&clock
);
3187 strftime (timebuf
, TIME_BUF
, "%M:%S", tm
);
3188 vty_out (vty
, "%5s", timebuf
);
3193 rip_route_type_print (int sub_type
)
3199 case RIP_ROUTE_STATIC
:
3201 case RIP_ROUTE_DEFAULT
:
3203 case RIP_ROUTE_REDISTRIBUTE
:
3205 case RIP_ROUTE_INTERFACE
:
3217 "Show RIP routes\n")
3219 struct route_node
*np
;
3220 struct rip_info
*rinfo
;
3225 vty_out (vty
, "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP%s"
3227 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,%s"
3228 " (i) - interface%s%s"
3229 " Network Next Hop Metric From Tag Time%s",
3230 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
3232 for (np
= route_top (rip
->table
); np
; np
= route_next (np
))
3233 if ((rinfo
= np
->info
) != NULL
)
3237 len
= vty_out (vty
, "%s(%s) %s/%d",
3238 /* np->lock, For debugging. */
3239 route_info
[rinfo
->type
].str
,
3240 rip_route_type_print (rinfo
->sub_type
),
3241 inet_ntoa (np
->p
.u
.prefix4
), np
->p
.prefixlen
);
3246 vty_out (vty
, "%*s", len
, " ");
3248 if (rinfo
->nexthop
.s_addr
)
3249 vty_out (vty
, "%-20s %2d ", inet_ntoa (rinfo
->nexthop
),
3252 vty_out (vty
, "0.0.0.0 %2d ", rinfo
->metric
);
3254 /* Route which exist in kernel routing table. */
3255 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
) &&
3256 (rinfo
->sub_type
== RIP_ROUTE_RTE
))
3258 vty_out (vty
, "%-15s ", inet_ntoa (rinfo
->from
));
3259 vty_out (vty
, "%3d ", rinfo
->tag
);
3260 rip_vty_out_uptime (vty
, rinfo
);
3262 else if (rinfo
->metric
== RIP_METRIC_INFINITY
)
3264 vty_out (vty
, "self ");
3265 vty_out (vty
, "%3d ", rinfo
->tag
);
3266 rip_vty_out_uptime (vty
, rinfo
);
3270 vty_out (vty
, "self ");
3271 vty_out (vty
, "%3d", rinfo
->tag
);
3274 vty_out (vty
, "%s", VTY_NEWLINE
);
3279 /* Return next event time. */
3281 rip_next_thread_timer (struct thread
*thread
)
3283 struct timeval timer_now
;
3285 gettimeofday (&timer_now
, NULL
);
3287 return thread
->u
.sands
.tv_sec
- timer_now
.tv_sec
;
3290 /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3291 DEFUN (show_ip_rip_status
,
3292 show_ip_rip_status_cmd
,
3293 "show ip rip status",
3297 "IP routing protocol process parameters and statistics\n")
3300 struct interface
*ifp
;
3301 struct rip_interface
*ri
;
3302 extern struct message ri_version_msg
[];
3304 char *receive_version
;
3309 vty_out (vty
, "Routing Protocol is \"rip\"%s", VTY_NEWLINE
);
3310 vty_out (vty
, " Sending updates every %ld seconds with +/-50%%,",
3312 vty_out (vty
, " next due in %d seconds%s",
3313 rip_next_thread_timer (rip
->t_update
),
3315 vty_out (vty
, " Timeout after %ld seconds,", rip
->timeout_time
);
3316 vty_out (vty
, " garbage collect after %ld seconds%s", rip
->garbage_time
,
3319 /* Filtering status show. */
3320 config_show_distribute (vty
);
3322 /* Default metric information. */
3323 vty_out (vty
, " Default redistribution metric is %d%s",
3324 rip
->default_metric
, VTY_NEWLINE
);
3326 /* Redistribute information. */
3327 vty_out (vty
, " Redistributing:");
3328 config_write_rip_redistribute (vty
, 0);
3329 vty_out (vty
, "%s", VTY_NEWLINE
);
3331 vty_out (vty
, " Default version control: send version %d,", rip
->version
);
3332 vty_out (vty
, " receive version %d %s", rip
->version
,
3335 vty_out (vty
, " Interface Send Recv Key-chain%s", VTY_NEWLINE
);
3337 for (node
= listhead (iflist
); node
; node
= nextnode (node
))
3339 ifp
= getdata (node
);
3342 if (ri
->enable_network
|| ri
->enable_interface
)
3344 if (ri
->ri_send
== RI_RIP_UNSPEC
)
3345 send_version
= lookup (ri_version_msg
, rip
->version
);
3347 send_version
= lookup (ri_version_msg
, ri
->ri_send
);
3349 if (ri
->ri_receive
== RI_RIP_UNSPEC
)
3350 receive_version
= lookup (ri_version_msg
, rip
->version
);
3352 receive_version
= lookup (ri_version_msg
, ri
->ri_receive
);
3354 vty_out (vty
, " %-17s%-3s %-3s %s%s", ifp
->name
,
3357 ri
->key_chain
? ri
->key_chain
: "",
3362 vty_out (vty
, " Routing for Networks:%s", VTY_NEWLINE
);
3363 config_write_rip_network (vty
, 0);
3365 vty_out (vty
, " Routing Information Sources:%s", VTY_NEWLINE
);
3366 vty_out (vty
, " Gateway BadPackets BadRoutes Distance Last Update%s", VTY_NEWLINE
);
3367 rip_peer_display (vty
);
3369 rip_distance_show (vty
);
3374 /* RIP configuration write function. */
3376 config_write_rip (struct vty
*vty
)
3379 struct route_node
*rn
;
3380 struct rip_distance
*rdistance
;
3384 /* Router RIP statement. */
3385 vty_out (vty
, "router rip%s", VTY_NEWLINE
);
3388 /* RIP version statement. Default is RIP version 2. */
3389 if (rip
->version
!= RIPv2
)
3390 vty_out (vty
, " version %d%s", rip
->version
,
3393 /* RIP timer configuration. */
3394 if (rip
->update_time
!= RIP_UPDATE_TIMER_DEFAULT
3395 || rip
->timeout_time
!= RIP_TIMEOUT_TIMER_DEFAULT
3396 || rip
->garbage_time
!= RIP_GARBAGE_TIMER_DEFAULT
)
3397 vty_out (vty
, " timers basic %lu %lu %lu%s",
3403 /* Default information configuration. */
3404 if (rip
->default_information
)
3406 if (rip
->default_information_route_map
)
3407 vty_out (vty
, " default-information originate route-map %s%s",
3408 rip
->default_information_route_map
, VTY_NEWLINE
);
3410 vty_out (vty
, " default-information originate%s",
3414 /* Redistribute configuration. */
3415 config_write_rip_redistribute (vty
, 1);
3417 /* RIP offset-list configuration. */
3418 config_write_rip_offset_list (vty
);
3420 /* RIP enabled network and interface configuration. */
3421 config_write_rip_network (vty
, 1);
3423 /* RIP default metric configuration */
3424 if (rip
->default_metric
!= RIP_DEFAULT_METRIC_DEFAULT
)
3425 vty_out (vty
, " default-metric %d%s",
3426 rip
->default_metric
, VTY_NEWLINE
);
3428 /* Distribute configuration. */
3429 write
+= config_write_distribute (vty
);
3431 /* Interface routemap configuration */
3432 write
+= config_write_if_rmap (vty
);
3434 /* Distance configuration. */
3436 vty_out (vty
, " distance %d%s", rip
->distance
, VTY_NEWLINE
);
3438 /* RIP source IP prefix distance configuration. */
3439 for (rn
= route_top (rip_distance_table
); rn
; rn
= route_next (rn
))
3440 if ((rdistance
= rn
->info
) != NULL
)
3441 vty_out (vty
, " distance %d %s/%d %s%s", rdistance
->distance
,
3442 inet_ntoa (rn
->p
.u
.prefix4
), rn
->p
.prefixlen
,
3443 rdistance
->access_list
? rdistance
->access_list
: "",
3446 /* RIP static route configuration. */
3447 for (rn
= route_top (rip
->route
); rn
; rn
= route_next (rn
))
3449 vty_out (vty
, " route %s/%d%s",
3450 inet_ntoa (rn
->p
.u
.prefix4
),
3458 /* RIP node structure. */
3459 struct cmd_node rip_node
=
3462 "%s(config-router)# ",
3466 /* Distribute-list update functions. */
3468 rip_distribute_update (struct distribute
*dist
)
3470 struct interface
*ifp
;
3471 struct rip_interface
*ri
;
3472 struct access_list
*alist
;
3473 struct prefix_list
*plist
;
3478 ifp
= if_lookup_by_name (dist
->ifname
);
3484 if (dist
->list
[DISTRIBUTE_IN
])
3486 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_IN
]);
3488 ri
->list
[RIP_FILTER_IN
] = alist
;
3490 ri
->list
[RIP_FILTER_IN
] = NULL
;
3493 ri
->list
[RIP_FILTER_IN
] = NULL
;
3495 if (dist
->list
[DISTRIBUTE_OUT
])
3497 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_OUT
]);
3499 ri
->list
[RIP_FILTER_OUT
] = alist
;
3501 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3504 ri
->list
[RIP_FILTER_OUT
] = NULL
;
3506 if (dist
->prefix
[DISTRIBUTE_IN
])
3508 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_IN
]);
3510 ri
->prefix
[RIP_FILTER_IN
] = plist
;
3512 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3515 ri
->prefix
[RIP_FILTER_IN
] = NULL
;
3517 if (dist
->prefix
[DISTRIBUTE_OUT
])
3519 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_OUT
]);
3521 ri
->prefix
[RIP_FILTER_OUT
] = plist
;
3523 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3526 ri
->prefix
[RIP_FILTER_OUT
] = NULL
;
3530 rip_distribute_update_interface (struct interface
*ifp
)
3532 struct distribute
*dist
;
3534 dist
= distribute_lookup (ifp
->name
);
3536 rip_distribute_update (dist
);
3539 /* Update all interface's distribute list. */
3541 rip_distribute_update_all ()
3543 struct interface
*ifp
;
3546 for (node
= listhead (iflist
); node
; nextnode (node
))
3548 ifp
= getdata (node
);
3549 rip_distribute_update_interface (ifp
);
3553 /* Delete all added rip route. */
3558 struct route_node
*rp
;
3559 struct rip_info
*rinfo
;
3563 /* Clear RIP routes */
3564 for (rp
= route_top (rip
->table
); rp
; rp
= route_next (rp
))
3565 if ((rinfo
= rp
->info
) != NULL
)
3567 if (rinfo
->type
== ZEBRA_ROUTE_RIP
&&
3568 rinfo
->sub_type
== RIP_ROUTE_RTE
)
3569 rip_zebra_ipv4_delete ((struct prefix_ipv4
*)&rp
->p
,
3570 &rinfo
->nexthop
, rinfo
->metric
);
3572 RIP_TIMER_OFF (rinfo
->t_timeout
);
3573 RIP_TIMER_OFF (rinfo
->t_garbage_collect
);
3576 route_unlock_node (rp
);
3578 rip_info_free (rinfo
);
3581 /* Cancel RIP related timers. */
3582 RIP_TIMER_OFF (rip
->t_update
);
3583 RIP_TIMER_OFF (rip
->t_triggered_update
);
3584 RIP_TIMER_OFF (rip
->t_triggered_interval
);
3586 /* Cancel read thread. */
3589 thread_cancel (rip
->t_read
);
3593 /* Close RIP socket. */
3600 /* Static RIP route configuration. */
3601 for (rp
= route_top (rip
->route
); rp
; rp
= route_next (rp
))
3605 route_unlock_node (rp
);
3608 /* RIP neighbor configuration. */
3609 for (rp
= route_top (rip
->neighbor
); rp
; rp
= route_next (rp
))
3613 route_unlock_node (rp
);
3616 /* Redistribute related clear. */
3617 if (rip
->default_information_route_map
)
3618 free (rip
->default_information_route_map
);
3620 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3621 if (rip
->route_map
[i
].name
)
3622 free (rip
->route_map
[i
].name
);
3624 XFREE (MTYPE_ROUTE_TABLE
, rip
->table
);
3625 XFREE (MTYPE_ROUTE_TABLE
, rip
->route
);
3626 XFREE (MTYPE_ROUTE_TABLE
, rip
->neighbor
);
3628 XFREE (MTYPE_RIP
, rip
);
3632 rip_clean_network ();
3633 rip_passive_interface_clean ();
3634 rip_offset_clean ();
3635 rip_interface_clean ();
3636 rip_distance_reset ();
3637 rip_redistribute_clean ();
3640 /* Reset all values to the default settings. */
3644 /* Reset global counters. */
3645 rip_global_route_changes
= 0;
3646 rip_global_queries
= 0;
3648 /* Call ripd related reset functions. */
3650 rip_route_map_reset ();
3652 /* Call library reset functions. */
3654 access_list_reset ();
3655 prefix_list_reset ();
3657 distribute_list_reset ();
3659 rip_interface_reset ();
3660 rip_distance_reset ();
3662 rip_zclient_reset ();
3666 rip_if_rmap_update (struct if_rmap
*if_rmap
)
3668 struct interface
*ifp
;
3669 struct rip_interface
*ri
;
3670 struct route_map
*rmap
;
3672 ifp
= if_lookup_by_name (if_rmap
->ifname
);
3678 if (if_rmap
->routemap
[IF_RMAP_IN
])
3680 rmap
= route_map_lookup_by_name (if_rmap
->routemap
[IF_RMAP_IN
]);
3682 ri
->routemap
[IF_RMAP_IN
] = rmap
;
3684 ri
->routemap
[IF_RMAP_IN
] = NULL
;
3687 ri
->routemap
[RIP_FILTER_IN
] = NULL
;
3689 if (if_rmap
->routemap
[IF_RMAP_OUT
])
3691 rmap
= route_map_lookup_by_name (if_rmap
->routemap
[IF_RMAP_OUT
]);
3693 ri
->routemap
[IF_RMAP_OUT
] = rmap
;
3695 ri
->routemap
[IF_RMAP_OUT
] = NULL
;
3698 ri
->routemap
[RIP_FILTER_OUT
] = NULL
;
3702 rip_if_rmap_update_interface (struct interface
*ifp
)
3704 struct if_rmap
*if_rmap
;
3706 if_rmap
= if_rmap_lookup (ifp
->name
);
3708 rip_if_rmap_update (if_rmap
);
3712 rip_routemap_update_redistribute (void)
3718 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3720 if (rip
->route_map
[i
].name
)
3721 rip
->route_map
[i
].map
=
3722 route_map_lookup_by_name (rip
->route_map
[i
].name
);
3728 rip_routemap_update ()
3730 struct interface
*ifp
;
3733 for (node
= listhead (iflist
); node
; nextnode (node
))
3735 ifp
= getdata (node
);
3736 rip_if_rmap_update_interface (ifp
);
3739 rip_routemap_update_redistribute ();
3742 /* Allocate new rip structure and set default value. */
3746 /* Randomize for triggered update random(). */
3747 srand (time (NULL
));
3749 /* Install top nodes. */
3750 install_node (&rip_node
, config_write_rip
);
3752 /* Install rip commands. */
3753 install_element (VIEW_NODE
, &show_ip_rip_cmd
);
3754 install_element (VIEW_NODE
, &show_ip_rip_status_cmd
);
3755 install_element (ENABLE_NODE
, &show_ip_rip_cmd
);
3756 install_element (ENABLE_NODE
, &show_ip_rip_status_cmd
);
3757 install_element (CONFIG_NODE
, &router_rip_cmd
);
3758 install_element (CONFIG_NODE
, &no_router_rip_cmd
);
3760 install_default (RIP_NODE
);
3761 install_element (RIP_NODE
, &rip_version_cmd
);
3762 install_element (RIP_NODE
, &no_rip_version_cmd
);
3763 install_element (RIP_NODE
, &no_rip_version_val_cmd
);
3764 install_element (RIP_NODE
, &rip_default_metric_cmd
);
3765 install_element (RIP_NODE
, &no_rip_default_metric_cmd
);
3766 install_element (RIP_NODE
, &no_rip_default_metric_val_cmd
);
3767 install_element (RIP_NODE
, &rip_timers_cmd
);
3768 install_element (RIP_NODE
, &no_rip_timers_cmd
);
3769 install_element (RIP_NODE
, &no_rip_timers_val_cmd
);
3770 install_element (RIP_NODE
, &rip_route_cmd
);
3771 install_element (RIP_NODE
, &no_rip_route_cmd
);
3772 install_element (RIP_NODE
, &rip_distance_cmd
);
3773 install_element (RIP_NODE
, &no_rip_distance_cmd
);
3774 install_element (RIP_NODE
, &rip_distance_source_cmd
);
3775 install_element (RIP_NODE
, &no_rip_distance_source_cmd
);
3776 install_element (RIP_NODE
, &rip_distance_source_access_list_cmd
);
3777 install_element (RIP_NODE
, &no_rip_distance_source_access_list_cmd
);
3779 /* Debug related init. */
3785 #endif /* HAVE_SNMP */
3787 /* Access list install. */
3788 access_list_init ();
3789 access_list_add_hook (rip_distribute_update_all
);
3790 access_list_delete_hook (rip_distribute_update_all
);
3792 /* Prefix list initialize.*/
3793 prefix_list_init ();
3794 prefix_list_add_hook (rip_distribute_update_all
);
3795 prefix_list_delete_hook (rip_distribute_update_all
);
3797 /* Distribute list install. */
3798 distribute_list_init (RIP_NODE
);
3799 distribute_list_add_hook (rip_distribute_update
);
3800 distribute_list_delete_hook (rip_distribute_update
);
3803 rip_route_map_init ();
3806 route_map_add_hook (rip_routemap_update
);
3807 route_map_delete_hook (rip_routemap_update
);
3809 if_rmap_init (RIP_NODE
);
3810 if_rmap_hook_add (rip_if_rmap_update
);
3811 if_rmap_hook_delete (rip_if_rmap_update
);
3813 /* Distance control. */
3814 rip_distance_table
= route_table_init ();