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