]> git.proxmox.com Git - mirror_frr.git/blame - ripd/ripd.c
ripd: Convert zlog_err to zlog_ferr for LIB_ERR_XXX
[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"
77cbe4a1 43#include "lib_errors.h"
718e3744 44
45#include "ripd/ripd.h"
46#include "ripd/rip_debug.h"
47
f6eacff4
DL
48DEFINE_QOBJ_TYPE(rip)
49
0b3acf4f 50/* UDP receive buffer size */
51#define RIP_UDP_RCV_BUF 41600
52
718e3744 53/* RIP Structure. */
54struct rip *rip = NULL;
55
56/* RIP neighbor address table. */
57struct route_table *rip_neighbor_table;
58
59/* RIP route changes. */
60long rip_global_route_changes = 0;
61
62/* RIP queries. */
63long rip_global_queries = 0;
6b0655a2 64
718e3744 65/* Prototypes. */
d62a17ae 66static void rip_event(enum rip_event, int);
67static void rip_output_process(struct connected *, struct sockaddr_in *, int,
d7c0a89a 68 uint8_t);
d62a17ae 69static int rip_triggered_update(struct thread *);
70static int rip_update_jitter(unsigned long);
6b0655a2 71
718e3744 72/* RIP output routes type. */
d62a17ae 73enum { rip_all_route, rip_changed_route };
6b0655a2 74
718e3744 75/* RIP command strings. */
d62a17ae 76static const struct message rip_msg[] = {{RIP_REQUEST, "REQUEST"},
77 {RIP_RESPONSE, "RESPONSE"},
78 {RIP_TRACEON, "TRACEON"},
79 {RIP_TRACEOFF, "TRACEOFF"},
80 {RIP_POLL, "POLL"},
81 {RIP_POLL_ENTRY, "POLL ENTRY"},
82 {0}};
6b0655a2 83
718e3744 84/* Utility function to set boradcast option to the socket. */
d62a17ae 85static int sockopt_broadcast(int sock)
718e3744 86{
d62a17ae 87 int ret;
88 int on = 1;
718e3744 89
d62a17ae 90 ret = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&on,
91 sizeof on);
92 if (ret < 0) {
93 zlog_warn("can't set sockopt SO_BROADCAST to socket %d", sock);
94 return -1;
95 }
96 return 0;
718e3744 97}
98
d62a17ae 99static int rip_route_rte(struct rip_info *rinfo)
718e3744 100{
d62a17ae 101 return (rinfo->type == ZEBRA_ROUTE_RIP
102 && rinfo->sub_type == RIP_ROUTE_RTE);
718e3744 103}
104
d62a17ae 105static struct rip_info *rip_info_new(void)
718e3744 106{
d62a17ae 107 return XCALLOC(MTYPE_RIP_INFO, sizeof(struct rip_info));
718e3744 108}
109
d62a17ae 110void rip_info_free(struct rip_info *rinfo)
718e3744 111{
d62a17ae 112 XFREE(MTYPE_RIP_INFO, rinfo);
718e3744 113}
114
115/* RIP route garbage collect timer. */
d62a17ae 116static int rip_garbage_collect(struct thread *t)
718e3744 117{
d62a17ae 118 struct rip_info *rinfo;
119 struct route_node *rp;
120
121 rinfo = THREAD_ARG(t);
122 rinfo->t_garbage_collect = NULL;
718e3744 123
d62a17ae 124 /* Off timeout timer. */
125 RIP_TIMER_OFF(rinfo->t_timeout);
718e3744 126
d62a17ae 127 /* Get route_node pointer. */
128 rp = rinfo->rp;
718e3744 129
d62a17ae 130 /* Unlock route_node. */
131 listnode_delete(rp->info, rinfo);
132 if (list_isempty((struct list *)rp->info)) {
acdf5e25 133 list_delete_and_null((struct list **)&rp->info);
d62a17ae 134 route_unlock_node(rp);
135 }
718e3744 136
d62a17ae 137 /* Free RIP routing information. */
138 rip_info_free(rinfo);
718e3744 139
d62a17ae 140 return 0;
718e3744 141}
142
d62a17ae 143static void rip_timeout_update(struct rip_info *rinfo);
bce8e868
LF
144
145/* Add new route to the ECMP list.
8478ae7e
LF
146 * RETURN: the new entry added in the list, or NULL if it is not the first
147 * entry and ECMP is not allowed.
bce8e868 148 */
d62a17ae 149struct rip_info *rip_ecmp_add(struct rip_info *rinfo_new)
718e3744 150{
d62a17ae 151 struct route_node *rp = rinfo_new->rp;
152 struct rip_info *rinfo = NULL;
153 struct list *list = NULL;
718e3744 154
d62a17ae 155 if (rp->info == NULL)
156 rp->info = list_new();
157 list = (struct list *)rp->info;
bce8e868 158
d62a17ae 159 /* If ECMP is not allowed and some entry already exists in the list,
160 * do nothing. */
161 if (listcount(list) && !rip->ecmp)
162 return NULL;
8478ae7e 163
d62a17ae 164 rinfo = rip_info_new();
165 memcpy(rinfo, rinfo_new, sizeof(struct rip_info));
166 listnode_add(list, rinfo);
bce8e868 167
d62a17ae 168 if (rip_route_rte(rinfo)) {
169 rip_timeout_update(rinfo);
170 rip_zebra_ipv4_add(rp);
171 }
bce8e868 172
d62a17ae 173 /* Set the route change flag on the first entry. */
174 rinfo = listgetdata(listhead(list));
175 SET_FLAG(rinfo->flags, RIP_RTF_CHANGED);
bce8e868 176
d62a17ae 177 /* Signal the output process to trigger an update (see section 2.5). */
178 rip_event(RIP_TRIGGERED_UPDATE, 0);
718e3744 179
d62a17ae 180 return rinfo;
bce8e868
LF
181}
182
183/* Replace the ECMP list with the new route.
184 * RETURN: the new entry added in the list
185 */
d62a17ae 186struct rip_info *rip_ecmp_replace(struct rip_info *rinfo_new)
187{
188 struct route_node *rp = rinfo_new->rp;
189 struct list *list = (struct list *)rp->info;
190 struct rip_info *rinfo = NULL, *tmp_rinfo = NULL;
191 struct listnode *node = NULL, *nextnode = NULL;
192
193 if (list == NULL || listcount(list) == 0)
194 return rip_ecmp_add(rinfo_new);
195
196 /* Get the first entry */
197 rinfo = listgetdata(listhead(list));
198
199 /* Learnt route replaced by a local one. Delete it from zebra. */
200 if (rip_route_rte(rinfo) && !rip_route_rte(rinfo_new))
201 if (CHECK_FLAG(rinfo->flags, RIP_RTF_FIB))
202 rip_zebra_ipv4_delete(rp);
203
204 /* Re-use the first entry, and delete the others. */
205 for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo))
206 if (tmp_rinfo != rinfo) {
207 RIP_TIMER_OFF(tmp_rinfo->t_timeout);
208 RIP_TIMER_OFF(tmp_rinfo->t_garbage_collect);
209 list_delete_node(list, node);
210 rip_info_free(tmp_rinfo);
211 }
718e3744 212
d62a17ae 213 RIP_TIMER_OFF(rinfo->t_timeout);
214 RIP_TIMER_OFF(rinfo->t_garbage_collect);
215 memcpy(rinfo, rinfo_new, sizeof(struct rip_info));
718e3744 216
d62a17ae 217 if (rip_route_rte(rinfo)) {
218 rip_timeout_update(rinfo);
219 /* The ADD message implies an update. */
220 rip_zebra_ipv4_add(rp);
221 }
718e3744 222
d62a17ae 223 /* Set the route change flag. */
224 SET_FLAG(rinfo->flags, RIP_RTF_CHANGED);
718e3744 225
d62a17ae 226 /* Signal the output process to trigger an update (see section 2.5). */
227 rip_event(RIP_TRIGGERED_UPDATE, 0);
718e3744 228
d62a17ae 229 return rinfo;
bce8e868
LF
230}
231
232/* Delete one route from the ECMP list.
233 * RETURN:
234 * null - the entry is freed, and other entries exist in the list
235 * the entry - the entry is the last one in the list; its metric is set
236 * to INFINITY, and the garbage collector is started for it
237 */
d62a17ae 238struct rip_info *rip_ecmp_delete(struct rip_info *rinfo)
239{
240 struct route_node *rp = rinfo->rp;
241 struct list *list = (struct list *)rp->info;
242
243 RIP_TIMER_OFF(rinfo->t_timeout);
244
245 if (listcount(list) > 1) {
246 /* Some other ECMP entries still exist. Just delete this entry.
247 */
248 RIP_TIMER_OFF(rinfo->t_garbage_collect);
249 listnode_delete(list, rinfo);
250 if (rip_route_rte(rinfo)
251 && CHECK_FLAG(rinfo->flags, RIP_RTF_FIB))
252 /* The ADD message implies the update. */
253 rip_zebra_ipv4_add(rp);
254 rip_info_free(rinfo);
255 rinfo = NULL;
256 } else {
257 assert(rinfo == listgetdata(listhead(list)));
258
259 /* This is the only entry left in the list. We must keep it in
260 * the list for garbage collection time, with INFINITY metric.
261 */
262
263 rinfo->metric = RIP_METRIC_INFINITY;
264 RIP_TIMER_ON(rinfo->t_garbage_collect, rip_garbage_collect,
265 rip->garbage_time);
266
267 if (rip_route_rte(rinfo)
268 && CHECK_FLAG(rinfo->flags, RIP_RTF_FIB))
269 rip_zebra_ipv4_delete(rp);
270 }
bce8e868 271
d62a17ae 272 /* Set the route change flag on the first entry. */
273 rinfo = listgetdata(listhead(list));
274 SET_FLAG(rinfo->flags, RIP_RTF_CHANGED);
bce8e868 275
d62a17ae 276 /* Signal the output process to trigger an update (see section 2.5). */
277 rip_event(RIP_TRIGGERED_UPDATE, 0);
bce8e868 278
d62a17ae 279 return rinfo;
bce8e868
LF
280}
281
282/* Timeout RIP routes. */
d62a17ae 283static int rip_timeout(struct thread *t)
bce8e868 284{
d62a17ae 285 rip_ecmp_delete((struct rip_info *)THREAD_ARG(t));
286 return 0;
718e3744 287}
288
d62a17ae 289static void rip_timeout_update(struct rip_info *rinfo)
718e3744 290{
d62a17ae 291 if (rinfo->metric != RIP_METRIC_INFINITY) {
292 RIP_TIMER_OFF(rinfo->t_timeout);
293 RIP_TIMER_ON(rinfo->t_timeout, rip_timeout, rip->timeout_time);
294 }
295}
296
297static int rip_filter(int rip_distribute, struct prefix_ipv4 *p,
298 struct rip_interface *ri)
299{
300 struct distribute *dist;
301 struct access_list *alist;
302 struct prefix_list *plist;
303 int distribute = rip_distribute == RIP_FILTER_OUT ? DISTRIBUTE_V4_OUT
304 : DISTRIBUTE_V4_IN;
305 const char *inout = rip_distribute == RIP_FILTER_OUT ? "out" : "in";
306
307 /* Input distribute-list filtering. */
308 if (ri->list[rip_distribute]) {
309 if (access_list_apply(ri->list[rip_distribute],
310 (struct prefix *)p)
311 == FILTER_DENY) {
312 if (IS_RIP_DEBUG_PACKET)
313 zlog_debug("%s/%d filtered by distribute %s",
314 inet_ntoa(p->prefix), p->prefixlen,
315 inout);
316 return -1;
718e3744 317 }
718e3744 318 }
d62a17ae 319 if (ri->prefix[rip_distribute]) {
320 if (prefix_list_apply(ri->prefix[rip_distribute],
321 (struct prefix *)p)
322 == PREFIX_DENY) {
323 if (IS_RIP_DEBUG_PACKET)
324 zlog_debug("%s/%d filtered by prefix-list %s",
325 inet_ntoa(p->prefix), p->prefixlen,
326 inout);
327 return -1;
718e3744 328 }
718e3744 329 }
d62a17ae 330
331 /* All interface filter check. */
332 dist = distribute_lookup(NULL);
333 if (dist) {
334 if (dist->list[distribute]) {
335 alist = access_list_lookup(AFI_IP,
336 dist->list[distribute]);
337
338 if (alist) {
339 if (access_list_apply(alist, (struct prefix *)p)
340 == FILTER_DENY) {
341 if (IS_RIP_DEBUG_PACKET)
342 zlog_debug(
343 "%s/%d filtered by distribute %s",
344 inet_ntoa(p->prefix),
345 p->prefixlen, inout);
346 return -1;
347 }
348 }
349 }
350 if (dist->prefix[distribute]) {
351 plist = prefix_list_lookup(AFI_IP,
352 dist->prefix[distribute]);
353
354 if (plist) {
355 if (prefix_list_apply(plist, (struct prefix *)p)
356 == PREFIX_DENY) {
357 if (IS_RIP_DEBUG_PACKET)
358 zlog_debug(
359 "%s/%d filtered by prefix-list %s",
360 inet_ntoa(p->prefix),
361 p->prefixlen, inout);
362 return -1;
363 }
364 }
365 }
366 }
367 return 0;
718e3744 368}
369
370/* Check nexthop address validity. */
d62a17ae 371static int rip_nexthop_check(struct in_addr *addr)
718e3744 372{
f4e14fdb 373 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 374 struct interface *ifp;
f4e14fdb 375 struct listnode *cnode;
d62a17ae 376 struct connected *ifc;
377 struct prefix *p;
718e3744 378
d62a17ae 379 /* If nexthop address matches local configured address then it is
380 invalid nexthop. */
b2d7c082 381
451fda4f 382 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 383 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) {
384 p = ifc->address;
718e3744 385
d62a17ae 386 if (p->family == AF_INET
387 && IPV4_ADDR_SAME(&p->u.prefix4, addr))
388 return -1;
389 }
718e3744 390 }
d62a17ae 391 return 0;
718e3744 392}
393
394/* RIP add route to routing table. */
d62a17ae 395static void rip_rte_process(struct rte *rte, struct sockaddr_in *from,
396 struct interface *ifp)
397{
398 int ret;
399 struct prefix_ipv4 p;
400 struct route_node *rp;
401 struct rip_info *rinfo = NULL, newinfo;
402 struct rip_interface *ri;
403 struct in_addr *nexthop;
404 int same = 0;
405 unsigned char old_dist, new_dist;
406 struct list *list = NULL;
407 struct listnode *node = NULL;
408
409 /* Make prefix structure. */
410 memset(&p, 0, sizeof(struct prefix_ipv4));
411 p.family = AF_INET;
412 p.prefix = rte->prefix;
413 p.prefixlen = ip_masklen(rte->mask);
414
415 /* Make sure mask is applied. */
416 apply_mask_ipv4(&p);
417
418 /* Apply input filters. */
419 ri = ifp->info;
718e3744 420
d62a17ae 421 ret = rip_filter(RIP_FILTER_IN, &p, ri);
422 if (ret < 0)
423 return;
424
425 memset(&newinfo, 0, sizeof(newinfo));
426 newinfo.type = ZEBRA_ROUTE_RIP;
427 newinfo.sub_type = RIP_ROUTE_RTE;
dd127197 428 newinfo.nh.gate.ipv4 = rte->nexthop;
d62a17ae 429 newinfo.from = from->sin_addr;
dd127197
DS
430 newinfo.nh.ifindex = ifp->ifindex;
431 newinfo.nh.type = NEXTHOP_TYPE_IPV4_IFINDEX;
d62a17ae 432 newinfo.metric = rte->metric;
433 newinfo.metric_out = rte->metric; /* XXX */
434 newinfo.tag = ntohs(rte->tag); /* XXX */
435
436 /* Modify entry according to the interface routemap. */
437 if (ri->routemap[RIP_FILTER_IN]) {
438 int ret;
439
440 /* The object should be of the type of rip_info */
441 ret = route_map_apply(ri->routemap[RIP_FILTER_IN],
442 (struct prefix *)&p, RMAP_RIP, &newinfo);
443
444 if (ret == RMAP_DENYMATCH) {
445 if (IS_RIP_DEBUG_PACKET)
446 zlog_debug(
447 "RIP %s/%d is filtered by route-map in",
448 inet_ntoa(p.prefix), p.prefixlen);
449 return;
450 }
451
452 /* Get back the object */
453 rte->nexthop = newinfo.nexthop_out;
454 rte->tag = htons(newinfo.tag_out); /* XXX */
996c9314
LB
455 rte->metric = 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];
d7c0a89a
QY
679 uint8_t netmask = 0;
680 uint8_t *p;
d62a17ae 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)) {
d7c0a89a 702 p = (uint8_t *)&rte->prefix;
d62a17ae 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);
d7c0a89a
QY
723 zlog_debug(" Sequence Number %ld",
724 (unsigned long)ntohl(
725 md5->sequence));
d62a17ae 726 } else if (rte->tag == htons(RIP_AUTH_DATA)) {
d7c0a89a 727 p = (uint8_t *)&rte->prefix;
d62a17ae 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),
d7c0a89a 757 (unsigned long)ntohl(rte->metric));
d62a17ae 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),
d7c0a89a 765 (unsigned 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{
d7c0a89a 775 uint32_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;
0961ea93 803 char *auth_str = (char *)rte + offsetof(struct rte, prefix);
d62a17ae 804 int i;
805
806 /* reject passwords with zeros in the middle of the string */
0961ea93 807 for (i = strnlen(auth_str, 16); i < 16; i++) {
d62a17ae 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);
c4efb224 832 if (keychain == NULL || keychain->key == NULL)
d62a17ae 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;
d7c0a89a
QY
852 uint8_t digest[RIP_AUTH_MD5_SIZE];
853 uint16_t packet_len;
d62a17ae 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 */
d7c0a89a 896 md5data = (struct rip_md5_data *)(((uint8_t *)packet) + packet_len);
d62a17ae 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);
e65e227f 906 if (key == NULL || key->string == NULL)
d62a17ae 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) {
d7c0a89a 1183 uint32_t addrval;
d62a17ae 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))) {
d7c0a89a 1249 uint32_t destination;
d62a17ae 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) {
77cbe4a1
DS
1343 zlog_ferr(LIB_ERR_SOCKET, "Cannot create UDP socket: %s",
1344 safe_strerror(errno));
d62a17ae 1345 exit(1);
1346 }
1347
1348 sockopt_broadcast(sock);
1349 sockopt_reuseaddr(sock);
1350 sockopt_reuseport(sock);
1351 setsockopt_ipv4_multicast_loop(sock, 0);
a4e987e0 1352#ifdef RIP_RECVMSG
d62a17ae 1353 setsockopt_pktinfo(sock);
a4e987e0 1354#endif /* RIP_RECVMSG */
78b31d5c 1355#ifdef IPTOS_PREC_INTERNETCONTROL
d62a17ae 1356 setsockopt_ipv4_tos(sock, IPTOS_PREC_INTERNETCONTROL);
78b31d5c 1357#endif
a4e987e0 1358
d62a17ae 1359 if (ripd_privs.change(ZPRIVS_RAISE))
77cbe4a1
DS
1360 zlog_ferr(LIB_ERR_PRIVILEGES,
1361 "rip_create_socket: could not raise privs");
d62a17ae 1362 setsockopt_so_recvbuf(sock, RIP_UDP_RCV_BUF);
1363 if ((ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr))) < 0)
1364
1365 {
1366 int save_errno = errno;
1367 if (ripd_privs.change(ZPRIVS_LOWER))
77cbe4a1
DS
1368 zlog_ferr(LIB_ERR_PRIVILEGES,
1369 "rip_create_socket: could not lower privs");
d62a17ae 1370
77cbe4a1
DS
1371 zlog_ferr(LIB_ERR_SOCKET,
1372 "%s: Can't bind socket %d to %s port %d: %s",
1373 __func__, sock, inet_ntoa(addr.sin_addr),
1374 (int)ntohs(addr.sin_port), safe_strerror(save_errno));
d62a17ae 1375
1376 close(sock);
1377 return ret;
1378 }
1379
1380 if (ripd_privs.change(ZPRIVS_LOWER))
77cbe4a1
DS
1381 zlog_ferr(LIB_ERR_PRIVILEGES,
1382 "rip_create_socket: could not lower privs");
d62a17ae 1383
1384 return sock;
a4e987e0 1385}
1386
c49ad8f1 1387/* RIP packet send to destination address, on interface denoted by
1388 * by connected argument. NULL to argument denotes destination should be
1389 * should be RIP multicast group
1390 */
d7c0a89a 1391static int rip_send_packet(uint8_t *buf, int size, struct sockaddr_in *to,
d62a17ae 1392 struct connected *ifc)
1393{
1394 int ret;
1395 struct sockaddr_in sin;
1396
1397 assert(ifc != NULL);
1398
1399 if (IS_RIP_DEBUG_PACKET) {
f69bd9da 1400#define ADDRESS_SIZE 20
d62a17ae 1401 char dst[ADDRESS_SIZE];
1402 dst[ADDRESS_SIZE - 1] = '\0';
1403
1404 if (to) {
1405 strncpy(dst, inet_ntoa(to->sin_addr), ADDRESS_SIZE - 1);
1406 } else {
1407 sin.sin_addr.s_addr = htonl(INADDR_RIP_GROUP);
1408 strncpy(dst, inet_ntoa(sin.sin_addr), ADDRESS_SIZE - 1);
1409 }
f69bd9da 1410#undef ADDRESS_SIZE
d62a17ae 1411 zlog_debug("rip_send_packet %s > %s (%s)",
1412 inet_ntoa(ifc->address->u.prefix4), dst,
1413 ifc->ifp->name);
1414 }
1415
1416 if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)) {
1417 /*
1418 * ZEBRA_IFA_SECONDARY is set on linux when an interface is
1419 * configured
1420 * with multiple addresses on the same subnet: the first address
1421 * on the subnet is configured "primary", and all subsequent
1422 * addresses
1423 * on that subnet are treated as "secondary" addresses.
1424 * In order to avoid routing-table bloat on other rip listeners,
1425 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY
1426 * source addrs.
1427 * XXX Since Linux is the only system for which the
1428 * ZEBRA_IFA_SECONDARY
1429 * flag is set, we would end up sending a packet for a
1430 * "secondary"
1431 * source address on non-linux systems.
1432 */
1433 if (IS_RIP_DEBUG_PACKET)
1434 zlog_debug("duplicate dropped");
1435 return 0;
1436 }
1437
1438 /* Make destination address. */
1439 memset(&sin, 0, sizeof(struct sockaddr_in));
1440 sin.sin_family = AF_INET;
6f0e3f6e 1441#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
d62a17ae 1442 sin.sin_len = sizeof(struct sockaddr_in);
6f0e3f6e 1443#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
718e3744 1444
d62a17ae 1445 /* When destination is specified, use it's port and address. */
1446 if (to) {
1447 sin.sin_port = to->sin_port;
1448 sin.sin_addr = to->sin_addr;
1449 } else {
1450 sin.sin_port = htons(RIP_PORT_DEFAULT);
1451 sin.sin_addr.s_addr = htonl(INADDR_RIP_GROUP);
ae735d2d 1452
d62a17ae 1453 rip_interface_multicast_set(rip->sock, ifc);
1454 }
718e3744 1455
d62a17ae 1456 ret = sendto(rip->sock, buf, size, 0, (struct sockaddr *)&sin,
1457 sizeof(struct sockaddr_in));
718e3744 1458
d62a17ae 1459 if (IS_RIP_DEBUG_EVENT)
1460 zlog_debug("SEND to %s.%d", inet_ntoa(sin.sin_addr),
1461 ntohs(sin.sin_port));
718e3744 1462
d62a17ae 1463 if (ret < 0)
1464 zlog_warn("can't send packet : %s", safe_strerror(errno));
718e3744 1465
d62a17ae 1466 return ret;
718e3744 1467}
1468
1469/* Add redistributed route to RIP table. */
d62a17ae 1470void rip_redistribute_add(int type, int sub_type, struct prefix_ipv4 *p,
996c9314
LB
1471 struct nexthop *nh, unsigned int metric,
1472 unsigned char distance, route_tag_t tag)
d62a17ae 1473{
1474 int ret;
1475 struct route_node *rp = NULL;
1476 struct rip_info *rinfo = NULL, newinfo;
1477 struct list *list = NULL;
1478
1479 /* Redistribute route */
1480 ret = rip_destination_check(p->prefix);
1481 if (!ret)
1482 return;
1483
1484 rp = route_node_get(rip->table, (struct prefix *)p);
1485
1486 memset(&newinfo, 0, sizeof(struct rip_info));
1487 newinfo.type = type;
1488 newinfo.sub_type = sub_type;
d62a17ae 1489 newinfo.metric = 1;
1490 newinfo.external_metric = metric;
1491 newinfo.distance = distance;
1492 if (tag <= UINT16_MAX) /* RIP only supports 16 bit tags */
1493 newinfo.tag = tag;
1494 newinfo.rp = rp;
3f5682c8 1495 newinfo.nh = *nh;
d62a17ae 1496
1497 if ((list = rp->info) != NULL && listcount(list) != 0) {
1498 rinfo = listgetdata(listhead(list));
1499
1500 if (rinfo->type == ZEBRA_ROUTE_CONNECT
1501 && rinfo->sub_type == RIP_ROUTE_INTERFACE
1502 && rinfo->metric != RIP_METRIC_INFINITY) {
1503 route_unlock_node(rp);
1504 return;
1505 }
718e3744 1506
d62a17ae 1507 /* Manually configured RIP route check. */
1508 if (rinfo->type == ZEBRA_ROUTE_RIP
1509 && ((rinfo->sub_type == RIP_ROUTE_STATIC)
1510 || (rinfo->sub_type == RIP_ROUTE_DEFAULT))) {
1511 if (type != ZEBRA_ROUTE_RIP
1512 || ((sub_type != RIP_ROUTE_STATIC)
1513 && (sub_type != RIP_ROUTE_DEFAULT))) {
1514 route_unlock_node(rp);
1515 return;
1516 }
1517 }
1518
11ff7164 1519 (void)rip_ecmp_replace(&newinfo);
d62a17ae 1520 route_unlock_node(rp);
1521 } else
11ff7164 1522 (void)rip_ecmp_add(&newinfo);
d62a17ae 1523
1524 if (IS_RIP_DEBUG_EVENT) {
996c9314
LB
1525 zlog_debug("Redistribute new prefix %s/%d",
1526 inet_ntoa(p->prefix), p->prefixlen);
718e3744 1527 }
1528
d62a17ae 1529 rip_event(RIP_TRIGGERED_UPDATE, 0);
718e3744 1530}
1531
1532/* Delete redistributed route from RIP table. */
d62a17ae 1533void rip_redistribute_delete(int type, int sub_type, struct prefix_ipv4 *p,
1534 ifindex_t ifindex)
1535{
1536 int ret;
1537 struct route_node *rp;
1538 struct rip_info *rinfo;
1539
1540 ret = rip_destination_check(p->prefix);
1541 if (!ret)
1542 return;
1543
1544 rp = route_node_lookup(rip->table, (struct prefix *)p);
1545 if (rp) {
1546 struct list *list = rp->info;
1547
1548 if (list != NULL && listcount(list) != 0) {
1549 rinfo = listgetdata(listhead(list));
1550 if (rinfo != NULL && rinfo->type == type
1551 && rinfo->sub_type == sub_type
dd127197 1552 && rinfo->nh.ifindex == ifindex) {
d62a17ae 1553 /* Perform poisoned reverse. */
1554 rinfo->metric = RIP_METRIC_INFINITY;
1555 RIP_TIMER_ON(rinfo->t_garbage_collect,
1556 rip_garbage_collect,
1557 rip->garbage_time);
1558 RIP_TIMER_OFF(rinfo->t_timeout);
1559 rinfo->flags |= RIP_RTF_CHANGED;
1560
1561 if (IS_RIP_DEBUG_EVENT)
1562 zlog_debug(
14aa0c3d 1563 "Poison %s/%d on the interface %s with an "
d62a17ae 1564 "infinity metric [delete]",
1565 inet_ntoa(p->prefix),
1566 p->prefixlen,
1567 ifindex2ifname(ifindex,
1568 VRF_DEFAULT));
1569
1570 rip_event(RIP_TRIGGERED_UPDATE, 0);
1571 }
1572 }
1573 route_unlock_node(rp);
1574 }
718e3744 1575}
1576
1577/* Response to request called from rip_read ().*/
d62a17ae 1578static void rip_request_process(struct rip_packet *packet, int size,
1579 struct sockaddr_in *from, struct connected *ifc)
1580{
1581 caddr_t lim;
1582 struct rte *rte;
1583 struct prefix_ipv4 p;
1584 struct route_node *rp;
1585 struct rip_info *rinfo;
1586 struct rip_interface *ri;
1587
1588 /* Does not reponse to the requests on the loopback interfaces */
1589 if (if_is_loopback(ifc->ifp))
1590 return;
1591
1592 /* Check RIP process is enabled on this interface. */
1593 ri = ifc->ifp->info;
1594 if (!ri->running)
1595 return;
1596
1597 /* When passive interface is specified, suppress responses */
1598 if (ri->passive)
1599 return;
1600
1601 /* RIP peer update. */
1602 rip_peer_update(from, packet->version);
1603
1604 lim = ((caddr_t)packet) + size;
1605 rte = packet->rte;
1606
1607 /* The Request is processed entry by entry. If there are no
1608 entries, no response is given. */
1609 if (lim == (caddr_t)rte)
1610 return;
1611
1612 /* There is one special case. If there is exactly one entry in the
1613 request, and it has an address family identifier of zero and a
1614 metric of infinity (i.e., 16), then this is a request to send the
1615 entire routing table. */
1616 if (lim == ((caddr_t)(rte + 1)) && ntohs(rte->family) == 0
1617 && ntohl(rte->metric) == RIP_METRIC_INFINITY) {
1618 /* All route with split horizon */
1619 rip_output_process(ifc, from, rip_all_route, packet->version);
1620 } else {
1621 if (ntohs(rte->family) != AF_INET)
1622 return;
1623
1624 /* Examine the list of RTEs in the Request one by one. For each
1625 entry, look up the destination in the router's routing
1626 database and, if there is a route, put that route's metric in
1627 the metric field of the RTE. If there is no explicit route
1628 to the specified destination, put infinity in the metric
1629 field. Once all the entries have been filled in, change the
1630 command from Request to Response and send the datagram back
1631 to the requestor. */
1632 p.family = AF_INET;
1633
1634 for (; ((caddr_t)rte) < lim; rte++) {
1635 p.prefix = rte->prefix;
1636 p.prefixlen = ip_masklen(rte->mask);
1637 apply_mask_ipv4(&p);
1638
1639 rp = route_node_lookup(rip->table, (struct prefix *)&p);
1640 if (rp) {
1641 rinfo = listgetdata(
1642 listhead((struct list *)rp->info));
1643 rte->metric = htonl(rinfo->metric);
1644 route_unlock_node(rp);
1645 } else
1646 rte->metric = htonl(RIP_METRIC_INFINITY);
1647 }
1648 packet->command = RIP_RESPONSE;
4e054866 1649
b2608623 1650 (void)rip_send_packet((uint8_t *)packet, size, from, ifc);
d62a17ae 1651 }
1652 rip_global_queries++;
718e3744 1653}
1654
1655#if RIP_RECVMSG
1656/* Set IPv6 packet info to the socket. */
d62a17ae 1657static int setsockopt_pktinfo(int sock)
718e3744 1658{
d62a17ae 1659 int ret;
1660 int val = 1;
1661
1662 ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val));
1663 if (ret < 0)
1664 zlog_warn("Can't setsockopt IP_PKTINFO : %s",
1665 safe_strerror(errno));
1666 return ret;
718e3744 1667}
1668
1669/* Read RIP packet by recvmsg function. */
d7c0a89a 1670int rip_recvmsg(int sock, uint8_t *buf, int size, struct sockaddr_in *from,
d62a17ae 1671 ifindex_t *ifindex)
1672{
1673 int ret;
1674 struct msghdr msg;
1675 struct iovec iov;
1676 struct cmsghdr *ptr;
1677 char adata[1024];
1678
0af35d90 1679 memset(&msg, 0, sizeof(msg));
d62a17ae 1680 msg.msg_name = (void *)from;
1681 msg.msg_namelen = sizeof(struct sockaddr_in);
1682 msg.msg_iov = &iov;
1683 msg.msg_iovlen = 1;
1684 msg.msg_control = (void *)adata;
1685 msg.msg_controllen = sizeof adata;
1686 iov.iov_base = buf;
1687 iov.iov_len = size;
1688
1689 ret = recvmsg(sock, &msg, 0);
1690 if (ret < 0)
1691 return ret;
718e3744 1692
d62a17ae 1693 for (ptr = ZCMSG_FIRSTHDR(&msg); ptr != NULL;
1694 ptr = CMSG_NXTHDR(&msg, ptr))
1695 if (ptr->cmsg_level == IPPROTO_IP
1696 && ptr->cmsg_type == IP_PKTINFO) {
1697 struct in_pktinfo *pktinfo;
1698 int i;
1699
1700 pktinfo = (struct in_pktinfo *)CMSG_DATA(ptr);
1701 i = pktinfo->ipi_ifindex;
1702 }
1703 return ret;
718e3744 1704}
1705
1706/* RIP packet read function. */
d62a17ae 1707int rip_read_new(struct thread *t)
1708{
1709 int ret;
1710 int sock;
1711 char buf[RIP_PACKET_MAXSIZ];
1712 struct sockaddr_in from;
1713 ifindex_t ifindex;
1714
1715 /* Fetch socket then register myself. */
1716 sock = THREAD_FD(t);
1717 rip_event(RIP_READ, sock);
1718
1719 /* Read RIP packet. */
1720 ret = rip_recvmsg(sock, buf, RIP_PACKET_MAXSIZ, &from, (int *)&ifindex);
1721 if (ret < 0) {
1722 zlog_warn("Can't read RIP packet: %s", safe_strerror(errno));
1723 return ret;
1724 }
1725
1726 return ret;
718e3744 1727}
1728#endif /* RIP_RECVMSG */
1729
1730/* First entry point of RIP packet. */
d62a17ae 1731static int rip_read(struct thread *t)
1732{
1733 int sock;
1734 int ret;
1735 int rtenum;
1736 union rip_buf rip_buf;
1737 struct rip_packet *packet;
1738 struct sockaddr_in from;
1739 int len;
1740 int vrecv;
1741 socklen_t fromlen;
1742 struct interface *ifp = NULL;
1743 struct connected *ifc;
1744 struct rip_interface *ri;
1745 struct prefix p;
1746
1747 /* Fetch socket then register myself. */
1748 sock = THREAD_FD(t);
1749 rip->t_read = NULL;
1750
1751 /* Add myself to tne next event */
1752 rip_event(RIP_READ, sock);
1753
1754 /* RIPd manages only IPv4. */
1755 memset(&from, 0, sizeof(struct sockaddr_in));
1756 fromlen = sizeof(struct sockaddr_in);
1757
1758 len = recvfrom(sock, (char *)&rip_buf.buf, sizeof(rip_buf.buf), 0,
1759 (struct sockaddr *)&from, &fromlen);
1760 if (len < 0) {
1761 zlog_info("recvfrom failed: %s", safe_strerror(errno));
1762 return len;
1763 }
1764
1765 /* Check is this packet comming from myself? */
1766 if (if_check_address(from.sin_addr)) {
1767 if (IS_RIP_DEBUG_PACKET)
1768 zlog_debug("ignore packet comes from myself");
1769 return -1;
1770 }
1771
1772 /* Which interface is this packet comes from. */
1773 ifc = if_lookup_address((void *)&from.sin_addr, AF_INET, VRF_DEFAULT);
1774 if (ifc)
1775 ifp = ifc->ifp;
1776
1777 /* RIP packet received */
1778 if (IS_RIP_DEBUG_EVENT)
1779 zlog_debug("RECV packet from %s port %d on %s",
1780 inet_ntoa(from.sin_addr), ntohs(from.sin_port),
1781 ifp ? ifp->name : "unknown");
1782
1783 /* If this packet come from unknown interface, ignore it. */
1784 if (ifp == NULL) {
1785 zlog_info(
1786 "rip_read: cannot find interface for packet from %s port %d",
1787 inet_ntoa(from.sin_addr), ntohs(from.sin_port));
1788 return -1;
1789 }
1790
1791 p.family = AF_INET;
1792 p.u.prefix4 = from.sin_addr;
1793 p.prefixlen = IPV4_MAX_BITLEN;
1794
1795 ifc = connected_lookup_prefix(ifp, &p);
1796
1797 if (ifc == NULL) {
1798 zlog_info(
1799 "rip_read: cannot find connected address for packet from %s "
1800 "port %d on interface %s",
1801 inet_ntoa(from.sin_addr), ntohs(from.sin_port),
1802 ifp->name);
1803 return -1;
1804 }
1805
1806 /* Packet length check. */
1807 if (len < RIP_PACKET_MINSIZ) {
1808 zlog_warn("packet size %d is smaller than minimum size %d", len,
1809 RIP_PACKET_MINSIZ);
1810 rip_peer_bad_packet(&from);
1811 return len;
1812 }
1813 if (len > RIP_PACKET_MAXSIZ) {
1814 zlog_warn("packet size %d is larger than max size %d", len,
1815 RIP_PACKET_MAXSIZ);
1816 rip_peer_bad_packet(&from);
1817 return len;
1818 }
1819
1820 /* Packet alignment check. */
1821 if ((len - RIP_PACKET_MINSIZ) % 20) {
1822 zlog_warn("packet size %d is wrong for RIP packet alignment",
1823 len);
1824 rip_peer_bad_packet(&from);
1825 return len;
1826 }
1827
1828 /* Set RTE number. */
1829 rtenum = ((len - RIP_PACKET_MINSIZ) / 20);
1830
1831 /* For easy to handle. */
1832 packet = &rip_buf.rip_packet;
1833
1834 /* RIP version check. */
1835 if (packet->version == 0) {
1836 zlog_info("version 0 with command %d received.",
1837 packet->command);
1838 rip_peer_bad_packet(&from);
1839 return -1;
1840 }
1841
1842 /* Dump RIP packet. */
1843 if (IS_RIP_DEBUG_RECV)
1844 rip_packet_dump(packet, len, "RECV");
1845
1846 /* RIP version adjust. This code should rethink now. RFC1058 says
1847 that "Version 1 implementations are to ignore this extra data and
1848 process only the fields specified in this document.". So RIPv3
1849 packet should be treated as RIPv1 ignoring must be zero field. */
1850 if (packet->version > RIPv2)
1851 packet->version = RIPv2;
1852
1853 /* Is RIP running or is this RIP neighbor ?*/
1854 ri = ifp->info;
1855 if (!ri->running && !rip_neighbor_lookup(&from)) {
1856 if (IS_RIP_DEBUG_EVENT)
1857 zlog_debug("RIP is not enabled on interface %s.",
1858 ifp->name);
1859 rip_peer_bad_packet(&from);
1860 return -1;
1861 }
1862
1863 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1864 vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ? rip->version_recv
1865 : ri->ri_receive);
1866 if (vrecv == RI_RIP_VERSION_NONE
1867 || ((packet->version == RIPv1) && !(vrecv & RIPv1))
1868 || ((packet->version == RIPv2) && !(vrecv & RIPv2))) {
1869 if (IS_RIP_DEBUG_PACKET)
1870 zlog_debug(
1871 " packet's v%d doesn't fit to if version spec",
1872 packet->version);
1873 rip_peer_bad_packet(&from);
1874 return -1;
1875 }
1876
1877 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1878 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1879 accepted; authenticated RIP-2 messages shall be discarded. */
1880 if ((ri->auth_type == RIP_NO_AUTH) && rtenum
1881 && (packet->version == RIPv2)
1882 && (packet->rte->family == htons(RIP_FAMILY_AUTH))) {
1883 if (IS_RIP_DEBUG_EVENT)
1884 zlog_debug(
1885 "packet RIPv%d is dropped because authentication disabled",
1886 packet->version);
1887 rip_peer_bad_packet(&from);
1888 return -1;
1889 }
1890
1891 /* RFC:
1892 If the router is configured to authenticate RIP-2 messages, then
1893 RIP-1 messages and RIP-2 messages which pass authentication
1894 testing shall be accepted; unauthenticated and failed
1895 authentication RIP-2 messages shall be discarded. For maximum
1896 security, RIP-1 messages should be ignored when authentication is
1897 in use (see section 4.1); otherwise, the routing information from
1898 authenticated messages will be propagated by RIP-1 routers in an
1899 unauthenticated manner.
1900 */
1901 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1902 * always reply regardless of authentication settings, because:
1903 *
1904 * - if there other authorised routers on-link, the REQUESTor can
1905 * passively obtain the routing updates anyway
1906 * - if there are no other authorised routers on-link, RIP can
1907 * easily be disabled for the link to prevent giving out information
1908 * on state of this routers RIP routing table..
1909 *
1910 * I.e. if RIPv1 has any place anymore these days, it's as a very
1911 * simple way to distribute routing information (e.g. to embedded
1912 * hosts / appliances) and the ability to give out RIPv1
1913 * routing-information freely, while still requiring RIPv2
1914 * authentication for any RESPONSEs might be vaguely useful.
1915 */
1916 if (ri->auth_type != RIP_NO_AUTH && packet->version == RIPv1) {
1917 /* Discard RIPv1 messages other than REQUESTs */
1918 if (packet->command != RIP_REQUEST) {
1919 if (IS_RIP_DEBUG_PACKET)
1920 zlog_debug(
1921 "RIPv1"
1922 " dropped because authentication enabled");
1923 rip_peer_bad_packet(&from);
1924 return -1;
1925 }
1926 } else if (ri->auth_type != RIP_NO_AUTH) {
1927 const char *auth_desc;
1928
1929 if (rtenum == 0) {
1930 /* There definitely is no authentication in the packet.
1931 */
1932 if (IS_RIP_DEBUG_PACKET)
1933 zlog_debug(
1934 "RIPv2 authentication failed: no auth RTE in packet");
1935 rip_peer_bad_packet(&from);
1936 return -1;
1937 }
1938
1939 /* First RTE must be an Authentication Family RTE */
1940 if (packet->rte->family != htons(RIP_FAMILY_AUTH)) {
1941 if (IS_RIP_DEBUG_PACKET)
1942 zlog_debug(
1943 "RIPv2"
1944 " dropped because authentication enabled");
1945 rip_peer_bad_packet(&from);
1946 return -1;
1947 }
1948
1949 /* Check RIPv2 authentication. */
1950 switch (ntohs(packet->rte->tag)) {
1951 case RIP_AUTH_SIMPLE_PASSWORD:
1952 auth_desc = "simple";
1953 ret = rip_auth_simple_password(packet->rte, &from, ifp);
1954 break;
1955
1956 case RIP_AUTH_MD5:
1957 auth_desc = "MD5";
1958 ret = rip_auth_md5(packet, &from, len, ifp);
1959 /* Reset RIP packet length to trim MD5 data. */
1960 len = ret;
1961 break;
1962
1963 default:
1964 ret = 0;
1965 auth_desc = "unknown type";
1966 if (IS_RIP_DEBUG_PACKET)
1967 zlog_debug(
1968 "RIPv2 Unknown authentication type %d",
1969 ntohs(packet->rte->tag));
1970 }
1971
1972 if (ret) {
1973 if (IS_RIP_DEBUG_PACKET)
1974 zlog_debug("RIPv2 %s authentication success",
1975 auth_desc);
1976 } else {
1977 if (IS_RIP_DEBUG_PACKET)
1978 zlog_debug("RIPv2 %s authentication failure",
1979 auth_desc);
1980 rip_peer_bad_packet(&from);
1981 return -1;
1982 }
1983 }
1984
1985 /* Process each command. */
1986 switch (packet->command) {
1987 case RIP_RESPONSE:
1988 rip_response_process(packet, len, &from, ifc);
1989 break;
1990 case RIP_REQUEST:
1991 case RIP_POLL:
1992 rip_request_process(packet, len, &from, ifc);
1993 break;
1994 case RIP_TRACEON:
1995 case RIP_TRACEOFF:
1996 zlog_info(
1997 "Obsolete command %s received, please sent it to routed",
1998 lookup_msg(rip_msg, packet->command, NULL));
1999 rip_peer_bad_packet(&from);
2000 break;
2001 case RIP_POLL_ENTRY:
2002 zlog_info("Obsolete command %s received",
2003 lookup_msg(rip_msg, packet->command, NULL));
2004 rip_peer_bad_packet(&from);
2005 break;
2006 default:
2007 zlog_info("Unknown RIP command %d received", packet->command);
2008 rip_peer_bad_packet(&from);
2009 break;
2010 }
2011
2012 return len;
718e3744 2013}
2014
718e3744 2015/* Write routing table entry to the stream and return next index of
2016 the routing table entry in the stream. */
d62a17ae 2017static int rip_write_rte(int num, struct stream *s, struct prefix_ipv4 *p,
d7c0a89a 2018 uint8_t version, struct rip_info *rinfo)
d62a17ae 2019{
2020 struct in_addr mask;
2021
2022 /* Write routing table entry. */
2023 if (version == RIPv1) {
2024 stream_putw(s, AF_INET);
2025 stream_putw(s, 0);
2026 stream_put_ipv4(s, p->prefix.s_addr);
2027 stream_put_ipv4(s, 0);
2028 stream_put_ipv4(s, 0);
2029 stream_putl(s, rinfo->metric_out);
2030 } else {
2031 masklen2ip(p->prefixlen, &mask);
2032
2033 stream_putw(s, AF_INET);
2034 stream_putw(s, rinfo->tag_out);
2035 stream_put_ipv4(s, p->prefix.s_addr);
2036 stream_put_ipv4(s, mask.s_addr);
2037 stream_put_ipv4(s, rinfo->nexthop_out.s_addr);
2038 stream_putl(s, rinfo->metric_out);
2039 }
2040
2041 return ++num;
718e3744 2042}
2043
2044/* Send update to the ifp or spcified neighbor. */
d62a17ae 2045void rip_output_process(struct connected *ifc, struct sockaddr_in *to,
d7c0a89a 2046 int route_type, uint8_t version)
d62a17ae 2047{
2048 int ret;
2049 struct stream *s;
2050 struct route_node *rp;
2051 struct rip_info *rinfo;
2052 struct rip_interface *ri;
2053 struct prefix_ipv4 *p;
2054 struct prefix_ipv4 classfull;
2055 struct prefix_ipv4 ifaddrclass;
2056 struct key *key = NULL;
2057 /* this might need to made dynamic if RIP ever supported auth methods
2058 with larger key string sizes */
2059 char auth_str[RIP_AUTH_SIMPLE_SIZE];
2060 size_t doff = 0; /* offset of digest offset field */
2061 int num = 0;
2062 int rtemax;
2063 int subnetted = 0;
2064 struct list *list = NULL;
2065 struct listnode *listnode = NULL;
2066
2067 /* Logging output event. */
2068 if (IS_RIP_DEBUG_EVENT) {
2069 if (to)
2070 zlog_debug("update routes to neighbor %s",
2071 inet_ntoa(to->sin_addr));
2072 else
2073 zlog_debug("update routes on interface %s ifindex %d",
2074 ifc->ifp->name, ifc->ifp->ifindex);
2075 }
718e3744 2076
d62a17ae 2077 /* Set output stream. */
2078 s = rip->obuf;
2079
2080 /* Reset stream and RTE counter. */
2081 stream_reset(s);
2082 rtemax = RIP_MAX_RTE;
2083
2084 /* Get RIP interface. */
2085 ri = ifc->ifp->info;
2086
2087 /* If output interface is in simple password authentication mode, we
2088 need space for authentication data. */
2089 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2090 rtemax -= 1;
2091
2092 /* If output interface is in MD5 authentication mode, we need space
2093 for authentication header and data. */
2094 if (ri->auth_type == RIP_AUTH_MD5)
2095 rtemax -= 2;
2096
2097 /* If output interface is in simple password authentication mode
2098 and string or keychain is specified we need space for auth. data */
2099 if (ri->auth_type != RIP_NO_AUTH) {
2100 if (ri->key_chain) {
2101 struct keychain *keychain;
2102
2103 keychain = keychain_lookup(ri->key_chain);
2104 if (keychain)
2105 key = key_lookup_for_send(keychain);
2106 }
2107 /* to be passed to auth functions later */
2108 rip_auth_prepare_str_send(ri, key, auth_str,
2109 RIP_AUTH_SIMPLE_SIZE);
558c6842 2110 if (strlen(auth_str) == 0)
2111 return;
d62a17ae 2112 }
2113
2114 if (version == RIPv1) {
2115 memcpy(&ifaddrclass, ifc->address, sizeof(struct prefix_ipv4));
2116 apply_classful_mask_ipv4(&ifaddrclass);
2117 subnetted = 0;
2118 if (ifc->address->prefixlen > ifaddrclass.prefixlen)
2119 subnetted = 1;
2120 }
2121
2122 for (rp = route_top(rip->table); rp; rp = route_next(rp))
2123 if ((list = rp->info) != NULL && listcount(list) != 0) {
2124 rinfo = listgetdata(listhead(list));
2125 /* For RIPv1, if we are subnetted, output subnets in our
2126 * network */
2127 /* that have the same mask as the output "interface".
2128 * For other */
2129 /* networks, only the classfull version is output. */
2130
2131 if (version == RIPv1) {
2132 p = (struct prefix_ipv4 *)&rp->p;
2133
2134 if (IS_RIP_DEBUG_PACKET)
2135 zlog_debug(
2136 "RIPv1 mask check, %s/%d considered for output",
2137 inet_ntoa(rp->p.u.prefix4),
2138 rp->p.prefixlen);
2139
2140 if (subnetted
2141 && prefix_match(
2142 (struct prefix *)&ifaddrclass,
2143 &rp->p)) {
2144 if ((ifc->address->prefixlen
2145 != rp->p.prefixlen)
2146 && (rp->p.prefixlen != 32))
2147 continue;
2148 } else {
2149 memcpy(&classfull, &rp->p,
2150 sizeof(struct prefix_ipv4));
2151 apply_classful_mask_ipv4(&classfull);
2152 if (rp->p.u.prefix4.s_addr != 0
2153 && classfull.prefixlen
2154 != rp->p.prefixlen)
2155 continue;
2156 }
2157 if (IS_RIP_DEBUG_PACKET)
2158 zlog_debug(
2159 "RIPv1 mask check, %s/%d made it through",
2160 inet_ntoa(rp->p.u.prefix4),
2161 rp->p.prefixlen);
2162 } else
2163 p = (struct prefix_ipv4 *)&rp->p;
2164
2165 /* Apply output filters. */
2166 ret = rip_filter(RIP_FILTER_OUT, p, ri);
2167 if (ret < 0)
2168 continue;
2169
2170 /* Changed route only output. */
2171 if (route_type == rip_changed_route
2172 && (!(rinfo->flags & RIP_RTF_CHANGED)))
2173 continue;
2174
2175 /* Split horizon. */
2176 /* if (split_horizon == rip_split_horizon) */
2177 if (ri->split_horizon == RIP_SPLIT_HORIZON) {
2178 /*
2179 * We perform split horizon for RIP and
2180 * connected route.
2181 * For rip routes, we want to suppress the route
2182 * if we would
2183 * end up sending the route back on the
2184 * interface that we
2185 * learned it from, with a higher metric. For
2186 * connected routes,
2187 * we suppress the route if the prefix is a
2188 * subset of the
2189 * source address that we are going to use for
2190 * the packet
2191 * (in order to handle the case when multiple
2192 * subnets are
2193 * configured on the same interface).
2194 */
2195 int suppress = 0;
2196 struct rip_info *tmp_rinfo = NULL;
9920df07 2197 struct connected *tmp_ifc = NULL;
d62a17ae 2198
2199 for (ALL_LIST_ELEMENTS_RO(list, listnode,
2200 tmp_rinfo))
2201 if (tmp_rinfo->type == ZEBRA_ROUTE_RIP
dd127197 2202 && tmp_rinfo->nh.ifindex
d62a17ae 2203 == ifc->ifp->ifindex) {
2204 suppress = 1;
2205 break;
2206 }
2207
2208 if (!suppress
9920df07 2209 && rinfo->type == ZEBRA_ROUTE_CONNECT) {
2210 for (ALL_LIST_ELEMENTS_RO(
2211 ifc->ifp->connected,
2212 listnode, tmp_ifc))
2213 if (prefix_match(
2214 (struct prefix *)p,
2215 tmp_ifc->address)) {
2216 suppress = 1;
2217 break;
2218 }
2219 }
d62a17ae 2220
2221 if (suppress)
2222 continue;
2223 }
2224
2225 /* Preparation for route-map. */
2226 rinfo->metric_set = 0;
2227 rinfo->nexthop_out.s_addr = 0;
2228 rinfo->metric_out = rinfo->metric;
2229 rinfo->tag_out = rinfo->tag;
2230 rinfo->ifindex_out = ifc->ifp->ifindex;
2231
2232 /* In order to avoid some local loops,
2233 * if the RIP route has a nexthop via this interface,
2234 * keep the nexthop,
2235 * otherwise set it to 0. The nexthop should not be
2236 * propagated
2237 * beyond the local broadcast/multicast area in order
2238 * to avoid an IGP multi-level recursive look-up.
2239 * see (4.4)
2240 */
dd127197
DS
2241 if (rinfo->nh.ifindex == ifc->ifp->ifindex)
2242 rinfo->nexthop_out = rinfo->nh.gate.ipv4;
d62a17ae 2243
2244 /* Interface route-map */
2245 if (ri->routemap[RIP_FILTER_OUT]) {
2246 ret = route_map_apply(
2247 ri->routemap[RIP_FILTER_OUT],
2248 (struct prefix *)p, RMAP_RIP, rinfo);
2249
2250 if (ret == RMAP_DENYMATCH) {
2251 if (IS_RIP_DEBUG_PACKET)
2252 zlog_debug(
2253 "RIP %s/%d is filtered by route-map out",
2254 inet_ntoa(p->prefix),
2255 p->prefixlen);
2256 continue;
2257 }
2258 }
2259
2260 /* Apply redistribute route map - continue, if deny */
2261 if (rip->route_map[rinfo->type].name
2262 && rinfo->sub_type != RIP_ROUTE_INTERFACE) {
2263 ret = route_map_apply(
2264 rip->route_map[rinfo->type].map,
2265 (struct prefix *)p, RMAP_RIP, rinfo);
2266
2267 if (ret == RMAP_DENYMATCH) {
2268 if (IS_RIP_DEBUG_PACKET)
2269 zlog_debug(
2270 "%s/%d is filtered by route-map",
2271 inet_ntoa(p->prefix),
2272 p->prefixlen);
2273 continue;
2274 }
2275 }
2276
2277 /* When route-map does not set metric. */
2278 if (!rinfo->metric_set) {
2279 /* If redistribute metric is set. */
2280 if (rip->route_map[rinfo->type].metric_config
2281 && rinfo->metric != RIP_METRIC_INFINITY) {
2282 rinfo->metric_out =
2283 rip->route_map[rinfo->type]
2284 .metric;
2285 } else {
2286 /* If the route is not connected or
2287 localy generated
2288 one, use default-metric value*/
2289 if (rinfo->type != ZEBRA_ROUTE_RIP
2290 && rinfo->type
2291 != ZEBRA_ROUTE_CONNECT
2292 && rinfo->metric
2293 != RIP_METRIC_INFINITY)
2294 rinfo->metric_out =
2295 rip->default_metric;
2296 }
2297 }
2298
2299 /* Apply offset-list */
2300 if (rinfo->metric != RIP_METRIC_INFINITY)
2301 rip_offset_list_apply_out(p, ifc->ifp,
2302 &rinfo->metric_out);
2303
2304 if (rinfo->metric_out > RIP_METRIC_INFINITY)
2305 rinfo->metric_out = RIP_METRIC_INFINITY;
2306
2307 /* Perform split-horizon with poisoned reverse
2308 * for RIP and connected routes.
2309 **/
2310 if (ri->split_horizon
2311 == RIP_SPLIT_HORIZON_POISONED_REVERSE) {
2312 /*
2313 * We perform split horizon for RIP and
2314 * connected route.
2315 * For rip routes, we want to suppress the route
2316 * if we would
2317 * end up sending the route back on the
2318 * interface that we
2319 * learned it from, with a higher metric. For
2320 * connected routes,
2321 * we suppress the route if the prefix is a
2322 * subset of the
2323 * source address that we are going to use for
2324 * the packet
2325 * (in order to handle the case when multiple
2326 * subnets are
2327 * configured on the same interface).
2328 */
2329 struct rip_info *tmp_rinfo = NULL;
9920df07 2330 struct connected *tmp_ifc = NULL;
d62a17ae 2331
2332 for (ALL_LIST_ELEMENTS_RO(list, listnode,
2333 tmp_rinfo))
2334 if (tmp_rinfo->type == ZEBRA_ROUTE_RIP
dd127197 2335 && tmp_rinfo->nh.ifindex
996c9314 2336 == ifc->ifp->ifindex)
9920df07 2337 rinfo->metric_out =
d62a17ae 2338 RIP_METRIC_INFINITY;
aea175a8 2339
9920df07 2340 if (rinfo->metric_out != RIP_METRIC_INFINITY
2341 && rinfo->type == ZEBRA_ROUTE_CONNECT) {
2342 for (ALL_LIST_ELEMENTS_RO(
2343 ifc->ifp->connected,
2344 listnode, tmp_ifc))
2345 if (prefix_match(
2346 (struct prefix *)p,
2347 tmp_ifc->address)) {
2348 rinfo->metric_out =
2349 RIP_METRIC_INFINITY;
2350 break;
2351 }
2352 }
d62a17ae 2353 }
2354
2355 /* Prepare preamble, auth headers, if needs be */
2356 if (num == 0) {
2357 stream_putc(s, RIP_RESPONSE);
2358 stream_putc(s, version);
2359 stream_putw(s, 0);
2360
2361 /* auth header for !v1 && !no_auth */
2362 if ((ri->auth_type != RIP_NO_AUTH)
2363 && (version != RIPv1))
2364 doff = rip_auth_header_write(
2365 s, ri, key, auth_str,
2366 RIP_AUTH_SIMPLE_SIZE);
2367 }
2368
2369 /* Write RTE to the stream. */
2370 num = rip_write_rte(num, s, p, version, rinfo);
2371 if (num == rtemax) {
2372 if (version == RIPv2
2373 && ri->auth_type == RIP_AUTH_MD5)
2374 rip_auth_md5_set(s, ri, doff, auth_str,
2375 RIP_AUTH_SIMPLE_SIZE);
2376
2377 ret = rip_send_packet(STREAM_DATA(s),
2378 stream_get_endp(s), to,
2379 ifc);
2380
2381 if (ret >= 0 && IS_RIP_DEBUG_SEND)
2382 rip_packet_dump((struct rip_packet *)
2383 STREAM_DATA(s),
2384 stream_get_endp(s),
2385 "SEND");
2386 num = 0;
2387 stream_reset(s);
2388 }
2389 }
2390
2391 /* Flush unwritten RTE. */
2392 if (num != 0) {
2393 if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
2394 rip_auth_md5_set(s, ri, doff, auth_str,
2395 RIP_AUTH_SIMPLE_SIZE);
2396
2397 ret = rip_send_packet(STREAM_DATA(s), stream_get_endp(s), to,
2398 ifc);
2399
2400 if (ret >= 0 && IS_RIP_DEBUG_SEND)
2401 rip_packet_dump((struct rip_packet *)STREAM_DATA(s),
2402 stream_get_endp(s), "SEND");
2403 stream_reset(s);
2404 }
2405
2406 /* Statistics updates. */
2407 ri->sent_updates++;
718e3744 2408}
2409
2410/* Send RIP packet to the interface. */
d7c0a89a 2411static void rip_update_interface(struct connected *ifc, uint8_t version,
d62a17ae 2412 int route_type)
2413{
2414 struct interface *ifp = ifc->ifp;
2415 struct rip_interface *ri = ifp->info;
2416 struct sockaddr_in to;
2417
2418 /* When RIP version is 2 and multicast enable interface. */
2419 if (version == RIPv2 && !ri->v2_broadcast && if_is_multicast(ifp)) {
2420 if (IS_RIP_DEBUG_EVENT)
2421 zlog_debug("multicast announce on %s ", ifp->name);
2422
2423 rip_output_process(ifc, NULL, route_type, version);
2424 return;
2425 }
2426
2427 /* If we can't send multicast packet, send it with unicast. */
2428 if (if_is_broadcast(ifp) || if_is_pointopoint(ifp)) {
2429 if (ifc->address->family == AF_INET) {
2430 /* Destination address and port setting. */
2431 memset(&to, 0, sizeof(struct sockaddr_in));
2432 if (ifc->destination)
2433 /* use specified broadcast or peer destination
2434 * addr */
2435 to.sin_addr = ifc->destination->u.prefix4;
2436 else if (ifc->address->prefixlen < IPV4_MAX_PREFIXLEN)
2437 /* calculate the appropriate broadcast address
2438 */
2439 to.sin_addr.s_addr = ipv4_broadcast_addr(
2440 ifc->address->u.prefix4.s_addr,
2441 ifc->address->prefixlen);
2442 else
2443 /* do not know where to send the packet */
2444 return;
2445 to.sin_port = htons(RIP_PORT_DEFAULT);
2446
2447 if (IS_RIP_DEBUG_EVENT)
2448 zlog_debug("%s announce to %s on %s",
2449 CONNECTED_PEER(ifc) ? "unicast"
2450 : "broadcast",
2451 inet_ntoa(to.sin_addr), ifp->name);
2452
2453 rip_output_process(ifc, &to, route_type, version);
2454 }
2455 }
718e3744 2456}
2457
2458/* Update send to all interface and neighbor. */
d62a17ae 2459static void rip_update_process(int route_type)
2460{
f4e14fdb 2461 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 2462 struct listnode *ifnode, *ifnnode;
2463 struct connected *connected;
2464 struct interface *ifp;
2465 struct rip_interface *ri;
2466 struct route_node *rp;
2467 struct sockaddr_in to;
2468 struct prefix *p;
2469
2470 /* Send RIP update to each interface. */
451fda4f 2471 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 2472 if (if_is_loopback(ifp))
2473 continue;
2474
2475 if (!if_is_operative(ifp))
2476 continue;
2477
2478 /* Fetch RIP interface information. */
2479 ri = ifp->info;
2480
2481 /* When passive interface is specified, suppress announce to the
2482 interface. */
2483 if (ri->passive)
2484 continue;
2485
2486 if (ri->running) {
2487 /*
2488 * If there is no version configuration in the
2489 * interface,
2490 * use rip's version setting.
2491 */
2492 int vsend = ((ri->ri_send == RI_RIP_UNSPEC)
2493 ? rip->version_send
2494 : ri->ri_send);
2495
2496 if (IS_RIP_DEBUG_EVENT)
2497 zlog_debug("SEND UPDATE to %s ifindex %d",
2498 ifp->name, ifp->ifindex);
2499
2500 /* send update on each connected network */
2501 for (ALL_LIST_ELEMENTS(ifp->connected, ifnode, ifnnode,
2502 connected)) {
2503 if (connected->address->family == AF_INET) {
2504 if (vsend & RIPv1)
2505 rip_update_interface(
2506 connected, RIPv1,
2507 route_type);
2508 if ((vsend & RIPv2)
2509 && if_is_multicast(ifp))
2510 rip_update_interface(
2511 connected, RIPv2,
2512 route_type);
2513 }
2514 }
2515 }
2516 }
2517
2518 /* RIP send updates to each neighbor. */
2519 for (rp = route_top(rip->neighbor); rp; rp = route_next(rp))
2520 if (rp->info != NULL) {
2521 p = &rp->p;
2522
2523 connected = if_lookup_address(&p->u.prefix4, AF_INET,
2524 VRF_DEFAULT);
2525 if (!connected) {
2526 zlog_warn(
2527 "Neighbor %s doesnt have connected interface!",
2528 inet_ntoa(p->u.prefix4));
2529 continue;
2530 }
2531
2532 /* Set destination address and port */
2533 memset(&to, 0, sizeof(struct sockaddr_in));
2534 to.sin_addr = p->u.prefix4;
2535 to.sin_port = htons(RIP_PORT_DEFAULT);
2536
2537 /* RIP version is rip's configuration. */
2538 rip_output_process(connected, &to, route_type,
2539 rip->version_send);
b9d92881 2540 }
718e3744 2541}
2542
2543/* RIP's periodical timer. */
d62a17ae 2544static int rip_update(struct thread *t)
718e3744 2545{
d62a17ae 2546 /* Clear timer pointer. */
2547 rip->t_update = NULL;
718e3744 2548
d62a17ae 2549 if (IS_RIP_DEBUG_EVENT)
2550 zlog_debug("update timer fire!");
718e3744 2551
d62a17ae 2552 /* Process update output. */
2553 rip_update_process(rip_all_route);
718e3744 2554
d62a17ae 2555 /* Triggered updates may be suppressed if a regular update is due by
2556 the time the triggered update would be sent. */
2557 RIP_TIMER_OFF(rip->t_triggered_interval);
2558 rip->trigger = 0;
718e3744 2559
d62a17ae 2560 /* Register myself. */
2561 rip_event(RIP_UPDATE_EVENT, 0);
718e3744 2562
d62a17ae 2563 return 0;
718e3744 2564}
2565
2566/* Walk down the RIP routing table then clear changed flag. */
d62a17ae 2567static void rip_clear_changed_flag(void)
718e3744 2568{
d62a17ae 2569 struct route_node *rp;
2570 struct rip_info *rinfo = NULL;
2571 struct list *list = NULL;
2572 struct listnode *listnode = NULL;
718e3744 2573
d62a17ae 2574 for (rp = route_top(rip->table); rp; rp = route_next(rp))
2575 if ((list = rp->info) != NULL)
2576 for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
2577 UNSET_FLAG(rinfo->flags, RIP_RTF_CHANGED);
2578 /* This flag can be set only on the first entry.
2579 */
2580 break;
2581 }
718e3744 2582}
2583
2584/* Triggered update interval timer. */
d62a17ae 2585static int rip_triggered_interval(struct thread *t)
718e3744 2586{
d62a17ae 2587 int rip_triggered_update(struct thread *);
718e3744 2588
d62a17ae 2589 rip->t_triggered_interval = NULL;
718e3744 2590
d62a17ae 2591 if (rip->trigger) {
2592 rip->trigger = 0;
2593 rip_triggered_update(t);
2594 }
2595 return 0;
2596}
718e3744 2597
2598/* Execute triggered update. */
d62a17ae 2599static int rip_triggered_update(struct thread *t)
718e3744 2600{
d62a17ae 2601 int interval;
718e3744 2602
d62a17ae 2603 /* Clear thred pointer. */
2604 rip->t_triggered_update = NULL;
718e3744 2605
d62a17ae 2606 /* Cancel interval timer. */
2607 RIP_TIMER_OFF(rip->t_triggered_interval);
2608 rip->trigger = 0;
718e3744 2609
d62a17ae 2610 /* Logging triggered update. */
2611 if (IS_RIP_DEBUG_EVENT)
2612 zlog_debug("triggered update!");
718e3744 2613
d62a17ae 2614 /* Split Horizon processing is done when generating triggered
2615 updates as well as normal updates (see section 2.6). */
2616 rip_update_process(rip_changed_route);
718e3744 2617
d62a17ae 2618 /* Once all of the triggered updates have been generated, the route
2619 change flags should be cleared. */
2620 rip_clear_changed_flag();
718e3744 2621
d62a17ae 2622 /* After a triggered update is sent, a timer should be set for a
2623 random interval between 1 and 5 seconds. If other changes that
2624 would trigger updates occur before the timer expires, a single
2625 update is triggered when the timer expires. */
2626 interval = (random() % 5) + 1;
718e3744 2627
d62a17ae 2628 rip->t_triggered_interval = NULL;
2629 thread_add_timer(master, rip_triggered_interval, NULL, interval,
2630 &rip->t_triggered_interval);
718e3744 2631
d62a17ae 2632 return 0;
718e3744 2633}
2634
2635/* Withdraw redistributed route. */
d62a17ae 2636void rip_redistribute_withdraw(int type)
2637{
2638 struct route_node *rp;
2639 struct rip_info *rinfo = NULL;
2640 struct list *list = NULL;
2641
2642 if (!rip)
2643 return;
2644
2645 for (rp = route_top(rip->table); rp; rp = route_next(rp))
2646 if ((list = rp->info) != NULL) {
2647 rinfo = listgetdata(listhead(list));
2648 if (rinfo->type == type
2649 && rinfo->sub_type != RIP_ROUTE_INTERFACE) {
2650 /* Perform poisoned reverse. */
2651 rinfo->metric = RIP_METRIC_INFINITY;
2652 RIP_TIMER_ON(rinfo->t_garbage_collect,
2653 rip_garbage_collect,
2654 rip->garbage_time);
2655 RIP_TIMER_OFF(rinfo->t_timeout);
2656 rinfo->flags |= RIP_RTF_CHANGED;
2657
2658 if (IS_RIP_DEBUG_EVENT) {
2659 struct prefix_ipv4 *p =
2660 (struct prefix_ipv4 *)&rp->p;
2661
2662 zlog_debug(
2663 "Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
2664 inet_ntoa(p->prefix),
2665 p->prefixlen,
dd127197
DS
2666 ifindex2ifname(
2667 rinfo->nh.ifindex,
2668 VRF_DEFAULT));
d62a17ae 2669 }
2670
2671 rip_event(RIP_TRIGGERED_UPDATE, 0);
2672 }
2673 }
2674}
2675
2676/* Create new RIP instance and set it to global variable. */
2677static int rip_create(void)
718e3744 2678{
d62a17ae 2679 rip = XCALLOC(MTYPE_RIP, sizeof(struct rip));
718e3744 2680
d62a17ae 2681 /* Set initial value. */
2682 rip->version_send = RI_RIP_VERSION_2;
2683 rip->version_recv = RI_RIP_VERSION_1_AND_2;
2684 rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
2685 rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
2686 rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
2687 rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
718e3744 2688
d62a17ae 2689 /* Initialize RIP routig table. */
2690 rip->table = route_table_init();
2691 rip->route = route_table_init();
2692 rip->neighbor = route_table_init();
718e3744 2693
d62a17ae 2694 /* Make output stream. */
2695 rip->obuf = stream_new(1500);
16705130 2696
d62a17ae 2697 /* Make socket. */
2698 rip->sock = rip_create_socket();
2699 if (rip->sock < 0)
2700 return rip->sock;
16705130 2701
d62a17ae 2702 /* Create read and timer thread. */
2703 rip_event(RIP_READ, rip->sock);
2704 rip_event(RIP_UPDATE_EVENT, 1);
718e3744 2705
d62a17ae 2706 QOBJ_REG(rip, rip);
718e3744 2707
d62a17ae 2708 return 0;
2709}
718e3744 2710
d62a17ae 2711/* Sned RIP request to the destination. */
2712int rip_request_send(struct sockaddr_in *to, struct interface *ifp,
d7c0a89a 2713 uint8_t version, struct connected *connected)
d62a17ae 2714{
2715 struct rte *rte;
2716 struct rip_packet rip_packet;
2717 struct listnode *node, *nnode;
2718
2719 memset(&rip_packet, 0, sizeof(rip_packet));
2720
2721 rip_packet.command = RIP_REQUEST;
2722 rip_packet.version = version;
2723 rte = rip_packet.rte;
2724 rte->metric = htonl(RIP_METRIC_INFINITY);
2725
2726 if (connected) {
2727 /*
2728 * connected is only sent for ripv1 case, or when
2729 * interface does not support multicast. Caller loops
2730 * over each connected address for this case.
2731 */
d7c0a89a 2732 if (rip_send_packet((uint8_t *)&rip_packet, sizeof(rip_packet),
d62a17ae 2733 to, connected)
2734 != sizeof(rip_packet))
2735 return -1;
2736 else
2737 return sizeof(rip_packet);
2738 }
718e3744 2739
d62a17ae 2740 /* send request on each connected network */
2741 for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) {
2742 struct prefix_ipv4 *p;
718e3744 2743
d62a17ae 2744 p = (struct prefix_ipv4 *)connected->address;
718e3744 2745
d62a17ae 2746 if (p->family != AF_INET)
2747 continue;
f6eacff4 2748
d7c0a89a 2749 if (rip_send_packet((uint8_t *)&rip_packet, sizeof(rip_packet),
d62a17ae 2750 to, connected)
2751 != sizeof(rip_packet))
2752 return -1;
2753 }
2754 return sizeof(rip_packet);
718e3744 2755}
2756
d62a17ae 2757static int rip_update_jitter(unsigned long time)
718e3744 2758{
239389ba 2759#define JITTER_BOUND 4
d62a17ae 2760 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2761 Given that, we cannot let time be less than JITTER_BOUND seconds.
2762 The RIPv2 RFC says jitter should be small compared to
2763 update_time. We consider 1/JITTER_BOUND to be small.
2764 */
2765
2766 int jitter_input = time;
2767 int jitter;
2768
2769 if (jitter_input < JITTER_BOUND)
2770 jitter_input = JITTER_BOUND;
2771
2772 jitter = (((random() % ((jitter_input * 2) + 1)) - jitter_input));
2773
2774 return jitter / JITTER_BOUND;
2775}
2776
2777void rip_event(enum rip_event event, int sock)
2778{
2779 int jitter = 0;
2780
2781 switch (event) {
2782 case RIP_READ:
2783 rip->t_read = NULL;
2784 thread_add_read(master, rip_read, NULL, sock, &rip->t_read);
2785 break;
2786 case RIP_UPDATE_EVENT:
2787 RIP_TIMER_OFF(rip->t_update);
2788 jitter = rip_update_jitter(rip->update_time);
2789 thread_add_timer(master, rip_update, NULL,
2790 sock ? 2 : rip->update_time + jitter,
2791 &rip->t_update);
2792 break;
2793 case RIP_TRIGGERED_UPDATE:
2794 if (rip->t_triggered_interval)
2795 rip->trigger = 1;
2796 else
2797 thread_add_event(master, rip_triggered_update, NULL, 0,
2798 &rip->t_triggered_update);
2799 break;
2800 default:
2801 break;
2802 }
718e3744 2803}
6b0655a2 2804
505e5056 2805DEFUN_NOSH (router_rip,
718e3744 2806 router_rip_cmd,
2807 "router rip",
2808 "Enable a routing process\n"
2809 "Routing Information Protocol (RIP)\n")
2810{
aad95a7d
QY
2811 int ret;
2812
d62a17ae 2813 /* If rip is not enabled before. */
2814 if (!rip) {
aad95a7d
QY
2815 ret = rip_create();
2816 if (ret < 0) {
2817 zlog_info("Can't create RIP");
2818 return CMD_WARNING_CONFIG_FAILED;
2819 }
718e3744 2820 }
aad95a7d 2821
d62a17ae 2822 VTY_PUSH_CONTEXT(RIP_NODE, rip);
718e3744 2823
d62a17ae 2824 return CMD_SUCCESS;
718e3744 2825}
2826
2827DEFUN (no_router_rip,
2828 no_router_rip_cmd,
2829 "no router rip",
2830 NO_STR
2831 "Enable a routing process\n"
2832 "Routing Information Protocol (RIP)\n")
2833{
d62a17ae 2834 if (rip)
2835 rip_clean();
2836 return CMD_SUCCESS;
718e3744 2837}
2838
2839DEFUN (rip_version,
2840 rip_version_cmd,
6147e2c6 2841 "version (1-2)",
718e3744 2842 "Set routing protocol version\n"
2843 "version\n")
2844{
d62a17ae 2845 int idx_number = 1;
2846 int version;
718e3744 2847
d62a17ae 2848 version = atoi(argv[idx_number]->arg);
2849 if (version != RIPv1 && version != RIPv2) {
2850 vty_out(vty, "invalid rip version %d\n", version);
2851 return CMD_WARNING_CONFIG_FAILED;
2852 }
2853 rip->version_send = version;
2854 rip->version_recv = version;
718e3744 2855
d62a17ae 2856 return CMD_SUCCESS;
80fa0c69 2857}
718e3744 2858
2859DEFUN (no_rip_version,
2860 no_rip_version_cmd,
55c727dd 2861 "no version [(1-2)]",
718e3744 2862 NO_STR
55c727dd
QY
2863 "Set routing protocol version\n"
2864 "Version\n")
718e3744 2865{
d62a17ae 2866 /* Set RIP version to the default. */
2867 rip->version_send = RI_RIP_VERSION_2;
2868 rip->version_recv = RI_RIP_VERSION_1_AND_2;
718e3744 2869
d62a17ae 2870 return CMD_SUCCESS;
80fa0c69 2871}
718e3744 2872
718e3744 2873
2874DEFUN (rip_route,
2875 rip_route_cmd,
2876 "route A.B.C.D/M",
2877 "RIP static route configuration\n"
2878 "IP prefix <network>/<length>\n")
2879{
d62a17ae 2880 int idx_ipv4_prefixlen = 1;
2881 int ret;
3f5682c8 2882 struct nexthop nh;
d62a17ae 2883 struct prefix_ipv4 p;
2884 struct route_node *node;
718e3744 2885
3f5682c8
DS
2886 memset(&nh, 0, sizeof(nh));
2887 nh.type = NEXTHOP_TYPE_IPV4;
2888
d62a17ae 2889 ret = str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
2890 if (ret < 0) {
2891 vty_out(vty, "Malformed address\n");
2892 return CMD_WARNING_CONFIG_FAILED;
2893 }
2894 apply_mask_ipv4(&p);
718e3744 2895
d62a17ae 2896 /* For router rip configuration. */
2897 node = route_node_get(rip->route, (struct prefix *)&p);
718e3744 2898
d62a17ae 2899 if (node->info) {
2900 vty_out(vty, "There is already same static route.\n");
2901 route_unlock_node(node);
851fcbae 2902 return CMD_WARNING;
d62a17ae 2903 }
718e3744 2904
d62a17ae 2905 node->info = (void *)1;
718e3744 2906
996c9314
LB
2907 rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, &nh, 0, 0,
2908 0);
718e3744 2909
d62a17ae 2910 return CMD_SUCCESS;
718e3744 2911}
2912
2913DEFUN (no_rip_route,
2914 no_rip_route_cmd,
2915 "no route A.B.C.D/M",
2916 NO_STR
2917 "RIP static route configuration\n"
2918 "IP prefix <network>/<length>\n")
2919{
d62a17ae 2920 int idx_ipv4_prefixlen = 2;
2921 int ret;
2922 struct prefix_ipv4 p;
2923 struct route_node *node;
718e3744 2924
d62a17ae 2925 ret = str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
2926 if (ret < 0) {
2927 vty_out(vty, "Malformed address\n");
2928 return CMD_WARNING_CONFIG_FAILED;
2929 }
2930 apply_mask_ipv4(&p);
2931
2932 /* For router rip configuration. */
2933 node = route_node_lookup(rip->route, (struct prefix *)&p);
2934 if (!node) {
2935 vty_out(vty, "Can't find route %s.\n",
2936 argv[idx_ipv4_prefixlen]->arg);
2937 return CMD_WARNING_CONFIG_FAILED;
2938 }
718e3744 2939
d62a17ae 2940 rip_redistribute_delete(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
2941 route_unlock_node(node);
718e3744 2942
d62a17ae 2943 node->info = NULL;
2944 route_unlock_node(node);
718e3744 2945
d62a17ae 2946 return CMD_SUCCESS;
718e3744 2947}
2948
2c239705 2949#if 0
dc63bfd4 2950static void
216565ab 2951rip_update_default_metric (void)
718e3744 2952{
2953 struct route_node *np;
bce8e868
LF
2954 struct rip_info *rinfo = NULL;
2955 struct list *list = NULL;
2956 struct listnode *listnode = NULL;
718e3744 2957
2958 for (np = route_top (rip->table); np; np = route_next (np))
bce8e868
LF
2959 if ((list = np->info) != NULL)
2960 for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo))
2961 if (rinfo->type != ZEBRA_ROUTE_RIP && rinfo->type != ZEBRA_ROUTE_CONNECT)
2962 rinfo->metric = rip->default_metric;
718e3744 2963}
2c239705 2964#endif
718e3744 2965
2966DEFUN (rip_default_metric,
2967 rip_default_metric_cmd,
6147e2c6 2968 "default-metric (1-16)",
718e3744 2969 "Set a metric of redistribute routes\n"
2970 "Default metric\n")
2971{
d62a17ae 2972 int idx_number = 1;
2973 if (rip) {
2974 rip->default_metric = atoi(argv[idx_number]->arg);
2975 /* rip_update_default_metric (); */
2976 }
2977 return CMD_SUCCESS;
718e3744 2978}
2979
2980DEFUN (no_rip_default_metric,
2981 no_rip_default_metric_cmd,
55c727dd 2982 "no default-metric [(1-16)]",
718e3744 2983 NO_STR
2984 "Set a metric of redistribute routes\n"
2985 "Default metric\n")
2986{
d62a17ae 2987 if (rip) {
2988 rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
2989 /* rip_update_default_metric (); */
2990 }
2991 return CMD_SUCCESS;
718e3744 2992}
2993
718e3744 2994
2995DEFUN (rip_timers,
2996 rip_timers_cmd,
6147e2c6 2997 "timers basic (5-2147483647) (5-2147483647) (5-2147483647)",
718e3744 2998 "Adjust routing timers\n"
2999 "Basic routing protocol update timers\n"
3000 "Routing table update timer value in second. Default is 30.\n"
3001 "Routing information timeout timer. Default is 180.\n"
3002 "Garbage collection timer. Default is 120.\n")
3003{
d62a17ae 3004 int idx_number = 2;
3005 int idx_number_2 = 3;
3006 int idx_number_3 = 4;
3007 unsigned long update;
3008 unsigned long timeout;
3009 unsigned long garbage;
3010 char *endptr = NULL;
3011 unsigned long RIP_TIMER_MAX = 2147483647;
3012 unsigned long RIP_TIMER_MIN = 5;
3013
3014 update = strtoul(argv[idx_number]->arg, &endptr, 10);
3015 if (update > RIP_TIMER_MAX || update < RIP_TIMER_MIN
3016 || *endptr != '\0') {
3017 vty_out(vty, "update timer value error\n");
3018 return CMD_WARNING_CONFIG_FAILED;
3019 }
3020
3021 timeout = strtoul(argv[idx_number_2]->arg, &endptr, 10);
3022 if (timeout > RIP_TIMER_MAX || timeout < RIP_TIMER_MIN
3023 || *endptr != '\0') {
3024 vty_out(vty, "timeout timer value error\n");
3025 return CMD_WARNING_CONFIG_FAILED;
3026 }
3027
3028 garbage = strtoul(argv[idx_number_3]->arg, &endptr, 10);
3029 if (garbage > RIP_TIMER_MAX || garbage < RIP_TIMER_MIN
3030 || *endptr != '\0') {
3031 vty_out(vty, "garbage timer value error\n");
3032 return CMD_WARNING_CONFIG_FAILED;
3033 }
3034
3035 /* Set each timer value. */
3036 rip->update_time = update;
3037 rip->timeout_time = timeout;
3038 rip->garbage_time = garbage;
3039
3040 /* Reset update timer thread. */
3041 rip_event(RIP_UPDATE_EVENT, 0);
3042
3043 return CMD_SUCCESS;
718e3744 3044}
3045
3046DEFUN (no_rip_timers,
3047 no_rip_timers_cmd,
55c727dd 3048 "no timers basic [(0-65535) (0-65535) (0-65535)]",
718e3744 3049 NO_STR
3050 "Adjust routing timers\n"
55c727dd
QY
3051 "Basic routing protocol update timers\n"
3052 "Routing table update timer value in second. Default is 30.\n"
3053 "Routing information timeout timer. Default is 180.\n"
3054 "Garbage collection timer. Default is 120.\n")
718e3744 3055{
d62a17ae 3056 /* Set each timer value to the default. */
3057 rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
3058 rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
3059 rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
718e3744 3060
d62a17ae 3061 /* Reset update timer thread. */
3062 rip_event(RIP_UPDATE_EVENT, 0);
718e3744 3063
d62a17ae 3064 return CMD_SUCCESS;
718e3744 3065}
16705130 3066
16705130 3067
718e3744 3068struct route_table *rip_distance_table;
3069
d62a17ae 3070struct rip_distance {
3071 /* Distance value for the IP source prefix. */
d7c0a89a 3072 uint8_t distance;
718e3744 3073
d62a17ae 3074 /* Name of the access-list to be matched. */
3075 char *access_list;
718e3744 3076};
3077
d62a17ae 3078static struct rip_distance *rip_distance_new(void)
718e3744 3079{
d62a17ae 3080 return XCALLOC(MTYPE_RIP_DISTANCE, sizeof(struct rip_distance));
718e3744 3081}
3082
d62a17ae 3083static void rip_distance_free(struct rip_distance *rdistance)
3084{
3085 XFREE(MTYPE_RIP_DISTANCE, rdistance);
718e3744 3086}
3087
d62a17ae 3088static int rip_distance_set(struct vty *vty, const char *distance_str,
3089 const char *ip_str, const char *access_list_str)
718e3744 3090{
d62a17ae 3091 int ret;
3092 struct prefix_ipv4 p;
d7c0a89a 3093 uint8_t distance;
d62a17ae 3094 struct route_node *rn;
3095 struct rip_distance *rdistance;
3096
3097 ret = str2prefix_ipv4(ip_str, &p);
3098 if (ret == 0) {
3099 vty_out(vty, "Malformed prefix\n");
3100 return CMD_WARNING_CONFIG_FAILED;
3101 }
3102
3103 distance = atoi(distance_str);
3104
3105 /* Get RIP distance node. */
3106 rn = route_node_get(rip_distance_table, (struct prefix *)&p);
3107 if (rn->info) {
3108 rdistance = rn->info;
3109 route_unlock_node(rn);
3110 } else {
3111 rdistance = rip_distance_new();
3112 rn->info = rdistance;
3113 }
3114
3115 /* Set distance value. */
3116 rdistance->distance = distance;
3117
3118 /* Reset access-list configuration. */
3119 if (rdistance->access_list) {
3120 free(rdistance->access_list);
3121 rdistance->access_list = NULL;
3122 }
3123 if (access_list_str)
3124 rdistance->access_list = strdup(access_list_str);
3125
3126 return CMD_SUCCESS;
3127}
3128
3129static int rip_distance_unset(struct vty *vty, const char *distance_str,
3130 const char *ip_str, const char *access_list_str)
3131{
3132 int ret;
3133 struct prefix_ipv4 p;
3134 struct route_node *rn;
3135 struct rip_distance *rdistance;
3136
3137 ret = str2prefix_ipv4(ip_str, &p);
3138 if (ret == 0) {
3139 vty_out(vty, "Malformed prefix\n");
3140 return CMD_WARNING_CONFIG_FAILED;
3141 }
3142
3143 rn = route_node_lookup(rip_distance_table, (struct prefix *)&p);
3144 if (!rn) {
3145 vty_out(vty, "Can't find specified prefix\n");
3146 return CMD_WARNING_CONFIG_FAILED;
3147 }
3148
3149 rdistance = rn->info;
718e3744 3150
718e3744 3151 if (rdistance->access_list)
d62a17ae 3152 free(rdistance->access_list);
3153 rip_distance_free(rdistance);
3154
718e3744 3155 rn->info = NULL;
d62a17ae 3156 route_unlock_node(rn);
3157 route_unlock_node(rn);
3158
3159 return CMD_SUCCESS;
718e3744 3160}
3161
d62a17ae 3162static void rip_distance_reset(void)
3163{
3164 struct route_node *rn;
3165 struct rip_distance *rdistance;
718e3744 3166
d62a17ae 3167 for (rn = route_top(rip_distance_table); rn; rn = route_next(rn))
3168 if ((rdistance = rn->info) != NULL) {
3169 if (rdistance->access_list)
3170 free(rdistance->access_list);
3171 rip_distance_free(rdistance);
3172 rn->info = NULL;
3173 route_unlock_node(rn);
3174 }
3175}
3176
3177/* Apply RIP information to distance method. */
d7c0a89a 3178uint8_t rip_distance_apply(struct rip_info *rinfo)
d62a17ae 3179{
3180 struct route_node *rn;
3181 struct prefix_ipv4 p;
3182 struct rip_distance *rdistance;
3183 struct access_list *alist;
3184
3185 if (!rip)
3186 return 0;
3187
3188 memset(&p, 0, sizeof(struct prefix_ipv4));
3189 p.family = AF_INET;
3190 p.prefix = rinfo->from;
3191 p.prefixlen = IPV4_MAX_BITLEN;
3192
3193 /* Check source address. */
3194 rn = route_node_match(rip_distance_table, (struct prefix *)&p);
3195 if (rn) {
3196 rdistance = rn->info;
3197 route_unlock_node(rn);
3198
3199 if (rdistance->access_list) {
3200 alist = access_list_lookup(AFI_IP,
3201 rdistance->access_list);
3202 if (alist == NULL)
3203 return 0;
3204 if (access_list_apply(alist, &rinfo->rp->p)
3205 == FILTER_DENY)
3206 return 0;
3207
3208 return rdistance->distance;
3209 } else
3210 return rdistance->distance;
718e3744 3211 }
718e3744 3212
d62a17ae 3213 if (rip->distance)
3214 return rip->distance;
718e3744 3215
d62a17ae 3216 return 0;
718e3744 3217}
3218
d62a17ae 3219static void rip_distance_show(struct vty *vty)
3220{
3221 struct route_node *rn;
3222 struct rip_distance *rdistance;
3223 int header = 1;
3224 char buf[BUFSIZ];
3225
3226 vty_out(vty, " Distance: (default is %d)\n",
3227 rip->distance ? rip->distance : ZEBRA_RIP_DISTANCE_DEFAULT);
3228
3229 for (rn = route_top(rip_distance_table); rn; rn = route_next(rn))
3230 if ((rdistance = rn->info) != NULL) {
3231 if (header) {
3232 vty_out(vty,
3233 " Address Distance List\n");
3234 header = 0;
3235 }
3236 sprintf(buf, "%s/%d", inet_ntoa(rn->p.u.prefix4),
3237 rn->p.prefixlen);
3238 vty_out(vty, " %-20s %4d %s\n", buf,
3239 rdistance->distance,
3240 rdistance->access_list ? rdistance->access_list
3241 : "");
3242 }
718e3744 3243}
3244
3245DEFUN (rip_distance,
3246 rip_distance_cmd,
6147e2c6 3247 "distance (1-255)",
718e3744 3248 "Administrative distance\n"
3249 "Distance value\n")
3250{
d62a17ae 3251 int idx_number = 1;
3252 rip->distance = atoi(argv[idx_number]->arg);
3253 return CMD_SUCCESS;
718e3744 3254}
3255
3256DEFUN (no_rip_distance,
3257 no_rip_distance_cmd,
6147e2c6 3258 "no distance (1-255)",
718e3744 3259 NO_STR
3260 "Administrative distance\n"
3261 "Distance value\n")
3262{
d62a17ae 3263 rip->distance = 0;
3264 return CMD_SUCCESS;
718e3744 3265}
3266
3267DEFUN (rip_distance_source,
3268 rip_distance_source_cmd,
6147e2c6 3269 "distance (1-255) A.B.C.D/M",
718e3744 3270 "Administrative distance\n"
3271 "Distance value\n"
3272 "IP source prefix\n")
3273{
d62a17ae 3274 int idx_number = 1;
3275 int idx_ipv4_prefixlen = 2;
3276 rip_distance_set(vty, argv[idx_number]->arg,
3277 argv[idx_ipv4_prefixlen]->arg, NULL);
3278 return CMD_SUCCESS;
718e3744 3279}
3280
3281DEFUN (no_rip_distance_source,
3282 no_rip_distance_source_cmd,
6147e2c6 3283 "no distance (1-255) A.B.C.D/M",
718e3744 3284 NO_STR
3285 "Administrative distance\n"
3286 "Distance value\n"
3287 "IP source prefix\n")
3288{
d62a17ae 3289 int idx_number = 2;
3290 int idx_ipv4_prefixlen = 3;
3291 rip_distance_unset(vty, argv[idx_number]->arg,
3292 argv[idx_ipv4_prefixlen]->arg, NULL);
3293 return CMD_SUCCESS;
718e3744 3294}
3295
3296DEFUN (rip_distance_source_access_list,
3297 rip_distance_source_access_list_cmd,
6147e2c6 3298 "distance (1-255) A.B.C.D/M WORD",
718e3744 3299 "Administrative distance\n"
3300 "Distance value\n"
3301 "IP source prefix\n"
3302 "Access list name\n")
3303{
d62a17ae 3304 int idx_number = 1;
3305 int idx_ipv4_prefixlen = 2;
3306 int idx_word = 3;
3307 rip_distance_set(vty, argv[idx_number]->arg,
3308 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
3309 return CMD_SUCCESS;
718e3744 3310}
3311
3312DEFUN (no_rip_distance_source_access_list,
3313 no_rip_distance_source_access_list_cmd,
6147e2c6 3314 "no distance (1-255) A.B.C.D/M WORD",
718e3744 3315 NO_STR
3316 "Administrative distance\n"
3317 "Distance value\n"
3318 "IP source prefix\n"
3319 "Access list name\n")
3320{
d62a17ae 3321 int idx_number = 2;
3322 int idx_ipv4_prefixlen = 3;
3323 int idx_word = 4;
3324 rip_distance_unset(vty, argv[idx_number]->arg,
3325 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
3326 return CMD_SUCCESS;
718e3744 3327}
6b0655a2 3328
8478ae7e 3329/* Update ECMP routes to zebra when ECMP is disabled. */
d62a17ae 3330static void rip_ecmp_disable(void)
3331{
3332 struct route_node *rp;
3333 struct rip_info *rinfo, *tmp_rinfo;
3334 struct list *list;
3335 struct listnode *node, *nextnode;
3336
3337 if (!rip)
3338 return;
3339
3340 for (rp = route_top(rip->table); rp; rp = route_next(rp))
3341 if ((list = rp->info) != NULL && listcount(list) > 1) {
3342 rinfo = listgetdata(listhead(list));
3343 if (!rip_route_rte(rinfo))
3344 continue;
3345
3346 /* Drop all other entries, except the first one. */
3347 for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo))
3348 if (tmp_rinfo != rinfo) {
3349 RIP_TIMER_OFF(tmp_rinfo->t_timeout);
3350 RIP_TIMER_OFF(
3351 tmp_rinfo->t_garbage_collect);
3352 list_delete_node(list, node);
3353 rip_info_free(tmp_rinfo);
3354 }
3355
3356 /* Update zebra. */
3357 rip_zebra_ipv4_add(rp);
3358
3359 /* Set the route change flag. */
3360 SET_FLAG(rinfo->flags, RIP_RTF_CHANGED);
3361
3362 /* Signal the output process to trigger an update. */
3363 rip_event(RIP_TRIGGERED_UPDATE, 0);
3364 }
8478ae7e
LF
3365}
3366
3367DEFUN (rip_allow_ecmp,
3368 rip_allow_ecmp_cmd,
3369 "allow-ecmp",
3370 "Allow Equal Cost MultiPath\n")
3371{
d62a17ae 3372 if (rip->ecmp) {
3373 vty_out(vty, "ECMP is already enabled.\n");
851fcbae 3374 return CMD_WARNING;
d62a17ae 3375 }
8478ae7e 3376
d62a17ae 3377 rip->ecmp = 1;
3378 zlog_info("ECMP is enabled.");
3379 return CMD_SUCCESS;
8478ae7e
LF
3380}
3381
3382DEFUN (no_rip_allow_ecmp,
3383 no_rip_allow_ecmp_cmd,
3384 "no allow-ecmp",
3385 NO_STR
3386 "Allow Equal Cost MultiPath\n")
3387{
d62a17ae 3388 if (!rip->ecmp) {
3389 vty_out(vty, "ECMP is already disabled.\n");
851fcbae 3390 return CMD_WARNING;
d62a17ae 3391 }
8478ae7e 3392
d62a17ae 3393 rip->ecmp = 0;
3394 zlog_info("ECMP is disabled.");
3395 rip_ecmp_disable();
3396 return CMD_SUCCESS;
8478ae7e
LF
3397}
3398
718e3744 3399/* Print out routes update time. */
d62a17ae 3400static void rip_vty_out_uptime(struct vty *vty, struct rip_info *rinfo)
718e3744 3401{
d62a17ae 3402 time_t clock;
3403 struct tm *tm;
718e3744 3404#define TIME_BUF 25
d62a17ae 3405 char timebuf[TIME_BUF];
3406 struct thread *thread;
3407
3408 if ((thread = rinfo->t_timeout) != NULL) {
3409 clock = thread_timer_remain_second(thread);
3410 tm = gmtime(&clock);
3411 strftime(timebuf, TIME_BUF, "%M:%S", tm);
3412 vty_out(vty, "%5s", timebuf);
3413 } else if ((thread = rinfo->t_garbage_collect) != NULL) {
3414 clock = thread_timer_remain_second(thread);
3415 tm = gmtime(&clock);
3416 strftime(timebuf, TIME_BUF, "%M:%S", tm);
3417 vty_out(vty, "%5s", timebuf);
3418 }
3419}
3420
3421static const char *rip_route_type_print(int sub_type)
3422{
3423 switch (sub_type) {
3424 case RIP_ROUTE_RTE:
3425 return "n";
3426 case RIP_ROUTE_STATIC:
3427 return "s";
3428 case RIP_ROUTE_DEFAULT:
3429 return "d";
3430 case RIP_ROUTE_REDISTRIBUTE:
3431 return "r";
3432 case RIP_ROUTE_INTERFACE:
3433 return "i";
3434 default:
3435 return "?";
3436 }
718e3744 3437}
3438
3439DEFUN (show_ip_rip,
3440 show_ip_rip_cmd,
3441 "show ip rip",
3442 SHOW_STR
3443 IP_STR
3444 "Show RIP routes\n")
3445{
d62a17ae 3446 struct route_node *np;
3447 struct rip_info *rinfo = NULL;
3448 struct list *list = NULL;
3449 struct listnode *listnode = NULL;
3450
3451 if (!rip)
3452 return CMD_SUCCESS;
3453
3454 vty_out(vty,
3455 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
3456 "Sub-codes:\n"
3457 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
3458 " (i) - interface\n\n"
3459 " Network Next Hop Metric From Tag Time\n");
3460
3461 for (np = route_top(rip->table); np; np = route_next(np))
3462 if ((list = np->info) != NULL)
3463 for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
3464 int len;
3465
3466 len = vty_out(
3467 vty, "%c(%s) %s/%d",
3468 /* np->lock, For debugging. */
3469 zebra_route_char(rinfo->type),
3470 rip_route_type_print(rinfo->sub_type),
3471 inet_ntoa(np->p.u.prefix4),
3472 np->p.prefixlen);
3473
3474 len = 24 - len;
3475
3476 if (len > 0)
3477 vty_out(vty, "%*s", len, " ");
3478
996c9314 3479 switch (rinfo->nh.type) {
3f5682c8
DS
3480 case NEXTHOP_TYPE_IPV4:
3481 case NEXTHOP_TYPE_IPV4_IFINDEX:
d62a17ae 3482 vty_out(vty, "%-20s %2d ",
dd127197 3483 inet_ntoa(rinfo->nh.gate.ipv4),
d62a17ae 3484 rinfo->metric);
3f5682c8
DS
3485 break;
3486 case NEXTHOP_TYPE_IFINDEX:
d62a17ae 3487 vty_out(vty,
3488 "0.0.0.0 %2d ",
3489 rinfo->metric);
3f5682c8
DS
3490 break;
3491 case NEXTHOP_TYPE_BLACKHOLE:
3492 vty_out(vty,
3493 "blackhole %2d ",
3494 rinfo->metric);
3495 break;
3496 case NEXTHOP_TYPE_IPV6:
3497 case NEXTHOP_TYPE_IPV6_IFINDEX:
3498 vty_out(vty,
3499 "V6 Address Hidden %2d ",
3500 rinfo->metric);
3501 break;
3502 }
d62a17ae 3503
3504 /* Route which exist in kernel routing table. */
3505 if ((rinfo->type == ZEBRA_ROUTE_RIP)
3506 && (rinfo->sub_type == RIP_ROUTE_RTE)) {
3507 vty_out(vty, "%-15s ",
3508 inet_ntoa(rinfo->from));
3509 vty_out(vty, "%3" ROUTE_TAG_PRI " ",
3510 (route_tag_t)rinfo->tag);
3511 rip_vty_out_uptime(vty, rinfo);
3512 } else if (rinfo->metric
3513 == RIP_METRIC_INFINITY) {
3514 vty_out(vty, "self ");
3515 vty_out(vty, "%3" ROUTE_TAG_PRI " ",
3516 (route_tag_t)rinfo->tag);
3517 rip_vty_out_uptime(vty, rinfo);
3518 } else {
3519 if (rinfo->external_metric) {
3520 len = vty_out(
3521 vty, "self (%s:%d)",
3522 zebra_route_string(
3523 rinfo->type),
3524 rinfo->external_metric);
3525 len = 16 - len;
3526 if (len > 0)
3527 vty_out(vty, "%*s", len,
3528 " ");
3529 } else
3530 vty_out(vty,
3531 "self ");
3532 vty_out(vty, "%3" ROUTE_TAG_PRI,
3533 (route_tag_t)rinfo->tag);
3534 }
3535
3536 vty_out(vty, "\n");
3537 }
3538 return CMD_SUCCESS;
718e3744 3539}
3540
16705130 3541/* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3542DEFUN (show_ip_rip_status,
3543 show_ip_rip_status_cmd,
3544 "show ip rip status",
718e3744 3545 SHOW_STR
3546 IP_STR
16705130 3547 "Show RIP routes\n"
718e3744 3548 "IP routing protocol process parameters and statistics\n")
3549{
f4e14fdb 3550 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 3551 struct interface *ifp;
3552 struct rip_interface *ri;
3553 extern const struct message ri_version_msg[];
3554 const char *send_version;
3555 const char *receive_version;
3556
3557 if (!rip)
3558 return CMD_SUCCESS;
3559
3560 vty_out(vty, "Routing Protocol is \"rip\"\n");
3561 vty_out(vty, " Sending updates every %ld seconds with +/-50%%,",
3562 rip->update_time);
3563 vty_out(vty, " next due in %lu seconds\n",
3564 thread_timer_remain_second(rip->t_update));
3565 vty_out(vty, " Timeout after %ld seconds,", rip->timeout_time);
3566 vty_out(vty, " garbage collect after %ld seconds\n", rip->garbage_time);
3567
3568 /* Filtering status show. */
3569 config_show_distribute(vty);
3570
3571 /* Default metric information. */
3572 vty_out(vty, " Default redistribution metric is %d\n",
3573 rip->default_metric);
3574
3575 /* Redistribute information. */
3576 vty_out(vty, " Redistributing:");
3577 config_write_rip_redistribute(vty, 0);
3578 vty_out(vty, "\n");
3579
3580 vty_out(vty, " Default version control: send version %s,",
3581 lookup_msg(ri_version_msg, rip->version_send, NULL));
3582 if (rip->version_recv == RI_RIP_VERSION_1_AND_2)
3583 vty_out(vty, " receive any version \n");
3584 else
3585 vty_out(vty, " receive version %s \n",
3586 lookup_msg(ri_version_msg, rip->version_recv, NULL));
3587
3588 vty_out(vty, " Interface Send Recv Key-chain\n");
3589
451fda4f 3590 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 3591 ri = ifp->info;
3592
3593 if (!ri->running)
3594 continue;
3595
3596 if (ri->enable_network || ri->enable_interface) {
3597 if (ri->ri_send == RI_RIP_UNSPEC)
3598 send_version =
3599 lookup_msg(ri_version_msg,
3600 rip->version_send, NULL);
3601 else
3602 send_version = lookup_msg(ri_version_msg,
3603 ri->ri_send, NULL);
3604
3605 if (ri->ri_receive == RI_RIP_UNSPEC)
3606 receive_version =
3607 lookup_msg(ri_version_msg,
3608 rip->version_recv, NULL);
3609 else
3610 receive_version = lookup_msg(
3611 ri_version_msg, ri->ri_receive, NULL);
3612
3613 vty_out(vty, " %-17s%-3s %-3s %s\n", ifp->name,
3614 send_version, receive_version,
3615 ri->key_chain ? ri->key_chain : "");
3616 }
3617 }
718e3744 3618
d62a17ae 3619 vty_out(vty, " Routing for Networks:\n");
3620 config_write_rip_network(vty, 0);
718e3744 3621
718e3744 3622 {
d62a17ae 3623 int found_passive = 0;
451fda4f 3624 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 3625 ri = ifp->info;
3626
3627 if ((ri->enable_network || ri->enable_interface)
3628 && ri->passive) {
3629 if (!found_passive) {
3630 vty_out(vty,
3631 " Passive Interface(s):\n");
3632 found_passive = 1;
3633 }
3634 vty_out(vty, " %s\n", ifp->name);
3635 }
3636 }
718e3744 3637 }
3638
d62a17ae 3639 vty_out(vty, " Routing Information Sources:\n");
3640 vty_out(vty,
3641 " Gateway BadPackets BadRoutes Distance Last Update\n");
3642 rip_peer_display(vty);
718e3744 3643
d62a17ae 3644 rip_distance_show(vty);
718e3744 3645
d62a17ae 3646 return CMD_SUCCESS;
3647}
718e3744 3648
d62a17ae 3649/* RIP configuration write function. */
3650static int config_write_rip(struct vty *vty)
3651{
3652 int write = 0;
3653 struct route_node *rn;
3654 struct rip_distance *rdistance;
3655
3656 if (rip) {
3657 /* Router RIP statement. */
3658 vty_out(vty, "router rip\n");
3659 write++;
3660
3661 /* RIP version statement. Default is RIP version 2. */
3662 if (rip->version_send != RI_RIP_VERSION_2
3663 || rip->version_recv != RI_RIP_VERSION_1_AND_2)
3664 vty_out(vty, " version %d\n", rip->version_send);
3665
3666 /* RIP timer configuration. */
3667 if (rip->update_time != RIP_UPDATE_TIMER_DEFAULT
3668 || rip->timeout_time != RIP_TIMEOUT_TIMER_DEFAULT
3669 || rip->garbage_time != RIP_GARBAGE_TIMER_DEFAULT)
3670 vty_out(vty, " timers basic %lu %lu %lu\n",
3671 rip->update_time, rip->timeout_time,
3672 rip->garbage_time);
3673
3674 /* Default information configuration. */
3675 if (rip->default_information) {
3676 if (rip->default_information_route_map)
3677 vty_out(vty,
3678 " default-information originate route-map %s\n",
3679 rip->default_information_route_map);
3680 else
3681 vty_out(vty,
3682 " default-information originate\n");
3683 }
16705130 3684
d62a17ae 3685 /* Redistribute configuration. */
3686 config_write_rip_redistribute(vty, 1);
3687
3688 /* RIP offset-list configuration. */
3689 config_write_rip_offset_list(vty);
3690
3691 /* RIP enabled network and interface configuration. */
3692 config_write_rip_network(vty, 1);
3693
3694 /* RIP default metric configuration */
3695 if (rip->default_metric != RIP_DEFAULT_METRIC_DEFAULT)
3696 vty_out(vty, " default-metric %d\n",
3697 rip->default_metric);
3698
3699 /* Distribute configuration. */
3700 write += config_write_distribute(vty);
3701
3702 /* Interface routemap configuration */
3703 write += config_write_if_rmap(vty);
3704
3705 /* Distance configuration. */
3706 if (rip->distance)
3707 vty_out(vty, " distance %d\n", rip->distance);
3708
3709 /* RIP source IP prefix distance configuration. */
3710 for (rn = route_top(rip_distance_table); rn;
3711 rn = route_next(rn))
3712 if ((rdistance = rn->info) != NULL)
3713 vty_out(vty, " distance %d %s/%d %s\n",
3714 rdistance->distance,
3715 inet_ntoa(rn->p.u.prefix4),
3716 rn->p.prefixlen,
3717 rdistance->access_list
3718 ? rdistance->access_list
3719 : "");
3720
3721 /* ECMP configuration. */
3722 if (rip->ecmp)
3723 vty_out(vty, " allow-ecmp\n");
3724
3725 /* RIP static route configuration. */
3726 for (rn = route_top(rip->route); rn; rn = route_next(rn))
3727 if (rn->info)
3728 vty_out(vty, " route %s/%d\n",
3729 inet_ntoa(rn->p.u.prefix4),
3730 rn->p.prefixlen);
3731 }
3732 return write;
3733}
718e3744 3734
d62a17ae 3735/* RIP node structure. */
3736static struct cmd_node rip_node = {RIP_NODE, "%s(config-router)# ", 1};
718e3744 3737
d62a17ae 3738/* Distribute-list update functions. */
3739static void rip_distribute_update(struct distribute *dist)
3740{
3741 struct interface *ifp;
3742 struct rip_interface *ri;
3743 struct access_list *alist;
3744 struct prefix_list *plist;
8478ae7e 3745
d62a17ae 3746 if (!dist->ifname)
3747 return;
718e3744 3748
d62a17ae 3749 ifp = if_lookup_by_name(dist->ifname, VRF_DEFAULT);
3750 if (ifp == NULL)
3751 return;
718e3744 3752
d62a17ae 3753 ri = ifp->info;
6b0655a2 3754
d62a17ae 3755 if (dist->list[DISTRIBUTE_V4_IN]) {
3756 alist = access_list_lookup(AFI_IP,
3757 dist->list[DISTRIBUTE_V4_IN]);
3758 if (alist)
3759 ri->list[RIP_FILTER_IN] = alist;
3760 else
3761 ri->list[RIP_FILTER_IN] = NULL;
3762 } else
3763 ri->list[RIP_FILTER_IN] = NULL;
3764
3765 if (dist->list[DISTRIBUTE_V4_OUT]) {
3766 alist = access_list_lookup(AFI_IP,
3767 dist->list[DISTRIBUTE_V4_OUT]);
3768 if (alist)
3769 ri->list[RIP_FILTER_OUT] = alist;
3770 else
3771 ri->list[RIP_FILTER_OUT] = NULL;
3772 } else
3773 ri->list[RIP_FILTER_OUT] = NULL;
3774
3775 if (dist->prefix[DISTRIBUTE_V4_IN]) {
3776 plist = prefix_list_lookup(AFI_IP,
3777 dist->prefix[DISTRIBUTE_V4_IN]);
3778 if (plist)
3779 ri->prefix[RIP_FILTER_IN] = plist;
3780 else
3781 ri->prefix[RIP_FILTER_IN] = NULL;
3782 } else
3783 ri->prefix[RIP_FILTER_IN] = NULL;
3784
3785 if (dist->prefix[DISTRIBUTE_V4_OUT]) {
3786 plist = prefix_list_lookup(AFI_IP,
3787 dist->prefix[DISTRIBUTE_V4_OUT]);
3788 if (plist)
3789 ri->prefix[RIP_FILTER_OUT] = plist;
3790 else
3791 ri->prefix[RIP_FILTER_OUT] = NULL;
3792 } else
3793 ri->prefix[RIP_FILTER_OUT] = NULL;
3794}
3795
3796void rip_distribute_update_interface(struct interface *ifp)
3797{
3798 struct distribute *dist;
3799
3800 dist = distribute_lookup(ifp->name);
3801 if (dist)
3802 rip_distribute_update(dist);
718e3744 3803}
3804
3805/* Update all interface's distribute list. */
02ff83c5 3806/* ARGSUSED */
d62a17ae 3807static void rip_distribute_update_all(struct prefix_list *notused)
718e3744 3808{
f4e14fdb 3809 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 3810 struct interface *ifp;
718e3744 3811
451fda4f 3812 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 3813 rip_distribute_update_interface(ifp);
718e3744 3814}
11dde9c2 3815/* ARGSUSED */
d62a17ae 3816static void rip_distribute_update_all_wrapper(struct access_list *notused)
11dde9c2 3817{
d62a17ae 3818 rip_distribute_update_all(NULL);
11dde9c2 3819}
6b0655a2 3820
718e3744 3821/* Delete all added rip route. */
d62a17ae 3822void rip_clean(void)
718e3744 3823{
d62a17ae 3824 int i;
3825 struct route_node *rp;
3826 struct rip_info *rinfo = NULL;
3827 struct list *list = NULL;
3828 struct listnode *listnode = NULL;
3829
3830 if (rip) {
3831 QOBJ_UNREG(rip);
3832
3833 /* Clear RIP routes */
3834 for (rp = route_top(rip->table); rp; rp = route_next(rp))
3835 if ((list = rp->info) != NULL) {
3836 rinfo = listgetdata(listhead(list));
3837 if (rip_route_rte(rinfo))
3838 rip_zebra_ipv4_delete(rp);
3839
3840 for (ALL_LIST_ELEMENTS_RO(list, listnode,
3841 rinfo)) {
3842 RIP_TIMER_OFF(rinfo->t_timeout);
3843 RIP_TIMER_OFF(rinfo->t_garbage_collect);
3844 rip_info_free(rinfo);
3845 }
affe9e99 3846 list_delete_and_null(&list);
d62a17ae 3847 rp->info = NULL;
3848 route_unlock_node(rp);
3849 }
3850
3851 /* Cancel RIP related timers. */
3852 RIP_TIMER_OFF(rip->t_update);
3853 RIP_TIMER_OFF(rip->t_triggered_update);
3854 RIP_TIMER_OFF(rip->t_triggered_interval);
3855
3856 /* Cancel read thread. */
3857 THREAD_READ_OFF(rip->t_read);
3858
3859 /* Close RIP socket. */
3860 if (rip->sock >= 0) {
3861 close(rip->sock);
3862 rip->sock = -1;
3863 }
718e3744 3864
00c9a53d 3865 stream_free(rip->obuf);
d62a17ae 3866 /* Static RIP route configuration. */
3867 for (rp = route_top(rip->route); rp; rp = route_next(rp))
3868 if (rp->info) {
3869 rp->info = NULL;
3870 route_unlock_node(rp);
3871 }
3872
3873 /* RIP neighbor configuration. */
3874 for (rp = route_top(rip->neighbor); rp; rp = route_next(rp))
3875 if (rp->info) {
3876 rp->info = NULL;
3877 route_unlock_node(rp);
3878 }
3879
3880 /* Redistribute related clear. */
3881 if (rip->default_information_route_map)
3882 free(rip->default_information_route_map);
3883
3884 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
3885 if (rip->route_map[i].name)
3886 free(rip->route_map[i].name);
3887
3888 XFREE(MTYPE_ROUTE_TABLE, rip->table);
3889 XFREE(MTYPE_ROUTE_TABLE, rip->route);
3890 XFREE(MTYPE_ROUTE_TABLE, rip->neighbor);
3891
3892 XFREE(MTYPE_RIP, rip);
3893 rip = NULL;
3894 }
3895
3896 rip_clean_network();
3897 rip_passive_nondefault_clean();
3898 rip_offset_clean();
3899 rip_interfaces_clean();
3900 rip_distance_reset();
3901 rip_redistribute_clean();
718e3744 3902}
3903
3904/* Reset all values to the default settings. */
d62a17ae 3905void rip_reset(void)
718e3744 3906{
d62a17ae 3907 /* Reset global counters. */
3908 rip_global_route_changes = 0;
3909 rip_global_queries = 0;
718e3744 3910
d62a17ae 3911 /* Call ripd related reset functions. */
3912 rip_debug_reset();
3913 rip_route_map_reset();
718e3744 3914
d62a17ae 3915 /* Call library reset functions. */
3916 vty_reset();
3917 access_list_reset();
3918 prefix_list_reset();
718e3744 3919
d62a17ae 3920 distribute_list_reset();
718e3744 3921
d62a17ae 3922 rip_interfaces_reset();
3923 rip_distance_reset();
718e3744 3924
d62a17ae 3925 rip_zclient_reset();
718e3744 3926}
3927
d62a17ae 3928static void rip_if_rmap_update(struct if_rmap *if_rmap)
16705130 3929{
d62a17ae 3930 struct interface *ifp;
3931 struct rip_interface *ri;
3932 struct route_map *rmap;
16705130 3933
d62a17ae 3934 ifp = if_lookup_by_name(if_rmap->ifname, VRF_DEFAULT);
3935 if (ifp == NULL)
3936 return;
16705130 3937
d62a17ae 3938 ri = ifp->info;
16705130 3939
d62a17ae 3940 if (if_rmap->routemap[IF_RMAP_IN]) {
3941 rmap = route_map_lookup_by_name(if_rmap->routemap[IF_RMAP_IN]);
3942 if (rmap)
3943 ri->routemap[IF_RMAP_IN] = rmap;
3944 else
3945 ri->routemap[IF_RMAP_IN] = NULL;
3946 } else
3947 ri->routemap[RIP_FILTER_IN] = NULL;
16705130 3948
d62a17ae 3949 if (if_rmap->routemap[IF_RMAP_OUT]) {
3950 rmap = route_map_lookup_by_name(if_rmap->routemap[IF_RMAP_OUT]);
3951 if (rmap)
3952 ri->routemap[IF_RMAP_OUT] = rmap;
3953 else
3954 ri->routemap[IF_RMAP_OUT] = NULL;
3955 } else
3956 ri->routemap[RIP_FILTER_OUT] = NULL;
16705130 3957}
3958
d62a17ae 3959void rip_if_rmap_update_interface(struct interface *ifp)
16705130 3960{
d62a17ae 3961 struct if_rmap *if_rmap;
16705130 3962
d62a17ae 3963 if_rmap = if_rmap_lookup(ifp->name);
3964 if (if_rmap)
3965 rip_if_rmap_update(if_rmap);
16705130 3966}
3967
d62a17ae 3968static void rip_routemap_update_redistribute(void)
16705130 3969{
d62a17ae 3970 int i;
16705130 3971
d62a17ae 3972 if (rip) {
3973 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
3974 if (rip->route_map[i].name)
3975 rip->route_map[i].map =
3976 route_map_lookup_by_name(
3977 rip->route_map[i].name);
3978 }
16705130 3979 }
16705130 3980}
3981
11dde9c2 3982/* ARGSUSED */
d62a17ae 3983static void rip_routemap_update(const char *notused)
16705130 3984{
f4e14fdb 3985 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 3986 struct interface *ifp;
16705130 3987
451fda4f 3988 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 3989 rip_if_rmap_update_interface(ifp);
16705130 3990
d62a17ae 3991 rip_routemap_update_redistribute();
16705130 3992}
3993
718e3744 3994/* Allocate new rip structure and set default value. */
d62a17ae 3995void rip_init(void)
3996{
3997 /* Install top nodes. */
3998 install_node(&rip_node, config_write_rip);
3999
4000 /* Install rip commands. */
4001 install_element(VIEW_NODE, &show_ip_rip_cmd);
4002 install_element(VIEW_NODE, &show_ip_rip_status_cmd);
4003 install_element(CONFIG_NODE, &router_rip_cmd);
4004 install_element(CONFIG_NODE, &no_router_rip_cmd);
4005
4006 install_default(RIP_NODE);
4007 install_element(RIP_NODE, &rip_version_cmd);
4008 install_element(RIP_NODE, &no_rip_version_cmd);
4009 install_element(RIP_NODE, &rip_default_metric_cmd);
4010 install_element(RIP_NODE, &no_rip_default_metric_cmd);
4011 install_element(RIP_NODE, &rip_timers_cmd);
4012 install_element(RIP_NODE, &no_rip_timers_cmd);
4013 install_element(RIP_NODE, &rip_route_cmd);
4014 install_element(RIP_NODE, &no_rip_route_cmd);
4015 install_element(RIP_NODE, &rip_distance_cmd);
4016 install_element(RIP_NODE, &no_rip_distance_cmd);
4017 install_element(RIP_NODE, &rip_distance_source_cmd);
4018 install_element(RIP_NODE, &no_rip_distance_source_cmd);
4019 install_element(RIP_NODE, &rip_distance_source_access_list_cmd);
4020 install_element(RIP_NODE, &no_rip_distance_source_access_list_cmd);
4021 install_element(RIP_NODE, &rip_allow_ecmp_cmd);
4022 install_element(RIP_NODE, &no_rip_allow_ecmp_cmd);
4023
4024 /* Debug related init. */
4025 rip_debug_init();
4026
4027 /* Access list install. */
4028 access_list_init();
4029 access_list_add_hook(rip_distribute_update_all_wrapper);
4030 access_list_delete_hook(rip_distribute_update_all_wrapper);
4031
4032 /* Prefix list initialize.*/
4033 prefix_list_init();
4034 prefix_list_add_hook(rip_distribute_update_all);
4035 prefix_list_delete_hook(rip_distribute_update_all);
4036
4037 /* Distribute list install. */
4038 distribute_list_init(RIP_NODE);
4039 distribute_list_add_hook(rip_distribute_update);
4040 distribute_list_delete_hook(rip_distribute_update);
4041
4042 /* Route-map */
4043 rip_route_map_init();
4044 rip_offset_init();
4045
4046 route_map_add_hook(rip_routemap_update);
4047 route_map_delete_hook(rip_routemap_update);
4048
4049 if_rmap_init(RIP_NODE);
4050 if_rmap_hook_add(rip_if_rmap_update);
4051 if_rmap_hook_delete(rip_if_rmap_update);
4052
4053 /* Distance control. */
4054 rip_distance_table = route_table_init();
718e3744 4055}