diff options
Diffstat (limited to 'nest/proto.c')
-rw-r--r-- | nest/proto.c | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/nest/proto.c b/nest/proto.c index 48ffade5..701952ff 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -18,6 +18,7 @@ #include "conf/conf.h" #include "nest/route.h" #include "nest/iface.h" +#include "nest/mpls.h" #include "nest/cli.h" #include "filter/filter.h" #include "filter/f-inst.h" @@ -764,7 +765,7 @@ channel_config_new(const struct channel_class *cc, const char *name, uint net_ty if (!net_val_match(net_type, proto->protocol->channel_mask)) cf_error("Unsupported channel type"); - if (proto->net_type && (net_type != proto->net_type)) + if (proto->net_type && (net_type != proto->net_type) && (net_type != NET_MPLS)) cf_error("Different channel type"); tab = new_config->def_tables[net_type]; @@ -955,6 +956,81 @@ proto_configure_channel(struct proto *p, struct channel **pc, struct channel_con return 1; } +/** + * proto_setup_mpls_map - automatically setup FEC map for protocol + * @p: affected protocol + * @rts: RTS_* value for generated MPLS routes + * @hooks: whether to update rte_insert / rte_remove hooks + * + * Add, remove or reconfigure MPLS FEC map of the protocol @p, depends on + * whether MPLS channel exists, and setup rte_insert / rte_remove hooks with + * default MPLS handlers. It is a convenience function supposed to be called + * from the protocol start and configure hooks, after reconfiguration of + * channels. For shutdown, use proto_shutdown_mpls_map(). If caller uses its own + * rte_insert / rte_remove hooks, it is possible to disable updating hooks and + * doing that manually. + */ +void +proto_setup_mpls_map(struct proto *p, uint rts, int hooks) +{ + struct mpls_fec_map *m = p->mpls_map; + struct channel *c = p->mpls_channel; + + if (!m && c) + { + /* + * Note that when called from a protocol start hook, it is called before + * mpls_channel_start(). But FEC map locks MPLS domain internally so it does + * not depend on lock from MPLS channel. + */ + p->mpls_map = mpls_fec_map_new(p->pool, c, rts); + } + else if (m && !c) + { + /* + * Note that for reconfiguration, it is called after the MPLS channel has + * been already removed. But removal of active MPLS channel would trigger + * protocol restart anyways. + */ + mpls_fec_map_free(m); + p->mpls_map = NULL; + } + else if (m && c) + { + // mpls_fec_map_reconfigure(m, c); + } + + if (hooks) + { + p->rte_insert = p->mpls_map ? mpls_rte_insert : NULL; + p->rte_remove = p->mpls_map ? mpls_rte_remove : NULL; + } +} + +/** + * proto_shutdown_mpls_map - automatically shutdown FEC map for protocol + * @p: affected protocol + * @hooks: whether to update rte_insert / rte_remove hooks + * + * Remove MPLS FEC map of the protocol @p during protocol shutdown. + */ +void +proto_shutdown_mpls_map(struct proto *p, int hooks) +{ + struct mpls_fec_map *m = p->mpls_map; + + if (!m) + return; + + mpls_fec_map_free(m); + p->mpls_map = NULL; + + if (hooks) + { + p->rte_insert = NULL; + p->rte_remove = NULL; + } +} static void proto_event(void *ptr) |