xref: /openbsd-src/usr.sbin/bgpd/session.h (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /*	$OpenBSD: session.h,v 1.116 2013/05/30 20:29:27 florian Exp $ */
2 
3 /*
4  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <time.h>
22 
23 #define	MAX_BACKLOG			5
24 #define	INTERVAL_CONNECTRETRY		120
25 #define	INTERVAL_HOLD_INITIAL		240
26 #define	INTERVAL_HOLD			90
27 #define	INTERVAL_IDLE_HOLD_INITIAL	30
28 #define	INTERVAL_HOLD_CLONED		3600
29 #define	INTERVAL_HOLD_DEMOTED		60
30 #define	MAX_IDLE_HOLD			3600
31 #define	MSGSIZE_HEADER			19
32 #define	MSGSIZE_HEADER_MARKER		16
33 #define	MSGSIZE_NOTIFICATION_MIN	21	/* 19 hdr + 1 code + 1 sub */
34 #define	MSGSIZE_OPEN_MIN		29
35 #define	MSGSIZE_UPDATE_MIN		23
36 #define	MSGSIZE_KEEPALIVE		MSGSIZE_HEADER
37 #define	MSGSIZE_RREFRESH		MSGSIZE_HEADER + 4
38 #define	MSG_PROCESS_LIMIT		25
39 #define	SESSION_CLEAR_DELAY		5
40 
41 enum session_state {
42 	STATE_NONE,
43 	STATE_IDLE,
44 	STATE_CONNECT,
45 	STATE_ACTIVE,
46 	STATE_OPENSENT,
47 	STATE_OPENCONFIRM,
48 	STATE_ESTABLISHED
49 };
50 
51 enum session_events {
52 	EVNT_NONE,
53 	EVNT_START,
54 	EVNT_STOP,
55 	EVNT_CON_OPEN,
56 	EVNT_CON_CLOSED,
57 	EVNT_CON_OPENFAIL,
58 	EVNT_CON_FATAL,
59 	EVNT_TIMER_CONNRETRY,
60 	EVNT_TIMER_HOLDTIME,
61 	EVNT_TIMER_KEEPALIVE,
62 	EVNT_RCVD_OPEN,
63 	EVNT_RCVD_KEEPALIVE,
64 	EVNT_RCVD_UPDATE,
65 	EVNT_RCVD_NOTIFICATION
66 };
67 
68 enum blockmodes {
69 	BM_NORMAL,
70 	BM_NONBLOCK
71 };
72 
73 enum msg_type {
74 	OPEN = 1,
75 	UPDATE,
76 	NOTIFICATION,
77 	KEEPALIVE,
78 	RREFRESH
79 };
80 
81 enum suberr_header {
82 	ERR_HDR_SYNC = 1,
83 	ERR_HDR_LEN,
84 	ERR_HDR_TYPE
85 };
86 
87 enum suberr_open {
88 	ERR_OPEN_VERSION = 1,
89 	ERR_OPEN_AS,
90 	ERR_OPEN_BGPID,
91 	ERR_OPEN_OPT,
92 	ERR_OPEN_AUTH,
93 	ERR_OPEN_HOLDTIME,
94 	ERR_OPEN_CAPA
95 };
96 
97 enum suberr_fsm {
98 	ERR_FSM_UNSPECIFIC = 0,
99 	ERR_FSM_UNEX_OPENSENT,
100 	ERR_FSM_UNEX_OPENCONFIRM,
101 	ERR_FSM_UNEX_ESTABLISHED
102 };
103 
104 enum opt_params {
105 	OPT_PARAM_NONE,
106 	OPT_PARAM_AUTH,
107 	OPT_PARAM_CAPABILITIES
108 };
109 
110 enum capa_codes {
111 	CAPA_NONE,
112 	CAPA_MP,
113 	CAPA_REFRESH,
114 	CAPA_RESTART = 64,
115 	CAPA_AS4BYTE = 65
116 };
117 
118 struct bgp_msg {
119 	struct ibuf	*buf;
120 	enum msg_type	 type;
121 	u_int16_t	 len;
122 };
123 
124 struct msg_header {
125 	u_char			 marker[MSGSIZE_HEADER_MARKER];
126 	u_int16_t		 len;
127 	u_int8_t		 type;
128 };
129 
130 struct msg_open {
131 	struct msg_header	 header;
132 	u_int32_t		 bgpid;
133 	u_int16_t		 myas;
134 	u_int16_t		 holdtime;
135 	u_int8_t		 version;
136 	u_int8_t		 optparamlen;
137 };
138 
139 struct bgpd_sysdep {
140 	u_int8_t		no_pfkey;
141 	u_int8_t		no_md5sig;
142 };
143 
144 struct ctl_conn {
145 	TAILQ_ENTRY(ctl_conn)	entry;
146 	struct imsgbuf		ibuf;
147 	int			restricted;
148 };
149 
150 TAILQ_HEAD(ctl_conns, ctl_conn)	ctl_conns;
151 
152 struct peer_stats {
153 	u_int64_t		 msg_rcvd_open;
154 	u_int64_t		 msg_rcvd_update;
155 	u_int64_t		 msg_rcvd_notification;
156 	u_int64_t		 msg_rcvd_keepalive;
157 	u_int64_t		 msg_rcvd_rrefresh;
158 	u_int64_t		 msg_sent_open;
159 	u_int64_t		 msg_sent_update;
160 	u_int64_t		 msg_sent_notification;
161 	u_int64_t		 msg_sent_keepalive;
162 	u_int64_t		 msg_sent_rrefresh;
163 	u_int64_t		 prefix_rcvd_update;
164 	u_int64_t		 prefix_rcvd_withdraw;
165 	u_int64_t		 prefix_rcvd_eor;
166 	u_int64_t		 prefix_sent_update;
167 	u_int64_t		 prefix_sent_withdraw;
168 	u_int64_t		 prefix_sent_eor;
169 	time_t			 last_updown;
170 	time_t			 last_read;
171 	u_int32_t		 prefix_cnt;
172 	u_int8_t		 last_sent_errcode;
173 	u_int8_t		 last_sent_suberr;
174 };
175 
176 enum Timer {
177 	Timer_None,
178 	Timer_ConnectRetry,
179 	Timer_Keepalive,
180 	Timer_Hold,
181 	Timer_IdleHold,
182 	Timer_IdleHoldReset,
183 	Timer_CarpUndemote,
184 	Timer_RestartTimeout,
185 	Timer_Max
186 };
187 
188 struct peer_timer {
189 	TAILQ_ENTRY(peer_timer)	entry;
190 	enum Timer		type;
191 	time_t			val;
192 };
193 
194 TAILQ_HEAD(peer_timer_head, peer_timer);
195 
196 struct peer {
197 	struct peer_config	 conf;
198 	struct peer_stats	 stats;
199 	struct {
200 		struct capabilities	ann;
201 		struct capabilities	peer;
202 		struct capabilities	neg;
203 	}			 capa;
204 	struct {
205 		struct bgpd_addr	local_addr;
206 		u_int32_t		spi_in;
207 		u_int32_t		spi_out;
208 		enum auth_method	method;
209 		u_int8_t		established;
210 	} auth;
211 	struct sockaddr_storage	 sa_local;
212 	struct sockaddr_storage	 sa_remote;
213 	struct peer_timer_head	 timers;
214 	struct msgbuf		 wbuf;
215 	struct ibuf_read	*rbuf;
216 	struct peer		*next;
217 	struct peer		*template;
218 	int			 fd;
219 	int			 lasterr;
220 	u_int			 errcnt;
221 	u_int			 IdleHoldTime;
222 	u_int32_t		 remote_bgpid;
223 	enum session_state	 state;
224 	enum session_state	 prev_state;
225 	u_int16_t		 short_as;
226 	u_int16_t		 holdtime;
227 	u_int8_t		 depend_ok;
228 	u_int8_t		 demoted;
229 	u_int8_t		 passive;
230 };
231 
232 extern struct peer	*peers;
233 extern time_t		 pauseaccept;
234 
235 struct ctl_timer {
236 	enum Timer	type;
237 	time_t		val;
238 };
239 
240 /* carp.c */
241 int	 carp_demote_init(char *, int);
242 void	 carp_demote_shutdown(void);
243 int	 carp_demote_get(char *);
244 int	 carp_demote_set(char *, int);
245 
246 /* config.c */
247 int	 merge_config(struct bgpd_config *, struct bgpd_config *,
248 	    struct peer *, struct listen_addrs *);
249 void	 prepare_listeners(struct bgpd_config *);
250 int	 get_mpe_label(struct rdomain *);
251 
252 /* control.c */
253 int	control_init(int, char *);
254 int	control_listen(int);
255 void	control_shutdown(int);
256 int	control_dispatch_msg(struct pollfd *, u_int *);
257 unsigned int	control_accept(int, int);
258 
259 /* log.c */
260 char		*log_fmt_peer(const struct peer_config *);
261 void		 log_statechange(struct peer *, enum session_state,
262 		    enum session_events);
263 void		 log_notification(const struct peer *, u_int8_t, u_int8_t,
264 		    u_char *, u_int16_t, const char *);
265 void		 log_conn_attempt(const struct peer *, struct sockaddr *);
266 
267 /* mrt.c */
268 void		 mrt_dump_bgp_msg(struct mrt *, void *, u_int16_t,
269 		     struct peer *);
270 void		 mrt_dump_state(struct mrt *, u_int16_t, u_int16_t,
271 		     struct peer *);
272 void		 mrt_done(void *);
273 
274 /* parse.y */
275 int	 parse_config(char *, struct bgpd_config *, struct mrt_head *,
276 	    struct peer **, struct network_head *, struct filter_head *,
277 	    struct rdomain_head *);
278 
279 /* pfkey.c */
280 int	pfkey_read(int, struct sadb_msg *);
281 int	pfkey_establish(struct peer *);
282 int	pfkey_remove(struct peer *);
283 int	pfkey_init(struct bgpd_sysdep *);
284 
285 /* printconf.c */
286 void	print_config(struct bgpd_config *, struct rib_names *,
287 	    struct network_head *, struct peer *, struct filter_head *,
288 	    struct mrt_head *, struct rdomain_head *);
289 
290 /* rde.c */
291 pid_t	 rde_main(int[2], int[2], int[2], int[2], int);
292 
293 /* session.c */
294 void		 session_socket_blockmode(int, enum blockmodes);
295 pid_t		 session_main(int[2], int[2], int[2], int[2]);
296 void		 bgp_fsm(struct peer *, enum session_events);
297 int		 session_neighbor_rrefresh(struct peer *p);
298 struct peer	*getpeerbyaddr(struct bgpd_addr *);
299 struct peer	*getpeerbydesc(const char *);
300 int		 imsg_compose_parent(int, u_int32_t, pid_t, void *, u_int16_t);
301 int		 imsg_compose_rde(int, pid_t, void *, u_int16_t);
302 void	 	 session_stop(struct peer *, u_int8_t);
303 
304 /* timer.c */
305 time_t			 getmonotime(void);
306 struct peer_timer	*timer_get(struct peer *, enum Timer);
307 struct peer_timer	*timer_nextisdue(struct peer *);
308 time_t			 timer_nextduein(struct peer *);
309 int			 timer_running(struct peer *, enum Timer, time_t *);
310 void			 timer_set(struct peer *, enum Timer, u_int);
311 void			 timer_stop(struct peer *, enum Timer);
312 void			 timer_remove(struct peer *, enum Timer);
313 void			 timer_remove_all(struct peer *);
314