2 * BIRD Internet Routing Daemon -- MPLS Structures
4 * (c) 2022 Ondrej Zajicek <santiago@crfreenet.org>
5 * (c) 2022 CZ.NIC z.s.p.o.
7 * Can be freely distributed and used under the terms of the GNU GPL.
13 #include "nest/bird.h"
14 #include "lib/bitmap.h"
16 #include "nest/route.h"
17 #include "nest/protocol.h"
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
26 #define MPLS_FEC_DOWN 0
27 #define MPLS_FEC_CLEAN 1
28 #define MPLS_FEC_DIRTY 2
31 struct mpls_domain_config
{
32 node n
; /* Node in config.mpls_domains */
33 struct mpls_domain
*domain
; /* Our instance */
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 */
42 node n
; /* Node in global list of MPLS domains (mpls_domains) */
43 struct mpls_domain_config
*cf
; /* Our config */
45 pool
*pool
; /* Pool for the domain and associated objects */
47 struct lmap labels
; /* Bitmap of allocated labels */
48 uint label_count
; /* Number of allocated labels */
49 uint use_count
; /* Reference counter */
51 struct config
*removed
; /* Deconfigured, waiting for zero use_count,
52 while keeping config obstacle */
54 list ranges
; /* List of label ranges (struct mpls_range) */
55 list handles
; /* List of label handles (struct mpls_handle) */
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 */
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 */
70 node n
; /* Node in mpls_domain.ranges */
71 struct mpls_range_config
*cf
; /* Our config */
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 */
81 node n
; /* Node in mpls_domain.handles */
83 struct mpls_range
*range
; /* Associated range, keeping reference */
84 uint label_count
; /* Number of allocated labels */
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
);
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
); }
101 struct mpls_channel_config
{
102 struct channel_config c
;
104 struct mpls_domain_config
*domain
;
105 struct mpls_range_config
*range
;
110 struct mpls_channel
{
113 struct mpls_domain
*domain
;
114 struct mpls_range
*range
;
120 void mpls_channel_postconfig(struct channel_config
*CF
);
121 extern struct channel_class channel_mpls
;
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 */
133 u8 state
; /* FEC state (MPLS_FEC_*) */
134 u8 policy
; /* Label policy (MPLS_POLICY_*) */
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 */
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 */
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
;
159 u8 mpls_rts
; /* Source value used for MPLS routes (RTS_*) */
160 u8 mpls_scope
; /* Scope value used for MPLS routes (SCOPE_*) */
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
);
177 struct mpls_show_ranges_cmd
{
178 struct mpls_domain_config
*domain
;
179 struct mpls_range_config
*range
;
182 struct mpls_domain
*dom
;
185 void mpls_show_ranges(struct mpls_show_ranges_cmd
*cmd
);