]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_ecommunity.h
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / bgpd / bgp_ecommunity.h
1 /* BGP Extended Communities Attribute.
2 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef _QUAGGA_BGP_ECOMMUNITY_H
22 #define _QUAGGA_BGP_ECOMMUNITY_H
23
24 #include "bgpd/bgp_route.h"
25 #include "bgpd/bgp_rpki.h"
26 #include "bgpd/bgpd.h"
27
28 /* Refer to rfc7153 for the IANA registry definitions. These are
29 * updated by other standards like rfc7674.
30 */
31 /* High-order octet of the Extended Communities type field. */
32 #define ECOMMUNITY_ENCODE_AS 0x00
33 #define ECOMMUNITY_ENCODE_IP 0x01
34 #define ECOMMUNITY_ENCODE_AS4 0x02
35 #define ECOMMUNITY_ENCODE_OPAQUE 0x03
36 #define ECOMMUNITY_ENCODE_EVPN 0x06
37 #define ECOMMUNITY_ENCODE_REDIRECT_IP_NH 0x08 /* Flow Spec */
38 /* Generic Transitive Experimental */
39 #define ECOMMUNITY_ENCODE_TRANS_EXP 0x80
40
41 /* RFC7674 */
42 #define ECOMMUNITY_EXTENDED_COMMUNITY_PART_2 0x81
43 #define ECOMMUNITY_EXTENDED_COMMUNITY_PART_3 0x82
44
45 /* Non-transitive extended community types. */
46 #define ECOMMUNITY_ENCODE_AS_NON_TRANS 0x40
47 #define ECOMMUNITY_ENCODE_IP_NON_TRANS 0x41
48 #define ECOMMUNITY_ENCODE_AS4_NON_TRANS 0x42
49 #define ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS 0x43
50
51 /* Low-order octet of the Extended Communities type field. */
52 /* Note: This really depends on the high-order octet. This means that
53 * multiple definitions for the same value are possible.
54 */
55 #define ECOMMUNITY_ORIGIN_VALIDATION_STATE 0x00
56 #define ECOMMUNITY_ROUTE_TARGET 0x02
57 #define ECOMMUNITY_SITE_ORIGIN 0x03
58 #define ECOMMUNITY_LINK_BANDWIDTH 0x04
59 #define ECOMMUNITY_TRAFFIC_RATE 0x06 /* Flow Spec */
60 #define ECOMMUNITY_TRAFFIC_ACTION 0x07
61 #define ECOMMUNITY_REDIRECT_VRF 0x08
62 #define ECOMMUNITY_TRAFFIC_MARKING 0x09
63 #define ECOMMUNITY_REDIRECT_IP_NH 0x00
64 /* from IANA: bgp-extended-communities/bgp-extended-communities.xhtml
65 * 0x0c Flow-spec Redirect to IPv4 - draft-ietf-idr-flowspec-redirect
66 */
67 #define ECOMMUNITY_FLOWSPEC_REDIRECT_IPV4 0x0c
68 /* from draft-ietf-idr-flow-spec-v6-09
69 * 0x0b Flow-spec Redirect to IPv6
70 */
71 #define ECOMMUNITY_FLOWSPEC_REDIRECT_IPV6 0x0b
72
73 /* Low-order octet of the Extended Communities type field for EVPN types */
74 #define ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY 0x00
75 #define ECOMMUNITY_EVPN_SUBTYPE_ESI_LABEL 0x01
76 #define ECOMMUNITY_EVPN_SUBTYPE_ES_IMPORT_RT 0x02
77 #define ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC 0x03
78 #define ECOMMUNITY_EVPN_SUBTYPE_DF_ELECTION 0x06
79 #define ECOMMUNITY_EVPN_SUBTYPE_DEF_GW 0x0d
80 #define ECOMMUNITY_EVPN_SUBTYPE_ND 0x08
81
82 #define ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY 0x01
83
84 /* DF alg bits - only lower 5 bits are applicable */
85 #define ECOMMUNITY_EVPN_SUBTYPE_DF_ALG_BITS 0x1f
86
87 #define ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG 0x01
88 #define ECOMMUNITY_EVPN_SUBTYPE_ND_OVERRIDE_FLAG 0x02
89 #define ECOMMUNITY_EVPN_SUBTYPE_PROXY_FLAG 0x04
90
91 #define ECOMMUNITY_EVPN_SUBTYPE_ESI_SA_FLAG (1 << 0) /* single-active */
92
93 /* Low-order octet of the Extended Communities type field for OPAQUE types */
94 #define ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP 0x0c
95
96 /* Extended communities attribute string format. */
97 #define ECOMMUNITY_FORMAT_ROUTE_MAP 0
98 #define ECOMMUNITY_FORMAT_COMMUNITY_LIST 1
99 #define ECOMMUNITY_FORMAT_DISPLAY 2
100
101 /* Extended Communities value is eight octet long. */
102 #define ECOMMUNITY_SIZE 8
103 #define IPV6_ECOMMUNITY_SIZE 20
104
105 /* Extended Community Origin Validation State */
106 enum ecommunity_origin_validation_states {
107 ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID,
108 ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND,
109 ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID,
110 ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED
111 };
112
113 /* Extended Communities type flag. */
114 #define ECOMMUNITY_FLAG_NON_TRANSITIVE 0x40
115
116 /* Extended Community readable string length */
117 #define ECOMMUNITY_STRLEN 64
118
119 /* Extended Communities attribute. */
120 struct ecommunity {
121 /* Reference counter. */
122 unsigned long refcnt;
123
124 /* Size of Each Unit of Extended Communities attribute.
125 * to differentiate between IPv6 ext comm and ext comm
126 */
127 uint8_t unit_size;
128
129 /* Size of Extended Communities attribute. */
130 uint32_t size;
131
132 /* Extended Communities value. */
133 uint8_t *val;
134
135 /* Human readable format string. */
136 char *str;
137
138 /* Disable IEEE floating-point encoding for extended community */
139 bool disable_ieee_floating;
140 };
141
142 struct ecommunity_as {
143 as_t as;
144 uint32_t val;
145 };
146
147 struct ecommunity_ip {
148 struct in_addr ip;
149 uint16_t val;
150 };
151
152 struct ecommunity_ip6 {
153 struct in6_addr ip;
154 uint16_t val;
155 };
156
157 /* Extended community value is eight octet. */
158 struct ecommunity_val {
159 char val[ECOMMUNITY_SIZE];
160 };
161
162 /* IPv6 Extended community value is eight octet. */
163 struct ecommunity_val_ipv6 {
164 char val[IPV6_ECOMMUNITY_SIZE];
165 };
166
167 #define ecom_length_size(X, Y) ((X)->size * (Y))
168
169 /*
170 * Encode BGP Route Target AS:nn.
171 */
172 static inline void encode_route_target_as(as_t as, uint32_t val,
173 struct ecommunity_val *eval)
174 {
175 eval->val[0] = ECOMMUNITY_ENCODE_AS;
176 eval->val[1] = ECOMMUNITY_ROUTE_TARGET;
177 eval->val[2] = (as >> 8) & 0xff;
178 eval->val[3] = as & 0xff;
179 eval->val[4] = (val >> 24) & 0xff;
180 eval->val[5] = (val >> 16) & 0xff;
181 eval->val[6] = (val >> 8) & 0xff;
182 eval->val[7] = val & 0xff;
183 }
184
185 /*
186 * Encode BGP Route Target IP:nn.
187 */
188 static inline void encode_route_target_ip(struct in_addr ip, uint16_t val,
189 struct ecommunity_val *eval)
190 {
191 eval->val[0] = ECOMMUNITY_ENCODE_IP;
192 eval->val[1] = ECOMMUNITY_ROUTE_TARGET;
193 memcpy(&eval->val[2], &ip, sizeof(struct in_addr));
194 eval->val[6] = (val >> 8) & 0xff;
195 eval->val[7] = val & 0xff;
196 }
197
198 /*
199 * Encode BGP Route Target AS4:nn.
200 */
201 static inline void encode_route_target_as4(as_t as, uint16_t val,
202 struct ecommunity_val *eval)
203 {
204 eval->val[0] = ECOMMUNITY_ENCODE_AS4;
205 eval->val[1] = ECOMMUNITY_ROUTE_TARGET;
206 eval->val[2] = (as >> 24) & 0xff;
207 eval->val[3] = (as >> 16) & 0xff;
208 eval->val[4] = (as >> 8) & 0xff;
209 eval->val[5] = as & 0xff;
210 eval->val[6] = (val >> 8) & 0xff;
211 eval->val[7] = val & 0xff;
212 }
213
214 /* Helper function to convert uint32 to IEEE-754 Floating Point */
215 static uint32_t uint32_to_ieee_float_uint32(uint32_t u)
216 {
217 union {
218 float r;
219 uint32_t d;
220 } f = {.r = (float)u};
221
222 return f.d;
223 }
224
225 /*
226 * Encode BGP Link Bandwidth extended community
227 * bandwidth (bw) is in bytes-per-sec
228 */
229 static inline void encode_lb_extcomm(as_t as, uint32_t bw, bool non_trans,
230 struct ecommunity_val *eval,
231 bool disable_ieee_floating)
232 {
233 uint32_t bandwidth =
234 disable_ieee_floating ? bw : uint32_to_ieee_float_uint32(bw);
235
236 memset(eval, 0, sizeof(*eval));
237 eval->val[0] = ECOMMUNITY_ENCODE_AS;
238 if (non_trans)
239 eval->val[0] |= ECOMMUNITY_FLAG_NON_TRANSITIVE;
240 eval->val[1] = ECOMMUNITY_LINK_BANDWIDTH;
241 eval->val[2] = (as >> 8) & 0xff;
242 eval->val[3] = as & 0xff;
243 eval->val[4] = (bandwidth >> 24) & 0xff;
244 eval->val[5] = (bandwidth >> 16) & 0xff;
245 eval->val[6] = (bandwidth >> 8) & 0xff;
246 eval->val[7] = bandwidth & 0xff;
247 }
248
249 static inline void encode_origin_validation_state(enum rpki_states state,
250 struct ecommunity_val *eval)
251 {
252 enum ecommunity_origin_validation_states ovs_state =
253 ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED;
254
255 switch (state) {
256 case RPKI_VALID:
257 ovs_state = ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID;
258 break;
259 case RPKI_NOTFOUND:
260 ovs_state = ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND;
261 break;
262 case RPKI_INVALID:
263 ovs_state = ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID;
264 break;
265 case RPKI_NOT_BEING_USED:
266 break;
267 }
268
269 memset(eval, 0, sizeof(*eval));
270 eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS;
271 eval->val[1] = ECOMMUNITY_ORIGIN_VALIDATION_STATE;
272 eval->val[7] = ovs_state;
273 }
274
275 extern void ecommunity_init(void);
276 extern void ecommunity_finish(void);
277 extern void ecommunity_free(struct ecommunity **);
278 extern struct ecommunity *ecommunity_parse(uint8_t *, unsigned short,
279 bool disable_ieee_floating);
280 extern struct ecommunity *ecommunity_parse_ipv6(uint8_t *pnt,
281 unsigned short length,
282 bool disable_ieee_floating);
283 extern struct ecommunity *ecommunity_dup(struct ecommunity *);
284 extern struct ecommunity *ecommunity_merge(struct ecommunity *,
285 struct ecommunity *);
286 extern struct ecommunity *ecommunity_uniq_sort(struct ecommunity *);
287 extern struct ecommunity *ecommunity_intern(struct ecommunity *);
288 extern bool ecommunity_cmp(const void *arg1, const void *arg2);
289 extern void ecommunity_unintern(struct ecommunity **ecommunity);
290 extern unsigned int ecommunity_hash_make(const void *);
291 extern struct ecommunity *ecommunity_str2com(const char *, int, int);
292 extern struct ecommunity *ecommunity_str2com_ipv6(const char *str, int type,
293 int keyword_included);
294 extern char *ecommunity_ecom2str(struct ecommunity *, int, int);
295 extern void ecommunity_strfree(char **s);
296 extern bool ecommunity_include(struct ecommunity *e1, struct ecommunity *e2);
297 extern bool ecommunity_match(const struct ecommunity *,
298 const struct ecommunity *);
299 extern char *ecommunity_str(struct ecommunity *);
300 extern struct ecommunity_val *ecommunity_lookup(const struct ecommunity *,
301 uint8_t, uint8_t);
302
303 extern bool ecommunity_add_val(struct ecommunity *ecom,
304 struct ecommunity_val *eval,
305 bool unique, bool overwrite);
306 extern bool ecommunity_add_val_ipv6(struct ecommunity *ecom,
307 struct ecommunity_val_ipv6 *eval,
308 bool unique, bool overwrite);
309
310 /* for vpn */
311 extern struct ecommunity *ecommunity_new(void);
312 extern bool ecommunity_strip(struct ecommunity *ecom, uint8_t type,
313 uint8_t subtype);
314 extern struct ecommunity *ecommunity_new(void);
315 extern bool ecommunity_del_val(struct ecommunity *ecom,
316 struct ecommunity_val *eval);
317 struct bgp_pbr_entry_action;
318 extern int ecommunity_fill_pbr_action(struct ecommunity_val *ecom_eval,
319 struct bgp_pbr_entry_action *api,
320 afi_t afi);
321
322 extern void bgp_compute_aggregate_ecommunity(
323 struct bgp_aggregate *aggregate,
324 struct ecommunity *ecommunity);
325
326 extern void bgp_compute_aggregate_ecommunity_hash(
327 struct bgp_aggregate *aggregate,
328 struct ecommunity *ecommunity);
329 extern void bgp_compute_aggregate_ecommunity_val(
330 struct bgp_aggregate *aggregate);
331 extern void bgp_remove_ecommunity_from_aggregate(
332 struct bgp_aggregate *aggregate,
333 struct ecommunity *ecommunity);
334 extern void bgp_remove_ecomm_from_aggregate_hash(
335 struct bgp_aggregate *aggregate,
336 struct ecommunity *ecommunity);
337 extern void bgp_aggr_ecommunity_remove(void *arg);
338 extern const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom,
339 uint32_t *bw);
340 extern struct ecommunity *ecommunity_replace_linkbw(as_t as,
341 struct ecommunity *ecom,
342 uint64_t cum_bw,
343 bool disable_ieee_floating);
344
345 static inline void ecommunity_strip_rts(struct ecommunity *ecom)
346 {
347 uint8_t subtype = ECOMMUNITY_ROUTE_TARGET;
348
349 ecommunity_strip(ecom, ECOMMUNITY_ENCODE_AS, subtype);
350 ecommunity_strip(ecom, ECOMMUNITY_ENCODE_IP, subtype);
351 ecommunity_strip(ecom, ECOMMUNITY_ENCODE_AS4, subtype);
352 }
353 extern struct ecommunity *
354 ecommunity_add_origin_validation_state(enum rpki_states rpki_state,
355 struct ecommunity *ecom);
356 #endif /* _QUAGGA_BGP_ECOMMUNITY_H */