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