summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichele Marchetto <michele@cvs.openbsd.org>2007-04-09 20:45:53 +0000
committerMichele Marchetto <michele@cvs.openbsd.org>2007-04-09 20:45:53 +0000
commita456875a1be0b30621087924aaa8e8f3331659a5 (patch)
tree9ab3801aac4fd1e979e1ec456baed7bcb4e014b7
parentb77de0322bb373112a4d0b239571875c9e07e9be (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.c38
-rw-r--r--usr.sbin/ripd/rde.h5
-rw-r--r--usr.sbin/ripd/rde_rib.c20
-rw-r--r--usr.sbin/ripd/ripe.h6
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 *);