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