]> git.ipfire.org Git - thirdparty/bird.git/blob - proto/rip/rip.c
eb2323160fbbf009b070662982661d5854534fd1
[thirdparty/bird.git] / proto / rip / rip.c
1 /*
2 * BIRD -- Routing Information Protocol (RIP)
3 *
4 * (c) 1998--1999 Pavel Machek <pavel@ucw.cz>
5 * (c) 2004--2013 Ondrej Filip <feela@network.cz>
6 * (c) 2009--2015 Ondrej Zajicek <santiago@crfreenet.org>
7 * (c) 2009--2015 CZ.NIC z.s.p.o.
8 *
9 * Can be freely distributed and used under the terms of the GNU GPL.
10 */
11
12 /**
13 * DOC: Routing Information Protocol (RIP)
14 *
15 * The RIP protocol is implemented in two files: |rip.c| containing the protocol
16 * logic, route management and the protocol glue with BIRD core, and |packets.c|
17 * handling RIP packet processing, RX, TX and protocol sockets.
18 *
19 * Each instance of RIP is described by a structure &rip_proto, which contains
20 * an internal RIP routing table, a list of protocol interfaces and the main
21 * timer responsible for RIP routing table cleanup.
22 *
23 * RIP internal routing table contains incoming and outgoing routes. For each
24 * network (represented by structure &rip_entry) there is one outgoing route
25 * stored directly in &rip_entry and an one-way linked list of incoming routes
26 * (structures &rip_rte). The list contains incoming routes from different RIP
27 * neighbors, but only routes with the lowest metric are stored (i.e., all
28 * stored incoming routes have the same metric).
29 *
30 * Note that RIP itself does not select outgoing route, that is done by the core
31 * routing table. When a new incoming route is received, it is propagated to the
32 * RIP table by rip_update_rte() and possibly stored in the list of incoming
33 * routes. Then the change may be propagated to the core by rip_announce_rte().
34 * The core selects the best route and propagate it to RIP by rip_rt_notify(),
35 * which updates outgoing route part of &rip_entry and possibly triggers route
36 * propagation by rip_trigger_update().
37 *
38 * RIP interfaces are represented by structures &rip_iface. A RIP interface
39 * contains a per-interface socket, a list of associated neighbors, interface
40 * configuration, and state information related to scheduled interface events
41 * and running update sessions. RIP interfaces are added and removed based on
42 * core interface notifications.
43 *
44 * There are two RIP interface events - regular updates and triggered updates.
45 * Both are managed from the RIP interface timer (rip_iface_timer()). Regular
46 * updates are called at fixed interval and propagate the whole routing table,
47 * while triggered updates are scheduled by rip_trigger_update() due to some
48 * routing table change and propagate only the routes modified since the time
49 * they were scheduled. There are also unicast-destined requested updates, but
50 * these are sent directly as a reaction to received RIP request message. The
51 * update session is started by rip_send_table(). There may be at most one
52 * active update session per interface, as the associated state (including the
53 * fib iterator) is stored directly in &rip_iface structure.
54 *
55 * RIP neighbors are represented by structures &rip_neighbor. Compared to
56 * neighbor handling in other routing protocols, RIP does not have explicit
57 * neighbor discovery and adjacency maintenance, which makes the &rip_neighbor
58 * related code a bit peculiar. RIP neighbors are interlinked with core neighbor
59 * structures (&neighbor) and use core neighbor notifications to ensure that RIP
60 * neighbors are timely removed. RIP neighbors are added based on received route
61 * notifications and removed based on core neighbor and RIP interface events.
62 *
63 * RIP neighbors are linked by RIP routes and use counter to track the number of
64 * associated routes, but when these RIP routes timeout, associated RIP neighbor
65 * is still alive (with zero counter). When RIP neighbor is removed but still
66 * has some associated routes, it is not freed, just changed to detached state
67 * (core neighbors and RIP ifaces are unlinked), then during the main timer
68 * cleanup phase the associated routes are removed and the &rip_neighbor
69 * structure is finally freed.
70 *
71 * Supported standards:
72 * RFC 1058 - RIPv1
73 * RFC 2453 - RIPv2
74 * RFC 2080 - RIPng
75 * RFC 2091 - Triggered RIP for demand circuits
76 * RFC 4822 - RIP cryptographic authentication
77 */
78
79 #include <stdlib.h>
80 #include "rip.h"
81
82
83 static inline void rip_lock_neighbor(struct rip_neighbor *n);
84 static inline void rip_unlock_neighbor(struct rip_neighbor *n);
85 static inline int rip_iface_link_up(struct rip_iface *ifa);
86 static inline void rip_kick_timer(struct rip_proto *p);
87 static inline void rip_iface_kick_timer(struct rip_iface *ifa);
88 static void rip_iface_timer(timer *timer);
89 static void rip_trigger_update(struct rip_proto *p);
90
91
92 /*
93 * RIP routes
94 */
95
96 static struct rip_rte *
97 rip_add_rte(struct rip_proto *p, struct rip_rte **rp, struct rip_rte *src)
98 {
99 struct rip_rte *rt = sl_alloc(p->rte_slab);
100
101 memcpy(rt, src, sizeof(struct rip_rte));
102 rt->next = *rp;
103 *rp = rt;
104
105 rip_lock_neighbor(rt->from);
106
107 return rt;
108 }
109
110 static inline void
111 rip_remove_rte(struct rip_proto *p UNUSED, struct rip_rte **rp)
112 {
113 struct rip_rte *rt = *rp;
114
115 rip_unlock_neighbor(rt->from);
116
117 *rp = rt->next;
118 sl_free(rt);
119 }
120
121 static inline int rip_same_rte(struct rip_rte *a, struct rip_rte *b)
122 { return a->metric == b->metric && a->tag == b->tag && ipa_equal(a->next_hop, b->next_hop); }
123
124 static inline int rip_valid_rte(struct rip_rte *rt)
125 { return rt->from->ifa != NULL; }
126
127 /**
128 * rip_announce_rte - announce route from RIP routing table to the core
129 * @p: RIP instance
130 * @en: related network
131 *
132 * The function takes a list of incoming routes from @en, prepare appropriate
133 * &rte for the core and propagate it by rte_update().
134 */
135 static void
136 rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
137 {
138 struct rip_rte *rt = en->routes;
139
140 /* Find first valid rte */
141 while (rt && !rip_valid_rte(rt))
142 rt = rt->next;
143
144 if (rt)
145 {
146 /* Update */
147 rta a0 = {
148 .pref = p->p.main_channel->preference,
149 .source = RTS_RIP,
150 .scope = SCOPE_UNIVERSE,
151 .dest = RTD_UNICAST,
152 };
153
154 u8 rt_metric = rt->metric;
155 u16 rt_tag = rt->tag;
156
157 if (p->ecmp)
158 {
159 /* ECMP route */
160 struct nexthop *nhs = NULL;
161 int num = 0;
162
163 for (rt = en->routes; rt && (num < p->ecmp); rt = rt->next)
164 {
165 if (!rip_valid_rte(rt))
166 continue;
167
168 struct nexthop *nh = allocz(sizeof(struct nexthop));
169
170 nh->gw = rt->next_hop;
171 nh->iface = rt->from->ifa->iface;
172 nh->weight = rt->from->ifa->cf->ecmp_weight;
173
174 nexthop_insert(&nhs, nh);
175 num++;
176
177 if (rt->tag != rt_tag)
178 rt_tag = 0;
179 }
180
181 a0.nh = *nhs;
182 }
183 else
184 {
185 /* Unipath route */
186 a0.from = rt->from->nbr->addr;
187 a0.nh.gw = rt->next_hop;
188 a0.nh.iface = rt->from->ifa->iface;
189 }
190
191 a0.eattrs = alloca(sizeof(ea_list) + 3*sizeof(eattr));
192 memset(a0.eattrs, 0, sizeof(ea_list)); /* Zero-ing only the ea_list header */
193 a0.eattrs->count = 3;
194 a0.eattrs->attrs[0] = (eattr) {
195 .id = EA_RIP_METRIC,
196 .type = EAF_TYPE_INT,
197 .u.data = rt_metric,
198 };
199 a0.eattrs->attrs[1] = (eattr) {
200 .id = EA_RIP_TAG,
201 .type = EAF_TYPE_INT,
202 .u.data = rt_tag,
203 };
204 a0.eattrs->attrs[2] = (eattr) {
205 .id = EA_RIP_FROM,
206 .type = EAF_TYPE_PTR,
207 .u.data = (uintptr_t) a0.nh.iface,
208 };
209
210 rta *a = rta_lookup(&a0);
211 rte *e = rte_get_temp(a, p->p.main_source);
212
213 rte_update(&p->p, en->n.addr, e);
214 }
215 else
216 {
217 /* Withdraw */
218 rte_update(&p->p, en->n.addr, NULL);
219 }
220 }
221
222 /**
223 * rip_update_rte - enter a route update to RIP routing table
224 * @p: RIP instance
225 * @addr: network address
226 * @new: a &rip_rte representing the new route
227 *
228 * The function is called by the RIP packet processing code whenever it receives
229 * a reachable route. The appropriate routing table entry is found and the list
230 * of incoming routes is updated. Eventually, the change is also propagated to
231 * the core by rip_announce_rte(). Note that for unreachable routes,
232 * rip_withdraw_rte() should be called instead of rip_update_rte().
233 */
234 void
235 rip_update_rte(struct rip_proto *p, net_addr *n, struct rip_rte *new)
236 {
237 struct rip_entry *en = fib_get(&p->rtable, n);
238 struct rip_rte *rt, **rp;
239 int changed = 0;
240
241 /* If the new route is better, remove all current routes */
242 if (en->routes && new->metric < en->routes->metric)
243 while (en->routes)
244 rip_remove_rte(p, &en->routes);
245
246 /* Find the old route (also set rp for later) */
247 for (rp = &en->routes; rt = *rp; rp = &rt->next)
248 if (rt->from == new->from)
249 {
250 if (rip_same_rte(rt, new))
251 {
252 rt->expires = new->expires;
253 return;
254 }
255
256 /* Remove the old route */
257 rip_remove_rte(p, rp);
258 changed = 1;
259 break;
260 }
261
262 /* If the new route is optimal, add it to the list */
263 if (!en->routes || new->metric == en->routes->metric)
264 {
265 rt = rip_add_rte(p, rp, new);
266 changed = 1;
267 }
268
269 /* Announce change if on relevant position (the first or any for ECMP) */
270 if (changed && (rp == &en->routes || p->ecmp))
271 rip_announce_rte(p, en);
272 }
273
274 /**
275 * rip_withdraw_rte - enter a route withdraw to RIP routing table
276 * @p: RIP instance
277 * @addr: network address
278 * @from: a &rip_neighbor propagating the withdraw
279 *
280 * The function is called by the RIP packet processing code whenever it receives
281 * an unreachable route. The incoming route for given network from nbr @from is
282 * removed. Eventually, the change is also propagated by rip_announce_rte().
283 */
284 void
285 rip_withdraw_rte(struct rip_proto *p, net_addr *n, struct rip_neighbor *from)
286 {
287 struct rip_entry *en = fib_find(&p->rtable, n);
288 struct rip_rte *rt, **rp;
289
290 if (!en)
291 return;
292
293 /* Find the old route */
294 for (rp = &en->routes; rt = *rp; rp = &rt->next)
295 if (rt->from == from)
296 break;
297
298 if (!rt)
299 return;
300
301 /* Remove the old route */
302 rip_remove_rte(p, rp);
303
304 /* Announce change if on relevant position */
305 if (rp == &en->routes || p->ecmp)
306 rip_announce_rte(p, en);
307 }
308
309 /*
310 * rip_rt_notify - core tells us about new route, so store
311 * it into our data structures.
312 */
313 static void
314 rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, struct rte *new,
315 struct rte *old UNUSED)
316 {
317 struct rip_proto *p = (struct rip_proto *) P;
318 struct rip_entry *en;
319 int old_metric;
320
321 if (new)
322 {
323 /* Update */
324 u32 rt_tag = ea_get_int(new->attrs->eattrs, EA_RIP_TAG, 0);
325 u32 rt_metric = ea_get_int(new->attrs->eattrs, EA_RIP_METRIC, 1);
326 struct iface *rt_from = (struct iface *) ea_get_int(new->attrs->eattrs, EA_RIP_FROM, 0);
327
328 if (rt_metric > p->infinity)
329 {
330 log(L_WARN "%s: Invalid rip_metric value %u for route %N",
331 p->p.name, rt_metric, net->n.addr);
332 rt_metric = p->infinity;
333 }
334
335 if (rt_tag > 0xffff)
336 {
337 log(L_WARN "%s: Invalid rip_tag value %u for route %N",
338 p->p.name, rt_tag, net->n.addr);
339 rt_metric = p->infinity;
340 rt_tag = 0;
341 }
342
343 /*
344 * Note that we accept exported routes with infinity metric (this could
345 * happen if rip_metric is modified in filters). Such entry has infinity
346 * metric but is RIP_ENTRY_VALID and therefore is not subject to garbage
347 * collection.
348 */
349
350 en = fib_get(&p->rtable, net->n.addr);
351
352 old_metric = en->valid ? en->metric : -1;
353
354 en->valid = RIP_ENTRY_VALID;
355 en->metric = rt_metric;
356 en->tag = rt_tag;
357 en->from = (new->src->proto == P) ? rt_from : NULL;
358 en->iface = new->attrs->nh.iface;
359 en->next_hop = new->attrs->nh.gw;
360 }
361 else
362 {
363 /* Withdraw */
364 en = fib_find(&p->rtable, net->n.addr);
365
366 if (!en || en->valid != RIP_ENTRY_VALID)
367 return;
368
369 old_metric = en->metric;
370
371 en->valid = RIP_ENTRY_STALE;
372 en->metric = p->infinity;
373 en->tag = 0;
374 en->from = NULL;
375 en->iface = NULL;
376 en->next_hop = IPA_NONE;
377 }
378
379 /* Activate triggered updates */
380 if (en->metric != old_metric)
381 {
382 en->changed = current_time();
383 rip_trigger_update(p);
384 }
385 }
386
387 void
388 rip_flush_table(struct rip_proto *p, struct rip_neighbor *n)
389 {
390 btime expires = current_time() + n->ifa->cf->timeout_time;
391
392 FIB_WALK(&p->rtable, struct rip_entry, en)
393 {
394 for (struct rip_rte *e = en->routes; e; e = e->next)
395 if ((e->from == n) && (e->expires == TIME_INFINITY))
396 e->expires = expires;
397 }
398 FIB_WALK_END;
399 }
400
401
402 /*
403 * RIP neighbors
404 */
405
406 struct rip_neighbor *
407 rip_get_neighbor(struct rip_proto *p, ip_addr *a, struct rip_iface *ifa)
408 {
409 neighbor *nbr = neigh_find(&p->p, *a, ifa->iface, 0);
410
411 if (!nbr || (nbr->scope == SCOPE_HOST) || !rip_iface_link_up(ifa))
412 return NULL;
413
414 if (nbr->data)
415 return nbr->data;
416
417 TRACE(D_EVENTS, "New neighbor %I on %s", *a, ifa->iface->name);
418
419 struct rip_neighbor *n = mb_allocz(p->p.pool, sizeof(struct rip_neighbor));
420 n->ifa = ifa;
421 n->nbr = nbr;
422 nbr->data = n;
423 n->csn = nbr->aux;
424
425 add_tail(&ifa->neigh_list, NODE n);
426
427 return n;
428 }
429
430 static void
431 rip_remove_neighbor(struct rip_proto *p, struct rip_neighbor *n)
432 {
433 neighbor *nbr = n->nbr;
434
435 TRACE(D_EVENTS, "Removing neighbor %I on %s", nbr->addr, nbr->ifreq->name);
436
437 rem_node(NODE n);
438 n->ifa = NULL;
439 n->nbr = NULL;
440 nbr->data = NULL;
441 nbr->aux = n->csn;
442
443 rfree(n->bfd_req);
444 n->bfd_req = NULL;
445 n->last_seen = 0;
446
447 if (!n->uc)
448 mb_free(n);
449
450 /* Related routes are removed in rip_timer() */
451 rip_kick_timer(p);
452 }
453
454 static inline void
455 rip_lock_neighbor(struct rip_neighbor *n)
456 {
457 n->uc++;
458 }
459
460 static inline void
461 rip_unlock_neighbor(struct rip_neighbor *n)
462 {
463 n->uc--;
464
465 if (!n->nbr && !n->uc)
466 mb_free(n);
467 }
468
469 static void
470 rip_neigh_notify(struct neighbor *nbr)
471 {
472 struct rip_proto *p = (struct rip_proto *) nbr->proto;
473 struct rip_neighbor *n = nbr->data;
474
475 if (!n)
476 return;
477
478 /*
479 * We assume that rip_neigh_notify() is called before rip_if_notify() for
480 * IF_CHANGE_DOWN and therefore n->ifa is still valid. We have no such
481 * ordering assumption for IF_CHANGE_LINK, so we test link state of the
482 * underlying iface instead of just rip_iface state.
483 */
484 if ((nbr->scope <= 0) || !rip_iface_link_up(n->ifa))
485 rip_remove_neighbor(p, n);
486 }
487
488 static void
489 rip_bfd_notify(struct bfd_request *req)
490 {
491 struct rip_neighbor *n = req->data;
492 struct rip_proto *p = n->ifa->rip;
493
494 if (req->down)
495 {
496 TRACE(D_EVENTS, "BFD session down for nbr %I on %s",
497 n->nbr->addr, n->ifa->iface->name);
498 rip_remove_neighbor(p, n);
499 }
500 }
501
502 void
503 rip_update_bfd(struct rip_proto *p, struct rip_neighbor *n)
504 {
505 int use_bfd = n->ifa->cf->bfd && n->last_seen;
506
507 if (use_bfd && !n->bfd_req)
508 {
509 /*
510 * For RIPv2, use the same address as rip_open_socket(). For RIPng, neighbor
511 * should contain an address from the same prefix, thus also link-local. It
512 * may cause problems if two link-local addresses are assigned to one iface.
513 */
514 ip_addr saddr = rip_is_v2(p) ? n->ifa->sk->saddr : n->nbr->ifa->ip;
515 n->bfd_req = bfd_request_session(p->p.pool, n->nbr->addr, saddr,
516 n->nbr->iface, p->p.vrf,
517 rip_bfd_notify, n, NULL);
518 }
519
520 if (!use_bfd && n->bfd_req)
521 {
522 rfree(n->bfd_req);
523 n->bfd_req = NULL;
524 }
525 }
526
527
528 /*
529 * RIP interfaces
530 */
531
532 static void
533 rip_iface_start(struct rip_iface *ifa)
534 {
535 struct rip_proto *p = ifa->rip;
536
537 TRACE(D_EVENTS, "Starting interface %s", ifa->iface->name);
538
539 if (! ifa->cf->demand_circuit)
540 {
541 ifa->next_regular = current_time() + (random() % ifa->cf->update_time) + 100 MS;
542 tm_set(ifa->timer, ifa->next_regular);
543 }
544 else
545 {
546 ifa->next_regular = TIME_INFINITY;
547 }
548
549 ifa->up = 1;
550
551 if (ifa->cf->passive)
552 return;
553
554 rip_send_request(p, ifa);
555 rip_send_table(p, ifa, ifa->addr, 0);
556 }
557
558 static void
559 rip_iface_stop(struct rip_iface *ifa)
560 {
561 struct rip_proto *p = ifa->rip;
562 struct rip_neighbor *n;
563
564 TRACE(D_EVENTS, "Stopping interface %s", ifa->iface->name);
565
566 rip_reset_tx_session(p, ifa);
567
568 ifa->next_regular = 0;
569 ifa->next_triggered = 0;
570 ifa->want_triggered = 0;
571
572 if (ifa->tx_pending)
573 ifa->tx_seqnum++;
574
575 ifa->tx_pending = 0;
576 ifa->req_pending = 0;
577
578 if (ifa->cf->demand_circuit && !ifa->cf->passive)
579 rip_send_flush(p, ifa);
580
581 WALK_LIST_FIRST(n, ifa->neigh_list)
582 rip_remove_neighbor(p, n);
583
584 tm_stop(ifa->timer);
585 tm_stop(ifa->rxmt_timer);
586 ifa->up = 0;
587 }
588
589 static inline int
590 rip_iface_link_up(struct rip_iface *ifa)
591 {
592 return !ifa->cf->check_link || (ifa->iface->flags & IF_LINK_UP);
593 }
594
595 static void
596 rip_iface_update_state(struct rip_iface *ifa)
597 {
598 int up = ifa->sk && rip_iface_link_up(ifa);
599
600 if (up == ifa->up)
601 return;
602
603 if (up)
604 rip_iface_start(ifa);
605 else
606 rip_iface_stop(ifa);
607 }
608
609 static void
610 rip_iface_update_buffers(struct rip_iface *ifa)
611 {
612 if (!ifa->sk)
613 return;
614
615 uint rbsize = ifa->cf->rx_buffer ?: ifa->iface->mtu;
616 uint tbsize = ifa->cf->tx_length ?: ifa->iface->mtu;
617 rbsize = MAX(rbsize, tbsize);
618
619 sk_set_rbsize(ifa->sk, rbsize);
620 sk_set_tbsize(ifa->sk, tbsize);
621
622 uint headers = (rip_is_v2(ifa->rip) ? IP4_HEADER_LENGTH : IP6_HEADER_LENGTH) + UDP_HEADER_LENGTH;
623 ifa->tx_plen = tbsize - headers;
624
625 if (ifa->cf->auth_type == RIP_AUTH_CRYPTO)
626 ifa->tx_plen -= RIP_AUTH_TAIL_LENGTH + max_mac_length(ifa->cf->passwords);
627 }
628
629 static inline void
630 rip_iface_update_bfd(struct rip_iface *ifa)
631 {
632 struct rip_proto *p = ifa->rip;
633 struct rip_neighbor *n;
634
635 WALK_LIST(n, ifa->neigh_list)
636 rip_update_bfd(p, n);
637 }
638
639
640 static void
641 rip_iface_locked(struct object_lock *lock)
642 {
643 struct rip_iface *ifa = lock->data;
644 struct rip_proto *p = ifa->rip;
645
646 if (!rip_open_socket(ifa))
647 {
648 log(L_ERR "%s: Cannot open socket for %s", p->p.name, ifa->iface->name);
649 return;
650 }
651
652 rip_iface_update_buffers(ifa);
653 rip_iface_update_state(ifa);
654 }
655
656
657 static struct rip_iface *
658 rip_find_iface(struct rip_proto *p, struct iface *what)
659 {
660 struct rip_iface *ifa;
661
662 WALK_LIST(ifa, p->iface_list)
663 if (ifa->iface == what)
664 return ifa;
665
666 return NULL;
667 }
668
669 static void
670 rip_add_iface(struct rip_proto *p, struct iface *iface, struct rip_iface_config *ic)
671 {
672 struct rip_iface *ifa;
673
674 TRACE(D_EVENTS, "Adding interface %s", iface->name);
675
676 ifa = mb_allocz(p->p.pool, sizeof(struct rip_iface));
677 ifa->rip = p;
678 ifa->iface = iface;
679 ifa->cf = ic;
680
681 if (ipa_nonzero(ic->address))
682 ifa->addr = ic->address;
683 else if (ic->mode == RIP_IM_MULTICAST)
684 ifa->addr = rip_is_v2(p) ? IP4_RIP_ROUTERS : IP6_RIP_ROUTERS;
685 else /* Broadcast */
686 ifa->addr = iface->addr4->brd;
687 /*
688 * The above is just a workaround for BSD as it can't send broadcasts
689 * to 255.255.255.255. BSD systems need the network broadcast address instead.
690 *
691 * TODO: move this to sysdep code
692 */
693
694 init_list(&ifa->neigh_list);
695
696 add_tail(&p->iface_list, NODE ifa);
697
698 ifa->timer = tm_new_init(p->p.pool, rip_iface_timer, ifa, 0, 0);
699 ifa->rxmt_timer = tm_new_init(p->p.pool, rip_rxmt_timeout, ifa, 0, 0);
700
701 struct object_lock *lock = olock_new(p->p.pool);
702 lock->type = OBJLOCK_UDP;
703 lock->port = ic->port;
704 lock->iface = iface;
705 lock->data = ifa;
706 lock->hook = rip_iface_locked;
707 ifa->lock = lock;
708
709 olock_acquire(lock);
710 }
711
712 static void
713 rip_remove_iface(struct rip_proto *p, struct rip_iface *ifa)
714 {
715 rip_iface_stop(ifa);
716
717 TRACE(D_EVENTS, "Removing interface %s", ifa->iface->name);
718
719 rem_node(NODE ifa);
720
721 rfree(ifa->sk);
722 rfree(ifa->lock);
723 rfree(ifa->timer);
724
725 mb_free(ifa);
726 }
727
728 static int
729 rip_reconfigure_iface(struct rip_proto *p, struct rip_iface *ifa, struct rip_iface_config *new)
730 {
731 struct rip_iface_config *old = ifa->cf;
732
733 /* Change of these options would require to reset the iface socket */
734 if ((new->mode != old->mode) ||
735 (new->port != old->port) ||
736 (new->tx_tos != old->tx_tos) ||
737 (new->tx_priority != old->tx_priority) ||
738 (new->ttl_security != old->ttl_security) ||
739 (new->demand_circuit != old->demand_circuit))
740 return 0;
741
742 TRACE(D_EVENTS, "Reconfiguring interface %s", ifa->iface->name);
743
744 ifa->cf = new;
745
746 rip_iface_update_buffers(ifa);
747
748 if ((! ifa->cf->demand_circuit) &&
749 (ifa->next_regular > (current_time() + new->update_time)))
750 ifa->next_regular = current_time() + (random() % new->update_time) + 100 MS;
751
752 if (ifa->up && new->demand_circuit && (new->passive != old->passive))
753 {
754 if (new->passive)
755 rip_send_flush(p, ifa);
756 else
757 {
758 rip_send_request(p, ifa);
759 rip_send_table(p, ifa, ifa->addr, 0);
760 }
761 }
762
763 if (new->check_link != old->check_link)
764 rip_iface_update_state(ifa);
765
766 if (new->bfd != old->bfd)
767 rip_iface_update_bfd(ifa);
768
769 if (ifa->up)
770 rip_iface_kick_timer(ifa);
771
772 return 1;
773 }
774
775 static void
776 rip_reconfigure_ifaces(struct rip_proto *p, struct rip_config *cf)
777 {
778 struct iface *iface;
779
780 WALK_LIST(iface, iface_list)
781 {
782 if (!(iface->flags & IF_UP))
783 continue;
784
785 /* Ignore ifaces without appropriate address */
786 if (rip_is_v2(p) ? !iface->addr4 : !iface->llv6)
787 continue;
788
789 struct rip_iface *ifa = rip_find_iface(p, iface);
790 struct rip_iface_config *ic = (void *) iface_patt_find(&cf->patt_list, iface, NULL);
791
792 if (ifa && ic)
793 {
794 if (rip_reconfigure_iface(p, ifa, ic))
795 continue;
796
797 /* Hard restart */
798 log(L_INFO "%s: Restarting interface %s", p->p.name, ifa->iface->name);
799 rip_remove_iface(p, ifa);
800 rip_add_iface(p, iface, ic);
801 }
802
803 if (ifa && !ic)
804 rip_remove_iface(p, ifa);
805
806 if (!ifa && ic)
807 rip_add_iface(p, iface, ic);
808 }
809 }
810
811 static void
812 rip_if_notify(struct proto *P, unsigned flags, struct iface *iface)
813 {
814 struct rip_proto *p = (void *) P;
815 struct rip_config *cf = (void *) P->cf;
816 struct rip_iface *ifa = rip_find_iface(p, iface);
817
818 if (iface->flags & IF_IGNORE)
819 return;
820
821 /* Add, remove or restart interface */
822 if (flags & (IF_CHANGE_UPDOWN | (rip_is_v2(p) ? IF_CHANGE_ADDR4 : IF_CHANGE_LLV6)))
823 {
824 if (ifa)
825 rip_remove_iface(p, ifa);
826
827 if (!(iface->flags & IF_UP))
828 return;
829
830 /* Ignore ifaces without appropriate address */
831 if (rip_is_v2(p) ? !iface->addr4 : !iface->llv6)
832 return;
833
834 struct rip_iface_config *ic = (void *) iface_patt_find(&cf->patt_list, iface, NULL);
835 if (ic)
836 rip_add_iface(p, iface, ic);
837
838 return;
839 }
840
841 if (!ifa)
842 return;
843
844 if (flags & IF_CHANGE_MTU)
845 rip_iface_update_buffers(ifa);
846
847 if (flags & IF_CHANGE_LINK)
848 rip_iface_update_state(ifa);
849 }
850
851
852 /*
853 * RIP timer events
854 */
855
856 /**
857 * rip_timer - RIP main timer hook
858 * @t: timer
859 *
860 * The RIP main timer is responsible for routing table maintenance. Invalid or
861 * expired routes (&rip_rte) are removed and garbage collection of stale routing
862 * table entries (&rip_entry) is done. Changes are propagated to core tables,
863 * route reload is also done here. Note that garbage collection uses a maximal
864 * GC time, while interfaces maintain an illusion of per-interface GC times in
865 * rip_send_response().
866 *
867 * Keeping incoming routes and the selected outgoing route are two independent
868 * functions, therefore after garbage collection some entries now considered
869 * invalid (RIP_ENTRY_DUMMY) still may have non-empty list of incoming routes,
870 * while some valid entries (representing an outgoing route) may have that list
871 * empty.
872 *
873 * The main timer is not scheduled periodically but it uses the time of the
874 * current next event and the minimal interval of any possible event to compute
875 * the time of the next run.
876 */
877 static void
878 rip_timer(timer *t)
879 {
880 struct rip_proto *p = t->data;
881 struct rip_config *cf = (void *) (p->p.cf);
882 struct rip_iface *ifa;
883 struct rip_neighbor *n, *nn;
884 struct fib_iterator fit;
885 btime now_ = current_time();
886 btime next = now_ + MIN(cf->min_timeout_time, cf->max_garbage_time);
887 btime expires = 0;
888
889 TRACE(D_EVENTS, "Main timer fired");
890
891 FIB_ITERATE_INIT(&fit, &p->rtable);
892
893 loop:
894 FIB_ITERATE_START(&p->rtable, &fit, struct rip_entry, en)
895 {
896 struct rip_rte *rt, **rp;
897 int changed = 0;
898
899 /* Checking received routes for timeout and for dead neighbors */
900 for (rp = &en->routes; rt = *rp; /* rp = &rt->next */)
901 {
902 if (!rip_valid_rte(rt) || (rt->expires <= now_))
903 {
904 rip_remove_rte(p, rp);
905 changed = 1;
906 continue;
907 }
908
909 next = MIN(next, rt->expires);
910 rp = &rt->next;
911 }
912
913 /* Propagating eventual change */
914 if (changed || p->rt_reload)
915 {
916 /*
917 * We have to restart the iteration because there may be a cascade of
918 * synchronous events rip_announce_rte() -> nest table change ->
919 * rip_rt_notify() -> p->rtable change, invalidating hidden variables.
920 */
921
922 FIB_ITERATE_PUT_NEXT(&fit, &p->rtable);
923 rip_announce_rte(p, en);
924 goto loop;
925 }
926
927 /* Checking stale entries for garbage collection timeout */
928 if (en->valid == RIP_ENTRY_STALE)
929 {
930 expires = en->changed + cf->max_garbage_time;
931
932 if (expires <= now_)
933 {
934 // TRACE(D_EVENTS, "entry is too old: %N", en->n.addr);
935 en->valid = 0;
936 }
937 else
938 next = MIN(next, expires);
939 }
940
941 /* Remove empty nodes */
942 if (!en->valid && !en->routes)
943 {
944 FIB_ITERATE_PUT(&fit);
945 fib_delete(&p->rtable, en);
946 goto loop;
947 }
948 }
949 FIB_ITERATE_END;
950
951 p->rt_reload = 0;
952
953 /* Handling neighbor expiration */
954 WALK_LIST(ifa, p->iface_list)
955 {
956 /* No expiration for demand circuit ifaces */
957 if (ifa->cf->demand_circuit)
958 continue;
959
960 WALK_LIST_DELSAFE(n, nn, ifa->neigh_list)
961 if (n->last_seen)
962 {
963 expires = n->last_seen + n->ifa->cf->timeout_time;
964
965 if (expires <= now_)
966 rip_remove_neighbor(p, n);
967 else
968 next = MIN(next, expires);
969 }
970 }
971
972 tm_start(p->timer, MAX(next - now_, 100 MS));
973 }
974
975 static inline void
976 rip_kick_timer(struct rip_proto *p)
977 {
978 if ((p->timer->expires > (current_time() + 100 MS)))
979 tm_start(p->timer, 100 MS);
980 }
981
982 /**
983 * rip_iface_timer - RIP interface timer hook
984 * @t: timer
985 *
986 * RIP interface timers are responsible for scheduling both regular and
987 * triggered updates. Fixed, delay-independent period is used for regular
988 * updates, while minimal separating interval is enforced for triggered updates.
989 * The function also ensures that a new update is not started when the old one
990 * is still running.
991 */
992 static void
993 rip_iface_timer(timer *t)
994 {
995 struct rip_iface *ifa = t->data;
996 struct rip_proto *p = ifa->rip;
997 btime now_ = current_time();
998 btime period = ifa->cf->update_time;
999
1000 if (ifa->cf->passive)
1001 return;
1002
1003 TRACE(D_EVENTS, "Interface timer fired for %s", ifa->iface->name);
1004
1005 if (ifa->tx_active)
1006 {
1007 tm_start(ifa->timer, 100 MS);
1008 return;
1009 }
1010
1011 if (now_ >= ifa->next_regular)
1012 {
1013 /* Send regular update, set timer for next period (or following one if necessay) */
1014 TRACE(D_EVENTS, "Sending regular updates for %s", ifa->iface->name);
1015 rip_send_table(p, ifa, ifa->addr, 0);
1016 ifa->next_regular += period * (1 + ((now_ - ifa->next_regular) / period));
1017 ifa->want_triggered = 0;
1018 p->triggered = 0;
1019 }
1020 else if (ifa->want_triggered && (now_ >= ifa->next_triggered))
1021 {
1022 /* Send triggered update, enforce interval between triggered updates */
1023 TRACE(D_EVENTS, "Sending triggered updates for %s", ifa->iface->name);
1024 rip_send_table(p, ifa, ifa->addr, ifa->want_triggered);
1025 ifa->next_triggered = now_ + MIN(5 S, period / 2);
1026 ifa->want_triggered = 0;
1027 p->triggered = 0;
1028 }
1029
1030 if (ifa->want_triggered && (ifa->next_triggered < ifa->next_regular))
1031 tm_set(ifa->timer, ifa->next_triggered);
1032 else if (ifa->next_regular != TIME_INFINITY)
1033 tm_set(ifa->timer, ifa->next_regular);
1034 }
1035
1036
1037 static inline void
1038 rip_iface_kick_timer(struct rip_iface *ifa)
1039 {
1040 if ((! tm_active(ifa->timer)) || (ifa->timer->expires > (current_time() + 100 MS)))
1041 tm_start(ifa->timer, 100 MS);
1042 }
1043
1044 static void
1045 rip_trigger_update(struct rip_proto *p)
1046 {
1047 if (p->triggered)
1048 return;
1049
1050 struct rip_iface *ifa;
1051 WALK_LIST(ifa, p->iface_list)
1052 {
1053 /* Interface not active */
1054 if (! ifa->up)
1055 continue;
1056
1057 /* Already scheduled */
1058 if (ifa->want_triggered)
1059 continue;
1060
1061 TRACE(D_EVENTS, "Scheduling triggered updates for %s", ifa->iface->name);
1062 ifa->want_triggered = current_time();
1063 rip_iface_kick_timer(ifa);
1064 p->triggered = 1;
1065 }
1066 }
1067
1068
1069 /*
1070 * RIP protocol glue
1071 */
1072
1073 static void
1074 rip_reload_routes(struct channel *C)
1075 {
1076 struct rip_proto *p = (struct rip_proto *) C->proto;
1077
1078 if (p->rt_reload)
1079 return;
1080
1081 TRACE(D_EVENTS, "Scheduling route reload");
1082 p->rt_reload = 1;
1083 rip_kick_timer(p);
1084 }
1085
1086 static int
1087 rip_rte_better(struct rte *new, struct rte *old)
1088 {
1089 ASSERT_DIE(new->src == old->src);
1090 struct rip_proto *p = (struct rip_proto *) new->src->proto;
1091
1092 u32 new_metric = ea_get_int(new->attrs->eattrs, EA_RIP_METRIC, p->infinity);
1093 u32 old_metric = ea_get_int(old->attrs->eattrs, EA_RIP_METRIC, p->infinity);
1094
1095 return new_metric < old_metric;
1096 }
1097
1098 static u32
1099 rip_rte_igp_metric(struct rte *rt)
1100 {
1101 return ea_get_int(rt->attrs->eattrs, EA_RIP_METRIC, IGP_METRIC_UNKNOWN);
1102 }
1103
1104 static void
1105 rip_postconfig(struct proto_config *CF)
1106 {
1107 // struct rip_config *cf = (void *) CF;
1108
1109 /* Define default channel */
1110 if (! proto_cf_main_channel(CF))
1111 channel_config_new(NULL, net_label[CF->net_type], CF->net_type, CF);
1112 }
1113
1114 static struct proto *
1115 rip_init(struct proto_config *CF)
1116 {
1117 struct proto *P = proto_new(CF);
1118
1119 P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF));
1120
1121 P->if_notify = rip_if_notify;
1122 P->rt_notify = rip_rt_notify;
1123 P->neigh_notify = rip_neigh_notify;
1124 P->reload_routes = rip_reload_routes;
1125 P->rte_better = rip_rte_better;
1126 P->rte_igp_metric = rip_rte_igp_metric;
1127
1128 return P;
1129 }
1130
1131 static int
1132 rip_start(struct proto *P)
1133 {
1134 struct rip_proto *p = (void *) P;
1135 struct rip_config *cf = (void *) (P->cf);
1136
1137 init_list(&p->iface_list);
1138 fib_init(&p->rtable, P->pool, cf->rip2 ? NET_IP4 : NET_IP6,
1139 sizeof(struct rip_entry), OFFSETOF(struct rip_entry, n), 0, NULL);
1140 p->rte_slab = sl_new(P->pool, sizeof(struct rip_rte));
1141 p->timer = tm_new_init(P->pool, rip_timer, p, 0, 0);
1142
1143 p->rip2 = cf->rip2;
1144 p->ecmp = cf->ecmp;
1145 p->infinity = cf->infinity;
1146 p->triggered = 0;
1147
1148 p->log_pkt_tbf = (struct tbf){ .rate = 1, .burst = 5 };
1149 p->log_rte_tbf = (struct tbf){ .rate = 4, .burst = 20 };
1150
1151 tm_start(p->timer, MIN(cf->min_timeout_time, cf->max_garbage_time));
1152
1153 return PS_UP;
1154 }
1155
1156 static int
1157 rip_shutdown(struct proto *P)
1158 {
1159 struct rip_proto *p = (void *) P;
1160
1161 TRACE(D_EVENTS, "Shutdown requested");
1162
1163 struct rip_iface *ifa;
1164 WALK_LIST(ifa, p->iface_list)
1165 rip_iface_stop(ifa);
1166
1167 return PS_DOWN;
1168 }
1169
1170 static int
1171 rip_reconfigure(struct proto *P, struct proto_config *CF)
1172 {
1173 struct rip_proto *p = (void *) P;
1174 struct rip_config *new = (void *) CF;
1175 // struct rip_config *old = (void *) (P->cf);
1176
1177 if (new->rip2 != p->rip2)
1178 return 0;
1179
1180 if (new->infinity != p->infinity)
1181 return 0;
1182
1183 if (!proto_configure_channel(P, &P->main_channel, proto_cf_main_channel(CF)))
1184 return 0;
1185
1186 TRACE(D_EVENTS, "Reconfiguring");
1187
1188 p->p.cf = CF;
1189 p->ecmp = new->ecmp;
1190 rip_reconfigure_ifaces(p, new);
1191
1192 p->rt_reload = 1;
1193 rip_kick_timer(p);
1194
1195 return 1;
1196 }
1197
1198 static void
1199 rip_get_route_info(rte *rte, byte *buf)
1200 {
1201 struct rip_proto *p = (struct rip_proto *) rte->src->proto;
1202 u32 rt_metric = ea_get_int(rte->attrs->eattrs, EA_RIP_METRIC, p->infinity);
1203 u32 rt_tag = ea_get_int(rte->attrs->eattrs, EA_RIP_TAG, 0);
1204
1205 buf += bsprintf(buf, " (%d/%d)", rte->attrs->pref, rt_metric);
1206
1207 if (rt_tag)
1208 bsprintf(buf, " [%04x]", rt_tag);
1209 }
1210
1211 static int
1212 rip_get_attr(const eattr *a, byte *buf, int buflen UNUSED)
1213 {
1214 switch (a->id)
1215 {
1216 case EA_RIP_METRIC:
1217 bsprintf(buf, "metric: %d", a->u.data);
1218 return GA_FULL;
1219
1220 case EA_RIP_TAG:
1221 bsprintf(buf, "tag: %04x", a->u.data);
1222 return GA_FULL;
1223
1224 default:
1225 return GA_UNKNOWN;
1226 }
1227 }
1228
1229 void
1230 rip_show_interfaces(struct proto *P, const char *iff)
1231 {
1232 struct rip_proto *p = (void *) P;
1233 struct rip_iface *ifa = NULL;
1234 struct rip_neighbor *n = NULL;
1235
1236 if (p->p.proto_state != PS_UP)
1237 {
1238 cli_msg(-1021, "%s: is not up", p->p.name);
1239 return;
1240 }
1241
1242 cli_msg(-1021, "%s:", p->p.name);
1243 cli_msg(-1021, "%-10s %-6s %6s %6s %7s",
1244 "Interface", "State", "Metric", "Nbrs", "Timer");
1245
1246 WALK_LIST(ifa, p->iface_list)
1247 {
1248 if (iff && !patmatch(iff, ifa->iface->name))
1249 continue;
1250
1251 int nbrs = 0;
1252 WALK_LIST(n, ifa->neigh_list)
1253 if (n->last_seen)
1254 nbrs++;
1255
1256 btime now_ = current_time();
1257 btime timer = ((ifa->next_regular < TIME_INFINITY) && (ifa->next_regular > now_)) ?
1258 (ifa->next_regular - now_) : 0;
1259 cli_msg(-1021, "%-10s %-6s %6u %6u %7t",
1260 ifa->iface->name, (ifa->up ? "Up" : "Down"), ifa->cf->metric, nbrs, timer);
1261 }
1262 }
1263
1264 void
1265 rip_show_neighbors(struct proto *P, const char *iff)
1266 {
1267 struct rip_proto *p = (void *) P;
1268 struct rip_iface *ifa = NULL;
1269 struct rip_neighbor *n = NULL;
1270
1271 if (p->p.proto_state != PS_UP)
1272 {
1273 cli_msg(-1022, "%s: is not up", p->p.name);
1274 return;
1275 }
1276
1277 cli_msg(-1022, "%s:", p->p.name);
1278 cli_msg(-1022, "%-25s %-10s %6s %6s %7s",
1279 "IP address", "Interface", "Metric", "Routes", "Seen");
1280
1281 WALK_LIST(ifa, p->iface_list)
1282 {
1283 if (iff && !patmatch(iff, ifa->iface->name))
1284 continue;
1285
1286 WALK_LIST(n, ifa->neigh_list)
1287 {
1288 if (!n->last_seen)
1289 continue;
1290
1291 btime timer = current_time() - n->last_seen;
1292 cli_msg(-1022, "%-25I %-10s %6u %6u %7t",
1293 n->nbr->addr, ifa->iface->name, ifa->cf->metric, n->uc, timer);
1294 }
1295 }
1296 }
1297
1298 static void
1299 rip_dump(struct proto *P)
1300 {
1301 struct rip_proto *p = (struct rip_proto *) P;
1302 struct rip_iface *ifa;
1303 int i;
1304
1305 i = 0;
1306 FIB_WALK(&p->rtable, struct rip_entry, en)
1307 {
1308 debug("RIP: entry #%d: %N via %I dev %s valid %d metric %d age %t\n",
1309 i++, en->n.addr, en->next_hop, en->iface ? en->iface->name : "(null)",
1310 en->valid, en->metric, current_time() - en->changed);
1311
1312 for (struct rip_rte *e = en->routes; e; e = e->next)
1313 debug("RIP: via %I metric %d expires %t\n",
1314 e->next_hop, e->metric, e->expires - current_time());
1315 }
1316 FIB_WALK_END;
1317
1318 i = 0;
1319 WALK_LIST(ifa, p->iface_list)
1320 {
1321 debug("RIP: interface #%d: %s, %I, up = %d, busy = %d\n",
1322 i++, ifa->iface->name, ifa->sk ? ifa->sk->daddr : IPA_NONE,
1323 ifa->up, ifa->tx_active);
1324 }
1325 }
1326
1327
1328 struct protocol proto_rip = {
1329 .name = "RIP",
1330 .template = "rip%d",
1331 .class = PROTOCOL_RIP,
1332 .preference = DEF_PREF_RIP,
1333 .channel_mask = NB_IP,
1334 .proto_size = sizeof(struct rip_proto),
1335 .config_size = sizeof(struct rip_config),
1336 .postconfig = rip_postconfig,
1337 .init = rip_init,
1338 .dump = rip_dump,
1339 .start = rip_start,
1340 .shutdown = rip_shutdown,
1341 .reconfigure = rip_reconfigure,
1342 .get_route_info = rip_get_route_info,
1343 .get_attr = rip_get_attr
1344 };