summaryrefslogtreecommitdiff
path: root/proto/static/static.c
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2010-11-11 12:24:27 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2010-11-11 12:24:27 +0100
commitfe181e7c63843ad65401cc1e400ae1ac3187122f (patch)
treedf37b8d76084521bb33e749a70ea85f04f19e16d /proto/static/static.c
parentf25cb0ef9f6341648513e793a3162b32fc250d2b (diff)
Adds support for iface link check to static protocol.
Diffstat (limited to 'proto/static/static.c')
-rw-r--r--proto/static/static.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/proto/static/static.c b/proto/static/static.c
index 6b42a379..4f879bd3 100644
--- a/proto/static/static.c
+++ b/proto/static/static.c
@@ -64,6 +64,20 @@ static_install(struct proto *p, struct static_route *r, struct iface *ifa)
r->installed = 1;
}
+static int
+static_decide(struct static_config *cf, struct static_route *r)
+{
+ struct iface *ifa = r->neigh->iface;
+
+ if (!ifa)
+ return 0;
+
+ if ((cf->check == STATIC_CHECK_LINK) && !(ifa->flags & IF_LINK_UP))
+ return 0;
+
+ return 1;
+}
+
static void
static_remove(struct proto *p, struct static_route *r)
{
@@ -80,7 +94,7 @@ static_remove(struct proto *p, struct static_route *r)
}
static void
-static_add(struct proto *p, struct static_route *r)
+static_add(struct proto *p, struct static_config *cf, struct static_route *r)
{
DBG("static_add(%I/%d,%d)\n", r->net, r->masklen, r->dest);
switch (r->dest)
@@ -93,8 +107,10 @@ static_add(struct proto *p, struct static_route *r)
r->chain = n->data;
n->data = r;
r->neigh = n;
- if (n->iface)
+ if (static_decide(cf, r))
static_install(p, r, n->iface);
+ else
+ static_remove(p, r);
}
else
log(L_ERR "Static route destination %I is invalid. Ignoring.", r->via);
@@ -115,7 +131,7 @@ static_start(struct proto *p)
DBG("Static: take off!\n");
WALK_LIST(r, c->other_routes)
- static_add(p, r);
+ static_add(p, c, r);
return PS_UP;
}
@@ -142,7 +158,7 @@ static_neigh_notify(struct neighbor *n)
DBG("Static: neighbor notify for %I: iface %p\n", n->addr, n->iface);
for(r=n->data; r; r=r->chain)
- if (n->iface)
+ if (static_decide((struct static_config *) p->cf, r))
static_install(p, r, n->iface);
else
static_remove(p, r);
@@ -249,13 +265,13 @@ static_match(struct proto *p, struct static_route *r, struct static_config *n)
WALK_LIST(t, n->iface_routes)
if (static_same_net(r, t))
{
- t->installed = static_same_dest(r, t);
+ t->installed = r->installed && static_same_dest(r, t);
return;
}
WALK_LIST(t, n->other_routes)
if (static_same_net(r, t))
{
- t->installed = static_same_dest(r, t);
+ t->installed = r->installed && static_same_dest(r, t);
return;
}
static_remove(p, r);
@@ -282,7 +298,7 @@ static_reconfigure(struct proto *p, struct proto_config *new)
static_install(p, r, ifa);
}
WALK_LIST(r, n->other_routes)
- static_add(p, r);
+ static_add(p, n, r);
return 1;
}