This diff changes a bit the way tcp md5sum (and ike) is setup.
The big change is that the pfkey handling is moved from the session engine
to the parent process. In a later step this should allow to no longer
distribute autentication data to the unprivileged childs (but this is not
done yet since this diff is already big enough).
The reloading of pfkey info is changed a bit (it is now done more often
since it will trigger whenever a session is in state idle or active) and
should hopefully help when you change tcp md5sum settings in your config.
As before bgpd will not reload pfkey on running sessions so after a bgpctl
reload you may want to bgpctl nei foo clear the sessions you want to
refresh but in general the regular timeout mechanisms will kick in and do
the same. In my testing this works great but please give this also a spin
and report any problems you can find.
--
:wq Claudio
Index: bgpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.c,v
retrieving revision 1.215
diff -u -p -r1.215 bgpd.c
--- bgpd.c 31 Mar 2019 16:57:38 -0000 1.215
+++ bgpd.c 4 May 2019 13:05:06 -0000
@@ -91,7 +91,8 @@ usage(void)
#define PFD_PIPE_SESSION 0
#define PFD_PIPE_ROUTE 1
#define PFD_SOCK_ROUTE 2
-#define POLL_MAX 3
+#define PFD_SOCK_PFKEY 3
+#define POLL_MAX 4
#define MAX_TIMEOUT 3600
int cmd_opts;
@@ -101,6 +102,7 @@ main(int argc, char *argv[])
{
struct bgpd_config *conf;
struct rde_rib *rr;
+ struct peer *p;
struct pollfd pfd[POLL_MAX];
time_t timeout;
pid_t se_pid = 0, rde_pid = 0, pid;
@@ -108,7 +110,7 @@ main(int argc, char *argv[])
char *saved_argv0;
int debug = 0;
int rflag = 0, sflag = 0;
- int rfd = -1;
+ int rfd, keyfd;
int ch, status;
int pipe_m2s[2];
int pipe_m2r[2];
@@ -229,6 +231,7 @@ main(int argc, char *argv[])
mrt_init(ibuf_rde, ibuf_se);
if ((rfd = kr_init()) == -1)
quit = 1;
+ keyfd = pfkey_init();
/*
* rpath, read config file
@@ -264,6 +267,9 @@ BROKEN if (pledge("stdio rpath wpath cpa
pfd[PFD_SOCK_ROUTE].fd = rfd;
pfd[PFD_SOCK_ROUTE].events = POLLIN;
+ pfd[PFD_SOCK_PFKEY].fd = keyfd;
+ pfd[PFD_SOCK_PFKEY].events = POLLIN;
+
set_pollfd(&pfd[PFD_PIPE_SESSION], ibuf_se);
set_pollfd(&pfd[PFD_PIPE_ROUTE], ibuf_rde);
@@ -304,6 +310,13 @@ BROKEN if (pledge("stdio rpath wpath cpa
quit = 1;
}
+ if (pfd[PFD_SOCK_PFKEY].revents & POLLIN) {
+ if (pfkey_read(keyfd, NULL) == -1) {
+ log_warnx("pfkey_read failed, exiting...");
+ quit = 1;
+ }
+ }
+
if (reconfig) {
u_int error;
@@ -349,15 +362,18 @@ BROKEN if (pledge("stdio rpath wpath cpa
ibuf_rde = NULL;
}
- while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) {
- SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
- free(rr);
- }
-
+ /* cleanup kernel data structures */
carp_demote_shutdown();
kr_shutdown(conf->fib_priority, conf->default_tableid);
pftable_clear_all();
+ TAILQ_FOREACH(p, &conf->peers, entry)
+ pfkey_remove(p);
+
+ while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) {
+ SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
+ free(rr);
+ }
free_config(conf);
log_debug("waiting for children to terminate");
@@ -520,6 +536,10 @@ reconfigure(char *conffile, struct bgpd_
if (imsg_compose(ibuf_se, IMSG_RECONF_PEER, p->conf.id, 0, -1,
&p->conf, sizeof(struct peer_config)) == -1)
return (-1);
+
+ if (p->reconf_action == RECONF_REINIT)
+ if (pfkey_establish(p) == -1)
+ log_peer_warnx(&p->conf, "pfkey setup failed");
}
/* networks go via kroute to the RDE */
@@ -690,6 +710,7 @@ int
dispatch_imsg(struct imsgbuf *ibuf, int idx, struct bgpd_config *conf)
{
struct imsg imsg;
+ struct peer *p;
ssize_t n;
int rv, verbose;
@@ -765,11 +786,25 @@ dispatch_imsg(struct imsgbuf *ibuf, int
case IMSG_PFTABLE_COMMIT:
if (idx != PFD_PIPE_ROUTE)
log_warnx("pftable request not from RDE");
- else
- if (imsg.hdr.len != IMSG_HEADER_SIZE)
- log_warnx("wrong imsg len");
- else if (pftable_commit() != 0)
- rv = -1;
+ else if (imsg.hdr.len != IMSG_HEADER_SIZE)
+ log_warnx("wrong imsg len");
+ else if (pftable_commit() != 0)
+ rv = -1;
+ break;
+ case IMSG_PFKEY_RELOAD:
+ if (idx != PFD_PIPE_SESSION)
+ log_warnx("pfkey reload request not from SE");
+ else if ((p = getpeerbyid(conf, imsg.hdr.peerid)) ==
+ NULL)
+ log_warnx("pfkey reload: no such peer: id=%u",
+ imsg.hdr.peerid);
+ else {
+ pfkey_remove(p);
+ if (pfkey_establish(p) == -1) {
+ log_peer_warnx(&p->conf,
+ "pfkey setup failed");
+ }
+ }
break;
case IMSG_CTL_RELOAD:
if (idx != PFD_PIPE_SESSION)
Index: bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.381
diff -u -p -r1.381 bgpd.h
--- bgpd.h 3 May 2019 15:25:47 -0000 1.381
+++ bgpd.h 4 May 2019 11:45:39 -0000
@@ -492,6 +492,7 @@ enum imsg_type {
IMSG_SESSION_STALE,
IMSG_SESSION_FLUSH,
IMSG_SESSION_RESTARTED,
+ IMSG_PFKEY_RELOAD,
IMSG_MRT_OPEN,
IMSG_MRT_REOPEN,
IMSG_MRT_CLOSE,
Index: config.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/config.c,v
retrieving revision 1.87
diff -u -p -r1.87 config.c
--- config.c 31 Mar 2019 16:57:38 -0000 1.87
+++ config.c 4 May 2019 13:02:53 -0000
@@ -318,8 +318,11 @@ merge_config(struct bgpd_config *xconf,
p->reconf_action = RECONF_REINIT;
while ((p = TAILQ_FIRST(&xconf->peers)) != NULL) {
np = getpeerbyid(conf, p->conf.id);
- if (np != NULL)
+ if (np != NULL) {
np->reconf_action = RECONF_KEEP;
+ /* copy the auth state since parent uses it */
+ np->auth = p->auth;
+ }
TAILQ_REMOVE(&xconf->peers, p, entry);
free(p);
Index: pfkey.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/pfkey.c,v
retrieving revision 1.54
diff -u -p -r1.54 pfkey.c
--- pfkey.c 20 Feb 2019 16:29:01 -0000 1.54
+++ pfkey.c 4 May 2019 13:03:35 -0000
@@ -22,6 +22,8 @@
#include <sys/uio.h>
#include <net/pfkeyv2.h>
#include <netinet/ip_ipsp.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
@@ -33,13 +35,15 @@
#include "session.h"
#include "log.h"
+extern struct bgpd_sysdep sysdep;
+
#define PFKEY2_CHUNK sizeof(u_int64_t)
#define ROUNDUP(x) (((x) + (PFKEY2_CHUNK - 1)) & ~(PFKEY2_CHUNK - 1))
#define IOV_CNT 20
static u_int32_t sadb_msg_seq = 0;
static u_int32_t pid = 0; /* should pid_t but pfkey needs u_int32_t */
-static int fd;
+static int pfkey_fd;
int pfkey_reply(int, u_int32_t *);
int pfkey_send(int, uint8_t, uint8_t, uint8_t,
@@ -502,15 +506,15 @@ int
pfkey_sa_add(struct bgpd_addr *src, struct bgpd_addr *dst, u_int8_t keylen,
char *key, u_int32_t *spi)
{
- if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_GETSPI, 0,
+ if (pfkey_send(pfkey_fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_GETSPI, 0,
src, dst, 0, 0, 0, NULL, 0, 0, NULL, 0, 0) < 0)
return (-1);
- if (pfkey_reply(fd, spi) < 0)
+ if (pfkey_reply(pfkey_fd, spi) < 0)
return (-1);
- if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_UPDATE, 0,
+ if (pfkey_send(pfkey_fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_UPDATE, 0,
src, dst, *spi, 0, keylen, key, 0, 0, NULL, 0, 0) < 0)
return (-1);
- if (pfkey_reply(fd, NULL) < 0)
+ if (pfkey_reply(pfkey_fd, NULL) < 0)
return (-1);
return (0);
}
@@ -518,10 +522,10 @@ pfkey_sa_add(struct bgpd_addr *src, stru
int
pfkey_sa_remove(struct bgpd_addr *src, struct bgpd_addr *dst, u_int32_t *spi)
{
- if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_DELETE, 0,
+ if (pfkey_send(pfkey_fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_DELETE, 0,
src, dst, *spi, 0, 0, NULL, 0, 0, NULL, 0, 0) < 0)
return (-1);
- if (pfkey_reply(fd, NULL) < 0)
+ if (pfkey_reply(pfkey_fd, NULL) < 0)
return (-1);
*spi = 0;
return (0);
@@ -579,7 +583,7 @@ pfkey_ipsec_establish(struct peer *p)
case AUTH_IPSEC_MANUAL_AH:
satype = p->auth.method == AUTH_IPSEC_MANUAL_ESP ?
SADB_SATYPE_ESP : SADB_SATYPE_AH;
- if (pfkey_send(fd, satype, SADB_ADD, 0,
+ if (pfkey_send(pfkey_fd, satype, SADB_ADD, 0,
&p->auth.local_addr, &p->conf.remote_addr,
p->auth.spi_out,
p->conf.auth.auth_alg_out,
@@ -590,9 +594,9 @@ pfkey_ipsec_establish(struct peer *p)
p->conf.auth.enc_key_out,
0, 0) < 0)
return (-1);
- if (pfkey_reply(fd, NULL) < 0)
+ if (pfkey_reply(pfkey_fd, NULL) < 0)
return (-1);
- if (pfkey_send(fd, satype, SADB_ADD, 0,
+ if (pfkey_send(pfkey_fd, satype, SADB_ADD, 0,
&p->conf.remote_addr, &p->auth.local_addr,
p->auth.spi_in,
p->conf.auth.auth_alg_in,
@@ -603,7 +607,7 @@ pfkey_ipsec_establish(struct peer *p)
p->conf.auth.enc_key_in,
0, 0) < 0)
return (-1);
- if (pfkey_reply(fd, NULL) < 0)
+ if (pfkey_reply(pfkey_fd, NULL) < 0)
return (-1);
break;
default:
@@ -611,28 +615,28 @@ pfkey_ipsec_establish(struct peer *p)
break;
}
- if (pfkey_flow(fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_OUT,
+ if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_OUT,
&p->auth.local_addr, &p->conf.remote_addr, 0, BGP_PORT) < 0)
return (-1);
- if (pfkey_reply(fd, NULL) < 0)
+ if (pfkey_reply(pfkey_fd, NULL) < 0)
return (-1);
- if (pfkey_flow(fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_OUT,
+ if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_OUT,
&p->auth.local_addr, &p->conf.remote_addr, BGP_PORT, 0) < 0)
return (-1);
- if (pfkey_reply(fd, NULL) < 0)
+ if (pfkey_reply(pfkey_fd, NULL) < 0)
return (-1);
- if (pfkey_flow(fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_IN,
+ if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_IN,
&p->conf.remote_addr, &p->auth.local_addr, 0, BGP_PORT) < 0)
return (-1);
- if (pfkey_reply(fd, NULL) < 0)
+ if (pfkey_reply(pfkey_fd, NULL) < 0)
return (-1);
- if (pfkey_flow(fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_IN,
+ if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_IN,
&p->conf.remote_addr, &p->auth.local_addr, BGP_PORT, 0) < 0)
return (-1);
- if (pfkey_reply(fd, NULL) < 0)
+ if (pfkey_reply(pfkey_fd, NULL) < 0)
return (-1);
p->auth.established = 1;
@@ -655,20 +659,20 @@ pfkey_ipsec_remove(struct peer *p)
case AUTH_IPSEC_MANUAL_AH:
satype = p->auth.method == AUTH_IPSEC_MANUAL_ESP ?
SADB_SATYPE_ESP : SADB_SATYPE_AH;
- if (pfkey_send(fd, satype, SADB_DELETE, 0,
+ if (pfkey_send(pfkey_fd, satype, SADB_DELETE, 0,
&p->auth.local_addr, &p->conf.remote_addr,
p->auth.spi_out, 0, 0, NULL, 0, 0, NULL,
0, 0) < 0)
return (-1);
- if (pfkey_reply(fd, NULL) < 0)
+ if (pfkey_reply(pfkey_fd, NULL) < 0)
return (-1);
- if (pfkey_send(fd, satype, SADB_DELETE, 0,
+ if (pfkey_send(pfkey_fd, satype, SADB_DELETE, 0,
&p->conf.remote_addr, &p->auth.local_addr,
p->auth.spi_in, 0, 0, NULL, 0, 0, NULL,
0, 0) < 0)
return (-1);
- if (pfkey_reply(fd, NULL) < 0)
+ if (pfkey_reply(pfkey_fd, NULL) < 0)
return (-1);
break;
default:
@@ -676,28 +680,28 @@ pfkey_ipsec_remove(struct peer *p)
break;
}
- if (pfkey_flow(fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_OUT,
+ if (pfkey_flow(pfkey_fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_OUT,
&p->auth.local_addr, &p->conf.remote_addr, 0, BGP_PORT) < 0)
return (-1);
- if (pfkey_reply(fd, NULL) < 0)
+ if (pfkey_reply(pfkey_fd, NULL) < 0)
return (-1);
- if (pfkey_flow(fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_OUT,
+ if (pfkey_flow(pfkey_fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_OUT,
&p->auth.local_addr, &p->conf.remote_addr, BGP_PORT, 0) < 0)
return (-1);
- if (pfkey_reply(fd, NULL) < 0)
+ if (pfkey_reply(pfkey_fd, NULL) < 0)
return (-1);
- if (pfkey_flow(fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_IN,
+ if (pfkey_flow(pfkey_fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_IN,
&p->conf.remote_addr, &p->auth.local_addr, 0, BGP_PORT) < 0)
return (-1);
- if (pfkey_reply(fd, NULL) < 0)
+ if (pfkey_reply(pfkey_fd, NULL) < 0)
return (-1);
- if (pfkey_flow(fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_IN,
+ if (pfkey_flow(pfkey_fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_IN,
&p->conf.remote_addr, &p->auth.local_addr, BGP_PORT, 0) < 0)
return (-1);
- if (pfkey_reply(fd, NULL) < 0)
+ if (pfkey_reply(pfkey_fd, NULL) < 0)
return (-1);
p->auth.established = 0;
@@ -740,16 +744,78 @@ pfkey_remove(struct peer *p)
}
int
-pfkey_init(struct bgpd_sysdep *sysdep)
+pfkey_init(void)
{
- if ((fd = socket(PF_KEY, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
+ if ((pfkey_fd = socket(PF_KEY, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
PF_KEY_V2)) == -1) {
if (errno == EPROTONOSUPPORT) {
log_warnx("PF_KEY not available, disabling ipsec");
- sysdep->no_pfkey = 1;
return (-1);
} else
fatal("pfkey setup failed");
}
- return (fd);
+ return (pfkey_fd);
+}
+
+int
+tcp_md5_check(int fd, struct peer *p)
+{
+ socklen_t len;
+ int opt;
+
+ if (p->conf.auth.method == AUTH_MD5SIG) {
+ if (sysdep.no_md5sig) {
+ log_peer_warnx(&p->conf,
+ "md5sig configured but not available");
+ return -1;
+ }
+ len = sizeof(opt);
+ if (getsockopt(fd, IPPROTO_TCP, TCP_MD5SIG,
+ &opt, &len) == -1)
+ fatal("getsockopt TCP_MD5SIG");
+ if (!opt) { /* non-md5'd connection! */
+ log_peer_warnx(&p->conf,
+ "connection attempt without md5 signature");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int
+tcp_md5_set(int fd, struct peer *p)
+{
+ int opt = 1;
+
+ if (p->conf.auth.method == AUTH_MD5SIG) {
+ if (sysdep.no_md5sig) {
+ log_peer_warnx(&p->conf,
+ "md5sig configured but not available");
+ return -1;
+ }
+ if (setsockopt(fd, IPPROTO_TCP, TCP_MD5SIG,
+ &opt, sizeof(opt)) == -1) {
+ log_peer_warn(&p->conf, "setsockopt md5sig");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+int
+tcp_md5_listen(int fd, struct peer_head *p)
+{
+ int opt = 1;
+
+ if (setsockopt(fd, IPPROTO_TCP, TCP_MD5SIG,
+ &opt, sizeof(opt)) == -1) {
+ if (errno == ENOPROTOOPT) { /* system w/o md5sig */
+ log_warnx("md5sig not available, disabling");
+ sysdep.no_md5sig = 1;
+ return 0;
+ }
+ return -1;
+ }
+ return 0;
}
Index: session.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
retrieving revision 1.379
diff -u -p -r1.379 session.c
--- session.c 25 Apr 2019 12:12:16 -0000 1.379
+++ session.c 4 May 2019 13:01:47 -0000
@@ -52,8 +52,7 @@
#define PFD_PIPE_ROUTE_CTL 2
#define PFD_SOCK_CTL 3
#define PFD_SOCK_RCTL 4
-#define PFD_SOCK_PFKEY 5
-#define PFD_LISTENERS_START 6
+#define PFD_LISTENERS_START 5
void session_sighdlr(int);
int setup_listeners(u_int *);
@@ -129,7 +128,6 @@ int
setup_listeners(u_int *la_cnt)
{
int ttl = 255;
- int opt;
struct listen_addr *la;
u_int cnt = 0;
@@ -147,15 +145,8 @@ setup_listeners(u_int *la_cnt)
continue;
}
- opt = 1;
- if (setsockopt(la->fd, IPPROTO_TCP, TCP_MD5SIG,
- &opt, sizeof(opt)) == -1) {
- if (errno == ENOPROTOOPT) { /* system w/o md5sig */
- log_warnx("md5sig not available, disabling");
- sysdep.no_md5sig = 1;
- } else
- fatal("setsockopt TCP_MD5SIG");
- }
+ if (tcp_md5_listen(la->fd, &conf->peers) == -1)
+ fatal("tcp_md5_listen");
/* set ttl to 255 so that ttl-security works */
if (la->sa.ss_family == AF_INET && setsockopt(la->fd,
@@ -188,7 +179,7 @@ setup_listeners(u_int *la_cnt)
void
session_main(int debug, int verbose)
{
- int timeout, pfkeysock;
+ int timeout;
unsigned int i, j, idx_peers, idx_listeners, idx_mrts;
u_int pfd_elms = 0, peer_l_elms = 0, mrt_l_elms = 0;
u_int listener_cnt, ctl_cnt, mrt_cnt;
@@ -217,7 +208,6 @@ session_main(int debug, int verbose)
fatal("chdir(\"/\")");
setproctitle("session engine");
- pfkeysock = pfkey_init(&sysdep);
if (setgroups(1, &pw->pw_gid) ||
setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
@@ -355,8 +345,6 @@ session_main(int debug, int verbose)
pfd[PFD_SOCK_CTL].fd = -1;
pfd[PFD_SOCK_RCTL].fd = -1;
}
- pfd[PFD_SOCK_PFKEY].fd = pfkeysock;
- pfd[PFD_SOCK_PFKEY].events = POLLIN;
i = PFD_LISTENERS_START;
TAILQ_FOREACH(la, conf->listen_addrs, entry) {
@@ -506,13 +494,6 @@ session_main(int debug, int verbose)
if (pfd[PFD_SOCK_RCTL].revents & POLLIN)
ctl_cnt += control_accept(rcsock, 1);
- if (pfd[PFD_SOCK_PFKEY].revents & POLLIN) {
- if (pfkey_read(pfkeysock, NULL) == -1) {
- log_warnx("pfkey_read failed, exiting...");
- session_quit = 1;
- }
- }
-
for (j = PFD_LISTENERS_START; j < idx_listeners; j++)
if (pfd[j].revents & POLLIN)
session_accept(pfd[j].fd);
@@ -540,7 +521,6 @@ session_main(int debug, int verbose)
sizeof(p->conf.shutcomm));
session_stop(p, ERR_CEASE_ADMIN_DOWN);
timer_remove_all(p);
- pfkey_remove(p);
free(p);
}
@@ -629,14 +609,6 @@ bgp_fsm(struct peer *peer, enum session_
/* init write buffer */
msgbuf_init(&peer->wbuf);
- /* init pfkey - remove old if any, load new ones */
- pfkey_remove(peer);
- if (pfkey_establish(peer) == -1) {
- log_peer_warnx(&peer->conf,
- "pfkey setup failed");
- return;
- }
-
peer->stats.last_sent_errcode = 0;
peer->stats.last_sent_suberr = 0;
@@ -909,6 +881,9 @@ change_state(struct peer *peer, enum ses
free(peer->rbuf);
peer->rbuf = NULL;
bzero(&peer->capa.peer, sizeof(peer->capa.peer));
+ if (!peer->template)
+ imsg_compose(ibuf_main, IMSG_PFKEY_RELOAD,
+ peer->conf.id, 0, -1, NULL, 0);
if (event != EVNT_STOP) {
timer_set(peer, Timer_IdleHold, peer->IdleHoldTime);
@@ -953,6 +928,9 @@ change_state(struct peer *peer, enum ses
}
break;
case STATE_ACTIVE:
+ if (!peer->template)
+ imsg_compose(ibuf_main, IMSG_PFKEY_RELOAD,
+ peer->conf.id, 0, -1, NULL, 0);
break;
case STATE_OPENSENT:
break;
@@ -986,7 +964,6 @@ void
session_accept(int listenfd)
{
int connfd;
- int opt;
socklen_t len;
struct sockaddr_storage cliaddr;
struct peer *p = NULL;
@@ -1032,23 +1009,9 @@ open:
return;
}
- if (p->conf.auth.method == AUTH_MD5SIG) {
- if (sysdep.no_md5sig) {
- log_peer_warnx(&p->conf,
- "md5sig configured but not available");
- close(connfd);
- return;
- }
- len = sizeof(opt);
- if (getsockopt(connfd, IPPROTO_TCP, TCP_MD5SIG,
- &opt, &len) == -1)
- fatal("getsockopt TCP_MD5SIG");
- if (!opt) { /* non-md5'd connection! */
- log_peer_warnx(&p->conf,
- "connection attempt without md5 signature");
- close(connfd);
- return;
- }
+ if (tcp_md5_check(connfd, p) == -1) {
+ close(connfd);
+ return;
}
p->fd = p->wbuf.fd = connfd;
if (session_setup_socket(p)) {
@@ -1072,7 +1035,6 @@ open:
int
session_connect(struct peer *peer)
{
- int opt = 1;
struct sockaddr *sa;
socklen_t sa_len;
@@ -1098,20 +1060,7 @@ session_connect(struct peer *peer)
return (-1);
}
- if (peer->conf.auth.method == AUTH_MD5SIG) {
- if (sysdep.no_md5sig) {
- log_peer_warnx(&peer->conf,
- "md5sig configured but not available");
- bgp_fsm(peer, EVNT_CON_OPENFAIL);
- return (-1);
- }
- if (setsockopt(peer->fd, IPPROTO_TCP, TCP_MD5SIG,
- &opt, sizeof(opt)) == -1) {
- log_peer_warn(&peer->conf, "setsockopt md5sig");
- bgp_fsm(peer, EVNT_CON_OPENFAIL);
- return (-1);
- }
- }
+ tcp_md5_set(peer->fd, peer);
peer->wbuf.fd = peer->fd;
/* if update source is set we need to bind() */
@@ -3238,6 +3187,11 @@ merge_peers(struct bgpd_config *c, struc
if (p->demoted && !p->conf.demote_group[0])
session_demote(p, -1);
+ /* if session is not open then refresh pfkey data */
+ if (p->state < STATE_OPENSENT && !p->template)
+ imsg_compose(ibuf_main, IMSG_PFKEY_RELOAD,
+ p->conf.id, 0, -1, NULL, 0);
+
/* sync the RDE in case we keep the peer */
if (imsg_rde(IMSG_SESSION_ADD, p->conf.id,
&p->conf, sizeof(struct peer_config)) == -1)
@@ -3258,5 +3212,6 @@ merge_peers(struct bgpd_config *c, struc
}
}
+ /* pfkeys of new peers already loaded by the parent process */
TAILQ_CONCAT(&c->peers, &nc->peers, entry);
}
Index: session.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.h,v
retrieving revision 1.136
diff -u -p -r1.136 session.h
--- session.h 7 Apr 2019 10:52:30 -0000 1.136
+++ session.h 4 May 2019 12:42:54 -0000
@@ -282,7 +282,10 @@ struct bgpd_config *parse_config(char *,
int pfkey_read(int, struct sadb_msg *);
int pfkey_establish(struct peer *);
int pfkey_remove(struct peer *);
-int pfkey_init(struct bgpd_sysdep *);
+int pfkey_init(void);
+int tcp_md5_check(int, struct peer *);
+int tcp_md5_set(int, struct peer *);
+int tcp_md5_listen(int, struct peer_head *);
/* printconf.c */
void print_config(struct bgpd_config *, struct rib_names *);