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