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