aboutsummaryrefslogtreecommitdiffstats
path: root/nest/proto.c
diff options
context:
space:
mode:
Diffstat (limited to 'nest/proto.c')
-rw-r--r--nest/proto.c78
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)