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