]>
git.ipfire.org Git - thirdparty/bird.git/blob - proto/rip/rip.c
2 * BIRD -- Routing Information Protocol (RIP)
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.
9 * Can be freely distributed and used under the terms of the GNU GPL.
13 * DOC: Routing Information Protocol (RIP)
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.
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.
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).
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().
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.
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.
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.
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.
71 * Supported standards:
75 * - RFC 4822 - RIP cryptographic authentication
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
);
96 rip_init_entry(struct fib_node
*fn
)
98 // struct rip_entry *en = (void) *fn;
100 const uint offset
= OFFSETOF(struct rip_entry
, routes
);
101 memset((byte
*)fn
+ offset
, 0, sizeof(struct rip_entry
) - offset
);
104 static struct rip_rte
*
105 rip_add_rte(struct rip_proto
*p
, struct rip_rte
**rp
, struct rip_rte
*src
)
107 struct rip_rte
*rt
= sl_alloc(p
->rte_slab
);
109 memcpy(rt
, src
, sizeof(struct rip_rte
));
113 rip_lock_neighbor(rt
->from
);
119 rip_remove_rte(struct rip_proto
*p
, struct rip_rte
**rp
)
121 struct rip_rte
*rt
= *rp
;
123 rip_unlock_neighbor(rt
->from
);
126 sl_free(p
->rte_slab
, rt
);
129 static inline int rip_same_rte(struct rip_rte
*a
, struct rip_rte
*b
)
130 { return a
->metric
== b
->metric
&& a
->tag
== b
->tag
&& ipa_equal(a
->next_hop
, b
->next_hop
); }
132 static inline int rip_valid_rte(struct rip_rte
*rt
)
133 { return rt
->from
->ifa
!= NULL
; }
136 * rip_announce_rte - announce route from RIP routing table to the core
138 * @en: related network
140 * The function takes a list of incoming routes from @en, prepare appropriate
141 * &rte for the core and propagate it by rte_update().
144 rip_announce_rte(struct rip_proto
*p
, struct rip_entry
*en
)
146 struct rip_rte
*rt
= en
->routes
;
148 /* Find first valid rte */
149 while (rt
&& !rip_valid_rte(rt
))
155 net
*n
= net_get(p
->p
.table
, en
->n
.prefix
, en
->n
.pxlen
);
158 .src
= p
->p
.main_source
,
160 .scope
= SCOPE_UNIVERSE
,
164 u8 rt_metric
= rt
->metric
;
165 u16 rt_tag
= rt
->tag
;
166 struct rip_rte
*rt2
= rt
->next
;
168 /* Find second valid rte */
169 while (rt2
&& !rip_valid_rte(rt2
))
175 struct mpnh
*nhs
= NULL
;
178 for (rt
= en
->routes
; rt
&& (num
< p
->ecmp
); rt
= rt
->next
)
180 if (!rip_valid_rte(rt
))
183 struct mpnh
*nh
= alloca(sizeof(struct mpnh
));
184 nh
->gw
= rt
->next_hop
;
185 nh
->iface
= rt
->from
->nbr
->iface
;
186 nh
->weight
= rt
->from
->ifa
->cf
->ecmp_weight
;
187 mpnh_insert(&nhs
, nh
);
190 if (rt
->tag
!= rt_tag
)
194 a0
.dest
= RTD_MULTIPATH
;
200 a0
.dest
= RTD_ROUTER
;
201 a0
.gw
= rt
->next_hop
;
202 a0
.iface
= rt
->from
->nbr
->iface
;
203 a0
.from
= rt
->from
->nbr
->addr
;
206 rta
*a
= rta_lookup(&a0
);
207 rte
*e
= rte_get_temp(a
);
209 e
->u
.rip
.from
= a0
.iface
;
210 e
->u
.rip
.metric
= rt_metric
;
211 e
->u
.rip
.tag
= rt_tag
;
216 rte_update(&p
->p
, n
, e
);
221 net
*n
= net_find(p
->p
.table
, en
->n
.prefix
, en
->n
.pxlen
);
222 rte_update(&p
->p
, n
, NULL
);
227 * rip_update_rte - enter a route update to RIP routing table
229 * @prefix: network prefix
230 * @pxlen: network prefix length
231 * @new: a &rip_rte representing the new route
233 * The function is called by the RIP packet processing code whenever it receives
234 * a reachable route. The appropriate routing table entry is found and the list
235 * of incoming routes is updated. Eventually, the change is also propagated to
236 * the core by rip_announce_rte(). Note that for unreachable routes,
237 * rip_withdraw_rte() should be called instead of rip_update_rte().
240 rip_update_rte(struct rip_proto
*p
, ip_addr
*prefix
, int pxlen
, struct rip_rte
*new)
242 struct rip_entry
*en
= fib_get(&p
->rtable
, prefix
, pxlen
);
243 struct rip_rte
*rt
, **rp
;
246 /* If the new route is better, remove all current routes */
247 if (en
->routes
&& new->metric
< en
->routes
->metric
)
249 rip_remove_rte(p
, &en
->routes
);
251 /* Find the old route (also set rp for later) */
252 for (rp
= &en
->routes
; rt
= *rp
; rp
= &rt
->next
)
253 if (rt
->from
== new->from
)
255 if (rip_same_rte(rt
, new))
257 rt
->expires
= new->expires
;
261 /* Remove the old route */
262 rip_remove_rte(p
, rp
);
267 /* If the new route is optimal, add it to the list */
268 if (!en
->routes
|| new->metric
== en
->routes
->metric
)
270 rt
= rip_add_rte(p
, rp
, new);
274 /* Announce change if on relevant position (the first or any for ECMP) */
275 if (changed
&& (rp
== &en
->routes
|| p
->ecmp
))
276 rip_announce_rte(p
, en
);
280 * rip_withdraw_rte - enter a route withdraw to RIP routing table
282 * @prefix: network prefix
283 * @pxlen: network prefix length
284 * @from: a &rip_neighbor propagating the withdraw
286 * The function is called by the RIP packet processing code whenever it receives
287 * an unreachable route. The incoming route for given network from nbr @from is
288 * removed. Eventually, the change is also propagated by rip_announce_rte().
291 rip_withdraw_rte(struct rip_proto
*p
, ip_addr
*prefix
, int pxlen
, struct rip_neighbor
*from
)
293 struct rip_entry
*en
= fib_find(&p
->rtable
, prefix
, pxlen
);
294 struct rip_rte
*rt
, **rp
;
299 /* Find the old route */
300 for (rp
= &en
->routes
; rt
= *rp
; rp
= &rt
->next
)
301 if (rt
->from
== from
)
307 /* Remove the old route */
308 rip_remove_rte(p
, rp
);
310 /* Announce change if on relevant position */
311 if (rp
== &en
->routes
|| p
->ecmp
)
312 rip_announce_rte(p
, en
);
316 * rip_rt_notify - core tells us about new route, so store
317 * it into our data structures.
320 rip_rt_notify(struct proto
*P
, struct rtable
*table UNUSED
, struct network
*net
, struct rte
*new,
321 struct rte
*old UNUSED
, struct ea_list
*attrs
)
323 struct rip_proto
*p
= (struct rip_proto
*) P
;
324 struct rip_entry
*en
;
330 u32 rt_metric
= ea_get_int(attrs
, EA_RIP_METRIC
, 1);
331 u32 rt_tag
= ea_get_int(attrs
, EA_RIP_TAG
, 0);
333 if (rt_metric
> p
->infinity
)
335 log(L_WARN
"%s: Invalid rip_metric value %u for route %I/%d",
336 p
->p
.name
, rt_metric
, net
->n
.prefix
, net
->n
.pxlen
);
337 rt_metric
= p
->infinity
;
342 log(L_WARN
"%s: Invalid rip_tag value %u for route %I/%d",
343 p
->p
.name
, rt_tag
, net
->n
.prefix
, net
->n
.pxlen
);
344 rt_metric
= p
->infinity
;
349 * Note that we accept exported routes with infinity metric (this could
350 * happen if rip_metric is modified in filters). Such entry has infinity
351 * metric but is RIP_ENTRY_VALID and therefore is not subject to garbage
355 en
= fib_get(&p
->rtable
, &net
->n
.prefix
, net
->n
.pxlen
);
357 old_metric
= en
->valid
? en
->metric
: -1;
359 en
->valid
= RIP_ENTRY_VALID
;
360 en
->metric
= rt_metric
;
362 en
->from
= (new->attrs
->src
->proto
== P
) ? new->u
.rip
.from
: NULL
;
363 en
->iface
= new->attrs
->iface
;
364 en
->next_hop
= new->attrs
->gw
;
369 en
= fib_find(&p
->rtable
, &net
->n
.prefix
, net
->n
.pxlen
);
371 if (!en
|| en
->valid
!= RIP_ENTRY_VALID
)
374 old_metric
= en
->metric
;
376 en
->valid
= RIP_ENTRY_STALE
;
377 en
->metric
= p
->infinity
;
381 en
->next_hop
= IPA_NONE
;
384 /* Activate triggered updates */
385 if (en
->metric
!= old_metric
)
388 rip_trigger_update(p
);
397 struct rip_neighbor
*
398 rip_get_neighbor(struct rip_proto
*p
, ip_addr
*a
, struct rip_iface
*ifa
)
400 neighbor
*nbr
= neigh_find2(&p
->p
, a
, ifa
->iface
, 0);
402 if (!nbr
|| (nbr
->scope
== SCOPE_HOST
) || !rip_iface_link_up(ifa
))
408 TRACE(D_EVENTS
, "New neighbor %I on %s", *a
, ifa
->iface
->name
);
410 struct rip_neighbor
*n
= mb_allocz(p
->p
.pool
, sizeof(struct rip_neighbor
));
416 add_tail(&ifa
->neigh_list
, NODE n
);
422 rip_remove_neighbor(struct rip_proto
*p
, struct rip_neighbor
*n
)
424 neighbor
*nbr
= n
->nbr
;
426 TRACE(D_EVENTS
, "Removing neighbor %I on %s", nbr
->addr
, nbr
->iface
->name
);
441 /* Related routes are removed in rip_timer() */
446 rip_lock_neighbor(struct rip_neighbor
*n
)
452 rip_unlock_neighbor(struct rip_neighbor
*n
)
456 if (!n
->nbr
&& !n
->uc
)
461 rip_neigh_notify(struct neighbor
*nbr
)
463 struct rip_proto
*p
= (struct rip_proto
*) nbr
->proto
;
464 struct rip_neighbor
*n
= nbr
->data
;
470 * We assume that rip_neigh_notify() is called before rip_if_notify() for
471 * IF_CHANGE_DOWN and therefore n->ifa is still valid. We have no such
472 * ordering assumption for IF_CHANGE_LINK, so we test link state of the
473 * underlying iface instead of just rip_iface state.
475 if ((nbr
->scope
<= 0) || !rip_iface_link_up(n
->ifa
))
476 rip_remove_neighbor(p
, n
);
480 rip_bfd_notify(struct bfd_request
*req
)
482 struct rip_neighbor
*n
= req
->data
;
483 struct rip_proto
*p
= n
->ifa
->rip
;
487 TRACE(D_EVENTS
, "BFD session down for nbr %I on %s",
488 n
->nbr
->addr
, n
->ifa
->iface
->name
);
489 rip_remove_neighbor(p
, n
);
494 rip_update_bfd(struct rip_proto
*p
, struct rip_neighbor
*n
)
496 int use_bfd
= n
->ifa
->cf
->bfd
&& n
->last_seen
;
498 if (use_bfd
&& !n
->bfd_req
)
501 * For RIPv2, use the same address as rip_open_socket(). For RIPng, neighbor
502 * should contain an address from the same prefix, thus also link-local. It
503 * may cause problems if two link-local addresses are assigned to one iface.
505 ip_addr saddr
= rip_is_v2(p
) ? n
->ifa
->sk
->saddr
: n
->nbr
->ifa
->ip
;
506 n
->bfd_req
= bfd_request_session(p
->p
.pool
, n
->nbr
->addr
, saddr
,
507 n
->nbr
->iface
, rip_bfd_notify
, n
);
510 if (!use_bfd
&& n
->bfd_req
)
523 rip_iface_start(struct rip_iface
*ifa
)
525 struct rip_proto
*p
= ifa
->rip
;
527 TRACE(D_EVENTS
, "Starting interface %s", ifa
->iface
->name
);
529 ifa
->next_regular
= now
+ (random() % ifa
->cf
->update_time
) + 1;
530 ifa
->next_triggered
= now
; /* Available immediately */
531 ifa
->want_triggered
= 1; /* All routes in triggered update */
532 tm_start(ifa
->timer
, 1); /* Or 100 ms */
535 if (!ifa
->cf
->passive
)
536 rip_send_request(ifa
->rip
, ifa
);
540 rip_iface_stop(struct rip_iface
*ifa
)
542 struct rip_proto
*p
= ifa
->rip
;
543 struct rip_neighbor
*n
;
545 TRACE(D_EVENTS
, "Stopping interface %s", ifa
->iface
->name
);
547 rip_reset_tx_session(p
, ifa
);
549 WALK_LIST_FIRST(n
, ifa
->neigh_list
)
550 rip_remove_neighbor(p
, n
);
557 rip_iface_link_up(struct rip_iface
*ifa
)
559 return !ifa
->cf
->check_link
|| (ifa
->iface
->flags
& IF_LINK_UP
);
563 rip_iface_update_state(struct rip_iface
*ifa
)
565 int up
= ifa
->sk
&& rip_iface_link_up(ifa
);
571 rip_iface_start(ifa
);
577 rip_iface_update_buffers(struct rip_iface
*ifa
)
582 uint rbsize
= ifa
->cf
->rx_buffer
?: ifa
->iface
->mtu
;
583 uint tbsize
= ifa
->cf
->tx_length
?: ifa
->iface
->mtu
;
584 rbsize
= MAX(rbsize
, tbsize
);
586 sk_set_rbsize(ifa
->sk
, rbsize
);
587 sk_set_tbsize(ifa
->sk
, tbsize
);
589 uint headers
= (rip_is_v2(ifa
->rip
) ? IP4_HEADER_LENGTH
: IP6_HEADER_LENGTH
) + UDP_HEADER_LENGTH
;
590 ifa
->tx_plen
= tbsize
- headers
;
592 if (ifa
->cf
->auth_type
== RIP_AUTH_CRYPTO
)
593 ifa
->tx_plen
-= RIP_AUTH_TAIL_LENGTH
+ max_mac_length(ifa
->cf
->passwords
);
597 rip_iface_update_bfd(struct rip_iface
*ifa
)
599 struct rip_proto
*p
= ifa
->rip
;
600 struct rip_neighbor
*n
;
602 WALK_LIST(n
, ifa
->neigh_list
)
603 rip_update_bfd(p
, n
);
608 rip_iface_locked(struct object_lock
*lock
)
610 struct rip_iface
*ifa
= lock
->data
;
611 struct rip_proto
*p
= ifa
->rip
;
613 if (!rip_open_socket(ifa
))
615 log(L_ERR
"%s: Cannot open socket for %s", p
->p
.name
, ifa
->iface
->name
);
619 rip_iface_update_buffers(ifa
);
620 rip_iface_update_state(ifa
);
624 static struct rip_iface
*
625 rip_find_iface(struct rip_proto
*p
, struct iface
*what
)
627 struct rip_iface
*ifa
;
629 WALK_LIST(ifa
, p
->iface_list
)
630 if (ifa
->iface
== what
)
637 rip_add_iface(struct rip_proto
*p
, struct iface
*iface
, struct rip_iface_config
*ic
)
639 struct rip_iface
*ifa
;
641 TRACE(D_EVENTS
, "Adding interface %s", iface
->name
);
643 ifa
= mb_allocz(p
->p
.pool
, sizeof(struct rip_iface
));
648 if (ipa_nonzero(ic
->address
))
649 ifa
->addr
= ic
->address
;
650 else if (ic
->mode
== RIP_IM_MULTICAST
)
651 ifa
->addr
= rip_is_v2(p
) ? IP4_RIP_ROUTERS
: IP6_RIP_ROUTERS
;
653 ifa
->addr
= iface
->addr
->brd
;
655 init_list(&ifa
->neigh_list
);
657 add_tail(&p
->iface_list
, NODE ifa
);
659 ifa
->timer
= tm_new_set(p
->p
.pool
, rip_iface_timer
, ifa
, 0, 0);
661 struct object_lock
*lock
= olock_new(p
->p
.pool
);
662 lock
->type
= OBJLOCK_UDP
;
663 lock
->port
= ic
->port
;
666 lock
->hook
= rip_iface_locked
;
673 rip_remove_iface(struct rip_proto
*p
, struct rip_iface
*ifa
)
677 TRACE(D_EVENTS
, "Removing interface %s", ifa
->iface
->name
);
689 rip_reconfigure_iface(struct rip_proto
*p
, struct rip_iface
*ifa
, struct rip_iface_config
*new)
691 struct rip_iface_config
*old
= ifa
->cf
;
693 /* Change of these options would require to reset the iface socket */
694 if ((new->mode
!= old
->mode
) ||
695 (new->port
!= old
->port
) ||
696 (new->tx_tos
!= old
->tx_tos
) ||
697 (new->tx_priority
!= old
->tx_priority
) ||
698 (new->ttl_security
!= old
->ttl_security
))
701 TRACE(D_EVENTS
, "Reconfiguring interface %s", ifa
->iface
->name
);
705 rip_iface_update_buffers(ifa
);
707 if (ifa
->next_regular
> (now
+ new->update_time
))
708 ifa
->next_regular
= now
+ (random() % new->update_time
) + 1;
710 if (new->check_link
!= old
->check_link
)
711 rip_iface_update_state(ifa
);
713 if (new->bfd
!= old
->bfd
)
714 rip_iface_update_bfd(ifa
);
717 rip_iface_kick_timer(ifa
);
723 rip_reconfigure_ifaces(struct rip_proto
*p
, struct rip_config
*cf
)
727 WALK_LIST(iface
, iface_list
)
729 if (! (iface
->flags
& IF_UP
))
732 struct rip_iface
*ifa
= rip_find_iface(p
, iface
);
733 struct rip_iface_config
*ic
= (void *) iface_patt_find(&cf
->patt_list
, iface
, NULL
);
737 if (rip_reconfigure_iface(p
, ifa
, ic
))
741 log(L_INFO
"%s: Restarting interface %s", p
->p
.name
, ifa
->iface
->name
);
742 rip_remove_iface(p
, ifa
);
743 rip_add_iface(p
, iface
, ic
);
747 rip_remove_iface(p
, ifa
);
750 rip_add_iface(p
, iface
, ic
);
755 rip_if_notify(struct proto
*P
, unsigned flags
, struct iface
*iface
)
757 struct rip_proto
*p
= (void *) P
;
758 struct rip_config
*cf
= (void *) P
->cf
;
760 if (iface
->flags
& IF_IGNORE
)
763 if (flags
& IF_CHANGE_UP
)
765 struct rip_iface_config
*ic
= (void *) iface_patt_find(&cf
->patt_list
, iface
, NULL
);
768 rip_add_iface(p
, iface
, ic
);
773 struct rip_iface
*ifa
= rip_find_iface(p
, iface
);
778 if (flags
& IF_CHANGE_DOWN
)
780 rip_remove_iface(p
, ifa
);
784 if (flags
& IF_CHANGE_MTU
)
785 rip_iface_update_buffers(ifa
);
787 if (flags
& IF_CHANGE_LINK
)
788 rip_iface_update_state(ifa
);
797 * rip_timer - RIP main timer hook
800 * The RIP main timer is responsible for routing table maintenance. Invalid or
801 * expired routes (&rip_rte) are removed and garbage collection of stale routing
802 * table entries (&rip_entry) is done. Changes are propagated to core tables,
803 * route reload is also done here. Note that garbage collection uses a maximal
804 * GC time, while interfaces maintain an illusion of per-interface GC times in
805 * rip_send_response().
807 * Keeping incoming routes and the selected outgoing route are two independent
808 * functions, therefore after garbage collection some entries now considered
809 * invalid (RIP_ENTRY_DUMMY) still may have non-empty list of incoming routes,
810 * while some valid entries (representing an outgoing route) may have that list
813 * The main timer is not scheduled periodically but it uses the time of the
814 * current next event and the minimal interval of any possible event to compute
815 * the time of the next run.
820 struct rip_proto
*p
= t
->data
;
821 struct rip_config
*cf
= (void *) (p
->p
.cf
);
822 struct rip_iface
*ifa
;
823 struct rip_neighbor
*n
, *nn
;
824 struct fib_iterator fit
;
825 bird_clock_t next
= now
+ MIN(cf
->min_timeout_time
, cf
->max_garbage_time
);
826 bird_clock_t expires
= 0;
828 TRACE(D_EVENTS
, "Main timer fired");
830 FIB_ITERATE_INIT(&fit
, &p
->rtable
);
833 FIB_ITERATE_START(&p
->rtable
, &fit
, node
)
835 struct rip_entry
*en
= (struct rip_entry
*) node
;
836 struct rip_rte
*rt
, **rp
;
839 /* Checking received routes for timeout and for dead neighbors */
840 for (rp
= &en
->routes
; rt
= *rp
; /* rp = &rt->next */)
842 if (!rip_valid_rte(rt
) || (rt
->expires
<= now
))
844 rip_remove_rte(p
, rp
);
849 next
= MIN(next
, rt
->expires
);
853 /* Propagating eventual change */
854 if (changed
|| p
->rt_reload
)
857 * We have to restart the iteration because there may be a cascade of
858 * synchronous events rip_announce_rte() -> nest table change ->
859 * rip_rt_notify() -> p->rtable change, invalidating hidden variables.
862 FIB_ITERATE_PUT_NEXT(&fit
, &p
->rtable
, node
);
863 rip_announce_rte(p
, en
);
867 /* Checking stale entries for garbage collection timeout */
868 if (en
->valid
== RIP_ENTRY_STALE
)
870 expires
= en
->changed
+ cf
->max_garbage_time
;
874 // TRACE(D_EVENTS, "entry is too old: %I/%d", en->n.prefix, en->n.pxlen);
878 next
= MIN(next
, expires
);
881 /* Remove empty nodes */
882 if (!en
->valid
&& !en
->routes
)
884 FIB_ITERATE_PUT(&fit
, node
);
885 fib_delete(&p
->rtable
, node
);
889 FIB_ITERATE_END(node
);
893 /* Handling neighbor expiration */
894 WALK_LIST(ifa
, p
->iface_list
)
895 WALK_LIST_DELSAFE(n
, nn
, ifa
->neigh_list
)
898 expires
= n
->last_seen
+ n
->ifa
->cf
->timeout_time
;
901 rip_remove_neighbor(p
, n
);
903 next
= MIN(next
, expires
);
906 tm_start(p
->timer
, MAX(next
- now
, 1));
910 rip_kick_timer(struct rip_proto
*p
)
912 if (p
->timer
->expires
> (now
+ 1))
913 tm_start(p
->timer
, 1); /* Or 100 ms */
917 * rip_iface_timer - RIP interface timer hook
920 * RIP interface timers are responsible for scheduling both regular and
921 * triggered updates. Fixed, delay-independent period is used for regular
922 * updates, while minimal separating interval is enforced for triggered updates.
923 * The function also ensures that a new update is not started when the old one
927 rip_iface_timer(timer
*t
)
929 struct rip_iface
*ifa
= t
->data
;
930 struct rip_proto
*p
= ifa
->rip
;
931 bird_clock_t period
= ifa
->cf
->update_time
;
933 if (ifa
->cf
->passive
)
936 TRACE(D_EVENTS
, "Interface timer fired for %s", ifa
->iface
->name
);
940 if (now
< (ifa
->next_regular
+ period
))
941 { tm_start(ifa
->timer
, 1); return; }
943 /* We are too late, reset is done by rip_send_table() */
944 log(L_WARN
"%s: Too slow update on %s, resetting", p
->p
.name
, ifa
->iface
->name
);
947 if (now
>= ifa
->next_regular
)
949 /* Send regular update, set timer for next period (or following one if necessay) */
950 TRACE(D_EVENTS
, "Sending regular updates for %s", ifa
->iface
->name
);
951 rip_send_table(p
, ifa
, ifa
->addr
, 0);
952 ifa
->next_regular
+= period
* (1 + ((now
- ifa
->next_regular
) / period
));
953 ifa
->want_triggered
= 0;
956 else if (ifa
->want_triggered
&& (now
>= ifa
->next_triggered
))
958 /* Send triggered update, enforce interval between triggered updates */
959 TRACE(D_EVENTS
, "Sending triggered updates for %s", ifa
->iface
->name
);
960 rip_send_table(p
, ifa
, ifa
->addr
, ifa
->want_triggered
);
961 ifa
->next_triggered
= now
+ MIN(5, period
/ 2 + 1);
962 ifa
->want_triggered
= 0;
966 tm_start(ifa
->timer
, ifa
->want_triggered
? 1 : (ifa
->next_regular
- now
));
970 rip_iface_kick_timer(struct rip_iface
*ifa
)
972 if (ifa
->timer
->expires
> (now
+ 1))
973 tm_start(ifa
->timer
, 1); /* Or 100 ms */
977 rip_trigger_update(struct rip_proto
*p
)
982 struct rip_iface
*ifa
;
983 WALK_LIST(ifa
, p
->iface_list
)
985 /* Interface not active */
989 /* Already scheduled */
990 if (ifa
->want_triggered
)
993 TRACE(D_EVENTS
, "Scheduling triggered updates for %s", ifa
->iface
->name
);
994 ifa
->want_triggered
= now
;
995 rip_iface_kick_timer(ifa
);
1006 static struct ea_list
*
1007 rip_prepare_attrs(struct linpool
*pool
, ea_list
*next
, u8 metric
, u16 tag
)
1009 struct ea_list
*l
= lp_alloc(pool
, sizeof(struct ea_list
) + 2 * sizeof(eattr
));
1012 l
->flags
= EALF_SORTED
;
1015 l
->attrs
[0].id
= EA_RIP_METRIC
;
1016 l
->attrs
[0].flags
= 0;
1017 l
->attrs
[0].type
= EAF_TYPE_INT
| EAF_TEMP
;
1018 l
->attrs
[0].u
.data
= metric
;
1020 l
->attrs
[1].id
= EA_RIP_TAG
;
1021 l
->attrs
[1].flags
= 0;
1022 l
->attrs
[1].type
= EAF_TYPE_INT
| EAF_TEMP
;
1023 l
->attrs
[1].u
.data
= tag
;
1029 rip_import_control(struct proto
*P UNUSED
, struct rte
**rt
, struct ea_list
**attrs
, struct linpool
*pool
)
1031 /* Prepare attributes with initial values */
1032 if ((*rt
)->attrs
->source
!= RTS_RIP
)
1033 *attrs
= rip_prepare_attrs(pool
, *attrs
, 1, 0);
1039 rip_reload_routes(struct proto
*P
)
1041 struct rip_proto
*p
= (struct rip_proto
*) P
;
1046 TRACE(D_EVENTS
, "Scheduling route reload");
1053 static struct ea_list
*
1054 rip_make_tmp_attrs(struct rte
*rt
, struct linpool
*pool
)
1056 return rip_prepare_attrs(pool
, NULL
, rt
->u
.rip
.metric
, rt
->u
.rip
.tag
);
1060 rip_store_tmp_attrs(struct rte
*rt
, struct ea_list
*attrs
)
1062 rt
->u
.rip
.metric
= ea_get_int(attrs
, EA_RIP_METRIC
, 1);
1063 rt
->u
.rip
.tag
= ea_get_int(attrs
, EA_RIP_TAG
, 0);
1067 rip_rte_better(struct rte
*new, struct rte
*old
)
1069 return new->u
.rip
.metric
< old
->u
.rip
.metric
;
1073 rip_rte_same(struct rte
*new, struct rte
*old
)
1075 return ((new->u
.rip
.metric
== old
->u
.rip
.metric
) &&
1076 (new->u
.rip
.tag
== old
->u
.rip
.tag
) &&
1077 (new->u
.rip
.from
== old
->u
.rip
.from
));
1081 static struct proto
*
1082 rip_init(struct proto_config
*cfg
)
1084 struct proto
*P
= proto_new(cfg
, sizeof(struct rip_proto
));
1086 P
->accept_ra_types
= RA_OPTIMAL
;
1087 P
->if_notify
= rip_if_notify
;
1088 P
->rt_notify
= rip_rt_notify
;
1089 P
->neigh_notify
= rip_neigh_notify
;
1090 P
->import_control
= rip_import_control
;
1091 P
->reload_routes
= rip_reload_routes
;
1092 P
->make_tmp_attrs
= rip_make_tmp_attrs
;
1093 P
->store_tmp_attrs
= rip_store_tmp_attrs
;
1094 P
->rte_better
= rip_rte_better
;
1095 P
->rte_same
= rip_rte_same
;
1101 rip_start(struct proto
*P
)
1103 struct rip_proto
*p
= (void *) P
;
1104 struct rip_config
*cf
= (void *) (P
->cf
);
1106 init_list(&p
->iface_list
);
1107 fib_init(&p
->rtable
, P
->pool
, sizeof(struct rip_entry
), 0, rip_init_entry
);
1108 p
->rte_slab
= sl_new(P
->pool
, sizeof(struct rip_rte
));
1109 p
->timer
= tm_new_set(P
->pool
, rip_timer
, p
, 0, 0);
1112 p
->infinity
= cf
->infinity
;
1115 p
->log_pkt_tbf
= (struct tbf
){ .rate
= 1, .burst
= 5 };
1116 p
->log_rte_tbf
= (struct tbf
){ .rate
= 4, .burst
= 20 };
1118 tm_start(p
->timer
, MIN(cf
->min_timeout_time
, cf
->max_garbage_time
));
1124 rip_reconfigure(struct proto
*P
, struct proto_config
*c
)
1126 struct rip_proto
*p
= (void *) P
;
1127 struct rip_config
*new = (void *) c
;
1128 // struct rip_config *old = (void *) (P->cf);
1130 if (new->infinity
!= p
->infinity
)
1133 TRACE(D_EVENTS
, "Reconfiguring");
1136 p
->ecmp
= new->ecmp
;
1137 rip_reconfigure_ifaces(p
, new);
1146 rip_get_route_info(rte
*rte
, byte
*buf
, ea_list
*attrs UNUSED
)
1148 buf
+= bsprintf(buf
, " (%d/%d)", rte
->pref
, rte
->u
.rip
.metric
);
1151 bsprintf(buf
, " [%04x]", rte
->u
.rip
.tag
);
1155 rip_get_attr(eattr
*a
, byte
*buf
, int buflen UNUSED
)
1160 bsprintf(buf
, "metric: %d", a
->u
.data
);
1164 bsprintf(buf
, "tag: %04x", a
->u
.data
);
1173 rip_show_interfaces(struct proto
*P
, char *iff
)
1175 struct rip_proto
*p
= (void *) P
;
1176 struct rip_iface
*ifa
= NULL
;
1177 struct rip_neighbor
*n
= NULL
;
1179 if (p
->p
.proto_state
!= PS_UP
)
1181 cli_msg(-1021, "%s: is not up", p
->p
.name
);
1186 cli_msg(-1021, "%s:", p
->p
.name
);
1187 cli_msg(-1021, "%-10s %-6s %6s %6s %6s",
1188 "Interface", "State", "Metric", "Nbrs", "Timer");
1190 WALK_LIST(ifa
, p
->iface_list
)
1192 if (iff
&& !patmatch(iff
, ifa
->iface
->name
))
1196 WALK_LIST(n
, ifa
->neigh_list
)
1200 int timer
= MAX(ifa
->next_regular
- now
, 0);
1201 cli_msg(-1021, "%-10s %-6s %6u %6u %6u",
1202 ifa
->iface
->name
, (ifa
->up
? "Up" : "Down"), ifa
->cf
->metric
, nbrs
, timer
);
1209 rip_show_neighbors(struct proto
*P
, char *iff
)
1211 struct rip_proto
*p
= (void *) P
;
1212 struct rip_iface
*ifa
= NULL
;
1213 struct rip_neighbor
*n
= NULL
;
1215 if (p
->p
.proto_state
!= PS_UP
)
1217 cli_msg(-1022, "%s: is not up", p
->p
.name
);
1222 cli_msg(-1022, "%s:", p
->p
.name
);
1223 cli_msg(-1022, "%-25s %-10s %6s %6s %6s",
1224 "IP address", "Interface", "Metric", "Routes", "Seen");
1226 WALK_LIST(ifa
, p
->iface_list
)
1228 if (iff
&& !patmatch(iff
, ifa
->iface
->name
))
1231 WALK_LIST(n
, ifa
->neigh_list
)
1236 int timer
= now
- n
->last_seen
;
1237 cli_msg(-1022, "%-25I %-10s %6u %6u %6u",
1238 n
->nbr
->addr
, ifa
->iface
->name
, ifa
->cf
->metric
, n
->uc
, timer
);
1246 rip_dump(struct proto
*P
)
1248 struct rip_proto
*p
= (struct rip_proto
*) P
;
1249 struct rip_iface
*ifa
;
1253 FIB_WALK(&p
->rtable
, e
)
1255 struct rip_entry
*en
= (struct rip_entry
*) e
;
1256 debug("RIP: entry #%d: %I/%d via %I dev %s valid %d metric %d age %d s\n",
1257 i
++, en
->n
.prefix
, en
->n
.pxlen
, en
->next_hop
, en
->iface
->name
,
1258 en
->valid
, en
->metric
, now
- en
->changed
);
1263 WALK_LIST(ifa
, p
->iface_list
)
1265 debug("RIP: interface #%d: %s, %I, up = %d, busy = %d\n",
1266 i
++, ifa
->iface
->name
, ifa
->sk
? ifa
->sk
->daddr
: IPA_NONE
,
1267 ifa
->up
, ifa
->tx_active
);
1272 struct protocol proto_rip
= {
1274 .template = "rip%d",
1275 .attr_class
= EAP_RIP
,
1276 .preference
= DEF_PREF_RIP
,
1277 .config_size
= sizeof(struct rip_config
),
1281 .reconfigure
= rip_reconfigure
,
1282 .get_route_info
= rip_get_route_info
,
1283 .get_attr
= rip_get_attr