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