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