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