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