Add grouping session functionality for load balancing and failover
[l2tpns.git] / bgp.h
1 /* BGPv4 (RFC1771) */
2 /* $Id: bgp.h,v 1.5 2005-06-04 15:42:35 bodea Exp $ */
3
4 #ifndef __BGP_H__
5 #define __BGP_H__
6
7 #define BGP_MAX_PACKET_SIZE 4096
8 #define BGP_HOLD_TIME 180 /* seconds before peer times us out */
9 #define BGP_KEEPALIVE_TIME 60 /* seconds between messages */
10 #define BGP_STATE_TIME 60 /* state transition timeout in seconds */
11 #define BGP_MAX_RETRY 42 /* maximum number of times to retry */
12 #define BGP_RETRY_BACKOFF 60 /* number of seconds between retries,
13 cumulative */
14
15 #define BGP_METRIC 1 /* multi_exit_disc */
16 #define BGP_LOCAL_PREF 100 /* local preference value */
17
18 struct bgp_header {
19 char marker[16];
20 uint16_t len;
21 uint8_t type;
22 } __attribute__ ((packed));
23
24 /* bgp_header.type */
25 #define BGP_MSG_OPEN 1
26 #define BGP_MSG_UPDATE 2
27 #define BGP_MSG_NOTIFICATION 3
28 #define BGP_MSG_KEEPALIVE 4
29
30 struct bgp_packet {
31 struct bgp_header header;
32 char data[BGP_MAX_PACKET_SIZE - sizeof(struct bgp_header)]; /* variable */
33 } __attribute__ ((packed));
34
35 struct bgp_data_open {
36 uint8_t version;
37 #define BGP_VERSION 4
38 uint16_t as;
39 uint16_t hold_time;
40 uint32_t identifier;
41 uint8_t opt_len;
42 #define BGP_DATA_OPEN_SIZE 10 /* size of struct excluding opt_params */
43 char opt_params[sizeof(((struct bgp_packet *)0)->data) - BGP_DATA_OPEN_SIZE]; /* variable */
44 } __attribute__ ((packed));
45
46 struct bgp_opt_param {
47 uint8_t type;
48 uint8_t len;
49 #define BGP_MAX_OPT_PARAM_SIZE 256
50 char value[BGP_MAX_OPT_PARAM_SIZE];
51 } __attribute__ ((packed));
52
53 #define BGP_PARAM_TYPE_CAPABILITY 2
54 struct bgp_capability {
55 uint8_t code;
56 uint8_t len;
57 #define BGP_MAX_CAPABILITY_SIZE 256
58 char value[BGP_MAX_CAPABILITY_SIZE];
59 } __attribute__ ((packed));
60
61 /* RFC4760 Multiprotocol extension */
62 #define BGP_CAP_CODE_MP 1
63
64 struct bgp_mp_cap_param {
65 uint16_t afi; /* sa_family_t */
66 uint8_t reserved; /* SHOULD be 0 */
67 uint8_t safi;
68 } __attribute__ ((packed));
69
70 /* bgp_mp_cap_param.afi */
71 #define BGP_MP_AFI_RESERVED 0
72 #define BGP_MP_AFI_IPv4 1
73 #define BGP_MP_AFI_IPv6 2
74 /* bgp_mp_cap_param.safi */
75 #define BGP_MP_SAFI_UNICAST 1
76 #define BGP_MP_SAFI_MULTICAST 2
77
78 struct bgp_ip6_prefix {
79 uint8_t len;
80 uint8_t prefix[16]; /* variable */
81 } __attribute__ ((packed));
82
83 /* end of RFC4760 specific definitions */
84
85 struct bgp_ip_prefix {
86 uint8_t len;
87 uint32_t prefix; /* variable */
88 } __attribute__ ((packed));
89
90 /* works for both IPv4 and IPv6 prefixes */
91 #define BGP_IP_PREFIX_SIZE(p) (1 + ((p).len / 8) + ((p).len % 8 != 0))
92
93 struct bgp_path_attr {
94 uint8_t flags;
95 uint8_t code;
96 union {
97 struct {
98 uint8_t len;
99 char value[29]; /* semi-random size, adequate for l2tpns */
100 } __attribute__ ((packed)) s; /* short */
101 struct {
102 uint16_t len;
103 char value[28];
104 } __attribute__ ((packed)) e; /* extended */
105 } data; /* variable */
106 } __attribute__ ((packed));
107
108 struct bgp_attr_mp_reach_nlri_partial {
109 uint16_t afi; /* sa_family_t */
110 uint8_t safi;
111 uint8_t next_hop_len;
112 uint8_t next_hop[16];
113 uint8_t reserved;
114 } __attribute__ ((packed));
115 #define BGP_PATH_ATTR_MP_REACH_NLRI_PARTIAL_SIZE (3 + sizeof(struct bgp_attr_mp_reach_nlri_partial))
116
117 struct bgp_attr_mp_unreach_nlri_partial {
118 uint16_t afi; /* sa_family_t */
119 uint8_t safi;
120 } __attribute__ ((packed));
121 /* we use it as an extended attribute */
122 #define BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE (4 + sizeof(struct bgp_attr_mp_unreach_nlri_partial))
123
124 /* bgp_path_attr.flags (bitfields) */
125 #define BGP_PATH_ATTR_FLAG_OPTIONAL (1 << 7)
126 #define BGP_PATH_ATTR_FLAG_TRANS (1 << 6)
127 #define BGP_PATH_ATTR_FLAG_PARTIAL (1 << 5)
128 #define BGP_PATH_ATTR_FLAG_EXTLEN (1 << 4)
129
130 /* bgp_path_attr.code, ...value */
131 #define BGP_PATH_ATTR_CODE_ORIGIN 1 /* well-known, mandatory */
132 # define BGP_PATH_ATTR_CODE_ORIGIN_IGP 0
133 # define BGP_PATH_ATTR_CODE_ORIGIN_EGP 1
134 # define BGP_PATH_ATTR_CODE_ORIGIN_INCOMPLETE 2
135 #define BGP_PATH_ATTR_CODE_AS_PATH 2 /* well-known, mandatory */
136 # define BGP_PATH_ATTR_CODE_AS_PATH_AS_SET 1
137 # define BGP_PATH_ATTR_CODE_AS_PATH_AS_SEQUENCE 2
138 #define BGP_PATH_ATTR_CODE_NEXT_HOP 3 /* well-known, mandatory */
139 #define BGP_PATH_ATTR_CODE_MULTI_EXIT_DISC 4 /* optional, non-transitive */
140 #define BGP_PATH_ATTR_CODE_LOCAL_PREF 5 /* well-known, discretionary */
141 #define BGP_PATH_ATTR_CODE_ATOMIC_AGGREGATE 6 /* well-known, discretionary */
142 #define BGP_PATH_ATTR_CODE_AGGREGATOR 7 /* optional, transitive */
143 #define BGP_PATH_ATTR_CODE_COMMUNITIES 8 /* optional, transitive (RFC1997) */
144 #define BGP_PATH_ATTR_CODE_MP_REACH_NLRI 14 /* optional, non-transitive (RFC4760) */
145 #define BGP_PATH_ATTR_CODE_MP_UNREACH_NLRI 15 /* optional, non-transitive (RFC4760) */
146
147 #define BGP_PATH_ATTR_SIZE(p) ((((p).flags & BGP_PATH_ATTR_FLAG_EXTLEN) \
148 ? ((p).data.e.len + 4) : (p).data.s.len) + 3)
149
150 /* well known COMMUNITIES */
151 #define BGP_COMMUNITY_NO_EXPORT 0xffffff01 /* don't advertise outside confederation */
152 #define BGP_COMMUNITY_NO_ADVERTISE 0xffffff02 /* don't advertise to any peer */
153 #define BGP_COMMUNITY_NO_EXPORT_SUBCONFED 0xffffff03 /* don't advertise to any other AS */
154
155 struct bgp_data_notification {
156 uint8_t error_code;
157 uint8_t error_subcode;
158 char data[sizeof(((struct bgp_packet *)0)->data) - 2]; /* variable */
159 } __attribute__ ((packed));
160
161 /* bgp_data_notification.error_code, .error_subcode */
162 #define BGP_ERR_UNSPEC 0
163 #define BGP_ERR_HEADER 1
164 # define BGP_ERR_HDR_NOT_SYNC 1
165 # define BGP_ERR_HDR_BAD_LEN 2
166 # define BGP_ERR_HDR_BAD_TYPE 3
167 #define BGP_ERR_OPEN 2
168 # define BGP_ERR_OPN_VERSION 1
169 # define BGP_ERR_OPN_BAD_AS 2
170 # define BGP_ERR_OPN_BAD_IDENT 3
171 # define BGP_ERR_OPN_UNSUP_PARAM 4
172 # define BGP_ERR_OPN_AUTH_FAILURE 5
173 # define BGP_ERR_OPN_HOLD_TIME 6
174 # define BGP_ERR_OPN_UNSUP_CAP 7
175 #define BGP_ERR_UPDATE 3
176 # define BGP_ERR_UPD_BAD_ATTR_LIST 1
177 # define BGP_ERR_UPD_UNKN_WK_ATTR 2
178 # define BGP_ERR_UPD_MISS_WK_ATTR 3
179 # define BGP_ERR_UPD_BAD_ATTR_FLAG 4
180 # define BGP_ERR_UPD_BAD_ATTR_LEN 5
181 # define BGP_ERR_UPD_BAD_ORIGIN 6
182 # define BGP_ERR_UPD_ROUTING_LOOP 7
183 # define BGP_ERR_UPD_BAD_NEXT_HOP 8
184 # define BGP_ERR_UPD_BAD_OPT_ATTR 9
185 # define BGP_ERR_UPD_BAD_NETWORK 10
186 # define BGP_ERR_UPD_BAD_AS_PATH 11
187 #define BGP_ERR_HOLD_TIMER_EXP 4
188 #define BGP_ERR_FSM 5
189 #define BGP_ERR_CEASE 6
190
191 enum bgp_state {
192 Disabled, /* initial, or failed */
193 Idle, /* trying to connect */
194 Connect, /* connect issued */
195 Active, /* connected, waiting to send OPEN */
196 OpenSent, /* OPEN sent, waiting for peer OPEN */
197 OpenConfirm, /* KEEPALIVE sent, waiting for peer KEEPALIVE */
198 Established, /* established */
199 };
200
201 struct bgp_route6_list {
202 struct bgp_ip6_prefix dest;
203 struct bgp_route6_list *next;
204 };
205
206 struct bgp_route_list {
207 struct bgp_ip_prefix dest;
208 struct bgp_route_list *next;
209 };
210
211 struct bgp_buf {
212 struct bgp_packet packet; /* BGP packet */
213 size_t done; /* bytes sent/recvd */
214 };
215
216 enum bgp_mp_handling {
217 HandleIPv6Routes,
218 DoesntHandleIPv6Routes,
219 HandlingUnknown,
220 };
221
222 /* state */
223 struct bgp_peer {
224 char name[32]; /* peer name */
225 in_addr_t addr; /* peer address */
226 in_addr_t source_addr; /* our source address */
227 int as; /* AS number */
228 int sock;
229 enum bgp_state state; /* FSM state */
230 enum bgp_state next_state; /* next state after outbuf cleared */
231 time_t state_time; /* time of last state change */
232 time_t keepalive_time; /* time to send next keepalive */
233 time_t retry_time; /* time for connection retry */
234 int retry_count; /* connection retry count */
235 int init_keepalive; /* initial keepalive time */
236 int init_hold; /* initial hold time */
237 int keepalive; /* negotiated keepalive time */
238 int hold; /* negotiated hold time */
239 time_t expire_time; /* time next peer packet expected */
240 int routing; /* propagate routes */
241 int update_routes; /* UPDATE required */
242 struct bgp_route_list *routes; /* routes known by this peer */
243 struct bgp_buf *outbuf; /* pending output */
244 struct bgp_buf *inbuf; /* pending input */
245 int cli_flag; /* updates requested from CLI */
246 char *path_attrs; /* path attrs to send in UPDATE message */
247 int path_attr_len; /* length of path attrs */
248 int path_attr_len_without_nexthop; /* length of path attrs without NEXT_HOP */
249 uint32_t events; /* events to poll */
250 struct event_data edata; /* poll data */
251 enum bgp_mp_handling mp_handling; /* how it handles IPv6 routes advertisements */
252 int update_routes6; /* UPDATE required for IPv6 routes */
253 struct bgp_route6_list *routes6; /* IPv6 routes known by this peer */
254 char mp_reach_nlri_partial[BGP_PATH_ATTR_MP_REACH_NLRI_PARTIAL_SIZE];
255 char mp_unreach_nlri_partial[BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE];
256 };
257
258 /* bgp_peer.cli_flag */
259 #define BGP_CLI_SUSPEND 1
260 #define BGP_CLI_ENABLE 2
261 #define BGP_CLI_RESTART 3
262
263 extern struct bgp_peer *bgp_peers;
264 extern int bgp_configured;
265
266 /* actions */
267 int bgp_setup(int as);
268 int bgp_start(struct bgp_peer *peer, char *name, int as, int keepalive,
269 int hold, struct in_addr update_source, int enable);
270
271 void bgp_stop(struct bgp_peer *peer);
272 void bgp_halt(struct bgp_peer *peer);
273 int bgp_restart(struct bgp_peer *peer);
274 int bgp_add_route(in_addr_t ip, int prefixlen);
275 int bgp_add_route6(struct in6_addr ip, int prefixlen);
276 int bgp_del_route(in_addr_t ip, int prefixlen);
277 int bgp_del_route6(struct in6_addr ip, int prefixlen);
278 void bgp_enable_routing(int enable);
279 int bgp_set_poll(void);
280 int bgp_process(uint32_t events[]);
281 void bgp_process_peers_timers();
282 char const *bgp_state_str(enum bgp_state state);
283
284 #endif /* __BGP_H__ */