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