]> git.proxmox.com Git - mirror_frr.git/blame - ripd/ripd.c
Merge pull request #13428 from opensourcerouting/ripd-bfd-fixes
[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"
24a58196 14#include "frrevent.h"
718e3744 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);
e6685141 53static void rip_triggered_update(struct event *);
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. */
e6685141 124static void rip_garbage_collect(struct event *t)
718e3744 125{
d62a17ae 126 struct rip_info *rinfo;
127 struct route_node *rp;
128
e16d030c 129 rinfo = EVENT_ARG(t);
718e3744 130
d62a17ae 131 /* Off timeout timer. */
e16d030c 132 EVENT_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
e16d030c
DS
214 EVENT_OFF(tmp_rinfo->t_timeout);
215 EVENT_OFF(tmp_rinfo->t_garbage_collect);
91b508dc
DS
216 list_delete_node(list, node);
217 rip_info_free(tmp_rinfo);
218 }
718e3744 219
e16d030c
DS
220 EVENT_OFF(rinfo->t_timeout);
221 EVENT_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
e16d030c 250 EVENT_OFF(rinfo->t_timeout);
d62a17ae 251
252 if (listcount(list) > 1) {
253 /* Some other ECMP entries still exist. Just delete this entry.
254 */
e16d030c 255 EVENT_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. */
e6685141 290static void rip_timeout(struct event *t)
bce8e868 291{
e16d030c 292 struct rip_info *rinfo = EVENT_ARG(t);
045c5389
RW
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) {
e16d030c 301 EVENT_OFF(rinfo->t_timeout);
907a2395
DS
302 event_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
e16d030c
DS
647 EVENT_OFF(rinfo->t_timeout);
648 EVENT_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);
c262df82 1126 rip_peer_bad_packet(rip, ri, 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);
c262df82 1140 rip_peer_bad_packet(rip, ri, 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. */
c262df82 1150 rip_peer_update(rip, ri, 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
762f54f0 1174 if (packet->version == RIPv1 && rte->tag != 0) {
1175 zlog_warn("RIPv1 reserved field is nonzero: %d",
1176 ntohs(rte->tag));
1177 continue;
1178 }
1179
d62a17ae 1180 /* - is the destination address valid (e.g., unicast; not net 0
1181 or 127) */
1182 if (!rip_destination_check(rte->prefix)) {
1183 zlog_info(
1184 "Network is net 0 or net 127 or it is not unicast network");
c262df82 1185 rip_peer_bad_route(rip, ri, from);
d62a17ae 1186 continue;
718e3744 1187 }
1188
d62a17ae 1189 /* Convert metric value to host byte order. */
1190 rte->metric = ntohl(rte->metric);
718e3744 1191
d62a17ae 1192 /* - is the metric valid (i.e., between 1 and 16, inclusive) */
1193 if (!(rte->metric >= 1 && rte->metric <= 16)) {
1194 zlog_info("Route's metric is not in the 1-16 range.");
c262df82 1195 rip_peer_bad_route(rip, ri, from);
d62a17ae 1196 continue;
1197 }
718e3744 1198
d62a17ae 1199 /* RIPv1 does not have nexthop value. */
975a328e
DA
1200 if (packet->version == RIPv1
1201 && rte->nexthop.s_addr != INADDR_ANY) {
53bb7f9b
MS
1202 zlog_info("RIPv1 packet with nexthop value %pI4",
1203 &rte->nexthop);
c262df82 1204 rip_peer_bad_route(rip, ri, from);
d62a17ae 1205 continue;
1206 }
718e3744 1207
d62a17ae 1208 /* That is, if the provided information is ignored, a possibly
1209 sub-optimal, but absolutely valid, route may be taken. If
1210 the received Next Hop is not directly reachable, it should be
1211 treated as 0.0.0.0. */
975a328e
DA
1212 if (packet->version == RIPv2
1213 && rte->nexthop.s_addr != INADDR_ANY) {
d7c0a89a 1214 uint32_t addrval;
d62a17ae 1215
1216 /* Multicast address check. */
1217 addrval = ntohl(rte->nexthop.s_addr);
1218 if (IN_CLASSD(addrval)) {
1219 zlog_info(
53bb7f9b
MS
1220 "Nexthop %pI4 is multicast address, skip this rte",
1221 &rte->nexthop);
d62a17ae 1222 continue;
1223 }
1224
1225 if (!if_lookup_address((void *)&rte->nexthop, AF_INET,
ae7b826a 1226 rip->vrf->vrf_id)) {
d62a17ae 1227 struct route_node *rn;
1228 struct rip_info *rinfo;
1229
1230 rn = route_node_match_ipv4(rip->table,
1231 &rte->nexthop);
1232
1233 if (rn) {
1234 rinfo = rn->info;
1235
1236 if (rinfo->type == ZEBRA_ROUTE_RIP
1237 && rinfo->sub_type
1238 == RIP_ROUTE_RTE) {
1239 if (IS_RIP_DEBUG_EVENT)
1240 zlog_debug(
53bb7f9b
MS
1241 "Next hop %pI4 is on RIP network. Set nexthop to the packet's originator",
1242 &rte->nexthop);
d62a17ae 1243 rte->nexthop = rinfo->from;
1244 } else {
1245 if (IS_RIP_DEBUG_EVENT)
1246 zlog_debug(
53bb7f9b
MS
1247 "Next hop %pI4 is not directly reachable. Treat it as 0.0.0.0",
1248 &rte->nexthop);
975a328e
DA
1249 rte->nexthop.s_addr =
1250 INADDR_ANY;
d62a17ae 1251 }
1252
1253 route_unlock_node(rn);
1254 } else {
1255 if (IS_RIP_DEBUG_EVENT)
1256 zlog_debug(
53bb7f9b
MS
1257 "Next hop %pI4 is not directly reachable. Treat it as 0.0.0.0",
1258 &rte->nexthop);
975a328e 1259 rte->nexthop.s_addr = INADDR_ANY;
d62a17ae 1260 }
1261 }
1262 }
718e3744 1263
d62a17ae 1264 /* For RIPv1, there won't be a valid netmask.
91b508dc
DS
1265 * This is a best guess at the masks. If everyone was using old
1266 * Ciscos before the 'ip subnet zero' option, it would be almost
1267 * right too :-)
1268 *
1269 * Cisco summarize ripv1 advertisements to the classful boundary
1270 * (/16 for class B's) except when the RIP packet does to inside
1271 * the classful network in question.
1272 */
975a328e
DA
1273 if ((packet->version == RIPv1
1274 && rte->prefix.s_addr != INADDR_ANY)
d62a17ae 1275 || (packet->version == RIPv2
975a328e
DA
1276 && (rte->prefix.s_addr != INADDR_ANY
1277 && rte->mask.s_addr == INADDR_ANY))) {
d7c0a89a 1278 uint32_t destination;
d62a17ae 1279
1280 if (subnetted == -1) {
f51eeb86 1281 memcpy(&ifaddr, ifc->address, sizeof(ifaddr));
d62a17ae 1282 memcpy(&ifaddrclass, &ifaddr,
f51eeb86 1283 sizeof(ifaddrclass));
d62a17ae 1284 apply_classful_mask_ipv4(&ifaddrclass);
1285 subnetted = 0;
1286 if (ifaddr.prefixlen > ifaddrclass.prefixlen)
1287 subnetted = 1;
1288 }
1289
1290 destination = ntohl(rte->prefix.s_addr);
1291
1292 if (IN_CLASSA(destination))
1293 masklen2ip(8, &rte->mask);
1294 else if (IN_CLASSB(destination))
1295 masklen2ip(16, &rte->mask);
1296 else if (IN_CLASSC(destination))
1297 masklen2ip(24, &rte->mask);
1298
1299 if (subnetted == 1)
1300 masklen2ip(ifaddrclass.prefixlen,
1301 (struct in_addr *)&destination);
1302 if ((subnetted == 1)
1303 && ((rte->prefix.s_addr & destination)
1304 == ifaddrclass.prefix.s_addr)) {
1305 masklen2ip(ifaddr.prefixlen, &rte->mask);
1306 if ((rte->prefix.s_addr & rte->mask.s_addr)
1307 != rte->prefix.s_addr)
1308 masklen2ip(32, &rte->mask);
1309 if (IS_RIP_DEBUG_EVENT)
53bb7f9b
MS
1310 zlog_debug("Subnetted route %pI4",
1311 &rte->prefix);
d62a17ae 1312 } else {
1313 if ((rte->prefix.s_addr & rte->mask.s_addr)
1314 != rte->prefix.s_addr)
1315 continue;
1316 }
1317
1318 if (IS_RIP_DEBUG_EVENT) {
53bb7f9b
MS
1319 zlog_debug("Resultant route %pI4",
1320 &rte->prefix);
1321 zlog_debug("Resultant mask %pI4",
1322 &rte->mask);
d62a17ae 1323 }
1324 }
1325
1326 /* In case of RIPv2, if prefix in RTE is not netmask applied one
1327 ignore the entry. */
975a328e
DA
1328 if ((packet->version == RIPv2)
1329 && (rte->mask.s_addr != INADDR_ANY)
d62a17ae 1330 && ((rte->prefix.s_addr & rte->mask.s_addr)
1331 != rte->prefix.s_addr)) {
1332 zlog_warn(
53bb7f9b
MS
1333 "RIPv2 address %pI4 is not mask /%d applied one",
1334 &rte->prefix, ip_masklen(rte->mask));
c262df82 1335 rip_peer_bad_route(rip, ri, from);
d62a17ae 1336 continue;
1337 }
1338
1339 /* Default route's netmask is ignored. */
975a328e
DA
1340 if (packet->version == RIPv2
1341 && (rte->prefix.s_addr == INADDR_ANY)
1342 && (rte->mask.s_addr != INADDR_ANY)) {
d62a17ae 1343 if (IS_RIP_DEBUG_EVENT)
1344 zlog_debug(
1345 "Default route with non-zero netmask. Set zero to netmask");
975a328e 1346 rte->mask.s_addr = INADDR_ANY;
d62a17ae 1347 }
1348
1349 /* Routing table updates. */
1350 rip_rte_process(rte, from, ifc->ifp);
718e3744 1351 }
718e3744 1352}
1353
a4e987e0 1354/* Make socket for RIP protocol. */
ae7b826a 1355int rip_create_socket(struct vrf *vrf)
d62a17ae 1356{
1357 int ret;
1358 int sock;
1359 struct sockaddr_in addr;
ae7b826a 1360 const char *vrf_dev = NULL;
d62a17ae 1361
1362 memset(&addr, 0, sizeof(struct sockaddr_in));
1363 addr.sin_family = AF_INET;
1364 addr.sin_addr.s_addr = INADDR_ANY;
6f0e3f6e 1365#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
d62a17ae 1366 addr.sin_len = sizeof(struct sockaddr_in);
6f0e3f6e 1367#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
d62a17ae 1368 /* sending port must always be the RIP port */
1369 addr.sin_port = htons(RIP_PORT_DEFAULT);
1370
1371 /* Make datagram socket. */
ae7b826a
RW
1372 if (vrf->vrf_id != VRF_DEFAULT)
1373 vrf_dev = vrf->name;
0cf6db21 1374 frr_with_privs(&ripd_privs) {
ae7b826a
RW
1375 sock = vrf_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, vrf->vrf_id,
1376 vrf_dev);
1377 if (sock < 0) {
1378 flog_err_sys(EC_LIB_SOCKET,
1379 "Cannot create UDP socket: %s",
1380 safe_strerror(errno));
1381 return -1;
1382 }
d62a17ae 1383 }
1384
1385 sockopt_broadcast(sock);
1386 sockopt_reuseaddr(sock);
1387 sockopt_reuseport(sock);
1388 setsockopt_ipv4_multicast_loop(sock, 0);
78b31d5c 1389#ifdef IPTOS_PREC_INTERNETCONTROL
d62a17ae 1390 setsockopt_ipv4_tos(sock, IPTOS_PREC_INTERNETCONTROL);
78b31d5c 1391#endif
338b8e91 1392 setsockopt_so_recvbuf(sock, RIP_UDP_RCV_BUF);
a4e987e0 1393
0cf6db21 1394 frr_with_privs(&ripd_privs) {
633fc9b1
DL
1395 if ((ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr)))
1396 < 0) {
53bb7f9b
MS
1397 zlog_err("%s: Can't bind socket %d to %pI4 port %d: %s",
1398 __func__, sock, &addr.sin_addr,
633fc9b1
DL
1399 (int)ntohs(addr.sin_port),
1400 safe_strerror(errno));
d62a17ae 1401
01b9e3fd
DL
1402 close(sock);
1403 return ret;
1404 }
01b9e3fd 1405 }
d62a17ae 1406
1407 return sock;
a4e987e0 1408}
1409
c49ad8f1 1410/* RIP packet send to destination address, on interface denoted by
1411 * by connected argument. NULL to argument denotes destination should be
1412 * should be RIP multicast group
1413 */
d7c0a89a 1414static int rip_send_packet(uint8_t *buf, int size, struct sockaddr_in *to,
d62a17ae 1415 struct connected *ifc)
1416{
045c5389
RW
1417 struct rip_interface *ri;
1418 struct rip *rip;
d62a17ae 1419 int ret;
1420 struct sockaddr_in sin;
e35356af
RW
1421 struct msghdr msg;
1422 struct iovec iov;
1423#ifdef GNU_LINUX
1424 struct cmsghdr *cmsgptr;
1425 char adata[256] = {};
1426 struct in_pktinfo *pkt;
1427#endif /* GNU_LINUX */
d62a17ae 1428
1429 assert(ifc != NULL);
045c5389
RW
1430 ri = ifc->ifp->info;
1431 rip = ri->rip;
d62a17ae 1432
1433 if (IS_RIP_DEBUG_PACKET) {
f69bd9da 1434#define ADDRESS_SIZE 20
d62a17ae 1435 char dst[ADDRESS_SIZE];
d62a17ae 1436
1437 if (to) {
53bb7f9b 1438 inet_ntop(AF_INET, &to->sin_addr, dst, sizeof(dst));
d62a17ae 1439 } else {
1440 sin.sin_addr.s_addr = htonl(INADDR_RIP_GROUP);
53bb7f9b 1441 inet_ntop(AF_INET, &sin.sin_addr, dst, sizeof(dst));
d62a17ae 1442 }
f69bd9da 1443#undef ADDRESS_SIZE
99404729 1444 zlog_debug("%s %pI4 > %s (%s)", __func__,
1445 &ifc->address->u.prefix4, dst, ifc->ifp->name);
d62a17ae 1446 }
1447
1448 if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)) {
1449 /*
1450 * ZEBRA_IFA_SECONDARY is set on linux when an interface is
91b508dc
DS
1451 * configured with multiple addresses on the same
1452 * subnet: the first address on the subnet is configured
1453 * "primary", and all subsequent addresses on that subnet
1454 * are treated as "secondary" addresses. In order to avoid
1455 * routing-table bloat on other rip listeners, we do not send
1456 * out RIP packets with ZEBRA_IFA_SECONDARY source addrs.
d62a17ae 1457 * XXX Since Linux is the only system for which the
91b508dc
DS
1458 * ZEBRA_IFA_SECONDARY flag is set, we would end up
1459 * sending a packet for a "secondary" source address on
1460 * non-linux systems.
d62a17ae 1461 */
1462 if (IS_RIP_DEBUG_PACKET)
1463 zlog_debug("duplicate dropped");
1464 return 0;
1465 }
1466
1467 /* Make destination address. */
6006b807 1468 memset(&sin, 0, sizeof(sin));
d62a17ae 1469 sin.sin_family = AF_INET;
6f0e3f6e 1470#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
d62a17ae 1471 sin.sin_len = sizeof(struct sockaddr_in);
6f0e3f6e 1472#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
718e3744 1473
d62a17ae 1474 /* When destination is specified, use it's port and address. */
1475 if (to) {
1476 sin.sin_port = to->sin_port;
1477 sin.sin_addr = to->sin_addr;
1478 } else {
1479 sin.sin_port = htons(RIP_PORT_DEFAULT);
1480 sin.sin_addr.s_addr = htonl(INADDR_RIP_GROUP);
ae735d2d 1481
d62a17ae 1482 rip_interface_multicast_set(rip->sock, ifc);
1483 }
718e3744 1484
e35356af
RW
1485 memset(&msg, 0, sizeof(msg));
1486 msg.msg_name = (void *)&sin;
1487 msg.msg_namelen = sizeof(struct sockaddr_in);
1488 msg.msg_iov = &iov;
1489 msg.msg_iovlen = 1;
1490 iov.iov_base = buf;
1491 iov.iov_len = size;
1492
1493#ifdef GNU_LINUX
1494 msg.msg_control = (void *)adata;
1495 msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
1496
1497 cmsgptr = (struct cmsghdr *)adata;
1498 cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
1499 cmsgptr->cmsg_level = IPPROTO_IP;
1500 cmsgptr->cmsg_type = IP_PKTINFO;
1501 pkt = (struct in_pktinfo *)CMSG_DATA(cmsgptr);
1502 pkt->ipi_ifindex = ifc->ifp->ifindex;
114918bd 1503 pkt->ipi_spec_dst.s_addr = ifc->address->u.prefix4.s_addr;
e35356af
RW
1504#endif /* GNU_LINUX */
1505
1506 ret = sendmsg(rip->sock, &msg, 0);
718e3744 1507
d62a17ae 1508 if (IS_RIP_DEBUG_EVENT)
fa930785 1509 zlog_debug("SEND to %pI4 port %d", &sin.sin_addr,
d62a17ae 1510 ntohs(sin.sin_port));
718e3744 1511
d62a17ae 1512 if (ret < 0)
1513 zlog_warn("can't send packet : %s", safe_strerror(errno));
718e3744 1514
d62a17ae 1515 return ret;
718e3744 1516}
1517
1518/* Add redistributed route to RIP table. */
045c5389
RW
1519void rip_redistribute_add(struct rip *rip, int type, int sub_type,
1520 struct prefix_ipv4 *p, struct nexthop *nh,
1521 unsigned int metric, unsigned char distance,
1522 route_tag_t tag)
d62a17ae 1523{
1524 int ret;
1525 struct route_node *rp = NULL;
1526 struct rip_info *rinfo = NULL, newinfo;
1527 struct list *list = NULL;
1528
1529 /* Redistribute route */
1530 ret = rip_destination_check(p->prefix);
1531 if (!ret)
1532 return;
1533
1534 rp = route_node_get(rip->table, (struct prefix *)p);
1535
6006b807 1536 memset(&newinfo, 0, sizeof(newinfo));
d62a17ae 1537 newinfo.type = type;
1538 newinfo.sub_type = sub_type;
d62a17ae 1539 newinfo.metric = 1;
1540 newinfo.external_metric = metric;
1541 newinfo.distance = distance;
1542 if (tag <= UINT16_MAX) /* RIP only supports 16 bit tags */
1543 newinfo.tag = tag;
1544 newinfo.rp = rp;
3f5682c8 1545 newinfo.nh = *nh;
d62a17ae 1546
1547 if ((list = rp->info) != NULL && listcount(list) != 0) {
1548 rinfo = listgetdata(listhead(list));
1549
1550 if (rinfo->type == ZEBRA_ROUTE_CONNECT
1551 && rinfo->sub_type == RIP_ROUTE_INTERFACE
1552 && rinfo->metric != RIP_METRIC_INFINITY) {
1553 route_unlock_node(rp);
1554 return;
1555 }
718e3744 1556
d62a17ae 1557 /* Manually configured RIP route check. */
1558 if (rinfo->type == ZEBRA_ROUTE_RIP
1559 && ((rinfo->sub_type == RIP_ROUTE_STATIC)
1560 || (rinfo->sub_type == RIP_ROUTE_DEFAULT))) {
1561 if (type != ZEBRA_ROUTE_RIP
1562 || ((sub_type != RIP_ROUTE_STATIC)
1563 && (sub_type != RIP_ROUTE_DEFAULT))) {
1564 route_unlock_node(rp);
1565 return;
1566 }
1567 }
1568
045c5389 1569 (void)rip_ecmp_replace(rip, &newinfo);
d62a17ae 1570 route_unlock_node(rp);
1571 } else
045c5389 1572 (void)rip_ecmp_add(rip, &newinfo);
d62a17ae 1573
1574 if (IS_RIP_DEBUG_EVENT) {
f42238f8 1575 zlog_debug("Redistribute new prefix %pFX", p);
718e3744 1576 }
1577
045c5389 1578 rip_event(rip, RIP_TRIGGERED_UPDATE, 0);
718e3744 1579}
1580
1581/* Delete redistributed route from RIP table. */
045c5389
RW
1582void rip_redistribute_delete(struct rip *rip, int type, int sub_type,
1583 struct prefix_ipv4 *p, ifindex_t ifindex)
d62a17ae 1584{
1585 int ret;
1586 struct route_node *rp;
1587 struct rip_info *rinfo;
1588
1589 ret = rip_destination_check(p->prefix);
1590 if (!ret)
1591 return;
1592
1593 rp = route_node_lookup(rip->table, (struct prefix *)p);
1594 if (rp) {
1595 struct list *list = rp->info;
1596
1597 if (list != NULL && listcount(list) != 0) {
1598 rinfo = listgetdata(listhead(list));
1599 if (rinfo != NULL && rinfo->type == type
1600 && rinfo->sub_type == sub_type
dd127197 1601 && rinfo->nh.ifindex == ifindex) {
d62a17ae 1602 /* Perform poisoned reverse. */
1603 rinfo->metric = RIP_METRIC_INFINITY;
1604 RIP_TIMER_ON(rinfo->t_garbage_collect,
1605 rip_garbage_collect,
1606 rip->garbage_time);
e16d030c 1607 EVENT_OFF(rinfo->t_timeout);
d62a17ae 1608 rinfo->flags |= RIP_RTF_CHANGED;
1609
1610 if (IS_RIP_DEBUG_EVENT)
1611 zlog_debug(
f42238f8
DS
1612 "Poison %pFX on the interface %s with an infinity metric [delete]",
1613 p,
ae7b826a
RW
1614 ifindex2ifname(
1615 ifindex,
1616 rip->vrf->vrf_id));
d62a17ae 1617
045c5389 1618 rip_event(rip, RIP_TRIGGERED_UPDATE, 0);
d62a17ae 1619 }
1620 }
1621 route_unlock_node(rp);
1622 }
718e3744 1623}
1624
1625/* Response to request called from rip_read ().*/
d62a17ae 1626static void rip_request_process(struct rip_packet *packet, int size,
1627 struct sockaddr_in *from, struct connected *ifc)
1628{
045c5389 1629 struct rip *rip;
d62a17ae 1630 caddr_t lim;
1631 struct rte *rte;
1632 struct prefix_ipv4 p;
1633 struct route_node *rp;
1634 struct rip_info *rinfo;
1635 struct rip_interface *ri;
1636
1637 /* Does not reponse to the requests on the loopback interfaces */
1638 if (if_is_loopback(ifc->ifp))
1639 return;
1640
1641 /* Check RIP process is enabled on this interface. */
1642 ri = ifc->ifp->info;
1643 if (!ri->running)
1644 return;
045c5389 1645 rip = ri->rip;
d62a17ae 1646
1647 /* When passive interface is specified, suppress responses */
1648 if (ri->passive)
1649 return;
1650
1651 /* RIP peer update. */
c262df82 1652 rip_peer_update(rip, ri, from, packet->version);
d62a17ae 1653
1654 lim = ((caddr_t)packet) + size;
1655 rte = packet->rte;
1656
1657 /* The Request is processed entry by entry. If there are no
1658 entries, no response is given. */
1659 if (lim == (caddr_t)rte)
1660 return;
1661
1662 /* There is one special case. If there is exactly one entry in the
1663 request, and it has an address family identifier of zero and a
1664 metric of infinity (i.e., 16), then this is a request to send the
1665 entire routing table. */
1666 if (lim == ((caddr_t)(rte + 1)) && ntohs(rte->family) == 0
1667 && ntohl(rte->metric) == RIP_METRIC_INFINITY) {
1668 /* All route with split horizon */
1669 rip_output_process(ifc, from, rip_all_route, packet->version);
1670 } else {
1671 if (ntohs(rte->family) != AF_INET)
1672 return;
1673
1674 /* Examine the list of RTEs in the Request one by one. For each
1675 entry, look up the destination in the router's routing
1676 database and, if there is a route, put that route's metric in
1677 the metric field of the RTE. If there is no explicit route
1678 to the specified destination, put infinity in the metric
1679 field. Once all the entries have been filled in, change the
1680 command from Request to Response and send the datagram back
1681 to the requestor. */
1682 p.family = AF_INET;
1683
1684 for (; ((caddr_t)rte) < lim; rte++) {
1685 p.prefix = rte->prefix;
1686 p.prefixlen = ip_masklen(rte->mask);
1687 apply_mask_ipv4(&p);
1688
1689 rp = route_node_lookup(rip->table, (struct prefix *)&p);
1690 if (rp) {
1691 rinfo = listgetdata(
1692 listhead((struct list *)rp->info));
1693 rte->metric = htonl(rinfo->metric);
1694 route_unlock_node(rp);
1695 } else
1696 rte->metric = htonl(RIP_METRIC_INFINITY);
1697 }
1698 packet->command = RIP_RESPONSE;
4e054866 1699
b2608623 1700 (void)rip_send_packet((uint8_t *)packet, size, from, ifc);
d62a17ae 1701 }
c08a2107 1702 rip->counters.queries++;
718e3744 1703}
1704
718e3744 1705/* First entry point of RIP packet. */
e6685141 1706static void rip_read(struct event *t)
d62a17ae 1707{
e16d030c 1708 struct rip *rip = EVENT_ARG(t);
d62a17ae 1709 int sock;
1710 int ret;
1711 int rtenum;
1712 union rip_buf rip_buf;
1713 struct rip_packet *packet;
1714 struct sockaddr_in from;
1715 int len;
1716 int vrecv;
1717 socklen_t fromlen;
1718 struct interface *ifp = NULL;
1719 struct connected *ifc;
c262df82 1720 struct rip_interface *ri = NULL;
d62a17ae 1721 struct prefix p;
1722
1723 /* Fetch socket then register myself. */
e16d030c 1724 sock = EVENT_FD(t);
d62a17ae 1725
1726 /* Add myself to tne next event */
045c5389 1727 rip_event(rip, RIP_READ, sock);
d62a17ae 1728
1729 /* RIPd manages only IPv4. */
6006b807 1730 memset(&from, 0, sizeof(from));
d62a17ae 1731 fromlen = sizeof(struct sockaddr_in);
1732
1733 len = recvfrom(sock, (char *)&rip_buf.buf, sizeof(rip_buf.buf), 0,
1734 (struct sockaddr *)&from, &fromlen);
1735 if (len < 0) {
ae7b826a
RW
1736 zlog_info("recvfrom failed (VRF %s): %s", rip->vrf_name,
1737 safe_strerror(errno));
cc9f21da 1738 return;
d62a17ae 1739 }
1740
1741 /* Check is this packet comming from myself? */
045c5389 1742 if (if_check_address(rip, from.sin_addr)) {
d62a17ae 1743 if (IS_RIP_DEBUG_PACKET)
ae7b826a
RW
1744 zlog_debug("ignore packet comes from myself (VRF %s)",
1745 rip->vrf_name);
cc9f21da 1746 return;
d62a17ae 1747 }
1748
1749 /* Which interface is this packet comes from. */
ae7b826a
RW
1750 ifc = if_lookup_address((void *)&from.sin_addr, AF_INET,
1751 rip->vrf->vrf_id);
c262df82 1752 if (ifc) {
d62a17ae 1753 ifp = ifc->ifp;
c262df82
RW
1754 ri = ifp->info;
1755 }
d62a17ae 1756
1757 /* RIP packet received */
1758 if (IS_RIP_DEBUG_EVENT)
53bb7f9b
MS
1759 zlog_debug("RECV packet from %pI4 port %d on %s (VRF %s)",
1760 &from.sin_addr, ntohs(from.sin_port),
ae7b826a 1761 ifp ? ifp->name : "unknown", rip->vrf_name);
d62a17ae 1762
1763 /* If this packet come from unknown interface, ignore it. */
c262df82 1764 if (ifp == NULL || ri == NULL) {
d62a17ae 1765 zlog_info(
99404729 1766 "%s: cannot find interface for packet from %pI4 port %d (VRF %s)",
1767 __func__, &from.sin_addr, ntohs(from.sin_port),
ae7b826a 1768 rip->vrf_name);
cc9f21da 1769 return;
d62a17ae 1770 }
1771
1772 p.family = AF_INET;
1773 p.u.prefix4 = from.sin_addr;
1774 p.prefixlen = IPV4_MAX_BITLEN;
1775
1776 ifc = connected_lookup_prefix(ifp, &p);
1777
1778 if (ifc == NULL) {
1779 zlog_info(
99404729 1780 "%s: cannot find connected address for packet from %pI4 port %d on interface %s (VRF %s)",
1781 __func__, &from.sin_addr, ntohs(from.sin_port),
ae7b826a 1782 ifp->name, rip->vrf_name);
cc9f21da 1783 return;
d62a17ae 1784 }
1785
1786 /* Packet length check. */
1787 if (len < RIP_PACKET_MINSIZ) {
1788 zlog_warn("packet size %d is smaller than minimum size %d", len,
1789 RIP_PACKET_MINSIZ);
c262df82 1790 rip_peer_bad_packet(rip, ri, &from);
cc9f21da 1791 return;
d62a17ae 1792 }
1793 if (len > RIP_PACKET_MAXSIZ) {
1794 zlog_warn("packet size %d is larger than max size %d", len,
1795 RIP_PACKET_MAXSIZ);
c262df82 1796 rip_peer_bad_packet(rip, ri, &from);
cc9f21da 1797 return;
d62a17ae 1798 }
1799
1800 /* Packet alignment check. */
1801 if ((len - RIP_PACKET_MINSIZ) % 20) {
1802 zlog_warn("packet size %d is wrong for RIP packet alignment",
1803 len);
c262df82 1804 rip_peer_bad_packet(rip, ri, &from);
cc9f21da 1805 return;
d62a17ae 1806 }
1807
1808 /* Set RTE number. */
1809 rtenum = ((len - RIP_PACKET_MINSIZ) / 20);
1810
1811 /* For easy to handle. */
1812 packet = &rip_buf.rip_packet;
1813
1814 /* RIP version check. */
1815 if (packet->version == 0) {
1816 zlog_info("version 0 with command %d received.",
1817 packet->command);
c262df82 1818 rip_peer_bad_packet(rip, ri, &from);
cc9f21da 1819 return;
d62a17ae 1820 }
1821
1822 /* Dump RIP packet. */
1823 if (IS_RIP_DEBUG_RECV)
1824 rip_packet_dump(packet, len, "RECV");
1825
1826 /* RIP version adjust. This code should rethink now. RFC1058 says
1827 that "Version 1 implementations are to ignore this extra data and
1828 process only the fields specified in this document.". So RIPv3
1829 packet should be treated as RIPv1 ignoring must be zero field. */
1830 if (packet->version > RIPv2)
1831 packet->version = RIPv2;
1832
1833 /* Is RIP running or is this RIP neighbor ?*/
045c5389 1834 if (!ri->running && !rip_neighbor_lookup(rip, &from)) {
d62a17ae 1835 if (IS_RIP_DEBUG_EVENT)
1836 zlog_debug("RIP is not enabled on interface %s.",
1837 ifp->name);
c262df82 1838 rip_peer_bad_packet(rip, ri, &from);
cc9f21da 1839 return;
d62a17ae 1840 }
1841
1842 /* RIP Version check. RFC2453, 4.6 and 5.1 */
1843 vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ? rip->version_recv
1844 : ri->ri_receive);
1845 if (vrecv == RI_RIP_VERSION_NONE
1846 || ((packet->version == RIPv1) && !(vrecv & RIPv1))
1847 || ((packet->version == RIPv2) && !(vrecv & RIPv2))) {
1848 if (IS_RIP_DEBUG_PACKET)
1849 zlog_debug(
1850 " packet's v%d doesn't fit to if version spec",
1851 packet->version);
c262df82 1852 rip_peer_bad_packet(rip, ri, &from);
cc9f21da 1853 return;
d62a17ae 1854 }
1855
1856 /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
1857 messages, then RIP-1 and unauthenticated RIP-2 messages will be
1858 accepted; authenticated RIP-2 messages shall be discarded. */
1859 if ((ri->auth_type == RIP_NO_AUTH) && rtenum
1860 && (packet->version == RIPv2)
1861 && (packet->rte->family == htons(RIP_FAMILY_AUTH))) {
1862 if (IS_RIP_DEBUG_EVENT)
1863 zlog_debug(
1864 "packet RIPv%d is dropped because authentication disabled",
1865 packet->version);
fe339c95 1866 ripd_notif_send_auth_type_failure(ifp->name);
c262df82 1867 rip_peer_bad_packet(rip, ri, &from);
cc9f21da 1868 return;
d62a17ae 1869 }
1870
1871 /* RFC:
1872 If the router is configured to authenticate RIP-2 messages, then
1873 RIP-1 messages and RIP-2 messages which pass authentication
1874 testing shall be accepted; unauthenticated and failed
1875 authentication RIP-2 messages shall be discarded. For maximum
1876 security, RIP-1 messages should be ignored when authentication is
1877 in use (see section 4.1); otherwise, the routing information from
1878 authenticated messages will be propagated by RIP-1 routers in an
1879 unauthenticated manner.
1880 */
1881 /* We make an exception for RIPv1 REQUEST packets, to which we'll
1882 * always reply regardless of authentication settings, because:
1883 *
1884 * - if there other authorised routers on-link, the REQUESTor can
1885 * passively obtain the routing updates anyway
1886 * - if there are no other authorised routers on-link, RIP can
1887 * easily be disabled for the link to prevent giving out information
1888 * on state of this routers RIP routing table..
1889 *
1890 * I.e. if RIPv1 has any place anymore these days, it's as a very
1891 * simple way to distribute routing information (e.g. to embedded
1892 * hosts / appliances) and the ability to give out RIPv1
1893 * routing-information freely, while still requiring RIPv2
1894 * authentication for any RESPONSEs might be vaguely useful.
1895 */
1896 if (ri->auth_type != RIP_NO_AUTH && packet->version == RIPv1) {
1897 /* Discard RIPv1 messages other than REQUESTs */
1898 if (packet->command != RIP_REQUEST) {
1899 if (IS_RIP_DEBUG_PACKET)
1900 zlog_debug(
3efd0893 1901 "RIPv1 dropped because authentication enabled");
fe339c95 1902 ripd_notif_send_auth_type_failure(ifp->name);
c262df82 1903 rip_peer_bad_packet(rip, ri, &from);
cc9f21da 1904 return;
d62a17ae 1905 }
1906 } else if (ri->auth_type != RIP_NO_AUTH) {
1907 const char *auth_desc;
1908
1909 if (rtenum == 0) {
1910 /* There definitely is no authentication in the packet.
1911 */
1912 if (IS_RIP_DEBUG_PACKET)
1913 zlog_debug(
1914 "RIPv2 authentication failed: no auth RTE in packet");
fe339c95 1915 ripd_notif_send_auth_type_failure(ifp->name);
c262df82 1916 rip_peer_bad_packet(rip, ri, &from);
cc9f21da 1917 return;
d62a17ae 1918 }
1919
1920 /* First RTE must be an Authentication Family RTE */
1921 if (packet->rte->family != htons(RIP_FAMILY_AUTH)) {
1922 if (IS_RIP_DEBUG_PACKET)
1923 zlog_debug(
3efd0893 1924 "RIPv2 dropped because authentication enabled");
fe339c95 1925 ripd_notif_send_auth_type_failure(ifp->name);
c262df82 1926 rip_peer_bad_packet(rip, ri, &from);
cc9f21da 1927 return;
d62a17ae 1928 }
1929
1930 /* Check RIPv2 authentication. */
1931 switch (ntohs(packet->rte->tag)) {
1932 case RIP_AUTH_SIMPLE_PASSWORD:
1933 auth_desc = "simple";
1934 ret = rip_auth_simple_password(packet->rte, &from, ifp);
1935 break;
1936
1937 case RIP_AUTH_MD5:
1938 auth_desc = "MD5";
1939 ret = rip_auth_md5(packet, &from, len, ifp);
1940 /* Reset RIP packet length to trim MD5 data. */
1941 len = ret;
1942 break;
1943
1944 default:
1945 ret = 0;
1946 auth_desc = "unknown type";
1947 if (IS_RIP_DEBUG_PACKET)
1948 zlog_debug(
1949 "RIPv2 Unknown authentication type %d",
1950 ntohs(packet->rte->tag));
1951 }
1952
1953 if (ret) {
1954 if (IS_RIP_DEBUG_PACKET)
1955 zlog_debug("RIPv2 %s authentication success",
1956 auth_desc);
1957 } else {
1958 if (IS_RIP_DEBUG_PACKET)
1959 zlog_debug("RIPv2 %s authentication failure",
1960 auth_desc);
fe339c95 1961 ripd_notif_send_auth_failure(ifp->name);
c262df82 1962 rip_peer_bad_packet(rip, ri, &from);
cc9f21da 1963 return;
d62a17ae 1964 }
1965 }
1966
1967 /* Process each command. */
1968 switch (packet->command) {
1969 case RIP_RESPONSE:
1970 rip_response_process(packet, len, &from, ifc);
1971 break;
1972 case RIP_REQUEST:
1973 case RIP_POLL:
1974 rip_request_process(packet, len, &from, ifc);
1975 break;
1976 case RIP_TRACEON:
1977 case RIP_TRACEOFF:
1978 zlog_info(
1979 "Obsolete command %s received, please sent it to routed",
1980 lookup_msg(rip_msg, packet->command, NULL));
c262df82 1981 rip_peer_bad_packet(rip, ri, &from);
d62a17ae 1982 break;
1983 case RIP_POLL_ENTRY:
1984 zlog_info("Obsolete command %s received",
1985 lookup_msg(rip_msg, packet->command, NULL));
c262df82 1986 rip_peer_bad_packet(rip, ri, &from);
d62a17ae 1987 break;
1988 default:
1989 zlog_info("Unknown RIP command %d received", packet->command);
c262df82 1990 rip_peer_bad_packet(rip, ri, &from);
d62a17ae 1991 break;
1992 }
718e3744 1993}
1994
718e3744 1995/* Write routing table entry to the stream and return next index of
1996 the routing table entry in the stream. */
d62a17ae 1997static int rip_write_rte(int num, struct stream *s, struct prefix_ipv4 *p,
d7c0a89a 1998 uint8_t version, struct rip_info *rinfo)
d62a17ae 1999{
2000 struct in_addr mask;
2001
2002 /* Write routing table entry. */
2003 if (version == RIPv1) {
2004 stream_putw(s, AF_INET);
2005 stream_putw(s, 0);
2006 stream_put_ipv4(s, p->prefix.s_addr);
2007 stream_put_ipv4(s, 0);
2008 stream_put_ipv4(s, 0);
2009 stream_putl(s, rinfo->metric_out);
2010 } else {
2011 masklen2ip(p->prefixlen, &mask);
2012
2013 stream_putw(s, AF_INET);
2014 stream_putw(s, rinfo->tag_out);
2015 stream_put_ipv4(s, p->prefix.s_addr);
2016 stream_put_ipv4(s, mask.s_addr);
2017 stream_put_ipv4(s, rinfo->nexthop_out.s_addr);
2018 stream_putl(s, rinfo->metric_out);
2019 }
2020
2021 return ++num;
718e3744 2022}
2023
2024/* Send update to the ifp or spcified neighbor. */
d62a17ae 2025void rip_output_process(struct connected *ifc, struct sockaddr_in *to,
d7c0a89a 2026 int route_type, uint8_t version)
d62a17ae 2027{
045c5389 2028 struct rip *rip;
d62a17ae 2029 int ret;
2030 struct stream *s;
2031 struct route_node *rp;
2032 struct rip_info *rinfo;
2033 struct rip_interface *ri;
2034 struct prefix_ipv4 *p;
2035 struct prefix_ipv4 classfull;
2036 struct prefix_ipv4 ifaddrclass;
2037 struct key *key = NULL;
2038 /* this might need to made dynamic if RIP ever supported auth methods
2039 with larger key string sizes */
2040 char auth_str[RIP_AUTH_SIMPLE_SIZE];
2041 size_t doff = 0; /* offset of digest offset field */
2042 int num = 0;
2043 int rtemax;
2044 int subnetted = 0;
2045 struct list *list = NULL;
2046 struct listnode *listnode = NULL;
2047
2048 /* Logging output event. */
2049 if (IS_RIP_DEBUG_EVENT) {
2050 if (to)
53bb7f9b
MS
2051 zlog_debug("update routes to neighbor %pI4",
2052 &to->sin_addr);
d62a17ae 2053 else
2054 zlog_debug("update routes on interface %s ifindex %d",
2055 ifc->ifp->name, ifc->ifp->ifindex);
2056 }
718e3744 2057
045c5389
RW
2058 /* Get RIP interface. */
2059 ri = ifc->ifp->info;
2060 rip = ri->rip;
2061
d62a17ae 2062 /* Set output stream. */
2063 s = rip->obuf;
2064
2065 /* Reset stream and RTE counter. */
2066 stream_reset(s);
2067 rtemax = RIP_MAX_RTE;
2068
d62a17ae 2069 /* If output interface is in simple password authentication mode, we
2070 need space for authentication data. */
2071 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2072 rtemax -= 1;
2073
2074 /* If output interface is in MD5 authentication mode, we need space
2075 for authentication header and data. */
2076 if (ri->auth_type == RIP_AUTH_MD5)
2077 rtemax -= 2;
2078
2079 /* If output interface is in simple password authentication mode
2080 and string or keychain is specified we need space for auth. data */
2081 if (ri->auth_type != RIP_NO_AUTH) {
2082 if (ri->key_chain) {
2083 struct keychain *keychain;
2084
2085 keychain = keychain_lookup(ri->key_chain);
2086 if (keychain)
2087 key = key_lookup_for_send(keychain);
2088 }
2089 /* to be passed to auth functions later */
5c84f238 2090 rip_auth_prepare_str_send(ri, key, auth_str, sizeof(auth_str));
558c6842 2091 if (strlen(auth_str) == 0)
2092 return;
d62a17ae 2093 }
2094
2095 if (version == RIPv1) {
f51eeb86 2096 memcpy(&ifaddrclass, ifc->address, sizeof(ifaddrclass));
d62a17ae 2097 apply_classful_mask_ipv4(&ifaddrclass);
2098 subnetted = 0;
2099 if (ifc->address->prefixlen > ifaddrclass.prefixlen)
2100 subnetted = 1;
2101 }
2102
91b508dc
DS
2103 for (rp = route_top(rip->table); rp; rp = route_next(rp)) {
2104 list = rp->info;
d62a17ae 2105
91b508dc
DS
2106 if (list == NULL)
2107 continue;
d62a17ae 2108
91b508dc
DS
2109 if (listcount(list) == 0)
2110 continue;
d62a17ae 2111
91b508dc
DS
2112 rinfo = listgetdata(listhead(list));
2113 /*
2114 * For RIPv1, if we are subnetted, output subnets in our
2115 * network that have the same mask as the output "interface".
2116 * For other networks, only the classfull version is output.
2117 */
2118 if (version == RIPv1) {
2119 p = (struct prefix_ipv4 *)&rp->p;
d62a17ae 2120
91b508dc
DS
2121 if (IS_RIP_DEBUG_PACKET)
2122 zlog_debug(
2123 "RIPv1 mask check, %pFX considered for output",
2124 &rp->p);
2125
2126 if (subnetted &&
2127 prefix_match((struct prefix *)&ifaddrclass,
2128 &rp->p)) {
2129 if ((ifc->address->prefixlen !=
2130 rp->p.prefixlen) &&
2131 (rp->p.prefixlen != IPV4_MAX_BITLEN))
2132 continue;
2133 } else {
2134 memcpy(&classfull, &rp->p,
2135 sizeof(struct prefix_ipv4));
2136 apply_classful_mask_ipv4(&classfull);
2137 if (rp->p.u.prefix4.s_addr != INADDR_ANY &&
2138 classfull.prefixlen != rp->p.prefixlen)
2139 continue;
2140 }
2141 if (IS_RIP_DEBUG_PACKET)
2142 zlog_debug(
2143 "RIPv1 mask check, %pFX made it through",
2144 &rp->p);
2145 } else
2146 p = (struct prefix_ipv4 *)&rp->p;
d62a17ae 2147
91b508dc
DS
2148 /* Apply output filters. */
2149 ret = rip_filter(RIP_FILTER_OUT, p, ri);
2150 if (ret < 0)
2151 continue;
d62a17ae 2152
91b508dc
DS
2153 /* Changed route only output. */
2154 if (route_type == rip_changed_route &&
2155 (!(rinfo->flags & RIP_RTF_CHANGED)))
2156 continue;
2157
2158 /* Split horizon. */
2159 if (ri->split_horizon == RIP_SPLIT_HORIZON) {
2160 /*
2161 * We perform split horizon for RIP and connected
2162 * route. For rip routes, we want to suppress the
2163 * route if we would end up sending the route back on
2164 * the interface that we learned it from, with a
2165 * higher metric. For connected routes, we suppress
2166 * the route if the prefix is a subset of the source
2167 * address that we are going to use for the packet
2168 * (in order to handle the case when multiple subnets
2169 * are configured on the same interface).
2170 */
2171 int suppress = 0;
2172 struct rip_info *tmp_rinfo = NULL;
2173 struct connected *tmp_ifc = NULL;
2174
2175 for (ALL_LIST_ELEMENTS_RO(list, listnode, tmp_rinfo))
2176 if (tmp_rinfo->type == ZEBRA_ROUTE_RIP &&
2177 tmp_rinfo->nh.ifindex ==
2178 ifc->ifp->ifindex) {
2179 suppress = 1;
2180 break;
9920df07 2181 }
d62a17ae 2182
91b508dc
DS
2183 if (!suppress && rinfo->type == ZEBRA_ROUTE_CONNECT) {
2184 for (ALL_LIST_ELEMENTS_RO(ifc->ifp->connected,
2185 listnode, tmp_ifc))
2186 if (prefix_match((struct prefix *)p,
2187 tmp_ifc->address)) {
2188 suppress = 1;
2189 break;
2190 }
d62a17ae 2191 }
2192
91b508dc
DS
2193 if (suppress)
2194 continue;
2195 }
d62a17ae 2196
91b508dc
DS
2197 /* Preparation for route-map. */
2198 rinfo->metric_set = 0;
2199 rinfo->nexthop_out.s_addr = 0;
2200 rinfo->metric_out = rinfo->metric;
2201 rinfo->tag_out = rinfo->tag;
2202 rinfo->ifindex_out = ifc->ifp->ifindex;
2203
2204 /* In order to avoid some local loops, if the RIP route has
2205 * a nexthop via this interface, keep the nexthop, otherwise
2206 * set it to 0. The nexthop should not be propagated beyond
2207 * the local broadcast/multicast area in order to avoid an
2208 * IGP multi-level recursive look-up. see (4.4)
2209 */
2210 if (rinfo->nh.ifindex == ifc->ifp->ifindex)
2211 rinfo->nexthop_out = rinfo->nh.gate.ipv4;
d62a17ae 2212
91b508dc
DS
2213 /* Interface route-map */
2214 if (ri->routemap[RIP_FILTER_OUT]) {
2215 ret = route_map_apply(ri->routemap[RIP_FILTER_OUT],
2216 (struct prefix *)p, rinfo);
2217
2218 if (ret == RMAP_DENYMATCH) {
2219 if (IS_RIP_DEBUG_PACKET)
2220 zlog_debug(
2221 "RIP %pFX is filtered by route-map out",
2222 p);
2223 continue;
d62a17ae 2224 }
91b508dc 2225 }
d62a17ae 2226
91b508dc
DS
2227 /* Apply redistribute route map - continue, if deny */
2228 if (rip->redist[rinfo->type].route_map.name &&
2229 rinfo->sub_type != RIP_ROUTE_INTERFACE) {
2230 ret = route_map_apply(
2231 rip->redist[rinfo->type].route_map.map,
2232 (struct prefix *)p, rinfo);
d62a17ae 2233
91b508dc
DS
2234 if (ret == RMAP_DENYMATCH) {
2235 if (IS_RIP_DEBUG_PACKET)
2236 zlog_debug(
2237 "%pFX is filtered by route-map",
2238 p);
2239 continue;
d62a17ae 2240 }
91b508dc 2241 }
d62a17ae 2242
91b508dc
DS
2243 /* When route-map does not set metric. */
2244 if (!rinfo->metric_set) {
2245 /* If redistribute metric is set. */
2246 if (rip->redist[rinfo->type].metric_config &&
2247 rinfo->metric != RIP_METRIC_INFINITY) {
2248 rinfo->metric_out =
2249 rip->redist[rinfo->type].metric;
2250 } else {
2251 /* If the route is not connected or localy
2252 * generated one, use default-metric value
2253 */
2254 if (rinfo->type != ZEBRA_ROUTE_RIP &&
2255 rinfo->type != ZEBRA_ROUTE_CONNECT &&
2256 rinfo->metric != RIP_METRIC_INFINITY)
2257 rinfo->metric_out = rip->default_metric;
d62a17ae 2258 }
91b508dc 2259 }
d62a17ae 2260
91b508dc
DS
2261 /* Apply offset-list */
2262 if (rinfo->metric != RIP_METRIC_INFINITY)
2263 rip_offset_list_apply_out(p, ifc->ifp,
2264 &rinfo->metric_out);
2265
2266 if (rinfo->metric_out > RIP_METRIC_INFINITY)
2267 rinfo->metric_out = RIP_METRIC_INFINITY;
2268
2269 /* Perform split-horizon with poisoned reverse
2270 * for RIP and connected routes.
2271 **/
2272 if (ri->split_horizon == RIP_SPLIT_HORIZON_POISONED_REVERSE) {
2273 /*
2274 * We perform split horizon for RIP and connected
2275 * route. For rip routes, we want to suppress the
2276 * route if we would end up sending the route back
2277 * on the interface that we learned it from, with a
2278 * higher metric. For connected routes, we suppress
2279 * the route if the prefix is a subset of the source
2280 * address that we are going to use for the packet
2281 * (in order to handle the case when multiple
2282 * subnets are configured on the same interface).
2283 */
2284 struct rip_info *tmp_rinfo = NULL;
2285 struct connected *tmp_ifc = NULL;
2286
2287 for (ALL_LIST_ELEMENTS_RO(list, listnode, tmp_rinfo))
2288 if (tmp_rinfo->type == ZEBRA_ROUTE_RIP &&
2289 tmp_rinfo->nh.ifindex == ifc->ifp->ifindex)
2290 rinfo->metric_out = RIP_METRIC_INFINITY;
2291
2292 if (rinfo->metric_out != RIP_METRIC_INFINITY &&
2293 rinfo->type == ZEBRA_ROUTE_CONNECT) {
2294 for (ALL_LIST_ELEMENTS_RO(ifc->ifp->connected,
2295 listnode, tmp_ifc))
2296 if (prefix_match((struct prefix *)p,
2297 tmp_ifc->address)) {
9920df07 2298 rinfo->metric_out =
d62a17ae 2299 RIP_METRIC_INFINITY;
91b508dc
DS
2300 break;
2301 }
d62a17ae 2302 }
91b508dc 2303 }
d62a17ae 2304
91b508dc
DS
2305 /* Prepare preamble, auth headers, if needs be */
2306 if (num == 0) {
2307 stream_putc(s, RIP_RESPONSE);
2308 stream_putc(s, version);
2309 stream_putw(s, 0);
2310
2311 /* auth header for !v1 && !no_auth */
2312 if ((ri->auth_type != RIP_NO_AUTH) &&
2313 (version != RIPv1))
2314 doff = rip_auth_header_write(
2315 s, ri, key, auth_str,
2316 RIP_AUTH_SIMPLE_SIZE);
2317 }
d62a17ae 2318
91b508dc
DS
2319 /* Write RTE to the stream. */
2320 num = rip_write_rte(num, s, p, version, rinfo);
2321 if (num == rtemax) {
2322 if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
2323 rip_auth_md5_set(s, ri, doff, auth_str,
2324 RIP_AUTH_SIMPLE_SIZE);
2325
2326 ret = rip_send_packet(STREAM_DATA(s),
2327 stream_get_endp(s), to, ifc);
2328
2329 if (ret >= 0 && IS_RIP_DEBUG_SEND)
2330 rip_packet_dump(
2331 (struct rip_packet *)STREAM_DATA(s),
2332 stream_get_endp(s), "SEND");
2333 num = 0;
2334 stream_reset(s);
d62a17ae 2335 }
91b508dc 2336 }
d62a17ae 2337
2338 /* Flush unwritten RTE. */
2339 if (num != 0) {
2340 if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
2341 rip_auth_md5_set(s, ri, doff, auth_str,
2342 RIP_AUTH_SIMPLE_SIZE);
2343
2344 ret = rip_send_packet(STREAM_DATA(s), stream_get_endp(s), to,
2345 ifc);
2346
2347 if (ret >= 0 && IS_RIP_DEBUG_SEND)
2348 rip_packet_dump((struct rip_packet *)STREAM_DATA(s),
2349 stream_get_endp(s), "SEND");
2350 stream_reset(s);
2351 }
2352
2353 /* Statistics updates. */
2354 ri->sent_updates++;
718e3744 2355}
2356
2357/* Send RIP packet to the interface. */
d7c0a89a 2358static void rip_update_interface(struct connected *ifc, uint8_t version,
d62a17ae 2359 int route_type)
2360{
2361 struct interface *ifp = ifc->ifp;
2362 struct rip_interface *ri = ifp->info;
2363 struct sockaddr_in to;
2364
2365 /* When RIP version is 2 and multicast enable interface. */
2366 if (version == RIPv2 && !ri->v2_broadcast && if_is_multicast(ifp)) {
2367 if (IS_RIP_DEBUG_EVENT)
2368 zlog_debug("multicast announce on %s ", ifp->name);
2369
2370 rip_output_process(ifc, NULL, route_type, version);
2371 return;
2372 }
2373
2374 /* If we can't send multicast packet, send it with unicast. */
2375 if (if_is_broadcast(ifp) || if_is_pointopoint(ifp)) {
2376 if (ifc->address->family == AF_INET) {
2377 /* Destination address and port setting. */
6006b807 2378 memset(&to, 0, sizeof(to));
d62a17ae 2379 if (ifc->destination)
2380 /* use specified broadcast or peer destination
2381 * addr */
2382 to.sin_addr = ifc->destination->u.prefix4;
936fbaef 2383 else if (ifc->address->prefixlen < IPV4_MAX_BITLEN)
d62a17ae 2384 /* calculate the appropriate broadcast address
2385 */
2386 to.sin_addr.s_addr = ipv4_broadcast_addr(
2387 ifc->address->u.prefix4.s_addr,
2388 ifc->address->prefixlen);
2389 else
2390 /* do not know where to send the packet */
2391 return;
2392 to.sin_port = htons(RIP_PORT_DEFAULT);
2393
2394 if (IS_RIP_DEBUG_EVENT)
53bb7f9b 2395 zlog_debug("%s announce to %pI4 on %s",
d62a17ae 2396 CONNECTED_PEER(ifc) ? "unicast"
2397 : "broadcast",
53bb7f9b 2398 &to.sin_addr, ifp->name);
d62a17ae 2399
2400 rip_output_process(ifc, &to, route_type, version);
2401 }
2402 }
718e3744 2403}
2404
2405/* Update send to all interface and neighbor. */
045c5389 2406static void rip_update_process(struct rip *rip, int route_type)
d62a17ae 2407{
d62a17ae 2408 struct listnode *ifnode, *ifnnode;
2409 struct connected *connected;
2410 struct interface *ifp;
2411 struct rip_interface *ri;
2412 struct route_node *rp;
2413 struct sockaddr_in to;
2414 struct prefix *p;
2415
2416 /* Send RIP update to each interface. */
ae7b826a 2417 FOR_ALL_INTERFACES (rip->vrf, ifp) {
d62a17ae 2418 if (if_is_loopback(ifp))
2419 continue;
2420
2421 if (!if_is_operative(ifp))
2422 continue;
2423
2424 /* Fetch RIP interface information. */
2425 ri = ifp->info;
2426
2427 /* When passive interface is specified, suppress announce to the
2428 interface. */
2429 if (ri->passive)
2430 continue;
2431
91b508dc
DS
2432 if (!ri->running)
2433 continue;
d62a17ae 2434
91b508dc
DS
2435 /*
2436 * If there is no version configuration in the
2437 * interface, use rip's version setting.
2438 */
2439 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ? rip->version_send
2440 : ri->ri_send);
2441
2442 if (IS_RIP_DEBUG_EVENT)
2443 zlog_debug("SEND UPDATE to %s ifindex %d", ifp->name,
2444 ifp->ifindex);
2445
2446 /* send update on each connected network */
2447 for (ALL_LIST_ELEMENTS(ifp->connected, ifnode, ifnnode,
2448 connected)) {
2449 if (connected->address->family == AF_INET) {
2450 if (vsend & RIPv1)
2451 rip_update_interface(connected, RIPv1,
2452 route_type);
2453 if ((vsend & RIPv2) && if_is_multicast(ifp))
2454 rip_update_interface(connected, RIPv2,
2455 route_type);
d62a17ae 2456 }
2457 }
2458 }
2459
2460 /* RIP send updates to each neighbor. */
91b508dc
DS
2461 for (rp = route_top(rip->neighbor); rp; rp = route_next(rp)) {
2462 if (rp->info == NULL)
2463 continue;
d62a17ae 2464
91b508dc 2465 p = &rp->p;
d62a17ae 2466
91b508dc
DS
2467 connected = if_lookup_address(&p->u.prefix4, AF_INET,
2468 rip->vrf->vrf_id);
2469 if (!connected) {
2470 zlog_warn(
2471 "Neighbor %pI4 doesn't have connected interface!",
2472 &p->u.prefix4);
2473 continue;
b9d92881 2474 }
91b508dc
DS
2475
2476 /* Set destination address and port */
2477 memset(&to, 0, sizeof(struct sockaddr_in));
2478 to.sin_addr = p->u.prefix4;
2479 to.sin_port = htons(RIP_PORT_DEFAULT);
2480
2481 /* RIP version is rip's configuration. */
2482 rip_output_process(connected, &to, route_type,
2483 rip->version_send);
2484 }
718e3744 2485}
2486
2487/* RIP's periodical timer. */
e6685141 2488static void rip_update(struct event *t)
718e3744 2489{
e16d030c 2490 struct rip *rip = EVENT_ARG(t);
045c5389 2491
d62a17ae 2492 if (IS_RIP_DEBUG_EVENT)
2493 zlog_debug("update timer fire!");
718e3744 2494
d62a17ae 2495 /* Process update output. */
045c5389 2496 rip_update_process(rip, rip_all_route);
718e3744 2497
d62a17ae 2498 /* Triggered updates may be suppressed if a regular update is due by
2499 the time the triggered update would be sent. */
e16d030c 2500 EVENT_OFF(rip->t_triggered_interval);
d62a17ae 2501 rip->trigger = 0;
718e3744 2502
d62a17ae 2503 /* Register myself. */
045c5389 2504 rip_event(rip, RIP_UPDATE_EVENT, 0);
718e3744 2505}
2506
2507/* Walk down the RIP routing table then clear changed flag. */
045c5389 2508static void rip_clear_changed_flag(struct rip *rip)
718e3744 2509{
d62a17ae 2510 struct route_node *rp;
2511 struct rip_info *rinfo = NULL;
2512 struct list *list = NULL;
2513 struct listnode *listnode = NULL;
718e3744 2514
91b508dc
DS
2515 for (rp = route_top(rip->table); rp; rp = route_next(rp)) {
2516 list = rp->info;
2517
2518 if (list == NULL)
2519 continue;
2520
2521 for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
2522 UNSET_FLAG(rinfo->flags, RIP_RTF_CHANGED);
2523 /* This flag can be set only on the first entry. */
2524 break;
2525 }
2526 }
718e3744 2527}
2528
2529/* Triggered update interval timer. */
e6685141 2530static void rip_triggered_interval(struct event *t)
718e3744 2531{
e16d030c 2532 struct rip *rip = EVENT_ARG(t);
718e3744 2533
d62a17ae 2534 if (rip->trigger) {
2535 rip->trigger = 0;
2536 rip_triggered_update(t);
2537 }
d62a17ae 2538}
718e3744 2539
2540/* Execute triggered update. */
e6685141 2541static void rip_triggered_update(struct event *t)
718e3744 2542{
e16d030c 2543 struct rip *rip = EVENT_ARG(t);
d62a17ae 2544 int interval;
718e3744 2545
d62a17ae 2546 /* Cancel interval timer. */
e16d030c 2547 EVENT_OFF(rip->t_triggered_interval);
d62a17ae 2548 rip->trigger = 0;
718e3744 2549
d62a17ae 2550 /* Logging triggered update. */
2551 if (IS_RIP_DEBUG_EVENT)
2552 zlog_debug("triggered update!");
718e3744 2553
d62a17ae 2554 /* Split Horizon processing is done when generating triggered
2555 updates as well as normal updates (see section 2.6). */
045c5389 2556 rip_update_process(rip, rip_changed_route);
718e3744 2557
d62a17ae 2558 /* Once all of the triggered updates have been generated, the route
2559 change flags should be cleared. */
045c5389 2560 rip_clear_changed_flag(rip);
718e3744 2561
d62a17ae 2562 /* After a triggered update is sent, a timer should be set for a
2563 random interval between 1 and 5 seconds. If other changes that
2564 would trigger updates occur before the timer expires, a single
2565 update is triggered when the timer expires. */
5920b3eb 2566 interval = (frr_weak_random() % 5) + 1;
718e3744 2567
907a2395
DS
2568 event_add_timer(master, rip_triggered_interval, rip, interval,
2569 &rip->t_triggered_interval);
718e3744 2570}
2571
2572/* Withdraw redistributed route. */
045c5389 2573void rip_redistribute_withdraw(struct rip *rip, int type)
d62a17ae 2574{
2575 struct route_node *rp;
2576 struct rip_info *rinfo = NULL;
2577 struct list *list = NULL;
2578
91b508dc
DS
2579 for (rp = route_top(rip->table); rp; rp = route_next(rp)) {
2580 list = rp->info;
d62a17ae 2581
91b508dc
DS
2582 if (list == NULL)
2583 continue;
d62a17ae 2584
91b508dc 2585 rinfo = listgetdata(listhead(list));
d62a17ae 2586
91b508dc
DS
2587 if (rinfo->type != type)
2588 continue;
2589
2590 if (rinfo->sub_type == RIP_ROUTE_INTERFACE)
2591 continue;
2592
2593 /* Perform poisoned reverse. */
2594 rinfo->metric = RIP_METRIC_INFINITY;
2595 RIP_TIMER_ON(rinfo->t_garbage_collect, rip_garbage_collect,
2596 rip->garbage_time);
e16d030c 2597 EVENT_OFF(rinfo->t_timeout);
91b508dc
DS
2598 rinfo->flags |= RIP_RTF_CHANGED;
2599
2600 if (IS_RIP_DEBUG_EVENT) {
2601 struct prefix_ipv4 *p = (struct prefix_ipv4 *)&rp->p;
2602
2603 zlog_debug(
2604 "Poisone %pFX on the interface %s with an infinity metric [withdraw]",
2605 p,
2606 ifindex2ifname(rinfo->nh.ifindex,
2607 rip->vrf->vrf_id));
d62a17ae 2608 }
91b508dc
DS
2609
2610 rip_event(rip, RIP_TRIGGERED_UPDATE, 0);
2611 }
d62a17ae 2612}
2613
045c5389
RW
2614struct rip *rip_lookup_by_vrf_id(vrf_id_t vrf_id)
2615{
2616 struct vrf *vrf;
2617
2618 vrf = vrf_lookup_by_id(vrf_id);
2619 if (!vrf)
2620 return NULL;
2621
2622 return vrf->info;
2623}
2624
ae7b826a
RW
2625struct rip *rip_lookup_by_vrf_name(const char *vrf_name)
2626{
2627 struct rip rip;
2628
2629 rip.vrf_name = (char *)vrf_name;
2630
2631 return RB_FIND(rip_instance_head, &rip_instances, &rip);
2632}
2633
d62a17ae 2634/* Create new RIP instance and set it to global variable. */
ae7b826a 2635struct rip *rip_create(const char *vrf_name, struct vrf *vrf, int socket)
718e3744 2636{
045c5389 2637 struct rip *rip;
045c5389 2638
d62a17ae 2639 rip = XCALLOC(MTYPE_RIP, sizeof(struct rip));
ae7b826a 2640 rip->vrf_name = XSTRDUP(MTYPE_RIP_VRF_NAME, vrf_name);
718e3744 2641
d62a17ae 2642 /* Set initial value. */
8c9226c2
RW
2643 rip->ecmp = yang_get_default_bool("%s/allow-ecmp", RIP_INSTANCE);
2644 rip->default_metric =
2645 yang_get_default_uint8("%s/default-metric", RIP_INSTANCE);
2646 rip->distance =
2647 yang_get_default_uint8("%s/distance/default", RIP_INSTANCE);
44f2f852
RW
2648 rip->passive_default =
2649 yang_get_default_bool("%s/passive-default", RIP_INSTANCE);
8c9226c2
RW
2650 rip->garbage_time = yang_get_default_uint32("%s/timers/flush-interval",
2651 RIP_INSTANCE);
2652 rip->timeout_time = yang_get_default_uint32(
2653 "%s/timers/holddown-interval", RIP_INSTANCE);
2654 rip->update_time = yang_get_default_uint32("%s/timers/update-interval",
2655 RIP_INSTANCE);
2656 rip->version_send =
2657 yang_get_default_enum("%s/version/send", RIP_INSTANCE);
2658 rip->version_recv =
2659 yang_get_default_enum("%s/version/receive", RIP_INSTANCE);
718e3744 2660
ca046902 2661 /* Initialize RIP data structures. */
d62a17ae 2662 rip->table = route_table_init();
045c5389 2663 route_table_set_info(rip->table, rip);
d62a17ae 2664 rip->neighbor = route_table_init();
29e897ad
RW
2665 rip->peer_list = list_new();
2666 rip->peer_list->cmp = (int (*)(void *, void *))rip_peer_list_cmp;
711915d2 2667 rip->peer_list->del = rip_peer_list_del;
2826309c
RW
2668 rip->distance_table = route_table_init();
2669 rip->distance_table->cleanup = rip_distance_table_node_cleanup;
ca046902 2670 rip->enable_interface = vector_init(1);
1205fdc4 2671 rip->enable_network = route_table_init();
5a29c0d5 2672 rip->passive_nondefault = vector_init(1);
3f21c8c4
RW
2673 rip->offset_list_master = list_new();
2674 rip->offset_list_master->cmp = (int (*)(void *, void *))offset_list_cmp;
6c4c3561 2675 rip->offset_list_master->del = (void (*)(void *))offset_list_free;
718e3744 2676
2d2eaa13 2677 /* Distribute list install. */
ae7b826a 2678 rip->distribute_ctx = distribute_list_ctx_create(vrf);
2d2eaa13
RW
2679 distribute_list_add_hook(rip->distribute_ctx, rip_distribute_update);
2680 distribute_list_delete_hook(rip->distribute_ctx, rip_distribute_update);
2681
4b23867c 2682 /* if rmap install. */
8f88441d 2683 rip->if_rmap_ctx = if_rmap_ctx_create(vrf_name);
4b23867c
PG
2684 if_rmap_hook_add(rip->if_rmap_ctx, rip_if_rmap_update);
2685 if_rmap_hook_delete(rip->if_rmap_ctx, rip_if_rmap_update);
2686
d62a17ae 2687 /* Make output stream. */
2688 rip->obuf = stream_new(1500);
16705130 2689
ae7b826a
RW
2690 /* Enable the routing instance if possible. */
2691 if (vrf && vrf_is_enabled(vrf))
2692 rip_instance_enable(rip, vrf, socket);
2693 else {
2694 rip->vrf = NULL;
2695 rip->sock = -1;
045c5389
RW
2696 }
2697
ae7b826a
RW
2698 RB_INSERT(rip_instance_head, &rip_instances, rip);
2699
045c5389 2700 return rip;
d62a17ae 2701}
718e3744 2702
d62a17ae 2703/* Sned RIP request to the destination. */
2704int rip_request_send(struct sockaddr_in *to, struct interface *ifp,
d7c0a89a 2705 uint8_t version, struct connected *connected)
d62a17ae 2706{
2707 struct rte *rte;
2708 struct rip_packet rip_packet;
2709 struct listnode *node, *nnode;
2710
2711 memset(&rip_packet, 0, sizeof(rip_packet));
2712
2713 rip_packet.command = RIP_REQUEST;
2714 rip_packet.version = version;
2715 rte = rip_packet.rte;
2716 rte->metric = htonl(RIP_METRIC_INFINITY);
2717
2718 if (connected) {
2719 /*
2720 * connected is only sent for ripv1 case, or when
2721 * interface does not support multicast. Caller loops
2722 * over each connected address for this case.
2723 */
d7c0a89a 2724 if (rip_send_packet((uint8_t *)&rip_packet, sizeof(rip_packet),
d62a17ae 2725 to, connected)
2726 != sizeof(rip_packet))
2727 return -1;
2728 else
2729 return sizeof(rip_packet);
2730 }
718e3744 2731
d62a17ae 2732 /* send request on each connected network */
2733 for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) {
2734 struct prefix_ipv4 *p;
718e3744 2735
d62a17ae 2736 p = (struct prefix_ipv4 *)connected->address;
718e3744 2737
d62a17ae 2738 if (p->family != AF_INET)
2739 continue;
f6eacff4 2740
d7c0a89a 2741 if (rip_send_packet((uint8_t *)&rip_packet, sizeof(rip_packet),
d62a17ae 2742 to, connected)
2743 != sizeof(rip_packet))
2744 return -1;
2745 }
2746 return sizeof(rip_packet);
718e3744 2747}
2748
d62a17ae 2749static int rip_update_jitter(unsigned long time)
718e3744 2750{
239389ba 2751#define JITTER_BOUND 4
d62a17ae 2752 /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
2753 Given that, we cannot let time be less than JITTER_BOUND seconds.
2754 The RIPv2 RFC says jitter should be small compared to
2755 update_time. We consider 1/JITTER_BOUND to be small.
2756 */
2757
2758 int jitter_input = time;
2759 int jitter;
2760
2761 if (jitter_input < JITTER_BOUND)
2762 jitter_input = JITTER_BOUND;
2763
5920b3eb
RZ
2764 jitter = (((frr_weak_random() % ((jitter_input * 2) + 1))
2765 - jitter_input));
d62a17ae 2766
2767 return jitter / JITTER_BOUND;
2768}
2769
045c5389 2770void rip_event(struct rip *rip, enum rip_event event, int sock)
d62a17ae 2771{
2772 int jitter = 0;
2773
2774 switch (event) {
2775 case RIP_READ:
907a2395 2776 event_add_read(master, rip_read, rip, sock, &rip->t_read);
d62a17ae 2777 break;
2778 case RIP_UPDATE_EVENT:
e16d030c 2779 EVENT_OFF(rip->t_update);
d62a17ae 2780 jitter = rip_update_jitter(rip->update_time);
907a2395
DS
2781 event_add_timer(master, rip_update, rip,
2782 sock ? 2 : rip->update_time + jitter,
2783 &rip->t_update);
d62a17ae 2784 break;
2785 case RIP_TRIGGERED_UPDATE:
2786 if (rip->t_triggered_interval)
2787 rip->trigger = 1;
2788 else
907a2395
DS
2789 event_add_event(master, rip_triggered_update, rip, 0,
2790 &rip->t_triggered_update);
d62a17ae 2791 break;
2792 default:
2793 break;
2794 }
718e3744 2795}
6b0655a2 2796
23b23d8c 2797struct rip_distance *rip_distance_new(void)
718e3744 2798{
d62a17ae 2799 return XCALLOC(MTYPE_RIP_DISTANCE, sizeof(struct rip_distance));
718e3744 2800}
2801
23b23d8c 2802void rip_distance_free(struct rip_distance *rdistance)
d62a17ae 2803{
2826309c
RW
2804 if (rdistance->access_list)
2805 free(rdistance->access_list);
d62a17ae 2806 XFREE(MTYPE_RIP_DISTANCE, rdistance);
718e3744 2807}
2808
2826309c
RW
2809static void rip_distance_table_node_cleanup(struct route_table *table,
2810 struct route_node *node)
d62a17ae 2811{
d62a17ae 2812 struct rip_distance *rdistance;
718e3744 2813
2826309c
RW
2814 rdistance = node->info;
2815 if (rdistance)
2816 rip_distance_free(rdistance);
d62a17ae 2817}
2818
2819/* Apply RIP information to distance method. */
045c5389 2820uint8_t rip_distance_apply(struct rip *rip, struct rip_info *rinfo)
d62a17ae 2821{
2822 struct route_node *rn;
2823 struct prefix_ipv4 p;
2824 struct rip_distance *rdistance;
2825 struct access_list *alist;
2826
6006b807 2827 memset(&p, 0, sizeof(p));
d62a17ae 2828 p.family = AF_INET;
2829 p.prefix = rinfo->from;
2830 p.prefixlen = IPV4_MAX_BITLEN;
2831
2832 /* Check source address. */
2826309c 2833 rn = route_node_match(rip->distance_table, (struct prefix *)&p);
d62a17ae 2834 if (rn) {
2835 rdistance = rn->info;
2836 route_unlock_node(rn);
2837
2838 if (rdistance->access_list) {
2839 alist = access_list_lookup(AFI_IP,
2840 rdistance->access_list);
2841 if (alist == NULL)
2842 return 0;
2843 if (access_list_apply(alist, &rinfo->rp->p)
2844 == FILTER_DENY)
2845 return 0;
b769fdc8 2846 }
2847 return rdistance->distance;
718e3744 2848 }
718e3744 2849
b769fdc8 2850 return rip->distance;
718e3744 2851}
2852
045c5389 2853static void rip_distance_show(struct vty *vty, struct rip *rip)
d62a17ae 2854{
2855 struct route_node *rn;
2856 struct rip_distance *rdistance;
2857 int header = 1;
2858 char buf[BUFSIZ];
2859
7f8a9cba 2860 vty_out(vty, " Distance: (default is %u)\n",
d62a17ae 2861 rip->distance ? rip->distance : ZEBRA_RIP_DISTANCE_DEFAULT);
2862
91b508dc
DS
2863 for (rn = route_top(rip->distance_table); rn; rn = route_next(rn)) {
2864 rdistance = rn->info;
2865
2866 if (rdistance == NULL)
2867 continue;
2868
2869 if (header) {
2870 vty_out(vty, " Address Distance List\n");
2871 header = 0;
d62a17ae 2872 }
91b508dc
DS
2873 snprintfrr(buf, sizeof(buf), "%pFX", &rn->p);
2874 vty_out(vty, " %-20s %4d %s\n", buf, rdistance->distance,
2875 rdistance->access_list ? rdistance->access_list : "");
2876 }
718e3744 2877}
2878
8478ae7e 2879/* Update ECMP routes to zebra when ECMP is disabled. */
045c5389 2880void rip_ecmp_disable(struct rip *rip)
d62a17ae 2881{
2882 struct route_node *rp;
2883 struct rip_info *rinfo, *tmp_rinfo;
2884 struct list *list;
2885 struct listnode *node, *nextnode;
2886
91b508dc
DS
2887 for (rp = route_top(rip->table); rp; rp = route_next(rp)) {
2888 list = rp->info;
d62a17ae 2889
91b508dc
DS
2890 if (!list)
2891 continue;
2892 if (listcount(list) == 0)
2893 continue;
d62a17ae 2894
91b508dc
DS
2895 rinfo = listgetdata(listhead(list));
2896 if (!rip_route_rte(rinfo))
2897 continue;
d62a17ae 2898
91b508dc
DS
2899 /* Drop all other entries, except the first one. */
2900 for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo)) {
2901 if (tmp_rinfo == rinfo)
2902 continue;
d62a17ae 2903
e16d030c
DS
2904 EVENT_OFF(tmp_rinfo->t_timeout);
2905 EVENT_OFF(tmp_rinfo->t_garbage_collect);
91b508dc
DS
2906 list_delete_node(list, node);
2907 rip_info_free(tmp_rinfo);
d62a17ae 2908 }
91b508dc
DS
2909
2910 /* Update zebra. */
2911 rip_zebra_ipv4_add(rip, rp);
2912
2913 /* Set the route change flag. */
2914 SET_FLAG(rinfo->flags, RIP_RTF_CHANGED);
2915
2916 /* Signal the output process to trigger an update. */
2917 rip_event(rip, RIP_TRIGGERED_UPDATE, 0);
2918 }
8478ae7e
LF
2919}
2920
718e3744 2921/* Print out routes update time. */
d62a17ae 2922static void rip_vty_out_uptime(struct vty *vty, struct rip_info *rinfo)
718e3744 2923{
d62a17ae 2924 time_t clock;
a2700b50 2925 struct tm tm;
718e3744 2926#define TIME_BUF 25
d62a17ae 2927 char timebuf[TIME_BUF];
e6685141 2928 struct event *thread;
d62a17ae 2929
2930 if ((thread = rinfo->t_timeout) != NULL) {
4f830a07 2931 clock = event_timer_remain_second(thread);
a2700b50
MS
2932 gmtime_r(&clock, &tm);
2933 strftime(timebuf, TIME_BUF, "%M:%S", &tm);
d62a17ae 2934 vty_out(vty, "%5s", timebuf);
2935 } else if ((thread = rinfo->t_garbage_collect) != NULL) {
4f830a07 2936 clock = event_timer_remain_second(thread);
a2700b50
MS
2937 gmtime_r(&clock, &tm);
2938 strftime(timebuf, TIME_BUF, "%M:%S", &tm);
d62a17ae 2939 vty_out(vty, "%5s", timebuf);
2940 }
2941}
2942
2943static const char *rip_route_type_print(int sub_type)
2944{
2945 switch (sub_type) {
2946 case RIP_ROUTE_RTE:
2947 return "n";
2948 case RIP_ROUTE_STATIC:
2949 return "s";
2950 case RIP_ROUTE_DEFAULT:
2951 return "d";
2952 case RIP_ROUTE_REDISTRIBUTE:
2953 return "r";
2954 case RIP_ROUTE_INTERFACE:
2955 return "i";
2956 default:
2957 return "?";
2958 }
718e3744 2959}
2960
2961DEFUN (show_ip_rip,
2962 show_ip_rip_cmd,
ae7b826a 2963 "show ip rip [vrf NAME]",
718e3744 2964 SHOW_STR
2965 IP_STR
ae7b826a
RW
2966 "Show RIP routes\n"
2967 VRF_CMD_HELP_STR)
718e3744 2968{
045c5389 2969 struct rip *rip;
d62a17ae 2970 struct route_node *np;
2971 struct rip_info *rinfo = NULL;
2972 struct list *list = NULL;
2973 struct listnode *listnode = NULL;
ae7b826a
RW
2974 const char *vrf_name;
2975 int idx = 0;
d62a17ae 2976
ae7b826a
RW
2977 if (argv_find(argv, argc, "vrf", &idx))
2978 vrf_name = argv[idx + 1]->arg;
2979 else
2980 vrf_name = VRF_DEFAULT_NAME;
2981
2982 rip = rip_lookup_by_vrf_name(vrf_name);
2983 if (!rip) {
2984 vty_out(vty, "%% RIP instance not found\n");
2985 return CMD_SUCCESS;
2986 }
2987 if (!rip->enabled) {
2988 vty_out(vty, "%% RIP instance is disabled\n");
d62a17ae 2989 return CMD_SUCCESS;
ae7b826a 2990 }
d62a17ae 2991
2992 vty_out(vty,
2993 "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
2994 "Sub-codes:\n"
2995 " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
2996 " (i) - interface\n\n"
2997 " Network Next Hop Metric From Tag Time\n");
2998
91b508dc
DS
2999 for (np = route_top(rip->table); np; np = route_next(np)) {
3000 list = np->info;
d62a17ae 3001
91b508dc
DS
3002 if (!list)
3003 continue;
3004
3005 for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
3006 int len;
3007
3008 len = vty_out(vty, "%c(%s) %pFX",
3009 /* np->lock, For debugging. */
3010 zebra_route_char(rinfo->type),
3011 rip_route_type_print(rinfo->sub_type),
3012 &np->p);
3013
3014 len = 24 - len;
3015
3016 if (len > 0)
3017 vty_out(vty, "%*s", len, " ");
d62a17ae 3018
91b508dc
DS
3019 switch (rinfo->nh.type) {
3020 case NEXTHOP_TYPE_IPV4:
3021 case NEXTHOP_TYPE_IPV4_IFINDEX:
3022 vty_out(vty, "%-20pI4 %2d ",
3023 &rinfo->nh.gate.ipv4, rinfo->metric);
3024 break;
3025 case NEXTHOP_TYPE_IFINDEX:
3026 vty_out(vty, "0.0.0.0 %2d ",
3027 rinfo->metric);
3028 break;
3029 case NEXTHOP_TYPE_BLACKHOLE:
3030 vty_out(vty, "blackhole %2d ",
3031 rinfo->metric);
3032 break;
3033 case NEXTHOP_TYPE_IPV6:
3034 case NEXTHOP_TYPE_IPV6_IFINDEX:
3035 vty_out(vty, "V6 Address Hidden %2d ",
3036 rinfo->metric);
3037 break;
3038 }
3039
3040 /* Route which exist in kernel routing table. */
3041 if ((rinfo->type == ZEBRA_ROUTE_RIP) &&
3042 (rinfo->sub_type == RIP_ROUTE_RTE)) {
3043 vty_out(vty, "%-15pI4 ", &rinfo->from);
3044 vty_out(vty, "%3" ROUTE_TAG_PRI " ",
3045 (route_tag_t)rinfo->tag);
3046 rip_vty_out_uptime(vty, rinfo);
3047 } else if (rinfo->metric == RIP_METRIC_INFINITY) {
3048 vty_out(vty, "self ");
3049 vty_out(vty, "%3" ROUTE_TAG_PRI " ",
3050 (route_tag_t)rinfo->tag);
3051 rip_vty_out_uptime(vty, rinfo);
3052 } else {
3053 if (rinfo->external_metric) {
3054 len = vty_out(
3055 vty, "self (%s:%d)",
3056 zebra_route_string(rinfo->type),
3057 rinfo->external_metric);
3058 len = 16 - len;
3059 if (len > 0)
3060 vty_out(vty, "%*s", len, " ");
3061 } else
3062 vty_out(vty, "self ");
3063 vty_out(vty, "%3" ROUTE_TAG_PRI,
3064 (route_tag_t)rinfo->tag);
d62a17ae 3065 }
91b508dc
DS
3066
3067 vty_out(vty, "\n");
3068 }
3069 }
d62a17ae 3070 return CMD_SUCCESS;
718e3744 3071}
3072
16705130 3073/* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
3074DEFUN (show_ip_rip_status,
3075 show_ip_rip_status_cmd,
ae7b826a 3076 "show ip rip [vrf NAME] status",
718e3744 3077 SHOW_STR
3078 IP_STR
16705130 3079 "Show RIP routes\n"
ae7b826a 3080 VRF_CMD_HELP_STR
718e3744 3081 "IP routing protocol process parameters and statistics\n")
3082{
045c5389 3083 struct rip *rip;
d62a17ae 3084 struct interface *ifp;
3085 struct rip_interface *ri;
3086 extern const struct message ri_version_msg[];
3087 const char *send_version;
3088 const char *receive_version;
ae7b826a
RW
3089 const char *vrf_name;
3090 int idx = 0;
d62a17ae 3091
ae7b826a
RW
3092 if (argv_find(argv, argc, "vrf", &idx))
3093 vrf_name = argv[idx + 1]->arg;
3094 else
3095 vrf_name = VRF_DEFAULT_NAME;
3096
3097 rip = rip_lookup_by_vrf_name(vrf_name);
3098 if (!rip) {
3099 vty_out(vty, "%% RIP instance not found\n");
d62a17ae 3100 return CMD_SUCCESS;
ae7b826a
RW
3101 }
3102 if (!rip->enabled) {
3103 vty_out(vty, "%% RIP instance is disabled\n");
3104 return CMD_SUCCESS;
3105 }
d62a17ae 3106
3107 vty_out(vty, "Routing Protocol is \"rip\"\n");
b745780b 3108 vty_out(vty, " Sending updates every %u seconds with +/-50%%,",
d62a17ae 3109 rip->update_time);
3110 vty_out(vty, " next due in %lu seconds\n",
4f830a07 3111 event_timer_remain_second(rip->t_update));
b745780b
RW
3112 vty_out(vty, " Timeout after %u seconds,", rip->timeout_time);
3113 vty_out(vty, " garbage collect after %u seconds\n", rip->garbage_time);
d62a17ae 3114
3115 /* Filtering status show. */
03a38493 3116 config_show_distribute(vty, rip->distribute_ctx);
d62a17ae 3117
3118 /* Default metric information. */
282ae30c 3119 vty_out(vty, " Default redistribution metric is %u\n",
d62a17ae 3120 rip->default_metric);
3121
3122 /* Redistribute information. */
3123 vty_out(vty, " Redistributing:");
045c5389 3124 rip_show_redistribute_config(vty, rip);
d62a17ae 3125 vty_out(vty, "\n");
3126
3127 vty_out(vty, " Default version control: send version %s,",
3128 lookup_msg(ri_version_msg, rip->version_send, NULL));
3129 if (rip->version_recv == RI_RIP_VERSION_1_AND_2)
3130 vty_out(vty, " receive any version \n");
3131 else
3132 vty_out(vty, " receive version %s \n",
3133 lookup_msg(ri_version_msg, rip->version_recv, NULL));
3134
3135 vty_out(vty, " Interface Send Recv Key-chain\n");
3136
ae7b826a 3137 FOR_ALL_INTERFACES (rip->vrf, ifp) {
d62a17ae 3138 ri = ifp->info;
3139
3140 if (!ri->running)
3141 continue;
3142
3143 if (ri->enable_network || ri->enable_interface) {
3144 if (ri->ri_send == RI_RIP_UNSPEC)
3145 send_version =
3146 lookup_msg(ri_version_msg,
3147 rip->version_send, NULL);
3148 else
3149 send_version = lookup_msg(ri_version_msg,
3150 ri->ri_send, NULL);
3151
3152 if (ri->ri_receive == RI_RIP_UNSPEC)
3153 receive_version =
3154 lookup_msg(ri_version_msg,
3155 rip->version_recv, NULL);
3156 else
3157 receive_version = lookup_msg(
3158 ri_version_msg, ri->ri_receive, NULL);
3159
3160 vty_out(vty, " %-17s%-3s %-3s %s\n", ifp->name,
3161 send_version, receive_version,
3162 ri->key_chain ? ri->key_chain : "");
3163 }
3164 }
718e3744 3165
d62a17ae 3166 vty_out(vty, " Routing for Networks:\n");
045c5389 3167 rip_show_network_config(vty, rip);
718e3744 3168
91b508dc
DS
3169 int found_passive = 0;
3170 FOR_ALL_INTERFACES (rip->vrf, ifp) {
3171 ri = ifp->info;
3172
3173 if ((ri->enable_network || ri->enable_interface) &&
3174 ri->passive) {
3175 if (!found_passive) {
3176 vty_out(vty, " Passive Interface(s):\n");
3177 found_passive = 1;
d62a17ae 3178 }
91b508dc 3179 vty_out(vty, " %s\n", ifp->name);
d62a17ae 3180 }
718e3744 3181 }
3182
d62a17ae 3183 vty_out(vty, " Routing Information Sources:\n");
3184 vty_out(vty,
3185 " Gateway BadPackets BadRoutes Distance Last Update\n");
045c5389 3186 rip_peer_display(vty, rip);
718e3744 3187
045c5389 3188 rip_distance_show(vty, rip);
718e3744 3189
d62a17ae 3190 return CMD_SUCCESS;
3191}
718e3744 3192
d62a17ae 3193/* RIP configuration write function. */
3194static int config_write_rip(struct vty *vty)
3195{
ae7b826a 3196 struct rip *rip;
d62a17ae 3197 int write = 0;
d62a17ae 3198
ae7b826a
RW
3199 RB_FOREACH(rip, rip_instance_head, &rip_instances) {
3200 char xpath[XPATH_MAXLEN];
3201 struct lyd_node *dnode;
045c5389 3202
ae7b826a
RW
3203 snprintf(xpath, sizeof(xpath),
3204 "/frr-ripd:ripd/instance[vrf='%s']", rip->vrf_name);
3205
3206 dnode = yang_dnode_get(running_config->dnode, xpath);
3207 assert(dnode);
d62a17ae 3208
8c9226c2
RW
3209 nb_cli_show_dnode_cmds(vty, dnode, false);
3210
ae7b826a
RW
3211 /* Distribute configuration. */
3212 config_write_distribute(vty, rip->distribute_ctx);
d62a17ae 3213
07679ad9
IR
3214 vty_out(vty, "exit\n");
3215
ae7b826a 3216 write = 1;
d62a17ae 3217 }
ae7b826a 3218
d62a17ae 3219 return write;
3220}
718e3744 3221
612c2c15 3222static int config_write_rip(struct vty *vty);
d62a17ae 3223/* RIP node structure. */
62b346ee 3224static struct cmd_node rip_node = {
f4b8291f 3225 .name = "rip",
62b346ee 3226 .node = RIP_NODE,
24389580 3227 .parent_node = CONFIG_NODE,
62b346ee 3228 .prompt = "%s(config-router)# ",
612c2c15 3229 .config_write = config_write_rip,
62b346ee 3230};
718e3744 3231
d62a17ae 3232/* Distribute-list update functions. */
03a38493
PG
3233static void rip_distribute_update(struct distribute_ctx *ctx,
3234 struct distribute *dist)
d62a17ae 3235{
3236 struct interface *ifp;
3237 struct rip_interface *ri;
3238 struct access_list *alist;
3239 struct prefix_list *plist;
8478ae7e 3240
ae7b826a 3241 if (!ctx->vrf || !dist->ifname)
d62a17ae 3242 return;
718e3744 3243
a36898e7 3244 ifp = if_lookup_by_name(dist->ifname, ctx->vrf->vrf_id);
d62a17ae 3245 if (ifp == NULL)
3246 return;
718e3744 3247
d62a17ae 3248 ri = ifp->info;
6b0655a2 3249
d62a17ae 3250 if (dist->list[DISTRIBUTE_V4_IN]) {
3251 alist = access_list_lookup(AFI_IP,
3252 dist->list[DISTRIBUTE_V4_IN]);
3253 if (alist)
3254 ri->list[RIP_FILTER_IN] = alist;
3255 else
3256 ri->list[RIP_FILTER_IN] = NULL;
3257 } else
3258 ri->list[RIP_FILTER_IN] = NULL;
3259
3260 if (dist->list[DISTRIBUTE_V4_OUT]) {
3261 alist = access_list_lookup(AFI_IP,
3262 dist->list[DISTRIBUTE_V4_OUT]);
3263 if (alist)
3264 ri->list[RIP_FILTER_OUT] = alist;
3265 else
3266 ri->list[RIP_FILTER_OUT] = NULL;
3267 } else
3268 ri->list[RIP_FILTER_OUT] = NULL;
3269
3270 if (dist->prefix[DISTRIBUTE_V4_IN]) {
3271 plist = prefix_list_lookup(AFI_IP,
3272 dist->prefix[DISTRIBUTE_V4_IN]);
3273 if (plist)
3274 ri->prefix[RIP_FILTER_IN] = plist;
3275 else
3276 ri->prefix[RIP_FILTER_IN] = NULL;
3277 } else
3278 ri->prefix[RIP_FILTER_IN] = NULL;
3279
3280 if (dist->prefix[DISTRIBUTE_V4_OUT]) {
3281 plist = prefix_list_lookup(AFI_IP,
3282 dist->prefix[DISTRIBUTE_V4_OUT]);
3283 if (plist)
3284 ri->prefix[RIP_FILTER_OUT] = plist;
3285 else
3286 ri->prefix[RIP_FILTER_OUT] = NULL;
3287 } else
3288 ri->prefix[RIP_FILTER_OUT] = NULL;
3289}
3290
3291void rip_distribute_update_interface(struct interface *ifp)
3292{
045c5389
RW
3293 struct rip_interface *ri = ifp->info;
3294 struct rip *rip = ri->rip;
d62a17ae 3295 struct distribute *dist;
3296
03a38493
PG
3297 if (!rip)
3298 return;
3299 dist = distribute_lookup(rip->distribute_ctx, ifp->name);
d62a17ae 3300 if (dist)
03a38493 3301 rip_distribute_update(rip->distribute_ctx, dist);
718e3744 3302}
3303
3304/* Update all interface's distribute list. */
02ff83c5 3305/* ARGSUSED */
d62a17ae 3306static void rip_distribute_update_all(struct prefix_list *notused)
718e3744 3307{
f4e14fdb 3308 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 3309 struct interface *ifp;
718e3744 3310
451fda4f 3311 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 3312 rip_distribute_update_interface(ifp);
718e3744 3313}
11dde9c2 3314/* ARGSUSED */
d62a17ae 3315static void rip_distribute_update_all_wrapper(struct access_list *notused)
11dde9c2 3316{
d62a17ae 3317 rip_distribute_update_all(NULL);
11dde9c2 3318}
6b0655a2 3319
718e3744 3320/* Delete all added rip route. */
045c5389 3321void rip_clean(struct rip *rip)
718e3744 3322{
eb6b3885
IR
3323 rip_interfaces_clean(rip);
3324
ae7b826a
RW
3325 if (rip->enabled)
3326 rip_instance_disable(rip);
d62a17ae 3327
2d2eaa13 3328 stream_free(rip->obuf);
d62a17ae 3329
2d2eaa13 3330 for (int i = 0; i < ZEBRA_ROUTE_MAX; i++)
f9120f71
RW
3331 if (rip->redist[i].route_map.name)
3332 free(rip->redist[i].route_map.name);
2d2eaa13
RW
3333
3334 route_table_finish(rip->table);
3335 route_table_finish(rip->neighbor);
711915d2 3336 list_delete(&rip->peer_list);
2d2eaa13 3337 distribute_list_delete(&rip->distribute_ctx);
8f88441d 3338 if_rmap_ctx_delete(rip->if_rmap_ctx);
d62a17ae 3339
045c5389
RW
3340 rip_clean_network(rip);
3341 rip_passive_nondefault_clean(rip);
ca046902 3342 vector_free(rip->enable_interface);
1205fdc4 3343 route_table_finish(rip->enable_network);
5a29c0d5 3344 vector_free(rip->passive_nondefault);
3f21c8c4 3345 list_delete(&rip->offset_list_master);
2826309c 3346 route_table_finish(rip->distance_table);
045c5389 3347
ae7b826a 3348 RB_REMOVE(rip_instance_head, &rip_instances, rip);
c262df82 3349 XFREE(MTYPE_TMP, rip->default_bfd_profile);
ae7b826a 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)) {
e16d030c
DS
3495 EVENT_OFF(rinfo->t_timeout);
3496 EVENT_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. */
e16d030c
DS
3508 EVENT_OFF(rip->t_update);
3509 EVENT_OFF(rip->t_triggered_update);
3510 EVENT_OFF(rip->t_triggered_interval);
ae7b826a
RW
3511
3512 /* Cancel read thread. */
e16d030c 3513 EVENT_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}