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