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