GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/bgpd/session.c Lines: 0 1584 0.0 %
Date: 2016-12-06 Branches: 0 1099 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: session.c,v 1.351 2016/07/25 14:29:28 claudio Exp $ */
2
3
/*
4
 * Copyright (c) 2003, 2004, 2005 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
21
#include <sys/mman.h>
22
#include <sys/socket.h>
23
#include <sys/time.h>
24
#include <sys/resource.h>
25
#include <sys/un.h>
26
#include <net/if_types.h>
27
#include <netinet/in.h>
28
#include <netinet/ip.h>
29
#include <netinet/tcp.h>
30
#include <arpa/inet.h>
31
#include <limits.h>
32
33
#include <err.h>
34
#include <errno.h>
35
#include <fcntl.h>
36
#include <poll.h>
37
#include <pwd.h>
38
#include <signal.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include <string.h>
42
#include <unistd.h>
43
44
#include "bgpd.h"
45
#include "mrt.h"
46
#include "session.h"
47
48
#define PFD_PIPE_MAIN		0
49
#define PFD_PIPE_ROUTE		1
50
#define PFD_PIPE_ROUTE_CTL	2
51
#define PFD_SOCK_CTL		3
52
#define PFD_SOCK_RCTL		4
53
#define PFD_SOCK_PFKEY		5
54
#define PFD_LISTENERS_START	6
55
56
void	session_sighdlr(int);
57
int	setup_listeners(u_int *);
58
void	init_conf(struct bgpd_config *);
59
void	init_peer(struct peer *);
60
void	start_timer_holdtime(struct peer *);
61
void	start_timer_keepalive(struct peer *);
62
void	session_close_connection(struct peer *);
63
void	change_state(struct peer *, enum session_state, enum session_events);
64
int	session_setup_socket(struct peer *);
65
void	session_accept(int);
66
int	session_connect(struct peer *);
67
void	session_tcp_established(struct peer *);
68
void	session_capa_ann_none(struct peer *);
69
int	session_capa_add(struct ibuf *, u_int8_t, u_int8_t);
70
int	session_capa_add_mp(struct ibuf *, u_int8_t);
71
int	session_capa_add_gr(struct peer *, struct ibuf *, u_int8_t);
72
struct bgp_msg	*session_newmsg(enum msg_type, u_int16_t);
73
int	session_sendmsg(struct bgp_msg *, struct peer *);
74
void	session_open(struct peer *);
75
void	session_keepalive(struct peer *);
76
void	session_update(u_int32_t, void *, size_t);
77
void	session_notification(struct peer *, u_int8_t, u_int8_t, void *,
78
	    ssize_t);
79
void	session_rrefresh(struct peer *, u_int8_t);
80
int	session_graceful_restart(struct peer *);
81
int	session_graceful_stop(struct peer *);
82
int	session_dispatch_msg(struct pollfd *, struct peer *);
83
int	session_process_msg(struct peer *);
84
int	parse_header(struct peer *, u_char *, u_int16_t *, u_int8_t *);
85
int	parse_open(struct peer *);
86
int	parse_update(struct peer *);
87
int	parse_refresh(struct peer *);
88
int	parse_notification(struct peer *);
89
int	parse_capabilities(struct peer *, u_char *, u_int16_t, u_int32_t *);
90
int	capa_neg_calc(struct peer *);
91
void	session_dispatch_imsg(struct imsgbuf *, int, u_int *);
92
void	session_up(struct peer *);
93
void	session_down(struct peer *);
94
void	session_demote(struct peer *, int);
95
96
int		 la_cmp(struct listen_addr *, struct listen_addr *);
97
struct peer	*getpeerbyip(struct sockaddr *);
98
void		 session_template_clone(struct peer *, struct sockaddr *,
99
		    u_int32_t, u_int32_t);
100
int		 session_match_mask(struct peer *, struct bgpd_addr *);
101
struct peer	*getpeerbyid(u_int32_t);
102
103
struct bgpd_config	*conf, *nconf;
104
struct bgpd_sysdep	 sysdep;
105
struct peer		*peers, *npeers;
106
volatile sig_atomic_t	 session_quit;
107
int			 pending_reconf;
108
int			 csock = -1, rcsock = -1;
109
u_int			 peer_cnt;
110
struct imsgbuf		*ibuf_rde;
111
struct imsgbuf		*ibuf_rde_ctl;
112
struct imsgbuf		*ibuf_main;
113
114
struct mrt_head		 mrthead;
115
time_t			 pauseaccept;
116
117
void
118
session_sighdlr(int sig)
119
{
120
	switch (sig) {
121
	case SIGINT:
122
	case SIGTERM:
123
		session_quit = 1;
124
		break;
125
	}
126
}
127
128
int
129
setup_listeners(u_int *la_cnt)
130
{
131
	int			 ttl = 255;
132
	int			 opt;
133
	struct listen_addr	*la;
134
	u_int			 cnt = 0;
135
136
	TAILQ_FOREACH(la, conf->listen_addrs, entry) {
137
		la->reconf = RECONF_NONE;
138
		cnt++;
139
140
		if (la->flags & LISTENER_LISTENING)
141
			continue;
142
143
		if (la->fd == -1) {
144
			log_warn("cannot establish listener on %s: invalid fd",
145
			    log_sockaddr((struct sockaddr *)&la->sa));
146
			continue;
147
		}
148
149
		opt = 1;
150
		if (setsockopt(la->fd, IPPROTO_TCP, TCP_MD5SIG,
151
		    &opt, sizeof(opt)) == -1) {
152
			if (errno == ENOPROTOOPT) {	/* system w/o md5sig */
153
				log_warnx("md5sig not available, disabling");
154
				sysdep.no_md5sig = 1;
155
			} else
156
				fatal("setsockopt TCP_MD5SIG");
157
		}
158
159
		/* set ttl to 255 so that ttl-security works */
160
		if (la->sa.ss_family == AF_INET && setsockopt(la->fd,
161
		    IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) == -1) {
162
			log_warn("setup_listeners setsockopt TTL");
163
			continue;
164
		}
165
		if (la->sa.ss_family == AF_INET6 && setsockopt(la->fd,
166
		    IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) == -1) {
167
			log_warn("setup_listeners setsockopt hoplimit");
168
			continue;
169
		}
170
171
		if (listen(la->fd, MAX_BACKLOG)) {
172
			close(la->fd);
173
			fatal("listen");
174
		}
175
176
		la->flags |= LISTENER_LISTENING;
177
178
		log_info("listening on %s",
179
		    log_sockaddr((struct sockaddr *)&la->sa));
180
	}
181
182
	*la_cnt = cnt;
183
184
	return (0);
