1 /* BGP Extended Communities Attribute.
2 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
4 * This file is part of GNU Zebra.
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
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.
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
21 #ifndef _QUAGGA_BGP_ECOMMUNITY_H
22 #define _QUAGGA_BGP_ECOMMUNITY_H
24 #include "bgpd/bgp_route.h"
25 #include "bgpd/bgp_rpki.h"
26 #include "bgpd/bgpd.h"
28 /* Refer to rfc7153 for the IANA registry definitions. These are
29 * updated by other standards like rfc7674.
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
42 #define ECOMMUNITY_EXTENDED_COMMUNITY_PART_2 0x81
43 #define ECOMMUNITY_EXTENDED_COMMUNITY_PART_3 0x82
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
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.
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
67 #define ECOMMUNITY_FLOWSPEC_REDIRECT_IPV4 0x0c
68 /* from draft-ietf-idr-flow-spec-v6-09
69 * 0x0b Flow-spec Redirect to IPv6
71 #define ECOMMUNITY_FLOWSPEC_REDIRECT_IPV6 0x0b
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
82 #define ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY 0x01
84 /* DF alg bits - only lower 5 bits are applicable */
85 #define ECOMMUNITY_EVPN_SUBTYPE_DF_ALG_BITS 0x1f
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
91 #define ECOMMUNITY_EVPN_SUBTYPE_ESI_SA_FLAG (1 << 0) /* single-active */
93 /* Low-order octet of the Extended Communities type field for OPAQUE types */
94 #define ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP 0x0c
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
101 /* Extended Communities value is eight octet long. */
102 #define ECOMMUNITY_SIZE 8
103 #define IPV6_ECOMMUNITY_SIZE 20
105 /* Extended Community Origin Validation State */
106 enum ecommunity_origin_validation_states
{
107 ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED
= -1,
108 ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID
,
109 ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND
,
110 ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID
113 /* Extended Communities type flag. */
114 #define ECOMMUNITY_FLAG_NON_TRANSITIVE 0x40
116 /* Extended Community readable string length */
117 #define ECOMMUNITY_STRLEN 64
119 /* Extended Communities attribute. */
121 /* Reference counter. */
122 unsigned long refcnt
;
124 /* Size of Each Unit of Extended Communities attribute.
125 * to differentiate between IPv6 ext comm and ext comm
129 /* Size of Extended Communities attribute. */
132 /* Extended Communities value. */
135 /* Human readable format string. */
138 /* Disable IEEE floating-point encoding for extended community */
139 bool disable_ieee_floating
;
142 struct ecommunity_as
{
147 struct ecommunity_ip
{
152 struct ecommunity_ip6
{
157 /* Extended community value is eight octet. */
158 struct ecommunity_val
{
159 char val
[ECOMMUNITY_SIZE
];
162 /* IPv6 Extended community value is eight octet. */
163 struct ecommunity_val_ipv6
{
164 char val
[IPV6_ECOMMUNITY_SIZE
];
167 #define ecom_length_size(X, Y) ((X)->size * (Y))
170 * Encode BGP Route Target AS:nn.
172 static inline void encode_route_target_as(as_t as
, uint32_t val
,
173 struct ecommunity_val
*eval
)
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;
186 * Encode BGP Route Target IP:nn.
188 static inline void encode_route_target_ip(struct in_addr ip
, uint16_t val
,
189 struct ecommunity_val
*eval
)
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;
199 * Encode BGP Route Target AS4:nn.
201 static inline void encode_route_target_as4(as_t as
, uint16_t val
,
202 struct ecommunity_val
*eval
)
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;
214 /* Helper function to convert uint32 to IEEE-754 Floating Point */
215 static uint32_t uint32_to_ieee_float_uint32(uint32_t u
)
220 } f
= {.r
= (float)u
};
226 * Encode BGP Link Bandwidth extended community
227 * bandwidth (bw) is in bytes-per-sec
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
)
234 disable_ieee_floating
? bw
: uint32_to_ieee_float_uint32(bw
);
236 memset(eval
, 0, sizeof(*eval
));
237 eval
->val
[0] = ECOMMUNITY_ENCODE_AS
;
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;
249 static inline void encode_origin_validation_state(enum rpki_states state
,
250 struct ecommunity_val
*eval
)
252 enum ecommunity_origin_validation_states ovs_state
=
253 ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED
;
257 ovs_state
= ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID
;
260 ovs_state
= ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND
;
263 ovs_state
= ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID
;
265 case RPKI_NOT_BEING_USED
:
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
;
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
*,
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
);
311 extern struct ecommunity
*ecommunity_new(void);
312 extern bool ecommunity_strip(struct ecommunity
*ecom
, uint8_t type
,
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
,
322 extern void bgp_compute_aggregate_ecommunity(
323 struct bgp_aggregate
*aggregate
,
324 struct ecommunity
*ecommunity
);
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
,
340 extern struct ecommunity
*ecommunity_replace_linkbw(as_t as
,
341 struct ecommunity
*ecom
,
343 bool disable_ieee_floating
);
345 static inline void ecommunity_strip_rts(struct ecommunity
*ecom
)
347 uint8_t subtype
= ECOMMUNITY_ROUTE_TARGET
;
349 ecommunity_strip(ecom
, ECOMMUNITY_ENCODE_AS
, subtype
);
350 ecommunity_strip(ecom
, ECOMMUNITY_ENCODE_IP
, subtype
);
351 ecommunity_strip(ecom
, ECOMMUNITY_ENCODE_AS4
, subtype
);
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 */