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