summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2014-02-26 13:25:39 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2014-02-26 16:01:20 +0100
commitd40c26594c22ad934a13061e11b373bdf81af8f9 (patch)
tree870d09d0868de496efc8a2c4996c1608310b0fc3 /proto
parent3216eb03ddddc057bb18fa4dd02b7935a604f71f (diff)
Fixes issues with static protocol reconfiguration.
The old static route was not removed when the nexthop changed and the new one was not viable (no neighbor). Thanks to Pierluigi Rolando for the original patch.
Diffstat (limited to 'proto')
-rw-r--r--proto/static/static.c25
-rw-r--r--proto/static/static.h2
2 files changed, 16 insertions, 11 deletions
diff --git a/proto/static/static.c b/proto/static/static.c
index 9b115acd..d3a595d3 100644
--- a/proto/static/static.c
+++ b/proto/static/static.c
@@ -62,7 +62,7 @@ static_install(struct proto *p, struct static_route *r, struct iface *ifa)
rta a, *aa;
rte *e;
- if (r->installed)
+ if (r->installed > 0)
return;
DBG("Installing static route %I/%d, rtd=%d\n", r->net, r->masklen, r->dest);
@@ -125,7 +125,7 @@ static_remove(struct proto *p, struct static_route *r)
if (!r->installed)
return;
- DBG("Removing static route %I/%d\n", r->net, r->masklen);
+ DBG("Removing static route %I/%d via %I\n", r->net, r->masklen, r->via);
n = net_find(p->table, r->net, r->masklen);
rte_update(p, n, NULL);
r->installed = 0;
@@ -420,19 +420,24 @@ static_match(struct proto *p, struct static_route *r, struct static_config *n)
if (r->neigh)
r->neigh->data = NULL;
+
WALK_LIST(t, n->iface_routes)
if (static_same_net(r, t))
- {
- t->installed = r->installed && static_same_dest(r, t);
- return;
- }
+ goto found;
+
WALK_LIST(t, n->other_routes)
if (static_same_net(r, t))
- {
- t->installed = r->installed && static_same_dest(r, t);
- return;
- }
+ goto found;
+
static_remove(p, r);
+ return;
+
+ found:
+ /* If destination is different, force reinstall */
+ if ((r->installed > 0) && !static_same_dest(r, t))
+ t->installed = -1;
+ else
+ t->installed = r->installed;
}
static inline rtable *
diff --git a/proto/static/static.h b/proto/static/static.h
index eb87ddec..99a0e68b 100644
--- a/proto/static/static.h
+++ b/proto/static/static.h
@@ -31,7 +31,7 @@ struct static_route {
struct neighbor *neigh;
byte *if_name; /* Name for RTD_DEVICE routes */
struct static_route *mp_next; /* Nexthops for RTD_MULTIPATH routes */
- int installed; /* Installed in master table */
+ int installed; /* Installed in rt table, -1 for reinstall */
};
/* Dummy nodes (parts of multipath route) abuses masklen field for weight