1 /* $OpenBSD: session.h,v 1.153 2021/09/03 07:48:24 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 MSGSIZE_RREFRESH_MIN MSGSIZE_RREFRESH 39 #define MSG_PROCESS_LIMIT 25 40 #define SESSION_CLEAR_DELAY 5 41 42 enum session_state { 43 STATE_NONE, 44 STATE_IDLE, 45 STATE_CONNECT, 46 STATE_ACTIVE, 47 STATE_OPENSENT, 48 STATE_OPENCONFIRM, 49 STATE_ESTABLISHED 50 }; 51 52 enum session_events { 53 EVNT_NONE, 54 EVNT_START, 55 EVNT_STOP, 56 EVNT_CON_OPEN, 57 EVNT_CON_CLOSED, 58 EVNT_CON_OPENFAIL, 59 EVNT_CON_FATAL, 60 EVNT_TIMER_CONNRETRY, 61 EVNT_TIMER_HOLDTIME, 62 EVNT_TIMER_KEEPALIVE, 63 EVNT_TIMER_SENDHOLD, 64 EVNT_RCVD_OPEN, 65 EVNT_RCVD_KEEPALIVE, 66 EVNT_RCVD_UPDATE, 67 EVNT_RCVD_NOTIFICATION 68 }; 69 70 enum msg_type { 71 OPEN = 1, 72 UPDATE, 73 NOTIFICATION, 74 KEEPALIVE, 75 RREFRESH 76 }; 77 78 enum suberr_header { 79 ERR_HDR_SYNC = 1, 80 ERR_HDR_LEN, 81 ERR_HDR_TYPE 82 }; 83 84 enum suberr_open { 85 ERR_OPEN_VERSION = 1, 86 ERR_OPEN_AS, 87 ERR_OPEN_BGPID, 88 ERR_OPEN_OPT, 89 ERR_OPEN_AUTH, 90 ERR_OPEN_HOLDTIME, 91 ERR_OPEN_CAPA, 92 ERR_OPEN_GROUP_CONFLICT, /* draft-ietf-idr-bgp-multisession-07 */ 93 ERR_OPEN_GROUP_REQUIRED /* draft-ietf-idr-bgp-multisession-07 */ 94 }; 95 96 enum suberr_fsm { 97 ERR_FSM_UNSPECIFIC = 0, 98 ERR_FSM_UNEX_OPENSENT, 99 ERR_FSM_UNEX_OPENCONFIRM, 100 ERR_FSM_UNEX_ESTABLISHED 101 }; 102 103 enum opt_params { 104 OPT_PARAM_NONE, 105 OPT_PARAM_AUTH, 106 OPT_PARAM_CAPABILITIES, 107 OPT_PARAM_EXT_LEN=255, 108 }; 109 110 enum capa_codes { 111 CAPA_NONE = 0, 112 CAPA_MP = 1, 113 CAPA_REFRESH = 2, 114 CAPA_RESTART = 64, 115 CAPA_AS4BYTE = 65, 116 CAPA_ADD_PATH = 69, 117 CAPA_ENHANCED_RR = 70, 118 }; 119 120 struct bgp_msg { 121 struct ibuf *buf; 122 enum msg_type type; 123 u_int16_t len; 124 }; 125 126 struct msg_header { 127 u_char marker[MSGSIZE_HEADER_MARKER]; 128 u_int16_t len; 129 u_int8_t type; 130 }; 131 132 struct msg_open { 133 struct msg_header header; 134 u_int32_t bgpid; 135 u_int16_t myas; 136 u_int16_t holdtime; 137 u_int8_t version; 138 u_int8_t optparamlen; 139 }; 140 141 struct bgpd_sysdep { 142 u_int8_t no_pfkey; 143 u_int8_t no_md5sig; 144 }; 145 146 struct ctl_conn { 147 TAILQ_ENTRY(ctl_conn) entry; 148 struct imsgbuf ibuf; 149 int restricted; 150 int throttled; 151 int terminate; 152 }; 153 154 struct peer_stats { 155 unsigned long long msg_rcvd_open; 156 unsigned long long msg_rcvd_update; 157 unsigned long long msg_rcvd_notification; 158 unsigned long long msg_rcvd_keepalive; 159 unsigned long long msg_rcvd_rrefresh; 160 unsigned long long msg_sent_open; 161 unsigned long long msg_sent_update; 162 unsigned long long msg_sent_notification; 163 unsigned long long msg_sent_keepalive; 164 unsigned long long msg_sent_rrefresh; 165 unsigned long long refresh_rcvd_req; 166 unsigned long long refresh_rcvd_borr; 167 unsigned long long refresh_rcvd_eorr; 168 unsigned long long refresh_sent_req; 169 unsigned long long refresh_sent_borr; 170 unsigned long long refresh_sent_eorr; 171 unsigned long long prefix_rcvd_update; 172 unsigned long long prefix_rcvd_withdraw; 173 unsigned long long prefix_rcvd_eor; 174 unsigned long long prefix_sent_update; 175 unsigned long long prefix_sent_withdraw; 176 unsigned long long prefix_sent_eor; 177 time_t last_updown; 178 time_t last_read; 179 time_t last_write; 180 u_int32_t prefix_cnt; 181 u_int32_t prefix_out_cnt; 182 u_int8_t last_sent_errcode; 183 u_int8_t last_sent_suberr; 184 u_int8_t last_rcvd_errcode; 185 u_int8_t last_rcvd_suberr; 186 char last_reason[REASON_LEN]; 187 }; 188 189 enum Timer { 190 Timer_None, 191 Timer_ConnectRetry, 192 Timer_Keepalive, 193 Timer_Hold, 194 Timer_SendHold, 195 Timer_IdleHold, 196 Timer_IdleHoldReset, 197 Timer_CarpUndemote, 198 Timer_RestartTimeout, 199 Timer_Rtr_Refresh, 200 Timer_Rtr_Retry, 201 Timer_Rtr_Expire, 202 Timer_Max 203 }; 204 205 struct timer { 206 TAILQ_ENTRY(timer) entry; 207 enum Timer type; 208 time_t val; 209 }; 210 211 TAILQ_HEAD(timer_head, timer); 212 213 struct peer { 214 struct peer_config conf; 215 struct peer_stats stats; 216 RB_ENTRY(peer) entry; 217 struct { 218 struct capabilities ann; 219 struct capabilities peer; 220 struct capabilities neg; 221 } capa; 222 struct { 223 struct bgpd_addr local_addr; 224 u_int32_t spi_in; 225 u_int32_t spi_out; 226 enum auth_method method; 227 u_int8_t established; 228 } auth; 229 struct bgpd_addr local; 230 struct bgpd_addr local_alt; 231 struct bgpd_addr remote; 232 struct timer_head timers; 233 struct msgbuf wbuf; 234 struct ibuf_read *rbuf; 235 struct peer *template; 236 int fd; 237 int lasterr; 238 u_int errcnt; 239 u_int IdleHoldTime; 240 u_int32_t remote_bgpid; 241 enum session_state state; 242 enum session_state prev_state; 243 enum reconf_action reconf_action; 244 u_int16_t short_as; 245 u_int16_t holdtime; 246 u_int16_t local_port; 247 u_int16_t remote_port; 248 u_int8_t depend_ok; 249 u_int8_t demoted; 250 u_int8_t passive; 251 u_int8_t throttled; 252 u_int8_t rpending; 253 }; 254 255 extern time_t pauseaccept; 256 257 struct ctl_timer { 258 enum Timer type; 259 time_t val; 260 }; 261 262 /* carp.c */ 263 int carp_demote_init(char *, int); 264 void carp_demote_shutdown(void); 265 int carp_demote_get(char *); 266 int carp_demote_set(char *, int); 267 268 /* config.c */ 269 void merge_config(struct bgpd_config *, struct bgpd_config *); 270 int prepare_listeners(struct bgpd_config *); 271 272 /* control.c */ 273 int control_check(char *); 274 int control_init(int, char *); 275 int control_listen(int); 276 size_t control_fill_pfds(struct pollfd *, size_t); 277 void control_shutdown(int); 278 int control_dispatch_msg(struct pollfd *, struct peer_head *); 279 unsigned int control_accept(int, int); 280 281 /* log.c */ 282 char *log_fmt_peer(const struct peer_config *); 283 void log_statechange(struct peer *, enum session_state, 284 enum session_events); 285 void log_notification(const struct peer *, u_int8_t, u_int8_t, 286 u_char *, u_int16_t, const char *); 287 void log_conn_attempt(const struct peer *, struct sockaddr *, 288 socklen_t); 289 290 /* mrt.c */ 291 void mrt_dump_bgp_msg(struct mrt *, void *, u_int16_t, 292 struct peer *, enum msg_type); 293 void mrt_dump_state(struct mrt *, u_int16_t, u_int16_t, 294 struct peer *); 295 void mrt_done(struct mrt *); 296 297 /* pfkey.c */ 298 int pfkey_read(int, struct sadb_msg *); 299 int pfkey_establish(struct peer *); 300 int pfkey_remove(struct peer *); 301 int pfkey_init(void); 302 int tcp_md5_check(int, struct peer *); 303 int tcp_md5_set(int, struct peer *); 304 int tcp_md5_prep_listener(struct listen_addr *, struct peer_head *); 305 void tcp_md5_add_listener(struct bgpd_config *, struct peer *); 306 void tcp_md5_del_listener(struct bgpd_config *, struct peer *); 307 308 /* printconf.c */ 309 void print_config(struct bgpd_config *, struct rib_names *); 310 311 /* rde.c */ 312 void rde_main(int, int); 313 314 /* rtr_proto.c */ 315 struct rtr_session; 316 size_t rtr_count(void); 317 void rtr_check_events(struct pollfd *, size_t); 318 size_t rtr_poll_events(struct pollfd *, size_t, time_t *); 319 struct rtr_session *rtr_new(uint32_t, char *); 320 struct rtr_session *rtr_get(uint32_t); 321 void rtr_free(struct rtr_session *); 322 void rtr_open(struct rtr_session *, int); 323 struct roa_tree *rtr_get_roa(struct rtr_session *); 324 void rtr_config_prep(void); 325 void rtr_config_merge(void); 326 void rtr_config_keep(struct rtr_session *); 327 void rtr_roa_merge(struct roa_tree *); 328 void rtr_shutdown(void); 329 void rtr_show(struct rtr_session *, pid_t); 330 331 /* rtr.c */ 332 void roa_insert(struct roa_tree *, struct roa *); 333 void rtr_main(int, int); 334 void rtr_imsg_compose(int, uint32_t, pid_t, void *, size_t); 335 void rtr_recalc(void); 336 337 /* session.c */ 338 RB_PROTOTYPE(peer_head, peer, entry, peer_compare); 339 340 void session_main(int, int); 341 void bgp_fsm(struct peer *, enum session_events); 342 int session_neighbor_rrefresh(struct peer *p); 343 struct peer *getpeerbydesc(struct bgpd_config *, const char *); 344 struct peer *getpeerbyip(struct bgpd_config *, struct sockaddr *); 345 struct peer *getpeerbyid(struct bgpd_config *, u_int32_t); 346 int peer_matched(struct peer *, struct ctl_neighbor *); 347 int imsg_ctl_parent(int, u_int32_t, pid_t, void *, u_int16_t); 348 int imsg_ctl_rde(int, pid_t, void *, u_int16_t); 349 void session_stop(struct peer *, u_int8_t); 350 351 /* timer.c */ 352 struct timer *timer_get(struct timer_head *, enum Timer); 353 struct timer *timer_nextisdue(struct timer_head *, time_t); 354 time_t timer_nextduein(struct timer_head *, time_t); 355 int timer_running(struct timer_head *, enum Timer, time_t *); 356 void timer_set(struct timer_head *, enum Timer, u_int); 357 void timer_stop(struct timer_head *, enum Timer); 358 void timer_remove(struct timer_head *, enum Timer); 359 void timer_remove_all(struct timer_head *); 360