185
}
186
187
void
188
session_main(int debug, int verbose)
189
{
190
	int			 timeout, pfkeysock;
191
	unsigned int		 i, j, idx_peers, idx_listeners, idx_mrts;
192
	u_int			 pfd_elms = 0, peer_l_elms = 0, mrt_l_elms = 0;
193
	u_int			 listener_cnt, ctl_cnt, mrt_cnt;
194
	u_int			 new_cnt;
195
	u_int32_t		 ctl_queued;
196
	struct passwd		*pw;
197
	struct peer		*p, **peer_l = NULL, *last, *next;
198
	struct mrt		*m, *xm, **mrt_l = NULL;
199
	struct pollfd		*pfd = NULL;
200
	struct ctl_conn		*ctl_conn;
201
	struct listen_addr	*la;
202
	void			*newp;
203
	short			 events;
204
205
	log_init(debug);
206
	log_verbose(verbose);
207
208
	if ((pw = getpwnam(BGPD_USER)) == NULL)
209
		fatal(NULL);
210
211
	if (chroot(pw->pw_dir) == -1)
212
		fatal("chroot");
213
	if (chdir("/") == -1)
214
		fatal("chdir(\"/\")");
215
216
	setproctitle("session engine");
217
	bgpd_process = PROC_SE;
218
	pfkeysock = pfkey_init(&sysdep);
219
220
	if (setgroups(1, &pw->pw_gid) ||
221
	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
222
	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
223
		fatal("can't drop privileges");
224
225
	if (pledge("stdio inet recvfd rpath wpath cpath", NULL) == -1)
226
		fatal("pledge");
227
228
	signal(SIGTERM, session_sighdlr);
229
	signal(SIGINT, session_sighdlr);
230
	signal(SIGPIPE, SIG_IGN);
231
	signal(SIGHUP, SIG_IGN);
232
	signal(SIGALRM, SIG_IGN);
233
	signal(SIGUSR1, SIG_IGN);
234
235
	if ((ibuf_main = malloc(sizeof(struct imsgbuf))) == NULL)
236
		fatal(NULL);
237
	imsg_init(ibuf_main, 3);
238
239
	TAILQ_INIT(&ctl_conns);
240
	LIST_INIT(&mrthead);
241
	listener_cnt = 0;
242
	peer_cnt = 0;
243
	ctl_cnt = 0;
244
245
	if ((conf = calloc(1, sizeof(struct bgpd_config))) == NULL)
246
		fatal(NULL);
247
	if ((conf->listen_addrs = calloc(1, sizeof(struct listen_addrs))) ==
248
	    NULL)
249
		fatal(NULL);
250
	TAILQ_INIT(conf->listen_addrs);
251
252
	log_info("session engine ready");
253
254
	while (session_quit == 0) {
255
		/* check for peers to be initialized or deleted */
256
		last = NULL;
257
		if (!pending_reconf) {
258
			for (p = peers; p != NULL; p = next) {
259
				next = p->next;
260
				/* cloned peer that idled out? */
261
				if (p->template && (p->state == STATE_IDLE ||
262
				    p->state == STATE_ACTIVE) &&
263
				    time(NULL) - p->stats.last_updown >=
264
				    INTERVAL_HOLD_CLONED)
265
					p->conf.reconf_action = RECONF_DELETE;
266
267
				/* new peer that needs init? */
268
				if (p->state == STATE_NONE)
269
					init_peer(p);
270
271
				/* reinit due? */
272
				if (p->conf.reconf_action == RECONF_REINIT) {
273
					session_stop(p, ERR_CEASE_ADMIN_RESET);
274
					if (!p->conf.down)
275
						timer_set(p, Timer_IdleHold, 0);
276
				}
277
278
				/* deletion due? */
279
				if (p->conf.reconf_action == RECONF_DELETE) {
280
					if (p->demoted)
281
						session_demote(p, -1);
282
					p->conf.demote_group[0] = 0;
283
					session_stop(p, ERR_CEASE_PEER_UNCONF);
284
					log_peer_warnx(&p->conf, "removed");
285
					if (last != NULL)
286
						last->next = next;
287
					else
288
						peers = next;
289
					timer_remove_all(p);
290
					free(p);
291
					peer_cnt--;
292
					continue;
293
				}
294
				p->conf.reconf_action = RECONF_NONE;
295
				last = p;
296
			}
297
		}
298
299
		if (peer_cnt > peer_l_elms) {
300
			if ((newp = reallocarray(peer_l, peer_cnt,
301
			    sizeof(struct peer *))) == NULL) {
302
				/* panic for now  */
303
				log_warn("could not resize peer_l from %u -> %u"
304
				    " entries", peer_l_elms, peer_cnt);
305
				fatalx("exiting");
306
			}
307
			peer_l = newp;
308
			peer_l_elms = peer_cnt;
309
		}
310
311
		mrt_cnt = 0;
312
		for (m = LIST_FIRST(&mrthead); m != NULL; m = xm) {
313
			xm = LIST_NEXT(m, entry);
314
			if (m->state == MRT_STATE_REMOVE) {
315
				mrt_clean(m);
316
				LIST_REMOVE(m, entry);
317
				free(m);
318
				continue;
319
			}
320
			if (m->wbuf.queued)
321
				mrt_cnt++;
322
		}
323
324
		if (mrt_cnt > mrt_l_elms) {
325
			if ((newp = reallocarray(mrt_l, mrt_cnt,
326
			    sizeof(struct mrt *))) == NULL) {
327
				/* panic for now  */
328
				log_warn("could not resize mrt_l from %u -> %u"
329
				    " entries", mrt_l_elms, mrt_cnt);
330
				fatalx("exiting");
331
			}
332
			mrt_l = newp;
333
			mrt_l_elms = mrt_cnt;
334
		}
335
336
		new_cnt = PFD_LISTENERS_START + listener_cnt + peer_cnt +
337
		    ctl_cnt + mrt_cnt;
338
		if (new_cnt > pfd_elms) {
339
			if ((newp = reallocarray(pfd, new_cnt,
340
			    sizeof(struct pollfd))) == NULL) {
341
				/* panic for now  */
342
				log_warn("could not resize pfd from %u -> %u"
343
				    " entries", pfd_elms, new_cnt);
344
				fatalx("exiting");
345
			}
346
			pfd = newp;
347
			pfd_elms = new_cnt;
348
		}
349
350
		bzero(pfd, sizeof(struct pollfd) * pfd_elms);
351
352
		set_pollfd(&pfd[PFD_PIPE_MAIN], ibuf_main);
353
		set_pollfd(&pfd[PFD_PIPE_ROUTE], ibuf_rde);
354
355
		ctl_queued = 0;
356
		TAILQ_FOREACH(ctl_conn, &ctl_conns, entry)
357
			ctl_queued += ctl_conn->ibuf.w.queued;
358
359
		/*
360
		 * Do not act as unlimited buffer. Don't read in more
361
		 * messages if the ctl sockets are getting full.
362
		 */
363
		if (ctl_queued < SESSION_CTL_QUEUE_MAX)
364
			set_pollfd(&pfd[PFD_PIPE_ROUTE_CTL], ibuf_rde_ctl);
365
366
		if (pauseaccept == 0) {
367
			pfd[PFD_SOCK_CTL].fd = csock;
368
			pfd[PFD_SOCK_CTL].events = POLLIN;
369
			pfd[PFD_SOCK_RCTL].fd = rcsock;
370
			pfd[PFD_SOCK_RCTL].events = POLLIN;
371
		} else {
372
			pfd[PFD_SOCK_CTL].fd = -1;
373
			pfd[PFD_SOCK_RCTL].fd = -1;
374
		}
375
		pfd[PFD_SOCK_PFKEY].fd = pfkeysock;
376
		pfd[PFD_SOCK_PFKEY].events = POLLIN;
377
378
		i = PFD_LISTENERS_START;
379
		TAILQ_FOREACH(la, conf->listen_addrs, entry) {
380
			if (pauseaccept == 0) {
381
				pfd[i].fd = la->fd;
382
				pfd[i].events = POLLIN;
383
			} else
384
				pfd[i].fd = -1;
385
			i++;
386
		}
387
		idx_listeners = i;
388
		timeout = 240;	/* loop every 240s at least */
389
390
		for (p = peers; p != NULL; p = p->next) {
391
			time_t	nextaction;
392
			struct peer_timer *pt;
393
394
			/* check timers */
395
			if ((pt = timer_nextisdue(p)) != NULL) {
396
				switch (pt->type) {
397
				case Timer_Hold:
398
					bgp_fsm(p, EVNT_TIMER_HOLDTIME);
399
					break;
400
				case Timer_ConnectRetry:
401
					bgp_fsm(p, EVNT_TIMER_CONNRETRY);
402
					break;
403
				case Timer_Keepalive:
404
					bgp_fsm(p, EVNT_TIMER_KEEPALIVE);
405
					break;
406
				case Timer_IdleHold:
407
					bgp_fsm(p, EVNT_START);
408
					break;
409
				case Timer_IdleHoldReset:
410
					p->IdleHoldTime /= 2;
411
					if (p->IdleHoldTime <=
412
					    INTERVAL_IDLE_HOLD_INITIAL) {
413
						p->IdleHoldTime =
414
						    INTERVAL_IDLE_HOLD_INITIAL;
415
						timer_stop(p,
416
						    Timer_IdleHoldReset);
417
						p->errcnt = 0;
418
					} else
419
						timer_set(p,
420
						    Timer_IdleHoldReset,
421
						    p->IdleHoldTime);
422
					break;
423
				case Timer_CarpUndemote:
424
					timer_stop(p, Timer_CarpUndemote);
425
					if (p->demoted &&
426
					    p->state == STATE_ESTABLISHED)
427
						session_demote(p, -1);
428
					break;
429
				case Timer_RestartTimeout:
430
					timer_stop(p, Timer_RestartTimeout);
431
					session_graceful_stop(p);
432
					break;
433
				default:
434
					fatalx("King Bula lost in time");
435
				}
436
			}
437
			if ((nextaction = timer_nextduein(p)) != -1 &&
438
			    nextaction < timeout)
439
				timeout = nextaction;
440
441
			/* are we waiting for a write? */
442
			events = POLLIN;
443
			if (p->wbuf.queued > 0 || p->state == STATE_CONNECT)
444
				events |= POLLOUT;
445
			/* is there still work to do? */
446
			if (p->rbuf && p->rbuf->wpos)
447
				timeout = 0;
448
449
			/* poll events */
450
			if (p->fd != -1 && events != 0) {
451
				pfd[i].fd = p->fd;
452
				pfd[i].events = events;
453
				peer_l[i - idx_listeners] = p;
454
				i++;
455
			}
456
		}
457
458
		idx_peers = i;
459
460
		LIST_FOREACH(m, &mrthead, entry)
461
			if (m->wbuf.queued) {
462
				pfd[i].fd = m->wbuf.fd;
463
				pfd[i].events = POLLOUT;
464
				mrt_l[i - idx_peers] = m;
465
				i++;
466
			}
467
468
		idx_mrts = i;
469
470
		TAILQ_FOREACH(ctl_conn, &ctl_conns, entry) {
471
			pfd[i].fd = ctl_conn->ibuf.fd;
472
			pfd[i].events = POLLIN;
473
			if (ctl_conn->ibuf.w.queued > 0)
474
				pfd[i].events |= POLLOUT;
475
			i++;
476
		}
477
478
		if (pauseaccept && timeout > 1)
479
			timeout = 1;
480
		if (timeout < 0)
481
			timeout = 0;
482
		if (poll(pfd, i, timeout * 1000) == -1)
483
			if (errno != EINTR)
484
				fatal("poll error");
485
486
		/*
487
		 * If we previously saw fd exhaustion, we stop accept()
488
		 * for 1 second to throttle the accept() loop.
489
		 */
490
		if (pauseaccept && getmonotime() > pauseaccept + 1)
491
			pauseaccept = 0;
492
493
		if (handle_pollfd(&pfd[PFD_PIPE_MAIN], ibuf_main) == -1) {
494
			log_warnx("SE: Lost connection to parent");
495
			session_quit = 1;
496
			continue;
497
		} else
498
			session_dispatch_imsg(ibuf_main, PFD_PIPE_MAIN,
499
			    &listener_cnt);
500
501
		if (handle_pollfd(&pfd[PFD_PIPE_ROUTE], ibuf_rde) == -1) {
502
			log_warnx("SE: Lost connection to RDE");
503
			msgbuf_clear(&ibuf_rde->w);
504
			free(ibuf_rde);
505
			ibuf_rde = NULL;
506
		} else
507
			session_dispatch_imsg(ibuf_rde, PFD_PIPE_ROUTE,
508
			    &listener_cnt);
509
510
		if (handle_pollfd(&pfd[PFD_PIPE_ROUTE_CTL], ibuf_rde_ctl) ==
511
		    -1) {
512
			log_warnx("SE: Lost connection to RDE control");
513
			msgbuf_clear(&ibuf_rde_ctl->w);
514
			free(ibuf_rde_ctl);
515
			ibuf_rde_ctl = NULL;
516
		} else
517
			session_dispatch_imsg(ibuf_rde_ctl, PFD_PIPE_ROUTE_CTL,
518
			    &listener_cnt);
519
520
		if (pfd[PFD_SOCK_CTL].revents & POLLIN)
521
			ctl_cnt += control_accept(csock, 0);
522
523
		if (pfd[PFD_SOCK_RCTL].revents & POLLIN)
524
			ctl_cnt += control_accept(rcsock, 1);
525
526
		if (pfd[PFD_SOCK_PFKEY].revents & POLLIN) {
527
			if (pfkey_read(pfkeysock, NULL) == -1) {
528
				log_warnx("pfkey_read failed, exiting...");
529
				session_quit = 1;
530
			}
531
		}
532
533
		for (j = PFD_LISTENERS_START; j < idx_listeners; j++)
534
			if (pfd[j].revents & POLLIN)
535
				session_accept(pfd[j].fd);
536
537
		for (; j < idx_peers; j++)
538
			session_dispatch_msg(&pfd[j],
539
			    peer_l[j - idx_listeners]);
540
541
		for (p = peers; p != NULL; p = p->next)
542
			if (p->rbuf && p->rbuf->wpos)
543
				session_process_msg(p);
544
545
		for (; j < idx_mrts; j++)
546
			if (pfd[j].revents & POLLOUT)
547
				mrt_write(mrt_l[j - idx_peers]);
548
549
		for (; j < i; j++)
550
			control_dispatch_msg(&pfd[j], &ctl_cnt);
551
	}
552
553
	while ((p = peers) != NULL) {
554
		peers = p->next;
555
		session_stop(p, ERR_CEASE_ADMIN_DOWN);
556
		pfkey_remove(p);
557
		free(p);
558
	}
559
560
	while ((m = LIST_FIRST(&mrthead)) != NULL) {
561
		mrt_clean(m);
562
		LIST_REMOVE(m, entry);
563
		free(m);
564
	}
565
566
	while ((la = TAILQ_FIRST(conf->listen_addrs)) != NULL) {
567
		TAILQ_REMOVE(conf->listen_addrs, la, entry);
568
		free(la);
569
	}
570
	free(conf->listen_addrs);
571
	free(peer_l);
572
	free(mrt_l);
573
	free(pfd);
574
575
	msgbuf_write(&ibuf_rde->w);
576
	msgbuf_clear(&ibuf_rde->w);
577
	free(ibuf_rde);
578
	msgbuf_write(&ibuf_main->w);
579
	msgbuf_clear(&ibuf_main->w);
580
	free(ibuf_main);
581
582
	control_shutdown(csock);
583
	control_shutdown(rcsock);
584
	log_info("session engine exiting");
585
	_exit(0);
586
}
587
588
void
589
init_conf(struct bgpd_config *c)
590
{
591
	if (!c->holdtime)
592
		c->holdtime = INTERVAL_HOLD;
593
	if (!c->connectretry)
594
		c->connectretry = INTERVAL_CONNECTRETRY;
595
}
596
597
void
598
init_peer(struct peer *p)
599
{
600
	TAILQ_INIT(&p->timers);
601
	p->fd = p->wbuf.fd = -1;
602
603
	if (p->conf.if_depend[0])
604
		imsg_compose(ibuf_main, IMSG_IFINFO, 0, 0, -1,
605
		    p->conf.if_depend, sizeof(p->conf.if_depend));
606
	else
607
		p->depend_ok = 1;
608
609
	peer_cnt++;
610
611
	change_state(p, STATE_IDLE, EVNT_NONE);
612
	if (p->conf.down)
613
		timer_stop(p, Timer_IdleHold);		/* no autostart */
614
	else
615
		timer_set(p, Timer_IdleHold, 0);	/* start ASAP */
616
617
	/*
618
	 * on startup, demote if requested.
619
	 * do not handle new peers. they must reach ESTABLISHED beforehands.
620
	 * peers added at runtime have reconf_action set to RECONF_REINIT.
621
	 */
622
	if (p->conf.reconf_action != RECONF_REINIT && p->conf.demote_group[0])
623
		session_demote(p, +1);
624
}
625
626
void
627
bgp_fsm(struct peer *peer, enum session_events event)
628
{
629
	switch (peer->state) {
630
	case STATE_NONE:
631
		/* nothing */
632
		break;
633
	case STATE_IDLE:
634
		switch (event) {
635
		case EVNT_START:
636
			timer_stop(peer, Timer_Hold);
637
			timer_stop(peer, Timer_Keepalive);
638
			timer_stop(peer, Timer_IdleHold);
639
640
			/* allocate read buffer */
641
			peer->rbuf = calloc(1, sizeof(struct ibuf_read));
642
			if (peer->rbuf == NULL)
643
				fatal(NULL);
644
645
			/* init write buffer */
646
			msgbuf_init(&peer->wbuf);
647
648
			/* init pfkey - remove old if any, load new ones */
649
			pfkey_remove(peer);
650
			if (pfkey_establish(peer) == -1) {
651
				log_peer_warnx(&peer->conf,
652
				    "pfkey setup failed");
653
				return;
654
			}
655
656
			peer->stats.last_sent_errcode = 0;
657
			peer->stats.last_sent_suberr = 0;
658
659
			if (!peer->depend_ok)
660
				timer_stop(peer, Timer_ConnectRetry);
661
			else if (peer->passive || peer->conf.passive ||
662
			    peer->conf.template) {
663
				change_state(peer, STATE_ACTIVE, event);
664
				timer_stop(peer, Timer_ConnectRetry);
665
			} else {
666
				change_state(peer, STATE_CONNECT, event);
667
				timer_set(peer, Timer_ConnectRetry,
668
				    conf->connectretry);
669
				session_connect(peer);
670
			}
671
			peer->passive = 0;
672
			break;
673
		default:
674
			/* ignore */
675
			break;
676
		}
677
		break;
678
	case STATE_CONNECT:
679
		switch (event) {
680
		case EVNT_START:
681
			/* ignore */
682
			break;
683
		case EVNT_CON_OPEN:
684
			session_tcp_established(peer);
685
			session_open(peer);
686
			timer_stop(peer, Timer_ConnectRetry);
687
			peer->holdtime = INTERVAL_HOLD_INITIAL;
688
			start_timer_holdtime(peer);
689
			change_state(peer, STATE_OPENSENT, event);
690
			break;
691
		case EVNT_CON_OPENFAIL:
692
			timer_set(peer, Timer_ConnectRetry,
693
			    conf->connectretry);
694
			session_close_connection(peer);
695
			change_state(peer, STATE_ACTIVE, event);
696
			break;
697
		case EVNT_TIMER_CONNRETRY:
698
			timer_set(peer, Timer_ConnectRetry,
699
			    conf->connectretry);
700
			session_connect(peer);
701
			break;
702
		default:
703
			change_state(peer, STATE_IDLE, event);
704
			break;
705
		}
706
		break;
707
	case STATE_ACTIVE:
708
		switch (event) {
709
		case EVNT_START:
710
			/* ignore */
711
			break;
712
		case EVNT_CON_OPEN:
713
			session_tcp_established(peer);
714
			session_open(peer);
715
			timer_stop(peer, Timer_ConnectRetry);
716
			peer->holdtime = INTERVAL_HOLD_INITIAL;
717
			start_timer_holdtime(peer);
718
			change_state(peer, STATE_OPENSENT, event);
719
			break;
720
		case EVNT_CON_OPENFAIL:
721
			timer_set(peer, Timer_ConnectRetry,
722
			    conf->connectretry);
723
			session_close_connection(peer);
724
			change_state(peer, STATE_ACTIVE, event);
725
			break;
726
		case EVNT_TIMER_CONNRETRY:
727
			timer_set(peer, Timer_ConnectRetry,
728
			    peer->holdtime);
729
			change_state(peer, STATE_CONNECT, event);
730
			session_connect(peer);
731
			break;
732
		default:
733
			change_state(peer, STATE_IDLE, event);
734
			break;
735
		}
736
		break;
737
	case STATE_OPENSENT:
738
		switch (event) {
739
		case EVNT_START:
740
			/* ignore */
741
			break;
742
		case EVNT_STOP:
743
			change_state(peer, STATE_IDLE, event);
744
			break;
745
		case EVNT_CON_CLOSED:
746
			session_close_connection(peer);
747
			timer_set(peer, Timer_ConnectRetry,
748
			    conf->connectretry);
749
			change_state(peer, STATE_ACTIVE, event);
750
			break;
751
		case EVNT_CON_FATAL:
752
			change_state(peer, STATE_IDLE, event);
753
			break;
754
		case EVNT_TIMER_HOLDTIME:
755
			session_notification(peer, ERR_HOLDTIMEREXPIRED,
756
			    0, NULL, 0);
757
			change_state(peer, STATE_IDLE, event);
758
			break;
759
		case EVNT_RCVD_OPEN:
760
			/* parse_open calls change_state itself on failure */
761
			if (parse_open(peer))
762
				break;
763
			session_keepalive(peer);
764
			change_state(peer, STATE_OPENCONFIRM, event);
765
			break;
766
		case EVNT_RCVD_NOTIFICATION:
767
			if (parse_notification(peer)) {
768
				change_state(peer, STATE_IDLE, event);
769
				/* don't punish, capa negotiation */
770
				timer_set(peer, Timer_IdleHold, 0);
771
				peer->IdleHoldTime /= 2;
772
			} else
773
				change_state(peer, STATE_IDLE, event);
774
			break;
775
		default:
776
			session_notification(peer,
777
			    ERR_FSM, ERR_FSM_UNEX_OPENSENT, NULL, 0);
778
			change_state(peer, STATE_IDLE, event);
779
			break;
780
		}
781
		break;
782
	case STATE_OPENCONFIRM:
783
		switch (event) {
784
		case EVNT_START:
785
			/* ignore */
786
			break;
787
		case EVNT_STOP:
788
			change_state(peer, STATE_IDLE, event);
789
			break;
790
		case EVNT_CON_CLOSED:
791
		case EVNT_CON_FATAL:
792
			change_state(peer, STATE_IDLE, event);
793
			break;
794
		case EVNT_TIMER_HOLDTIME:
795
			session_notification(peer, ERR_HOLDTIMEREXPIRED,
796
			    0, NULL, 0);
797
			change_state(peer, STATE_IDLE, event);
798
			break;
799
		case EVNT_TIMER_KEEPALIVE:
800
			session_keepalive(peer);
801
			break;
802
		case EVNT_RCVD_KEEPALIVE:
803
			start_timer_holdtime(peer);
804
			change_state(peer, STATE_ESTABLISHED, event);
805
			break;
806
		case EVNT_RCVD_NOTIFICATION:
807
			parse_notification(peer);
808
			change_state(peer, STATE_IDLE, event);
809
			break;
810
		default:
811
			session_notification(peer,
812
			    ERR_FSM, ERR_FSM_UNEX_OPENCONFIRM, NULL, 0);
813
			change_state(peer, STATE_IDLE, event);
814
			break;
815
		}
816
		break;
817
	case STATE_ESTABLISHED:
818
		switch (event) {
819
		case EVNT_START:
820
			/* ignore */
821
			break;
822
		case EVNT_STOP:
823
			change_state(peer, STATE_IDLE, event);
824
			break;
825
		case EVNT_CON_CLOSED:
826
		case EVNT_CON_FATAL:
827
			change_state(peer, STATE_IDLE, event);
828
			break;
829
		case EVNT_TIMER_HOLDTIME:
830
			session_notification(peer, ERR_HOLDTIMEREXPIRED,
831
			    0, NULL, 0);
832
			change_state(peer, STATE_IDLE, event);
833
			break;
834
		case EVNT_TIMER_KEEPALIVE:
835
			session_keepalive(peer);
836
			break;
837
		case EVNT_RCVD_KEEPALIVE:
838
			start_timer_holdtime(peer);
839
			break;
840
		case EVNT_RCVD_UPDATE:
841
			start_timer_holdtime(peer);
842
			if (parse_update(peer))
843
				change_state(peer, STATE_IDLE, event);
844
			else
845
				start_timer_holdtime(peer);
846
			break;
847
		case EVNT_RCVD_NOTIFICATION:
848
			parse_notification(peer);
849
			change_state(peer, STATE_IDLE, event);
850
			break;
851
		default:
852
			session_notification(peer,
853
			    ERR_FSM, ERR_FSM_UNEX_ESTABLISHED, NULL, 0);
854
			change_state(peer, STATE_IDLE, event);
855
			break;
856
		}
857
		break;
858
	}
859
}
860
861
void
862
start_timer_holdtime(struct peer *peer)
863
{
864
	if (peer->holdtime > 0)
865
		timer_set(peer, Timer_Hold, peer->holdtime);
866
	else
867
		timer_stop(peer, Timer_Hold);
868
}
869
870
void
871
start_timer_keepalive(struct peer *peer)
872
{
873
	if (peer->holdtime > 0)
874
		timer_set(peer, Timer_Keepalive, peer->holdtime / 3);
875
	else
876
		timer_stop(peer, Timer_Keepalive);
877
}
878
879
void
880
session_close_connection(struct peer *peer)
881
{
882
	if (peer->fd != -1) {
883
		close(peer->fd);
884
		pauseaccept = 0;
885
	}
886
	peer->fd = peer->wbuf.fd = -1;
887
}
888
889
void
890
change_state(struct peer *peer, enum session_state state,
891
    enum session_events event)
892
{
893
	struct mrt	*mrt;
894
895
	switch (state) {
896
	case STATE_IDLE:
897
		/* carp demotion first. new peers handled in init_peer */
898
		if (peer->state == STATE_ESTABLISHED &&
899
		    peer->conf.demote_group[0] && !peer->demoted)
900
			session_demote(peer, +1);
901
902
		/*
903
		 * try to write out what's buffered (maybe a notification),
904
		 * don't bother if it fails
905
		 */
906
		if (peer->state >= STATE_OPENSENT && peer->wbuf.queued)
907
			msgbuf_write(&peer->wbuf);
908
909
		/*
910
		 * we must start the timer for the next EVNT_START
911
		 * if we are coming here due to an error and the
912
		 * session was not established successfully before, the
913
		 * starttimerinterval needs to be exponentially increased
914
		 */
915
		if (peer->IdleHoldTime == 0)
916
			peer->IdleHoldTime = INTERVAL_IDLE_HOLD_INITIAL;
917
		peer->holdtime = INTERVAL_HOLD_INITIAL;
918
		timer_stop(peer, Timer_ConnectRetry);
919
		timer_stop(peer, Timer_Keepalive);
920
		timer_stop(peer, Timer_Hold);
921
		timer_stop(peer, Timer_IdleHold);
922
		timer_stop(peer, Timer_IdleHoldReset);
923
		session_close_connection(peer);
924
		msgbuf_clear(&peer->wbuf);
925
		free(peer->rbuf);
926
		peer->rbuf = NULL;
927
		bzero(&peer->capa.peer, sizeof(peer->capa.peer));
928
929
		if (event != EVNT_STOP) {
930
			timer_set(peer, Timer_IdleHold, peer->IdleHoldTime);
931
			if (event != EVNT_NONE &&
932
			    peer->IdleHoldTime < MAX_IDLE_HOLD/2)
933
				peer->IdleHoldTime *= 2;
934
		}
935
		if (peer->state == STATE_ESTABLISHED) {
936
			if (peer->capa.neg.grestart.restart == 2 &&
937
			    (event == EVNT_CON_CLOSED ||
938
			    event == EVNT_CON_FATAL)) {
939
				/* don't punish graceful restart */
940
				timer_set(peer, Timer_IdleHold, 0);
941
				peer->IdleHoldTime /= 2;
942
				session_graceful_restart(peer);
943
			} else
944
				session_down(peer);
945
		}
946
		if (peer->state == STATE_NONE ||
947
		    peer->state == STATE_ESTABLISHED) {
948
			/* initialize capability negotiation structures */
949
			memcpy(&peer->capa.ann, &peer->conf.capabilities,
950
			    sizeof(peer->capa.ann));
951
			if (!peer->conf.announce_capa)
952
				session_capa_ann_none(peer);
953
		}
954
		break;
955
	case STATE_CONNECT:
956
		if (peer->state == STATE_ESTABLISHED &&
957
		    peer->capa.neg.grestart.restart == 2) {
958
			/* do the graceful restart dance */
959
			session_graceful_restart(peer);
960
			peer->holdtime = INTERVAL_HOLD_INITIAL;
961
			timer_stop(peer, Timer_ConnectRetry);
962
			timer_stop(peer, Timer_Keepalive);
963
			timer_stop(peer, Timer_Hold);
964
			timer_stop(peer, Timer_IdleHold);
965
			timer_stop(peer, Timer_IdleHoldReset);
966
			session_close_connection(peer);
967
			msgbuf_clear(&peer->wbuf);
968
			bzero(&peer->capa.peer, sizeof(peer->capa.peer));
969
		}
970
		break;
971
	case STATE_ACTIVE:
972
		break;
973
	case STATE_OPENSENT:
974
		break;
975
	case STATE_OPENCONFIRM:
976
		break;
977
	case STATE_ESTABLISHED:
978
		timer_set(peer, Timer_IdleHoldReset, peer->IdleHoldTime);
979
		if (peer->demoted)
980
			timer_set(peer, Timer_CarpUndemote,
981
			    INTERVAL_HOLD_DEMOTED);
982
		session_up(peer);
983
		break;
984
	default:		/* something seriously fucked */
985
		break;
986
	}
987
988
	log_statechange(peer, state, event);
989
	LIST_FOREACH(mrt, &mrthead, entry) {
990
		if (!(mrt->type == MRT_ALL_IN || mrt->type == MRT_ALL_OUT))
991
			continue;
992
		if ((mrt->peer_id == 0 && mrt->group_id == 0) ||
993
		    mrt->peer_id == peer->conf.id || (mrt->group_id != 0 &&
994
		    mrt->group_id == peer->conf.groupid))
995
			mrt_dump_state(mrt, peer->state, state, peer);
996
	}
997
	peer->prev_state = peer->state;
998
	peer->state = state;
999
}
1000
1001
void
1002
session_accept(int listenfd)
1003
{
1004
	int			 connfd;
1005
	int			 opt;
1006
	socklen_t		 len;
1007
	struct sockaddr_storage	 cliaddr;
1008
	struct peer		*p = NULL;
1009
1010
	len = sizeof(cliaddr);
1011
	if ((connfd = accept4(listenfd,
1012
	    (struct sockaddr *)&cliaddr, &len,
1013
	    SOCK_CLOEXEC | SOCK_NONBLOCK)) == -1) {
1014
		if (errno == ENFILE || errno == EMFILE)
1015
			pauseaccept = getmonotime();
1016
		else if (errno != EWOULDBLOCK && errno != EINTR &&
1017
		    errno != ECONNABORTED)
1018
			log_warn("accept");
1019
		return;
1020
	}
1021
1022
	p = getpeerbyip((struct sockaddr *)&cliaddr);
1023
1024
	if (p != NULL && p->state == STATE_IDLE && p->errcnt < 2) {
1025
		if (timer_running(p, Timer_IdleHold, NULL)) {
1026
			/* fast reconnect after clear */
1027
			p->passive = 1;
1028
			bgp_fsm(p, EVNT_START);
1029
		}
1030
	}
1031
1032
	if (p != NULL &&
1033
	    (p->state == STATE_CONNECT || p->state == STATE_ACTIVE)) {
1034
		if (p->fd != -1) {
1035
			if (p->state == STATE_CONNECT)
1036
				session_close_connection(p);
1037
			else {
1038
				close(connfd);
1039
				return;
1040
			}
1041
		}
1042
1043
open:
1044
		if (p->conf.auth.method != AUTH_NONE && sysdep.no_pfkey) {
1045
			log_peer_warnx(&p->conf,
1046
			    "ipsec or md5sig configured but not available");
1047
			close(connfd);
1048
			return;
1049
		}
1050
1051
		if (p->conf.auth.method == AUTH_MD5SIG) {
1052
			if (sysdep.no_md5sig) {
1053
				log_peer_warnx(&p->conf,
1054
				    "md5sig configured but not available");
1055
				close(connfd);
1056
				return;
1057
			}
1058
			len = sizeof(opt);
1059
			if (getsockopt(connfd, IPPROTO_TCP, TCP_MD5SIG,
1060
			    &opt, &len) == -1)
1061
				fatal("getsockopt TCP_MD5SIG");
1062
			if (!opt) {	/* non-md5'd connection! */
1063
				log_peer_warnx(&p->conf,
1064
				    "connection attempt without md5 signature");
1065
				close(connfd);
1066
				return;
1067
			}
1068
		}
1069
		p->fd = p->wbuf.fd = connfd;
1070
		if (session_setup_socket(p)) {
1071
			close(connfd);
1072
			return;
1073
		}
1074
		bgp_fsm(p, EVNT_CON_OPEN);
1075
		return;
1076
	} else if (p != NULL && p->state == STATE_ESTABLISHED &&
1077
	    p->capa.neg.grestart.restart == 2) {
1078
		/* first do the graceful restart dance */
1079
		change_state(p, STATE_CONNECT, EVNT_CON_CLOSED);
1080
		/* then do part of the open dance */
1081
		goto open;
1082
	} else {
1083
		log_conn_attempt(p, (struct sockaddr *)&cliaddr);
1084
		close(connfd);
1085
	}
1086
}
1087
1088
int
1089
session_connect(struct peer *peer)
1090
{
1091
	int			 opt = 1;
1092
	struct sockaddr		*sa;
1093
1094
	/*
1095
	 * we do not need the overcomplicated collision detection RFC 1771
1096
	 * describes; we simply make sure there is only ever one concurrent
1097
	 * tcp connection per peer.
1098
	 */
1099
	if (peer->fd != -1)
1100
		return (-1);
1101
1102
	if ((peer->fd = socket(aid2af(peer->conf.remote_addr.aid),
1103
	    SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, IPPROTO_TCP)) == -1) {
1104
		log_peer_warn(&peer->conf, "session_connect socket");
1105
		bgp_fsm(peer, EVNT_CON_OPENFAIL);
1106
		return (-1);
1107
	}
1108
1109
	if (peer->conf.auth.method != AUTH_NONE && sysdep.no_pfkey) {
1110
		log_peer_warnx(&peer->conf,
1111
		    "ipsec or md5sig configured but not available");
1112
		bgp_fsm(peer, EVNT_CON_OPENFAIL);
1113
		return (-1);
1114
	}
1115
1116
	if (peer->conf.auth.method == AUTH_MD5SIG) {
1117
		if (sysdep.no_md5sig) {
1118
			log_peer_warnx(&peer->conf,
1119
			    "md5sig configured but not available");
1120
			bgp_fsm(peer, EVNT_CON_OPENFAIL);
1121
			return (-1);
1122
		}
1123
		if (setsockopt(peer->fd, IPPROTO_TCP, TCP_MD5SIG,
1124
		    &opt, sizeof(opt)) == -1) {
1125
			log_peer_warn(&peer->conf, "setsockopt md5sig");
1126
			bgp_fsm(peer, EVNT_CON_OPENFAIL);
1127
			return (-1);
1128
		}
1129
	}
1130
	peer->wbuf.fd = peer->fd;
1131
1132
	/* if update source is set we need to bind() */
1133
	if ((sa = addr2sa(&peer->conf.local_addr, 0)) != NULL) {
1134
		if (bind(peer->fd, sa, sa->sa_len) == -1) {
1135
			log_peer_warn(&peer->conf, "session_connect bind");
1136
			bgp_fsm(peer, EVNT_CON_OPENFAIL);
1137
			return (-1);
1138
		}
1139
	}
1140
1141
	if (session_setup_socket(peer)) {
1142
		bgp_fsm(peer, EVNT_CON_OPENFAIL);
1143
		return (-1);
1144
	}
1145
1146
	sa = addr2sa(&peer->conf.remote_addr, BGP_PORT);
1147
	if (connect(peer->fd, sa, sa->sa_len) == -1) {
1148
		if (errno != EINPROGRESS) {
1149
			if (errno != peer->lasterr)
1150
				log_peer_warn(&peer->conf, "connect");
1151
			peer->lasterr = errno;
1152
			bgp_fsm(peer, EVNT_CON_OPENFAIL);
1153
			return (-1);
1154
		}
1155
	} else
1156
		bgp_fsm(peer, EVNT_CON_OPEN);
1157
1158
	return (0);
1159
}
1160
1161
int
1162
session_setup_socket(struct peer *p)
1163
{
1164
	int	ttl = p->conf.distance;
1165
	int	pre = IPTOS_PREC_INTERNETCONTROL;
1166
	int	nodelay = 1;
1167
	int	bsize;
1168
1169
	switch (p->conf.remote_addr.aid) {
1170
	case AID_INET:
1171
		/* set precedence, see RFC 1771 appendix 5 */
1172
		if (setsockopt(p->fd, IPPROTO_IP, IP_TOS, &pre, sizeof(pre)) ==
1173
		    -1) {
1174
			log_peer_warn(&p->conf,
1175
			    "session_setup_socket setsockopt TOS");
1176
			return (-1);
1177
		}
1178
1179
		if (p->conf.ebgp) {
1180
			/* set TTL to foreign router's distance
1181
			   1=direct n=multihop with ttlsec, we always use 255 */
1182
			if (p->conf.ttlsec) {
1183
				ttl = 256 - p->conf.distance;
1184
				if (setsockopt(p->fd, IPPROTO_IP, IP_MINTTL,
1185
				    &ttl, sizeof(ttl)) == -1) {
1186
					log_peer_warn(&p->conf,
1187
					    "session_setup_socket: "
1188
					    "setsockopt MINTTL");
1189
					return (-1);
1190
				}
1191
				ttl = 255;
1192
			}
1193
1194
			if (setsockopt(p->fd, IPPROTO_IP, IP_TTL, &ttl,
1195
			    sizeof(ttl)) == -1) {
1196
				log_peer_warn(&p->conf,
1197
				    "session_setup_socket setsockopt TTL");
1198
				return (-1);
1199
			}
1200
		}
1201
		break;
1202
	case AID_INET6:
1203
		if (p->conf.ebgp) {
1204
			/* set hoplimit to foreign router's distance
1205
			   1=direct n=multihop with ttlsec, we always use 255 */
1206
			if (p->conf.ttlsec) {
1207
				ttl = 256 - p->conf.distance;
1208
				if (setsockopt(p->fd, IPPROTO_IPV6,
1209
				    IPV6_MINHOPCOUNT, &ttl, sizeof(ttl))
1210
				    == -1) {
1211
					log_peer_warn(&p->conf,
1212
					    "session_setup_socket: "
1213
					    "setsockopt MINHOPCOUNT");
1214
					return (-1);
1215
				}
1216
				ttl = 255;
1217
			}
1218
			if (setsockopt(p->fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1219
			    &ttl, sizeof(ttl)) == -1) {
1220
				log_peer_warn(&p->conf,
1221
				    "session_setup_socket setsockopt hoplimit");
1222
				return (-1);
1223
			}
1224
		}
1225
		break;
1226
	}
1227
1228
	/* set TCP_NODELAY */
1229
	if (setsockopt(p->fd, IPPROTO_TCP, TCP_NODELAY, &nodelay,
1230
	    sizeof(nodelay)) == -1) {
1231
		log_peer_warn(&p->conf,
1232
		    "session_setup_socket setsockopt TCP_NODELAY");
1233
		return (-1);
1234
	}
1235
1236
	/* only increase bufsize (and thus window) if md5 or ipsec is in use */
1237
	if (p->conf.auth.method != AUTH_NONE) {
1238
		/* try to increase bufsize. no biggie if it fails */
1239
		bsize = 65535;
1240
		while (bsize > 8192 &&
1241
		    setsockopt(p->fd, SOL_SOCKET, SO_RCVBUF, &bsize,
1242
		    sizeof(bsize)) == -1 && errno != EINVAL)
1243
			bsize /= 2;
1244
		bsize = 65535;
1245
		while (bsize > 8192 &&
1246
		    setsockopt(p->fd, SOL_SOCKET, SO_SNDBUF, &bsize,
1247
		    sizeof(bsize)) == -1 && errno != EINVAL)
1248
			bsize /= 2;
1249
	}
1250
1251
	return (0);
1252
}
1253
1254
void
1255
session_tcp_established(struct peer *peer)
1256
{
1257
	socklen_t	len;
1258
1259
	len = sizeof(peer->sa_local);
1260
	if (getsockname(peer->fd, (struct sockaddr *)&peer->sa_local,
1261
	    &len) == -1)
1262
		log_warn("getsockname");
1263
	len = sizeof(peer->sa_remote);
1264
	if (getpeername(peer->fd, (struct sockaddr *)&peer->sa_remote,
1265
	    &len) == -1)
1266
		log_warn("getpeername");
1267
}
1268
1269
void
1270
session_capa_ann_none(struct peer *peer)
1271
{
1272
	bzero(&peer->capa.ann, sizeof(peer->capa.ann));
1273
}
1274
1275
int
1276
session_capa_add(struct ibuf *opb, u_int8_t capa_code, u_int8_t capa_len)
1277
{
1278
	int errs = 0;
1279
1280
	errs += ibuf_add(opb, &capa_code, sizeof(capa_code));
1281
	errs += ibuf_add(opb, &capa_len, sizeof(capa_len));
1282
	return (errs);
1283
}
1284
1285
int
1286
session_capa_add_mp(struct ibuf *buf, u_int8_t aid)
1287
{
1288
	u_int8_t		 safi, pad = 0;
1289
	u_int16_t		 afi;
1290
	int			 errs = 0;
1291
1292
	if (aid2afi(aid, &afi, &safi) == -1)
1293
		fatalx("session_capa_add_mp: bad afi/safi pair");
1294
	afi = htons(afi);
1295
	errs += ibuf_add(buf, &afi, sizeof(afi));
1296
	errs += ibuf_add(buf, &pad, sizeof(pad));
1297
	errs += ibuf_add(buf, &safi, sizeof(safi));
1298
1299
	return (errs);
1300
}
1301
1302
int
1303
session_capa_add_gr(struct peer *p, struct ibuf *b, u_int8_t aid)
1304
{
1305
	u_int		errs = 0;
1306
	u_int16_t	afi;
1307
	u_int8_t	flags, safi;
1308
1309
	if (aid2afi(aid, &afi, &safi)) {
1310
		log_warn("session_capa_add_gr: bad AID");
1311
		return (1);
1312
	}
1313
	if (p->capa.neg.grestart.flags[aid] & CAPA_GR_RESTARTING)
1314
		flags = CAPA_GR_F_FLAG;
1315
	else
1316
		flags = 0;
1317
1318
	afi = htons(afi);
1319
	errs += ibuf_add(b, &afi, sizeof(afi));
1320
	errs += ibuf_add(b, &safi, sizeof(safi));
1321
	errs += ibuf_add(b, &flags, sizeof(flags));
1322
1323
	return (errs);
1324
}
1325
1326
struct bgp_msg *
1327
session_newmsg(enum msg_type msgtype, u_int16_t len)
1328
{
1329
	struct bgp_msg		*msg;
1330
	struct msg_header	 hdr;
1331
	struct ibuf		*buf;
1332
	int			 errs = 0;
1333
1334
	memset(&hdr.marker, 0xff, sizeof(hdr.marker));
1335
	hdr.len = htons(len);
1336
	hdr.type = msgtype;
1337
1338
	if ((buf = ibuf_open(len)) == NULL)
1339
		return (NULL);
1340
1341
	errs += ibuf_add(buf, &hdr.marker, sizeof(hdr.marker));
1342
	errs += ibuf_add(buf, &hdr.len, sizeof(hdr.len));
1343
	errs += ibuf_add(buf, &hdr.type, sizeof(hdr.type));
1344
1345
	if (errs || (msg = calloc(1, sizeof(*msg))) == NULL) {
1346
		ibuf_free(buf);
1347
		return (NULL);
1348
	}
1349
1350
	msg->buf = buf;
1351
	msg->type = msgtype;
1352
	msg->len = len;
1353
1354
	return (msg);
1355
}
1356
1357
int
1358
session_sendmsg(struct bgp_msg *msg, struct peer *p)
1359
{
1360
	struct mrt		*mrt;
1361
1362
	LIST_FOREACH(mrt, &mrthead, entry) {
1363
		if (!(mrt->type == MRT_ALL_OUT || (msg->type == UPDATE &&
1364
		    mrt->type == MRT_UPDATE_OUT)))
1365
			continue;
1366
		if ((mrt->peer_id == 0 && mrt->group_id == 0) ||
1367
		    mrt->peer_id == p->conf.id || (mrt->group_id == 0 &&
1368
		    mrt->group_id == p->conf.groupid))
1369
			mrt_dump_bgp_msg(mrt, msg->buf->buf, msg->len, p);
1370
	}
1371
1372
	ibuf_close(&p->wbuf, msg->buf);
1373
	free(msg);
1374
	return (0);
1375
}
1376
1377
void
1378
session_open(struct peer *p)
1379
{
1380
	struct bgp_msg		*buf;
1381
	struct ibuf		*opb;
1382
	struct msg_open		 msg;
1383
	u_int16_t		 len;
1384
	u_int8_t		 i, op_type, optparamlen = 0;
1385
	int			 errs = 0;
1386
	int			 mpcapa = 0;
1387
1388
1389
	if ((opb = ibuf_dynamic(0, UCHAR_MAX - sizeof(op_type) -
1390
	    sizeof(optparamlen))) == NULL) {
1391
		bgp_fsm(p, EVNT_CON_FATAL);
1392
		return;
1393
	}
1394
1395
	/* multiprotocol extensions, RFC 4760 */
1396
	for (i = 0; i < AID_MAX; i++)
1397
		if (p->capa.ann.mp[i]) {	/* 4 bytes data */
1398
			errs += session_capa_add(opb, CAPA_MP, 4);
1399
			errs += session_capa_add_mp(opb, i);
1400
			mpcapa++;
1401
		}
1402
1403
	/* route refresh, RFC 2918 */
1404
	if (p->capa.ann.refresh)	/* no data */
1405
		errs += session_capa_add(opb, CAPA_REFRESH, 0);
1406
1407
	/* graceful restart and End-of-RIB marker, RFC 4724 */
1408
	if (p->capa.ann.grestart.restart) {
1409
		int		rst = 0;
1410
		u_int16_t	hdr;
1411
		u_int8_t	grlen;
1412
1413
		if (mpcapa) {
1414
			grlen = 2 + 4 * mpcapa;
1415
			for (i = 0; i < AID_MAX; i++) {
1416
				if (p->capa.neg.grestart.flags[i] &
1417
				    CAPA_GR_RESTARTING)
1418
					rst++;
1419
			}
1420
		} else {	/* AID_INET */
1421
			grlen = 2 + 4;
1422
			if (p->capa.neg.grestart.flags[AID_INET] &
1423
			    CAPA_GR_RESTARTING)
1424
				rst++;
1425
		}
1426
1427
		hdr = conf->holdtime;		/* default timeout */
1428
		/* if client does graceful restart don't set R flag */
1429
		if (!rst)
1430
			hdr |= CAPA_GR_R_FLAG;
1431
		hdr = htons(hdr);
1432
1433
		errs += session_capa_add(opb, CAPA_RESTART, grlen);
1434
		errs += ibuf_add(opb, &hdr, sizeof(hdr));
1435
1436
		if (mpcapa) {
1437
			for (i = 0; i < AID_MAX; i++) {
1438
				if (p->capa.ann.mp[i]) {
1439
					errs += session_capa_add_gr(p, opb, i);
1440
				}
1441
			}
1442
		} else {	/* AID_INET */
1443
			errs += session_capa_add_gr(p, opb, AID_INET);
1444
		}
1445
	}
1446
1447
	/* 4-bytes AS numbers, draft-ietf-idr-as4bytes-13 */
1448
	if (p->capa.ann.as4byte) {	/* 4 bytes data */
1449
		u_int32_t	nas;
1450
1451
		nas = htonl(conf->as);
1452
		errs += session_capa_add(opb, CAPA_AS4BYTE, sizeof(nas));
1453
		errs += ibuf_add(opb, &nas, sizeof(nas));
1454
	}
1455
1456
	if (ibuf_size(opb))
1457
		optparamlen = ibuf_size(opb) + sizeof(op_type) +
1458
		    sizeof(optparamlen);
1459
1460
	len = MSGSIZE_OPEN_MIN + optparamlen;
1461
	if (errs || (buf = session_newmsg(OPEN, len)) == NULL) {
1462
		ibuf_free(opb);
1463
		bgp_fsm(p, EVNT_CON_FATAL);
1464
		return;
1465
	}
1466
1467
	msg.version = 4;
1468
	msg.myas = htons(conf->short_as);
1469
	if (p->conf.holdtime)
1470
		msg.holdtime = htons(p->conf.holdtime);
1471
	else
1472
		msg.holdtime = htons(conf->holdtime);
1473
	msg.bgpid = conf->bgpid;	/* is already in network byte order */
1474
	msg.optparamlen = optparamlen;
1475
1476
	errs += ibuf_add(buf->buf, &msg.version, sizeof(msg.version));
1477
	errs += ibuf_add(buf->buf, &msg.myas, sizeof(msg.myas));
1478
	errs += ibuf_add(buf->buf, &msg.holdtime, sizeof(msg.holdtime));
1479
	errs += ibuf_add(buf->buf, &msg.bgpid, sizeof(msg.bgpid));
1480
	errs += ibuf_add(buf->buf, &msg.optparamlen, sizeof(msg.optparamlen));
1481
1482
	if (optparamlen) {
1483
		op_type = OPT_PARAM_CAPABILITIES;
1484
		optparamlen = ibuf_size(opb);
1485
		errs += ibuf_add(buf->buf, &op_type, sizeof(op_type));
1486
		errs += ibuf_add(buf->buf, &optparamlen, sizeof(optparamlen));
1487
		errs += ibuf_add(buf->buf, opb->buf, ibuf_size(opb));
1488
	}
1489
1490
	ibuf_free(opb);
1491
1492
	if (errs) {
1493
		ibuf_free(buf->buf);
1494
		free(buf);
1495
		bgp_fsm(p, EVNT_CON_FATAL);
1496
		return;
1497
	}
1498
1499
	if (session_sendmsg(buf, p) == -1) {
1500
		bgp_fsm(p, EVNT_CON_FATAL);
1501
		return;
1502
	}
1503
1504
	p->stats.msg_sent_open++;
1505
}
1506
1507
void
1508
session_keepalive(struct peer *p)
1509
{
1510
	struct bgp_msg		*buf;
1511
1512
	if ((buf = session_newmsg(KEEPALIVE, MSGSIZE_KEEPALIVE)) == NULL ||
1513
	    session_sendmsg(buf, p) == -1) {
1514
		bgp_fsm(p, EVNT_CON_FATAL);
1515
		return;
1516
	}
1517
1518
	start_timer_keepalive(p);
1519
	p->stats.msg_sent_keepalive++;
1520
}
1521
1522
void
1523
session_update(u_int32_t peerid, void *data, size_t datalen)
1524
{
1525
	struct peer		*p;
1526
	struct bgp_msg		*buf;
1527
1528
	if ((p = getpeerbyid(peerid)) == NULL) {
1529
		log_warnx("no such peer: id=%u", peerid);
1530
		return;
1531
	}
1532
1533
	if (p->state != STATE_ESTABLISHED)
1534
		return;
1535
1536
	if ((buf = session_newmsg(UPDATE, MSGSIZE_HEADER + datalen)) == NULL) {
1537
		bgp_fsm(p, EVNT_CON_FATAL);
1538
		return;
1539
	}
1540
1541
	if (ibuf_add(buf->buf, data, datalen)) {
1542
		ibuf_free(buf->buf);
1543
		free(buf);
1544
		bgp_fsm(p, EVNT_CON_FATAL);
1545
		return;
1546
	}
1547
1548
	if (session_sendmsg(buf, p) == -1) {
1549
		bgp_fsm(p, EVNT_CON_FATAL);
1550
		return;
1551
	}
1552
1553
	start_timer_keepalive(p);
1554
	p->stats.msg_sent_update++;
1555
}
1556
1557
void
1558
session_notification(struct peer *p, u_int8_t errcode, u_int8_t subcode,
1559
    void *data, ssize_t datalen)
1560
{
1561
	struct bgp_msg		*buf;
1562
	int			 errs = 0;
1563
1564
	if (p->stats.last_sent_errcode)	/* some notification already sent */
1565
		return;
1566
1567
	log_notification(p, errcode, subcode, data, datalen, "sending");
1568
1569
	if ((buf = session_newmsg(NOTIFICATION,
1570
	    MSGSIZE_NOTIFICATION_MIN + datalen)) == NULL) {
1571
		bgp_fsm(p, EVNT_CON_FATAL);
1572
		return;
1573
	}
1574
1575
	errs += ibuf_add(buf->buf, &errcode, sizeof(errcode));
1576
	errs += ibuf_add(buf->buf, &subcode, sizeof(subcode));
1577
1578
	if (datalen > 0)
1579
		errs += ibuf_add(buf->buf, data, datalen);
1580
1581
	if (errs) {
1582
		ibuf_free(buf->buf);
1583
		free(buf);
1584
		bgp_fsm(p, EVNT_CON_FATAL);
1585
		return;
1586
	}
1587
1588
	if (session_sendmsg(buf, p) == -1) {
1589
		bgp_fsm(p, EVNT_CON_FATAL);
1590
		return;
1591
	}
1592
1593
	p->stats.msg_sent_notification++;
1594
	p->stats.last_sent_errcode = errcode;
1595
	p->stats.last_sent_suberr = subcode;
1596
}
1597
1598
int
1599
session_neighbor_rrefresh(struct peer *p)
1600
{
1601
	u_int8_t	i;
1602
1603
	if (!p->capa.peer.refresh)
1604
		return (-1);
1605
1606
	for (i = 0; i < AID_MAX; i++) {
1607
		if (p->capa.peer.mp[i] != 0)
1608
			session_rrefresh(p, i);
1609
	}
1610
1611
	return (0);
1612
}
1613
1614
void
1615
session_rrefresh(struct peer *p, u_int8_t aid)
1616
{
1617
	struct bgp_msg		*buf;
1618
	int			 errs = 0;
1619
	u_int16_t		 afi;
1620
	u_int8_t		 safi, null8 = 0;
1621
1622
	if (aid2afi(aid, &afi, &safi) == -1)
1623
		fatalx("session_rrefresh: bad afi/safi pair");
1624
1625
	if ((buf = session_newmsg(RREFRESH, MSGSIZE_RREFRESH)) == NULL) {
1626
		bgp_fsm(p, EVNT_CON_FATAL);
1627
		return;
1628
	}
1629
1630
	afi = htons(afi);
1631
	errs += ibuf_add(buf->buf, &afi, sizeof(afi));
1632
	errs += ibuf_add(buf->buf, &null8, sizeof(null8));
1633
	errs += ibuf_add(buf->buf, &safi, sizeof(safi));
1634
1635
	if (errs) {
1636
		ibuf_free(buf->buf);
1637
		free(buf);
1638
		bgp_fsm(p, EVNT_CON_FATAL);
1639
		return;
1640
	}
1641
1642
	if (session_sendmsg(buf, p) == -1) {
1643
		bgp_fsm(p, EVNT_CON_FATAL);
1644
		return;
1645
	}
1646
1647
	p->stats.msg_sent_rrefresh++;
1648
}
1649
1650
int
1651
session_graceful_restart(struct peer *p)
1652
{
1653
	u_int8_t	i;
1654
1655
	timer_set(p, Timer_RestartTimeout, p->capa.neg.grestart.timeout);
1656
1657
	for (i = 0; i < AID_MAX; i++) {
1658
		if (p->capa.neg.grestart.flags[i] & CAPA_GR_PRESENT) {
1659
			if (imsg_compose(ibuf_rde, IMSG_SESSION_STALE,
1660
			    p->conf.id, 0, -1, &i, sizeof(i)) == -1)
1661
				return (-1);
1662
			log_peer_warnx(&p->conf,
1663
			    "graceful restart of %s, keeping routes",
1664
			    aid2str(i));
1665
			p->capa.neg.grestart.flags[i] |= CAPA_GR_RESTARTING;
1666
		} else if (p->capa.neg.mp[i]) {
1667
			if (imsg_compose(ibuf_rde, IMSG_SESSION_FLUSH,
1668
			    p->conf.id, 0, -1, &i, sizeof(i)) == -1)
1669
				return (-1);
1670
			log_peer_warnx(&p->conf,
1671
			    "graceful restart of %s, flushing routes",
1672
			    aid2str(i));
1673
		}
1674
	}
1675
	return (0);
1676
}
1677
1678
int
1679
session_graceful_stop(struct peer *p)
1680
{
1681
	u_int8_t	i;
1682
1683
	for (i = 0; i < AID_MAX; i++) {
1684
		/*
1685
		 * Only flush if the peer is restarting and the timeout fired.
1686
		 * In all other cases the session was already flushed when the
1687
		 * session went down or when the new open message was parsed.
1688
		 */
1689
		if (p->capa.neg.grestart.flags[i] & CAPA_GR_RESTARTING) {
1690
			log_peer_warnx(&p->conf, "graceful restart of %s, "
1691
			    "time-out, flushing", aid2str(i));
1692
			if (imsg_compose(ibuf_rde, IMSG_SESSION_FLUSH,
1693
			    p->conf.id, 0, -1, &i, sizeof(i)) == -1)
1694
				return (-1);
1695
		}
1696
		p->capa.neg.grestart.flags[i] &= ~CAPA_GR_RESTARTING;
1697
	}
1698
	return (0);
1699
}
1700
1701
int
1702
session_dispatch_msg(struct pollfd *pfd, struct peer *p)
1703
{
1704
	ssize_t		n;
1705
	socklen_t	len;
1706
	int		error;
1707
1708
	if (p->state == STATE_CONNECT) {
1709
		if (pfd->revents & POLLOUT) {
1710
			if (pfd->revents & POLLIN) {
1711
				/* error occurred */
1712
				len = sizeof(error);
1713
				if (getsockopt(pfd->fd, SOL_SOCKET, SO_ERROR,
1714
				    &error, &len) == -1 || error) {
1715
					if (error)
1716
						errno = error;
1717
					if (errno != p->lasterr) {
1718
						log_peer_warn(&p->conf,
1719
						    "socket error");
1720
						p->lasterr = errno;
1721
					}
1722
					bgp_fsm(p, EVNT_CON_OPENFAIL);
1723
					return (1);
1724
				}
1725
			}
1726
			bgp_fsm(p, EVNT_CON_OPEN);
1727
			return (1);
1728
		}
1729
		if (pfd->revents & POLLHUP) {
1730
			bgp_fsm(p, EVNT_CON_OPENFAIL);
1731
			return (1);
1732
		}
1733
		if (pfd->revents & (POLLERR|POLLNVAL)) {
1734
			bgp_fsm(p, EVNT_CON_FATAL);
1735
			return (1);
1736
		}
1737
		return (0);
1738
	}
1739
1740
	if (pfd->revents & POLLHUP) {
1741
		bgp_fsm(p, EVNT_CON_CLOSED);
1742
		return (1);
1743
	}
1744
	if (pfd->revents & (POLLERR|POLLNVAL)) {
1745
		bgp_fsm(p, EVNT_CON_FATAL);
1746
		return (1);
1747
	}
1748
1749
	if (pfd->revents & POLLOUT && p->wbuf.queued) {
1750
		if ((error = msgbuf_write(&p->wbuf)) <= 0 && errno != EAGAIN) {
1751
			if (error == 0)
1752
				log_peer_warnx(&p->conf, "Connection closed");
1753
			else if (error == -1)
1754
				log_peer_warn(&p->conf, "write error");
1755
			bgp_fsm(p, EVNT_CON_FATAL);
1756
			return (1);
1757
		}
1758
		if (!(pfd->revents & POLLIN))
1759
			return (1);
1760
	}
1761
1762
	if (p->rbuf && pfd->revents & POLLIN) {
1763
		if ((n = read(p->fd, p->rbuf->buf + p->rbuf->wpos,
1764
		    sizeof(p->rbuf->buf) - p->rbuf->wpos)) == -1) {
1765
			if (errno != EINTR && errno != EAGAIN) {
1766
				log_peer_warn(&p->conf, "read error");
1767
				bgp_fsm(p, EVNT_CON_FATAL);
1768
			}
1769
			return (1);
1770
		}
1771
		if (n == 0) {	/* connection closed */
1772
			bgp_fsm(p, EVNT_CON_CLOSED);
1773
			return (1);
1774
		}
1775
1776
		p->rbuf->wpos += n;
1777
		p->stats.last_read = time(NULL);
1778
		return (1);
1779
	}
1780
	return (0);
1781
}
1782
1783
int
1784
session_process_msg(struct peer *p)
1785
{
1786
	ssize_t		rpos, av, left;
1787
	int		processed = 0;
1788
	u_int16_t	msglen;
1789
	u_int8_t	msgtype;
1790
1791
	rpos = 0;
1792
	av = p->rbuf->wpos;
1793
1794
	/*
1795
	 * session might drop to IDLE -> buffers deallocated
1796
	 * we MUST check rbuf != NULL before use
1797
	 */
1798
	for (;;) {
1799
		if (rpos + MSGSIZE_HEADER > av)
1800
			break;
1801
		if (p->rbuf == NULL)
1802
			break;
1803
		if (parse_header(p, p->rbuf->buf + rpos, &msglen,
1804
		    &msgtype) == -1)
1805
			return (0);
1806
		if (rpos + msglen > av)
1807
			break;
1808
		p->rbuf->rptr = p->rbuf->buf + rpos;
1809
1810
		switch (msgtype) {
1811
		case OPEN:
1812
			bgp_fsm(p, EVNT_RCVD_OPEN);
1813
			p->stats.msg_rcvd_open++;
1814
			break;
1815
		case UPDATE:
1816
			bgp_fsm(p, EVNT_RCVD_UPDATE);
1817
			p->stats.msg_rcvd_update++;
1818
			break;
1819
		case NOTIFICATION:
1820
			bgp_fsm(p, EVNT_RCVD_NOTIFICATION);
1821
			p->stats.msg_rcvd_notification++;
1822
			break;
1823
		case KEEPALIVE:
1824
			bgp_fsm(p, EVNT_RCVD_KEEPALIVE);
1825
			p->stats.msg_rcvd_keepalive++;
1826
			break;
1827
		case RREFRESH:
1828
			parse_refresh(p);
1829
			p->stats.msg_rcvd_rrefresh++;
1830
			break;
1831
		default:	/* cannot happen */
1832
			session_notification(p, ERR_HEADER, ERR_HDR_TYPE,
1833
			    &msgtype, 1);
1834
			log_warnx("received message with unknown type %u",
1835
			    msgtype);
1836
			bgp_fsm(p, EVNT_CON_FATAL);
1837
		}
1838
		rpos += msglen;
1839
		if (++processed > MSG_PROCESS_LIMIT)
1840
			break;
1841
	}
1842
	if (p->rbuf == NULL)
1843
		return (1);
1844
1845
	if (rpos < av) {
1846
		left = av - rpos;
1847
		memmove(&p->rbuf->buf, p->rbuf->buf + rpos, left);
1848
		p->rbuf->wpos = left;
1849
	} else
1850
		p->rbuf->wpos = 0;
1851
1852
	return (1);
1853
}
1854
1855
int
1856
parse_header(struct peer *peer, u_char *data, u_int16_t *len, u_int8_t *type)
1857
{
1858
	struct mrt		*mrt;
1859
	u_char			*p;
1860
	u_int16_t		 olen;
1861
	static const u_int8_t	 marker[MSGSIZE_HEADER_MARKER] = { 0xff, 0xff,
1862
				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1863
				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1864
1865
	/* caller MUST make sure we are getting 19 bytes! */
1866
	p = data;
1867
	if (memcmp(p, marker, sizeof(marker))) {
1868
		log_peer_warnx(&peer->conf, "sync error");
1869
		session_notification(peer, ERR_HEADER, ERR_HDR_SYNC, NULL, 0);
1870
		bgp_fsm(peer, EVNT_CON_FATAL);
1871
		return (-1);
1872
	}
1873
	p += MSGSIZE_HEADER_MARKER;
1874
1875
	memcpy(&olen, p, 2);
1876
	*len = ntohs(olen);
1877
	p += 2;
1878
	memcpy(type, p, 1);
1879
1880
	if (*len < MSGSIZE_HEADER || *len > MAX_PKTSIZE) {
1881
		log_peer_warnx(&peer->conf,
1882
		    "received message: illegal length: %u byte", *len);
1883
		session_notification(peer, ERR_HEADER, ERR_HDR_LEN,
1884
		    &olen, sizeof(olen));
1885
		bgp_fsm(peer, EVNT_CON_FATAL);
1886
		return (-1);
1887
	}
1888
1889
	switch (*type) {
1890
	case OPEN:
1891
		if (*len < MSGSIZE_OPEN_MIN) {
1892
			log_peer_warnx(&peer->conf,
1893
			    "received OPEN: illegal len: %u byte", *len);
1894
			session_notification(peer, ERR_HEADER, ERR_HDR_LEN,
1895
			    &olen, sizeof(olen));
1896
			bgp_fsm(peer, EVNT_CON_FATAL);
1897
			return (-1);
1898
		}
1899
		break;
1900
	case NOTIFICATION:
1901
		if (*len < MSGSIZE_NOTIFICATION_MIN) {
1902
			log_peer_warnx(&peer->conf,
1903
			    "received NOTIFICATION: illegal len: %u byte",
1904
			    *len);
1905
			session_notification(peer, ERR_HEADER, ERR_HDR_LEN,
1906
			    &olen, sizeof(olen));
1907
			bgp_fsm(peer, EVNT_CON_FATAL);
1908
			return (-1);
1909
		}
1910
		break;
1911
	case UPDATE:
1912
		if (*len < MSGSIZE_UPDATE_MIN) {
1913
			log_peer_warnx(&peer->conf,
1914
			    "received UPDATE: illegal len: %u byte", *len);
1915
			session_notification(peer, ERR_HEADER, ERR_HDR_LEN,
1916
			    &olen, sizeof(olen));
1917
			bgp_fsm(peer, EVNT_CON_FATAL);
1918
			return (-1);
1919
		}
1920
		break;
1921
	case KEEPALIVE:
1922
		if (*len != MSGSIZE_KEEPALIVE) {
1923
			log_peer_warnx(&peer->conf,
1924
			    "received KEEPALIVE: illegal len: %u byte", *len);
1925
			session_notification(peer, ERR_HEADER, ERR_HDR_LEN,
1926
			    &olen, sizeof(olen));
1927
			bgp_fsm(peer, EVNT_CON_FATAL);
1928
			return (-1);
1929
		}
1930
		break;
1931
	case RREFRESH:
1932
		if (*len != MSGSIZE_RREFRESH) {
1933
			log_peer_warnx(&peer->conf,
1934
			    "received RREFRESH: illegal len: %u byte", *len);
1935
			session_notification(peer, ERR_HEADER, ERR_HDR_LEN,
1936
			    &olen, sizeof(olen));
1937
			bgp_fsm(peer, EVNT_CON_FATAL);
1938
			return (-1);
1939
		}
1940
		break;
1941
	default:
1942
		log_peer_warnx(&peer->conf,
1943
		    "received msg with unknown type %u", *type);
1944
		session_notification(peer, ERR_HEADER, ERR_HDR_TYPE,
1945
		    type, 1);
1946
		bgp_fsm(peer, EVNT_CON_FATAL);
1947
		return (-1);
1948
	}
1949
	LIST_FOREACH(mrt, &mrthead, entry) {
1950
		if (!(mrt->type == MRT_ALL_IN || (*type == UPDATE &&
1951
		    mrt->type == MRT_UPDATE_IN)))
1952
			continue;
1953
		if ((mrt->peer_id == 0 && mrt->group_id == 0) ||
1954
		    mrt->peer_id == peer->conf.id || (mrt->group_id != 0 &&
1955
		    mrt->group_id == peer->conf.groupid))
1956
			mrt_dump_bgp_msg(mrt, data, *len, peer);
1957
	}
1958
	return (0);
1959
}
1960
1961
int
1962
parse_open(struct peer *peer)
1963
{
1964
	u_char		*p, *op_val;
1965
	u_int8_t	 version, rversion;
1966
	u_int16_t	 short_as, msglen;
1967
	u_int16_t	 holdtime, oholdtime, myholdtime;
1968
	u_int32_t	 as, bgpid;
1969
	u_int8_t	 optparamlen, plen;
1970
	u_int8_t	 op_type, op_len;
1971
1972
	p = peer->rbuf->rptr;
1973
	p += MSGSIZE_HEADER_MARKER;
1974
	memcpy(&msglen, p, sizeof(msglen));
1975
	msglen = ntohs(msglen);
1976
1977
	p = peer->rbuf->rptr;
1978
	p += MSGSIZE_HEADER;	/* header is already checked */
1979
1980
	memcpy(&version, p, sizeof(version));
1981
	p += sizeof(version);
1982
1983
	if (version != BGP_VERSION) {
1984
		log_peer_warnx(&peer->conf,
1985
		    "peer wants unrecognized version %u", version);
1986
		if (version > BGP_VERSION)
1987
			rversion = version - BGP_VERSION;
1988
		else
1989
			rversion = BGP_VERSION;
1990
		session_notification(peer, ERR_OPEN, ERR_OPEN_VERSION,
1991
		    &rversion, sizeof(rversion));
1992
		change_state(peer, STATE_IDLE, EVNT_RCVD_OPEN);
1993
		return (-1);
1994
	}
1995
1996
	memcpy(&short_as, p, sizeof(short_as));
1997
	p += sizeof(short_as);
1998
	as = peer->short_as = ntohs(short_as);
1999
2000
	memcpy(&oholdtime, p, sizeof(oholdtime));
2001
	p += sizeof(oholdtime);
2002
2003
	holdtime = ntohs(oholdtime);
2004
	if (holdtime && holdtime < peer->conf.min_holdtime) {
2005
		log_peer_warnx(&peer->conf,
2006
		    "peer requests unacceptable holdtime %u", holdtime);
2007
		session_notification(peer, ERR_OPEN, ERR_OPEN_HOLDTIME,
2008
		    NULL, 0);
2009
		change_state(peer, STATE_IDLE, EVNT_RCVD_OPEN);
2010
		return (-1);
2011
	}
2012
2013
	myholdtime = peer->conf.holdtime;
2014
	if (!myholdtime)
2015
		myholdtime = conf->holdtime;
2016
	if (holdtime < myholdtime)
2017
		peer->holdtime = holdtime;
2018
	else
2019
		peer->holdtime = myholdtime;
2020
2021
	memcpy(&bgpid, p, sizeof(bgpid));
2022
	p += sizeof(bgpid);
2023
2024
	/* check bgpid for validity - just disallow 0 */
2025
	if (ntohl(bgpid) == 0) {
2026
		log_peer_warnx(&peer->conf, "peer BGPID %u unacceptable",
2027
		    ntohl(bgpid));
2028
		session_notification(peer, ERR_OPEN, ERR_OPEN_BGPID,
2029
		    NULL, 0);
2030
		change_state(peer, STATE_IDLE, EVNT_RCVD_OPEN);
2031
		return (-1);
2032
	}
2033
	peer->remote_bgpid = bgpid;
2034
2035
	memcpy(&optparamlen, p, sizeof(optparamlen));
2036
	p += sizeof(optparamlen);
2037
2038
	if (optparamlen != msglen - MSGSIZE_OPEN_MIN) {
2039
			log_peer_warnx(&peer->conf,
2040
			    "corrupt OPEN message received: length mismatch");
2041
			session_notification(peer, ERR_OPEN, 0, NULL, 0);
2042
			change_state(peer, STATE_IDLE, EVNT_RCVD_OPEN);
2043
			return (-1);
2044
	}
2045
2046
	plen = optparamlen;
2047
	while (plen > 0) {
2048
		if (plen < 2) {
2049
			log_peer_warnx(&peer->conf,
2050
			    "corrupt OPEN message received, len wrong");
2051
			session_notification(peer, ERR_OPEN, 0, NULL, 0);
2052
			change_state(peer, STATE_IDLE, EVNT_RCVD_OPEN);
2053
			return (-1);
2054
		}
2055
		memcpy(&op_type, p, sizeof(op_type));
2056
		p += sizeof(op_type);
2057
		plen -= sizeof(op_type);
2058
		memcpy(&op_len, p, sizeof(op_len));
2059
		p += sizeof(op_len);
2060
		plen -= sizeof(op_len);
2061
		if (op_len > 0) {
2062
			if (plen < op_len) {
2063
				log_peer_warnx(&peer->conf,
2064
				    "corrupt OPEN message received, len wrong");
2065
				session_notification(peer, ERR_OPEN, 0,
2066
				    NULL, 0);
2067
				change_state(peer, STATE_IDLE, EVNT_RCVD_OPEN);
2068
				return (-1);
2069
			}
2070
			op_val = p;
2071
			p += op_len;
2072
			plen -= op_len;
2073
		} else
2074
			op_val = NULL;
2075
2076
		switch (op_type) {
2077
		case OPT_PARAM_CAPABILITIES:		/* RFC 3392 */
2078
			if (parse_capabilities(peer, op_val, op_len,
2079
			    &as) == -1) {
2080
				session_notification(peer, ERR_OPEN, 0,
2081
				    NULL, 0);
2082
				change_state(peer, STATE_IDLE, EVNT_RCVD_OPEN);
2083
				return (-1);
2084
			}
2085
			break;
2086
		case OPT_PARAM_AUTH:			/* deprecated */
2087
		default:
2088
			/*
2089
			 * unsupported type
2090
			 * the RFCs tell us to leave the data section empty
2091
			 * and notify the peer with ERR_OPEN, ERR_OPEN_OPT.
2092
			 * How the peer should know _which_ optional parameter
2093
			 * we don't support is beyond me.
2094
			 */
2095
			log_peer_warnx(&peer->conf,
2096
			    "received OPEN message with unsupported optional "
2097
			    "parameter: type %u", op_type);
2098
			session_notification(peer, ERR_OPEN, ERR_OPEN_OPT,
2099
				NULL, 0);
2100
			change_state(peer, STATE_IDLE, EVNT_RCVD_OPEN);
2101
			timer_set(peer, Timer_IdleHold, 0);	/* no punish */
2102
			peer->IdleHoldTime /= 2;
2103
			return (-1);
2104
		}
2105
	}
2106
2107
	/* if remote-as is zero and it's a cloned neighbor, accept any */
2108
	if (peer->template && !peer->conf.remote_as && as != AS_TRANS) {
2109
		peer->conf.remote_as = as;
2110
		peer->conf.ebgp = (peer->conf.remote_as != conf->as);
2111
		if (!peer->conf.ebgp)
2112
			/* force enforce_as off for iBGP sessions */
2113
			peer->conf.enforce_as = ENFORCE_AS_OFF;
2114
	}
2115
2116
	if (peer->conf.remote_as != as) {
2117
		log_peer_warnx(&peer->conf, "peer sent wrong AS %s",
2118
		    log_as(as));
2119
		session_notification(peer, ERR_OPEN, ERR_OPEN_AS, NULL, 0);
2120
		change_state(peer, STATE_IDLE, EVNT_RCVD_OPEN);
2121
		return (-1);
2122
	}
2123
2124
	if (capa_neg_calc(peer) == -1) {
2125
		log_peer_warnx(&peer->conf,
2126
		    "capability negotiation calculation failed");
2127
		session_notification(peer, ERR_OPEN, 0, NULL, 0);
2128
		change_state(peer, STATE_IDLE, EVNT_RCVD_OPEN);
2129
		return (-1);
2130
	}
2131
2132
	return (0);
2133
}
2134
2135
int
2136
parse_update(struct peer *peer)
2137
{
2138
	u_char		*p;
2139
	u_int16_t	 datalen;
2140
2141
	/*
2142
	 * we pass the message verbatim to the rde.
2143
	 * in case of errors the whole session is reset with a
2144
	 * notification anyway, we only need to know the peer
2145
	 */
2146
	p = peer->rbuf->rptr;
2147
	p += MSGSIZE_HEADER_MARKER;
2148
	memcpy(&datalen, p, sizeof(datalen));
2149
	datalen = ntohs(datalen);
2150
2151
	p = peer->rbuf->rptr;
2152
	p += MSGSIZE_HEADER;	/* header is already checked */
2153
	datalen -= MSGSIZE_HEADER;
2154
2155
	if (imsg_compose(ibuf_rde, IMSG_UPDATE, peer->conf.id, 0, -1, p,
2156
	    datalen) == -1)
2157
		return (-1);
2158
2159
	return (0);
2160
}
2161
2162
int
2163
parse_refresh(struct peer *peer)
2164
{
2165
	u_char		*p;
2166
	u_int16_t	 afi;
2167
	u_int8_t	 aid, safi;
2168
2169
	p = peer->rbuf->rptr;
2170
	p += MSGSIZE_HEADER;	/* header is already checked */
2171
2172
	/*
2173
	 * We could check if we actually announced the capability but
2174
	 * as long as the message is correctly encoded we don't care.
2175
	 */
2176
2177
	/* afi, 2 byte */
2178
	memcpy(&afi, p, sizeof(afi));
2179
	afi = ntohs(afi);
2180
	p += 2;
2181
	/* reserved, 1 byte */
2182
	p += 1;
2183
	/* safi, 1 byte */
2184
	memcpy(&safi, p, sizeof(safi));
2185
2186
	/* afi/safi unchecked -	unrecognized values will be ignored anyway */
2187
	if (afi2aid(afi, safi, &aid) == -1) {
2188
		log_peer_warnx(&peer->conf, "peer sent bad refresh, "
2189
		    "invalid afi/safi pair");
2190
		return (0);
2191
	}
2192
2193
	if (imsg_compose(ibuf_rde, IMSG_REFRESH, peer->conf.id, 0, -1, &aid,
2194
	    sizeof(aid)) == -1)
2195
		return (-1);
2196
2197
	return (0);
2198
}
2199
2200
int
2201
parse_notification(struct peer *peer)
2202
{
2203
	u_char		*p;
2204
	u_int16_t	 datalen;
2205
	u_int8_t	 errcode;
2206
	u_int8_t	 subcode;
2207
	u_int8_t	 capa_code;
2208
	u_int8_t	 capa_len;
2209
	u_int8_t	 i;
2210
2211
	/* just log */
2212
	p = peer->rbuf->rptr;
2213
	p += MSGSIZE_HEADER_MARKER;
2214
	memcpy(&datalen, p, sizeof(datalen));
2215
	datalen = ntohs(datalen);
2216
2217
	p = peer->rbuf->rptr;
2218
	p += MSGSIZE_HEADER;	/* header is already checked */
2219
	datalen -= MSGSIZE_HEADER;
2220
2221
	memcpy(&errcode, p, sizeof(errcode));
2222
	p += sizeof(errcode);
2223
	datalen -= sizeof(errcode);
2224
2225
	memcpy(&subcode, p, sizeof(subcode));
2226
	p += sizeof(subcode);
2227
	datalen -= sizeof(subcode);
2228
2229
	log_notification(peer, errcode, subcode, p, datalen, "received");
2230
	peer->errcnt++;
2231
2232
	if (errcode == ERR_OPEN && subcode == ERR_OPEN_CAPA) {
2233
		if (datalen == 0) {	/* zebra likes to send those.. humbug */
2234
			log_peer_warnx(&peer->conf, "received \"unsupported "
2235
			    "capability\" notification without data part, "
2236
			    "disabling capability announcements altogether");
2237
			session_capa_ann_none(peer);
2238
		}
2239
2240
		while (datalen > 0) {
2241
			if (datalen < 2) {
2242
				log_peer_warnx(&peer->conf,
2243
				    "parse_notification: "
2244
				    "expect len >= 2, len is %u", datalen);
2245
				return (-1);
2246
			}
2247
			memcpy(&capa_code, p, sizeof(capa_code));
2248
			p += sizeof(capa_code);
2249
			datalen -= sizeof(capa_code);
2250
			memcpy(&capa_len, p, sizeof(capa_len));
2251
			p += sizeof(capa_len);
2252
			datalen -= sizeof(capa_len);
2253
			if (datalen < capa_len) {
2254
				log_peer_warnx(&peer->conf,
2255
				    "parse_notification: capa_len %u exceeds "
2256
				    "remaining msg length %u", capa_len,
2257
				    datalen);
2258
				return (-1);
2259
			}
2260
			p += capa_len;
2261
			datalen -= capa_len;
2262
			switch (capa_code) {
2263
			case CAPA_MP:
2264
				for (i = 0; i < AID_MAX; i++)
2265
					peer->capa.ann.mp[i] = 0;
2266
				log_peer_warnx(&peer->conf,
2267
				    "disabling multiprotocol capability");
2268
				break;
2269
			case CAPA_REFRESH:
2270
				peer->capa.ann.refresh = 0;
2271
				log_peer_warnx(&peer->conf,
2272
				    "disabling route refresh capability");
2273
				break;
2274
			case CAPA_RESTART:
2275
				peer->capa.ann.grestart.restart = 0;
2276
				log_peer_warnx(&peer->conf,
2277
				    "disabling restart capability");
2278
				break;
2279
			case CAPA_AS4BYTE:
2280
				peer->capa.ann.as4byte = 0;
2281
				log_peer_warnx(&peer->conf,
2282
				    "disabling 4-byte AS num capability");
2283
				break;
2284
			default:	/* should not happen... */
2285
				log_peer_warnx(&peer->conf, "received "
2286
				    "\"unsupported capability\" notification "
2287
				    "for unknown capability %u, disabling "
2288
				    "capability announcements altogether",
2289
				    capa_code);
2290
				session_capa_ann_none(peer);
2291
				break;
2292
			}
2293
		}
2294
2295
		return (1);
2296
	}
2297
2298
	if (errcode == ERR_OPEN && subcode == ERR_OPEN_OPT) {
2299
		session_capa_ann_none(peer);
2300
		return (1);
2301
	}
2302
2303
	return (0);
2304
}
2305
2306
int
2307
parse_capabilities(struct peer *peer, u_char *d, u_int16_t dlen, u_int32_t *as)
2308
{
2309
	u_char		*capa_val;
2310
	u_int32_t	 remote_as;
2311
	u_int16_t	 len;
2312
	u_int16_t	 afi;
2313
	u_int16_t	 gr_header;
2314
	u_int8_t	 safi;
2315
	u_int8_t	 aid;
2316
	u_int8_t	 gr_flags;
2317
	u_int8_t	 capa_code;
2318
	u_int8_t	 capa_len;
2319
	u_int8_t	 i;
2320
2321
	len = dlen;
2322
	while (len > 0) {
2323
		if (len < 2) {
2324
			log_peer_warnx(&peer->conf, "Bad capabilities attr "
2325
			    "length: %u, too short", len);
2326
			return (-1);
2327
		}
2328
		memcpy(&capa_code, d, sizeof(capa_code));
2329
		d += sizeof(capa_code);
2330
		len -= sizeof(capa_code);
2331
		memcpy(&capa_len, d, sizeof(capa_len));
2332
		d += sizeof(capa_len);
2333
		len -= sizeof(capa_len);
2334
		if (capa_len > 0) {
2335
			if (len < capa_len) {
2336
				log_peer_warnx(&peer->conf,
2337
				    "Bad capabilities attr length: "
2338
				    "len %u smaller than capa_len %u",
2339
				    len, capa_len);
2340
				return (-1);
2341
			}
2342
			capa_val = d;
2343
			d += capa_len;
2344
			len -= capa_len;
2345
		} else
2346
			capa_val = NULL;
2347
2348
		switch (capa_code) {
2349
		case CAPA_MP:			/* RFC 4760 */
2350
			if (capa_len != 4) {
2351
				log_peer_warnx(&peer->conf,
2352
				    "Bad multi protocol capability length: "
2353
				    "%u", capa_len);
2354
				break;
2355
			}
2356
			memcpy(&afi, capa_val, sizeof(afi));
2357
			afi = ntohs(afi);
2358
			memcpy(&safi, capa_val + 3, sizeof(safi));
2359
			if (afi2aid(afi, safi, &aid) == -1) {
2360
				log_peer_warnx(&peer->conf,
2361
				    "Received multi protocol capability: "
2362
				    " unknown AFI %u, safi %u pair",
2363
				    afi, safi);
2364
				break;
2365
			}
2366
			peer->capa.peer.mp[aid] = 1;
2367
			break;
2368
		case CAPA_REFRESH:
2369
			peer->capa.peer.refresh = 1;
2370
			break;
2371
		case CAPA_RESTART:
2372
			if (capa_len == 2) {
2373
				/* peer only supports EoR marker */
2374
				peer->capa.peer.grestart.restart = 1;
2375
				peer->capa.peer.grestart.timeout = 0;
2376
				break;
2377
			} else if (capa_len % 4 != 2) {
2378
				log_peer_warnx(&peer->conf,
2379
				    "Bad graceful restart capability length: "
2380
				    "%u", capa_len);
2381
				peer->capa.peer.grestart.restart = 0;
2382
				peer->capa.peer.grestart.timeout = 0;
2383
				break;
2384
			}
2385
2386
			memcpy(&gr_header, capa_val, sizeof(gr_header));
2387
			gr_header = ntohs(gr_header);
2388
			peer->capa.peer.grestart.timeout =
2389
			    gr_header & CAPA_GR_TIMEMASK;
2390
			if (peer->capa.peer.grestart.timeout == 0) {
2391
				log_peer_warnx(&peer->conf, "Received "
2392
				    "graceful restart timeout is zero");
2393
				peer->capa.peer.grestart.restart = 0;
2394
				break;
2395
			}
2396
2397
			for (i = 2; i <= capa_len - 4; i += 4) {
2398
				memcpy(&afi, capa_val + i, sizeof(afi));
2399
				afi = ntohs(afi);
2400
				memcpy(&safi, capa_val + i + 2, sizeof(safi));
2401
				if (afi2aid(afi, safi, &aid) == -1) {
2402
					log_peer_warnx(&peer->conf,
2403
					    "Received graceful restart capa: "
2404
					    " unknown AFI %u, safi %u pair",
2405
					    afi, safi);
2406
					continue;
2407
				}
2408
				memcpy(&gr_flags, capa_val + i + 3,
2409
				    sizeof(gr_flags));
2410
				peer->capa.peer.grestart.flags[aid] |=
2411
				    CAPA_GR_PRESENT;
2412
				if (gr_flags & CAPA_GR_F_FLAG)
2413
					peer->capa.peer.grestart.flags[aid] |=
2414
					    CAPA_GR_FORWARD;
2415
				if (gr_header & CAPA_GR_R_FLAG)
2416
					peer->capa.peer.grestart.flags[aid] |=
2417
					    CAPA_GR_RESTART;
2418
				peer->capa.peer.grestart.restart = 2;
2419
			}
2420
			break;
2421
		case CAPA_AS4BYTE:
2422
			if (capa_len != 4) {
2423
				log_peer_warnx(&peer->conf,
2424
				    "Bad AS4BYTE capability length: "
2425
				    "%u", capa_len);
2426
				peer->capa.peer.as4byte = 0;
2427
				break;
2428
			}
2429
			memcpy(&remote_as, capa_val, sizeof(remote_as));
2430
			*as = ntohl(remote_as);
2431
			peer->capa.peer.as4byte = 1;
2432
			break;
2433
		default:
2434
			break;
2435
		}
2436
	}
2437
2438
	return (0);
2439
}
2440
2441
int
2442
capa_neg_calc(struct peer *p)
2443
{
2444
	u_int8_t	i, hasmp = 0;
2445
2446
	/* refresh: does not realy matter here, use peer setting */
2447
	p->capa.neg.refresh = p->capa.peer.refresh;
2448
2449
	/* as4byte: both side must announce capability */
2450
	if (p->capa.ann.as4byte && p->capa.peer.as4byte)
2451
		p->capa.neg.as4byte = 1;
2452
	else
2453
		p->capa.neg.as4byte = 0;
2454
2455
	/* MP: both side must announce capability */
2456
	for (i = 0; i < AID_MAX; i++) {
2457
		if (p->capa.ann.mp[i] && p->capa.peer.mp[i]) {
2458
			p->capa.neg.mp[i] = 1;
2459
			hasmp = 1;
2460
		} else
2461
			p->capa.neg.mp[i] = 0;
2462
	}
2463
	/* if no MP capability present default to IPv4 unicast mode */
2464
	if (!hasmp)
2465
		p->capa.neg.mp[AID_INET] = 1;
2466
2467
	/*
2468
	 * graceful restart: only the peer capabilities are of interest here.
2469
	 * It is necessary to compare the new values with the previous ones
2470
	 * and act acordingly. AFI/SAFI that are not part in the MP capability
2471
	 * are treated as not being present.
2472
	 */
2473
2474
	for (i = 0; i < AID_MAX; i++) {
2475
		int8_t	negflags;
2476
2477
		/* disable GR if the AFI/SAFI is not present */
2478
		if (p->capa.peer.grestart.flags[i] & CAPA_GR_PRESENT &&
2479
		    p->capa.neg.mp[i] == 0)
2480
			p->capa.peer.grestart.flags[i] = 0;	/* disable */
2481
		/* look at current GR state and decide what to do */
2482
		negflags = p->capa.neg.grestart.flags[i];
2483
		p->capa.neg.grestart.flags[i] = p->capa.peer.grestart.flags[i];
2484
		if (negflags & CAPA_GR_RESTARTING) {
2485
			if (!(p->capa.peer.grestart.flags[i] &
2486
			    CAPA_GR_FORWARD)) {
2487
				if (imsg_compose(ibuf_rde, IMSG_SESSION_FLUSH,
2488
				    p->conf.id, 0, -1, &i, sizeof(i)) == -1)
2489
					return (-1);
2490
				log_peer_warnx(&p->conf, "graceful restart of "
2491
				    "%s, not restarted, flushing", aid2str(i));
2492
			} else
2493
				p->capa.neg.grestart.flags[i] |=
2494
				    CAPA_GR_RESTARTING;
2495
		}
2496
	}
2497
	p->capa.neg.grestart.timeout = p->capa.peer.grestart.timeout;
2498
	p->capa.neg.grestart.restart = p->capa.peer.grestart.restart;
2499
2500
	return (0);
2501
}
2502
2503
void
2504
session_dispatch_imsg(struct imsgbuf *ibuf, int idx, u_int *listener_cnt)
2505
{
2506
	struct imsg		 imsg;
2507
	struct mrt		 xmrt;
2508
	struct mrt		*mrt;
2509
	struct imsgbuf		*i;
2510
	struct peer_config	*pconf;
2511
	struct peer		*p, *next;
2512
	struct listen_addr	*la, *nla;
2513
	struct kif		*kif;
2514
	u_char			*data;
2515
	enum reconf_action	 reconf;
2516
	int			 n, fd, depend_ok, restricted;
2517
	u_int8_t		 aid, errcode, subcode;
2518
2519
	while (ibuf) {
2520
		if ((n = imsg_get(ibuf, &imsg)) == -1)
2521
			fatal("session_dispatch_imsg: imsg_get error");
2522
2523
		if (n == 0)
2524
			break;
2525
2526
		switch (imsg.hdr.type) {
2527
		case IMSG_SOCKET_CONN:
2528
		case IMSG_SOCKET_CONN_CTL:
2529
			if (idx != PFD_PIPE_MAIN)
2530
				fatalx("reconf request not from parent");
2531
			if ((fd = imsg.fd) == -1) {
2532
				log_warnx("expected to receive imsg fd to "
2533
				    "RDE but didn't receive any");
2534
				break;
2535
			}
2536
			if ((i = malloc(sizeof(struct imsgbuf))) == NULL)
2537
				fatal(NULL);
2538
			imsg_init(i, fd);
2539
			if (imsg.hdr.type == IMSG_SOCKET_CONN) {
2540
				if (ibuf_rde) {
2541
					log_warnx("Unexpected imsg connection "
2542
					    "to RDE received");
2543
					msgbuf_clear(&ibuf_rde->w);
2544
					free(ibuf_rde);
2545
				}
2546
				ibuf_rde = i;
2547
			} else {
2548
				if (ibuf_rde_ctl) {
2549
					log_warnx("Unexpected imsg ctl "
2550
					    "connection to RDE received");
2551
					msgbuf_clear(&ibuf_rde_ctl->w);
2552
					free(ibuf_rde_ctl);
2553
				}
2554
				ibuf_rde_ctl = i;
2555
			}
2556
			break;
2557
		case IMSG_RECONF_CONF:
2558
			if (idx != PFD_PIPE_MAIN)
2559
				fatalx("reconf request not from parent");
2560
			if ((nconf = malloc(sizeof(struct bgpd_config))) ==
2561
			    NULL)
2562
				fatal(NULL);
2563
			memcpy(nconf, imsg.data, sizeof(struct bgpd_config));
2564
			if ((nconf->listen_addrs = calloc(1,
2565
			    sizeof(struct listen_addrs))) == NULL)
2566
				fatal(NULL);
2567
			TAILQ_INIT(nconf->listen_addrs);
2568
			npeers = NULL;
2569
			init_conf(nconf);
2570
			pending_reconf = 1;
2571
			break;
2572
		case IMSG_RECONF_PEER:
2573
			if (idx != PFD_PIPE_MAIN)
2574
				fatalx("reconf request not from parent");
2575
			pconf = imsg.data;
2576
			p = getpeerbyaddr(&pconf->remote_addr);
2577
			if (p == NULL) {
2578
				if ((p = calloc(1, sizeof(struct peer))) ==
2579
				    NULL)
2580
					fatal("new_peer");
2581
				p->state = p->prev_state = STATE_NONE;
2582
				p->next = npeers;
2583
				npeers = p;
2584
				reconf = RECONF_REINIT;
2585
			} else
2586
				reconf = RECONF_KEEP;
2587
2588
			memcpy(&p->conf, pconf, sizeof(struct peer_config));
2589
			p->conf.reconf_action = reconf;
2590
2591
			/* sync the RDE in case we keep the peer */
2592
			if (reconf == RECONF_KEEP) {
2593
				if (imsg_compose(ibuf_rde, IMSG_SESSION_ADD,
2594
				    p->conf.id, 0, -1, &p->conf,
2595
				    sizeof(struct peer_config)) == -1)
2596
					fatalx("imsg_compose error");
2597
				if (p->conf.template) {
2598
					/* apply the conf to all clones */
2599
					struct peer *np;
2600
					for (np = peers; np; np = np->next) {
2601
						if (np->template != p)
2602
							continue;
2603
						session_template_clone(np,
2604
						    NULL, np->conf.id,
2605
						    np->conf.remote_as);
2606
						if (imsg_compose(ibuf_rde,
2607
						    IMSG_SESSION_ADD,
2608
						    np->conf.id, 0, -1,
2609
						    &np->conf,
2610
						    sizeof(struct peer_config))
2611
						    == -1)
2612
							fatalx("imsg_compose error");
2613
					}
2614
				}
2615
			}
2616
			break;
2617
		case IMSG_RECONF_LISTENER:
2618
			if (idx != PFD_PIPE_MAIN)
2619
				fatalx("reconf request not from parent");
2620
			if (nconf == NULL)
2621
				fatalx("IMSG_RECONF_LISTENER but no config");
2622
			nla = imsg.data;
2623
			TAILQ_FOREACH(la, conf->listen_addrs, entry)
2624
				if (!la_cmp(la, nla))
2625
					break;
2626
2627
			if (la == NULL) {
2628
				if (nla->reconf != RECONF_REINIT)
2629
					fatalx("king bula sez: "
2630
					    "expected REINIT");
2631
2632
				if ((nla->fd = imsg.fd) == -1)
2633
					log_warnx("expected to receive fd for "
2634
					    "%s but didn't receive any",
2635
					    log_sockaddr((struct sockaddr *)
2636
					    &nla->sa));
2637
2638
				la = calloc(1, sizeof(struct listen_addr));
2639
				if (la == NULL)
2640
					fatal(NULL);
2641
				memcpy(&la->sa, &nla->sa, sizeof(la->sa));
2642
				la->flags = nla->flags;
2643
				la->fd = nla->fd;
2644
				la->reconf = RECONF_REINIT;
2645
				TAILQ_INSERT_TAIL(nconf->listen_addrs, la,
2646
				    entry);
2647
			} else {
2648
				if (nla->reconf != RECONF_KEEP)
2649
					fatalx("king bula sez: expected KEEP");
2650
				la->reconf = RECONF_KEEP;
2651
			}
2652
2653
			break;
2654
		case IMSG_RECONF_CTRL:
2655
			if (idx != PFD_PIPE_MAIN)
2656
				fatalx("reconf request not from parent");
2657
			if (imsg.hdr.len != IMSG_HEADER_SIZE +
2658
			    sizeof(restricted))
2659
				fatalx("IFINFO imsg with wrong len");
2660
			memcpy(&restricted, imsg.data, sizeof(restricted));
2661
			if (imsg.fd == -1) {
2662
				log_warnx("expected to receive fd for control "
2663
				    "socket but didn't receive any");
2664
				break;
2665
			}
2666
			if (restricted) {
2667
				control_shutdown(rcsock);
2668
				rcsock = imsg.fd;
2669
			} else {
2670
				control_shutdown(csock);
2671
				csock = imsg.fd;
2672
			}
2673
			break;
2674
		case IMSG_RECONF_DONE:
2675
			if (idx != PFD_PIPE_MAIN)
2676
				fatalx("reconf request not from parent");
2677
			if (nconf == NULL)
2678
				fatalx("got IMSG_RECONF_DONE but no config");
2679
			conf->flags = nconf->flags;
2680
			conf->log = nconf->log;
2681
			conf->bgpid = nconf->bgpid;
2682
			conf->clusterid = nconf->clusterid;
2683
			conf->as = nconf->as;
2684
			conf->short_as = nconf->short_as;
2685
			conf->holdtime = nconf->holdtime;
2686
			conf->min_holdtime = nconf->min_holdtime;
2687
			conf->connectretry = nconf->connectretry;
2688
2689
			/* add new peers */
2690
			for (p = npeers; p != NULL; p = next) {
2691
				next = p->next;
2692
				p->next = peers;
2693
				peers = p;
2694
			}
2695
			/* find ones that need attention */
2696
			for (p = peers; p != NULL; p = p->next) {
2697
				/* needs to be deleted? */
2698
				if (p->conf.reconf_action == RECONF_NONE &&
2699
				    !p->template)
2700
					p->conf.reconf_action = RECONF_DELETE;
2701
				/* had demotion, is demoted, demote removed? */
2702
				if (p->demoted && !p->conf.demote_group[0])
2703
						session_demote(p, -1);
2704
			}
2705
2706
			/* delete old listeners */
2707
			for (la = TAILQ_FIRST(conf->listen_addrs); la != NULL;
2708
			    la = nla) {
2709
				nla = TAILQ_NEXT(la, entry);
2710
				if (la->reconf == RECONF_NONE) {
2711
					log_info("not listening on %s any more",
2712
					    log_sockaddr(
2713
					    (struct sockaddr *)&la->sa));
2714
					TAILQ_REMOVE(conf->listen_addrs, la,
2715
					    entry);
2716
					close(la->fd);
2717
					free(la);
2718
				}
2719
			}
2720
2721
			/* add new listeners */
2722
			while ((la = TAILQ_FIRST(nconf->listen_addrs)) !=
2723
			    NULL) {
2724
				TAILQ_REMOVE(nconf->listen_addrs, la, entry);
2725
				TAILQ_INSERT_TAIL(conf->listen_addrs, la,
2726
				    entry);
2727
			}
2728
2729
			setup_listeners(listener_cnt);
2730
			free(nconf->listen_addrs);
2731
			free(nconf);
2732
			nconf = NULL;
2733
			pending_reconf = 0;
2734
			log_info("SE reconfigured");
2735
			imsg_compose(ibuf_main, IMSG_RECONF_DONE, 0, 0,
2736
			    -1, NULL, 0);
2737
			break;
2738
		case IMSG_IFINFO:
2739
			if (idx != PFD_PIPE_MAIN)
2740
				fatalx("IFINFO message not from parent");
2741
			if (imsg.hdr.len != IMSG_HEADER_SIZE +
2742
			    sizeof(struct kif))
2743
				fatalx("IFINFO imsg with wrong len");
2744
			kif = imsg.data;
2745
			depend_ok = (kif->flags & IFF_UP) &&
2746
			    LINK_STATE_IS_UP(kif->link_state);
2747
2748
			for (p = peers; p != NULL; p = p->next)
2749
				if (!strcmp(p->conf.if_depend, kif->ifname)) {
2750
					if (depend_ok && !p->depend_ok) {
2751
						p->depend_ok = depend_ok;
2752
						bgp_fsm(p, EVNT_START);
2753
					} else if (!depend_ok && p->depend_ok) {
2754
						p->depend_ok = depend_ok;
2755
						session_stop(p,
2756
						    ERR_CEASE_OTHER_CHANGE);
2757
					}
2758
				}
2759
			break;
2760
		case IMSG_MRT_OPEN:
2761
		case IMSG_MRT_REOPEN:
2762
			if (imsg.hdr.len > IMSG_HEADER_SIZE +
2763
			    sizeof(struct mrt)) {
2764
				log_warnx("wrong imsg len");
2765
				break;
2766
			}
2767
2768
			memcpy(&xmrt, imsg.data, sizeof(struct mrt));
2769
			if ((xmrt.wbuf.fd = imsg.fd) == -1)
2770
				log_warnx("expected to receive fd for mrt dump "
2771
				    "but didn't receive any");
2772
2773
			mrt = mrt_get(&mrthead, &xmrt);
2774
			if (mrt == NULL) {
2775
				/* new dump */
2776
				mrt = calloc(1, sizeof(struct mrt));
2777
				if (mrt == NULL)
2778
					fatal("session_dispatch_imsg");
2779
				memcpy(mrt, &xmrt, sizeof(struct mrt));
2780
				TAILQ_INIT(&mrt->wbuf.bufs);
2781
				LIST_INSERT_HEAD(&mrthead, mrt, entry);
2782
			} else {
2783
				/* old dump reopened */
2784
				close(mrt->wbuf.fd);
2785
				mrt->wbuf.fd = xmrt.wbuf.fd;
2786
			}
2787
			break;
2788
		case IMSG_MRT_CLOSE:
2789
			if (imsg.hdr.len > IMSG_HEADER_SIZE +
2790
			    sizeof(struct mrt)) {
2791
				log_warnx("wrong imsg len");
2792
				break;
2793
			}
2794
2795
			memcpy(&xmrt, imsg.data, sizeof(struct mrt));
2796
			mrt = mrt_get(&mrthead, &xmrt);
2797
			if (mrt != NULL)
2798
				mrt_done(mrt);
2799
			break;
2800
		case IMSG_CTL_KROUTE:
2801
		case IMSG_CTL_KROUTE_ADDR:
2802
		case IMSG_CTL_SHOW_NEXTHOP:
2803
		case IMSG_CTL_SHOW_INTERFACE:
2804
		case IMSG_CTL_SHOW_FIB_TABLES:
2805
			if (idx != PFD_PIPE_MAIN)
2806
				fatalx("ctl kroute request not from parent");
2807
			control_imsg_relay(&imsg);
2808
			break;
2809
		case IMSG_CTL_SHOW_RIB:
2810
		case IMSG_CTL_SHOW_RIB_PREFIX:
2811
		case IMSG_CTL_SHOW_RIB_ATTR:
2812
		case IMSG_CTL_SHOW_RIB_MEM:
2813
		case IMSG_CTL_SHOW_NETWORK:
2814
		case IMSG_CTL_SHOW_NEIGHBOR:
2815
			if (idx != PFD_PIPE_ROUTE_CTL)
2816
				fatalx("ctl rib request not from RDE");
2817
			control_imsg_relay(&imsg);
2818
			break;
2819
		case IMSG_CTL_END:
2820
		case IMSG_CTL_RESULT:
2821
			control_imsg_relay(&imsg);
2822
			break;
2823
		case IMSG_UPDATE:
2824
			if (idx != PFD_PIPE_ROUTE)
2825
				fatalx("update request not from RDE");
2826
			if (imsg.hdr.len > IMSG_HEADER_SIZE +
2827
			    MAX_PKTSIZE - MSGSIZE_HEADER ||
2828
			    imsg.hdr.len < IMSG_HEADER_SIZE +
2829
			    MSGSIZE_UPDATE_MIN - MSGSIZE_HEADER)
2830
				log_warnx("RDE sent invalid update");
2831
			else
2832
				session_update(imsg.hdr.peerid, imsg.data,
2833
				    imsg.hdr.len - IMSG_HEADER_SIZE);
2834
			break;
2835
		case IMSG_UPDATE_ERR:
2836
			if (idx != PFD_PIPE_ROUTE)
2837
				fatalx("update request not from RDE");
2838
			if (imsg.hdr.len < IMSG_HEADER_SIZE + 2) {
2839
				log_warnx("RDE sent invalid notification");
2840
				break;
2841
			}
2842
			if ((p = getpeerbyid(imsg.hdr.peerid)) == NULL) {
2843
				log_warnx("no such peer: id=%u",
2844
				    imsg.hdr.peerid);
2845
				break;
2846
			}
2847
			data = imsg.data;
2848
			errcode = *data++;
2849
			subcode = *data++;
2850
2851
			if (imsg.hdr.len == IMSG_HEADER_SIZE + 2)
2852
				data = NULL;
2853
2854
			session_notification(p, errcode, subcode,
2855
			    data, imsg.hdr.len - IMSG_HEADER_SIZE - 2);
2856
			switch (errcode) {
2857
			case ERR_CEASE:
2858
				switch (subcode) {
2859
				case ERR_CEASE_MAX_PREFIX:
2860
					bgp_fsm(p, EVNT_STOP);
2861
					if (p->conf.max_prefix_restart)
2862
						timer_set(p, Timer_IdleHold, 60 *
2863
						    p->conf.max_prefix_restart);
2864
					break;
2865
				default:
2866
					bgp_fsm(p, EVNT_CON_FATAL);
2867
					break;
2868
				}
2869
				break;
2870
			default:
2871
				bgp_fsm(p, EVNT_CON_FATAL);
2872
				break;
2873
			}
2874
			break;
2875
		case IMSG_SESSION_RESTARTED:
2876
			if (idx != PFD_PIPE_ROUTE)
2877
				fatalx("update request not from RDE");
2878
			if (imsg.hdr.len < IMSG_HEADER_SIZE + sizeof(aid)) {
2879
				log_warnx("RDE sent invalid restart msg");
2880
				break;
2881
			}
2882
			if ((p = getpeerbyid(imsg.hdr.peerid)) == NULL) {
2883
				log_warnx("no such peer: id=%u",
2884
				    imsg.hdr.peerid);
2885
				break;
2886
			}
2887
			memcpy(&aid, imsg.data, sizeof(aid));
2888
			if (aid >= AID_MAX)
2889
				fatalx("IMSG_SESSION_RESTARTED: bad AID");
2890
			if (p->capa.neg.grestart.flags[aid] &
2891
			    CAPA_GR_RESTARTING) {
2892
				log_peer_warnx(&p->conf,
2893
				    "graceful restart of %s finished",
2894
				    aid2str(aid));
2895
				p->capa.neg.grestart.flags[aid] &=
2896
				    ~CAPA_GR_RESTARTING;
2897
				timer_stop(p, Timer_RestartTimeout);
2898
2899
				/* signal back to RDE to cleanup stale routes */
2900
				if (imsg_compose(ibuf_rde,
2901
				    IMSG_SESSION_RESTARTED, imsg.hdr.peerid, 0,
2902
				    -1, &aid, sizeof(aid)) == -1)
2903
					fatal("imsg_compose: "
2904
					    "IMSG_SESSION_RESTARTED");
2905
			}
2906
			break;
2907
		case IMSG_SESSION_DOWN:
2908
			if (idx != PFD_PIPE_ROUTE)
2909
				fatalx("update request not from RDE");
2910
			if ((p = getpeerbyid(imsg.hdr.peerid)) == NULL) {
2911
				log_warnx("no such peer: id=%u",
2912
				    imsg.hdr.peerid);
2913
				break;
2914
			}
2915
			session_stop(p, ERR_CEASE_ADMIN_DOWN);
2916
			break;
2917
		default:
2918
			break;
2919
		}
2920
		imsg_free(&imsg);
2921
	}
2922
}
2923
2924
int
2925
la_cmp(struct listen_addr *a, struct listen_addr *b)
2926
{
2927
	struct sockaddr_in	*in_a, *in_b;
2928
	struct sockaddr_in6	*in6_a, *in6_b;
2929
2930
	if (a->sa.ss_family != b->sa.ss_family)
2931
		return (1);
2932
2933
	switch (a->sa.ss_family) {
2934
	case AF_INET:
2935
		in_a = (struct sockaddr_in *)&a->sa;
2936
		in_b = (struct sockaddr_in *)&b->sa;
2937
		if (in_a->sin_addr.s_addr != in_b->sin_addr.s_addr)
2938
			return (1);
2939
		if (in_a->sin_port != in_b->sin_port)
2940
			return (1);
2941
		break;
2942
	case AF_INET6:
2943
		in6_a = (struct sockaddr_in6 *)&a->sa;
2944
		in6_b = (struct sockaddr_in6 *)&b->sa;
2945
		if (bcmp(&in6_a->sin6_addr, &in6_b->sin6_addr,
2946
		    sizeof(struct in6_addr)))
2947
			return (1);
2948
		if (in6_a->sin6_port != in6_b->sin6_port)
2949
			return (1);
2950
		break;
2951
	default:
2952
		fatal("king bula sez: unknown address family");
2953
		/* NOTREACHED */
2954
	}
2955
2956
	return (0);
2957
}
2958
2959
struct peer *
2960
getpeerbyaddr(struct bgpd_addr *addr)
2961
{
2962
	struct peer *p;
2963
2964
	/* we might want a more effective way to find peers by IP */
2965
	for (p = peers; p != NULL &&
2966
	    memcmp(&p->conf.remote_addr, addr, sizeof(p->conf.remote_addr));
2967
	    p = p->next)
2968
		;	/* nothing */
2969
2970
	return (p);
2971
}
2972
2973
struct peer *
2974
getpeerbydesc(const char *descr)
2975
{
2976
	struct peer	*p, *res = NULL;
2977
	int		 match = 0;
2978
2979
	for (p = peers; p != NULL; p = p->next)
2980
		if (!strcmp(p->conf.descr, descr)) {
2981
			res = p;
2982
			match++;
2983
		}
2984
2985
	if (match > 1)
2986
		log_info("neighbor description \"%s\" not unique, request "
2987
		    "aborted", descr);
2988
2989
	if (match == 1)
2990
		return (res);
2991
	else
2992
		return (NULL);
2993
}
2994
2995
struct peer *
2996
getpeerbyip(struct sockaddr *ip)
2997
{
2998
	struct bgpd_addr addr;
2999
	struct peer	*p, *newpeer, *loose = NULL;
3000
	u_int32_t	 id;
3001
3002
	sa2addr(ip, &addr);
3003
3004
	/* we might want a more effective way to find peers by IP */
3005
	for (p = peers; p != NULL; p = p->next)
3006
		if (!p->conf.template &&
3007
		    !memcmp(&addr, &p->conf.remote_addr, sizeof(addr)))
3008
			return (p);
3009
3010
	/* try template matching */
3011
	for (p = peers; p != NULL; p = p->next)
3012
		if (p->conf.template &&
3013
		    p->conf.remote_addr.aid == addr.aid &&
3014
		    session_match_mask(p, &addr))
3015
			if (loose == NULL || loose->conf.remote_masklen <
3016
			    p->conf.remote_masklen)
3017
				loose = p;
3018
3019
	if (loose != NULL) {
3020
		/* clone */
3021
		if ((newpeer = malloc(sizeof(struct peer))) == NULL)
3022
			fatal(NULL);
3023
		memcpy(newpeer, loose, sizeof(struct peer));
3024
		for (id = UINT_MAX; id > UINT_MAX / 2; id--) {
3025
			for (p = peers; p != NULL && p->conf.id != id;
3026
			    p = p->next)
3027
				;	/* nothing */
3028
			if (p == NULL) {	/* we found a free id */
3029
				break;
3030
			}
3031
		}
3032
		newpeer->template = loose;
3033
		session_template_clone(newpeer, ip, id, 0);
3034
		newpeer->state = newpeer->prev_state = STATE_NONE;
3035
		newpeer->conf.reconf_action = RECONF_KEEP;
3036
		newpeer->rbuf = NULL;
3037
		init_peer(newpeer);
3038
		bgp_fsm(newpeer, EVNT_START);
3039
		newpeer->next = peers;
3040
		peers = newpeer;
3041
		return (newpeer);
3042
	}
3043
3044
	return (NULL);
3045
}
3046
3047
void
3048
session_template_clone(struct peer *p, struct sockaddr *ip, u_int32_t id,
3049
    u_int32_t as)
3050
{
3051
	struct bgpd_addr	remote_addr;
3052
3053
	if (ip)
3054
		sa2addr(ip, &remote_addr);
3055
	else
3056
		memcpy(&remote_addr, &p->conf.remote_addr, sizeof(remote_addr));
3057
3058
	memcpy(&p->conf, &p->template->conf, sizeof(struct peer_config));
3059
3060
	p->conf.id = id;
3061
3062
	if (as) {
3063
		p->conf.remote_as = as;
3064
		p->conf.ebgp = (p->conf.remote_as != conf->as);
3065
		if (!p->conf.ebgp)
3066
			/* force enforce_as off for iBGP sessions */
3067
			p->conf.enforce_as = ENFORCE_AS_OFF;
3068
	}
3069
3070
	memcpy(&p->conf.remote_addr, &remote_addr, sizeof(remote_addr));
3071
	switch (p->conf.remote_addr.aid) {
3072
	case AID_INET:
3073
		p->conf.remote_masklen = 32;
3074
		break;
3075
	case AID_INET6:
3076
		p->conf.remote_masklen = 128;
3077
		break;
3078
	}
3079
	p->conf.template = 0;
3080
}
3081
3082
int
3083
session_match_mask(struct peer *p, struct bgpd_addr *a)
3084
{
3085
	in_addr_t	 v4mask;
3086
	struct in6_addr	 masked;
3087
3088
	switch (p->conf.remote_addr.aid) {
3089
	case AID_INET:
3090
		v4mask = htonl(prefixlen2mask(p->conf.remote_masklen));
3091
		if (p->conf.remote_addr.v4.s_addr == (a->v4.s_addr & v4mask))
3092
			return (1);
3093
		return (0);
3094
	case AID_INET6:
3095
		inet6applymask(&masked, &a->v6, p->conf.remote_masklen);
3096
3097
		if (!memcmp(&masked, &p->conf.remote_addr.v6, sizeof(masked)))
3098
			return (1);
3099
		return (0);
3100
	}
3101
	return (0);
3102
}
3103
3104
struct peer *
3105
getpeerbyid(u_int32_t peerid)
3106
{
3107
	struct peer *p;
3108
3109
	/* we might want a more effective way to find peers by IP */
3110
	for (p = peers; p != NULL &&
3111
	    p->conf.id != peerid; p = p->next)
3112
		;	/* nothing */
3113
3114
	return (p);
3115
}
3116
3117
void
3118
session_down(struct peer *peer)
3119
{
3120
	bzero(&peer->capa.neg, sizeof(peer->capa.neg));
3121
	peer->stats.last_updown = time(NULL);
3122
	if (imsg_compose(ibuf_rde, IMSG_SESSION_DOWN, peer->conf.id, 0, -1,
3123
	    NULL, 0) == -1)
3124
		fatalx("imsg_compose error");
3125
}
3126
3127
void
3128
session_up(struct peer *p)
3129
{
3130
	struct session_up	 sup;
3131
3132
	if (imsg_compose(ibuf_rde, IMSG_SESSION_ADD, p->conf.id, 0, -1,
3133
	    &p->conf, sizeof(p->conf)) == -1)
3134
		fatalx("imsg_compose error");
3135
3136
	sa2addr((struct sockaddr *)&p->sa_local, &sup.local_addr);
3137
	sa2addr((struct sockaddr *)&p->sa_remote, &sup.remote_addr);
3138
3139
	sup.remote_bgpid = p->remote_bgpid;
3140
	sup.short_as = p->short_as;
3141
	memcpy(&sup.capa, &p->capa.neg, sizeof(sup.capa));
3142
	p->stats.last_updown = time(NULL);
3143
	if (imsg_compose(ibuf_rde, IMSG_SESSION_UP, p->conf.id, 0, -1,
3144
	    &sup, sizeof(sup)) == -1)
3145
		fatalx("imsg_compose error");
3146
}
3147
3148
int
3149
imsg_ctl_parent(int type, u_int32_t peerid, pid_t pid, void *data,
3150
    u_int16_t datalen)
3151
{
3152
	return (imsg_compose(ibuf_main, type, peerid, pid, -1, data, datalen));
3153
}
3154
3155
int
3156
imsg_ctl_rde(int type, pid_t pid, void *data, u_int16_t datalen)
3157
{
3158
	/*
3159
	 * Use control socket to talk to RDE to bypass the queue of the
3160
	 * regular imsg socket.
3161
	 */
3162
	return (imsg_compose(ibuf_rde_ctl, type, 0, pid, -1, data, datalen));
3163
}
3164
3165
void
3166
session_demote(struct peer *p, int level)
3167
{
3168
	struct demote_msg	msg;
3169
3170
	strlcpy(msg.demote_group, p->conf.demote_group,
3171
	    sizeof(msg.demote_group));
3172
	msg.level = level;
3173
	if (imsg_compose(ibuf_main, IMSG_DEMOTE, p->conf.id, 0, -1,
3174
	    &msg, sizeof(msg)) == -1)
3175
		fatalx("imsg_compose error");
3176
3177
	p->demoted += level;
3178
}
3179
3180
void
3181
session_stop(struct peer *peer, u_int8_t subcode)
3182
{
3183
	switch (peer->state) {
3184
	case STATE_OPENSENT:
3185
	case STATE_OPENCONFIRM:
3186
	case STATE_ESTABLISHED:
3187
		session_notification(peer, ERR_CEASE, subcode, NULL, 0);
3188
		break;
3189
	default:
3190
		/* session not open, no need to send notification */
3191
		break;
3192
	}
3193
	bgp_fsm(peer, EVNT_STOP);
3194
}