1 /* $OpenBSD: session.h,v 1.149 2020/12/23 13:20:48 claudio 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_TIMER_SENDHOLD, 63 EVNT_RCVD_OPEN, 64 EVNT_RCVD_KEEPALIVE, 65 EVNT_RCVD_UPDATE, 66 EVNT_RCVD_NOTIFICATION 67 }; 68 69 enum msg_type { 70 OPEN = 1, 71 UPDATE, 72 NOTIFICATION, 73 KEEPALIVE, 74 RREFRESH 75 }; 76 77 enum suberr_header { 78 ERR_HDR_SYNC = 1, 79 ERR_HDR_LEN, 80 ERR_HDR_TYPE 81 }; 82 83 enum suberr_open { 84 ERR_OPEN_VERSION = 1, 85 ERR_OPEN_AS, 86 ERR_OPEN_BGPID, 87 ERR_OPEN_OPT, 88 ERR_OPEN_AUTH, 89 ERR_OPEN_HOLDTIME, 90 ERR_OPEN_CAPA, 91 ERR_OPEN_GROUP_CONFLICT, /* draft-ietf-idr-bgp-multisession-07 */ 92 ERR_OPEN_GROUP_REQUIRED /* draft-ietf-idr-bgp-multisession-07 */ 93 }; 94 95 enum suberr_fsm { 96 ERR_FSM_UNSPECIFIC = 0, 97 ERR_FSM_UNEX_OPENSENT, 98 ERR_FSM_UNEX_OPENCONFIRM, 99 ERR_FSM_UNEX_ESTABLISHED 100 }; 101 102 enum opt_params { 103 OPT_PARAM_NONE, 104 OPT_PARAM_AUTH, 105 OPT_PARAM_CAPABILITIES 106 }; 107 108 enum capa_codes { 109 CAPA_NONE, 110 CAPA_MP, 111 CAPA_REFRESH, 112 CAPA_RESTART = 64, 113 CAPA_AS4BYTE = 65 114 }; 115 116 struct bgp_msg { 117 struct ibuf *buf; 118 enum msg_type type; 119 u_int16_t len; 120 }; 121 122 struct msg_header { 123 u_char marker[MSGSIZE_HEADER_MARKER]; 124 u_int16_t len; 125 u_int8_t type; 126 }; 127 128 struct msg_open { 129 struct msg_header header; 130 u_int32_t bgpid; 131 u_int16_t myas; 132 u_int16_t holdtime; 133 u_int8_t version; 134 u_int8_t optparamlen; 135 }; 136 137 struct bgpd_sysdep { 138 u_int8_t no_pfkey; 139 u_int8_t no_md5sig; 140 }; 141 142 struct ctl_conn { 143 TAILQ_ENTRY(ctl_conn) entry; 144 struct imsgbuf ibuf; 145 int restricted; 146 int throttled; 147 int terminate; 148 }; 149 150 struct peer_stats { 151 unsigned long long msg_rcvd_open; 152 unsigned long long msg_rcvd_update; 153 unsigned long long msg_rcvd_notification; 154 unsigned long long msg_rcvd_keepalive; 155 unsigned long long msg_rcvd_rrefresh; 156 unsigned long long msg_sent_open; 157 unsigned long long msg_sent_update; 158 unsigned long long msg_sent_notification; 159 unsigned long long msg_sent_keepalive; 160 unsigned long long msg_sent_rrefresh; 161 unsigned long long prefix_rcvd_update; 162 unsigned long long prefix_rcvd_withdraw; 163 unsigned long long prefix_rcvd_eor; 164 unsigned long long prefix_sent_update; 165 unsigned long long prefix_sent_withdraw; 166 unsigned long long prefix_sent_eor; 167 time_t last_updown; 168 time_t last_read; 169 time_t last_write; 170 u_int32_t prefix_cnt; 171 u_int32_t prefix_out_cnt; 172 u_int8_t last_sent_errcode; 173 u_int8_t last_sent_suberr; 174 u_int8_t last_rcvd_errcode; 175 u_int8_t last_rcvd_suberr; 176 char last_reason[REASON_LEN]; 177 }; 178 179 enum Timer { 180 Timer_None, 181 Timer_ConnectRetry, 182 Timer_Keepalive, 183 Timer_Hold, 184 Timer_SendHold, 185 Timer_IdleHold, 186 Timer_IdleHoldReset, 187 Timer_CarpUndemote, 188 Timer_RestartTimeout, 189 Timer_Max 190 }; 191 192 struct timer { 193 TAILQ_ENTRY(timer) entry; 194 enum Timer type; 195 time_t val; 196 }; 197 198 TAILQ_HEAD(timer_head, timer); 199 200 struct peer { 201 struct peer_config conf; 202 struct peer_stats stats; 203 RB_ENTRY(peer) entry; 204 struct { 205 struct capabilities ann; 206 struct capabilities peer; 207 struct capabilities neg; 208 } capa; 209 struct { 210 struct bgpd_addr local_addr; 211 u_int32_t spi_in; 212 u_int32_t spi_out; 213 enum auth_method method; 214 u_int8_t established; 215 } auth; 216 struct bgpd_addr local; 217 struct bgpd_addr local_alt; 218 struct bgpd_addr remote; 219 struct timer_head timers; 220 struct msgbuf wbuf; 221 struct ibuf_read *rbuf; 222 struct peer *template; 223 int fd; 224 int lasterr; 225 u_int errcnt; 226 u_int IdleHoldTime; 227 u_int32_t remote_bgpid; 228 enum session_state state; 229 enum session_state prev_state; 230 enum reconf_action reconf_action; 231 u_int16_t short_as; 232 u_int16_t holdtime; 233 u_int16_t local_port; 234 u_int16_t remote_port; 235 u_int8_t depend_ok; 236 u_int8_t demoted; 237 u_int8_t passive; 238 u_int8_t throttled; 239 u_int8_t rpending; 240 }; 241 242 extern time_t pauseaccept; 243 244 struct ctl_timer { 245 enum Timer type; 246 time_t val; 247 }; 248 249 /* carp.c */ 250 int carp_demote_init(char *, int); 251 void carp_demote_shutdown(void); 252 int carp_demote_get(char *); 253 int carp_demote_set(char *, int); 254 255 /* config.c */ 256 void merge_config(struct bgpd_config *, struct bgpd_config *); 257 int prepare_listeners(struct bgpd_config *); 258 259 /* control.c */ 260 int control_check(char *); 261 int control_init(int, char *); 262 int control_listen(int); 263 size_t control_fill_pfds(struct pollfd *, size_t); 264 void control_shutdown(int); 265 int control_dispatch_msg(struct pollfd *, struct peer_head *); 266 unsigned int control_accept(int, int); 267 268 /* log.c */ 269 char *log_fmt_peer(const struct peer_config *); 270 void log_statechange(struct peer *, enum session_state, 271 enum session_events); 272 void log_notification(const struct peer *, u_int8_t, u_int8_t, 273 u_char *, u_int16_t, const char *); 274 void log_conn_attempt(const struct peer *, struct sockaddr *, 275 socklen_t); 276 277 /* mrt.c */ 278 void mrt_dump_bgp_msg(struct mrt *, void *, u_int16_t, 279 struct peer *); 280 void mrt_dump_state(struct mrt *, u_int16_t, u_int16_t, 281 struct peer *); 282 void mrt_done(struct mrt *); 283 284 /* parse.y */ 285 struct bgpd_config *parse_config(char *, struct peer_head *); 286 287 /* pfkey.c */ 288 int pfkey_read(int, struct sadb_msg *); 289 int pfkey_establish(struct peer *); 290 int pfkey_remove(struct peer *); 291 int pfkey_init(void); 292 int tcp_md5_check(int, struct peer *); 293 int tcp_md5_set(int, struct peer *); 294 int tcp_md5_prep_listener(struct listen_addr *, struct peer_head *); 295 void tcp_md5_add_listener(struct bgpd_config *, struct peer *); 296 void tcp_md5_del_listener(struct bgpd_config *, struct peer *); 297 298 /* printconf.c */ 299 void print_config(struct bgpd_config *, struct rib_names *); 300 301 /* rde.c */ 302 void rde_main(int, int); 303 304 /* session.c */ 305 RB_PROTOTYPE(peer_head, peer, entry, peer_compare); 306 307 void session_main(int, int); 308 void bgp_fsm(struct peer *, enum session_events); 309 int session_neighbor_rrefresh(struct peer *p); 310 struct peer *getpeerbydesc(struct bgpd_config *, const char *); 311 struct peer *getpeerbyip(struct bgpd_config *, struct sockaddr *); 312 struct peer *getpeerbyid(struct bgpd_config *, u_int32_t); 313 int peer_matched(struct peer *, struct ctl_neighbor *); 314 int imsg_ctl_parent(int, u_int32_t, pid_t, void *, u_int16_t); 315 int imsg_ctl_rde(int, pid_t, void *, u_int16_t); 316 void session_stop(struct peer *, u_int8_t); 317 318 /* timer.c */ 319 struct timer *timer_get(struct timer_head *, enum Timer); 320 struct timer *timer_nextisdue(struct timer_head *, time_t); 321 time_t timer_nextduein(struct timer_head *, time_t); 322 int timer_running(struct timer_head *, enum Timer, time_t *); 323 void timer_set(struct timer_head *, enum Timer, u_int); 324 void timer_stop(struct timer_head *, enum Timer); 325 void timer_remove(struct timer_head *, enum Timer); 326 void timer_remove_all(struct timer_head *); 327