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