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