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