diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2016-01-26 11:48:58 +0100 |
---|---|---|
committer | Jan Moskyto Matejka <mq@ucw.cz> | 2016-02-01 10:28:50 +0100 |
commit | f4a60a9bc429c28cb397402331dc01a789197450 (patch) | |
tree | e8cead76aa1c2aedfb76d7e3ceade2fc4a7214cf /proto/static/static.c | |
parent | 9f5782d9691f23296c4b1a68ef66630d9cc3a6cd (diff) |
Channels - explicit links between protocols and tables
The patch adds support for channels, structures connecting protocols and
tables and handling most interactions between them. The documentation is
missing yet.
Diffstat (limited to 'proto/static/static.c')
-rw-r--r-- | proto/static/static.c | 69 |
1 files changed, 53 insertions, 16 deletions
diff --git a/proto/static/static.c b/proto/static/static.c index 809c29fb..6239fccb 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -54,7 +54,7 @@ static inline rtable * p_igp_table(struct proto *p) { struct static_config *cf = (void *) p->cf; - return cf->igp_table ? cf->igp_table->table : p->table; + return cf->igp_table ? cf->igp_table->table : p->main_channel->table; } static void @@ -108,11 +108,11 @@ static_install(struct proto *p, struct static_route *r, struct iface *ifa) } if (r->dest == RTDX_RECURSIVE) - rta_set_recursive_next_hop(p->table, &a, p_igp_table(p), &r->via, &r->via); + rta_set_recursive_next_hop(p->main_channel->table, &a, p_igp_table(p), &r->via, &r->via); /* We skip rta_lookup() here */ - n = net_get(p->table, r->net); + n = net_get(p->main_channel->table, r->net); e = rte_get_temp(&a); e->net = n; e->pflags = 0; @@ -136,7 +136,7 @@ static_remove(struct proto *p, struct static_route *r) return; DBG("Removing static route %N via %I\n", r->net, r->via); - n = net_find(p->table, r->net); + n = net_find(p->main_channel->table, r->net); rte_update(p, n, NULL); r->installed = 0; } @@ -309,6 +309,17 @@ static_shutdown(struct proto *p) r->installed = 0; } + /* Handle failure during channel reconfigure */ + /* FIXME: This should be handled in a better way */ + cf = (void *) p->cf_new; + if (cf) + { + WALK_LIST(r, cf->iface_routes) + r->installed = 0; + WALK_LIST(r, cf->other_routes) + r->installed = 0; + } + return PS_DOWN; } @@ -450,16 +461,40 @@ static_init_config(struct static_config *c) init_list(&c->other_routes); } +static void +static_postconfig(struct proto_config *CF) +{ + struct static_config *cf = (void *) CF; + struct static_route *r; + + if (EMPTY_LIST(CF->channels)) + cf_error("Channel not specified"); + + + WALK_LIST(r, cf->iface_routes) + if (r->net->type != CF->net_type) + cf_error("Route %N incompatible with channel type", r->net); + + WALK_LIST(r, cf->other_routes) + if (r->net->type != CF->net_type) + cf_error("Route %N incompatible with channel type", r->net); +} + + static struct proto * -static_init(struct proto_config *c) +static_init(struct proto_config *CF) { - struct proto *p = proto_new(c, sizeof(struct proto)); + struct proto *P = proto_new(CF); + // struct static_proto *p = (void *) P; + // struct static_config *cf = (void *) CF; - p->neigh_notify = static_neigh_notify; - p->if_notify = static_if_notify; - p->rte_mergable = static_rte_mergable; + P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF)); - return p; + P->neigh_notify = static_neigh_notify; + P->if_notify = static_if_notify; + P->rte_mergable = static_rte_mergable; + + return P; } static inline int @@ -543,15 +578,18 @@ cf_igp_table(struct static_config *cf) } static int -static_reconfigure(struct proto *p, struct proto_config *new) +static_reconfigure(struct proto *p, struct proto_config *CF) { struct static_config *o = (void *) p->cf; - struct static_config *n = (void *) new; + struct static_config *n = (void *) CF; struct static_route *r; if (cf_igp_table(o) != cf_igp_table(n)) return 0; + if (!proto_configure_channel(p, &p->main_channel, proto_cf_main_channel(CF))) + return 0; + /* Delete all obsolete routes and reset neighbor entries */ WALK_LIST(r, o->iface_routes) static_match(p, r, n); @@ -617,20 +655,19 @@ static_copy_config(struct proto_config *dest, struct proto_config *src) struct static_config *d = (struct static_config *) dest; struct static_config *s = (struct static_config *) src; - /* Shallow copy of everything */ - proto_copy_rest(dest, src, sizeof(struct static_config)); - /* Copy route lists */ static_copy_routes(&d->iface_routes, &s->iface_routes); static_copy_routes(&d->other_routes, &s->other_routes); } - struct protocol proto_static = { .name = "Static", .template = "static%d", .preference = DEF_PREF_STATIC, + .channel_mask = NB_ANY, + .proto_size = sizeof(struct proto), .config_size = sizeof(struct static_config), + .postconfig = static_postconfig, .init = static_init, .dump = static_dump, .start = static_start, |