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