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