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