diff options
Diffstat (limited to 'proto/static/static.c')
-rw-r--r-- | proto/static/static.c | 25 |
1 files changed, 15 insertions, 10 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 * |