]> git.proxmox.com Git - mirror_frr.git/blame - ripd/ripd.c
bgpd: improve default shutdown help string
[mirror_frr.git] / ripd / ripd.c
CommitLineData
718e3744 1/* RIP version 1 and 2.
fbf5d033 2 * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
718e3744 3 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro <kunihiro@zebra.org>
4 *
5 * This file is part of GNU Zebra.
6 *
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
10 * later version.
11 *
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.
16 *
896014f4
DL
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
718e3744 20 */
21
22#include <zebra.h>
23
b2d7c082 24#include "vrf.h"
718e3744 25#include "if.h"
26#include "command.h"
27#include "prefix.h"
28#include "table.h"
29#include "thread.h"
30#include "memory.h"
31#include "log.h"
32#include "stream.h"
33#include "filter.h"
34#include "sockunion.h"
1af81933 35#include "sockopt.h"
718e3744 36#include "routemap.h"
16705130 37#include "if_rmap.h"
718e3744 38#include "plist.h"
39#include "distribute.h"
c1a03d47 40#include "md5.h"
718e3744 41#include "keychain.h"
edd7c245 42#include "privs.h"
718e3744 43
44#include "ripd/ripd.h"
45#include "ripd/rip_debug.h"
46
f6eacff4
DL
47DEFINE_QOBJ_TYPE(rip)
48
0b3acf4f 49/* UDP receive buffer size */
50#define RIP_UDP_RCV_BUF 41600
51
718e3744 52/* RIP Structure. */
53struct rip *rip = NULL;
54
55/* RIP neighbor address table. */
56struct route_table *rip_neighbor_table;
57
58/* RIP route changes. */
59long rip_global_route_changes = 0;
60
61/* RIP queries. */
62long rip_global_queries = 0;
6b0655a2 63
718e3744 64/* Prototypes. */
d62a17ae 65static void rip_event(enum rip_event, int);
66static void rip_output_process(struct connected *, struct sockaddr_in *, int,
67 u_char);
68static int rip_triggered_update(struct thread *);
69static int rip_update_jitter(unsigned long);
6b0655a2 70
718e3744 71/* RIP output routes type. */
d62a17ae 72enum { rip_all_route, rip_changed_route };
6b0655a2 73
718e3744 74/* RIP command strings. */
d62a17ae 75static const struct message rip_msg[] = {{RIP_REQUEST, "REQUEST"},
76 {RIP_RESPONSE, "RESPONSE"},
77 {RIP_TRACEON, "TRACEON"},
78 {RIP_TRACEOFF, "TRACEOFF"},
79 {RIP_POLL, "POLL"},
80 {RIP_POLL_ENTRY, "POLL ENTRY"},
81 {0}};
6b0655a2 82
718e3744 83/* Utility function to set boradcast option to the socket. */
d62a17ae 84static int sockopt_broadcast(int sock)
718e3744 85{
d62a17ae 86 int ret;
87 int on = 1;
718e3744 88
d62a17ae 89 ret = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&on,
90 sizeof on);
91 if (ret < 0) {
92 zlog_warn("can't set sockopt SO_BROADCAST to socket %d", sock);
93 return -1;
94 }
95 return 0;
718e3744 96}
97
d62a17ae 98static int rip_route_rte(struct rip_info *rinfo)
718e3744 99{
d62a17ae 100 return (rinfo->type == ZEBRA_ROUTE_RIP
101 && rinfo->sub_type == RIP_ROUTE_RTE);
718e3744 102}
103
d62a17ae 104static struct rip_info *rip_info_new(void)
718e3744 105{
d62a17ae 106 return XCALLOC(MTYPE_RIP_INFO, sizeof(struct rip_info));
718e3744 107}
108
d62a17ae 109void rip_info_free(struct rip_info *rinfo)
718e3744 110{
d62a17ae 111 XFREE(MTYPE_RIP_INFO, rinfo);
718e3744 112}
113
114/* RIP route garbage collect timer. */
d62a17ae 115static int rip_garbage_collect(struct thread *t)
718e3744 116{
d62a17ae 117 struct rip_info *rinfo;
118 struct route_node *rp;
119
120 rinfo = THREAD_ARG(t);
121 rinfo->t_garbage_collect = NULL;
718e3744 122
d62a17ae 123 /* Off timeout timer. */
124 RIP_TIMER_OFF(rinfo->t_timeout);
718e3744 125
d62a17ae 126 /* Get route_node pointer. */
127 rp = rinfo->rp;
718e3744 128
d62a17ae 129 /* Unlock route_node. */
130 listnode_delete(rp->info, rinfo);
131 if (list_isempty((struct list *)rp->info)) {
acdf5e25 132 list_delete_and_null((struct list **)&rp->info);
d62a17ae 133 route_unlock_node(rp);
134 }
718e3744 135
d62a17ae 136 /* Free RIP routing information. */
137 rip_info_free(rinfo);
718e3744 138
d62a17ae 139 return 0;
718e3744 140}
141
d62a17ae 142static void rip_timeout_update(struct rip_info *rinfo);
bce8e868
LF
143
144/* Add new route to the ECMP list.
8478ae7e
LF
145 * RETURN: the new entry added in the list, or NULL if it is not the first
146 * entry and ECMP is not allowed.
bce8e868 147 */
d62a17ae 148struct rip_info *rip_ecmp_add(struct rip_info *rinfo_new)
718e3744 149{
d62a17ae 150 struct route_node *rp = rinfo_new->rp;
151 struct rip_info *rinfo = NULL;
152 struct list *list = NULL;
718e3744 153
d62a17ae 154 if (rp->info == NULL)
155 rp->info = list_new();
156 list = (struct list *)rp->info;
bce8e868 157
d62a17ae 158 /* If ECMP is not allowed and some entry already exists in the list,
159 * do nothing. */
160 if (listcount(list) && !rip->ecmp)
161 return NULL;
8478ae7e 162
d62a17ae 163 rinfo = rip_info_new();
164 memcpy(rinfo, rinfo_new, sizeof(struct rip_info));
165 listnode_add(list, rinfo);
bce8e868 166
d62a17ae 167 if (rip_route_rte(rinfo)) {
168 rip_timeout_update(rinfo);
169 rip_zebra_ipv4_add(rp);
170 }
bce8e868 171
d62a17ae 172 /* Set the route change flag on the first entry. */
173 rinfo = listgetdata(listhead(list));
174 SET_FLAG(rinfo->flags, RIP_RTF_CHANGED);
bce8e868 175
d62a17ae 176 /* Signal the output process to trigger an update (see section 2.5). */
177 rip_event(RIP_TRIGGERED_UPDATE, 0);
718e3744 178
d62a17ae 179 return rinfo;
bce8e868
LF
180}
181
182/* Replace the ECMP list with the new route.
183 * RETURN: the new entry added in the list
184 */
d62a17ae 185struct rip_info *rip_ecmp_replace(struct rip_info *rinfo_new)
186{
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;
191
192 if (list == NULL || listcount(list) == 0)
193 return rip_ecmp_add(rinfo_new);
194
195 /* Get the first entry */
196 rinfo = listgetdata(listhead(list));
197
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);
202
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);
210 }
718e3744 211
d62a17ae 212 RIP_TIMER_OFF(rinfo->t_timeout);
213 RIP_TIMER_OFF(rinfo->t_garbage_collect);
214 memcpy(rinfo, rinfo_new, sizeof(struct rip_info));
718e3744 215
d62a17ae 216 if (rip_route_rte(rinfo)) {
217 rip_timeout_update(rinfo);
218 /* The ADD message implies an update. */
219 rip_zebra_ipv4_add(rp);
220 }
718e3744 221
d62a17ae 222 /* Set the route change flag. */
223 SET_FLAG(rinfo->flags, RIP_RTF_CHANGED);
718e3744 224
d62a17ae 225 /* Signal the output process to trigger an update (see section 2.5). */
226 rip_event(RIP_TRIGGERED_UPDATE, 0);
718e3744 227
d62a17ae 228 return rinfo;
bce8e868
LF
229}
230
231/* Delete one route from the ECMP list.
232 * RETURN:
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
236 */
d62a17ae 237struct rip_info *rip_ecmp_delete(struct rip_info *rinfo)
238{
239 struct route_node *rp = rinfo->rp;
240 struct list *list = (struct list *)rp->info;
241
242 RIP_TIMER_OFF(rinfo->t_timeout);
243
244 if (listcount(list) > 1) {
245 /* Some other ECMP entries still exist. Just delete this entry.
246 */
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);
254 rinfo = NULL;
255 } else {
256 assert(rinfo == listgetdata(listhead(list)));
257
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.
260 */
261
262 rinfo->metric = RIP_METRIC_INFINITY;
263 RIP_TIMER_ON(rinfo->t_garbage_collect, rip_garbage_collect,
264 rip->garbage_time);
265
266 if (rip_route_rte(rinfo)
267 && CHECK_FLAG(rinfo->flags, RIP_RTF_FIB))
268 rip_zebra_ipv4_delete(rp);
269 }
bce8e868 270
d62a17ae 271 /* Set the route change flag on the first entry. */
272 rinfo = listgetdata(listhead(list));
273 SET_FLAG(rinfo->flags, RIP_RTF_CHANGED);
bce8e868 274
d62a17ae 275 /* Signal the output process to trigger an update (see section 2.5). */
276 rip_event(RIP_TRIGGERED_UPDATE, 0);
bce8e868 277
d62a17ae 278 return rinfo;
bce8e868
LF
279}
280
281/* Timeout RIP routes. */
d62a17ae 282static int rip_timeout(struct thread *t)
bce8e868 283{
d62a17ae 284 rip_ecmp_delete((struct rip_info *)THREAD_ARG(t));
285 return 0;
718e3744 286}
287
d62a17ae 288static void rip_timeout_update(struct rip_info *rinfo)
718e3744 289{
d62a17ae 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);
293 }
294}
295
296static int rip_filter(int rip_distribute, struct prefix_ipv4 *p,
297 struct rip_interface *ri)
298{
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
303 : DISTRIBUTE_V4_IN;
304 const char *inout = rip_distribute == RIP_FILTER_OUT ? "out" : "in";
305
306 /* Input distribute-list filtering. */
307 if (ri->list[rip_distribute]) {
308 if (access_list_apply(ri->list[rip_distribute],
309 (struct prefix *)p)
310 == FILTER_DENY) {
311 if (IS_RIP_DEBUG_PACKET)
312 zlog_debug("%s/%d filtered by distribute %s",
313 inet_ntoa(p->prefix), p->prefixlen,
314 inout);
315 return -1;
718e3744 316 }
718e3744 317 }
d62a17ae 318 if (ri->prefix[rip_distribute]) {
319 if (prefix_list_apply(ri->prefix[rip_distribute],
320 (struct prefix *)p)
321 == PREFIX_DENY) {
322 if (IS_RIP_DEBUG_PACKET)
323 zlog_debug("%s/%d filtered by prefix-list %s",
324 inet_ntoa(p->prefix), p->prefixlen,
325 inout);
326 return -1;
718e3744 327 }
718e3744 328 }
d62a17ae 329
330 /* All interface filter check. */
331 dist = distribute_lookup(NULL);
332 if (dist) {
333 if (dist->list[distribute]) {
334 alist = access_list_lookup(AFI_IP,
335 dist->list[distribute]);
336
337 if (alist) {
338 if (access_list_apply(alist, (struct prefix *)p)
339 == FILTER_DENY) {
340 if (IS_RIP_DEBUG_PACKET)
341 zlog_debug(
342 "%s/%d filtered by distribute %s",
343 inet_ntoa(p->prefix),
344 p->prefixlen, inout);
345 return -1;
346 }
347 }
348 }
349 if (dist->prefix[distribute]) {
350 plist = prefix_list_lookup(AFI_IP,
351 dist->prefix[distribute]);
352
353 if (plist) {
354 if (prefix_list_apply(plist, (struct prefix *)p)
355 == PREFIX_DENY) {
356 if (IS_RIP_DEBUG_PACKET)
357 zlog_debug(
358 "%s/%d filtered by prefix-list %s",
359 inet_ntoa(p->prefix),
360 p->prefixlen, inout);
361 return -1;
362 }
363 }
364 }
365 }
366 return 0;
718e3744 367}
368
369/* Check nexthop address validity. */
d62a17ae 370static int rip_nexthop_check(struct in_addr *addr)
718e3744 371{
f4e14fdb 372 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 373 struct interface *ifp;
f4e14fdb 374 struct listnode *cnode;
d62a17ae 375 struct connected *ifc;
376 struct prefix *p;
718e3744 377
d62a17ae 378 /* If nexthop address matches local configured address then it is
379 invalid nexthop. */
b2d7c082 380
451fda4f 381 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 382 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) {
383 p = ifc->address;
718e3744 384
d62a17ae 385 if (p->family == AF_INET
386 && IPV4_ADDR_SAME(&p->u.prefix4, addr))
387 return -1;
388 }
718e3744 389 }
d62a17ae 390 return 0;
718e3744 391}
392
393/* RIP add route to routing table. */
d62a17ae 394static void rip_rte_process(struct rte *rte, struct sockaddr_in *from,
395 struct interface *ifp)
396{
397 int ret;
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;
403 int same = 0;
404 unsigned char old_dist, new_dist;
405 struct list *list = NULL;
406 struct listnode *node = NULL;
407
408 /* Make prefix structure. */
409 memset(&p, 0, sizeof(struct prefix_ipv4));
410 p.family = AF_INET;
411 p.prefix = rte->prefix;
412 p.prefixlen = ip_masklen(rte->mask);
413
414 /* Make sure mask is applied. */
415 apply_mask_ipv4(&p);
416
417 /* Apply input filters. */
418 ri = ifp->info;
718e3744 419
d62a17ae 420 ret = rip_filter(RIP_FILTER_IN, &p, ri);
421 if (ret < 0)
422 return;
423
424 memset(&newinfo, 0, sizeof(newinfo));
425 newinfo.type = ZEBRA_ROUTE_RIP;
426 newinfo.sub_type = RIP_ROUTE_RTE;
dd127197 427 newinfo.nh.gate.ipv4 = rte->nexthop;
d62a17ae 428 newinfo.from = from->sin_addr;
dd127197
DS
429 newinfo.nh.ifindex = ifp->ifindex;
430 newinfo.nh.type = NEXTHOP_TYPE_IPV4_IFINDEX;
d62a17ae 431 newinfo.metric = rte->metric;
432 newinfo.metric_out = rte->metric; /* XXX */
433 newinfo.tag = ntohs(rte->tag); /* XXX */
434
435 /* Modify entry according to the interface routemap. */
436 if (ri->routemap[RIP_FILTER_IN]) {
437 int ret;
438
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);
442
443 if (ret == RMAP_DENYMATCH) {
444 if (IS_RIP_DEBUG_PACKET)
445 zlog_debug(
446 "RIP %s/%d is filtered by route-map in",
447 inet_ntoa(p.prefix), p.prefixlen);
448 return;
449 }
450
451 /* Get back the object */
452 rte->nexthop = newinfo.nexthop_out;
453 rte->tag = htons(newinfo.tag_out); /* XXX */
9d303b37
DL
454 rte->metric =
455 newinfo.metric_out; /* XXX: the routemap uses the
456 metric_out field */
d62a17ae 457 }
458
459 /* Once the entry has been validated, update the metric by
460 adding the cost of the network on wich the message
461 arrived. If the result is greater than infinity, use infinity
462 (RFC2453 Sec. 3.9.2) */
463 /* Zebra ripd can handle offset-list in. */
464 ret = rip_offset_list_apply_in(&p, ifp, &rte->metric);
718e3744 465
d62a17ae 466 /* If offset-list does not modify the metric use interface's
467 metric. */
468 if (!ret)
469 rte->metric += ifp->metric ? ifp->metric : 1;
718e3744 470
d62a17ae 471 if (rte->metric > RIP_METRIC_INFINITY)
472 rte->metric = RIP_METRIC_INFINITY;
473
474 /* Set nexthop pointer. */
475 if (rte->nexthop.s_addr == 0)
476 nexthop = &from->sin_addr;
477 else
478 nexthop = &rte->nexthop;
479
480 /* Check if nexthop address is myself, then do nothing. */
481 if (rip_nexthop_check(nexthop) < 0) {
482 if (IS_RIP_DEBUG_PACKET)
483 zlog_debug("Nexthop address %s is myself",
484 inet_ntoa(*nexthop));
485 return;
486 }
487
488 /* Get index for the prefix. */
489 rp = route_node_get(rip->table, (struct prefix *)&p);
490
491 newinfo.rp = rp;
dd127197
DS
492 newinfo.nh.gate.ipv4 = *nexthop;
493 newinfo.nh.type = NEXTHOP_TYPE_IPV4;
d62a17ae 494 newinfo.metric = rte->metric;
495 newinfo.tag = ntohs(rte->tag);
496 newinfo.distance = rip_distance_apply(&newinfo);
497
498 new_dist = newinfo.distance ? newinfo.distance
499 : ZEBRA_RIP_DISTANCE_DEFAULT;
500
501 /* Check to see whether there is already RIP route on the table. */
502 if ((list = rp->info) != NULL)
503 for (ALL_LIST_ELEMENTS_RO(list, node, rinfo)) {
504 /* Need to compare with redistributed entry or local
505 * entry */
506 if (!rip_route_rte(rinfo))
507 break;
508
509 if (IPV4_ADDR_SAME(&rinfo->from, &from->sin_addr)
dd127197 510 && IPV4_ADDR_SAME(&rinfo->nh.gate.ipv4, nexthop))
d62a17ae 511 break;
512
513 if (!listnextnode(node)) {
514 /* Not found in the list */
515
516 if (rte->metric > rinfo->metric) {
517 /* New route has a greater metric.
518 * Discard it. */
519 route_unlock_node(rp);
520 return;
521 }
522
523 if (rte->metric < rinfo->metric)
524 /* New route has a smaller metric.
525 * Replace the ECMP list
526 * with the new one in below. */
527 break;
528
529 /* Metrics are same. We compare the distances.
530 */
531 old_dist = rinfo->distance
532 ? rinfo->distance
533 : ZEBRA_RIP_DISTANCE_DEFAULT;
534
535 if (new_dist > old_dist) {
536 /* New route has a greater distance.
537 * Discard it. */
538 route_unlock_node(rp);
539 return;
540 }
541
542 if (new_dist < old_dist)
543 /* New route has a smaller distance.
544 * Replace the ECMP list
545 * with the new one in below. */
546 break;
547
548 /* Metrics and distances are both same. Keep
549 * "rinfo" null and
550 * the new route is added in the ECMP list in
551 * below. */
552 }
718e3744 553 }
d62a17ae 554
555 if (rinfo) {
556 /* Local static route. */
557 if (rinfo->type == ZEBRA_ROUTE_RIP
558 && ((rinfo->sub_type == RIP_ROUTE_STATIC)
559 || (rinfo->sub_type == RIP_ROUTE_DEFAULT))
560 && rinfo->metric != RIP_METRIC_INFINITY) {
561 route_unlock_node(rp);
562 return;
718e3744 563 }
d62a17ae 564
565 /* Redistributed route check. */
566 if (rinfo->type != ZEBRA_ROUTE_RIP
567 && rinfo->metric != RIP_METRIC_INFINITY) {
568 old_dist = rinfo->distance;
569 /* Only routes directly connected to an interface
570 * (nexthop == 0)
571 * may have a valid NULL distance */
dd127197 572 if (rinfo->nh.gate.ipv4.s_addr != 0)
d62a17ae 573 old_dist = old_dist
574 ? old_dist
575 : ZEBRA_RIP_DISTANCE_DEFAULT;
576 /* If imported route does not have STRICT precedence,
577 mark it as a ghost */
578 if (new_dist <= old_dist
579 && rte->metric != RIP_METRIC_INFINITY)
580 rip_ecmp_replace(&newinfo);
581
582 route_unlock_node(rp);
583 return;
718e3744 584 }
d62a17ae 585 }
586
587 if (!rinfo) {
588 if (rp->info)
589 route_unlock_node(rp);
590
591 /* Now, check to see whether there is already an explicit route
592 for the destination prefix. If there is no such route, add
593 this route to the routing table, unless the metric is
594 infinity (there is no point in adding a route which
595 unusable). */
596 if (rte->metric != RIP_METRIC_INFINITY)
597 rip_ecmp_add(&newinfo);
598 } else {
599 /* Route is there but we are not sure the route is RIP or not.
600 */
601
602 /* If there is an existing route, compare the next hop address
603 to the address of the router from which the datagram came.
604 If this datagram is from the same router as the existing
605 route, reinitialize the timeout. */
606 same = (IPV4_ADDR_SAME(&rinfo->from, &from->sin_addr)
dd127197 607 && (rinfo->nh.ifindex == ifp->ifindex));
d62a17ae 608
609 old_dist = rinfo->distance ? rinfo->distance
610 : ZEBRA_RIP_DISTANCE_DEFAULT;
611
612 /* Next, compare the metrics. If the datagram is from the same
613 router as the existing route, and the new metric is different
614 than the old one; or, if the new metric is lower than the old
615 one, or if the tag has been changed; or if there is a route
616 with a lower administrave distance; or an update of the
617 distance on the actual route; do the following actions: */
618 if ((same && rinfo->metric != rte->metric)
619 || (rte->metric < rinfo->metric)
620 || ((same) && (rinfo->metric == rte->metric)
621 && (newinfo.tag != rinfo->tag))
622 || (old_dist > new_dist)
623 || ((old_dist != new_dist) && same)) {
624 if (listcount(list) == 1) {
625 if (newinfo.metric != RIP_METRIC_INFINITY)
626 rip_ecmp_replace(&newinfo);
627 else
628 rip_ecmp_delete(rinfo);
629 } else {
630 if (newinfo.metric < rinfo->metric)
631 rip_ecmp_replace(&newinfo);
632 else if (newinfo.metric > rinfo->metric)
633 rip_ecmp_delete(rinfo);
634 else if (new_dist < old_dist)
635 rip_ecmp_replace(&newinfo);
636 else if (new_dist > old_dist)
637 rip_ecmp_delete(rinfo);
638 else {
639 int update = CHECK_FLAG(rinfo->flags,
640 RIP_RTF_FIB)
641 ? 1
642 : 0;
643
644 assert(newinfo.metric
645 != RIP_METRIC_INFINITY);
646
647 RIP_TIMER_OFF(rinfo->t_timeout);
648 RIP_TIMER_OFF(rinfo->t_garbage_collect);
649 memcpy(rinfo, &newinfo,
650 sizeof(struct rip_info));
651 rip_timeout_update(rinfo);
652
653 if (update)
654 rip_zebra_ipv4_add(rp);
655
656 /* - Set the route change flag on the
657 * first entry. */
658 rinfo = listgetdata(listhead(list));
659 SET_FLAG(rinfo->flags, RIP_RTF_CHANGED);
660 rip_event(RIP_TRIGGERED_UPDATE, 0);
661 }
662 }
663 } else /* same & no change */
664 rip_timeout_update(rinfo);
665
666 /* Unlock tempolary lock of the route. */
667 route_unlock_node(rp);
668 }
669}
670
671/* Dump RIP packet */
672static void rip_packet_dump(struct rip_packet *packet, int size,
673 const char *sndrcv)
674{
675 caddr_t lim;
676 struct rte *rte;
677 const char *command_str;
678 char pbuf[BUFSIZ], nbuf[BUFSIZ];
679 u_char netmask = 0;
680 u_char *p;
681
682 /* Set command string. */
683 if (packet->command > 0 && packet->command < RIP_COMMAND_MAX)
684 command_str = lookup_msg(rip_msg, packet->command, NULL);
685 else
686 command_str = "unknown";
687
688 /* Dump packet header. */
689 zlog_debug("%s %s version %d packet size %d", sndrcv, command_str,
690 packet->version, size);
691
692 /* Dump each routing table entry. */
693 rte = packet->rte;
694
695 for (lim = (caddr_t)packet + size; (caddr_t)rte < lim; rte++) {
696 if (packet->version == RIPv2) {
697 netmask = ip_masklen(rte->mask);
698
699 if (rte->family == htons(RIP_FAMILY_AUTH)) {
700 if (rte->tag
701 == htons(RIP_AUTH_SIMPLE_PASSWORD)) {
702 p = (u_char *)&rte->prefix;
703
704 zlog_debug(
705 " family 0x%X type %d auth string: %s",
706 ntohs(rte->family),
707 ntohs(rte->tag), p);
708 } else if (rte->tag == htons(RIP_AUTH_MD5)) {
709 struct rip_md5_info *md5;
710
711 md5 = (struct rip_md5_info *)&packet
712 ->rte;
713
714 zlog_debug(
715 " family 0x%X type %d (MD5 authentication)",
716 ntohs(md5->family),
717 ntohs(md5->type));
718 zlog_debug(
719 " RIP-2 packet len %d Key ID %d"
720 " Auth Data len %d",
721 ntohs(md5->packet_len),
722 md5->keyid, md5->auth_len);
723 zlog_debug(
724 " Sequence Number %ld",
725 (u_long)ntohl(md5->sequence));
726 } else if (rte->tag == htons(RIP_AUTH_DATA)) {
727 p = (u_char *)&rte->prefix;
728
729 zlog_debug(
730 " family 0x%X type %d (MD5 data)",
731 ntohs(rte->family),
732 ntohs(rte->tag));
733 zlog_debug(
734 " MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
735 "%02X%02X%02X%02X%02X%02X%02X%02X",
736 p[0], p[1], p[2], p[3], p[4],
737 p[5], p[6], p[7], p[8], p[9],
738 p[10], p[11], p[12], p[13],
739 p[14], p[15]);
740 } else {
741 zlog_debug(
742 " family 0x%X type %d (Unknown auth type)",
743 ntohs(rte->family),
744 ntohs(rte->tag));
745 }
746 } else
747 zlog_debug(
748 " %s/%d -> %s family %d tag %" ROUTE_TAG_PRI
749 " metric %ld",
750 inet_ntop(AF_INET, &rte->prefix, pbuf,
751 BUFSIZ),
752 netmask,
753 inet_ntop(AF_INET, &rte->nexthop, nbuf,
754 BUFSIZ),
755 ntohs(rte->family),
756 (route_tag_t)ntohs(rte->tag),
757 (u_long)ntohl(rte->metric));
758 } else {
759 zlog_debug(
760 " %s family %d tag %" ROUTE_TAG_PRI
761 " metric %ld",
762 inet_ntop(AF_INET, &rte->prefix, pbuf, BUFSIZ),
763 ntohs(rte->family),
764 (route_tag_t)ntohs(rte->tag),
765 (u_long)ntohl(rte->metric));
718e3744 766 }
718e3744 767 }
718e3744 768}
769
770/* Check if the destination address is valid (unicast; not net 0
771 or 127) (RFC2453 Section 3.9.2 - Page 26). But we don't
772 check net 0 because we accept default route. */
d62a17ae 773static int rip_destination_check(struct in_addr addr)
718e3744 774{
d62a17ae 775 u_int32_t destination;
718e3744 776
d62a17ae 777 /* Convert to host byte order. */
778 destination = ntohl(addr.s_addr);
718e3744 779
d62a17ae 780 if (IPV4_NET127(destination))
781 return 0;
718e3744 782
d62a17ae 783 /* Net 0 may match to the default route. */
784 if (IPV4_NET0(destination) && destination != 0)
785 return 0;
718e3744 786
d62a17ae 787 /* Unicast address must belong to class A, B, C. */
788 if (IN_CLASSA(destination))
789 return 1;
790 if (IN_CLASSB(destination))
791 return 1;
792 if (IN_CLASSC(destination))
793 return 1;
718e3744 794
d62a17ae 795 return 0;
718e3744 796}
797
798/* RIP version 2 authentication. */
d62a17ae 799static int rip_auth_simple_password(struct rte *rte, struct sockaddr_in *from,
800 struct interface *ifp)
801{
802 struct rip_interface *ri;
803 char *auth_str = (char *)&rte->prefix;
804 int i;
805
806 /* reject passwords with zeros in the middle of the string */
807 for (i = strlen(auth_str); i < 16; i++) {
808 if (auth_str[i] != '\0')
809 return 0;
810 }
811
812 if (IS_RIP_DEBUG_EVENT)
813 zlog_debug("RIPv2 simple password authentication from %s",
814 inet_ntoa(from->sin_addr));
815
816 ri = ifp->info;
817
818 if (ri->auth_type != RIP_AUTH_SIMPLE_PASSWORD
819 || rte->tag != htons(RIP_AUTH_SIMPLE_PASSWORD))
820 return 0;
718e3744 821
d62a17ae 822 /* Simple password authentication. */
823 if (ri->auth_str) {
824 if (strncmp(auth_str, ri->auth_str, 16) == 0)
825 return 1;
826 }
827 if (ri->key_chain) {
828 struct keychain *keychain;
829 struct key *key;
830
831 keychain = keychain_lookup(ri->key_chain);
832 if (keychain == NULL)
833 return 0;
834
835 key = key_match_for_accept(keychain, auth_str);
836 if (key)
837 return 1;
838 }
839 return 0;
718e3744 840}
841
842/* RIP version 2 authentication with MD5. */
d62a17ae 843static int rip_auth_md5(struct rip_packet *packet, struct sockaddr_in *from,
844 int length, struct interface *ifp)
845{
846 struct rip_interface *ri;
847 struct rip_md5_info *md5;
848 struct rip_md5_data *md5data;
849 struct keychain *keychain;
850 struct key *key;
851 MD5_CTX ctx;
852 u_char digest[RIP_AUTH_MD5_SIZE];
853 u_int16_t packet_len;
854 char auth_str[RIP_AUTH_MD5_SIZE];
855
856 if (IS_RIP_DEBUG_EVENT)
857 zlog_debug("RIPv2 MD5 authentication from %s",
858 inet_ntoa(from->sin_addr));
718e3744 859
d62a17ae 860 ri = ifp->info;
861 md5 = (struct rip_md5_info *)&packet->rte;
862
863 /* Check auth type. */
864 if (ri->auth_type != RIP_AUTH_MD5 || md5->type != htons(RIP_AUTH_MD5))
865 return 0;
866
867 /* If the authentication length is less than 16, then it must be wrong
868 * for
869 * any interpretation of rfc2082. Some implementations also interpret
870 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka
871 * RIP_AUTH_MD5_COMPAT_SIZE.
872 */
873 if (!((md5->auth_len == RIP_AUTH_MD5_SIZE)
874 || (md5->auth_len == RIP_AUTH_MD5_COMPAT_SIZE))) {
875 if (IS_RIP_DEBUG_EVENT)
876 zlog_debug(
877 "RIPv2 MD5 authentication, strange authentication "
878 "length field %d",
879 md5->auth_len);
880 return 0;
881 }
882
883 /* grab and verify check packet length */
884 packet_len = ntohs(md5->packet_len);
718e3744 885
d62a17ae 886 if (packet_len > (length - RIP_HEADER_SIZE - RIP_AUTH_MD5_SIZE)) {
887 if (IS_RIP_DEBUG_EVENT)
888 zlog_debug(
889 "RIPv2 MD5 authentication, packet length field %d "
890 "greater than received length %d!",
891 md5->packet_len, length);
892 return 0;
893 }
894
895 /* retrieve authentication data */
896 md5data = (struct rip_md5_data *)(((u_char *)packet) + packet_len);
897
898 memset(auth_str, 0, RIP_AUTH_MD5_SIZE);
899
900 if (ri->key_chain) {
901 keychain = keychain_lookup(ri->key_chain);
902 if (keychain == NULL)
903 return 0;
904
905 key = key_lookup_for_accept(keychain, md5->keyid);
906 if (key == NULL)
907 return 0;
908
909 strncpy(auth_str, key->string, RIP_AUTH_MD5_SIZE);
910 } else if (ri->auth_str)
911 strncpy(auth_str, ri->auth_str, RIP_AUTH_MD5_SIZE);
912
913 if (auth_str[0] == 0)
914 return 0;
915
916 /* MD5 digest authentication. */
917 memset(&ctx, 0, sizeof(ctx));
918 MD5Init(&ctx);
919 MD5Update(&ctx, packet, packet_len + RIP_HEADER_SIZE);
920 MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE);
921 MD5Final(digest, &ctx);
922
923 if (memcmp(md5data->digest, digest, RIP_AUTH_MD5_SIZE) == 0)
924 return packet_len;
925 else
926 return 0;
718e3744 927}
928
b14ee00b 929/* Pick correct auth string for sends, prepare auth_str buffer for use.
930 * (left justified and padded).
931 *
932 * presumes one of ri or key is valid, and that the auth strings they point
933 * to are nul terminated. If neither are present, auth_str will be fully
934 * zero padded.
935 *
936 */
d62a17ae 937static void rip_auth_prepare_str_send(struct rip_interface *ri, struct key *key,
938 char *auth_str, int len)
718e3744 939{
d62a17ae 940 assert(ri || key);
718e3744 941
d62a17ae 942 memset(auth_str, 0, len);
943 if (key && key->string)
944 strncpy(auth_str, key->string, len);
945 else if (ri->auth_str)
946 strncpy(auth_str, ri->auth_str, len);
718e3744 947
d62a17ae 948 return;
b14ee00b 949}
718e3744 950
b14ee00b 951/* Write RIPv2 simple password authentication information
952 *
d62a17ae 953 * auth_str is presumed to be 2 bytes and correctly prepared
b14ee00b 954 * (left justified and zero padded).
955 */
d62a17ae 956static void rip_auth_simple_write(struct stream *s, char *auth_str, int len)
b14ee00b 957{
d62a17ae 958 assert(s && len == RIP_AUTH_SIMPLE_SIZE);
959
960 stream_putw(s, RIP_FAMILY_AUTH);
961 stream_putw(s, RIP_AUTH_SIMPLE_PASSWORD);
962 stream_put(s, auth_str, RIP_AUTH_SIMPLE_SIZE);
963
964 return;
b14ee00b 965}
718e3744 966
d62a17ae 967/* write RIPv2 MD5 "authentication header"
b14ee00b 968 * (uses the auth key data field)
969 *
970 * Digest offset field is set to 0.
971 *
972 * returns: offset of the digest offset field, which must be set when
973 * length to the auth-data MD5 digest is known.
974 */
d62a17ae 975static size_t rip_auth_md5_ah_write(struct stream *s, struct rip_interface *ri,
976 struct key *key)
977{
978 size_t doff = 0;
979
980 assert(s && ri && ri->auth_type == RIP_AUTH_MD5);
981
982 /* MD5 authentication. */
983 stream_putw(s, RIP_FAMILY_AUTH);
984 stream_putw(s, RIP_AUTH_MD5);
985
986 /* MD5 AH digest offset field.
987 *
988 * Set to placeholder value here, to true value when RIP-2 Packet length
989 * is known. Actual value is set in .....().
990 */
991 doff = stream_get_endp(s);
992 stream_putw(s, 0);
993
994 /* Key ID. */
995 if (key)
996 stream_putc(s, key->index % 256);
997 else
998 stream_putc(s, 1);
999
1000 /* Auth Data Len. Set 16 for MD5 authentication data. Older ripds
1001 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for
1002 * this
1003 * to be configurable.
1004 */
1005 stream_putc(s, ri->md5_auth_len);
1006
1007 /* Sequence Number (non-decreasing). */
1008 /* RFC2080: The value used in the sequence number is
1009 arbitrary, but two suggestions are the time of the
1010 message's creation or a simple message counter. */
1011 stream_putl(s, time(NULL));
1012
1013 /* Reserved field must be zero. */
1014 stream_putl(s, 0);
1015 stream_putl(s, 0);
1016
1017 return doff;
b14ee00b 1018}
1019
1020/* If authentication is in used, write the appropriate header
1021 * returns stream offset to which length must later be written
1022 * or 0 if this is not required
1023 */
d62a17ae 1024static size_t rip_auth_header_write(struct stream *s, struct rip_interface *ri,
1025 struct key *key, char *auth_str, int len)
1026{
1027 assert(ri->auth_type != RIP_NO_AUTH);
1028
1029 switch (ri->auth_type) {
1030 case RIP_AUTH_SIMPLE_PASSWORD:
1031 rip_auth_prepare_str_send(ri, key, auth_str, len);
1032 rip_auth_simple_write(s, auth_str, len);
1033 return 0;
1034 case RIP_AUTH_MD5:
1035 return rip_auth_md5_ah_write(s, ri, key);
1036 }
1037 assert(1);
1038 return 0;
b14ee00b 1039}
1040
1041/* Write RIPv2 MD5 authentication data trailer */
d62a17ae 1042static void rip_auth_md5_set(struct stream *s, struct rip_interface *ri,
1043 size_t doff, char *auth_str, int authlen)
1044{
1045 unsigned long len;
1046 MD5_CTX ctx;
1047 unsigned char digest[RIP_AUTH_MD5_SIZE];
1048
1049 /* Make it sure this interface is configured as MD5
1050 authentication. */
1051 assert((ri->auth_type == RIP_AUTH_MD5)
1052 && (authlen == RIP_AUTH_MD5_SIZE));
1053 assert(doff > 0);
1054
1055 /* Get packet length. */
1056 len = stream_get_endp(s);
1057
1058 /* Check packet length. */
1059 if (len < (RIP_HEADER_SIZE + RIP_RTE_SIZE)) {
1060 zlog_err(
1061 "rip_auth_md5_set(): packet length %ld is less than minimum length.",
1062 len);
1063 return;
1064 }
1065
1066 /* Set the digest offset length in the header */
1067 stream_putw_at(s, doff, len);
1068
1069 /* Set authentication data. */
1070 stream_putw(s, RIP_FAMILY_AUTH);
1071 stream_putw(s, RIP_AUTH_DATA);
1072
1073 /* Generate a digest for the RIP packet. */
1074 memset(&ctx, 0, sizeof(ctx));
1075 MD5Init(&ctx);
1076 MD5Update(&ctx, STREAM_DATA(s), stream_get_endp(s));
1077 MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE);
1078 MD5Final(digest, &ctx);
1079
1080 /* Copy the digest to the packet. */
1081 stream_write(s, digest, RIP_AUTH_MD5_SIZE);
718e3744 1082}
1083
1084/* RIP routing information. */
d62a17ae 1085static void rip_response_process(struct rip_packet *packet, int size,
1086 struct sockaddr_in *from,
1087 struct connected *ifc)
1088{
1089 caddr_t lim;
1090 struct rte *rte;
1091 struct prefix_ipv4 ifaddr;
1092 struct prefix_ipv4 ifaddrclass;
1093 int subnetted;
1094
1095 memset(&ifaddr, 0, sizeof(ifaddr));
1096 /* We don't know yet. */
1097 subnetted = -1;
1098
1099 /* The Response must be ignored if it is not from the RIP
1100 port. (RFC2453 - Sec. 3.9.2)*/
1101 if (from->sin_port != htons(RIP_PORT_DEFAULT)) {
1102 zlog_info("response doesn't come from RIP port: %d",
1103 from->sin_port);
1104 rip_peer_bad_packet(from);
1105 return;
718e3744 1106 }
1107
d62a17ae 1108 /* The datagram's IPv4 source address should be checked to see
1109 whether the datagram is from a valid neighbor; the source of the
1110 datagram must be on a directly connected network (RFC2453 - Sec.
1111 3.9.2) */
1112 if (if_lookup_address((void *)&from->sin_addr, AF_INET, VRF_DEFAULT)
1113 == NULL) {
1114 zlog_info(
1115 "This datagram doesn't came from a valid neighbor: %s",
1116 inet_ntoa(from->sin_addr));
1117 rip_peer_bad_packet(from);
1118 return;
718e3744 1119 }
1120
d62a17ae 1121 /* It is also worth checking to see whether the response is from one
1122 of the router's own addresses. */
1123
1124 ; /* Alredy done in rip_read () */
1125
1126 /* Update RIP peer. */
1127 rip_peer_update(from, packet->version);
1128
1129 /* Set RTE pointer. */
1130 rte = packet->rte;
1131
1132 for (lim = (caddr_t)packet + size; (caddr_t)rte < lim; rte++) {
1133 /* RIPv2 authentication check. */
1134 /* If the Address Family Identifier of the first (and only the
1135 first) entry in the message is 0xFFFF, then the remainder of
1136 the entry contains the authentication. */
1137 /* If the packet gets here it means authentication enabled */
1138 /* Check is done in rip_read(). So, just skipping it */
1139 if (packet->version == RIPv2 && rte == packet->rte
1140 && rte->family == htons(RIP_FAMILY_AUTH))
1141 continue;
1142
1143 if (rte->family != htons(AF_INET)) {
1144 /* Address family check. RIP only supports AF_INET. */
1145 zlog_info("Unsupported family %d from %s.",
1146 ntohs(rte->family),
1147 inet_ntoa(from->sin_addr));
1148 continue;
718e3744 1149 }
d62a17ae 1150
1151 /* - is the destination address valid (e.g., unicast; not net 0
1152 or 127) */
1153 if (!rip_destination_check(rte->prefix)) {
1154 zlog_info(
1155 "Network is net 0 or net 127 or it is not unicast network");
1156 rip_peer_bad_route(from);
1157 continue;
718e3744 1158 }
1159
d62a17ae 1160 /* Convert metric value to host byte order. */
1161 rte->metric = ntohl(rte->metric);
718e3744 1162
d62a17ae 1163 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1164 if (!(rte->metric >= 1 && rte->metric <= 16)) {
1165 zlog_info("Route's metric is not in the 1-16 range.");
1166 rip_peer_bad_route(from);
1167 continue;
1168 }
718e3744 1169
d62a17ae 1170 /* RIPv1 does not have nexthop value. */
1171 if (packet->version == RIPv1 && rte->nexthop.s_addr != 0) {
1172 zlog_info("RIPv1 packet with nexthop value %s",
1173 inet_ntoa(rte->nexthop));
1174 rip_peer_bad_route(from);
1175 continue;
1176 }
718e3744 1177
d62a17ae 1178 /* That is, if the provided information is ignored, a possibly
1179 sub-optimal, but absolutely valid, route may be taken. If
1180 the received Next Hop is not directly reachable, it should be
1181 treated as 0.0.0.0. */
1182 if (packet->version == RIPv2 && rte->nexthop.s_addr != 0) {
1183 u_int32_t addrval;
1184
1185 /* Multicast address check. */
1186 addrval = ntohl(rte->nexthop.s_addr);
1187 if (IN_CLASSD(addrval)) {
1188 zlog_info(
1189 "Nexthop %s is multicast address, skip this rte",
1190 inet_ntoa(rte->nexthop));
1191 continue;
1192 }
1193
1194 if (!if_lookup_address((void *)&rte->nexthop, AF_INET,
1195 VRF_DEFAULT)) {
1196 struct route_node *rn;
1197 struct rip_info *rinfo;
1198
1199 rn = route_node_match_ipv4(rip->table,
1200 &rte->nexthop);
1201
1202 if (rn) {
1203 rinfo = rn->info;
1204
1205 if (rinfo->type == ZEBRA_ROUTE_RIP
1206 && rinfo->sub_type
1207 == RIP_ROUTE_RTE) {
1208 if (IS_RIP_DEBUG_EVENT)
1209 zlog_debug(
1210 "Next hop %s is on RIP network. Set nexthop to the packet's originator",
1211 inet_ntoa(
1212 rte->nexthop));
1213 rte->nexthop = rinfo->from;
1214 } else {
1215 if (IS_RIP_DEBUG_EVENT)
1216 zlog_debug(
1217 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1218 inet_ntoa(
1219 rte->nexthop));
1220 rte->nexthop.s_addr = 0;
1221 }
1222
1223 route_unlock_node(rn);
1224 } else {
1225 if (IS_RIP_DEBUG_EVENT)
1226 zlog_debug(
1227 "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
1228 inet_ntoa(
1229 rte->nexthop));
1230 rte->nexthop.s_addr = 0;
1231 }
1232 }
1233 }
718e3744 1234
d62a17ae 1235 /* For RIPv1, there won't be a valid netmask.
1236
1237 This is a best guess at the masks. If everyone was using old
1238 Ciscos before the 'ip subnet zero' option, it would be almost
1239 right too :-)
1240
1241 Cisco summarize ripv1 advertisments to the classful boundary
1242 (/16 for class B's) except when the RIP packet does to inside
1243 the classful network in question. */
1244
1245 if ((packet->version == RIPv1 && rte->prefix.s_addr != 0)
1246 || (packet->version == RIPv2
1247 && (rte->prefix.s_addr != 0
1248 && rte->mask.s_addr == 0))) {
1249 u_int32_t destination;
1250
1251 if (subnetted == -1) {
1252 memcpy(&ifaddr, ifc->address,
1253 sizeof(struct prefix_ipv4));
1254 memcpy(&ifaddrclass, &ifaddr,
1255 sizeof(struct prefix_ipv4));
1256 apply_classful_mask_ipv4(&ifaddrclass);
1257 subnetted = 0;
1258 if (ifaddr.prefixlen > ifaddrclass.prefixlen)
1259 subnetted = 1;
1260 }
1261
1262 destination = ntohl(rte->prefix.s_addr);
1263
1264 if (IN_CLASSA(destination))
1265 masklen2ip(8, &rte->mask);
1266 else if (IN_CLASSB(destination))
1267 masklen2ip(16, &rte->mask);
1268 else if (IN_CLASSC(destination))
1269 masklen2ip(24, &rte->mask);
1270
1271 if (subnetted == 1)
1272 masklen2ip(ifaddrclass.prefixlen,
1273 (struct in_addr *)&destination);
1274 if ((subnetted == 1)
1275 && ((rte->prefix.s_addr & destination)
1276 == ifaddrclass.prefix.s_addr)) {
1277 masklen2ip(ifaddr.prefixlen, &rte->mask);
1278 if ((rte->prefix.s_addr & rte->mask.s_addr)
1279 != rte->prefix.s_addr)
1280 masklen2ip(32, &rte->mask);
1281 if (IS_RIP_DEBUG_EVENT)
1282 zlog_debug("Subnetted route %s",
1283 inet_ntoa(rte->prefix));
1284 } else {
1285 if ((rte->prefix.s_addr & rte->mask.s_addr)
1286 != rte->prefix.s_addr)
1287 continue;
1288 }
1289
1290 if (IS_RIP_DEBUG_EVENT) {
1291 zlog_debug("Resultant route %s",
1292 inet_ntoa(rte->prefix));
1293 zlog_debug("Resultant mask %s",
1294 inet_ntoa(rte->mask));
1295 }
1296 }
1297
1298 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1299 ignore the entry. */
1300 if ((packet->version == RIPv2) && (rte->mask.s_addr != 0)
1301 && ((rte->prefix.s_addr & rte->mask.s_addr)
1302 != rte->prefix.s_addr)) {
1303 zlog_warn(
1304 "RIPv2 address %s is not mask /%d applied one",
1305 inet_ntoa(rte->prefix), ip_masklen(rte->mask));
1306 rip_peer_bad_route(from);
1307 continue;
1308 }
1309
1310 /* Default route's netmask is ignored. */
1311 if (packet->version == RIPv2 && (rte->prefix.s_addr == 0)
1312 && (rte->mask.s_addr != 0)) {
1313 if (IS_RIP_DEBUG_EVENT)
1314 zlog_debug(
1315 "Default route with non-zero netmask. Set zero to netmask");
1316 rte->mask.s_addr = 0;
1317 }
1318
1319 /* Routing table updates. */
1320 rip_rte_process(rte, from, ifc->ifp);
718e3744 1321 }
718e3744 1322}
1323
a4e987e0 1324/* Make socket for RIP protocol. */
d62a17ae 1325static int rip_create_socket(void)
1326{
1327 int ret;
1328 int sock;
1329 struct sockaddr_in addr;
1330
1331 memset(&addr, 0, sizeof(struct sockaddr_in));
1332 addr.sin_family = AF_INET;
1333 addr.sin_addr.s_addr = INADDR_ANY;
6f0e3f6e 1334#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
d62a17ae 1335 addr.sin_len = sizeof(struct sockaddr_in);
6f0e3f6e 1336#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
d62a17ae 1337 /* sending port must always be the RIP port */
1338 addr.sin_port = htons(RIP_PORT_DEFAULT);
1339
1340 /* Make datagram socket. */
1341 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1342 if (sock < 0) {
1343 zlog_err("Cannot create UDP socket: %s", safe_strerror(errno));
1344 exit(1);
1345 }
1346
1347 sockopt_broadcast(sock);
1348 sockopt_reuseaddr(sock);
1349 sockopt_reuseport(sock);
1350 setsockopt_ipv4_multicast_loop(sock, 0);
a4e987e0 1351#ifdef RIP_RECVMSG
d62a17ae 1352 setsockopt_pktinfo(sock);
a4e987e0 1353#endif /* RIP_RECVMSG */
78b31d5c 1354#ifdef IPTOS_PREC_INTERNETCONTROL
d62a17ae 1355 setsockopt_ipv4_tos(sock, IPTOS_PREC_INTERNETCONTROL);
78b31d5c 1356#endif
a4e987e0 1357
d62a17ae 1358 if (ripd_privs.change(ZPRIVS_RAISE))
1359 zlog_err("rip_create_socket: could not raise privs");
1360 setsockopt_so_recvbuf(sock, RIP_UDP_RCV_BUF);
1361 if ((ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr))) < 0)
1362
1363 {
1364 int save_errno = errno;
1365 if (ripd_privs.change(ZPRIVS_LOWER))
1366 zlog_err("rip_create_socket: could not lower privs");
1367
1368 zlog_err("%s: Can't bind socket %d to %s port %d: %s", __func__,
1369 sock, inet_ntoa(addr.sin_addr),
1370 (int)ntohs(addr.sin_port), safe_strerror(save_errno));
1371
1372 close(sock);
1373 return ret;
1374 }
1375
1376 if (ripd_privs.change(ZPRIVS_LOWER))
1377 zlog_err("rip_create_socket: could not lower privs");
1378
1379 return sock;
a4e987e0 1380}
1381
c49ad8f1 1382/* RIP packet send to destination address, on interface denoted by
1383 * by connected argument. NULL to argument denotes destination should be
1384 * should be RIP multicast group
1385 */
d62a17ae 1386static int rip_send_packet(u_char *buf, int size, struct sockaddr_in *to,
1387 struct connected *ifc)
1388{
1389 int ret;
1390 struct sockaddr_in sin;
1391
1392 assert(ifc != NULL);
1393
1394 if (IS_RIP_DEBUG_PACKET) {
f69bd9da 1395#define ADDRESS_SIZE 20
d62a17ae 1396 char dst[ADDRESS_SIZE];
1397 dst[ADDRESS_SIZE - 1] = '\0';
1398
1399 if (to) {
1400 strncpy(dst, inet_ntoa(to->sin_addr), ADDRESS_SIZE - 1);
1401 } else {
1402 sin.sin_addr.s_addr = htonl(INADDR_RIP_GROUP);
1403 strncpy(dst, inet_ntoa(sin.sin_addr), ADDRESS_SIZE - 1);
1404 }
f69bd9da 1405#undef ADDRESS_SIZE
d62a17ae 1406 zlog_debug("rip_send_packet %s > %s (%s)",
1407 inet_ntoa(ifc->address->u.prefix4), dst,
1408 ifc->ifp->name);
1409 }
1410
1411 if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)) {
1412 /*
1413 * ZEBRA_IFA_SECONDARY is set on linux when an interface is
1414 * configured
1415 * with multiple addresses on the same subnet: the first address
1416 * on the subnet is configured "primary", and all subsequent
1417 * addresses
1418 * on that subnet are treated as "secondary" addresses.
1419 * In order to avoid routing-table bloat on other rip listeners,
1420 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY
1421 * source addrs.
1422 * XXX Since Linux is the only system for which the
1423 * ZEBRA_IFA_SECONDARY
1424 * flag is set, we would end up sending a packet for a
1425 * "secondary"
1426 * source address on non-linux systems.
1427 */
1428 if (IS_RIP_DEBUG_PACKET)
1429 zlog_debug("duplicate dropped");
1430 return 0;
1431 }
1432
1433 /* Make destination address. */
1434 memset(&sin, 0, sizeof(struct sockaddr_in));
1435 sin.sin_family = AF_INET;
6f0e3f6e 1436#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
d62a17ae 1437 sin.sin_len = sizeof(struct sockaddr_in);
6f0e3f6e 1438#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
718e3744 1439
d62a17ae 1440 /* When destination is specified, use it's port and address. */
1441 if (to) {
1442 sin.sin_port = to->sin_port;
1443 sin.sin_addr = to->sin_addr;
1444 } else {
1445 sin.sin_port = htons(RIP_PORT_DEFAULT);
1446 sin.sin_addr.s_addr = htonl(INADDR_RIP_GROUP);
ae735d2d 1447
d62a17ae 1448 rip_interface_multicast_set(rip->sock, ifc);
1449 }
718e3744 1450
d62a17ae 1451 ret = sendto(rip->sock, buf, size, 0, (struct sockaddr *)&sin,
1452 sizeof(struct sockaddr_in));
718e3744 1453
d62a17ae 1454 if (IS_RIP_DEBUG_EVENT)
1455 zlog_debug("SEND to %s.%d", inet_ntoa(sin.sin_addr),
1456 ntohs(sin.sin_port));
718e3744 1457
d62a17ae 1458 if (ret < 0)
1459 zlog_warn("can't send packet : %s", safe_strerror(errno));
718e3744 1460
d62a17ae 1461 return ret;
718e3744 1462}
1463
1464/* Add redistributed route to RIP table. */
d62a17ae 1465void rip_redistribute_add(int type, int sub_type, struct prefix_ipv4 *p,
3f5682c8 1466 struct nexthop *nh,
d62a17ae 1467 unsigned int metric, unsigned char distance,
1468 route_tag_t tag)
1469{
1470 int ret;
1471 struct route_node *rp = NULL;
1472 struct rip_info *rinfo = NULL, newinfo;
1473 struct list *list = NULL;
1474
1475 /* Redistribute route */
1476 ret = rip_destination_check(p->prefix);
1477 if (!ret)
1478 return;
1479
1480 rp = route_node_get(rip->table, (struct prefix *)p);
1481
1482 memset(&newinfo, 0, sizeof(struct rip_info));
1483 newinfo.type = type;
1484 newinfo.sub_type = sub_type;
d62a17ae 1485 newinfo.metric = 1;
1486 newinfo.external_metric = metric;
1487 newinfo.distance = distance;
1488 if (tag <= UINT16_MAX) /* RIP only supports 16 bit tags */
1489 newinfo.tag = tag;
1490 newinfo.rp = rp;
3f5682c8 1491 newinfo.nh = *nh;
d62a17ae 1492
1493 if ((list = rp->info) != NULL && listcount(list) != 0) {
1494 rinfo = listgetdata(listhead(list));
1495
1496 if (rinfo->type == ZEBRA_ROUTE_CONNECT
1497 && rinfo->sub_type == RIP_ROUTE_INTERFACE
1498 && rinfo->metric != RIP_METRIC_INFINITY) {
1499 route_unlock_node(rp);
1500 return;
1501 }
718e3744 1502
d62a17ae 1503 /* Manually configured RIP route check. */
1504 if (rinfo->type == ZEBRA_ROUTE_RIP
1505 && ((rinfo->sub_type == RIP_ROUTE_STATIC)
1506 || (rinfo->sub_type == RIP_ROUTE_DEFAULT))) {
1507 if (type != ZEBRA_ROUTE_RIP
1508 || ((sub_type != RIP_ROUTE_STATIC)
1509 && (sub_type != RIP_ROUTE_DEFAULT))) {
1510 route_unlock_node(rp);
1511 return;
1512 }
1513 }
1514
11ff7164 1515 (void)rip_ecmp_replace(&newinfo);
d62a17ae 1516 route_unlock_node(rp);
1517 } else
11ff7164 1518 (void)rip_ecmp_add(&newinfo);
d62a17ae 1519
1520 if (IS_RIP_DEBUG_EVENT) {
3f5682c8
DS
1521 zlog_debug(
1522 "Redistribute new prefix %s/%d",
1523 inet_ntoa(p->prefix), p->prefixlen);
718e3744 1524 }
1525
d62a17ae 1526 rip_event(RIP_TRIGGERED_UPDATE, 0);
718e3744 1527}
1528
1529/* Delete redistributed route from RIP table. */
d62a17ae 1530void rip_redistribute_delete(int type, int sub_type, struct prefix_ipv4 *p,
1531 ifindex_t ifindex)
1532{
1533 int ret;
1534 struct route_node *rp;
1535 struct rip_info *rinfo;
1536
1537 ret = rip_destination_check(p->prefix);
1538 if (!ret)
1539 return;
1540
1541 rp = route_node_lookup(rip->table, (struct prefix *)p);
1542 if (rp) {
1543 struct list *list = rp->info;
1544
1545 if (list != NULL && listcount(list) != 0) {
1546 rinfo = listgetdata(listhead(list));
1547 if (rinfo != NULL && rinfo->type == type
1548 && rinfo->sub_type == sub_type
dd127197 1549 && rinfo->nh.ifindex == ifindex) {
d62a17ae 1550 /* Perform poisoned reverse. */
1551 rinfo->metric = RIP_METRIC_INFINITY;
1552 RIP_TIMER_ON(rinfo->t_garbage_collect,
1553 rip_garbage_collect,
1554 rip->garbage_time);
1555 RIP_TIMER_OFF(rinfo->t_timeout);
1556 rinfo->flags |= RIP_RTF_CHANGED;
1557
1558 if (IS_RIP_DEBUG_EVENT)
1559 zlog_debug(
14aa0c3d 1560 "Poison %s/%d on the interface %s with an "
d62a17ae 1561 "infinity metric [delete]",
1562 inet_ntoa(p->prefix),
1563 p->prefixlen,
1564 ifindex2ifname(ifindex,
1565 VRF_DEFAULT));
1566
1567 rip_event(RIP_TRIGGERED_UPDATE, 0);
1568 }
1569 }
1570 route_unlock_node(rp);
1571 }
718e3744 1572}
1573
1574/* Response to request called from rip_read ().*/
d62a17ae 1575static void rip_request_process(struct rip_packet *packet, int size,
1576 struct sockaddr_in *from, struct connected *ifc)
1577{
1578 caddr_t lim;
1579 struct rte *rte;
1580 struct prefix_ipv4 p;
1581 struct route_node *rp;
1582 struct rip_info *rinfo;
1583 struct rip_interface *ri;
1584
1585 /* Does not reponse to the requests on the loopback interfaces */
1586 if (if_is_loopback(ifc->ifp))
1587 return;
1588
1589 /* Check RIP process is enabled on this interface. */
1590 ri = ifc->ifp->info;
1591 if (!ri->running)
1592 return;
1593
1594 /* When passive interface is specified, suppress responses */
1595 if (ri->passive)
1596 return;
1597
1598 /* RIP peer update. */
1599 rip_peer_update(from, packet->version);
1600
1601 lim = ((caddr_t)packet) + size;
1602 rte = packet->rte;
1603
1604 /* The Request is processed entry by entry. If there are no
1605 entries, no response is given. */
1606 if (lim == (caddr_t)rte)
1607 return;
1608
1609 /* There is one special case. If there is exactly one entry in the
1610 request, and it has an address family identifier of zero and a
1611 metric of infinity (i.e., 16), then this is a request to send the
1612 entire routing table. */
1613 if (lim == ((caddr_t)(rte + 1)) && ntohs(rte->family) == 0
1614 && ntohl(rte->metric) == RIP_METRIC_INFINITY) {
1615 /* All route with split horizon */
1616 rip_output_process(ifc, from, rip_all_route, packet->version);
1617 } else {
1618 if (ntohs(rte->family) != AF_INET)
1619 return;
1620
1621 /* Examine the list of RTEs in the Request one by one. For each
1622 entry, look up the destination in the router's routing
1623 database and, if there is a route, put that route's metric in
1624 the metric field of the RTE. If there is no explicit route
1625 to the specified destination, put infinity in the metric
1626 field. Once all the entries have been filled in, change the
1627 command from Request to Response and send the datagram back
1628 to the requestor. */
1629 p.family = AF_INET;
1630
1631 for (; ((caddr_t)rte) < lim; rte++) {
1632 p.prefix = rte->prefix;
1633 p.prefixlen = ip_masklen(rte->mask);
1634 apply_mask_ipv4(&p);
1635
1636 rp = route_node_lookup(rip->table, (struct prefix *)&p);
1637 if (rp) {
1638 rinfo = listgetdata(
1639 listhead((struct list *)rp->info));
1640 rte->metric = htonl(rinfo->metric);
1641 route_unlock_node(rp);
1642 } else
1643 rte->metric = htonl(RIP_METRIC_INFINITY);
1644 }
1645 packet->command = RIP_RESPONSE;
4e054866 1646
d62a17ae 1647 rip_send_packet((u_char *)packet, size, from, ifc);
1648 }
1649 rip_global_queries++;
718e3744 1650}
1651
1652#if RIP_RECVMSG
1653/* Set IPv6 packet info to the socket. */
d62a17ae 1654static int setsockopt_pktinfo(int sock)
718e3744 1655{
d62a17ae 1656 int ret;
1657 int val = 1;
1658
1659 ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val));
1660 if (ret < 0)
1661 zlog_warn("Can't setsockopt IP_PKTINFO : %s",
1662 safe_strerror(errno));
1663 return ret;
718e3744 1664}
1665
1666/* Read RIP packet by recvmsg function. */
d62a17ae 1667int rip_recvmsg(int sock, u_char *buf, int size, struct sockaddr_in *from,
1668 ifindex_t *ifindex)
1669{
1670 int ret;
1671 struct msghdr msg;
1672 struct iovec iov;
1673 struct cmsghdr *ptr;
1674 char adata[1024];
1675
0af35d90 1676 memset(&msg, 0, sizeof(msg));
d62a17ae 1677 msg.msg_name = (void *)from;
1678 msg.msg_namelen = sizeof(struct sockaddr_in);
1679 msg.msg_iov = &iov;
1680 msg.msg_iovlen = 1;
1681 msg.msg_control = (void *)adata;
1682 msg.msg_controllen = sizeof adata;
1683 iov.iov_base = buf;
1684 iov.iov_len = size;
1685
1686 ret = recvmsg(sock, &msg, 0);
1687 if (ret < 0)
1688 return ret;
718e3744 1689
d62a17ae 1690 for (ptr = ZCMSG_FIRSTHDR(&msg); ptr != NULL;
1691 ptr = CMSG_NXTHDR(&msg, ptr))
1692 if (ptr->cmsg_level == IPPROTO_IP
1693 && ptr->cmsg_type == IP_PKTINFO) {
1694 struct in_pktinfo *pktinfo;
1695 int i;
1696
1697 pktinfo = (struct in_pktinfo *)CMSG_DATA(ptr);
1698 i = pktinfo->ipi_ifindex;
1699 }
1700 return ret;
718e3744 1701}
1702
1703/* RIP packet read function. */
d62a17ae 1704int rip_read_new(struct thread *t)
1705{
1706 int ret;
1707 int sock;
1708 char buf[RIP_PACKET_MAXSIZ];
1709 struct sockaddr_in from;
1710 ifindex_t ifindex;
1711
1712 /* Fetch socket then register myself. */
1713 sock = THREAD_FD(t);
1714 rip_event(RIP_READ, sock);
1715
1716 /* Read RIP packet. */
1717 ret = rip_recvmsg(sock, buf, RIP_PACKET_MAXSIZ, &from, (int *)&ifindex);
1718 if (ret < 0) {
1719 zlog_warn("Can't read RIP packet: %s", safe_strerror(errno));
1720 return ret;
1721 }
1722
1723 return ret;
718e3744 1724}
1725#endif /* RIP_RECVMSG */
1726
1727/* First entry point of RIP packet. */
d62a17ae 1728static int rip_read(struct thread *t)
1729{
1730 int sock;
1731 int ret;
1732 int rtenum;
1733 union rip_buf rip_buf;
1734 struct rip_packet *packet;
1735 struct sockaddr_in from;
1736 int len;
1737 int vrecv;
1738 socklen_t fromlen;
1739 struct interface *ifp = NULL;
1740 struct connected *ifc;
1741 struct rip_interface *ri;
1742 struct prefix p;
1743
1744 /* Fetch socket then register myself. */
1745 sock = THREAD_FD(t);
1746 rip->t_read = NULL;
1747
1748 /* Add myself to tne next event */
1749 rip_event(RIP_READ, sock);
1750
1751 /* RIPd manages only IPv4. */
1752 memset(&from, 0, sizeof(struct sockaddr_in));
1753 fromlen = sizeof(struct sockaddr_in);
1754
1755 len = recvfrom(sock, (char *)&rip_buf.buf, sizeof(rip_buf.buf), 0,
1756 (struct sockaddr *)&from, &fromlen);
1757 if (len < 0) {
1758 zlog_info("recvfrom failed: %s", safe_strerror(errno));
1759 return len;
1760 }
1761
1762 /* Check is this packet comming from myself? */
1763 if (if_check_address(from.sin_addr)) {
1764 if (IS_RIP_DEBUG_PACKET)
1765 zlog_debug("ignore packet comes from myself");
1766 return -1;
1767 }
1768
1769 /* Which interface is this packet comes from. */
1770 ifc = if_lookup_address((void *)&from.sin_addr, AF_INET, VRF_DEFAULT);
1771 if (ifc)
1772 ifp = ifc->ifp;
1773
1774 /* RIP packet received */
1775 if (IS_RIP_DEBUG_EVENT)
1776 zlog_debug("RECV packet from %s port %d on %s",
1777 inet_ntoa(from.sin_addr), ntohs(from.sin_port),
1778 ifp ? ifp->name : "unknown");
1779
1780 /* If this packet come from unknown interface, ignore it. */
1781 if (ifp == NULL) {
1782 zlog_info(
1783 "rip_read: cannot find interface for packet from %s port %d",
1784 inet_ntoa(from.sin_addr), ntohs(from.sin_port));
1785 return -1;
1786 }
1787
1788 p.family = AF_INET;
1789 p.u.prefix4 = from.sin_addr;
1790 p.prefixlen = IPV4_MAX_BITLEN;
1791
1792 ifc = connected_lookup_prefix(ifp, &p);
1793
1794 if (ifc == NULL) {
1795 zlog_info(
1796 "rip_read: cannot find connected address for packet from %s "
1797 "port %d on interface %s",
1798 inet_ntoa(from.sin_addr), ntohs(from.sin_port),
1799 ifp->name);
1800 return -1;
1801 }
1802
1803 /* Packet length check. */
1804 if (len < RIP_PACKET_MINSIZ) {
1805 zlog_warn("packet size %d is smaller than minimum size %d", len,
1806 RIP_PACKET_MINSIZ);
1807 rip_peer_bad_packet(&from);
1808 return len;
1809 }
1810 if (len > RIP_PACKET_MAXSIZ) {
1811 zlog_warn("packet size %d is larger than max size %d", len,
1812 RIP_PACKET_MAXSIZ);
1813 rip_peer_bad_packet(&from);
1814 return len;
1815 }
1816
1817 /* Packet alignment check. */
1818 if ((len - RIP_PACKET_MINSIZ) % 20) {
1819 zlog_warn("packet size %d is wrong for RIP packet alignment",
1820 len);
1821 rip_peer_bad_packet(&from);
1822 return len;
1823 }
1824
1825 /* Set RTE number. */
1826 rtenum = ((len - RIP_PACKET_MINSIZ) / 20);
1827
1828 /* For easy to handle. */
1829 packet = &rip_buf.rip_packet;
1830
1831 /* RIP version check. */
1832 if (packet->version == 0) {
1833 zlog_info("version 0 with command %d received.",
1834 packet->command);
1835 rip_peer_bad_packet(&from);
1836 return -1;
1837 }
1838
1839 /* Dump RIP packet. */
1840 if (IS_RIP_DEBUG_RECV)
1841 rip_packet_dump(packet, len, "RECV");
1842
1843 /* RIP version adjust. This code should rethink now. RFC1058 says
1844 that "Version 1 implementations are to ignore this extra data and
1845 process only the fields specified in this document.". So RIPv3
1846 packet should be treated as RIPv1 ignoring must be zero field. */
1847 if (packet->version > RIPv2)
1848 packet->version = RIPv2;
1849
1850 /* Is RIP running or is this RIP neighbor ?*/
1851 ri = ifp->info;
1852 if (!ri->running && !rip_neighbor_lookup(&from)) {
1853 if (IS_RIP_DEBUG_EVENT)
1854 zlog_debug("RIP is not enabled on interface %s.",
1855 ifp->name);
1856 rip_peer_bad_packet(&from);
1857 return -1;
1858 }
1859
1860 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1861 vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ? rip->version_recv
1862 : ri->ri_receive);
1863 if (vrecv == RI_RIP_VERSION_NONE
1864 || ((packet->version == RIPv1) && !(vrecv & RIPv1))
1865 || ((packet->version == RIPv2) && !(vrecv & RIPv2))) {
1866 if (IS_RIP_DEBUG_PACKET)
1867 zlog_debug(
1868 " packet's v%d doesn't fit to if version spec",
1869 packet->version);
1870 rip_peer_bad_packet(&from);
1871 return -1;
1872 }
1873
1874 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1875 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1876 accepted; authenticated RIP-2 messages shall be discarded. */
1877 if ((ri->auth_type == RIP_NO_AUTH) && rtenum
1878 && (packet->version == RIPv2)
1879 && (packet->rte->family == htons(RIP_FAMILY_AUTH))) {
1880 if (IS_RIP_DEBUG_EVENT)
1881 zlog_debug(
1882 "packet RIPv%d is dropped because authentication disabled",
1883 packet->version);
1884 rip_peer_bad_packet(&from);
1885 return -1;
1886 }
1887
1888 /* RFC:
1889 If the router is configured to authenticate RIP-2 messages, then
1890 RIP-1 messages and RIP-2 messages which pass authentication
1891 testing shall be accepted; unauthenticated and failed
1892 authentication RIP-2 messages shall be discarded. For maximum
1893 security, RIP-1 messages should be ignored when authentication is
1894 in use (see section 4.1); otherwise, the routing information from
1895 authenticated messages will be propagated by RIP-1 routers in an
1896 unauthenticated manner.
1897 */
1898 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1899 * always reply regardless of authentication settings, because:
1900 *
1901 * - if there other authorised routers on-link, the REQUESTor can
1902 * passively obtain the routing updates anyway
1903 * - if there are no other authorised routers on-link, RIP can
1904 * easily be disabled for the link to prevent giving out information
1905 * on state of this routers RIP routing table..
1906 *
1907 * I.e. if RIPv1 has any place anymore these days, it's as a very
1908 * simple way to distribute routing information (e.g. to embedded
1909 * hosts / appliances) and the ability to give out RIPv1
1910 * routing-information freely, while still requiring RIPv2
1911 * authentication for any RESPONSEs might be vaguely useful.
1912 */
1913 if (ri->auth_type != RIP_NO_AUTH && packet->version == RIPv1) {
1914 /* Discard RIPv1 messages other than REQUESTs */
1915 if (packet->command != RIP_REQUEST) {
1916 if (IS_RIP_DEBUG_PACKET)
1917 zlog_debug(
1918 "RIPv1"
1919 " dropped because authentication enabled");
1920 rip_peer_bad_packet(&from);
1921 return -1;
1922 }
1923 } else if (ri->auth_type != RIP_NO_AUTH) {
1924 const char *auth_desc;
1925
1926 if (rtenum == 0) {
1927 /* There definitely is no authentication in the packet.
1928 */
1929 if (IS_RIP_DEBUG_PACKET)
1930 zlog_debug(
1931 "RIPv2 authentication failed: no auth RTE in packet");
1932 rip_peer_bad_packet(&from);
1933 return -1;
1934 }
1935
1936 /* First RTE must be an Authentication Family RTE */
1937 if (packet->rte->family != htons(RIP_FAMILY_AUTH)) {
1938 if (IS_RIP_DEBUG_PACKET)
1939 zlog_debug(
1940 "RIPv2"
1941 " dropped because authentication enabled");
1942 rip_peer_bad_packet(&from);
1943 return -1;
1944 }
1945
1946 /* Check RIPv2 authentication. */
1947 switch (ntohs(packet->rte->tag)) {
1948 case RIP_AUTH_SIMPLE_PASSWORD:
1949 auth_desc = "simple";
1950 ret = rip_auth_simple_password(packet->rte, &from, ifp);
1951 break;
1952
1953 case RIP_AUTH_MD5:
1954 auth_desc = "MD5";
1955 ret = rip_auth_md5(packet, &from, len, ifp);
1956 /* Reset RIP packet length to trim MD5 data. */
1957 len = ret;
1958 break;
1959
1960 default:
1961 ret = 0;
1962 auth_desc = "unknown type";
1963 if (IS_RIP_DEBUG_PACKET)
1964 zlog_debug(
1965 "RIPv2 Unknown authentication type %d",
1966 ntohs(packet->rte->tag));
1967 }
1968
1969 if (ret) {
1970 if (IS_RIP_DEBUG_PACKET)
1971 zlog_debug("RIPv2 %s authentication success",
1972 auth_desc);
1973 } else {
1974 if (IS_RIP_DEBUG_PACKET)
1975 zlog_debug("RIPv2 %s authentication failure",
1976 auth_desc);
1977 rip_peer_bad_packet(&from);
1978 return -1;
1979 }
1980 }
1981
1982 /* Process each command. */
1983 switch (packet->command) {
1984 case RIP_RESPONSE:
1985 rip_response_process(packet, len, &from, ifc);
1986 break;
1987 case RIP_REQUEST:
1988 case RIP_POLL:
1989 rip_request_process(packet, len, &from, ifc);
1990 break;
1991 case RIP_TRACEON:
1992 case RIP_TRACEOFF:
1993 zlog_info(
1994 "Obsolete command %s received, please sent it to routed",
1995 lookup_msg(rip_msg, packet->command, NULL));
1996 rip_peer_bad_packet(&from);
1997 break;
1998 case RIP_POLL_ENTRY:
1999 zlog_info("Obsolete command %s received",
2000 lookup_msg(rip_msg, packet->command, NULL));
2001 rip_peer_bad_packet(&from);
2002 break;
2003 default:
2004 zlog_info("Unknown RIP command %d received", packet->command);
2005 rip_peer_bad_packet(&from);
2006 break;
2007 }
2008
2009 return len;
718e3744 2010}
2011
718e3744 2012/* Write routing table entry to the stream and return next index of
2013 the routing table entry in the stream. */
d62a17ae 2014static int rip_write_rte(int num, struct stream *s, struct prefix_ipv4 *p,
2015 u_char version, struct rip_info *rinfo)
2016{
2017 struct in_addr mask;
2018
2019 /* Write routing table entry. */
2020 if (version == RIPv1) {
2021 stream_putw(s, AF_INET);
2022 stream_putw(s, 0);
2023 stream_put_ipv4(s, p->prefix.s_addr);
2024 stream_put_ipv4(s, 0);
2025 stream_put_ipv4(s, 0);
2026 stream_putl(s, rinfo->metric_out);
2027 } else {
2028 masklen2ip(p->prefixlen, &mask);
2029
2030 stream_putw(s, AF_INET);
2031 stream_putw(s, rinfo->tag_out);
2032 stream_put_ipv4(s, p->prefix.s_addr);
2033 stream_put_ipv4(s, mask.s_addr);
2034 stream_put_ipv4(s, rinfo->nexthop_out.s_addr);
2035 stream_putl(s, rinfo->metric_out);
2036 }
2037
2038 return ++num;
718e3744 2039}
2040
2041/* Send update to the ifp or spcified neighbor. */
d62a17ae 2042void rip_output_process(struct connected *ifc, struct sockaddr_in *to,
2043 int route_type, u_char version)
2044{
2045 int ret;
2046 struct stream *s;
2047 struct route_node *rp;
2048 struct rip_info *rinfo;
2049 struct rip_interface *ri;
2050 struct prefix_ipv4 *p;
2051 struct prefix_ipv4 classfull;
2052 struct prefix_ipv4 ifaddrclass;
2053 struct key *key = NULL;
2054 /* this might need to made dynamic if RIP ever supported auth methods
2055 with larger key string sizes */
2056 char auth_str[RIP_AUTH_SIMPLE_SIZE];
2057 size_t doff = 0; /* offset of digest offset field */
2058 int num = 0;
2059 int rtemax;
2060 int subnetted = 0;
2061 struct list *list = NULL;
2062 struct listnode *listnode = NULL;
2063
2064 /* Logging output event. */
2065 if (IS_RIP_DEBUG_EVENT) {
2066 if (to)
2067 zlog_debug("update routes to neighbor %s",
2068 inet_ntoa(to->sin_addr));
2069 else
2070 zlog_debug("update routes on interface %s ifindex %d",
2071 ifc->ifp->name, ifc->ifp->ifindex);
2072 }
718e3744 2073
d62a17ae 2074 /* Set output stream. */
2075 s = rip->obuf;
2076
2077 /* Reset stream and RTE counter. */
2078 stream_reset(s);
2079 rtemax = RIP_MAX_RTE;
2080
2081 /* Get RIP interface. */
2082 ri = ifc->ifp->info;
2083
2084 /* If output interface is in simple password authentication mode, we
2085 need space for authentication data. */
2086 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2087 rtemax -= 1;
2088
2089 /* If output interface is in MD5 authentication mode, we need space
2090 for authentication header and data. */
2091 if (ri->auth_type == RIP_AUTH_MD5)
2092 rtemax -= 2;
2093
2094 /* If output interface is in simple password authentication mode
2095 and string or keychain is specified we need space for auth. data */
2096 if (ri->auth_type != RIP_NO_AUTH) {
2097 if (ri->key_chain) {
2098 struct keychain *keychain;
2099
2100 keychain = keychain_lookup(ri->key_chain);
2101 if (keychain)
2102 key = key_lookup_for_send(keychain);
2103 }
2104 /* to be passed to auth functions later */
2105 rip_auth_prepare_str_send(ri, key, auth_str,
2106 RIP_AUTH_SIMPLE_SIZE);
2107 }
2108
2109 if (version == RIPv1) {
2110 memcpy(&ifaddrclass, ifc->address, sizeof(struct prefix_ipv4));
2111 apply_classful_mask_ipv4(&ifaddrclass);
2112 subnetted = 0;
2113 if (ifc->address->prefixlen > ifaddrclass.prefixlen)
2114 subnetted = 1;
2115 }
2116
2117 for (rp = route_top(rip->table); rp; rp = route_next(rp))
2118 if ((list = rp->info) != NULL && listcount(list) != 0) {
2119 rinfo = listgetdata(listhead(list));
2120 /* For RIPv1, if we are subnetted, output subnets in our
2121 * network */
2122 /* that have the same mask as the output "interface".
2123 * For other */
2124 /* networks, only the classfull version is output. */
2125
2126 if (version == RIPv1) {
2127 p = (struct prefix_ipv4 *)&rp->p;
2128
2129 if (IS_RIP_DEBUG_PACKET)
2130 zlog_debug(
2131 "RIPv1 mask check, %s/%d considered for output",
2132 inet_ntoa(rp->p.u.prefix4),
2133 rp->p.prefixlen);
2134
2135 if (subnetted
2136 && prefix_match(
2137 (struct prefix *)&ifaddrclass,
2138 &rp->p)) {
2139 if ((ifc->address->prefixlen
2140 != rp->p.prefixlen)
2141 && (rp->p.prefixlen != 32))
2142 continue;
2143 } else {
2144 memcpy(&classfull, &rp->p,
2145 sizeof(struct prefix_ipv4));
2146 apply_classful_mask_ipv4(&classfull);
2147 if (rp->p.u.prefix4.s_addr != 0
2148 && classfull.prefixlen
2149 != rp->p.prefixlen)
2150 continue;
2151 }
2152 if (IS_RIP_DEBUG_PACKET)
2153 zlog_debug(
2154 "RIPv1 mask check, %s/%d made it through",
2155 inet_ntoa(rp->p.u.prefix4),
2156 rp->p.prefixlen);
2157 } else
2158 p = (struct prefix_ipv4 *)&rp->p;
2159
2160 /* Apply output filters. */
2161 ret = rip_filter(RIP_FILTER_OUT, p, ri);
2162 if (ret < 0)
2163 continue;
2164
2165 /* Changed route only output. */
2166 if (route_type == rip_changed_route
2167 && (!(rinfo->flags & RIP_RTF_CHANGED)))
2168 continue;
2169
2170 /* Split horizon. */
2171 /* if (split_horizon == rip_split_horizon) */
2172 if (ri->split_horizon == RIP_SPLIT_HORIZON) {
2173 /*
2174 * We perform split horizon for RIP and
2175 * connected route.
2176 * For rip routes, we want to suppress the route
2177 * if we would
2178 * end up sending the route back on the
2179 * interface that we
2180 * learned it from, with a higher metric. For
2181 * connected routes,
2182 * we suppress the route if the prefix is a
2183 * subset of the
2184 * source address that we are going to use for
2185 * the packet
2186 * (in order to handle the case when multiple
2187 * subnets are
2188 * configured on the same interface).
2189 */
2190 int suppress = 0;
2191 struct rip_info *tmp_rinfo = NULL;
2192
2193 for (ALL_LIST_ELEMENTS_RO(list, listnode,
2194 tmp_rinfo))
2195 if (tmp_rinfo->type == ZEBRA_ROUTE_RIP
dd127197 2196 && tmp_rinfo->nh.ifindex
d62a17ae 2197 == ifc->ifp->ifindex) {
2198 suppress = 1;
2199 break;
2200 }
2201
2202 if (!suppress
2203 && rinfo->type == ZEBRA_ROUTE_CONNECT
2204 && prefix_match((struct prefix *)p,
2205 ifc->address))
2206 suppress = 1;
2207
2208 if (suppress)
2209 continue;
2210 }
2211
2212 /* Preparation for route-map. */
2213 rinfo->metric_set = 0;
2214 rinfo->nexthop_out.s_addr = 0;
2215 rinfo->metric_out = rinfo->metric;
2216 rinfo->tag_out = rinfo->tag;
2217 rinfo->ifindex_out = ifc->ifp->ifindex;
2218
2219 /* In order to avoid some local loops,
2220 * if the RIP route has a nexthop via this interface,
2221 * keep the nexthop,
2222 * otherwise set it to 0. The nexthop should not be
2223 * propagated
2224 * beyond the local broadcast/multicast area in order
2225 * to avoid an IGP multi-level recursive look-up.
2226 * see (4.4)
2227 */
dd127197
DS
2228 if (rinfo->nh.ifindex == ifc->ifp->ifindex)
2229 rinfo->nexthop_out = rinfo->nh.gate.ipv4;
d62a17ae 2230
2231 /* Interface route-map */
2232 if (ri->routemap[RIP_FILTER_OUT]) {
2233 ret = route_map_apply(
2234 ri->routemap[RIP_FILTER_OUT],
2235 (struct prefix *)p, RMAP_RIP, rinfo);
2236
2237 if (ret == RMAP_DENYMATCH) {
2238 if (IS_RIP_DEBUG_PACKET)
2239 zlog_debug(
2240 "RIP %s/%d is filtered by route-map out",
2241 inet_ntoa(p->prefix),
2242 p->prefixlen);
2243 continue;
2244 }
2245 }
2246
2247 /* Apply redistribute route map - continue, if deny */
2248 if (rip->route_map[rinfo->type].name
2249 && rinfo->sub_type != RIP_ROUTE_INTERFACE) {
2250 ret = route_map_apply(
2251 rip->route_map[rinfo->type].map,
2252 (struct prefix *)p, RMAP_RIP, rinfo);
2253
2254 if (ret == RMAP_DENYMATCH) {
2255 if (IS_RIP_DEBUG_PACKET)
2256 zlog_debug(
2257 "%s/%d is filtered by route-map",
2258 inet_ntoa(p->prefix),
2259 p->prefixlen);
2260 continue;
2261 }
2262 }
2263
2264 /* When route-map does not set metric. */
2265 if (!rinfo->metric_set) {
2266 /* If redistribute metric is set. */
2267 if (rip->route_map[rinfo->type].metric_config
2268 && rinfo->metric != RIP_METRIC_INFINITY) {
2269 rinfo->metric_out =
2270 rip->route_map[rinfo->type]
2271 .metric;
2272 } else {
2273 /* If the route is not connected or
2274 localy generated
2275 one, use default-metric value*/
2276 if (rinfo->type != ZEBRA_ROUTE_RIP
2277 && rinfo->type
2278 != ZEBRA_ROUTE_CONNECT
2279 && rinfo->metric
2280 != RIP_METRIC_INFINITY)
2281 rinfo->metric_out =
2282 rip->default_metric;
2283 }
2284 }
2285
2286 /* Apply offset-list */
2287 if (rinfo->metric != RIP_METRIC_INFINITY)
2288 rip_offset_list_apply_out(p, ifc->ifp,
2289 &rinfo->metric_out);
2290
2291 if (rinfo->metric_out > RIP_METRIC_INFINITY)
2292 rinfo->metric_out = RIP_METRIC_INFINITY;
2293
2294 /* Perform split-horizon with poisoned reverse
2295 * for RIP and connected routes.
2296 **/
2297 if (ri->split_horizon
2298 == RIP_SPLIT_HORIZON_POISONED_REVERSE) {
2299 /*
2300 * We perform split horizon for RIP and
2301 * connected route.
2302 * For rip routes, we want to suppress the route
2303 * if we would
2304 * end up sending the route back on the
2305 * interface that we
2306 * learned it from, with a higher metric. For
2307 * connected routes,
2308 * we suppress the route if the prefix is a
2309 * subset of the
2310 * source address that we are going to use for
2311 * the packet
2312 * (in order to handle the case when multiple
2313 * subnets are
2314 * configured on the same interface).
2315 */
2316 struct rip_info *tmp_rinfo = NULL;
2317
2318 for (ALL_LIST_ELEMENTS_RO(list, listnode,
2319 tmp_rinfo))
2320 if (tmp_rinfo->type == ZEBRA_ROUTE_RIP
dd127197 2321 && tmp_rinfo->nh.ifindex
d62a17ae 2322 == ifc->ifp->ifindex)
2323 rinfo->metric_out =
2324 RIP_METRIC_INFINITY;
2325 if (tmp_rinfo->type == ZEBRA_ROUTE_CONNECT
2326 && prefix_match((struct prefix *)p,
2327 ifc->address))
2328 rinfo->metric_out = RIP_METRIC_INFINITY;
2329 }
2330
2331 /* Prepare preamble, auth headers, if needs be */
2332 if (num == 0) {
2333 stream_putc(s, RIP_RESPONSE);
2334 stream_putc(s, version);
2335 stream_putw(s, 0);
2336
2337 /* auth header for !v1 && !no_auth */
2338 if ((ri->auth_type != RIP_NO_AUTH)
2339 && (version != RIPv1))
2340 doff = rip_auth_header_write(
2341 s, ri, key, auth_str,
2342 RIP_AUTH_SIMPLE_SIZE);
2343 }
2344
2345 /* Write RTE to the stream. */
2346 num = rip_write_rte(num, s, p, version, rinfo);
2347 if (num == rtemax) {
2348 if (version == RIPv2
2349 && ri->auth_type == RIP_AUTH_MD5)
2350 rip_auth_md5_set(s, ri, doff, auth_str,
2351 RIP_AUTH_SIMPLE_SIZE);
2352
2353 ret = rip_send_packet(STREAM_DATA(s),
2354 stream_get_endp(s), to,
2355 ifc);
2356
2357 if (ret >= 0 && IS_RIP_DEBUG_SEND)
2358 rip_packet_dump((struct rip_packet *)
2359 STREAM_DATA(s),
2360 stream_get_endp(s),
2361 "SEND");
2362 num = 0;
2363 stream_reset(s);
2364 }
2365 }
2366
2367 /* Flush unwritten RTE. */
2368 if (num != 0) {
2369 if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
2370 rip_auth_md5_set(s, ri, doff, auth_str,
2371 RIP_AUTH_SIMPLE_SIZE);
2372
2373 ret = rip_send_packet(STREAM_DATA(s), stream_get_endp(s), to,
2374 ifc);
2375
2376 if (ret >= 0 && IS_RIP_DEBUG_SEND)
2377 rip_packet_dump((struct rip_packet *)STREAM_DATA(s),
2378 stream_get_endp(s), "SEND");
2379 stream_reset(s);
2380 }
2381
2382 /* Statistics updates. */
2383 ri->sent_updates++;
718e3744 2384}
2385
2386/* Send RIP packet to the interface. */
d62a17ae 2387static void rip_update_interface(struct connected *ifc, u_char version,
2388 int route_type)
2389{
2390 struct interface *ifp = ifc->ifp;
2391 struct rip_interface *ri = ifp->info;
2392 struct sockaddr_in to;
2393
2394 /* When RIP version is 2 and multicast enable interface. */
2395 if (version == RIPv2 && !ri->v2_broadcast && if_is_multicast(ifp)) {
2396 if (IS_RIP_DEBUG_EVENT)
2397 zlog_debug("multicast announce on %s ", ifp->name);
2398
2399 rip_output_process(ifc, NULL, route_type, version);
2400 return;
2401 }
2402
2403 /* If we can't send multicast packet, send it with unicast. */
2404 if (if_is_broadcast(ifp) || if_is_pointopoint(ifp)) {
2405 if (ifc->address->family == AF_INET) {
2406 /* Destination address and port setting. */
2407 memset(&to, 0, sizeof(struct sockaddr_in));
2408 if (ifc->destination)
2409 /* use specified broadcast or peer destination
2410 * addr */
2411 to.sin_addr = ifc->destination->u.prefix4;
2412 else if (ifc->address->prefixlen < IPV4_MAX_PREFIXLEN)
2413 /* calculate the appropriate broadcast address
2414 */
2415 to.sin_addr.s_addr = ipv4_broadcast_addr(
2416 ifc->address->u.prefix4.s_addr,
2417 ifc->address->prefixlen);
2418 else
2419 /* do not know where to send the packet */
2420 return;
2421 to.sin_port = htons(RIP_PORT_DEFAULT);
2422
2423 if (IS_RIP_DEBUG_EVENT)
2424 zlog_debug("%s announce to %s on %s",
2425 CONNECTED_PEER(ifc) ? "unicast"
2426 : "broadcast",
2427 inet_ntoa(to.sin_addr), ifp->name);
2428
2429 rip_output_process(ifc, &to, route_type, version);
2430 }
2431 }
718e3744 2432}
2433
2434/* Update send to all interface and neighbor. */
d62a17ae 2435static void rip_update_process(int route_type)
2436{
f4e14fdb 2437 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 2438 struct listnode *ifnode, *ifnnode;
2439 struct connected *connected;
2440 struct interface *ifp;
2441 struct rip_interface *ri;
2442 struct route_node *rp;
2443 struct sockaddr_in to;
2444 struct prefix *p;
2445
2446 /* Send RIP update to each interface. */
451fda4f 2447 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 2448 if (if_is_loopback(ifp))
2449 continue;
2450
2451 if (!if_is_operative(ifp))
2452 continue;
2453
2454 /* Fetch RIP interface information. */
2455 ri = ifp->info;
2456
2457 /* When passive interface is specified, suppress announce to the
2458 interface. */
2459 if (ri->passive)
2460 continue;
2461
2462 if (ri->running) {
2463 /*
2464 * If there is no version configuration in the
2465 * interface,
2466 * use rip's version setting.
2467 */
2468 int vsend = ((ri->ri_send == RI_RIP_UNSPEC)
2469 ? rip->version_send
2470 : ri->ri_send);
2471
2472 if (IS_RIP_DEBUG_EVENT)
2473 zlog_debug("SEND UPDATE to %s ifindex %d",
2474 ifp->name, ifp->ifindex);
2475
2476 /* send update on each connected network */
2477 for (ALL_LIST_ELEMENTS(ifp->connected, ifnode, ifnnode,
2478 connected)) {
2479 if (connected->address->family == AF_INET) {
2480 if (vsend & RIPv1)
2481 rip_update_interface(
2482 connected, RIPv1,
2483 route_type);
2484 if ((vsend & RIPv2)
2485 && if_is_multicast(ifp))
2486 rip_update_interface(
2487 connected, RIPv2,
2488 route_type);
2489 }
2490 }
2491 }
2492 }
2493
2494 /* RIP send updates to each neighbor. */
2495 for (rp = route_top(rip->neighbor); rp; rp = route_next(rp))
2496 if (rp->info != NULL) {
2497 p = &rp->p;
2498
2499 connected = if_lookup_address(&p->u.prefix4, AF_INET,
2500 VRF_DEFAULT);
2501 if (!connected) {
2502 zlog_warn(
2503 "Neighbor %s doesnt have connected interface!",
2504 inet_ntoa(p->u.prefix4));
2505 continue;
2506 }
2507
2508 /* Set destination address and port */
2509 memset(&to, 0, sizeof(struct sockaddr_in));
2510 to.sin_addr = p->u.prefix4;
2511 to.sin_port = htons(RIP_PORT_DEFAULT);
2512
2513 /* RIP version is rip's configuration. */
2514 rip_output_process(connected, &to, route_type,
2515 rip->version_send);
b9d92881 2516 }
718e3744 2517}
2518
2519/* RIP's periodical timer. */
d62a17ae 2520static int rip_update(struct thread *t)
718e3744 2521{
d62a17ae 2522 /* Clear timer pointer. */
2523 rip->t_update = NULL;
718e3744 2524
d62a17ae 2525 if (IS_RIP_DEBUG_EVENT)
2526 zlog_debug("update timer fire!");
718e3744 2527
d62a17ae 2528 /* Process update output. */
2529 rip_update_process(rip_all_route);
718e3744 2530
d62a17ae 2531 /* Triggered updates may be suppressed if a regular update is due by
2532 the time the triggered update would be sent. */
2533 RIP_TIMER_OFF(rip->t_triggered_interval);
2534 rip->trigger = 0;
718e3744 2535
d62a17ae 2536 /* Register myself. */
2537 rip_event(RIP_UPDATE_EVENT, 0);
718e3744 2538
d62a17ae 2539 return 0;
718e3744 2540}
2541
2542/* Walk down the RIP routing table then clear changed flag. */
d62a17ae 2543static void rip_clear_changed_flag(void)
718e3744 2544{
d62a17ae 2545 struct route_node *rp;
2546 struct rip_info *rinfo = NULL;
2547 struct list *list = NULL;
2548 struct listnode *listnode = NULL;
718e3744 2549
d62a17ae 2550 for (rp = route_top(rip->table); rp; rp = route_next(rp))
2551 if ((list = rp->info) != NULL)
2552 for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
2553 UNSET_FLAG(rinfo->flags, RIP_RTF_CHANGED);
2554 /* This flag can be set only on the first entry.
2555 */
2556 break;
2557 }
718e3744 2558}
2559
2560/* Triggered update interval timer. */
d62a17ae 2561static int rip_triggered_interval(struct thread *t)
718e3744 2562{
d62a17ae 2563 int rip_triggered_update(struct thread *);
718e3744 2564
d62a17ae 2565 rip->t_triggered_interval = NULL;
718e3744 2566
d62a17ae 2567 if (rip->trigger) {
2568 rip->trigger = 0;
2569 rip_triggered_update(t);
2570 }
2571 return 0;
2572}
718e3744 2573
2574/* Execute triggered update. */
d62a17ae 2575static int rip_triggered_update(struct thread *t)
718e3744 2576{
d62a17ae 2577 int interval;
718e3744 2578
d62a17ae 2579 /* Clear thred pointer. */
2580 rip->t_triggered_update = NULL;
718e3744 2581
d62a17ae 2582 /* Cancel interval timer. */
2583 RIP_TIMER_OFF(rip->t_triggered_interval);
2584 rip->trigger = 0;
718e3744 2585
d62a17ae 2586 /* Logging triggered update. */
2587 if (IS_RIP_DEBUG_EVENT)
2588 zlog_debug("triggered update!");
718e3744 2589
d62a17ae 2590 /* Split Horizon processing is done when generating triggered
2591 updates as well as normal updates (see section 2.6). */
2592 rip_update_process(rip_changed_route);
718e3744 2593
d62a17ae 2594 /* Once all of the triggered updates have been generated, the route
2595 change flags should be cleared. */
2596 rip_clear_changed_flag();
718e3744 2597
d62a17ae 2598 /* After a triggered update is sent, a timer should be set for a
2599 random interval between 1 and 5 seconds. If other changes that
2600 would trigger updates occur before the timer expires, a single
2601 update is triggered when the timer expires. */
2602 interval = (random() % 5) + 1;
718e3744 2603
d62a17ae 2604 rip->t_triggered_interval = NULL;
2605 thread_add_timer(master, rip_triggered_interval, NULL, interval,
2606 &rip->t_triggered_interval);
718e3744 2607
d62a17ae 2608 return 0;
718e3744 2609}
2610
2611/* Withdraw redistributed route. */
d62a17ae 2612void rip_redistribute_withdraw(int type)
2613{
2614 struct route_node *rp;
2615 struct rip_info *rinfo = NULL;
2616 struct list *list = NULL;
2617
2618 if (!rip)
2619 return;
2620
2621 for (rp = route_top(rip->table); rp; rp = route_next(rp))
2622 if ((list = rp->info) != NULL) {
2623 rinfo = listgetdata(listhead(list));
2624 if (rinfo->type == type
2625 && rinfo->sub_type != RIP_ROUTE_INTERFACE) {
2626 /* Perform poisoned reverse. */
2627 rinfo->metric = RIP_METRIC_INFINITY;
2628 RIP_TIMER_ON(rinfo->t_garbage_collect,
2629 rip_garbage_collect,
2630 rip->garbage_time);
2631 RIP_TIMER_OFF(rinfo->t_timeout);
2632 rinfo->flags |= RIP_RTF_CHANGED;
2633
2634 if (IS_RIP_DEBUG_EVENT) {
2635 struct prefix_ipv4 *p =
2636 (struct prefix_ipv4 *)&rp->p;
2637
2638 zlog_debug(
2639 "Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2640 inet_ntoa(p->prefix),
2641 p->prefixlen,
dd127197
DS
2642 ifindex2ifname(
2643 rinfo->nh.ifindex,
2644 VRF_DEFAULT));
d62a17ae 2645 }
2646
2647 rip_event(RIP_TRIGGERED_UPDATE, 0);
2648 }
2649 }
2650}
2651
2652/* Create new RIP instance and set it to global variable. */
2653static int rip_create(void)
718e3744 2654{
d62a17ae 2655 rip = XCALLOC(MTYPE_RIP, sizeof(struct rip));
718e3744 2656
d62a17ae 2657 /* Set initial value. */
2658 rip->version_send = RI_RIP_VERSION_2;
2659 rip->version_recv = RI_RIP_VERSION_1_AND_2;
2660 rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
2661 rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
2662 rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
2663 rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
718e3744 2664
d62a17ae 2665 /* Initialize RIP routig table. */
2666 rip->table = route_table_init();
2667 rip->route = route_table_init();
2668 rip->neighbor = route_table_init();
718e3744 2669
d62a17ae 2670 /* Make output stream. */
2671 rip->obuf = stream_new(1500);
16705130 2672
d62a17ae 2673 /* Make socket. */
2674 rip->sock = rip_create_socket();
2675 if (rip->sock < 0)
2676 return rip->sock;
16705130 2677
d62a17ae 2678 /* Create read and timer thread. */
2679 rip_event(RIP_READ, rip->sock);
2680 rip_event(RIP_UPDATE_EVENT, 1);
718e3744 2681
d62a17ae 2682 QOBJ_REG(rip, rip);
718e3744 2683
d62a17ae 2684 return 0;
2685}
718e3744 2686
d62a17ae 2687/* Sned RIP request to the destination. */
2688int rip_request_send(struct sockaddr_in *to, struct interface *ifp,
2689 u_char version, struct connected *connected)
2690{
2691 struct rte *rte;
2692 struct rip_packet rip_packet;
2693 struct listnode *node, *nnode;
2694
2695 memset(&rip_packet, 0, sizeof(rip_packet));
2696
2697 rip_packet.command = RIP_REQUEST;
2698 rip_packet.version = version;
2699 rte = rip_packet.rte;
2700 rte->metric = htonl(RIP_METRIC_INFINITY);
2701
2702 if (connected) {
2703 /*
2704 * connected is only sent for ripv1 case, or when
2705 * interface does not support multicast. Caller loops
2706 * over each connected address for this case.
2707 */
2708 if (rip_send_packet((u_char *)&rip_packet, sizeof(rip_packet),
2709 to, connected)
2710 != sizeof(rip_packet))
2711 return -1;
2712 else
2713 return sizeof(rip_packet);
2714 }
718e3744 2715
d62a17ae 2716 /* send request on each connected network */
2717 for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) {
2718 struct prefix_ipv4 *p;
718e3744 2719
d62a17ae 2720 p = (struct prefix_ipv4 *)connected->address;
718e3744 2721
d62a17ae 2722 if (p->family != AF_INET)
2723 continue;
f6eacff4 2724
d62a17ae 2725 if (rip_send_packet((u_char *)&rip_packet, sizeof(rip_packet),
2726 to, connected)
2727 != sizeof(rip_packet))
2728 return -1;
2729 }
2730 return sizeof(rip_packet);
718e3744 2731}
2732
d62a17ae 2733static int rip_update_jitter(unsigned long time)
718e3744 2734{
239389ba 2735#define JITTER_BOUND 4
d62a17ae 2736 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2737 Given that, we cannot let time be less than JITTER_BOUND seconds.
2738 The RIPv2 RFC says jitter should be small compared to
2739 update_time. We consider 1/JITTER_BOUND to be small.
2740 */
2741
2742 int jitter_input = time;
2743 int jitter;
2744
2745 if (jitter_input < JITTER_BOUND)
2746 jitter_input = JITTER_BOUND;
2747
2748 jitter = (((random() % ((jitter_input * 2) + 1)) - jitter_input));
2749
2750 return jitter / JITTER_BOUND;
2751}
2752
2753void rip_event(enum rip_event event, int sock)
2754{
2755 int jitter = 0;
2756
2757 switch (event) {
2758 case RIP_READ:
2759 rip->t_read = NULL;
2760 thread_add_read(master, rip_read, NULL, sock, &rip->t_read);
2761 break;
2762 case RIP_UPDATE_EVENT:
2763 RIP_TIMER_OFF(rip->t_update);
2764 jitter = rip_update_jitter(rip->update_time);
2765 thread_add_timer(master, rip_update, NULL,
2766 sock ? 2 : rip->update_time + jitter,
2767 &rip->t_update);
2768 break;
2769 case RIP_TRIGGERED_UPDATE:
2770 if (rip->t_triggered_interval)
2771 rip->trigger = 1;
2772 else
2773 thread_add_event(master, rip_triggered_update, NULL, 0,
2774 &rip->t_triggered_update);
2775 break;
2776 default:
2777 break;
2778 }
718e3744 2779}
6b0655a2 2780
505e5056 2781DEFUN_NOSH (router_rip,
718e3744 2782 router_rip_cmd,
2783 "router rip",
2784 "Enable a routing process\n"
2785 "Routing Information Protocol (RIP)\n")
2786{
d62a17ae 2787 int ret;
718e3744 2788
d62a17ae 2789 /* If rip is not enabled before. */
2790 if (!rip) {
2791 ret = rip_create();
2792 if (ret < 0) {
2793 zlog_info("Can't create RIP");
2794 return CMD_WARNING_CONFIG_FAILED;
2795 }
718e3744 2796 }
d62a17ae 2797 VTY_PUSH_CONTEXT(RIP_NODE, rip);
718e3744 2798
d62a17ae 2799 return CMD_SUCCESS;
718e3744 2800}
2801
2802DEFUN (no_router_rip,
2803 no_router_rip_cmd,
2804 "no router rip",
2805 NO_STR
2806 "Enable a routing process\n"
2807 "Routing Information Protocol (RIP)\n")
2808{
d62a17ae 2809 if (rip)
2810 rip_clean();
2811 return CMD_SUCCESS;
718e3744 2812}
2813
2814DEFUN (rip_version,
2815 rip_version_cmd,
6147e2c6 2816 "version (1-2)",
718e3744 2817 "Set routing protocol version\n"
2818 "version\n")
2819{
d62a17ae 2820 int idx_number = 1;
2821 int version;
718e3744 2822
d62a17ae 2823 version = atoi(argv[idx_number]->arg);
2824 if (version != RIPv1 && version != RIPv2) {
2825 vty_out(vty, "invalid rip version %d\n", version);
2826 return CMD_WARNING_CONFIG_FAILED;
2827 }
2828 rip->version_send = version;
2829 rip->version_recv = version;
718e3744 2830
d62a17ae 2831 return CMD_SUCCESS;
80fa0c69 2832}
718e3744 2833
2834DEFUN (no_rip_version,
2835 no_rip_version_cmd,
55c727dd 2836 "no version [(1-2)]",
718e3744 2837 NO_STR
55c727dd
QY
2838 "Set routing protocol version\n"
2839 "Version\n")
718e3744 2840{
d62a17ae 2841 /* Set RIP version to the default. */
2842 rip->version_send = RI_RIP_VERSION_2;
2843 rip->version_recv = RI_RIP_VERSION_1_AND_2;
718e3744 2844
d62a17ae 2845 return CMD_SUCCESS;
80fa0c69 2846}
718e3744 2847
718e3744 2848
2849DEFUN (rip_route,
2850 rip_route_cmd,
2851 "route A.B.C.D/M",
2852 "RIP static route configuration\n"
2853 "IP prefix <network>/<length>\n")
2854{
d62a17ae 2855 int idx_ipv4_prefixlen = 1;
2856 int ret;
3f5682c8 2857 struct nexthop nh;
d62a17ae 2858 struct prefix_ipv4 p;
2859 struct route_node *node;
718e3744 2860
3f5682c8
DS
2861 memset(&nh, 0, sizeof(nh));
2862 nh.type = NEXTHOP_TYPE_IPV4;
2863
d62a17ae 2864 ret = str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
2865 if (ret < 0) {
2866 vty_out(vty, "Malformed address\n");
2867 return CMD_WARNING_CONFIG_FAILED;
2868 }
2869 apply_mask_ipv4(&p);
718e3744 2870
d62a17ae 2871 /* For router rip configuration. */
2872 node = route_node_get(rip->route, (struct prefix *)&p);
718e3744 2873
d62a17ae 2874 if (node->info) {
2875 vty_out(vty, "There is already same static route.\n");
2876 route_unlock_node(node);
851fcbae 2877 return CMD_WARNING;
d62a17ae 2878 }
718e3744 2879
d62a17ae 2880 node->info = (void *)1;
718e3744 2881
3f5682c8 2882 rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, &nh, 0,
d62a17ae 2883 0, 0);
718e3744 2884
d62a17ae 2885 return CMD_SUCCESS;
718e3744 2886}
2887
2888DEFUN (no_rip_route,
2889 no_rip_route_cmd,
2890 "no route A.B.C.D/M",
2891 NO_STR
2892 "RIP static route configuration\n"
2893 "IP prefix <network>/<length>\n")
2894{
d62a17ae 2895 int idx_ipv4_prefixlen = 2;
2896 int ret;
2897 struct prefix_ipv4 p;
2898 struct route_node *node;
718e3744 2899
d62a17ae 2900 ret = str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
2901 if (ret < 0) {
2902 vty_out(vty, "Malformed address\n");
2903 return CMD_WARNING_CONFIG_FAILED;
2904 }
2905 apply_mask_ipv4(&p);
2906
2907 /* For router rip configuration. */
2908 node = route_node_lookup(rip->route, (struct prefix *)&p);
2909 if (!node) {
2910 vty_out(vty, "Can't find route %s.\n",
2911 argv[idx_ipv4_prefixlen]->arg);
2912 return CMD_WARNING_CONFIG_FAILED;
2913 }
718e3744 2914
d62a17ae 2915 rip_redistribute_delete(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
2916 route_unlock_node(node);
718e3744 2917
d62a17ae 2918 node->info = NULL;
2919 route_unlock_node(node);
718e3744 2920
d62a17ae 2921 return CMD_SUCCESS;
718e3744 2922}
2923
2c239705 2924#if 0
dc63bfd4 2925static void
216565ab 2926rip_update_default_metric (void)
718e3744 2927{
2928 struct route_node *np;
bce8e868
LF
2929 struct rip_info *rinfo = NULL;
2930 struct list *list = NULL;
2931 struct listnode *listnode = NULL;
718e3744 2932
2933 for (np = route_top (rip->table); np; np = route_next (np))
bce8e868
LF
2934 if ((list = np->info) != NULL)
2935 for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo))
2936 if (rinfo->type != ZEBRA_ROUTE_RIP && rinfo->type != ZEBRA_ROUTE_CONNECT)
2937 rinfo->metric = rip->default_metric;
718e3744 2938}
2c239705 2939#endif
718e3744 2940
2941DEFUN (rip_default_metric,
2942 rip_default_metric_cmd,
6147e2c6 2943 "default-metric (1-16)",
718e3744 2944 "Set a metric of redistribute routes\n"
2945 "Default metric\n")
2946{
d62a17ae 2947 int idx_number = 1;
2948 if (rip) {
2949 rip->default_metric = atoi(argv[idx_number]->arg);
2950 /* rip_update_default_metric (); */
2951 }
2952 return CMD_SUCCESS;
718e3744 2953}
2954
2955DEFUN (no_rip_default_metric,
2956 no_rip_default_metric_cmd,
55c727dd 2957 "no default-metric [(1-16)]",
718e3744 2958 NO_STR
2959 "Set a metric of redistribute routes\n"
2960 "Default metric\n")
2961{
d62a17ae 2962 if (rip) {
2963 rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
2964 /* rip_update_default_metric (); */
2965 }
2966 return CMD_SUCCESS;
718e3744 2967}
2968
718e3744 2969
2970DEFUN (rip_timers,
2971 rip_timers_cmd,
6147e2c6 2972 "timers basic (5-2147483647) (5-2147483647) (5-2147483647)",
718e3744 2973 "Adjust routing timers\n"
2974 "Basic routing protocol update timers\n"
2975 "Routing table update timer value in second. Default is 30.\n"
2976 "Routing information timeout timer. Default is 180.\n"
2977 "Garbage collection timer. Default is 120.\n")
2978{
d62a17ae 2979 int idx_number = 2;
2980 int idx_number_2 = 3;
2981 int idx_number_3 = 4;
2982 unsigned long update;
2983 unsigned long timeout;
2984 unsigned long garbage;
2985 char *endptr = NULL;
2986 unsigned long RIP_TIMER_MAX = 2147483647;
2987 unsigned long RIP_TIMER_MIN = 5;
2988
2989 update = strtoul(argv[idx_number]->arg, &endptr, 10);
2990 if (update > RIP_TIMER_MAX || update < RIP_TIMER_MIN
2991 || *endptr != '\0') {
2992 vty_out(vty, "update timer value error\n");
2993 return CMD_WARNING_CONFIG_FAILED;
2994 }
2995
2996 timeout = strtoul(argv[idx_number_2]->arg, &endptr, 10);
2997 if (timeout > RIP_TIMER_MAX || timeout < RIP_TIMER_MIN
2998 || *endptr != '\0') {
2999 vty_out(vty, "timeout timer value error\n");
3000 return CMD_WARNING_CONFIG_FAILED;
3001 }
3002
3003 garbage = strtoul(argv[idx_number_3]->arg, &endptr, 10);
3004 if (garbage > RIP_TIMER_MAX || garbage < RIP_TIMER_MIN
3005 || *endptr != '\0') {
3006 vty_out(vty, "garbage timer value error\n");
3007 return CMD_WARNING_CONFIG_FAILED;
3008 }
3009
3010 /* Set each timer value. */
3011 rip->update_time = update;
3012 rip->timeout_time = timeout;
3013 rip->garbage_time = garbage;
3014
3015 /* Reset update timer thread. */
3016 rip_event(RIP_UPDATE_EVENT, 0);
3017
3018 return CMD_SUCCESS;
718e3744 3019}
3020
3021DEFUN (no_rip_timers,
3022 no_rip_timers_cmd,
55c727dd 3023 "no timers basic [(0-65535) (0-65535) (0-65535)]",
718e3744 3024 NO_STR
3025 "Adjust routing timers\n"
55c727dd
QY
3026 "Basic routing protocol update timers\n"
3027 "Routing table update timer value in second. Default is 30.\n"
3028 "Routing information timeout timer. Default is 180.\n"
3029 "Garbage collection timer. Default is 120.\n")
718e3744 3030{
d62a17ae 3031 /* Set each timer value to the default. */
3032 rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
3033 rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
3034 rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
718e3744 3035
d62a17ae 3036 /* Reset update timer thread. */
3037 rip_event(RIP_UPDATE_EVENT, 0);
718e3744 3038
d62a17ae 3039 return CMD_SUCCESS;
718e3744 3040}
16705130 3041
16705130 3042
718e3744 3043struct route_table *rip_distance_table;
3044
d62a17ae 3045struct rip_distance {
3046 /* Distance value for the IP source prefix. */
3047 u_char distance;
718e3744 3048
d62a17ae 3049 /* Name of the access-list to be matched. */
3050 char *access_list;
718e3744 3051};
3052
d62a17ae 3053static struct rip_distance *rip_distance_new(void)
718e3744 3054{
d62a17ae 3055 return XCALLOC(MTYPE_RIP_DISTANCE, sizeof(struct rip_distance));
718e3744 3056}
3057
d62a17ae 3058static void rip_distance_free(struct rip_distance *rdistance)
3059{
3060 XFREE(MTYPE_RIP_DISTANCE, rdistance);
718e3744 3061}
3062
d62a17ae 3063static int rip_distance_set(struct vty *vty, const char *distance_str,
3064 const char *ip_str, const char *access_list_str)
718e3744 3065{
d62a17ae 3066 int ret;
3067 struct prefix_ipv4 p;
3068 u_char distance;
3069 struct route_node *rn;
3070 struct rip_distance *rdistance;
3071
3072 ret = str2prefix_ipv4(ip_str, &p);
3073 if (ret == 0) {
3074 vty_out(vty, "Malformed prefix\n");
3075 return CMD_WARNING_CONFIG_FAILED;
3076 }
3077
3078 distance = atoi(distance_str);
3079
3080 /* Get RIP distance node. */
3081 rn = route_node_get(rip_distance_table, (struct prefix *)&p);
3082 if (rn->info) {
3083 rdistance = rn->info;
3084 route_unlock_node(rn);
3085 } else {
3086 rdistance = rip_distance_new();
3087 rn->info = rdistance;
3088 }
3089
3090 /* Set distance value. */
3091 rdistance->distance = distance;
3092
3093 /* Reset access-list configuration. */
3094 if (rdistance->access_list) {
3095 free(rdistance->access_list);
3096 rdistance->access_list = NULL;
3097 }
3098 if (access_list_str)
3099 rdistance->access_list = strdup(access_list_str);
3100
3101 return CMD_SUCCESS;
3102}
3103
3104static int rip_distance_unset(struct vty *vty, const char *distance_str,
3105 const char *ip_str, const char *access_list_str)
3106{
3107 int ret;
3108 struct prefix_ipv4 p;
3109 struct route_node *rn;
3110 struct rip_distance *rdistance;
3111
3112 ret = str2prefix_ipv4(ip_str, &p);
3113 if (ret == 0) {
3114 vty_out(vty, "Malformed prefix\n");
3115 return CMD_WARNING_CONFIG_FAILED;
3116 }
3117
3118 rn = route_node_lookup(rip_distance_table, (struct prefix *)&p);
3119 if (!rn) {
3120 vty_out(vty, "Can't find specified prefix\n");
3121 return CMD_WARNING_CONFIG_FAILED;
3122 }
3123
3124 rdistance = rn->info;
718e3744 3125
718e3744 3126 if (rdistance->access_list)
d62a17ae 3127 free(rdistance->access_list);
3128 rip_distance_free(rdistance);
3129
718e3744 3130 rn->info = NULL;
d62a17ae 3131 route_unlock_node(rn);
3132 route_unlock_node(rn);
3133
3134 return CMD_SUCCESS;
718e3744 3135}
3136
d62a17ae 3137static void rip_distance_reset(void)
3138{
3139 struct route_node *rn;
3140 struct rip_distance *rdistance;
718e3744 3141
d62a17ae 3142 for (rn = route_top(rip_distance_table); rn; rn = route_next(rn))
3143 if ((rdistance = rn->info) != NULL) {
3144 if (rdistance->access_list)
3145 free(rdistance->access_list);
3146 rip_distance_free(rdistance);
3147 rn->info = NULL;
3148 route_unlock_node(rn);
3149 }
3150}
3151
3152/* Apply RIP information to distance method. */
3153u_char rip_distance_apply(struct rip_info *rinfo)
3154{
3155 struct route_node *rn;
3156 struct prefix_ipv4 p;
3157 struct rip_distance *rdistance;
3158 struct access_list *alist;
3159
3160 if (!rip)
3161 return 0;
3162
3163 memset(&p, 0, sizeof(struct prefix_ipv4));
3164 p.family = AF_INET;
3165 p.prefix = rinfo->from;
3166 p.prefixlen = IPV4_MAX_BITLEN;
3167
3168 /* Check source address. */
3169 rn = route_node_match(rip_distance_table, (struct prefix *)&p);
3170 if (rn) {
3171 rdistance = rn->info;
3172 route_unlock_node(rn);
3173
3174 if (rdistance->access_list) {
3175 alist = access_list_lookup(AFI_IP,
3176 rdistance->access_list);
3177 if (alist == NULL)
3178 return 0;
3179 if (access_list_apply(alist, &rinfo->rp->p)
3180 == FILTER_DENY)
3181 return 0;
3182
3183 return rdistance->distance;
3184 } else
3185 return rdistance->distance;
718e3744 3186 }
718e3744 3187
d62a17ae 3188 if (rip->distance)
3189 return rip->distance;
718e3744 3190
d62a17ae 3191 return 0;
718e3744 3192}
3193
d62a17ae 3194static void rip_distance_show(struct vty *vty)
3195{
3196 struct route_node *rn;
3197 struct rip_distance *rdistance;
3198 int header = 1;
3199 char buf[BUFSIZ];
3200
3201 vty_out(vty, " Distance: (default is %d)\n",
3202 rip->distance ? rip->distance : ZEBRA_RIP_DISTANCE_DEFAULT);
3203
3204 for (rn = route_top(rip_distance_table); rn; rn = route_next(rn))
3205 if ((rdistance = rn->info) != NULL) {
3206 if (header) {
3207 vty_out(vty,
3208 " Address Distance List\n");
3209 header = 0;
3210 }
3211 sprintf(buf, "%s/%d", inet_ntoa(rn->p.u.prefix4),
3212 rn->p.prefixlen);
3213 vty_out(vty, " %-20s %4d %s\n", buf,
3214 rdistance->distance,
3215 rdistance->access_list ? rdistance->access_list
3216 : "");
3217 }
718e3744 3218}
3219
3220DEFUN (rip_distance,
3221 rip_distance_cmd,
6147e2c6 3222 "distance (1-255)",
718e3744 3223 "Administrative distance\n"
3224 "Distance value\n")
3225{
d62a17ae 3226 int idx_number = 1;
3227 rip->distance = atoi(argv[idx_number]->arg);
3228 return CMD_SUCCESS;
718e3744 3229}
3230
3231DEFUN (no_rip_distance,
3232 no_rip_distance_cmd,
6147e2c6 3233 "no distance (1-255)",
718e3744 3234 NO_STR
3235 "Administrative distance\n"
3236 "Distance value\n")
3237{
d62a17ae 3238 rip->distance = 0;
3239 return CMD_SUCCESS;
718e3744 3240}
3241
3242DEFUN (rip_distance_source,
3243 rip_distance_source_cmd,
6147e2c6 3244 "distance (1-255) A.B.C.D/M",
718e3744 3245 "Administrative distance\n"
3246 "Distance value\n"
3247 "IP source prefix\n")
3248{
d62a17ae 3249 int idx_number = 1;
3250 int idx_ipv4_prefixlen = 2;
3251 rip_distance_set(vty, argv[idx_number]->arg,
3252 argv[idx_ipv4_prefixlen]->arg, NULL);
3253 return CMD_SUCCESS;
718e3744 3254}
3255
3256DEFUN (no_rip_distance_source,
3257 no_rip_distance_source_cmd,
6147e2c6 3258 "no distance (1-255) A.B.C.D/M",
718e3744 3259 NO_STR
3260 "Administrative distance\n"
3261 "Distance value\n"
3262 "IP source prefix\n")
3263{
d62a17ae 3264 int idx_number = 2;
3265 int idx_ipv4_prefixlen = 3;
3266 rip_distance_unset(vty, argv[idx_number]->arg,
3267 argv[idx_ipv4_prefixlen]->arg, NULL);
3268 return CMD_SUCCESS;
718e3744 3269}
3270
3271DEFUN (rip_distance_source_access_list,
3272 rip_distance_source_access_list_cmd,
6147e2c6 3273 "distance (1-255) A.B.C.D/M WORD",
718e3744 3274 "Administrative distance\n"
3275 "Distance value\n"
3276 "IP source prefix\n"
3277 "Access list name\n")
3278{
d62a17ae 3279 int idx_number = 1;
3280 int idx_ipv4_prefixlen = 2;
3281 int idx_word = 3;
3282 rip_distance_set(vty, argv[idx_number]->arg,
3283 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
3284 return CMD_SUCCESS;
718e3744 3285}
3286
3287DEFUN (no_rip_distance_source_access_list,
3288 no_rip_distance_source_access_list_cmd,
6147e2c6 3289 "no distance (1-255) A.B.C.D/M WORD",
718e3744 3290 NO_STR
3291 "Administrative distance\n"
3292 "Distance value\n"
3293 "IP source prefix\n"
3294 "Access list name\n")
3295{
d62a17ae 3296 int idx_number = 2;
3297 int idx_ipv4_prefixlen = 3;
3298 int idx_word = 4;
3299 rip_distance_unset(vty, argv[idx_number]->arg,
3300 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
3301 return CMD_SUCCESS;
718e3744 3302}
6b0655a2 3303
8478ae7e 3304/* Update ECMP routes to zebra when ECMP is disabled. */
d62a17ae 3305static void rip_ecmp_disable(void)
3306{
3307 struct route_node *rp;
3308 struct rip_info *rinfo, *tmp_rinfo;
3309 struct list *list;
3310 struct listnode *node, *nextnode;
3311
3312 if (!rip)
3313 return;
3314
3315 for (rp = route_top(rip->table); rp; rp = route_next(rp))
3316 if ((list = rp->info) != NULL && listcount(list) > 1) {
3317 rinfo = listgetdata(listhead(list));
3318 if (!rip_route_rte(rinfo))
3319 continue;
3320
3321 /* Drop all other entries, except the first one. */
3322 for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo))
3323 if (tmp_rinfo != rinfo) {
3324 RIP_TIMER_OFF(tmp_rinfo->t_timeout);
3325 RIP_TIMER_OFF(
3326 tmp_rinfo->t_garbage_collect);
3327 list_delete_node(list, node);
3328 rip_info_free(tmp_rinfo);
3329 }
3330
3331 /* Update zebra. */
3332 rip_zebra_ipv4_add(rp);
3333
3334 /* Set the route change flag. */
3335 SET_FLAG(rinfo->flags, RIP_RTF_CHANGED);
3336
3337 /* Signal the output process to trigger an update. */
3338 rip_event(RIP_TRIGGERED_UPDATE, 0);
3339 }
8478ae7e
LF
3340}
3341
3342DEFUN (rip_allow_ecmp,
3343 rip_allow_ecmp_cmd,
3344 "allow-ecmp",
3345 "Allow Equal Cost MultiPath\n")
3346{
d62a17ae 3347 if (rip->ecmp) {
3348 vty_out(vty, "ECMP is already enabled.\n");
851fcbae 3349 return CMD_WARNING;
d62a17ae 3350 }
8478ae7e 3351
d62a17ae 3352 rip->ecmp = 1;
3353 zlog_info("ECMP is enabled.");
3354 return CMD_SUCCESS;
8478ae7e
LF
3355}
3356
3357DEFUN (no_rip_allow_ecmp,
3358 no_rip_allow_ecmp_cmd,
3359 "no allow-ecmp",
3360 NO_STR
3361 "Allow Equal Cost MultiPath\n")
3362{
d62a17ae 3363 if (!rip->ecmp) {
3364 vty_out(vty, "ECMP is already disabled.\n");
851fcbae 3365 return CMD_WARNING;
d62a17ae 3366 }
8478ae7e 3367
d62a17ae 3368 rip->ecmp = 0;
3369 zlog_info("ECMP is disabled.");
3370 rip_ecmp_disable();
3371 return CMD_SUCCESS;
8478ae7e
LF
3372}
3373
718e3744 3374/* Print out routes update time. */
d62a17ae 3375static void rip_vty_out_uptime(struct vty *vty, struct rip_info *rinfo)
718e3744 3376{
d62a17ae 3377 time_t clock;
3378 struct tm *tm;
718e3744 3379#define TIME_BUF 25
d62a17ae 3380 char timebuf[TIME_BUF];
3381 struct thread *thread;
3382
3383 if ((thread = rinfo->t_timeout) != NULL) {
3384 clock = thread_timer_remain_second(thread);
3385 tm = gmtime(&clock);
3386 strftime(timebuf, TIME_BUF, "%M:%S", tm);
3387 vty_out(vty, "%5s", timebuf);
3388 } else if ((thread = rinfo->t_garbage_collect) != NULL) {
3389 clock = thread_timer_remain_second(thread);
3390 tm = gmtime(&clock);
3391 strftime(timebuf, TIME_BUF, "%M:%S", tm);
3392 vty_out(vty, "%5s", timebuf);
3393 }
3394}
3395
3396static const char *rip_route_type_print(int sub_type)
3397{
3398 switch (sub_type) {
3399 case RIP_ROUTE_RTE:
3400 return "n";
3401 case RIP_ROUTE_STATIC:
3402 return "s";
3403 case RIP_ROUTE_DEFAULT:
3404 return "d";
3405 case RIP_ROUTE_REDISTRIBUTE:
3406 return "r";
3407 case RIP_ROUTE_INTERFACE:
3408 return "i";
3409 default:
3410 return "?";
3411 }
718e3744 3412}
3413
3414DEFUN (show_ip_rip,
3415 show_ip_rip_cmd,
3416 "show ip rip",
3417 SHOW_STR
3418 IP_STR
3419 "Show RIP routes\n")
3420{
d62a17ae 3421 struct route_node *np;
3422 struct rip_info *rinfo = NULL;
3423 struct list *list = NULL;
3424 struct listnode *listnode = NULL;
3425
3426 if (!rip)
3427 return CMD_SUCCESS;
3428
3429 vty_out(vty,
3430 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
3431 "Sub-codes:\n"
3432 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
3433 " (i) - interface\n\n"
3434 " Network Next Hop Metric From Tag Time\n");
3435
3436 for (np = route_top(rip->table); np; np = route_next(np))
3437 if ((list = np->info) != NULL)
3438 for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
3439 int len;
3440
3441 len = vty_out(
3442 vty, "%c(%s) %s/%d",
3443 /* np->lock, For debugging. */
3444 zebra_route_char(rinfo->type),
3445 rip_route_type_print(rinfo->sub_type),
3446 inet_ntoa(np->p.u.prefix4),
3447 np->p.prefixlen);
3448
3449 len = 24 - len;
3450
3451 if (len > 0)
3452 vty_out(vty, "%*s", len, " ");
3453
3f5682c8
DS
3454 switch(rinfo->nh.type) {
3455 case NEXTHOP_TYPE_IPV4:
3456 case NEXTHOP_TYPE_IPV4_IFINDEX:
d62a17ae 3457 vty_out(vty, "%-20s %2d ",
dd127197 3458 inet_ntoa(rinfo->nh.gate.ipv4),
d62a17ae 3459 rinfo->metric);
3f5682c8
DS
3460 break;
3461 case NEXTHOP_TYPE_IFINDEX:
d62a17ae 3462 vty_out(vty,
3463 "0.0.0.0 %2d ",
3464 rinfo->metric);
3f5682c8
DS
3465 break;
3466 case NEXTHOP_TYPE_BLACKHOLE:
3467 vty_out(vty,
3468 "blackhole %2d ",
3469 rinfo->metric);
3470 break;
3471 case NEXTHOP_TYPE_IPV6:
3472 case NEXTHOP_TYPE_IPV6_IFINDEX:
3473 vty_out(vty,
3474 "V6 Address Hidden %2d ",
3475 rinfo->metric);
3476 break;
3477 }
d62a17ae 3478
3479 /* Route which exist in kernel routing table. */
3480 if ((rinfo->type == ZEBRA_ROUTE_RIP)
3481 && (rinfo->sub_type == RIP_ROUTE_RTE)) {
3482 vty_out(vty, "%-15s ",
3483 inet_ntoa(rinfo->from));
3484 vty_out(vty, "%3" ROUTE_TAG_PRI " ",
3485 (route_tag_t)rinfo->tag);
3486 rip_vty_out_uptime(vty, rinfo);
3487 } else if (rinfo->metric
3488 == RIP_METRIC_INFINITY) {
3489 vty_out(vty, "self ");
3490 vty_out(vty, "%3" ROUTE_TAG_PRI " ",
3491 (route_tag_t)rinfo->tag);
3492 rip_vty_out_uptime(vty, rinfo);
3493 } else {
3494 if (rinfo->external_metric) {
3495 len = vty_out(
3496 vty, "self (%s:%d)",
3497 zebra_route_string(
3498 rinfo->type),
3499 rinfo->external_metric);
3500 len = 16 - len;
3501 if (len > 0)
3502 vty_out(vty, "%*s", len,
3503 " ");
3504 } else
3505 vty_out(vty,
3506 "self ");
3507 vty_out(vty, "%3" ROUTE_TAG_PRI,
3508 (route_tag_t)rinfo->tag);
3509 }
3510
3511 vty_out(vty, "\n");
3512 }
3513 return CMD_SUCCESS;
718e3744 3514}
3515
16705130 3516/* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3517DEFUN (show_ip_rip_status,
3518 show_ip_rip_status_cmd,
3519 "show ip rip status",
718e3744 3520 SHOW_STR
3521 IP_STR
16705130 3522 "Show RIP routes\n"
718e3744 3523 "IP routing protocol process parameters and statistics\n")
3524{
f4e14fdb 3525 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 3526 struct interface *ifp;
3527 struct rip_interface *ri;
3528 extern const struct message ri_version_msg[];
3529 const char *send_version;
3530 const char *receive_version;
3531
3532 if (!rip)
3533 return CMD_SUCCESS;
3534
3535 vty_out(vty, "Routing Protocol is \"rip\"\n");
3536 vty_out(vty, " Sending updates every %ld seconds with +/-50%%,",
3537 rip->update_time);
3538 vty_out(vty, " next due in %lu seconds\n",
3539 thread_timer_remain_second(rip->t_update));
3540 vty_out(vty, " Timeout after %ld seconds,", rip->timeout_time);
3541 vty_out(vty, " garbage collect after %ld seconds\n", rip->garbage_time);
3542
3543 /* Filtering status show. */
3544 config_show_distribute(vty);
3545
3546 /* Default metric information. */
3547 vty_out(vty, " Default redistribution metric is %d\n",
3548 rip->default_metric);
3549
3550 /* Redistribute information. */
3551 vty_out(vty, " Redistributing:");
3552 config_write_rip_redistribute(vty, 0);
3553 vty_out(vty, "\n");
3554
3555 vty_out(vty, " Default version control: send version %s,",
3556 lookup_msg(ri_version_msg, rip->version_send, NULL));
3557 if (rip->version_recv == RI_RIP_VERSION_1_AND_2)
3558 vty_out(vty, " receive any version \n");
3559 else
3560 vty_out(vty, " receive version %s \n",
3561 lookup_msg(ri_version_msg, rip->version_recv, NULL));
3562
3563 vty_out(vty, " Interface Send Recv Key-chain\n");
3564
451fda4f 3565 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 3566 ri = ifp->info;
3567
3568 if (!ri->running)
3569 continue;
3570
3571 if (ri->enable_network || ri->enable_interface) {
3572 if (ri->ri_send == RI_RIP_UNSPEC)
3573 send_version =
3574 lookup_msg(ri_version_msg,
3575 rip->version_send, NULL);
3576 else
3577 send_version = lookup_msg(ri_version_msg,
3578 ri->ri_send, NULL);
3579
3580 if (ri->ri_receive == RI_RIP_UNSPEC)
3581 receive_version =
3582 lookup_msg(ri_version_msg,
3583 rip->version_recv, NULL);
3584 else
3585 receive_version = lookup_msg(
3586 ri_version_msg, ri->ri_receive, NULL);
3587
3588 vty_out(vty, " %-17s%-3s %-3s %s\n", ifp->name,
3589 send_version, receive_version,
3590 ri->key_chain ? ri->key_chain : "");
3591 }
3592 }
718e3744 3593
d62a17ae 3594 vty_out(vty, " Routing for Networks:\n");
3595 config_write_rip_network(vty, 0);
718e3744 3596
718e3744 3597 {
d62a17ae 3598 int found_passive = 0;
451fda4f 3599 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 3600 ri = ifp->info;
3601
3602 if ((ri->enable_network || ri->enable_interface)
3603 && ri->passive) {
3604 if (!found_passive) {
3605 vty_out(vty,
3606 " Passive Interface(s):\n");
3607 found_passive = 1;
3608 }
3609 vty_out(vty, " %s\n", ifp->name);
3610 }
3611 }
718e3744 3612 }
3613
d62a17ae 3614 vty_out(vty, " Routing Information Sources:\n");
3615 vty_out(vty,
3616 " Gateway BadPackets BadRoutes Distance Last Update\n");
3617 rip_peer_display(vty);
718e3744 3618
d62a17ae 3619 rip_distance_show(vty);
718e3744 3620
d62a17ae 3621 return CMD_SUCCESS;
3622}
718e3744 3623
d62a17ae 3624/* RIP configuration write function. */
3625static int config_write_rip(struct vty *vty)
3626{
3627 int write = 0;
3628 struct route_node *rn;
3629 struct rip_distance *rdistance;
3630
3631 if (rip) {
3632 /* Router RIP statement. */
3633 vty_out(vty, "router rip\n");
3634 write++;
3635
3636 /* RIP version statement. Default is RIP version 2. */
3637 if (rip->version_send != RI_RIP_VERSION_2
3638 || rip->version_recv != RI_RIP_VERSION_1_AND_2)
3639 vty_out(vty, " version %d\n", rip->version_send);
3640
3641 /* RIP timer configuration. */
3642 if (rip->update_time != RIP_UPDATE_TIMER_DEFAULT
3643 || rip->timeout_time != RIP_TIMEOUT_TIMER_DEFAULT
3644 || rip->garbage_time != RIP_GARBAGE_TIMER_DEFAULT)
3645 vty_out(vty, " timers basic %lu %lu %lu\n",
3646 rip->update_time, rip->timeout_time,
3647 rip->garbage_time);
3648
3649 /* Default information configuration. */
3650 if (rip->default_information) {
3651 if (rip->default_information_route_map)
3652 vty_out(vty,
3653 " default-information originate route-map %s\n",
3654 rip->default_information_route_map);
3655 else
3656 vty_out(vty,
3657 " default-information originate\n");
3658 }
16705130 3659
d62a17ae 3660 /* Redistribute configuration. */
3661 config_write_rip_redistribute(vty, 1);
3662
3663 /* RIP offset-list configuration. */
3664 config_write_rip_offset_list(vty);
3665
3666 /* RIP enabled network and interface configuration. */
3667 config_write_rip_network(vty, 1);
3668
3669 /* RIP default metric configuration */
3670 if (rip->default_metric != RIP_DEFAULT_METRIC_DEFAULT)
3671 vty_out(vty, " default-metric %d\n",
3672 rip->default_metric);
3673
3674 /* Distribute configuration. */
3675 write += config_write_distribute(vty);
3676
3677 /* Interface routemap configuration */
3678 write += config_write_if_rmap(vty);
3679
3680 /* Distance configuration. */
3681 if (rip->distance)
3682 vty_out(vty, " distance %d\n", rip->distance);
3683
3684 /* RIP source IP prefix distance configuration. */
3685 for (rn = route_top(rip_distance_table); rn;
3686 rn = route_next(rn))
3687 if ((rdistance = rn->info) != NULL)
3688 vty_out(vty, " distance %d %s/%d %s\n",
3689 rdistance->distance,
3690 inet_ntoa(rn->p.u.prefix4),
3691 rn->p.prefixlen,
3692 rdistance->access_list
3693 ? rdistance->access_list
3694 : "");
3695
3696 /* ECMP configuration. */
3697 if (rip->ecmp)
3698 vty_out(vty, " allow-ecmp\n");
3699
3700 /* RIP static route configuration. */
3701 for (rn = route_top(rip->route); rn; rn = route_next(rn))
3702 if (rn->info)
3703 vty_out(vty, " route %s/%d\n",
3704 inet_ntoa(rn->p.u.prefix4),
3705 rn->p.prefixlen);
3706 }
3707 return write;
3708}
718e3744 3709
d62a17ae 3710/* RIP node structure. */
3711static struct cmd_node rip_node = {RIP_NODE, "%s(config-router)# ", 1};
718e3744 3712
d62a17ae 3713/* Distribute-list update functions. */
3714static void rip_distribute_update(struct distribute *dist)
3715{
3716 struct interface *ifp;
3717 struct rip_interface *ri;
3718 struct access_list *alist;
3719 struct prefix_list *plist;
8478ae7e 3720
d62a17ae 3721 if (!dist->ifname)
3722 return;
718e3744 3723
d62a17ae 3724 ifp = if_lookup_by_name(dist->ifname, VRF_DEFAULT);
3725 if (ifp == NULL)
3726 return;
718e3744 3727
d62a17ae 3728 ri = ifp->info;
6b0655a2 3729
d62a17ae 3730 if (dist->list[DISTRIBUTE_V4_IN]) {
3731 alist = access_list_lookup(AFI_IP,
3732 dist->list[DISTRIBUTE_V4_IN]);
3733 if (alist)
3734 ri->list[RIP_FILTER_IN] = alist;
3735 else
3736 ri->list[RIP_FILTER_IN] = NULL;
3737 } else
3738 ri->list[RIP_FILTER_IN] = NULL;
3739
3740 if (dist->list[DISTRIBUTE_V4_OUT]) {
3741 alist = access_list_lookup(AFI_IP,
3742 dist->list[DISTRIBUTE_V4_OUT]);
3743 if (alist)
3744 ri->list[RIP_FILTER_OUT] = alist;
3745 else
3746 ri->list[RIP_FILTER_OUT] = NULL;
3747 } else
3748 ri->list[RIP_FILTER_OUT] = NULL;
3749
3750 if (dist->prefix[DISTRIBUTE_V4_IN]) {
3751 plist = prefix_list_lookup(AFI_IP,
3752 dist->prefix[DISTRIBUTE_V4_IN]);
3753 if (plist)
3754 ri->prefix[RIP_FILTER_IN] = plist;
3755 else
3756 ri->prefix[RIP_FILTER_IN] = NULL;
3757 } else
3758 ri->prefix[RIP_FILTER_IN] = NULL;
3759
3760 if (dist->prefix[DISTRIBUTE_V4_OUT]) {
3761 plist = prefix_list_lookup(AFI_IP,
3762 dist->prefix[DISTRIBUTE_V4_OUT]);
3763 if (plist)
3764 ri->prefix[RIP_FILTER_OUT] = plist;
3765 else
3766 ri->prefix[RIP_FILTER_OUT] = NULL;
3767 } else
3768 ri->prefix[RIP_FILTER_OUT] = NULL;
3769}
3770
3771void rip_distribute_update_interface(struct interface *ifp)
3772{
3773 struct distribute *dist;
3774
3775 dist = distribute_lookup(ifp->name);
3776 if (dist)
3777 rip_distribute_update(dist);
718e3744 3778}
3779
3780/* Update all interface's distribute list. */
02ff83c5 3781/* ARGSUSED */
d62a17ae 3782static void rip_distribute_update_all(struct prefix_list *notused)
718e3744 3783{
f4e14fdb 3784 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 3785 struct interface *ifp;
718e3744 3786
451fda4f 3787 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 3788 rip_distribute_update_interface(ifp);
718e3744 3789}
11dde9c2 3790/* ARGSUSED */
d62a17ae 3791static void rip_distribute_update_all_wrapper(struct access_list *notused)
11dde9c2 3792{
d62a17ae 3793 rip_distribute_update_all(NULL);
11dde9c2 3794}
6b0655a2 3795
718e3744 3796/* Delete all added rip route. */
d62a17ae 3797void rip_clean(void)
718e3744 3798{
d62a17ae 3799 int i;
3800 struct route_node *rp;
3801 struct rip_info *rinfo = NULL;
3802 struct list *list = NULL;
3803 struct listnode *listnode = NULL;
3804
3805 if (rip) {
3806 QOBJ_UNREG(rip);
3807
3808 /* Clear RIP routes */
3809 for (rp = route_top(rip->table); rp; rp = route_next(rp))
3810 if ((list = rp->info) != NULL) {
3811 rinfo = listgetdata(listhead(list));
3812 if (rip_route_rte(rinfo))
3813 rip_zebra_ipv4_delete(rp);
3814
3815 for (ALL_LIST_ELEMENTS_RO(list, listnode,
3816 rinfo)) {
3817 RIP_TIMER_OFF(rinfo->t_timeout);
3818 RIP_TIMER_OFF(rinfo->t_garbage_collect);
3819 rip_info_free(rinfo);
3820 }
affe9e99 3821 list_delete_and_null(&list);
d62a17ae 3822 rp->info = NULL;
3823 route_unlock_node(rp);
3824 }
3825
3826 /* Cancel RIP related timers. */
3827 RIP_TIMER_OFF(rip->t_update);
3828 RIP_TIMER_OFF(rip->t_triggered_update);
3829 RIP_TIMER_OFF(rip->t_triggered_interval);
3830
3831 /* Cancel read thread. */
3832 THREAD_READ_OFF(rip->t_read);
3833
3834 /* Close RIP socket. */
3835 if (rip->sock >= 0) {
3836 close(rip->sock);
3837 rip->sock = -1;
3838 }
718e3744 3839
00c9a53d 3840 stream_free(rip->obuf);
d62a17ae 3841 /* Static RIP route configuration. */
3842 for (rp = route_top(rip->route); rp; rp = route_next(rp))
3843 if (rp->info) {
3844 rp->info = NULL;
3845 route_unlock_node(rp);
3846 }
3847
3848 /* RIP neighbor configuration. */
3849 for (rp = route_top(rip->neighbor); rp; rp = route_next(rp))
3850 if (rp->info) {
3851 rp->info = NULL;
3852 route_unlock_node(rp);
3853 }
3854
3855 /* Redistribute related clear. */
3856 if (rip->default_information_route_map)
3857 free(rip->default_information_route_map);
3858
3859 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
3860 if (rip->route_map[i].name)
3861 free(rip->route_map[i].name);
3862
3863 XFREE(MTYPE_ROUTE_TABLE, rip->table);
3864 XFREE(MTYPE_ROUTE_TABLE, rip->route);
3865 XFREE(MTYPE_ROUTE_TABLE, rip->neighbor);
3866
3867 XFREE(MTYPE_RIP, rip);
3868 rip = NULL;
3869 }
3870
3871 rip_clean_network();
3872 rip_passive_nondefault_clean();
3873 rip_offset_clean();
3874 rip_interfaces_clean();
3875 rip_distance_reset();
3876 rip_redistribute_clean();
718e3744 3877}
3878
3879/* Reset all values to the default settings. */
d62a17ae 3880void rip_reset(void)
718e3744 3881{
d62a17ae 3882 /* Reset global counters. */
3883 rip_global_route_changes = 0;
3884 rip_global_queries = 0;
718e3744 3885
d62a17ae 3886 /* Call ripd related reset functions. */
3887 rip_debug_reset();
3888 rip_route_map_reset();
718e3744 3889
d62a17ae 3890 /* Call library reset functions. */
3891 vty_reset();
3892 access_list_reset();
3893 prefix_list_reset();
718e3744 3894
d62a17ae 3895 distribute_list_reset();
718e3744 3896
d62a17ae 3897 rip_interfaces_reset();
3898 rip_distance_reset();
718e3744 3899
d62a17ae 3900 rip_zclient_reset();
718e3744 3901}
3902
d62a17ae 3903static void rip_if_rmap_update(struct if_rmap *if_rmap)
16705130 3904{
d62a17ae 3905 struct interface *ifp;
3906 struct rip_interface *ri;
3907 struct route_map *rmap;
16705130 3908
d62a17ae 3909 ifp = if_lookup_by_name(if_rmap->ifname, VRF_DEFAULT);
3910 if (ifp == NULL)
3911 return;
16705130 3912
d62a17ae 3913 ri = ifp->info;
16705130 3914
d62a17ae 3915 if (if_rmap->routemap[IF_RMAP_IN]) {
3916 rmap = route_map_lookup_by_name(if_rmap->routemap[IF_RMAP_IN]);
3917 if (rmap)
3918 ri->routemap[IF_RMAP_IN] = rmap;
3919 else
3920 ri->routemap[IF_RMAP_IN] = NULL;
3921 } else
3922 ri->routemap[RIP_FILTER_IN] = NULL;
16705130 3923
d62a17ae 3924 if (if_rmap->routemap[IF_RMAP_OUT]) {
3925 rmap = route_map_lookup_by_name(if_rmap->routemap[IF_RMAP_OUT]);
3926 if (rmap)
3927 ri->routemap[IF_RMAP_OUT] = rmap;
3928 else
3929 ri->routemap[IF_RMAP_OUT] = NULL;
3930 } else
3931 ri->routemap[RIP_FILTER_OUT] = NULL;
16705130 3932}
3933
d62a17ae 3934void rip_if_rmap_update_interface(struct interface *ifp)
16705130 3935{
d62a17ae 3936 struct if_rmap *if_rmap;
16705130 3937
d62a17ae 3938 if_rmap = if_rmap_lookup(ifp->name);
3939 if (if_rmap)
3940 rip_if_rmap_update(if_rmap);
16705130 3941}
3942
d62a17ae 3943static void rip_routemap_update_redistribute(void)
16705130 3944{
d62a17ae 3945 int i;
16705130 3946
d62a17ae 3947 if (rip) {
3948 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
3949 if (rip->route_map[i].name)
3950 rip->route_map[i].map =
3951 route_map_lookup_by_name(
3952 rip->route_map[i].name);
3953 }
16705130 3954 }
16705130 3955}
3956
11dde9c2 3957/* ARGSUSED */
d62a17ae 3958static void rip_routemap_update(const char *notused)
16705130 3959{
f4e14fdb 3960 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 3961 struct interface *ifp;
16705130 3962
451fda4f 3963 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 3964 rip_if_rmap_update_interface(ifp);
16705130 3965
d62a17ae 3966 rip_routemap_update_redistribute();
16705130 3967}
3968
718e3744 3969/* Allocate new rip structure and set default value. */
d62a17ae 3970void rip_init(void)
3971{
3972 /* Install top nodes. */
3973 install_node(&rip_node, config_write_rip);
3974
3975 /* Install rip commands. */
3976 install_element(VIEW_NODE, &show_ip_rip_cmd);
3977 install_element(VIEW_NODE, &show_ip_rip_status_cmd);
3978 install_element(CONFIG_NODE, &router_rip_cmd);
3979 install_element(CONFIG_NODE, &no_router_rip_cmd);
3980
3981 install_default(RIP_NODE);
3982 install_element(RIP_NODE, &rip_version_cmd);
3983 install_element(RIP_NODE, &no_rip_version_cmd);
3984 install_element(RIP_NODE, &rip_default_metric_cmd);
3985 install_element(RIP_NODE, &no_rip_default_metric_cmd);
3986 install_element(RIP_NODE, &rip_timers_cmd);
3987 install_element(RIP_NODE, &no_rip_timers_cmd);
3988 install_element(RIP_NODE, &rip_route_cmd);
3989 install_element(RIP_NODE, &no_rip_route_cmd);
3990 install_element(RIP_NODE, &rip_distance_cmd);
3991 install_element(RIP_NODE, &no_rip_distance_cmd);
3992 install_element(RIP_NODE, &rip_distance_source_cmd);
3993 install_element(RIP_NODE, &no_rip_distance_source_cmd);
3994 install_element(RIP_NODE, &rip_distance_source_access_list_cmd);
3995 install_element(RIP_NODE, &no_rip_distance_source_access_list_cmd);
3996 install_element(RIP_NODE, &rip_allow_ecmp_cmd);
3997 install_element(RIP_NODE, &no_rip_allow_ecmp_cmd);
3998
3999 /* Debug related init. */
4000 rip_debug_init();
4001
4002 /* Access list install. */
4003 access_list_init();
4004 access_list_add_hook(rip_distribute_update_all_wrapper);
4005 access_list_delete_hook(rip_distribute_update_all_wrapper);
4006
4007 /* Prefix list initialize.*/
4008 prefix_list_init();
4009 prefix_list_add_hook(rip_distribute_update_all);
4010 prefix_list_delete_hook(rip_distribute_update_all);
4011
4012 /* Distribute list install. */
4013 distribute_list_init(RIP_NODE);
4014 distribute_list_add_hook(rip_distribute_update);
4015 distribute_list_delete_hook(rip_distribute_update);
4016
4017 /* Route-map */
4018 rip_route_map_init();
4019 rip_offset_init();
4020
4021 route_map_add_hook(rip_routemap_update);
4022 route_map_delete_hook(rip_routemap_update);
4023
4024 if_rmap_init(RIP_NODE);
4025 if_rmap_hook_add(rip_if_rmap_update);
4026 if_rmap_hook_delete(rip_if_rmap_update);
4027
4028 /* Distance control. */
4029 rip_distance_table = route_table_init();
718e3744 4030}