diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2010-05-16 11:03:59 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2010-05-16 11:03:59 +0200 |
commit | c1cefd7bea79201c58c7c0fa8e192be3cc5ed771 (patch) | |
tree | c873db97fde228ffeffd101c809f8e1b97ee57b5 | |
parent | 7ff5803becec14da870d3997d78e3963fa5ec6e6 (diff) | |
download | bird-c1cefd7bea79201c58c7c0fa8e192be3cc5ed771.tar bird-c1cefd7bea79201c58c7c0fa8e192be3cc5ed771.zip |
Do not remove old static route if it is in new config with different gw.
-rw-r--r-- | proto/static/static.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/proto/static/static.c b/proto/static/static.c index 9308c59..6b42a37 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -218,15 +218,18 @@ static_init(struct proto_config *c) return p; } -static int -static_same_route(struct static_route *x, struct static_route *y) +static inline int +static_same_net(struct static_route *x, struct static_route *y) { - return ipa_equal(x->net, y->net) - && x->masklen == y->masklen - && x->dest == y->dest + return ipa_equal(x->net, y->net) && (x->masklen == y->masklen); +} + +static inline int +static_same_dest(struct static_route *x, struct static_route *y) +{ + return (x->dest == y->dest) && (x->dest != RTD_ROUTER || ipa_equal(x->via, y->via)) - && (x->dest != RTD_DEVICE || !strcmp(x->if_name, y->if_name)) - ; + && (x->dest != RTD_DEVICE || !strcmp(x->if_name, y->if_name)); } static void @@ -234,18 +237,25 @@ static_match(struct proto *p, struct static_route *r, struct static_config *n) { struct static_route *t; + /* + * For given old route *r we find whether a route to the same + * network is also in the new route list. In that case, we keep the + * route and possibly update the route later if destination changed. + * Otherwise, we remove the route. + */ + if (r->neigh) r->neigh->data = NULL; WALK_LIST(t, n->iface_routes) - if (static_same_route(r, t)) + if (static_same_net(r, t)) { - t->installed = 1; + t->installed = static_same_dest(r, t); return; } WALK_LIST(t, n->other_routes) - if (static_same_route(r, t)) + if (static_same_net(r, t)) { - t->installed = 1; + t->installed = static_same_dest(r, t); return; } static_remove(p, r); |