diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2022-09-15 01:38:18 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2023-10-04 13:01:21 +0200 |
commit | 333ddd4f981b90d5d3dff166b6abf9bf40bede9f (patch) | |
tree | cfe873631d254b9198d7040a7f922f65d158f15d /nest/proto.c | |
parent | e55696a4f88b63c622bb3a0360f9114d01253e53 (diff) |
MPLS subsystem
The MPLS subsystem manages MPLS labels and handles their allocation to
MPLS-aware routing protocols. These labels are then attached to IP or VPN
routes representing label switched paths -- LSPs.
There was already a preliminary MPLS support consisting of MPLS label
net_addr, MPLS routing tables with static MPLS routes, remote labels in
next hops, and kernel protocol support.
This patch adds the MPLS domain as a basic structure representing local
label space with dynamic label allocator and configurable label ranges.
To represent LSPs, allocated local labels can be attached as route
attributes to IP or VPN routes with local labels as attributes.
There are several steps for handling LSP routes in routing protocols --
deciding to which forwarding equivalence class (FEC) the LSP route
belongs, allocating labels for new FECs, announcing MPLS routes for new
FECs, attaching labels to LSP routes. The FEC map structure implements
basic code for managing FECs in routing protocols, therefore existing
protocols can be made MPLS-aware by adding FEC map and delegating
most work related to local label management to it.
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) |