diff options
author | Mikael Magnusson <mikma@users.sourceforge.net> | 2023-11-25 23:38:46 +0100 |
---|---|---|
committer | Mikael Magnusson <mikma@users.sourceforge.net> | 2023-11-25 23:38:46 +0100 |
commit | b26801568ed5aa75797d752b1de458cc4bcac152 (patch) | |
tree | a10f4d613305fd77d540283952111d9a2f893549 /nest/mpls.h | |
parent | 03ed8f17dc5c8399ed81bef22e34c62301a3cad1 (diff) | |
parent | 333ddd4f981b90d5d3dff166b6abf9bf40bede9f (diff) |
Merge commit '333ddd4f' into wireguard-next-tmp7-1
Diffstat (limited to 'nest/mpls.h')
-rw-r--r-- | nest/mpls.h | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/nest/mpls.h b/nest/mpls.h new file mode 100644 index 00000000..a84ede14 --- /dev/null +++ b/nest/mpls.h @@ -0,0 +1,170 @@ +/* + * BIRD Internet Routing Daemon -- MPLS Structures + * + * (c) 2022 Ondrej Zajicek <santiago@crfreenet.org> + * (c) 2022 CZ.NIC z.s.p.o. + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +#ifndef _BIRD_MPLS_H_ +#define _BIRD_MPLS_H_ + +#include "nest/bird.h" +#include "lib/bitmap.h" +#include "lib/hash.h" +#include "nest/route.h" +#include "nest/protocol.h" + + +#define MPLS_POLICY_NONE 0 +#define MPLS_POLICY_STATIC 1 +#define MPLS_POLICY_PREFIX 2 +#define MPLS_POLICY_AGGREGATE 3 + +#define MPLS_FEC_DOWN 0 +#define MPLS_FEC_CLEAN 1 +#define MPLS_FEC_DIRTY 2 + + +struct mpls_domain_config { + node n; /* Node in config.mpls_domains */ + struct mpls_domain *domain; /* Our instance */ + const char *name; + + list ranges; /* List of label ranges (struct mpls_range_config) */ + struct mpls_range_config *static_range; /* Default static label range */ + struct mpls_range_config *dynamic_range; /* Default dynamic label range */ +}; + +struct mpls_domain { + node n; /* Node in global list of MPLS domains (mpls_domains) */ + struct mpls_domain_config *cf; /* Our config */ + const char *name; + pool *pool; /* Pool for the domain and associated objects */ + + struct lmap labels; /* Bitmap of allocated labels */ + uint label_count; /* Number of allocated labels */ + uint use_count; /* Reference counter */ + + struct config *removed; /* Deconfigured, waiting for zero use_count, + while keeping config obstacle */ + + list ranges; /* List of label ranges (struct mpls_range) */ + list handles; /* List of label handles (struct mpls_handle) */ +}; + +struct mpls_range_config { + node n; /* Node in mpls_domain_config.ranges */ + struct mpls_range *range; /* Our instance */ + struct mpls_domain_config *domain; /* Parent MPLS domain */ + const char *name; + + uint start; /* Label range start, (uint) -1 for undefined */ + uint length; /* Label range length, (uint) -1 for undefined */ +}; + +struct mpls_range { + node n; /* Node in mpls_domain.ranges */ + struct mpls_range_config *cf; /* Our config */ + const char *name; + + uint lo, hi; /* Label range interval */ + uint label_count; /* Number of allocated labels */ + uint use_count; /* Reference counter */ + u8 removed; /* Deconfigured, waiting for zero use_count */ +}; + +struct mpls_handle { + node n; /* Node in mpls_domain.handles */ + + struct mpls_range *range; /* Associated range, keeping reference */ + uint label_count; /* Number of allocated labels */ +}; + + +void mpls_init(void); +struct mpls_domain_config * mpls_domain_config_new(struct symbol *s); +void mpls_domain_postconfig(struct mpls_domain_config *cf); +struct mpls_range_config * mpls_range_config_new(struct mpls_domain_config *m, struct symbol *s); +void mpls_preconfig(struct config *c); +void mpls_commit(struct config *new, struct config *old); +uint mpls_new_label(struct mpls_domain *m, struct mpls_handle *h); +void mpls_free_label(struct mpls_domain *m, struct mpls_handle *h, uint n); + +static inline struct mpls_domain_config *cf_default_mpls_domain(struct config *cfg) +{ return EMPTY_LIST(cfg->mpls_domains) ? NULL : HEAD(cfg->mpls_domains); } + + +struct mpls_channel_config { + struct channel_config c; + + struct mpls_domain_config *domain; + struct mpls_range_config *range; + + uint label_policy; +}; + +struct mpls_channel { + struct channel c; + + struct mpls_domain *domain; + struct mpls_range *range; + + uint label_policy; +}; + + +void mpls_channel_postconfig(struct channel_config *CF); +extern struct channel_class channel_mpls; + + +struct mpls_fec { + u32 label; /* Label for FEC */ + u32 hash; /* Hash for primary key (net / rta) */ + u32 uc; /* Number of LSPs for FEC */ + union { /* Extension part of key */ + u32 path_id; /* Source path_id */ + u32 class_id; /* Aaggregation class */ + }; + + u8 state; /* FEC state (MPLS_FEC_*) */ + u8 policy; /* Label policy (MPLS_POLICY_*) */ + + struct mpls_fec *next_k; /* Next in mpls_fec.net_hash/rta_hash */ + struct mpls_fec *next_l; /* Next in mpls_fec.label_hash */ + union { /* Primary key */ + struct rta *rta; + net_addr net[0]; + }; +}; + +struct mpls_fec_map { + pool *pool; /* Pool for FEC map */ + slab *slabs[4]; /* Slabs for FEC allocation */ + HASH(struct mpls_fec) net_hash; /* Hash table for MPLS_POLICY_PREFIX FECs */ + HASH(struct mpls_fec) rta_hash; /* Hash table for MPLS_POLICY_AGGREGATE FECs */ + HASH(struct mpls_fec) label_hash; /* Hash table for FEC lookup by label */ + + struct channel *channel; /* MPLS channel for FEC announcement */ + struct mpls_domain *domain; /* MPLS domain, keeping reference */ + struct mpls_handle *handle; /* Handle for allocation of labels */ + + u8 mpls_rts; /* Source value used for MPLS routes (RTS_*) */ + u8 mpls_scope; /* Scope value used for MPLS routes () */ +}; + + +struct mpls_fec_map *mpls_fec_map_new(pool *p, struct channel *c, uint rts); +void mpls_fec_map_free(struct mpls_fec_map *m); +struct mpls_fec *mpls_find_fec_by_label(struct mpls_fec_map *x, u32 label); +struct mpls_fec *mpls_get_fec_by_label(struct mpls_fec_map *m, u32 label); +struct mpls_fec *mpls_get_fec_by_net(struct mpls_fec_map *m, const net_addr *net, u32 path_id); +struct mpls_fec *mpls_get_fec_by_rta(struct mpls_fec_map *m, const rta *src, u32 class_id); +void mpls_free_fec(struct mpls_fec_map *x, struct mpls_fec *fec); +void mpls_handle_rte(struct mpls_fec_map *m, const net_addr *n, rte *r, linpool *lp, struct mpls_fec **locked_fec); +void mpls_handle_rte_cleanup(struct mpls_fec_map *m, struct mpls_fec **locked_fec); +void mpls_rte_insert(net *n UNUSED, rte *r); +void mpls_rte_remove(net *n UNUSED, rte *r); + +#endif |