]> git.ipfire.org Git - thirdparty/bird.git/blob - nest/mpls.h
1f3d02dc583754d0886a4a528e8f181059cc6911
[thirdparty/bird.git] / nest / mpls.h
1 /*
2 * BIRD Internet Routing Daemon -- MPLS Structures
3 *
4 * (c) 2022 Ondrej Zajicek <santiago@crfreenet.org>
5 * (c) 2022 CZ.NIC z.s.p.o.
6 *
7 * Can be freely distributed and used under the terms of the GNU GPL.
8 */
9
10 #ifndef _BIRD_MPLS_H_
11 #define _BIRD_MPLS_H_
12
13 #include "nest/bird.h"
14 #include "lib/bitmap.h"
15 #include "lib/hash.h"
16 #include "nest/route.h"
17 #include "nest/protocol.h"
18
19
20 #define MPLS_POLICY_NONE 0
21 #define MPLS_POLICY_STATIC 1
22 #define MPLS_POLICY_PREFIX 2
23 #define MPLS_POLICY_AGGREGATE 3
24 #define MPLS_POLICY_VRF 4
25
26 #define MPLS_FEC_DOWN 0
27 #define MPLS_FEC_CLEAN 1
28 #define MPLS_FEC_DIRTY 2
29
30
31 struct mpls_domain_config {
32 node n; /* Node in config.mpls_domains */
33 struct mpls_domain *domain; /* Our instance */
34 const char *name;
35
36 list ranges; /* List of label ranges (struct mpls_range_config) */
37 struct mpls_range_config *static_range; /* Default static label range */
38 struct mpls_range_config *dynamic_range; /* Default dynamic label range */
39 };
40
41 struct mpls_domain {
42 node n; /* Node in global list of MPLS domains (mpls_domains) */
43 struct mpls_domain_config *cf; /* Our config */
44 const char *name;
45 pool *pool; /* Pool for the domain and associated objects */
46
47 struct lmap labels; /* Bitmap of allocated labels */
48 uint label_count; /* Number of allocated labels */
49 uint use_count; /* Reference counter */
50
51 struct config *removed; /* Deconfigured, waiting for zero use_count,
52 while keeping config obstacle */
53
54 list ranges; /* List of label ranges (struct mpls_range) */
55 list handles; /* List of label handles (struct mpls_handle) */
56 };
57
58 struct mpls_range_config {
59 node n; /* Node in mpls_domain_config.ranges */
60 struct mpls_range *range; /* Our instance */
61 struct mpls_domain_config *domain; /* Parent MPLS domain */
62 const char *name;
63
64 uint start; /* Label range start, (uint) -1 for undefined */
65 uint length; /* Label range length, (uint) -1 for undefined */
66 u8 implicit; /* Implicitly defined range */
67 };
68
69 struct mpls_range {
70 node n; /* Node in mpls_domain.ranges */
71 struct mpls_range_config *cf; /* Our config */
72 const char *name;
73
74 uint lo, hi; /* Label range interval */
75 uint label_count; /* Number of allocated labels */
76 uint use_count; /* Reference counter */
77 u8 removed; /* Deconfigured, waiting for zero use_count */
78 };
79
80 struct mpls_handle {
81 node n; /* Node in mpls_domain.handles */
82
83 struct mpls_range *range; /* Associated range, keeping reference */
84 uint label_count; /* Number of allocated labels */
85 };
86
87
88 void mpls_init(void);
89 struct mpls_domain_config * mpls_domain_config_new(struct symbol *s);
90 void mpls_domain_postconfig(struct mpls_domain_config *cf);
91 struct mpls_range_config * mpls_range_config_new(struct mpls_domain_config *m, struct symbol *s);
92 void mpls_preconfig(struct config *c);
93 void mpls_commit(struct config *new, struct config *old);
94 uint mpls_new_label(struct mpls_domain *m, struct mpls_handle *h, uint n);
95 void mpls_free_label(struct mpls_domain *m, struct mpls_handle *h, uint n);
96
97 static inline struct mpls_domain_config *cf_default_mpls_domain(struct config *cfg)
98 { return EMPTY_LIST(cfg->mpls_domains) ? NULL : HEAD(cfg->mpls_domains); }
99
100
101 struct mpls_channel_config {
102 struct channel_config c;
103
104 struct mpls_domain_config *domain;
105 struct mpls_range_config *range;
106
107 uint label_policy;
108 };
109
110 struct mpls_channel {
111 struct channel c;
112
113 struct mpls_domain *domain;
114 struct mpls_range *range;
115
116 uint label_policy;
117 };
118
119
120 void mpls_channel_postconfig(struct channel_config *CF);
121 extern struct channel_class channel_mpls;
122
123
124 struct mpls_fec {
125 u32 label; /* Label for FEC */
126 u32 hash; /* Hash for primary key (net / rta) */
127 u32 uc; /* Number of LSPs for FEC */
128 union { /* Extension part of key */
129 u32 path_id; /* Source path_id */
130 u32 class_id; /* Aaggregation class */
131 };
132
133 u8 state; /* FEC state (MPLS_FEC_*) */
134 u8 policy; /* Label policy (MPLS_POLICY_*) */
135
136 struct mpls_fec *next_k; /* Next in mpls_fec.net_hash/rta_hash */
137 struct mpls_fec *next_l; /* Next in mpls_fec.label_hash */
138 union { /* Primary key */
139 struct rta *rta;
140 struct iface *iface;
141 net_addr net[0];
142 };
143 };
144
145 struct mpls_fec_map {
146 pool *pool; /* Pool for FEC map */
147 slab *slabs[4]; /* Slabs for FEC allocation */
148 HASH(struct mpls_fec) net_hash; /* Hash table for MPLS_POLICY_PREFIX FECs */
149 HASH(struct mpls_fec) rta_hash; /* Hash table for MPLS_POLICY_AGGREGATE FECs */
150 HASH(struct mpls_fec) label_hash; /* Hash table for FEC lookup by label */
151 struct mpls_fec *vrf_fec; /* Single FEC for MPLS_POLICY_VRF */
152
153 struct channel *channel; /* MPLS channel for FEC announcement */
154 struct mpls_domain *domain; /* MPLS domain, keeping reference */
155 struct mpls_handle *handle; /* Handle for allocation of labels */
156 struct mpls_handle *static_handle; /* Handle for static label allocations, optional */
157 struct iface *vrf_iface;
158
159 u8 mpls_rts; /* Source value used for MPLS routes (RTS_*) */
160 u8 mpls_scope; /* Scope value used for MPLS routes (SCOPE_*) */
161 };
162
163
164 struct mpls_fec_map *mpls_fec_map_new(pool *p, struct channel *c, uint rts);
165 void mpls_fec_map_free(struct mpls_fec_map *m);
166 struct mpls_fec *mpls_find_fec_by_label(struct mpls_fec_map *x, u32 label);
167 struct mpls_fec *mpls_get_fec_by_label(struct mpls_fec_map *m, u32 label);
168 struct mpls_fec *mpls_get_fec_by_net(struct mpls_fec_map *m, const net_addr *net, u32 path_id);
169 struct mpls_fec *mpls_get_fec_by_rta(struct mpls_fec_map *m, const rta *src, u32 class_id);
170 void mpls_free_fec(struct mpls_fec_map *x, struct mpls_fec *fec);
171 int mpls_handle_rte(struct mpls_fec_map *m, const net_addr *n, rte *r, linpool *lp, struct mpls_fec **locked_fec);
172 void mpls_handle_rte_cleanup(struct mpls_fec_map *m, struct mpls_fec **locked_fec);
173 void mpls_rte_insert(net *n UNUSED, rte *r);
174 void mpls_rte_remove(net *n UNUSED, rte *r);
175
176
177 struct mpls_show_ranges_cmd {
178 struct mpls_domain_config *domain;
179 struct mpls_range_config *range;
180
181 /* Runtime */
182 struct mpls_domain *dom;
183 };
184
185 void mpls_show_ranges(struct mpls_show_ranges_cmd *cmd);
186
187 #endif