diff options
author | Michele Marchetto <michele@cvs.openbsd.org> | 2007-04-09 20:45:53 +0000 |
---|---|---|
committer | Michele Marchetto <michele@cvs.openbsd.org> | 2007-04-09 20:45:53 +0000 |
commit | a456875a1be0b30621087924aaa8e8f3331659a5 (patch) | |
tree | 9ab3801aac4fd1e979e1ec456baed7bcb4e014b7 | |
parent | b77de0322bb373112a4d0b239571875c9e07e9be (diff) |
Improve the handling of "counting to infinity" mechanism and add an heuristic
higly recommended in the rfc.
tested by me and OK claudio@
-rw-r--r-- | usr.sbin/ripd/rde.c | 38 | ||||
-rw-r--r-- | usr.sbin/ripd/rde.h | 5 | ||||
-rw-r--r-- | usr.sbin/ripd/rde_rib.c | 20 | ||||
-rw-r--r-- | usr.sbin/ripd/ripe.h | 6 |
4 files changed, 50 insertions, 19 deletions
diff --git a/usr.sbin/ripd/rde.c b/usr.sbin/ripd/rde.c index 22b93adaebe..408bc97731e 100644 --- a/usr.sbin/ripd/rde.c +++ b/usr.sbin/ripd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.5 2007/03/31 09:49:20 michele Exp $ */ +/* $OpenBSD: rde.c,v 1.6 2007/04/09 20:45:52 michele Exp $ */ /* * Copyright (c) 2006 Michele Marchetto <mydecay@openbeer.it> @@ -383,6 +383,7 @@ rde_send_delete_kroute(struct rt_node *r) int rde_check_route(struct rip_route *e) { + struct timeval tv, now; struct rt_node *rn; struct iface *iface; int metric; @@ -396,17 +397,14 @@ rde_check_route(struct rip_route *e) htonl(INADDR_LOOPBACK & IN_CLASSA_NET)) return (-1); - if (e->metric > INFINITY) - return (-1); - if ((iface = if_find_index(e->ifindex)) == NULL) return (-1); metric = MIN(INFINITY, e->metric + iface->cost); - if (metric >= INFINITY) - return (0); if ((rn = rt_find(e->address.s_addr, e->mask.s_addr)) == NULL) { + if (metric >= INFINITY) + return (0); rn = rt_new_rr(e, metric); rt_insert(rn); rde_send_change_kroute(rn); @@ -427,13 +425,31 @@ rde_check_route(struct rip_route *e) rde_send_change_kroute(rn); triggered_update(rn); } else if (e->nexthop.s_addr == rn->nexthop.s_addr && - e->metric > metric) { - rn->metric = metric; - rde_send_change_kroute(rn); - triggered_update(rn); + metric > rn->metric) { + rn->metric = metric; + rde_send_change_kroute(rn); + triggered_update(rn); + if (rn->metric == INFINITY) + route_start_garbage(rn); + } else if (e->nexthop.s_addr != rn->nexthop.s_addr && + metric == rn->metric) { + /* If the new metric is the same as the old one, + * examine the timeout for the existing route. If it + * is at least halfway to the expiration point, switch + * to the new route. + */ + timerclear(&tv); + gettimeofday(&now, NULL); + evtimer_pending(&rn->timeout_timer, &tv); + if (tv.tv_sec - now.tv_sec < ROUTE_TIMEOUT / 2) { + rn->nexthop.s_addr = e->nexthop.s_addr; + rn->ifindex = e->ifindex; + rde_send_change_kroute(rn); + } } - if (e->nexthop.s_addr == rn->nexthop.s_addr) + if (e->nexthop.s_addr == rn->nexthop.s_addr && + rn->metric < INFINITY) route_reset_timers(rn); } diff --git a/usr.sbin/ripd/rde.h b/usr.sbin/ripd/rde.h index f27d561a8ae..429c5a91055 100644 --- a/usr.sbin/ripd/rde.h +++ b/usr.sbin/ripd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.1 2006/10/18 16:11:58 norby Exp $ */ +/* $OpenBSD: rde.h,v 1.2 2007/04/09 20:45:52 michele Exp $ */ /* * Copyright (c) 2006 Michele Marchetto <mydecay@openbeer.it> @@ -46,7 +46,7 @@ void rde_send_delete_kroute(struct rt_node *); int rde_imsg_compose_ripe(int, u_int32_t, pid_t, void *, u_int16_t); -/* rde_routes.c */ +/* rde_rib.c */ void rt_init(void); int rt_compare(struct rt_node *, struct rt_node *); struct rt_node *rt_find(in_addr_t, in_addr_t); @@ -59,6 +59,7 @@ void rt_snap(u_int32_t); void rt_clear(void); void route_reset_timers(struct rt_node *); int route_start_timeout(struct rt_node *); +void route_start_garbage(struct rt_node *); void rt_dump(pid_t); #endif /* _RDE_H_ */ diff --git a/usr.sbin/ripd/rde_rib.c b/usr.sbin/ripd/rde_rib.c index e26292ee953..ce10a480f73 100644 --- a/usr.sbin/ripd/rde_rib.c +++ b/usr.sbin/ripd/rde_rib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_rib.c,v 1.1 2006/10/18 16:11:58 norby Exp $ */ +/* $OpenBSD: rde_rib.c,v 1.2 2007/04/09 20:45:52 michele Exp $ */ /* * Copyright (c) 2006 Michele Marchetto <mydecay@openbeer.it> @@ -44,7 +44,6 @@ RB_GENERATE(rt_tree, rt_node, entry, rt_compare) void route_action_timeout(int, short, void *); void route_action_garbage(int, short, void *); -int route_start_timeout(struct rt_node *); /* timers */ int @@ -58,6 +57,21 @@ route_start_timeout(struct rt_node *rn) return (evtimer_add(&rn->timeout_timer, &tv)); } +void +route_start_garbage(struct rt_node *rn) +{ + struct timeval tv; + + timerclear(&tv); + tv.tv_sec = ROUTE_GARBAGE; + + if (evtimer_pending(&rn->timeout_timer, NULL)) { + if (evtimer_del(&rn->timeout_timer) == -1) + fatal("route_start_garbage"); + evtimer_add(&rn->garbage_timer, &tv); + } +} + /* ARGSUSED */ void route_action_timeout(int fd, short event, void *arg) @@ -95,7 +109,7 @@ route_reset_timers(struct rt_node *r) evtimer_del(&r->timeout_timer); evtimer_del(&r->garbage_timer); - event_add(&r->timeout_timer, &tv); + evtimer_add(&r->timeout_timer, &tv); } /* route table */ diff --git a/usr.sbin/ripd/ripe.h b/usr.sbin/ripd/ripe.h index 3c901901afe..8a7d2c70270 100644 --- a/usr.sbin/ripd/ripe.h +++ b/usr.sbin/ripd/ripe.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ripe.h,v 1.5 2007/03/27 20:19:04 michele Exp $ */ +/* $OpenBSD: ripe.h,v 1.6 2007/04/09 20:45:52 michele Exp $ */ /* * Copyright (c) 2006 Michele Marchetto <mydecay@openbeer.it> @@ -73,12 +73,12 @@ struct nbr { int flags; }; -/* packet */ +/* packet.c */ int send_packet(struct iface *, void *, size_t, struct sockaddr_in *); void recv_packet(int, short, void *); int gen_rip_hdr(struct buf *, u_int8_t); -/* interface */ +/* interface.c */ void if_init(struct ripd_conf *, struct iface *); int if_fsm(struct iface *, enum iface_event); int if_set_mcast(struct iface *); |