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