1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 1996, 97, 98 Kunihiro Ishiguro
6 #ifndef _QUAGGA_BGP_ATTR_H
7 #define _QUAGGA_BGP_ATTR_H
10 #include "bgp_attr_evpn.h"
11 #include "bgpd/bgp_encap_types.h"
14 /* Simple bit mapping. */
17 #define SET_BITMAP(MAP, NUM) \
18 SET_FLAG(MAP[(NUM) / BITMAP_NBBY], 1 << ((NUM) % BITMAP_NBBY))
20 #define CHECK_BITMAP(MAP, NUM) \
21 CHECK_FLAG(MAP[(NUM) / BITMAP_NBBY], 1 << ((NUM) % BITMAP_NBBY))
23 #define BGP_MED_MAX UINT32_MAX
25 /* BGP Attribute type range. */
26 #define BGP_ATTR_TYPE_RANGE 256
27 #define BGP_ATTR_BITMAP_SIZE (BGP_ATTR_TYPE_RANGE / BITMAP_NBBY)
29 /* BGP Attribute flags. */
30 #define BGP_ATTR_FLAG_OPTIONAL 0x80 /* Attribute is optional. */
31 #define BGP_ATTR_FLAG_TRANS 0x40 /* Attribute is transitive. */
32 #define BGP_ATTR_FLAG_PARTIAL 0x20 /* Attribute is partial. */
33 #define BGP_ATTR_FLAG_EXTLEN 0x10 /* Extended length flag. */
35 /* BGP attribute header must bigger than 2. */
36 #define BGP_ATTR_MIN_LEN 3 /* Attribute flag, type length. */
37 #define BGP_ATTR_DEFAULT_WEIGHT 32768
39 /* Valid lengths for mp_nexthop_len */
40 #define BGP_ATTR_NHLEN_IPV4 IPV4_MAX_BYTELEN
41 #define BGP_ATTR_NHLEN_VPNV4 8+IPV4_MAX_BYTELEN
42 #define BGP_ATTR_NHLEN_IPV6_GLOBAL IPV6_MAX_BYTELEN
43 #define BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL (IPV6_MAX_BYTELEN * 2)
44 #define BGP_ATTR_NHLEN_VPNV6_GLOBAL 8+IPV6_MAX_BYTELEN
45 #define BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL ((8+IPV6_MAX_BYTELEN) * 2)
47 /* Prefix SID types */
48 #define BGP_PREFIX_SID_LABEL_INDEX 1
49 #define BGP_PREFIX_SID_IPV6 2
50 #define BGP_PREFIX_SID_ORIGINATOR_SRGB 3
51 #define BGP_PREFIX_SID_VPN_SID 4
52 #define BGP_PREFIX_SID_SRV6_L3_SERVICE 5
53 #define BGP_PREFIX_SID_SRV6_L2_SERVICE 6
55 #define BGP_PREFIX_SID_LABEL_INDEX_LENGTH 7
56 #define BGP_PREFIX_SID_IPV6_LENGTH 19
57 #define BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH 6
58 #define BGP_PREFIX_SID_VPN_SID_LENGTH 19
60 /* SRv6 Service Sub-TLV types */
61 #define BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO 1
62 #define BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO_LENGTH 21
64 /* SRv6 Service Data Sub-Sub-TLV types */
65 #define BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE 1
66 #define BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE_LENGTH 6
68 #define BGP_ATTR_NH_AFI(afi, attr) \
69 ((afi != AFI_L2VPN) ? afi : \
70 ((attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV4) ? AFI_IP : AFI_IP6))
72 /* PMSI tunnel types (RFC 6514) */
74 struct bgp_attr_encap_subtlv
{
75 struct bgp_attr_encap_subtlv
*next
; /* for chaining */
76 /* Reference count of this attribute. */
80 uint8_t value
[0]; /* will be extended */
85 * old rfp<->rfapi representation
87 struct bgp_tea_options
{
88 struct bgp_tea_options
*next
;
89 uint8_t options_count
;
90 uint16_t options_length
; /* each TLV may be 256 in length */
93 void *value
; /* pointer to data */
99 PMSI_TNLTYPE_NO_INFO
= 0,
100 PMSI_TNLTYPE_RSVP_TE_P2MP
,
101 PMSI_TNLTYPE_MLDP_P2MP
,
102 PMSI_TNLTYPE_PIM_SSM
,
104 PMSI_TNLTYPE_PIM_BIDIR
,
105 PMSI_TNLTYPE_INGR_REPL
,
106 PMSI_TNLTYPE_MLDP_MP2MP
,
107 PMSI_TNLTYPE_MAX
= PMSI_TNLTYPE_MLDP_MP2MP
113 * draft-dawra-idr-srv6-vpn-04
115 struct bgp_attr_srv6_vpn
{
116 unsigned long refcnt
;
123 * SRv6-L3VPN-Service-TLV
124 * draft-dawra-idr-srv6-vpn-05
126 struct bgp_attr_srv6_l3vpn
{
127 unsigned long refcnt
;
129 uint16_t endpoint_behavior
;
131 uint8_t loc_block_len
;
132 uint8_t loc_node_len
;
135 uint8_t transposition_len
;
136 uint8_t transposition_offset
;
139 /* BGP core attribute structure. */
141 /* AS Path structure */
142 struct aspath
*aspath
;
144 /* Community structure */
145 struct community
*community
;
147 /* Reference count of this attribute. */
148 unsigned long refcnt
;
150 /* Flag of attribute is set or not. */
153 /* Apart from in6_addr, the remaining static attributes */
154 struct in_addr nexthop
;
157 ifindex_t nh_ifindex
;
159 /* Path origin attribute */
162 /* PMSI tunnel type (RFC 6514). */
163 enum pta_type pmsi_tnl_type
;
165 /* has the route-map changed any attribute?
166 Used on the peer outbound side. */
167 uint32_t rmap_change_flags
;
169 /* Multi-Protocol Nexthop, AFI IPv6 */
170 struct in6_addr mp_nexthop_global
;
171 struct in6_addr mp_nexthop_local
;
173 /* ifIndex corresponding to mp_nexthop_local. */
174 ifindex_t nh_lla_ifindex
;
176 /* Extended Communities attribute. */
177 struct ecommunity
*ecommunity
;
179 /* Extended Communities attribute. */
180 struct ecommunity
*ipv6_ecommunity
;
182 /* Large Communities attribute. */
183 struct lcommunity
*lcommunity
;
185 /* Route-Reflector Cluster attribute */
186 struct cluster_list
*cluster1
;
188 /* Unknown transitive attribute. */
189 struct transit
*transit
;
191 struct in_addr mp_nexthop_global_in
;
193 /* Aggregator Router ID attribute */
194 struct in_addr aggregator_addr
;
196 /* Route Reflector Originator attribute */
197 struct in_addr originator_id
;
199 /* Local weight, not actually an attribute */
205 /* MP Nexthop length */
206 uint8_t mp_nexthop_len
;
208 /* MP Nexthop preference */
209 uint8_t mp_nexthop_prefer_global
;
211 /* Static MAC for EVPN */
214 /* Flag for default gateway extended community in EVPN */
217 /* NA router flag (R-bit) support in EVPN */
222 /* Path is not "locally-active" on the advertising VTEP. This is
223 * translated into an ARP-ND ECOM.
225 #define ATTR_ES_PROXY_ADVERT (1 << 0)
226 /* Destination ES is present locally. This flag is set on local
227 * paths and sync paths
229 #define ATTR_ES_IS_LOCAL (1 << 1)
230 /* There are one or more non-best paths from ES peers. Note that
231 * this flag is only set on the local MAC-IP paths in the VNI
232 * route table (not set in the global routing table). And only
233 * non-proxy advertisements from an ES peer can result in this
236 #define ATTR_ES_PEER_ACTIVE (1 << 2)
237 /* There are one or more non-best proxy paths from ES peers */
238 #define ATTR_ES_PEER_PROXY (1 << 3)
239 /* An ES peer has router bit set - only applicable if
240 * ATTR_ES_PEER_ACTIVE is set
242 #define ATTR_ES_PEER_ROUTER (1 << 4)
244 /* These two flags are only set on L3 routes installed in a
245 * VRF as a result of EVPN MAC-IP route
246 * XXX - while splitting up per-family attrs these need to be
247 * classified as non-EVPN
249 #define ATTR_ES_L3_NHG_USE (1 << 5)
250 #define ATTR_ES_L3_NHG_ACTIVE (1 << 6)
251 #define ATTR_ES_L3_NHG (ATTR_ES_L3_NHG_USE | ATTR_ES_L3_NHG_ACTIVE)
257 uint32_t label_index
;
263 struct bgp_attr_srv6_vpn
*srv6_vpn
;
266 struct bgp_attr_srv6_l3vpn
*srv6_l3vpn
;
268 uint16_t encap_tunneltype
; /* grr */
269 struct bgp_attr_encap_subtlv
*encap_subtlvs
; /* rfc5512 */
271 #ifdef ENABLE_BGP_VNC
272 struct bgp_attr_encap_subtlv
*vnc_subtlvs
; /* VNC-specific */
275 struct bgp_route_evpn evpn_overlay
;
277 /* EVPN MAC Mobility sequence number, if any. */
279 /* highest MM sequence number rxed in a MAC-IP route from an
280 * ES peer (this includes both proxy and non-proxy MAC-IP
281 * advertisements from ES peers).
282 * This is only applicable to local paths in the VNI routing
283 * table and derived from other imported/non-best paths.
285 uint32_t mm_sync_seqnum
;
287 /* EVPN local router-mac */
290 /* Distance as applied by Route map */
294 uint32_t rmap_table_id
;
296 /* Link bandwidth value, if any. */
305 /* EVPN DF preference and algorithm for DF election on local ESs */
310 enum nexthop_types_t nh_type
;
312 /* If NEXTHOP_TYPE_BLACKHOLE, then blackhole type */
313 enum blackhole_type bh_type
;
315 /* OTC value if set */
319 uint64_t aigp_metric
;
322 /* rmap_change_flags definition */
323 #define BATTR_RMAP_IPV4_NHOP_CHANGED (1 << 0)
324 #define BATTR_RMAP_NEXTHOP_PEER_ADDRESS (1 << 1)
325 #define BATTR_REFLECTED (1 << 2)
326 #define BATTR_RMAP_NEXTHOP_UNCHANGED (1 << 3)
327 #define BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED (1 << 4)
328 #define BATTR_RMAP_IPV6_LL_NHOP_CHANGED (1 << 5)
329 #define BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED (1 << 6)
330 #define BATTR_RMAP_LINK_BW_SET (1 << 7)
331 #define BATTR_RMAP_L3VPN_ACCEPT_GRE (1 << 8)
332 #define BATTR_RMAP_VPNV4_NHOP_CHANGED (1 << 9)
333 #define BATTR_RMAP_VPNV6_GLOBAL_NHOP_CHANGED (1 << 10)
335 /* Router Reflector related structure. */
336 struct cluster_list
{
337 unsigned long refcnt
;
339 struct in_addr
*list
;
342 /* Unknown transit attribute. */
344 unsigned long refcnt
;
349 /* "(void) 0" will generate a compiler error. this is a safety check to
350 * ensure we're not using a value that exceeds the bit size of attr->flag. */
351 #define ATTR_FLAG_BIT(X) \
352 __builtin_choose_expr((X) >= 1 && (X) <= 64, 1ULL << ((X)-1), (void)0)
354 #define BGP_CLUSTER_LIST_LENGTH(attr) \
355 (((attr)->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) \
356 ? bgp_attr_get_cluster((attr))->length \
359 enum bgp_attr_parse_ret
{
360 BGP_ATTR_PARSE_PROCEED
= 0,
361 BGP_ATTR_PARSE_ERROR
= -1,
362 BGP_ATTR_PARSE_WITHDRAW
= -2,
364 /* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR
366 BGP_ATTR_PARSE_ERROR_NOTIFYPLS
= -3,
367 BGP_ATTR_PARSE_EOR
= -4,
370 struct bpacket_attr_vec_arr
;
373 extern void bgp_attr_init(void);
374 extern void bgp_attr_finish(void);
375 extern enum bgp_attr_parse_ret
376 bgp_attr_parse(struct peer
*peer
, struct attr
*attr
, bgp_size_t size
,
377 struct bgp_nlri
*mp_update
, struct bgp_nlri
*mp_withdraw
);
378 extern struct attr
*bgp_attr_intern(struct attr
*attr
);
379 extern void bgp_attr_unintern_sub(struct attr
*attr
);
380 extern void bgp_attr_unintern(struct attr
**pattr
);
381 extern void bgp_attr_flush(struct attr
*attr
);
382 extern struct attr
*bgp_attr_default_set(struct attr
*attr
, struct bgp
*bgp
,
384 extern struct attr
*bgp_attr_aggregate_intern(
385 struct bgp
*bgp
, uint8_t origin
, struct aspath
*aspath
,
386 struct community
*community
, struct ecommunity
*ecommunity
,
387 struct lcommunity
*lcommunity
, struct bgp_aggregate
*aggregate
,
388 uint8_t atomic_aggregate
, const struct prefix
*p
);
389 extern bgp_size_t
bgp_packet_attribute(
390 struct bgp
*bgp
, struct peer
*peer
, struct stream
*s
, struct attr
*attr
,
391 struct bpacket_attr_vec_arr
*vecarr
, struct prefix
*p
, afi_t afi
,
392 safi_t safi
, struct peer
*from
, struct prefix_rd
*prd
,
393 mpls_label_t
*label
, uint32_t num_labels
, bool addpath_capable
,
394 uint32_t addpath_tx_id
, struct bgp_path_info
*bpi
);
395 extern void bgp_dump_routes_attr(struct stream
*s
, struct bgp_path_info
*bpi
,
396 const struct prefix
*p
);
397 extern bool attrhash_cmp(const void *arg1
, const void *arg2
);
398 extern unsigned int attrhash_key_make(const void *p
);
399 extern void attr_show_all(struct vty
*vty
);
400 extern unsigned long int attr_count(void);
401 extern unsigned long int attr_unknown_count(void);
402 extern void bgp_path_attribute_discard_vty(struct vty
*vty
, struct peer
*peer
,
403 const char *discard_attrs
, bool set
);
404 extern void bgp_path_attribute_withdraw_vty(struct vty
*vty
, struct peer
*peer
,
405 const char *withdraw_attrs
,
407 extern enum bgp_attr_parse_ret
bgp_attr_ignore(struct peer
*peer
, uint8_t type
);
409 /* Cluster list prototypes. */
410 extern bool cluster_loop_check(struct cluster_list
*cluster
,
411 struct in_addr originator
);
413 /* Below exported for unit-test purposes only */
414 struct bgp_attr_parser_args
{
416 bgp_size_t length
; /* attribute data length; */
417 bgp_size_t total
; /* total length, inc header */
423 extern int bgp_mp_reach_parse(struct bgp_attr_parser_args
*args
,
424 struct bgp_nlri
*mp_update
);
425 extern int bgp_mp_unreach_parse(struct bgp_attr_parser_args
*args
,
426 struct bgp_nlri
*mp_withdraw
);
427 extern enum bgp_attr_parse_ret
428 bgp_attr_prefix_sid(struct bgp_attr_parser_args
*args
);
430 extern struct bgp_attr_encap_subtlv
*
431 encap_tlv_dup(struct bgp_attr_encap_subtlv
*orig
);
433 extern void bgp_attr_flush_encap(struct attr
*attr
);
435 extern void bgp_attr_extcom_tunnel_type(struct attr
*attr
,
436 bgp_encap_types
*tunnel_type
);
439 * Set of functions to encode MP_REACH_NLRI and MP_UNREACH_NLRI attributes.
440 * Typical call sequence is to call _start(), followed by multiple _prefix(),
441 * one for each NLRI that needs to be encoded into the UPDATE message, and
442 * finally the _end() function.
444 extern size_t bgp_packet_mpattr_start(struct stream
*s
, struct peer
*peer
,
445 afi_t afi
, safi_t safi
,
446 struct bpacket_attr_vec_arr
*vecarr
,
448 extern void bgp_packet_mpattr_prefix(struct stream
*s
, afi_t afi
, safi_t safi
,
449 const struct prefix
*p
,
450 const struct prefix_rd
*prd
,
451 mpls_label_t
*label
, uint32_t num_labels
,
452 bool addpath_capable
,
453 uint32_t addpath_tx_id
, struct attr
*);
454 extern size_t bgp_packet_mpattr_prefix_size(afi_t afi
, safi_t safi
,
455 const struct prefix
*p
);
456 extern void bgp_packet_mpattr_end(struct stream
*s
, size_t sizep
);
458 extern size_t bgp_packet_mpunreach_start(struct stream
*s
, afi_t afi
,
460 extern void bgp_packet_mpunreach_prefix(
461 struct stream
*s
, const struct prefix
*p
, afi_t afi
, safi_t safi
,
462 const struct prefix_rd
*prd
, mpls_label_t
*label
, uint32_t num_labels
,
463 bool addpath_capable
, uint32_t addpath_tx_id
, struct attr
*attr
);
464 extern void bgp_packet_mpunreach_end(struct stream
*s
, size_t attrlen_pnt
);
466 extern enum bgp_attr_parse_ret
bgp_attr_nexthop_valid(struct peer
*peer
,
469 static inline bool bgp_rmap_nhop_changed(uint32_t out_rmap_flags
,
470 uint32_t in_rmap_flags
)
472 return ((CHECK_FLAG(out_rmap_flags
, BATTR_RMAP_NEXTHOP_PEER_ADDRESS
) ||
473 CHECK_FLAG(out_rmap_flags
, BATTR_RMAP_NEXTHOP_UNCHANGED
) ||
474 CHECK_FLAG(out_rmap_flags
, BATTR_RMAP_IPV4_NHOP_CHANGED
) ||
475 CHECK_FLAG(out_rmap_flags
, BATTR_RMAP_VPNV4_NHOP_CHANGED
) ||
476 CHECK_FLAG(out_rmap_flags
,
477 BATTR_RMAP_VPNV6_GLOBAL_NHOP_CHANGED
) ||
478 CHECK_FLAG(out_rmap_flags
,
479 BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED
) ||
480 CHECK_FLAG(out_rmap_flags
,
481 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
) ||
482 CHECK_FLAG(out_rmap_flags
, BATTR_RMAP_IPV6_LL_NHOP_CHANGED
) ||
483 CHECK_FLAG(in_rmap_flags
, BATTR_RMAP_NEXTHOP_UNCHANGED
))
488 static inline uint32_t mac_mobility_seqnum(struct attr
*attr
)
490 return (attr
) ? attr
->mm_seqnum
: 0;
493 static inline enum pta_type
bgp_attr_get_pmsi_tnl_type(struct attr
*attr
)
495 return attr
->pmsi_tnl_type
;
498 static inline void bgp_attr_set_pmsi_tnl_type(struct attr
*attr
,
499 enum pta_type pmsi_tnl_type
)
501 attr
->pmsi_tnl_type
= pmsi_tnl_type
;
504 static inline struct ecommunity
*
505 bgp_attr_get_ecommunity(const struct attr
*attr
)
507 return attr
->ecommunity
;
510 static inline void bgp_attr_set_ecommunity(struct attr
*attr
,
511 struct ecommunity
*ecomm
)
513 attr
->ecommunity
= ecomm
;
516 SET_FLAG(attr
->flag
, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
518 UNSET_FLAG(attr
->flag
, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
521 static inline struct lcommunity
*
522 bgp_attr_get_lcommunity(const struct attr
*attr
)
524 return attr
->lcommunity
;
527 static inline void bgp_attr_set_lcommunity(struct attr
*attr
,
528 struct lcommunity
*lcomm
)
530 attr
->lcommunity
= lcomm
;
533 SET_FLAG(attr
->flag
, ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
));
535 UNSET_FLAG(attr
->flag
,
536 ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
));
539 static inline struct community
*bgp_attr_get_community(const struct attr
*attr
)
541 return attr
->community
;
544 static inline void bgp_attr_set_community(struct attr
*attr
,
545 struct community
*comm
)
547 attr
->community
= comm
;
550 SET_FLAG(attr
->flag
, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
));
552 UNSET_FLAG(attr
->flag
, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
));
555 static inline struct ecommunity
*
556 bgp_attr_get_ipv6_ecommunity(const struct attr
*attr
)
558 return attr
->ipv6_ecommunity
;
561 static inline void bgp_attr_set_ipv6_ecommunity(struct attr
*attr
,
562 struct ecommunity
*ipv6_ecomm
)
564 attr
->ipv6_ecommunity
= ipv6_ecomm
;
568 ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES
));
570 UNSET_FLAG(attr
->flag
,
571 ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES
));
574 static inline struct transit
*bgp_attr_get_transit(const struct attr
*attr
)
576 return attr
->transit
;
579 static inline void bgp_attr_set_transit(struct attr
*attr
,
580 struct transit
*transit
)
582 attr
->transit
= transit
;
585 static inline uint64_t bgp_attr_get_aigp_metric(const struct attr
*attr
)
587 return attr
->aigp_metric
;
590 static inline void bgp_attr_set_aigp_metric(struct attr
*attr
, uint64_t aigp
)
592 attr
->aigp_metric
= aigp
;
595 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_AIGP
);
598 static inline struct cluster_list
*bgp_attr_get_cluster(const struct attr
*attr
)
600 return attr
->cluster1
;
603 static inline void bgp_attr_set_cluster(struct attr
*attr
,
604 struct cluster_list
*cl
)
609 static inline const struct bgp_route_evpn
*
610 bgp_attr_get_evpn_overlay(const struct attr
*attr
)
612 return &attr
->evpn_overlay
;
615 static inline void bgp_attr_set_evpn_overlay(struct attr
*attr
,
616 struct bgp_route_evpn
*eo
)
618 memcpy(&attr
->evpn_overlay
, eo
, sizeof(struct bgp_route_evpn
));
621 static inline struct bgp_attr_encap_subtlv
*
622 bgp_attr_get_vnc_subtlvs(const struct attr
*attr
)
624 #ifdef ENABLE_BGP_VNC
625 return attr
->vnc_subtlvs
;
632 bgp_attr_set_vnc_subtlvs(struct attr
*attr
,
633 struct bgp_attr_encap_subtlv
*vnc_subtlvs
)
635 #ifdef ENABLE_BGP_VNC
636 attr
->vnc_subtlvs
= vnc_subtlvs
;
640 #endif /* _QUAGGA_BGP_ATTR_H */