diff options
Diffstat (limited to 'nest')
-rw-r--r-- | nest/config.Y | 2 | ||||
-rw-r--r-- | nest/proto.c | 25 | ||||
-rw-r--r-- | nest/protocol.h | 4 |
3 files changed, 26 insertions, 5 deletions
diff --git a/nest/config.Y b/nest/config.Y index 5c4f2393..044aba2b 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -214,7 +214,7 @@ proto_item: channel_start: net_type { - $$ = this_channel = channel_config_new(NULL, $1, this_proto); + $$ = this_channel = channel_config_get(NULL, net_label[$1], $1, this_proto); }; channel_item: diff --git a/nest/proto.c b/nest/proto.c index e103fec6..d584cb93 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -455,11 +455,10 @@ const struct channel_class channel_basic = { }; void * -channel_config_new(const struct channel_class *cc, uint net_type, struct proto_config *proto) +channel_config_new(const struct channel_class *cc, const char *name, uint net_type, struct proto_config *proto) { struct channel_config *cf = NULL; struct rtable_config *tab = NULL; - const char *name = NULL; if (net_type) { @@ -470,7 +469,6 @@ channel_config_new(const struct channel_class *cc, uint net_type, struct proto_c cf_error("Different channel type"); tab = new_config->def_tables[net_type]; - name = net_label[net_type]; } if (!cc) @@ -479,6 +477,7 @@ channel_config_new(const struct channel_class *cc, uint net_type, struct proto_c cf = cfg_allocz(cc->config_size); cf->name = name; cf->channel = cc; + cf->parent = proto; cf->table = tab; cf->out_filter = FILTER_REJECT; @@ -491,6 +490,26 @@ channel_config_new(const struct channel_class *cc, uint net_type, struct proto_c return cf; } +void * +channel_config_get(const struct channel_class *cc, const char *name, uint net_type, struct proto_config *proto) +{ + struct channel_config *cf; + + /* We are using name as token, so no strcmp() */ + WALK_LIST(cf, proto->channels) + if (cf->name == name) + { + /* Allow to redefine channel only if inherited from template */ + if (cf->parent == proto) + cf_error("Multiple %s channels", name); + + cf->parent = proto; + return cf; + } + + return channel_config_new(cc, name, net_type, proto); +} + struct channel_config * channel_copy_config(struct channel_config *src, struct proto_config *proto) { diff --git a/nest/protocol.h b/nest/protocol.h index c8f37367..9afd3a0a 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -461,6 +461,7 @@ struct channel_config { const char *name; const struct channel_class *channel; + struct proto_config *parent; /* Where channel is defined (proto or template) */ struct rtable_config *table; /* Table we're attached to */ struct filter *in_filter, *out_filter; /* Attached filters */ struct channel_limit rx_limit; /* Limit for receiving routes from protocol @@ -585,7 +586,8 @@ static inline void channel_open(struct channel *c) { channel_set_state(c, CS_UP) static inline void channel_close(struct channel *c) { channel_set_state(c, CS_FLUSHING); } void channel_request_feeding(struct channel *c); -void *channel_config_new(const struct channel_class *cc, uint net_type, struct proto_config *proto); +void *channel_config_new(const struct channel_class *cc, const char *name, uint net_type, struct proto_config *proto); +void *channel_config_get(const struct channel_class *cc, const char *name, uint net_type, struct proto_config *proto); int channel_reconfigure(struct channel *c, struct channel_config *cf); |