]>
Commit | Line | Data |
---|---|---|
2638249d MM |
1 | /* |
2 | * BIRD -- The Border Gateway Protocol | |
3 | * | |
4 | * (c) 2000 Martin Mares <mj@ucw.cz> | |
d15b0b0a OZ |
5 | * (c) 2008--2016 Ondrej Zajicek <santiago@crfreenet.org> |
6 | * (c) 2008--2016 CZ.NIC z.s.p.o. | |
2638249d MM |
7 | * |
8 | * Can be freely distributed and used under the terms of the GNU GPL. | |
9 | */ | |
10 | ||
11 | #ifndef _BIRD_BGP_H_ | |
12 | #define _BIRD_BGP_H_ | |
13 | ||
46eb80d5 | 14 | #include <stdint.h> |
d15b0b0a OZ |
15 | #include <setjmp.h> |
16 | #include "nest/bird.h" | |
c2b28c99 | 17 | #include "nest/route.h" |
77e43c8b | 18 | #include "nest/bfd.h" |
d15b0b0a | 19 | //#include "lib/lists.h" |
e7d2ac44 | 20 | #include "lib/hash.h" |
d15b0b0a | 21 | #include "lib/socket.h" |
c2b28c99 | 22 | |
c00d31be | 23 | struct linpool; |
10be74da | 24 | struct eattr; |
c00d31be | 25 | |
d15b0b0a OZ |
26 | |
27 | /* Address families */ | |
28 | ||
29 | #define BGP_AFI_IPV4 1 | |
30 | #define BGP_AFI_IPV6 2 | |
31 | ||
32 | #define BGP_SAFI_UNICAST 1 | |
33 | #define BGP_SAFI_MULTICAST 2 | |
1e37e35c OZ |
34 | #define BGP_SAFI_MPLS 4 |
35 | #define BGP_SAFI_MPLS_VPN 128 | |
711d617d | 36 | #define BGP_SAFI_VPN_MULTICAST 129 |
ac3ad139 | 37 | #define BGP_SAFI_FLOW 133 |
d15b0b0a OZ |
38 | |
39 | /* Internal AF codes */ | |
40 | ||
41 | #define BGP_AF(A, B) (((u32)(A) << 16) | (u32)(B)) | |
42 | #define BGP_AFI(A) ((u32)(A) >> 16) | |
43 | #define BGP_SAFI(A) ((u32)(A) & 0xFFFF) | |
44 | ||
45 | #define BGP_AF_IPV4 BGP_AF( BGP_AFI_IPV4, BGP_SAFI_UNICAST ) | |
46 | #define BGP_AF_IPV6 BGP_AF( BGP_AFI_IPV6, BGP_SAFI_UNICAST ) | |
47 | #define BGP_AF_IPV4_MC BGP_AF( BGP_AFI_IPV4, BGP_SAFI_MULTICAST ) | |
48 | #define BGP_AF_IPV6_MC BGP_AF( BGP_AFI_IPV6, BGP_SAFI_MULTICAST ) | |
1e37e35c OZ |
49 | #define BGP_AF_IPV4_MPLS BGP_AF( BGP_AFI_IPV4, BGP_SAFI_MPLS ) |
50 | #define BGP_AF_IPV6_MPLS BGP_AF( BGP_AFI_IPV6, BGP_SAFI_MPLS ) | |
51 | #define BGP_AF_VPN4_MPLS BGP_AF( BGP_AFI_IPV4, BGP_SAFI_MPLS_VPN ) | |
52 | #define BGP_AF_VPN6_MPLS BGP_AF( BGP_AFI_IPV6, BGP_SAFI_MPLS_VPN ) | |
711d617d OZ |
53 | #define BGP_AF_VPN4_MC BGP_AF( BGP_AFI_IPV4, BGP_SAFI_VPN_MULTICAST ) |
54 | #define BGP_AF_VPN6_MC BGP_AF( BGP_AFI_IPV6, BGP_SAFI_VPN_MULTICAST ) | |
ac3ad139 OZ |
55 | #define BGP_AF_FLOW4 BGP_AF( BGP_AFI_IPV4, BGP_SAFI_FLOW ) |
56 | #define BGP_AF_FLOW6 BGP_AF( BGP_AFI_IPV6, BGP_SAFI_FLOW ) | |
d15b0b0a OZ |
57 | |
58 | ||
59 | struct bgp_write_state; | |
60 | struct bgp_parse_state; | |
61 | struct bgp_export_state; | |
62 | struct bgp_bucket; | |
63 | ||
64 | struct bgp_af_desc { | |
65 | u32 afi; | |
66 | u32 net; | |
ef57b70f OZ |
67 | u8 mpls; |
68 | u8 no_igp; | |
d15b0b0a OZ |
69 | const char *name; |
70 | uint (*encode_nlri)(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size); | |
71 | void (*decode_nlri)(struct bgp_parse_state *s, byte *pos, uint len, rta *a); | |
72 | void (*update_next_hop)(struct bgp_export_state *s, eattr *nh, ea_list **to); | |
73 | uint (*encode_next_hop)(struct bgp_write_state *s, eattr *nh, byte *buf, uint size); | |
74 | void (*decode_next_hop)(struct bgp_parse_state *s, byte *pos, uint len, rta *a); | |
75 | }; | |
76 | ||
77 | ||
2638249d MM |
78 | struct bgp_config { |
79 | struct proto_config c; | |
11cb6202 | 80 | u32 local_as, remote_as; |
d15b0b0a | 81 | ip_addr local_ip; /* Source address to use */ |
2638249d | 82 | ip_addr remote_ip; |
53ffbff3 | 83 | struct iface *iface; /* Interface for link-local addresses */ |
d15b0b0a | 84 | u16 local_port; /* Local listening port */ |
dcde7ae5 | 85 | u16 remote_port; /* Neighbor destination port */ |
23ee6b1c | 86 | int peer_type; /* Internal or external BGP (BGP_PT_*, optional) */ |
2638249d | 87 | int multihop; /* Number of hops if multihop */ |
82f42ea0 | 88 | int strict_bind; /* Bind listening socket to local address */ |
d15b0b0a | 89 | int ttl_security; /* Enable TTL security [RFC 5082] */ |
56a2bed4 | 90 | int compare_path_lengths; /* Use path lengths when selecting best route */ |
73272f04 | 91 | int med_metric; /* Compare MULTI_EXIT_DISC even between routes from differen ASes */ |
d1e146f2 | 92 | int igp_metric; /* Use IGP metrics when selecting best route */ |
3228c72c | 93 | int prefer_older; /* Prefer older routes according to RFC 5004 */ |
be4cd99a | 94 | int deterministic_med; /* Use more complicated algo to have strict RFC 4271 MED comparison */ |
56a2bed4 MM |
95 | u32 default_local_pref; /* Default value for LOCAL_PREF attribute */ |
96 | u32 default_med; /* Default value for MULTI_EXIT_DISC attribute */ | |
c49e4a65 | 97 | int capabilities; /* Enable capability handshake [RFC 5492] */ |
d15b0b0a | 98 | int enable_refresh; /* Enable local support for route refresh [RFC 2918] */ |
c49e4a65 | 99 | int enable_as4; /* Enable local support for 4B AS numbers [RFC 6793] */ |
06e0d1b6 | 100 | int enable_extended_messages; /* Enable local support for extended messages [draft] */ |
4847a894 OZ |
101 | u32 rr_cluster_id; /* Route reflector cluster ID, if different from local ID */ |
102 | int rr_client; /* Whether neighbor is RR client of me */ | |
a92fe607 | 103 | int rs_client; /* Whether neighbor is RS client of me */ |
d15b0b0a OZ |
104 | u32 confederation; /* Confederation ID, or zero if confeds not active */ |
105 | int confederation_member; /* Whether neighbor AS is member of our confederation */ | |
be6e39eb | 106 | int passive; /* Do not initiate outgoing connection */ |
41677025 | 107 | int interpret_communities; /* Hardwired handling of well-known communities */ |
a15dab76 | 108 | int allow_local_as; /* Allow that number of local ASNs in incoming AS_PATHs */ |
1950a479 | 109 | int allow_local_pref; /* Allow LOCAL_PREF in EBGP sessions */ |
a52476c9 | 110 | int allow_as_sets; /* Allow AS_SETs in incoming AS_PATHs */ |
0b228fca | 111 | int enforce_first_as; /* Enable check for neighbor AS as first AS in AS_PATH */ |
0c791f87 | 112 | int gr_mode; /* Graceful restart mode (BGP_GR_*) */ |
5bd73431 | 113 | int llgr_mode; /* Long-lived graceful restart mode (BGP_LLGR_*) */ |
a7baa098 | 114 | int setkey; /* Set MD5 password to system SA/SP database */ |
cc881bd1 | 115 | /* Times below are in seconds */ |
0c791f87 | 116 | unsigned gr_time; /* Graceful restart timeout */ |
5bd73431 | 117 | unsigned llgr_time; /* Long-lived graceful restart stale time */ |
6cf72d7a OZ |
118 | unsigned connect_delay_time; /* Minimum delay between connect attempts */ |
119 | unsigned connect_retry_time; /* Timeout for connect attempts */ | |
3fdbafb6 MM |
120 | unsigned hold_time, initial_hold_time; |
121 | unsigned keepalive_time; | |
6fd766c1 MM |
122 | unsigned error_amnesia_time; /* Errors are forgotten after */ |
123 | unsigned error_delay_time_min; /* Time to wait after an error is detected */ | |
124 | unsigned error_delay_time_max; | |
125 | unsigned disable_after_error; /* Disable the protocol when error is detected */ | |
63472779 | 126 | u32 disable_after_cease; /* Disable it when cease is received, bitfield */ |
1ec52253 | 127 | |
fd9f0c06 | 128 | const char *password; /* Password used for MD5 authentication */ |
e0835db4 | 129 | net_addr *remote_range; /* Allowed neighbor range for dynamic BGP */ |
fd9f0c06 | 130 | const char *dynamic_name; /* Name pattern for dynamic BGP */ |
e0835db4 | 131 | int dynamic_name_digits; /* Minimum number of digits for dynamic names */ |
523f020b | 132 | int check_link; /* Use iface link state for liveness detection */ |
1ec52253 | 133 | int bfd; /* Use BFD for liveness detection */ |
c01e3741 MM |
134 | }; |
135 | ||
d15b0b0a OZ |
136 | struct bgp_channel_config { |
137 | struct channel_config c; | |
138 | ||
139 | u32 afi; | |
ef57b70f | 140 | const struct bgp_af_desc *desc; |
d15b0b0a OZ |
141 | |
142 | ip_addr next_hop_addr; /* Local address for NEXT_HOP attribute */ | |
1cab2b4a OZ |
143 | u8 next_hop_self; /* Always set next hop to local IP address (NH_*) */ |
144 | u8 next_hop_keep; /* Do not modify next hop attribute (NH_*) */ | |
3c360581 | 145 | u8 mandatory; /* Channel is mandatory in capability negotiation */ |
d15b0b0a OZ |
146 | u8 missing_lladdr; /* What we will do when we don' know link-local addr, see MLL_* */ |
147 | u8 gw_mode; /* How we compute route gateway from next_hop attr, see GW_* */ | |
148 | u8 secondary; /* Accept also non-best routes (i.e. RA_ACCEPTED) */ | |
149 | u8 gr_able; /* Allow full graceful restart for the channel */ | |
5bd73431 OZ |
150 | u8 llgr_able; /* Allow full long-lived GR for the channel */ |
151 | uint llgr_time; /* Long-lived graceful restart stale time */ | |
d8022d26 | 152 | u8 ext_next_hop; /* Allow both IPv4 and IPv6 next hops */ |
d15b0b0a | 153 | u8 add_path; /* Use ADD-PATH extension [RFC 7911] */ |
09ee846d OZ |
154 | u8 aigp; /* AIGP is allowed on this session */ |
155 | u8 aigp_originate; /* AIGP is originated automatically */ | |
156 | u32 cost; /* IGP cost for direct next hops */ | |
682d3f7d | 157 | u8 import_table; /* Use c.in_table as Adj-RIB-In */ |
b7d7599c | 158 | u8 export_table; /* Use c.out_table as Adj-RIB-Out */ |
d15b0b0a | 159 | |
ef57b70f OZ |
160 | struct rtable_config *igp_table_ip4; /* Table for recursive IPv4 next hop lookups */ |
161 | struct rtable_config *igp_table_ip6; /* Table for recursive IPv6 next hop lookups */ | |
d15b0b0a OZ |
162 | }; |
163 | ||
23ee6b1c OZ |
164 | #define BGP_PT_INTERNAL 1 |
165 | #define BGP_PT_EXTERNAL 2 | |
166 | ||
1cab2b4a OZ |
167 | #define NH_NO 0 |
168 | #define NH_ALL 1 | |
169 | #define NH_IBGP 2 | |
170 | #define NH_EBGP 3 | |
3f9b7bfe | 171 | |
1cab2b4a OZ |
172 | #define MLL_SELF 1 |
173 | #define MLL_DROP 2 | |
174 | #define MLL_IGNORE 3 | |
175 | ||
176 | #define GW_DIRECT 1 | |
177 | #define GW_RECURSIVE 2 | |
087cecd0 | 178 | |
d15b0b0a OZ |
179 | #define BGP_ADD_PATH_RX 1 |
180 | #define BGP_ADD_PATH_TX 2 | |
181 | #define BGP_ADD_PATH_FULL 3 | |
094d2bdb | 182 | |
d15b0b0a OZ |
183 | #define BGP_GR_ABLE 1 |
184 | #define BGP_GR_AWARE 2 | |
0c791f87 | 185 | |
d15b0b0a | 186 | /* For GR capability common flags */ |
0c791f87 OZ |
187 | #define BGP_GRF_RESTART 0x80 |
188 | ||
d15b0b0a | 189 | /* For GR capability per-AF flags */ |
0c791f87 OZ |
190 | #define BGP_GRF_FORWARDING 0x80 |
191 | ||
5bd73431 OZ |
192 | #define BGP_LLGR_ABLE 1 |
193 | #define BGP_LLGR_AWARE 2 | |
194 | ||
195 | #define BGP_LLGRF_FORWARDING 0x80 | |
196 | ||
197 | #define BGP_GRS_NONE 0 /* No GR */ | |
198 | #define BGP_GRS_ACTIVE 1 /* Graceful restart per RFC 4724 */ | |
199 | #define BGP_GRS_LLGR 2 /* Long-lived GR phase (stale timer active) */ | |
200 | ||
201 | #define BGP_BFD_GRACEFUL 2 /* BFD down triggers graceful restart */ | |
202 | ||
094d2bdb | 203 | |
d15b0b0a OZ |
204 | struct bgp_af_caps { |
205 | u32 afi; | |
206 | u8 ready; /* Multiprotocol capability, RFC 4760 */ | |
207 | u8 gr_able; /* Graceful restart support, RFC 4724 */ | |
208 | u8 gr_af_flags; /* Graceful restart per-AF flags */ | |
5bd73431 OZ |
209 | u8 llgr_able; /* Long-lived GR, RFC draft */ |
210 | u32 llgr_time; /* Long-lived GR stale time */ | |
211 | u8 llgr_flags; /* Long-lived GR per-AF flags */ | |
d8022d26 | 212 | u8 ext_next_hop; /* Extended IPv6 next hop, RFC 5549 */ |
d15b0b0a OZ |
213 | u8 add_path; /* Multiple paths support, RFC 7911 */ |
214 | }; | |
215 | ||
216 | struct bgp_caps { | |
217 | u32 as4_number; /* Announced ASN */ | |
218 | ||
219 | u8 as4_support; /* Four-octet AS capability, RFC 6793 */ | |
220 | u8 ext_messages; /* Extended message length, RFC draft */ | |
221 | u8 route_refresh; /* Route refresh capability, RFC 2918 */ | |
222 | u8 enhanced_refresh; /* Enhanced route refresh, RFC 7313 */ | |
223 | ||
224 | u8 gr_aware; /* Graceful restart capability, RFC 4724 */ | |
225 | u8 gr_flags; /* Graceful restart flags */ | |
226 | u16 gr_time; /* Graceful restart time in seconds */ | |
227 | ||
5bd73431 | 228 | u8 llgr_aware; /* Long-lived GR capability, RFC draft */ |
4a50c8bd OZ |
229 | u8 any_ext_next_hop; /* Bitwise OR of per-AF ext_next_hop */ |
230 | u8 any_add_path; /* Bitwise OR of per-AF add_path */ | |
5bd73431 | 231 | |
d15b0b0a | 232 | u16 af_count; /* Number of af_data items */ |
7e5f769d | 233 | u16 length; /* Length of capabilities in OPEN msg */ |
d15b0b0a OZ |
234 | |
235 | struct bgp_af_caps af_data[0]; /* Per-AF capability data */ | |
236 | }; | |
237 | ||
256cc8ee OZ |
238 | #define WALK_AF_CAPS(caps,ac) \ |
239 | for (ac = caps->af_data; ac < &caps->af_data[caps->af_count]; ac++) | |
240 | ||
241 | ||
d15b0b0a OZ |
242 | struct bgp_socket { |
243 | node n; /* Node in global bgp_sockets */ | |
244 | sock *sk; /* Real listening socket */ | |
245 | u32 uc; /* Use count */ | |
246 | }; | |
247 | ||
21d09632 OZ |
248 | struct bgp_stats { |
249 | uint rx_messages, tx_messages; | |
250 | uint rx_updates, tx_updates; | |
251 | u64 rx_bytes, tx_bytes; | |
252 | ||
253 | uint fsm_established_transitions; | |
254 | }; | |
255 | ||
c01e3741 MM |
256 | struct bgp_conn { |
257 | struct bgp_proto *bgp; | |
258 | struct birdsock *sk; | |
d15b0b0a OZ |
259 | u8 state; /* State of connection state machine */ |
260 | u8 as4_session; /* Session uses 4B AS numbers in AS_PATH (both sides support it) */ | |
261 | u8 ext_messages; /* Session uses extended message length */ | |
23ee6b1c | 262 | u32 received_as; /* ASN received in OPEN message */ |
d15b0b0a OZ |
263 | |
264 | struct bgp_caps *local_caps; | |
265 | struct bgp_caps *remote_caps; | |
02552526 OZ |
266 | timer *connect_timer; |
267 | timer *hold_timer; | |
268 | timer *keepalive_timer; | |
269 | event *tx_ev; | |
d15b0b0a OZ |
270 | u32 packets_to_send; /* Bitmap of packet types to be sent */ |
271 | u32 channels_to_send; /* Bitmap of channels with packets to be sent */ | |
272 | u8 last_channel; /* Channel used last time for TX */ | |
273 | u8 last_channel_count; /* Number of times the last channel was used in succession */ | |
efcece2d MM |
274 | int notify_code, notify_subcode, notify_size; |
275 | byte *notify_data; | |
d15b0b0a OZ |
276 | |
277 | uint hold_time, keepalive_time; /* Times calculated from my and neighbor's requirements */ | |
2638249d MM |
278 | }; |
279 | ||
280 | struct bgp_proto { | |
281 | struct proto p; | |
a22c3e59 OZ |
282 | const struct bgp_config *cf; /* Shortcut to BGP configuration */ |
283 | ip_addr local_ip, remote_ip; | |
11cb6202 | 284 | u32 local_as, remote_as; |
d15b0b0a | 285 | u32 public_as; /* Externally visible ASN (local_as or confederation id) */ |
c01e3741 MM |
286 | u32 local_id; /* BGP identifier of this router */ |
287 | u32 remote_id; /* BGP identifier of the neighbor */ | |
4847a894 | 288 | u32 rr_cluster_id; /* Route reflector cluster ID */ |
e0835db4 | 289 | u8 start_state; /* Substates that partitions BS_START */ |
d15b0b0a OZ |
290 | u8 is_internal; /* Internal BGP session (local_as == remote_as) */ |
291 | u8 is_interior; /* Internal or intra-confederation BGP session */ | |
292 | u8 as4_session; /* Session uses 4B AS numbers in AS_PATH (both sides support it) */ | |
293 | u8 rr_client; /* Whether neighbor is RR client of me */ | |
294 | u8 rs_client; /* Whether neighbor is RS client of me */ | |
e0835db4 OZ |
295 | u8 ipv4; /* Use IPv4 connection, i.e. remote_ip is IPv4 */ |
296 | u8 passive; /* Do not initiate outgoing connection */ | |
d15b0b0a OZ |
297 | u8 route_refresh; /* Route refresh allowed to send [RFC 2918] */ |
298 | u8 enhanced_refresh; /* Enhanced refresh is negotiated [RFC 7313] */ | |
0c791f87 | 299 | u8 gr_ready; /* Neighbor could do graceful restart */ |
5bd73431 | 300 | u8 llgr_ready; /* Neighbor could do Long-lived GR, implies gr_ready */ |
d15b0b0a OZ |
301 | u8 gr_active_num; /* Neighbor is doing GR, number of active channels */ |
302 | u8 channel_count; /* Number of active channels */ | |
863ecfc7 | 303 | u8 summary_add_path_rx; /* Summary state of ADD_PATH RX w.r.t active channels */ |
d15b0b0a OZ |
304 | u32 *afi_map; /* Map channel index -> AFI */ |
305 | struct bgp_channel **channel_map; /* Map channel index -> channel */ | |
b552ecc4 MM |
306 | struct bgp_conn *conn; /* Connection we have established */ |
307 | struct bgp_conn outgoing_conn; /* Outgoing connection we're working with */ | |
c01e3741 MM |
308 | struct bgp_conn incoming_conn; /* Incoming connection we have neither accepted nor rejected yet */ |
309 | struct object_lock *lock; /* Lock for neighbor connection */ | |
9be9a264 | 310 | struct neighbor *neigh; /* Neighbor entry corresponding to remote ip, NULL if multihop */ |
d15b0b0a | 311 | struct bgp_socket *sock; /* Shared listening socket */ |
1ec52253 | 312 | struct bfd_request *bfd_req; /* BFD request, if BFD is used */ |
e0835db4 | 313 | struct birdsock *postponed_sk; /* Postponed incoming socket for dynamic BGP */ |
21d09632 OZ |
314 | struct bgp_stats stats; /* BGP statistics */ |
315 | btime last_established; /* Last time of enter/leave of established state */ | |
316 | btime last_rx_update; /* Last time of RX update */ | |
a22c3e59 | 317 | ip_addr link_addr; /* Link-local version of local_ip */ |
02552526 OZ |
318 | event *event; /* Event for respawning and shutting process */ |
319 | timer *startup_timer; /* Timer used to delay protocol startup due to previous errors (startup_delay) */ | |
320 | timer *gr_timer; /* Timer waiting for reestablishment after graceful restart */ | |
e0835db4 | 321 | int dynamic_name_counter; /* Counter for dynamic BGP names */ |
cc881bd1 OZ |
322 | uint startup_delay; /* Delay (in seconds) of protocol startup due to previous errors */ |
323 | btime last_proto_error; /* Time of last error that leads to protocol stop */ | |
11b32d91 OZ |
324 | u8 last_error_class; /* Error class of last error */ |
325 | u32 last_error_code; /* Error code of last error. BGP protocol errors | |
326 | are encoded as (bgp_err_code << 16 | bgp_err_subcode) */ | |
d15b0b0a OZ |
327 | }; |
328 | ||
329 | struct bgp_channel { | |
330 | struct channel c; | |
331 | ||
332 | /* Rest are BGP specific data */ | |
333 | struct bgp_channel_config *cf; | |
d15b0b0a OZ |
334 | |
335 | u32 afi; | |
336 | u32 index; | |
337 | const struct bgp_af_desc *desc; | |
338 | ||
b8a3608a OZ |
339 | rtable *igp_table_ip4; /* Table for recursive IPv4 next hop lookups */ |
340 | rtable *igp_table_ip6; /* Table for recursive IPv6 next hop lookups */ | |
341 | ||
342 | /* Rest are zeroed when down */ | |
343 | pool *pool; | |
d15b0b0a OZ |
344 | HASH(struct bgp_bucket) bucket_hash; /* Hash table of route buckets */ |
345 | struct bgp_bucket *withdraw_bucket; /* Withdrawn routes */ | |
346 | list bucket_queue; /* Queue of buckets to send (struct bgp_bucket) */ | |
347 | ||
348 | HASH(struct bgp_prefix) prefix_hash; /* Prefixes to be sent */ | |
349 | slab *prefix_slab; /* Slab holding prefix nodes */ | |
350 | ||
d15b0b0a OZ |
351 | ip_addr next_hop_addr; /* Local address for NEXT_HOP attribute */ |
352 | ip_addr link_addr; /* Link-local version of next_hop_addr */ | |
353 | ||
354 | u32 packets_to_send; /* Bitmap of packet types to be sent */ | |
355 | ||
5bd73431 OZ |
356 | u8 ext_next_hop; /* Session allows both IPv4 and IPv6 next hops */ |
357 | ||
d15b0b0a | 358 | u8 gr_ready; /* Neighbor could do GR on this AF */ |
5bd73431 | 359 | u8 gr_active; /* Neighbor is doing GR (BGP_GRS_*) */ |
d15b0b0a | 360 | |
5bd73431 OZ |
361 | timer *stale_timer; /* Long-lived stale timer for LLGR */ |
362 | u32 stale_time; /* Stored LLGR stale time from last session */ | |
d8022d26 | 363 | |
d15b0b0a OZ |
364 | u8 add_path_rx; /* Session expects receive of ADD-PATH extended NLRI */ |
365 | u8 add_path_tx; /* Session expects transmit of ADD-PATH extended NLRI */ | |
366 | ||
367 | u8 feed_state; /* Feed state (TX) for EoR, RR packets, see BFS_* */ | |
368 | u8 load_state; /* Load state (RX) for EoR, RR packets, see BFS_* */ | |
c2b28c99 MM |
369 | }; |
370 | ||
371 | struct bgp_prefix { | |
d15b0b0a OZ |
372 | node buck_node; /* Node in per-bucket list */ |
373 | struct bgp_prefix *next; /* Node in prefix hash table */ | |
374 | u32 hash; | |
094d2bdb | 375 | u32 path_id; |
d15b0b0a | 376 | net_addr net[0]; |
c2b28c99 MM |
377 | }; |
378 | ||
379 | struct bgp_bucket { | |
c2b28c99 | 380 | node send_node; /* Node in send queue */ |
d15b0b0a OZ |
381 | struct bgp_bucket *next; /* Node in bucket hash table */ |
382 | list prefixes; /* Prefixes in this bucket (struct bgp_prefix) */ | |
383 | u32 hash; /* Hash over extended attributes */ | |
c2b28c99 | 384 | ea_list eattrs[0]; /* Per-bucket extended attributes */ |
2638249d MM |
385 | }; |
386 | ||
d15b0b0a OZ |
387 | struct bgp_export_state { |
388 | struct bgp_proto *proto; | |
389 | struct bgp_channel *channel; | |
390 | struct linpool *pool; | |
391 | ||
392 | struct bgp_proto *src; | |
393 | rte *route; | |
1e37e35c | 394 | int mpls; |
d15b0b0a OZ |
395 | |
396 | u32 attrs_seen[1]; | |
397 | uint err_withdraw; | |
09ee846d | 398 | uint local_next_hop; |
d15b0b0a OZ |
399 | }; |
400 | ||
401 | struct bgp_write_state { | |
402 | struct bgp_proto *proto; | |
403 | struct bgp_channel *channel; | |
404 | struct linpool *pool; | |
405 | ||
863ecfc7 | 406 | int mp_reach; |
d15b0b0a OZ |
407 | int as4_session; |
408 | int add_path; | |
1e37e35c | 409 | int mpls; |
d15b0b0a OZ |
410 | |
411 | eattr *mp_next_hop; | |
4c553c5a | 412 | const adata *mpls_labels; |
d15b0b0a OZ |
413 | }; |
414 | ||
415 | struct bgp_parse_state { | |
416 | struct bgp_proto *proto; | |
417 | struct bgp_channel *channel; | |
418 | struct linpool *pool; | |
419 | ||
420 | int as4_session; | |
421 | int add_path; | |
1e37e35c | 422 | int mpls; |
d15b0b0a OZ |
423 | |
424 | u32 attrs_seen[256/32]; | |
425 | ||
426 | u32 mp_reach_af; | |
427 | u32 mp_unreach_af; | |
428 | ||
429 | uint attr_len; | |
430 | uint ip_reach_len; | |
431 | uint ip_unreach_len; | |
432 | uint ip_next_hop_len; | |
433 | uint mp_reach_len; | |
434 | uint mp_unreach_len; | |
435 | uint mp_next_hop_len; | |
436 | ||
437 | byte *attrs; | |
438 | byte *ip_reach_nlri; | |
439 | byte *ip_unreach_nlri; | |
440 | byte *ip_next_hop_data; | |
441 | byte *mp_reach_nlri; | |
442 | byte *mp_unreach_nlri; | |
443 | byte *mp_next_hop_data; | |
444 | ||
445 | uint err_withdraw; | |
446 | uint err_subcode; | |
447 | jmp_buf err_jmpbuf; | |
448 | ||
1e37e35c OZ |
449 | struct hostentry *hostentry; |
450 | adata *mpls_labels; | |
451 | ||
d15b0b0a OZ |
452 | /* Cached state for bgp_rte_update() */ |
453 | u32 last_id; | |
454 | struct rte_src *last_src; | |
455 | rta *cached_rta; | |
456 | }; | |
457 | ||
72a6ef11 MM |
458 | #define BGP_PORT 179 |
459 | #define BGP_VERSION 4 | |
460 | #define BGP_HEADER_LENGTH 19 | |
06e0d1b6 OZ |
461 | #define BGP_MAX_MESSAGE_LENGTH 4096 |
462 | #define BGP_MAX_EXT_MSG_LENGTH 65535 | |
72a6ef11 | 463 | #define BGP_RX_BUFFER_SIZE 4096 |
06e0d1b6 OZ |
464 | #define BGP_TX_BUFFER_SIZE 4096 |
465 | #define BGP_RX_BUFFER_EXT_SIZE 65535 | |
466 | #define BGP_TX_BUFFER_EXT_SIZE 65535 | |
467 | ||
d15b0b0a OZ |
468 | static inline int bgp_channel_is_ipv4(struct bgp_channel *c) |
469 | { return BGP_AFI(c->afi) == BGP_AFI_IPV4; } | |
470 | ||
471 | static inline int bgp_channel_is_ipv6(struct bgp_channel *c) | |
472 | { return BGP_AFI(c->afi) == BGP_AFI_IPV6; } | |
473 | ||
ef57b70f OZ |
474 | static inline int bgp_cc_is_ipv4(struct bgp_channel_config *c) |
475 | { return BGP_AFI(c->afi) == BGP_AFI_IPV4; } | |
476 | ||
477 | static inline int bgp_cc_is_ipv6(struct bgp_channel_config *c) | |
478 | { return BGP_AFI(c->afi) == BGP_AFI_IPV6; } | |
479 | ||
d15b0b0a OZ |
480 | static inline uint bgp_max_packet_length(struct bgp_conn *conn) |
481 | { return conn->ext_messages ? BGP_MAX_EXT_MSG_LENGTH : BGP_MAX_MESSAGE_LENGTH; } | |
482 | ||
483 | static inline void | |
484 | bgp_parse_error(struct bgp_parse_state *s, uint subcode) | |
485 | { | |
486 | s->err_subcode = subcode; | |
487 | longjmp(s->err_jmpbuf, 1); | |
488 | } | |
2638249d | 489 | |
973399ae | 490 | extern struct linpool *bgp_linpool; |
1e37e35c | 491 | extern struct linpool *bgp_linpool2; |
973399ae | 492 | |
11cb6202 | 493 | |
cc881bd1 | 494 | void bgp_start_timer(timer *t, uint value); |
a7f23f58 | 495 | void bgp_check_config(struct bgp_config *c); |
efcece2d | 496 | void bgp_error(struct bgp_conn *c, unsigned code, unsigned subcode, byte *data, int len); |
b552ecc4 | 497 | void bgp_close_conn(struct bgp_conn *c); |
b99d3786 | 498 | void bgp_update_startup_delay(struct bgp_proto *p); |
cf31112f | 499 | void bgp_conn_enter_openconfirm_state(struct bgp_conn *conn); |
11b32d91 OZ |
500 | void bgp_conn_enter_established_state(struct bgp_conn *conn); |
501 | void bgp_conn_enter_close_state(struct bgp_conn *conn); | |
502 | void bgp_conn_enter_idle_state(struct bgp_conn *conn); | |
0c791f87 | 503 | void bgp_handle_graceful_restart(struct bgp_proto *p); |
d15b0b0a OZ |
504 | void bgp_graceful_restart_done(struct bgp_channel *c); |
505 | void bgp_refresh_begin(struct bgp_channel *c); | |
506 | void bgp_refresh_end(struct bgp_channel *c); | |
11b32d91 | 507 | void bgp_store_error(struct bgp_proto *p, struct bgp_conn *c, u8 class, u32 code); |
8a68316e | 508 | void bgp_stop(struct bgp_proto *p, int subcode, byte *data, uint len); |
b99d3786 | 509 | |
094d2bdb OZ |
510 | struct rte_source *bgp_find_source(struct bgp_proto *p, u32 path_id); |
511 | struct rte_source *bgp_get_source(struct bgp_proto *p, u32 path_id); | |
512 | ||
09ee846d OZ |
513 | static inline int |
514 | rte_resolvable(rte *rt) | |
515 | { | |
516 | return rt->attrs->dest == RTD_UNICAST; | |
517 | } | |
11b32d91 | 518 | |
2638249d | 519 | |
85368cd4 MM |
520 | #ifdef LOCAL_DEBUG |
521 | #define BGP_FORCE_DEBUG 1 | |
522 | #else | |
523 | #define BGP_FORCE_DEBUG 0 | |
524 | #endif | |
525 | #define BGP_TRACE(flags, msg, args...) do { if ((p->p.debug & flags) || BGP_FORCE_DEBUG) \ | |
526 | log(L_TRACE "%s: " msg, p->p.name , ## args ); } while(0) | |
527 | ||
cb530392 OZ |
528 | #define BGP_TRACE_RL(rl, flags, msg, args...) do { if ((p->p.debug & flags) || BGP_FORCE_DEBUG) \ |
529 | log_rl(rl, L_TRACE "%s: " msg, p->p.name , ## args ); } while(0) | |
530 | ||
531 | ||
c01e3741 MM |
532 | /* attrs.c */ |
533 | ||
d15b0b0a OZ |
534 | static inline eattr * |
535 | bgp_find_attr(ea_list *attrs, uint code) | |
536 | { | |
ee7e2ffd | 537 | return ea_find(attrs, EA_CODE(PROTOCOL_BGP, code)); |
d15b0b0a OZ |
538 | } |
539 | ||
540 | eattr * | |
541 | bgp_set_attr(ea_list **attrs, struct linpool *pool, uint code, uint flags, uintptr_t val); | |
542 | ||
543 | static inline void | |
544 | bgp_set_attr_u32(ea_list **to, struct linpool *pool, uint code, uint flags, u32 val) | |
545 | { bgp_set_attr(to, pool, code, flags, (uintptr_t) val); } | |
546 | ||
547 | static inline void | |
4c553c5a | 548 | bgp_set_attr_ptr(ea_list **to, struct linpool *pool, uint code, uint flags, const struct adata *val) |
d15b0b0a OZ |
549 | { bgp_set_attr(to, pool, code, flags, (uintptr_t) val); } |
550 | ||
551 | static inline void | |
552 | bgp_set_attr_data(ea_list **to, struct linpool *pool, uint code, uint flags, void *data, uint len) | |
553 | { | |
554 | struct adata *a = lp_alloc_adata(pool, len); | |
d6072054 | 555 | bmemcpy(a->data, data, len); |
d15b0b0a OZ |
556 | bgp_set_attr(to, pool, code, flags, (uintptr_t) a); |
557 | } | |
558 | ||
559 | static inline void | |
560 | bgp_unset_attr(ea_list **to, struct linpool *pool, uint code) | |
561 | { eattr *e = bgp_set_attr(to, pool, code, 0, 0); e->type = EAF_TYPE_UNDEF; } | |
562 | ||
563 | ||
d15b0b0a OZ |
564 | int bgp_encode_attrs(struct bgp_write_state *s, ea_list *attrs, byte *buf, byte *end); |
565 | ea_list * bgp_decode_attrs(struct bgp_parse_state *s, byte *data, uint len); | |
09ee846d | 566 | void bgp_finish_attrs(struct bgp_parse_state *s, rta *a); |
d15b0b0a OZ |
567 | |
568 | void bgp_init_bucket_table(struct bgp_channel *c); | |
7fc55925 | 569 | void bgp_free_bucket_table(struct bgp_channel *c); |
d15b0b0a OZ |
570 | void bgp_free_bucket(struct bgp_channel *c, struct bgp_bucket *b); |
571 | void bgp_defer_bucket(struct bgp_channel *c, struct bgp_bucket *b); | |
572 | void bgp_withdraw_bucket(struct bgp_channel *c, struct bgp_bucket *b); | |
573 | ||
574 | void bgp_init_prefix_table(struct bgp_channel *c); | |
7fc55925 | 575 | void bgp_free_prefix_table(struct bgp_channel *c); |
d15b0b0a OZ |
576 | void bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *bp); |
577 | ||
ef2c708d | 578 | int bgp_rte_better(struct rte *, struct rte *); |
8d9eef17 | 579 | int bgp_rte_mergable(rte *pri, rte *sec); |
be4cd99a | 580 | int bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best); |
5bd73431 | 581 | struct rte *bgp_rte_modify_stale(struct rte *r, struct linpool *pool); |
13c0be19 | 582 | void bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old); |
14375237 | 583 | int bgp_preexport(struct proto *, struct rte **, struct linpool *); |
d15b0b0a | 584 | int bgp_get_attr(struct eattr *e, byte *buf, int buflen); |
13c0be19 | 585 | void bgp_get_route_info(struct rte *, byte *buf); |
09ee846d OZ |
586 | int bgp_total_aigp_metric_(rte *e, u64 *metric, const struct adata **ad); |
587 | ||
588 | #define BGP_AIGP_METRIC 1 | |
589 | #define BGP_AIGP_MAX U64(0xffffffffffffffff) | |
590 | ||
591 | static inline u64 | |
592 | bgp_total_aigp_metric(rte *r) | |
593 | { | |
594 | u64 metric = BGP_AIGP_MAX; | |
595 | const struct adata *ad; | |
596 | ||
597 | bgp_total_aigp_metric_(r, &metric, &ad); | |
598 | return metric; | |
599 | } | |
c00d31be | 600 | |
4847a894 | 601 | |
c01e3741 MM |
602 | /* packets.c */ |
603 | ||
863ecfc7 | 604 | void bgp_dump_state_change(struct bgp_conn *conn, uint old, uint new); |
4a50c8bd | 605 | void bgp_prepare_capabilities(struct bgp_conn *conn); |
d15b0b0a OZ |
606 | const struct bgp_af_desc *bgp_get_af_desc(u32 afi); |
607 | const struct bgp_af_caps *bgp_find_af_caps(struct bgp_caps *caps, u32 afi); | |
608 | void bgp_schedule_packet(struct bgp_conn *conn, struct bgp_channel *c, int type); | |
11b32d91 | 609 | void bgp_kick_tx(void *vconn); |
72a6ef11 | 610 | void bgp_tx(struct birdsock *sk); |
3e236955 | 611 | int bgp_rx(struct birdsock *sk, uint size); |
b8113a5e | 612 | const char * bgp_error_dsc(unsigned code, unsigned subcode); |
b99d3786 | 613 | void bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned subcode, byte *data, unsigned len); |
72a6ef11 | 614 | |
d15b0b0a OZ |
615 | void bgp_update_next_hop(struct bgp_export_state *s, eattr *a, ea_list **to); |
616 | ||
617 | ||
c01e3741 MM |
618 | /* Packet types */ |
619 | ||
620 | #define PKT_OPEN 0x01 | |
621 | #define PKT_UPDATE 0x02 | |
622 | #define PKT_NOTIFICATION 0x03 | |
623 | #define PKT_KEEPALIVE 0x04 | |
9aed29e6 OZ |
624 | #define PKT_ROUTE_REFRESH 0x05 /* [RFC2918] */ |
625 | #define PKT_BEGIN_REFRESH 0x1e /* Dummy type for BoRR packet [RFC7313] */ | |
72a6ef11 | 626 | #define PKT_SCHEDULE_CLOSE 0x1f /* Used internally to schedule socket close */ |
c01e3741 MM |
627 | |
628 | /* Attributes */ | |
629 | ||
630 | #define BAF_OPTIONAL 0x80 | |
631 | #define BAF_TRANSITIVE 0x40 | |
632 | #define BAF_PARTIAL 0x20 | |
633 | #define BAF_EXT_LEN 0x10 | |
634 | ||
09ee846d OZ |
635 | #define BAF_DECODE_FLAGS 0x0100 /* Private flag - attribute flags are handled by the decode hook */ |
636 | ||
82f42ea0 | 637 | #define BA_ORIGIN 0x01 /* RFC 4271 */ /* WM */ |
c01e3741 MM |
638 | #define BA_AS_PATH 0x02 /* WM */ |
639 | #define BA_NEXT_HOP 0x03 /* WM */ | |
640 | #define BA_MULTI_EXIT_DISC 0x04 /* ON */ | |
c00d31be | 641 | #define BA_LOCAL_PREF 0x05 /* WD */ |
c01e3741 MM |
642 | #define BA_ATOMIC_AGGR 0x06 /* WD */ |
643 | #define BA_AGGREGATOR 0x07 /* OT */ | |
82f42ea0 OZ |
644 | #define BA_COMMUNITY 0x08 /* RFC 1997 */ /* OT */ |
645 | #define BA_ORIGINATOR_ID 0x09 /* RFC 4456 */ /* ON */ | |
646 | #define BA_CLUSTER_LIST 0x0a /* RFC 4456 */ /* ON */ | |
647 | #define BA_MP_REACH_NLRI 0x0e /* RFC 4760 */ | |
648 | #define BA_MP_UNREACH_NLRI 0x0f /* RFC 4760 */ | |
d15b0b0a OZ |
649 | #define BA_EXT_COMMUNITY 0x10 /* RFC 4360 */ |
650 | #define BA_AS4_PATH 0x11 /* RFC 6793 */ | |
651 | #define BA_AS4_AGGREGATOR 0x12 /* RFC 6793 */ | |
09ee846d | 652 | #define BA_AIGP 0x1a /* RFC 7311 */ |
2be9218a | 653 | #define BA_LARGE_COMMUNITY 0x20 /* RFC 8092 */ |
c01e3741 | 654 | |
1e37e35c OZ |
655 | /* Bird's private internal BGP attributes */ |
656 | #define BA_MPLS_LABEL_STACK 0xfe /* MPLS label stack transfer attribute */ | |
657 | ||
11b32d91 | 658 | /* BGP connection states */ |
c01e3741 MM |
659 | |
660 | #define BS_IDLE 0 | |
661 | #define BS_CONNECT 1 /* Attempting to connect */ | |
662 | #define BS_ACTIVE 2 /* Waiting for connection retry & listening */ | |
663 | #define BS_OPENSENT 3 | |
664 | #define BS_OPENCONFIRM 4 | |
665 | #define BS_ESTABLISHED 5 | |
11b32d91 OZ |
666 | #define BS_CLOSE 6 /* Used during transition to BS_IDLE */ |
667 | ||
ac574513 OZ |
668 | #define BS_MAX 7 |
669 | ||
11b32d91 | 670 | /* BGP start states |
9aed29e6 | 671 | * |
11b32d91 OZ |
672 | * Used in PS_START for fine-grained specification of starting state. |
673 | * | |
9aed29e6 OZ |
674 | * When BGP protocol is started by core, it goes to BSS_PREPARE. When BGP |
675 | * protocol done what is neccessary to start itself (like acquiring the lock), | |
d15b0b0a | 676 | * it goes to BSS_CONNECT. |
11b32d91 OZ |
677 | */ |
678 | ||
679 | #define BSS_PREPARE 0 /* Used before ordinary BGP started, i. e. waiting for lock */ | |
dd91e467 OZ |
680 | #define BSS_DELAY 1 /* Startup delay due to previous errors */ |
681 | #define BSS_CONNECT 2 /* Ordinary BGP connecting */ | |
11b32d91 | 682 | |
9aed29e6 OZ |
683 | |
684 | /* BGP feed states (TX) | |
685 | * | |
686 | * RFC 4724 specifies that an initial feed should end with End-of-RIB mark. | |
687 | * | |
688 | * RFC 7313 specifies that a route refresh should be demarcated by BoRR and EoRR packets. | |
689 | * | |
d15b0b0a | 690 | * These states (stored in c->feed_state) are used to keep track of these |
9aed29e6 OZ |
691 | * requirements. When such feed is started, BFS_LOADING / BFS_REFRESHING is |
692 | * set. When it ended, BFS_LOADED / BFS_REFRESHED is set to schedule End-of-RIB | |
693 | * or EoRR packet. When the packet is sent, the state returned to BFS_NONE. | |
694 | * | |
695 | * Note that when a non-demarcated feed (e.g. plain RFC 4271 initial load | |
696 | * without End-of-RIB or plain RFC 2918 route refresh without BoRR/EoRR | |
697 | * demarcation) is active, BFS_NONE is set. | |
698 | * | |
699 | * BFS_NONE, BFS_LOADING and BFS_REFRESHING are also used as load states (RX) | |
700 | * with correspondent semantics (-, expecting End-of-RIB, expecting EoRR). | |
701 | */ | |
702 | ||
703 | #define BFS_NONE 0 /* No feed or original non-demarcated feed */ | |
704 | #define BFS_LOADING 1 /* Initial feed active, End-of-RIB planned */ | |
705 | #define BFS_LOADED 2 /* Loading done, End-of-RIB marker scheduled */ | |
706 | #define BFS_REFRESHING 3 /* Route refresh (introduced by BoRR) active */ | |
707 | #define BFS_REFRESHED 4 /* Refresh done, EoRR packet scheduled */ | |
708 | ||
709 | ||
11b32d91 OZ |
710 | /* Error classes */ |
711 | ||
712 | #define BE_NONE 0 | |
713 | #define BE_MISC 1 /* Miscellaneous error */ | |
714 | #define BE_SOCKET 2 /* Socket error */ | |
715 | #define BE_BGP_RX 3 /* BGP protocol error notification received */ | |
716 | #define BE_BGP_TX 4 /* BGP protocol error notification sent */ | |
717 | #define BE_AUTO_DOWN 5 /* Automatic shutdown */ | |
718 | #define BE_MAN_DOWN 6 /* Manual shutdown */ | |
719 | ||
720 | /* Misc error codes */ | |
721 | ||
722 | #define BEM_NEIGHBOR_LOST 1 | |
723 | #define BEM_INVALID_NEXT_HOP 2 | |
72b28a04 | 724 | #define BEM_INVALID_MD5 3 /* MD5 authentication kernel request failed (possibly not supported) */ |
a34b0934 | 725 | #define BEM_NO_SOCKET 4 |
523f020b OZ |
726 | #define BEM_LINK_DOWN 5 |
727 | #define BEM_BFD_DOWN 6 | |
728 | #define BEM_GRACEFUL_RESTART 7 | |
11b32d91 | 729 | |
72b28a04 OZ |
730 | /* Automatic shutdown error codes */ |
731 | ||
732 | #define BEA_ROUTE_LIMIT_EXCEEDED 1 | |
c01e3741 | 733 | |
bd2d8190 MM |
734 | /* Well-known communities */ |
735 | ||
736 | #define BGP_COMM_NO_EXPORT 0xffffff01 /* Don't export outside local AS / confed. */ | |
737 | #define BGP_COMM_NO_ADVERTISE 0xffffff02 /* Don't export at all */ | |
738 | #define BGP_COMM_NO_EXPORT_SUBCONFED 0xffffff03 /* NO_EXPORT even in local confederation */ | |
739 | ||
5bd73431 OZ |
740 | #define BGP_COMM_LLGR_STALE 0xffff0006 /* Route is stale according to LLGR */ |
741 | #define BGP_COMM_NO_LLGR 0xffff0007 /* Do not treat the route according to LLGR */ | |
742 | ||
cea63664 MM |
743 | /* Origins */ |
744 | ||
745 | #define ORIGIN_IGP 0 | |
746 | #define ORIGIN_EGP 1 | |
747 | #define ORIGIN_INCOMPLETE 2 | |
748 | ||
cf31112f | 749 | |
2638249d | 750 | #endif |