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