xref: /openbsd-src/usr.sbin/bgpd/session.h (revision 0d4ceb41004f299c91661fe76cfd13f053a31300)
1*0d4ceb41Sclaudio /*	$OpenBSD: session.h,v 1.184 2024/12/16 16:10:10 claudio Exp $ */
2a16c0992Shenning 
3a16c0992Shenning /*
4050527e1Shenning  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5a16c0992Shenning  *
6a16c0992Shenning  * Permission to use, copy, modify, and distribute this software for any
7a16c0992Shenning  * purpose with or without fee is hereby granted, provided that the above
8a16c0992Shenning  * copyright notice and this permission notice appear in all copies.
9a16c0992Shenning  *
10a16c0992Shenning  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11a16c0992Shenning  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12a16c0992Shenning  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13a16c0992Shenning  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14a16c0992Shenning  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15a16c0992Shenning  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16a16c0992Shenning  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17a16c0992Shenning  */
18a16c0992Shenning 
19a16c0992Shenning #include <sys/types.h>
200b8ba8d8Shenning #include <sys/socket.h>
219632980cShenning #include <time.h>
22a16c0992Shenning 
23a16c0992Shenning #define	MAX_BACKLOG			5
24a16c0992Shenning #define	INTERVAL_CONNECTRETRY		120
25a16c0992Shenning #define	INTERVAL_HOLD_INITIAL		240
26a16c0992Shenning #define	INTERVAL_HOLD			90
27065afdacShenning #define	INTERVAL_IDLE_HOLD_INITIAL	30
287f5c1560Shenning #define	INTERVAL_HOLD_DEMOTED		60
296c15f943Sclaudio #define	INTERVAL_STALE			180
301d44387dSclaudio #define	INTERVAL_SESSION_DOWN		3600
31500c9a74Shenning #define	MAX_IDLE_HOLD			3600
32a16c0992Shenning #define	MSGSIZE_HEADER			19
33a16c0992Shenning #define	MSGSIZE_HEADER_MARKER		16
34a16c0992Shenning #define	MSGSIZE_NOTIFICATION_MIN	21	/* 19 hdr + 1 code + 1 sub */
35a16c0992Shenning #define	MSGSIZE_OPEN_MIN		29
36a16c0992Shenning #define	MSGSIZE_UPDATE_MIN		23
37a16c0992Shenning #define	MSGSIZE_KEEPALIVE		MSGSIZE_HEADER
3863c2de87Sclaudio #define	MSGSIZE_RREFRESH		(MSGSIZE_HEADER + 4)
3963c2de87Sclaudio #define	MSGSIZE_RREFRESH_MIN		MSGSIZE_RREFRESH
40a24c8854Shenning #define	MSG_PROCESS_LIMIT		25
410c6d719cShenning #define	SESSION_CLEAR_DELAY		5
42a16c0992Shenning 
439d3ea286Shenning enum session_state {
449d3ea286Shenning 	STATE_NONE,
459d3ea286Shenning 	STATE_IDLE,
469d3ea286Shenning 	STATE_CONNECT,
479d3ea286Shenning 	STATE_ACTIVE,
489d3ea286Shenning 	STATE_OPENSENT,
499d3ea286Shenning 	STATE_OPENCONFIRM,
509d3ea286Shenning 	STATE_ESTABLISHED
519d3ea286Shenning };
529d3ea286Shenning 
539d3ea286Shenning enum session_events {
549d3ea286Shenning 	EVNT_NONE,
559d3ea286Shenning 	EVNT_START,
569d3ea286Shenning 	EVNT_STOP,
579d3ea286Shenning 	EVNT_CON_OPEN,
589d3ea286Shenning 	EVNT_CON_CLOSED,
599d3ea286Shenning 	EVNT_CON_OPENFAIL,
609d3ea286Shenning 	EVNT_CON_FATAL,
619d3ea286Shenning 	EVNT_TIMER_CONNRETRY,
629d3ea286Shenning 	EVNT_TIMER_HOLDTIME,
639d3ea286Shenning 	EVNT_TIMER_KEEPALIVE,
64ab9b1ccdSclaudio 	EVNT_TIMER_SENDHOLD,
659d3ea286Shenning 	EVNT_RCVD_OPEN,
669d3ea286Shenning 	EVNT_RCVD_KEEPALIVE,
679d3ea286Shenning 	EVNT_RCVD_UPDATE,
686c15f943Sclaudio 	EVNT_RCVD_NOTIFICATION,
696c15f943Sclaudio 	EVNT_RCVD_GRACE_NOTIFICATION,
709d3ea286Shenning };
719d3ea286Shenning 
72a16c0992Shenning enum msg_type {
73*0d4ceb41Sclaudio 	MSG_OPEN = 1,
74*0d4ceb41Sclaudio 	MSG_UPDATE,
75*0d4ceb41Sclaudio 	MSG_NOTIFICATION,
76*0d4ceb41Sclaudio 	MSG_KEEPALIVE,
77*0d4ceb41Sclaudio 	MSG_RREFRESH
78a16c0992Shenning };
79a16c0992Shenning 
80a16c0992Shenning enum suberr_header {
81a16c0992Shenning 	ERR_HDR_SYNC = 1,
82a16c0992Shenning 	ERR_HDR_LEN,
83a16c0992Shenning 	ERR_HDR_TYPE
84a16c0992Shenning };
85a16c0992Shenning 
86a16c0992Shenning enum suberr_open {
87a16c0992Shenning 	ERR_OPEN_VERSION = 1,
88a16c0992Shenning 	ERR_OPEN_AS,
89a16c0992Shenning 	ERR_OPEN_BGPID,
90a16c0992Shenning 	ERR_OPEN_OPT,
911114d9c2Sclaudio 	ERR_OPEN_AUTH,			/* deprecated */
929f9a2d6eShenning 	ERR_OPEN_HOLDTIME,
935e9951bbSphessler 	ERR_OPEN_CAPA,
941114d9c2Sclaudio 	ERR_OPEN_ROLE = 11,
95a16c0992Shenning };
96a16c0992Shenning 
97b972ce67Sclaudio enum suberr_fsm {
98b972ce67Sclaudio 	ERR_FSM_UNSPECIFIC = 0,
99b972ce67Sclaudio 	ERR_FSM_UNEX_OPENSENT,
100b972ce67Sclaudio 	ERR_FSM_UNEX_OPENCONFIRM,
101b972ce67Sclaudio 	ERR_FSM_UNEX_ESTABLISHED
102b972ce67Sclaudio };
103b972ce67Sclaudio 
10482cfeca0Shenning enum opt_params {
10582cfeca0Shenning 	OPT_PARAM_NONE,
10682cfeca0Shenning 	OPT_PARAM_AUTH,
107df79d77dSclaudio 	OPT_PARAM_CAPABILITIES,
108df79d77dSclaudio 	OPT_PARAM_EXT_LEN=255,
10982cfeca0Shenning };
11082cfeca0Shenning 
111775cb5d9Shenning struct bgpd_sysdep {
11239386878Sclaudio 	uint8_t			no_pfkey;
11339386878Sclaudio 	uint8_t			no_md5sig;
114775cb5d9Shenning };
115775cb5d9Shenning 
11627157683Shenning struct ctl_conn {
117435f34f3Shenning 	TAILQ_ENTRY(ctl_conn)	entry;
118c8f6e08eSclaudio 	struct imsgbuf		imsgbuf;
11941928d45Shenning 	int			restricted;
120383bcad8Sclaudio 	int			throttled;
121fb02cdf0Sclaudio 	int			terminate;
12227157683Shenning };
12327157683Shenning 
124faafae76Shenning struct peer_stats {
12583d69b66Sclaudio 	unsigned long long	 msg_rcvd_open;
12683d69b66Sclaudio 	unsigned long long	 msg_rcvd_update;
12783d69b66Sclaudio 	unsigned long long	 msg_rcvd_notification;
12883d69b66Sclaudio 	unsigned long long	 msg_rcvd_keepalive;
12983d69b66Sclaudio 	unsigned long long	 msg_rcvd_rrefresh;
13083d69b66Sclaudio 	unsigned long long	 msg_sent_open;
13183d69b66Sclaudio 	unsigned long long	 msg_sent_update;
13283d69b66Sclaudio 	unsigned long long	 msg_sent_notification;
13383d69b66Sclaudio 	unsigned long long	 msg_sent_keepalive;
13483d69b66Sclaudio 	unsigned long long	 msg_sent_rrefresh;
13563c2de87Sclaudio 	unsigned long long	 refresh_rcvd_req;
13663c2de87Sclaudio 	unsigned long long	 refresh_rcvd_borr;
13763c2de87Sclaudio 	unsigned long long	 refresh_rcvd_eorr;
13863c2de87Sclaudio 	unsigned long long	 refresh_sent_req;
13963c2de87Sclaudio 	unsigned long long	 refresh_sent_borr;
14063c2de87Sclaudio 	unsigned long long	 refresh_sent_eorr;
14183d69b66Sclaudio 	unsigned long long	 prefix_rcvd_update;
14283d69b66Sclaudio 	unsigned long long	 prefix_rcvd_withdraw;
14383d69b66Sclaudio 	unsigned long long	 prefix_rcvd_eor;
14483d69b66Sclaudio 	unsigned long long	 prefix_sent_update;
14583d69b66Sclaudio 	unsigned long long	 prefix_sent_withdraw;
14683d69b66Sclaudio 	unsigned long long	 prefix_sent_eor;
1479632980cShenning 	time_t			 last_updown;
1489632980cShenning 	time_t			 last_read;
1491f00d07fSclaudio 	time_t			 last_write;
150db359c81Sclaudio 	uint32_t		 msg_queue_len;
15139386878Sclaudio 	uint32_t		 prefix_cnt;
15239386878Sclaudio 	uint32_t		 prefix_out_cnt;
1534d242bdfSclaudio 	uint32_t		 pending_update;
1544d242bdfSclaudio 	uint32_t		 pending_withdraw;
15539386878Sclaudio 	uint8_t			 last_sent_errcode;
15639386878Sclaudio 	uint8_t			 last_sent_suberr;
15739386878Sclaudio 	uint8_t			 last_rcvd_errcode;
15839386878Sclaudio 	uint8_t			 last_rcvd_suberr;
159a78f83ceSderaadt 	char			 last_reason[REASON_LEN];
160faafae76Shenning };
161faafae76Shenning 
162d7629114Sclaudio struct auth_state {
163d7629114Sclaudio 	struct bgpd_addr	local_addr;
164d7629114Sclaudio 	struct bgpd_addr	remote_addr;
165d7629114Sclaudio 	uint32_t		spi_in;
166d7629114Sclaudio 	uint32_t		spi_out;
167d7629114Sclaudio 	enum auth_method	method;
168d7629114Sclaudio 	uint8_t			established;
169d7629114Sclaudio };
170d7629114Sclaudio 
171c6a99735Shenning enum Timer {
172c6a99735Shenning 	Timer_None,
173c6a99735Shenning 	Timer_ConnectRetry,
174c6a99735Shenning 	Timer_Keepalive,
175c6a99735Shenning 	Timer_Hold,
176ab9b1ccdSclaudio 	Timer_SendHold,
177c6a99735Shenning 	Timer_IdleHold,
178c6a99735Shenning 	Timer_IdleHoldReset,
1793a1e4272Shenning 	Timer_CarpUndemote,
18098b82802Sclaudio 	Timer_RestartTimeout,
1811d44387dSclaudio 	Timer_SessionDown,
182bd9df44eSclaudio 	Timer_Rtr_Refresh,
183bd9df44eSclaudio 	Timer_Rtr_Retry,
184bd9df44eSclaudio 	Timer_Rtr_Expire,
185dfd27b08Sclaudio 	Timer_Rtr_Active,
186c6a99735Shenning 	Timer_Max
187c6a99735Shenning };
188c6a99735Shenning 
18982fcfa8bSclaudio struct timer {
19082fcfa8bSclaudio 	TAILQ_ENTRY(timer)	entry;
191c6a99735Shenning 	enum Timer		type;
192c6a99735Shenning 	time_t			val;
193c6a99735Shenning };
194c6a99735Shenning 
19582fcfa8bSclaudio TAILQ_HEAD(timer_head, timer);
196c6a99735Shenning 
1979d3ea286Shenning struct peer {
1989d3ea286Shenning 	struct peer_config	 conf;
199faafae76Shenning 	struct peer_stats	 stats;
2007876190cSclaudio 	RB_ENTRY(peer)		 entry;
2012a25504dShenning 	struct {
2022a25504dShenning 		struct capabilities	ann;
2032a25504dShenning 		struct capabilities	peer;
20486729c90Sclaudio 		struct capabilities	neg;
2052a25504dShenning 	}			 capa;
206d7629114Sclaudio 	struct auth_state	 auth_state;
207d7629114Sclaudio 	struct auth_config	 auth_conf;
208a27d9e33Sclaudio 	struct bgpd_addr	 local;
209be6ced5eSclaudio 	struct bgpd_addr	 local_alt;
210a27d9e33Sclaudio 	struct bgpd_addr	 remote;
21182fcfa8bSclaudio 	struct timer_head	 timers;
21205453d67Sclaudio 	struct msgbuf		*wbuf;
21317098ec8Sclaudio 	struct peer		*template;
2148de33993Sderaadt 	int			 fd;
215c25f6a16Shenning 	int			 lasterr;
2164b86b4f3Shenning 	u_int			 errcnt;
217c25f6a16Shenning 	u_int			 IdleHoldTime;
218cf5008fdSclaudio 	unsigned int		 if_scope;	/* interface scope for IPv6 */
21939386878Sclaudio 	uint32_t		 remote_bgpid;
220c25f6a16Shenning 	enum session_state	 state;
221c25f6a16Shenning 	enum session_state	 prev_state;
22282fc6237Sclaudio 	enum reconf_action	 reconf_action;
223372bb3aaSclaudio 	enum role		 remote_role;
22439386878Sclaudio 	uint16_t		 short_as;
22539386878Sclaudio 	uint16_t		 holdtime;
22639386878Sclaudio 	uint16_t		 local_port;
22739386878Sclaudio 	uint16_t		 remote_port;
22839386878Sclaudio 	uint8_t			 depend_ok;
22939386878Sclaudio 	uint8_t			 demoted;
23039386878Sclaudio 	uint8_t			 passive;
23139386878Sclaudio 	uint8_t			 throttled;
23239386878Sclaudio 	uint8_t			 rpending;
233442a0320Sclaudio 	uint8_t			 rdesession;
2349d3ea286Shenning };
2359d3ea286Shenning 
23678c7f42bSclaudio extern time_t		 pauseaccept;
23727157683Shenning 
2380d594c94Shenning struct ctl_timer {
2390d594c94Shenning 	enum Timer	type;
2400d594c94Shenning 	time_t		val;
2411b5a1903Shenning };
2421b5a1903Shenning 
243802d458fSclaudio /* carp.c */
244802d458fSclaudio int	 carp_demote_init(char *, int);
245802d458fSclaudio void	 carp_demote_shutdown(void);
246802d458fSclaudio int	 carp_demote_get(char *);
247802d458fSclaudio int	 carp_demote_set(char *, int);
248802d458fSclaudio 
249802d458fSclaudio /* config.c */
25082fc6237Sclaudio void	 merge_config(struct bgpd_config *, struct bgpd_config *);
2517f893e0cSclaudio void	 free_deleted_peers(struct bgpd_config *);
2521adf6159Sremi int	 prepare_listeners(struct bgpd_config *);
253802d458fSclaudio 
254802d458fSclaudio /* control.c */
2551adf6159Sremi int	control_check(char *);
256802d458fSclaudio int	control_init(int, char *);
257802d458fSclaudio int	control_listen(int);
25876e39a7cSclaudio size_t	control_fill_pfds(struct pollfd *, size_t);
259802d458fSclaudio void	control_shutdown(int);
26076e39a7cSclaudio int	control_dispatch_msg(struct pollfd *, struct peer_head *);
261802d458fSclaudio unsigned int	control_accept(int, int);
2629d3ea286Shenning 
2639d3ea286Shenning /* log.c */
2640c88bf70Sclaudio char	*log_fmt_peer(const struct peer_config *);
265f884cd93Shenning void	 log_statechange(struct peer *, enum session_state,
2669d3ea286Shenning 	    enum session_events);
26739386878Sclaudio void	 log_notification(const struct peer *, uint8_t, uint8_t,
268beb044e9Sclaudio 	    const struct ibuf *, const char *);
269255fe563Sclaudio void	 log_conn_attempt(const struct peer *, struct sockaddr *,
270255fe563Sclaudio 	    socklen_t);
2719d3ea286Shenning 
272802d458fSclaudio /* mrt.c */
273eaff30a2Sclaudio void	 mrt_dump_bgp_msg(struct mrt *, struct ibuf *, struct peer *,
274eaff30a2Sclaudio 	    enum msg_type);
27539386878Sclaudio void	 mrt_dump_state(struct mrt *, uint16_t, uint16_t,
276802d458fSclaudio 	    struct peer *);
277bb8b30dfSclaudio void	 mrt_done(struct mrt *);
278802d458fSclaudio 
279c3246d3fShenning /* pfkey.c */
28093662c4eSclaudio struct sadb_msg;
281442124ddSclaudio int	pfkey_read(int, struct sadb_msg *);
282d7629114Sclaudio int	pfkey_establish(struct auth_state *, struct auth_config *,
283d7629114Sclaudio 	    const struct bgpd_addr *, const struct bgpd_addr *);
284d7629114Sclaudio int	pfkey_remove(struct auth_state *);
285c2bef38bSclaudio int	pfkey_init(void);
286d7629114Sclaudio int	pfkey_send_conf(struct imsgbuf *, uint32_t, struct auth_config *);
287d7629114Sclaudio int	pfkey_recv_conf(struct peer *, struct imsg *);
288d7629114Sclaudio int	tcp_md5_check(int, struct auth_config *);
289d7629114Sclaudio int	tcp_md5_set(int, struct auth_config *, struct bgpd_addr *);
290febbc040Sclaudio int	tcp_md5_prep_listener(struct listen_addr *, struct peer_head *);
291febbc040Sclaudio void	tcp_md5_add_listener(struct bgpd_config *, struct peer *);
292febbc040Sclaudio void	tcp_md5_del_listener(struct bgpd_config *, struct peer *);
293977216a6Shenning 
294977216a6Shenning /* printconf.c */
29582fc6237Sclaudio void	print_config(struct bgpd_config *, struct rib_names *);
2967f5c1560Shenning 
297802d458fSclaudio /* rde.c */
29813ff36d2Sclaudio void	rde_main(int, int);
299802d458fSclaudio 
300bd9df44eSclaudio /* rtr_proto.c */
301bd9df44eSclaudio struct rtr_session;
302bd9df44eSclaudio size_t			 rtr_count(void);
303bd9df44eSclaudio void			 rtr_check_events(struct pollfd *, size_t);
304bd9df44eSclaudio size_t			 rtr_poll_events(struct pollfd *, size_t, time_t *);
305d87cfbccSclaudio struct rtr_session	*rtr_new(uint32_t, struct rtr_config_msg *);
306bd9df44eSclaudio struct rtr_session	*rtr_get(uint32_t);
307bd9df44eSclaudio void			 rtr_free(struct rtr_session *);
308bd9df44eSclaudio void			 rtr_open(struct rtr_session *, int);
309bd9df44eSclaudio void			 rtr_config_prep(void);
310bd9df44eSclaudio void			 rtr_config_merge(void);
311d87cfbccSclaudio void			 rtr_config_keep(struct rtr_session *,
312d87cfbccSclaudio 			     struct rtr_config_msg *);
313bd9df44eSclaudio void			 rtr_roa_merge(struct roa_tree *);
31483072fb6Sclaudio void			 rtr_aspa_merge(struct aspa_tree *);
315bd9df44eSclaudio void			 rtr_shutdown(void);
316bd9df44eSclaudio void			 rtr_show(struct rtr_session *, pid_t);
317bd9df44eSclaudio 
318bd9df44eSclaudio /* rtr.c */
319dfd27b08Sclaudio void	rtr_sem_acquire(int);
320dfd27b08Sclaudio void	rtr_sem_release(int);
32183072fb6Sclaudio void	rtr_roa_insert(struct roa_tree *, struct roa *);
32283072fb6Sclaudio void	rtr_aspa_insert(struct aspa_tree *, struct aspa_set *);
323bd9df44eSclaudio void	rtr_main(int, int);
324bd9df44eSclaudio void	rtr_imsg_compose(int, uint32_t, pid_t, void *, size_t);
325bd9df44eSclaudio void	rtr_recalc(void);
326bd9df44eSclaudio 
327802d458fSclaudio /* session.c */
3287876190cSclaudio RB_PROTOTYPE(peer_head, peer, entry, peer_compare);
3297876190cSclaudio 
33013ff36d2Sclaudio void		 session_main(int, int);
331c9c4d4e4Sclaudio void		 bgp_fsm(struct peer *, enum session_events, struct ibuf *);
332802d458fSclaudio int		 session_neighbor_rrefresh(struct peer *p);
33382fc6237Sclaudio struct peer	*getpeerbydesc(struct bgpd_config *, const char *);
33482fc6237Sclaudio struct peer	*getpeerbyip(struct bgpd_config *, struct sockaddr *);
33539386878Sclaudio struct peer	*getpeerbyid(struct bgpd_config *, uint32_t);
336514180acSclaudio int		 peer_matched(struct peer *, struct ctl_neighbor *);
3370b920bb9Sclaudio int		 imsg_ctl_parent(struct imsg *);
3380b920bb9Sclaudio int		 imsg_ctl_rde(struct imsg *);
3390b920bb9Sclaudio int		 imsg_ctl_rde_msg(int, uint32_t, pid_t);
3403a82eff3Sclaudio void		 session_stop(struct peer *, uint8_t, const char *);
341d7629114Sclaudio struct bgpd_addr *session_localaddr(struct peer *);
3421b5a1903Shenning 
3431b5a1903Shenning /* timer.c */
34482fcfa8bSclaudio struct timer	*timer_get(struct timer_head *, enum Timer);
34582fcfa8bSclaudio struct timer	*timer_nextisdue(struct timer_head *, time_t);
34682fcfa8bSclaudio time_t		 timer_nextduein(struct timer_head *, time_t);
34782fcfa8bSclaudio int		 timer_running(struct timer_head *, enum Timer, time_t *);
34882fcfa8bSclaudio void		 timer_set(struct timer_head *, enum Timer, u_int);
34982fcfa8bSclaudio void		 timer_stop(struct timer_head *, enum Timer);
35082fcfa8bSclaudio void		 timer_remove(struct timer_head *, enum Timer);
35182fcfa8bSclaudio void		 timer_remove_all(struct timer_head *);
352