Download raw body.
bgpd: rework pfkey (ipsec/tcpmd5) code
This diff reworks the pfkey code to handle ipsec and tcpmd5 to be
independent of struct peer. Instead use struct auth_config and struct
auth_state. Make sure the auth_config (which includes the secrets, remains
in the parent (apart from -portable where Linux needs the md5 keys in the
SE to work)). Only the auth_config method is shared with the SE since it
is needed to turn on the TCP_MD5SIG socketopts.
By spliting the auth_config out of peer_config the sharing can be better
controlled. To be extra sure adjust the control_imsg_relay() function to
double clear the buffer so it is not sent to any bgpctl tool.
There is more work to do here but lets start with this since it is already
long enough :) This still passes the md5 regress test. I did not try ipsec
yet but is actually anyone using this?
--
:wq Claudio
Index: bgpctl/output.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/output.c,v
diff -u -p -r1.54 output.c
--- bgpctl/output.c 20 Aug 2024 12:00:20 -0000 1.54
+++ bgpctl/output.c 27 Sep 2024 14:54:55 -0000
@@ -302,7 +302,7 @@ show_neighbor_full(struct peer *p, struc
ina.s_addr = htonl(p->remote_bgpid);
printf(" BGP version 4, remote router-id %s",
inet_ntoa(ina));
- printf("%s\n", fmt_auth_method(p->auth.method));
+ printf("%s\n", fmt_auth_method(p->auth_state.method));
}
printf(" BGP state = %s", statenames[p->state]);
if (p->conf.down) {
Index: bgpctl/output_json.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/output_json.c,v
diff -u -p -r1.46 output_json.c
--- bgpctl/output_json.c 14 Aug 2024 19:10:51 -0000 1.46
+++ bgpctl/output_json.c 27 Sep 2024 14:54:55 -0000
@@ -240,9 +240,9 @@ json_neighbor_full(struct peer *p)
json_do_uint("max_out_prefix_restart",
p->conf.max_out_prefix_restart);
}
- if (p->auth.method != AUTH_NONE)
+ if (p->auth_state.method != AUTH_NONE)
json_do_string("authentication",
- fmt_auth_method(p->auth.method));
+ fmt_auth_method(p->auth_state.method));
json_do_bool("ttl_security", p->conf.ttlsec);
json_do_uint("holdtime", p->conf.holdtime);
json_do_uint("min_holdtime", p->conf.min_holdtime);
Index: bgpd/bgpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.c,v
diff -u -p -r1.267 bgpd.c
--- bgpd/bgpd.c 4 Sep 2024 15:06:36 -0000 1.267
+++ bgpd/bgpd.c 27 Sep 2024 14:54:23 -0000
@@ -467,7 +467,7 @@ BROKEN if (pledge("stdio rpath wpath cpa
pftable_clear_all();
RB_FOREACH(p, peer_head, &conf->peers)
- pfkey_remove(p);
+ pfkey_remove(&p->auth_state);
while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) {
SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
@@ -651,9 +651,12 @@ send_config(struct bgpd_config *conf)
if (imsg_compose(ibuf_se, IMSG_RECONF_PEER, p->conf.id, 0, -1,
&p->conf, sizeof(p->conf)) == -1)
return (-1);
+ if (pfkey_send_conf(ibuf_se, p->conf.id, &p->auth_conf) == -1)
+ return (-1);
if (p->reconf_action == RECONF_REINIT)
- if (pfkey_establish(p) == -1)
+ if (pfkey_establish(&p->auth_state, &p->auth_conf,
+ session_localaddr(p), &p->conf.remote_addr) == -1)
log_peer_warnx(&p->conf, "pfkey setup failed");
}
@@ -943,7 +946,9 @@ dispatch_imsg(struct imsgbuf *imsgbuf, i
}
p = getpeerbyid(conf, imsg_get_id(&imsg));
if (p != NULL) {
- if (pfkey_establish(p) == -1)
+ if (pfkey_establish(&p->auth_state,
+ &p->auth_conf, session_localaddr(p),
+ &p->conf.remote_addr) == -1)
log_peer_warnx(&p->conf,
"pfkey setup failed");
}
Index: bgpd/bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
diff -u -p -r1.496 bgpd.h
--- bgpd/bgpd.h 4 Sep 2024 15:06:36 -0000 1.496
+++ bgpd/bgpd.h 27 Sep 2024 14:54:23 -0000
@@ -379,7 +379,7 @@ enum auth_enc_alg {
AUTH_EALG_AES,
};
-struct peer_auth {
+struct auth_config {
char md5key[TCP_MD5_KEY_LEN];
char auth_key_in[IPSEC_AUTH_KEY_LEN];
char auth_key_out[IPSEC_AUTH_KEY_LEN];
@@ -452,7 +452,6 @@ struct peer_config {
struct bgpd_addr remote_addr;
struct bgpd_addr local_addr_v4;
struct bgpd_addr local_addr_v6;
- struct peer_auth auth;
struct capabilities capabilities;
struct addpath_eval eval;
char group[PEER_DESCR_LEN];
@@ -649,6 +648,7 @@ enum imsg_type {
IMSG_RECONF_CONF,
IMSG_RECONF_RIB,
IMSG_RECONF_PEER,
+ IMSG_RECONF_PEER_AUTH,
IMSG_RECONF_FILTER,
IMSG_RECONF_LISTENER,
IMSG_RECONF_CTRL,
Index: bgpd/config.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/config.c,v
diff -u -p -r1.111 config.c
--- bgpd/config.c 4 Sep 2024 13:30:10 -0000 1.111
+++ bgpd/config.c 27 Sep 2024 14:54:23 -0000
@@ -440,8 +440,8 @@ merge_config(struct bgpd_config *xconf,
np = getpeerbyid(conf, p->conf.id);
if (np != NULL) {
np->reconf_action = RECONF_KEEP;
- /* copy the auth state since parent uses it */
- np->auth = p->auth;
+ /* keep the auth state since parent needs it */
+ np->auth_state = p->auth_state;
RB_REMOVE(peer_head, &xconf->peers, p);
free(p);
@@ -467,7 +467,7 @@ free_deleted_peers(struct bgpd_config *c
RB_FOREACH_SAFE(p, peer_head, &conf->peers, nextp) {
if (p->reconf_action == RECONF_DELETE) {
/* peer no longer exists, clear pfkey state */
- pfkey_remove(p);
+ pfkey_remove(&p->auth_state);
RB_REMOVE(peer_head, &conf->peers, p);
free(p);
}
Index: bgpd/control.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/control.c,v
diff -u -p -r1.118 control.c
--- bgpd/control.c 20 Aug 2024 11:59:39 -0000 1.118
+++ bgpd/control.c 27 Sep 2024 15:03:12 -0000
@@ -544,6 +544,7 @@ control_imsg_relay(struct imsg *imsg, st
/* special handling for peers since only the stats are sent from RDE */
if (type == IMSG_CTL_SHOW_NEIGHBOR) {
struct rde_peer_stats stats;
+ struct peer peer;
if (p == NULL) {
log_warnx("%s: no such peer: id=%u", __func__,
@@ -554,20 +555,22 @@ control_imsg_relay(struct imsg *imsg, st
log_warnx("%s: imsg_get_data", __func__);
return (0);
}
- p->stats.prefix_cnt = stats.prefix_cnt;
- p->stats.prefix_out_cnt = stats.prefix_out_cnt;
- p->stats.prefix_rcvd_update = stats.prefix_rcvd_update;
- p->stats.prefix_rcvd_withdraw = stats.prefix_rcvd_withdraw;
- p->stats.prefix_rcvd_eor = stats.prefix_rcvd_eor;
- p->stats.prefix_sent_update = stats.prefix_sent_update;
- p->stats.prefix_sent_withdraw = stats.prefix_sent_withdraw;
- p->stats.prefix_sent_eor = stats.prefix_sent_eor;
- p->stats.pending_update = stats.pending_update;
- p->stats.pending_withdraw = stats.pending_withdraw;
- p->stats.msg_queue_len = msgbuf_queuelen(&p->wbuf);
+ peer = *p;
+ memset(&peer.auth_conf, 0, sizeof(peer.auth_conf));
+ peer.stats.prefix_cnt = stats.prefix_cnt;
+ peer.stats.prefix_out_cnt = stats.prefix_out_cnt;
+ peer.stats.prefix_rcvd_update = stats.prefix_rcvd_update;
+ peer.stats.prefix_rcvd_withdraw = stats.prefix_rcvd_withdraw;
+ peer.stats.prefix_rcvd_eor = stats.prefix_rcvd_eor;
+ peer.stats.prefix_sent_update = stats.prefix_sent_update;
+ peer.stats.prefix_sent_withdraw = stats.prefix_sent_withdraw;
+ peer.stats.prefix_sent_eor = stats.prefix_sent_eor;
+ peer.stats.pending_update = stats.pending_update;
+ peer.stats.pending_withdraw = stats.pending_withdraw;
+ peer.stats.msg_queue_len = msgbuf_queuelen(&p->wbuf);
return imsg_compose(&c->imsgbuf, type, 0, pid, -1,
- p, sizeof(*p));
+ &peer, sizeof(peer));
}
/* if command finished no need to send exit message */
Index: bgpd/parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
diff -u -p -r1.468 parse.y
--- bgpd/parse.y 20 Sep 2024 02:00:46 -0000 1.468
+++ bgpd/parse.y 27 Sep 2024 14:54:23 -0000
@@ -2076,59 +2076,59 @@ peeropts : REMOTEAS as4number {
curpeer->conf.max_out_prefix_restart = $4;
}
| TCP MD5SIG PASSWORD string {
- if (curpeer->conf.auth.method) {
+ if (curpeer->auth_conf.method) {
yyerror("auth method cannot be redefined");
free($4);
YYERROR;
}
- if (strlcpy(curpeer->conf.auth.md5key, $4,
- sizeof(curpeer->conf.auth.md5key)) >=
- sizeof(curpeer->conf.auth.md5key)) {
+ if (strlcpy(curpeer->auth_conf.md5key, $4,
+ sizeof(curpeer->auth_conf.md5key)) >=
+ sizeof(curpeer->auth_conf.md5key)) {
yyerror("tcp md5sig password too long: max %zu",
- sizeof(curpeer->conf.auth.md5key) - 1);
+ sizeof(curpeer->auth_conf.md5key) - 1);
free($4);
YYERROR;
}
- curpeer->conf.auth.method = AUTH_MD5SIG;
- curpeer->conf.auth.md5key_len = strlen($4);
+ curpeer->auth_conf.method = AUTH_MD5SIG;
+ curpeer->auth_conf.md5key_len = strlen($4);
free($4);
}
| TCP MD5SIG KEY string {
- if (curpeer->conf.auth.method) {
+ if (curpeer->auth_conf.method) {
yyerror("auth method cannot be redefined");
free($4);
YYERROR;
}
- if (str2key($4, curpeer->conf.auth.md5key,
- sizeof(curpeer->conf.auth.md5key)) == -1) {
+ if (str2key($4, curpeer->auth_conf.md5key,
+ sizeof(curpeer->auth_conf.md5key)) == -1) {
free($4);
YYERROR;
}
- curpeer->conf.auth.method = AUTH_MD5SIG;
- curpeer->conf.auth.md5key_len = strlen($4) / 2;
+ curpeer->auth_conf.method = AUTH_MD5SIG;
+ curpeer->auth_conf.md5key_len = strlen($4) / 2;
free($4);
}
| IPSEC espah IKE {
- if (curpeer->conf.auth.method) {
+ if (curpeer->auth_conf.method) {
yyerror("auth method cannot be redefined");
YYERROR;
}
if ($2)
- curpeer->conf.auth.method = AUTH_IPSEC_IKE_ESP;
+ curpeer->auth_conf.method = AUTH_IPSEC_IKE_ESP;
else
- curpeer->conf.auth.method = AUTH_IPSEC_IKE_AH;
+ curpeer->auth_conf.method = AUTH_IPSEC_IKE_AH;
}
| IPSEC espah inout SPI NUMBER STRING STRING encspec {
enum auth_alg auth_alg;
uint8_t keylen;
- if (curpeer->conf.auth.method &&
- (((curpeer->conf.auth.spi_in && $3 == 1) ||
- (curpeer->conf.auth.spi_out && $3 == 0)) ||
- ($2 == 1 && curpeer->conf.auth.method !=
+ if (curpeer->auth_conf.method &&
+ (((curpeer->auth_conf.spi_in && $3 == 1) ||
+ (curpeer->auth_conf.spi_out && $3 == 0)) ||
+ ($2 == 1 && curpeer->auth_conf.method !=
AUTH_IPSEC_MANUAL_ESP) ||
- ($2 == 0 && curpeer->conf.auth.method !=
+ ($2 == 0 && curpeer->auth_conf.method !=
AUTH_IPSEC_MANUAL_AH))) {
yyerror("auth method cannot be redefined");
free($6);
@@ -2158,7 +2158,7 @@ peeropts : REMOTEAS as4number {
}
if ($2)
- curpeer->conf.auth.method =
+ curpeer->auth_conf.method =
AUTH_IPSEC_MANUAL_ESP;
else {
if ($8.enc_alg) {
@@ -2167,7 +2167,7 @@ peeropts : REMOTEAS as4number {
free($7);
YYERROR;
}
- curpeer->conf.auth.method =
+ curpeer->auth_conf.method =
AUTH_IPSEC_MANUAL_AH;
}
@@ -2178,37 +2178,37 @@ peeropts : REMOTEAS as4number {
}
if ($3 == 1) {
- if (str2key($7, curpeer->conf.auth.auth_key_in,
- sizeof(curpeer->conf.auth.auth_key_in)) ==
+ if (str2key($7, curpeer->auth_conf.auth_key_in,
+ sizeof(curpeer->auth_conf.auth_key_in)) ==
-1) {
free($7);
YYERROR;
}
- curpeer->conf.auth.spi_in = $5;
- curpeer->conf.auth.auth_alg_in = auth_alg;
- curpeer->conf.auth.enc_alg_in = $8.enc_alg;
- memcpy(&curpeer->conf.auth.enc_key_in,
+ curpeer->auth_conf.spi_in = $5;
+ curpeer->auth_conf.auth_alg_in = auth_alg;
+ curpeer->auth_conf.enc_alg_in = $8.enc_alg;
+ memcpy(&curpeer->auth_conf.enc_key_in,
&$8.enc_key,
- sizeof(curpeer->conf.auth.enc_key_in));
- curpeer->conf.auth.enc_keylen_in =
+ sizeof(curpeer->auth_conf.enc_key_in));
+ curpeer->auth_conf.enc_keylen_in =
$8.enc_key_len;
- curpeer->conf.auth.auth_keylen_in = keylen;
+ curpeer->auth_conf.auth_keylen_in = keylen;
} else {
- if (str2key($7, curpeer->conf.auth.auth_key_out,
- sizeof(curpeer->conf.auth.auth_key_out)) ==
+ if (str2key($7, curpeer->auth_conf.auth_key_out,
+ sizeof(curpeer->auth_conf.auth_key_out)) ==
-1) {
free($7);
YYERROR;
}
- curpeer->conf.auth.spi_out = $5;
- curpeer->conf.auth.auth_alg_out = auth_alg;
- curpeer->conf.auth.enc_alg_out = $8.enc_alg;
- memcpy(&curpeer->conf.auth.enc_key_out,
+ curpeer->auth_conf.spi_out = $5;
+ curpeer->auth_conf.auth_alg_out = auth_alg;
+ curpeer->auth_conf.enc_alg_out = $8.enc_alg;
+ memcpy(&curpeer->auth_conf.enc_key_out,
&$8.enc_key,
- sizeof(curpeer->conf.auth.enc_key_out));
- curpeer->conf.auth.enc_keylen_out =
+ sizeof(curpeer->auth_conf.enc_key_out));
+ curpeer->auth_conf.enc_keylen_out =
$8.enc_key_len;
- curpeer->conf.auth.auth_keylen_out = keylen;
+ curpeer->auth_conf.auth_keylen_out = keylen;
}
free($7);
}
@@ -5073,10 +5073,10 @@ neighbor_consistent(struct peer *p)
}
/* with any form of ipsec local-address is required */
- if ((p->conf.auth.method == AUTH_IPSEC_IKE_ESP ||
- p->conf.auth.method == AUTH_IPSEC_IKE_AH ||
- p->conf.auth.method == AUTH_IPSEC_MANUAL_ESP ||
- p->conf.auth.method == AUTH_IPSEC_MANUAL_AH) &&
+ if ((p->auth_conf.method == AUTH_IPSEC_IKE_ESP ||
+ p->auth_conf.method == AUTH_IPSEC_IKE_AH ||
+ p->auth_conf.method == AUTH_IPSEC_MANUAL_ESP ||
+ p->auth_conf.method == AUTH_IPSEC_MANUAL_AH) &&
local_addr->aid == AID_UNSPEC) {
yyerror("neighbors with any form of IPsec configured "
"need local-address to be specified");
@@ -5084,9 +5084,9 @@ neighbor_consistent(struct peer *p)
}
/* with static keying we need both directions */
- if ((p->conf.auth.method == AUTH_IPSEC_MANUAL_ESP ||
- p->conf.auth.method == AUTH_IPSEC_MANUAL_AH) &&
- (!p->conf.auth.spi_in || !p->conf.auth.spi_out)) {
+ if ((p->auth_conf.method == AUTH_IPSEC_MANUAL_ESP ||
+ p->auth_conf.method == AUTH_IPSEC_MANUAL_AH) &&
+ (!p->auth_conf.spi_in || !p->auth_conf.spi_out)) {
yyerror("with manual keyed IPsec, SPIs and keys "
"for both directions are required");
return (-1);
Index: bgpd/pfkey.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/pfkey.c,v
diff -u -p -r1.68 pfkey.c
--- bgpd/pfkey.c 7 Nov 2022 22:39:13 -0000 1.68
+++ bgpd/pfkey.c 27 Sep 2024 14:54:23 -0000
@@ -45,31 +45,19 @@ static uint32_t sadb_msg_seq = 0;
static uint32_t pid = 0; /* should pid_t but pfkey needs uint32_t */
static int pfkey_fd;
-int pfkey_reply(int, uint32_t *);
-int pfkey_send(int, uint8_t, uint8_t, uint8_t,
- struct bgpd_addr *, struct bgpd_addr *,
- uint32_t, uint8_t, int, char *, uint8_t, int, char *,
- uint16_t, uint16_t);
+static int pfkey_reply(int, uint32_t *);
+static int pfkey_send(int, uint8_t, uint8_t, uint8_t,
+ const struct bgpd_addr *, const struct bgpd_addr *,
+ uint32_t, uint8_t, int, char *, uint8_t, int, char *,
+ uint16_t, uint16_t);
#define pfkey_flow(fd, satype, cmd, dir, from, to, sport, dport) \
pfkey_send(fd, satype, cmd, dir, from, to, \
0, 0, 0, NULL, 0, 0, NULL, sport, dport)
-static struct bgpd_addr *
-pfkey_localaddr(struct peer *p)
-{
- switch (p->conf.remote_addr.aid) {
- case AID_INET:
- return &p->conf.local_addr_v4;
- case AID_INET6:
- return &p->conf.local_addr_v6;
- }
- fatalx("Unknown AID in pfkey_localaddr");
-}
-
-int
+static int
pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir,
- struct bgpd_addr *src, struct bgpd_addr *dst, uint32_t spi,
+ const struct bgpd_addr *src, const struct bgpd_addr *dst, uint32_t spi,
uint8_t aalg, int alen, char *akey, uint8_t ealg, int elen, char *ekey,
uint16_t sport, uint16_t dport)
{
@@ -385,7 +373,7 @@ pfkey_send(int sd, uint8_t satype, uint8
iov[iov_cnt].iov_base = &sa_akey;
iov[iov_cnt].iov_len = sizeof(sa_akey);
iov_cnt++;
- iov[iov_cnt].iov_base = akey;
+ iov[iov_cnt].iov_base = ((void *)akey);
iov[iov_cnt].iov_len = ((alen + 7) / 8) * 8;
smsg.sadb_msg_len += sa_akey.sadb_key_len;
iov_cnt++;
@@ -395,7 +383,7 @@ pfkey_send(int sd, uint8_t satype, uint8
iov[iov_cnt].iov_base = &sa_ekey;
iov[iov_cnt].iov_len = sizeof(sa_ekey);
iov_cnt++;
- iov[iov_cnt].iov_base = ekey;
+ iov[iov_cnt].iov_base = ((void *)ekey);
iov[iov_cnt].iov_len = ((elen + 7) / 8) * 8;
smsg.sadb_msg_len += sa_ekey.sadb_key_len;
iov_cnt++;
@@ -447,7 +435,7 @@ pfkey_read(int sd, struct sadb_msg *h)
return (1);
}
-int
+static int
pfkey_reply(int sd, uint32_t *spi)
{
struct sadb_msg hdr, *msg;
@@ -511,8 +499,8 @@ pfkey_reply(int sd, uint32_t *spi)
}
static int
-pfkey_sa_add(struct bgpd_addr *src, struct bgpd_addr *dst, uint8_t keylen,
- char *key, uint32_t *spi)
+pfkey_sa_add(const struct bgpd_addr *src, const struct bgpd_addr *dst,
+ uint8_t keylen, char *key, uint32_t *spi)
{
if (pfkey_send(pfkey_fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_GETSPI, 0,
src, dst, 0, 0, 0, NULL, 0, 0, NULL, 0, 0) == -1)
@@ -528,7 +516,8 @@ pfkey_sa_add(struct bgpd_addr *src, stru
}
static int
-pfkey_sa_remove(struct bgpd_addr *src, struct bgpd_addr *dst, uint32_t *spi)
+pfkey_sa_remove(const struct bgpd_addr *src, const struct bgpd_addr *dst,
+ uint32_t *spi)
{
if (pfkey_send(pfkey_fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_DELETE, 0,
src, dst, *spi, 0, 0, NULL, 0, 0, NULL, 0, 0) == -1)
@@ -540,56 +529,54 @@ pfkey_sa_remove(struct bgpd_addr *src, s
}
static int
-pfkey_md5sig_establish(struct peer *p)
+pfkey_md5sig_establish(struct auth_state *as, struct auth_config *auth,
+ const struct bgpd_addr *local_addr, const struct bgpd_addr *remote_addr)
{
uint32_t spi_out = 0;
uint32_t spi_in = 0;
- if (pfkey_sa_add(pfkey_localaddr(p), &p->conf.remote_addr,
- p->conf.auth.md5key_len, p->conf.auth.md5key,
- &spi_out) == -1)
+ if (pfkey_sa_add(local_addr, remote_addr,
+ auth->md5key_len, auth->md5key, &spi_out) == -1)
goto fail;
- if (pfkey_sa_add(&p->conf.remote_addr, pfkey_localaddr(p),
- p->conf.auth.md5key_len, p->conf.auth.md5key,
- &spi_in) == -1)
+ if (pfkey_sa_add(remote_addr, local_addr,
+ auth->md5key_len, auth->md5key, &spi_in) == -1)
goto fail;
/* cleanup old flow if one was present */
- if (p->auth.established) {
- if (pfkey_remove(p) == -1)
+ if (as->established) {
+ if (pfkey_remove(as) == -1)
return (-1);
}
- p->auth.established = 1;
- p->auth.spi_out = spi_out;
- p->auth.spi_in = spi_in;
+ as->established = 1;
+ as->method = auth->method;
+ as->local_addr = *local_addr;
+ as->remote_addr = *remote_addr;
+ as->spi_out = spi_out;
+ as->spi_in = spi_in;
return (0);
fail:
- log_peer_warn(&p->conf, "failed to insert md5sig");
return (-1);
}
static int
-pfkey_md5sig_remove(struct peer *p)
+pfkey_md5sig_remove(struct auth_state *as)
{
- if (p->auth.spi_out)
- if (pfkey_sa_remove(&p->auth.local_addr, &p->conf.remote_addr,
- &p->auth.spi_out) == -1)
+ if (as->spi_out)
+ if (pfkey_sa_remove(&as->local_addr, &as->remote_addr,
+ &as->spi_out) == -1)
goto fail;
- if (p->auth.spi_in)
- if (pfkey_sa_remove(&p->conf.remote_addr, &p->auth.local_addr,
- &p->auth.spi_in) == -1)
+ if (as->spi_in)
+ if (pfkey_sa_remove(&as->remote_addr, &as->local_addr,
+ &as->spi_in) == -1)
goto fail;
- p->auth.established = 0;
- p->auth.spi_out = 0;
- p->auth.spi_in = 0;
+ memset(as, 0, sizeof(*as));
return (0);
fail:
- log_peer_warn(&p->conf, "failed to remove md5sig");
return (-1);
}
@@ -620,18 +607,18 @@ pfkey_enc_alg(enum auth_enc_alg alg)
}
static int
-pfkey_ipsec_establish(struct peer *p)
+pfkey_ipsec_establish(struct auth_state *as, struct auth_config *auth,
+ const struct bgpd_addr *local_addr, const struct bgpd_addr *remote_addr)
{
uint8_t satype = SADB_SATYPE_ESP;
- struct bgpd_addr *local_addr = pfkey_localaddr(p);
/* cleanup first, unlike in the TCP MD5 case */
- if (p->auth.established) {
- if (pfkey_remove(p) == -1)
+ if (as->established) {
+ if (pfkey_remove(as) == -1)
return (-1);
}
- switch (p->auth.method) {
+ switch (auth->method) {
case AUTH_IPSEC_IKE_ESP:
satype = SADB_SATYPE_ESP;
break;
@@ -640,30 +627,30 @@ pfkey_ipsec_establish(struct peer *p)
break;
case AUTH_IPSEC_MANUAL_ESP:
case AUTH_IPSEC_MANUAL_AH:
- satype = p->auth.method == AUTH_IPSEC_MANUAL_ESP ?
+ satype = auth->method == AUTH_IPSEC_MANUAL_ESP ?
SADB_SATYPE_ESP : SADB_SATYPE_AH;
if (pfkey_send(pfkey_fd, satype, SADB_ADD, 0,
- local_addr, &p->conf.remote_addr,
- p->conf.auth.spi_out,
- pfkey_auth_alg(p->conf.auth.auth_alg_out),
- p->conf.auth.auth_keylen_out,
- p->conf.auth.auth_key_out,
- pfkey_enc_alg(p->conf.auth.enc_alg_out),
- p->conf.auth.enc_keylen_out,
- p->conf.auth.enc_key_out,
+ local_addr, remote_addr,
+ auth->spi_out,
+ pfkey_auth_alg(auth->auth_alg_out),
+ auth->auth_keylen_out,
+ auth->auth_key_out,
+ pfkey_enc_alg(auth->enc_alg_out),
+ auth->enc_keylen_out,
+ auth->enc_key_out,
0, 0) == -1)
goto fail_key;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_key;
if (pfkey_send(pfkey_fd, satype, SADB_ADD, 0,
- &p->conf.remote_addr, local_addr,
- p->conf.auth.spi_in,
- pfkey_auth_alg(p->conf.auth.auth_alg_in),
- p->conf.auth.auth_keylen_in,
- p->conf.auth.auth_key_in,
- pfkey_enc_alg(p->conf.auth.enc_alg_in),
- p->conf.auth.enc_keylen_in,
- p->conf.auth.enc_key_in,
+ remote_addr, local_addr,
+ auth->spi_in,
+ pfkey_auth_alg(auth->auth_alg_in),
+ auth->auth_keylen_in,
+ auth->auth_key_in,
+ pfkey_enc_alg(auth->enc_alg_in),
+ auth->enc_keylen_in,
+ auth->enc_key_in,
0, 0) == -1)
goto fail_key;
if (pfkey_reply(pfkey_fd, NULL) == -1)
@@ -674,49 +661,52 @@ pfkey_ipsec_establish(struct peer *p)
}
if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_OUT,
- local_addr, &p->conf.remote_addr, 0, BGP_PORT) == -1)
+ local_addr, remote_addr, 0, BGP_PORT) == -1)
goto fail_flow;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_flow;
if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_OUT,
- local_addr, &p->conf.remote_addr, BGP_PORT, 0) == -1)
+ local_addr, remote_addr, BGP_PORT, 0) == -1)
goto fail_flow;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_flow;
if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_IN,
- &p->conf.remote_addr, local_addr, 0, BGP_PORT) == -1)
+ remote_addr, local_addr, 0, BGP_PORT) == -1)
goto fail_flow;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_flow;
if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_IN,
- &p->conf.remote_addr, local_addr, BGP_PORT, 0) == -1)
+ remote_addr, local_addr, BGP_PORT, 0) == -1)
goto fail_flow;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_flow;
/* save SPI so that they can be removed later on */
- p->auth.spi_in = p->conf.auth.spi_in;
- p->auth.spi_out = p->conf.auth.spi_out;
- p->auth.established = 1;
+ as->established = 1;
+ as->method = auth->method;
+ as->local_addr = *local_addr;
+ as->remote_addr = *remote_addr;
+ as->spi_in = auth->spi_in;
+ as->spi_out = auth->spi_out;
return (0);
fail_key:
- log_peer_warn(&p->conf, "failed to insert ipsec key");
+ log_warn("failed to insert ipsec key");
return (-1);
fail_flow:
- log_peer_warn(&p->conf, "failed to insert ipsec flow");
+ log_warn("failed to insert ipsec flow");
return (-1);
}
static int
-pfkey_ipsec_remove(struct peer *p)
+pfkey_ipsec_remove(struct auth_state *as)
{
uint8_t satype;
- switch (p->auth.method) {
+ switch (as->method) {
case AUTH_IPSEC_IKE_ESP:
satype = SADB_SATYPE_ESP;
break;
@@ -725,20 +715,18 @@ pfkey_ipsec_remove(struct peer *p)
break;
case AUTH_IPSEC_MANUAL_ESP:
case AUTH_IPSEC_MANUAL_AH:
- satype = p->auth.method == AUTH_IPSEC_MANUAL_ESP ?
+ satype = as->method == AUTH_IPSEC_MANUAL_ESP ?
SADB_SATYPE_ESP : SADB_SATYPE_AH;
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) == -1)
+ &as->local_addr, &as->remote_addr,
+ as->spi_out, 0, 0, NULL, 0, 0, NULL, 0, 0) == -1)
goto fail_key;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_key;
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) == -1)
+ &as->remote_addr, &as->local_addr,
+ as->spi_in, 0, 0, NULL, 0, 0, NULL, 0, 0) == -1)
goto fail_key;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_key;
@@ -748,88 +736,75 @@ pfkey_ipsec_remove(struct peer *p)
}
if (pfkey_flow(pfkey_fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_OUT,
- &p->auth.local_addr, &p->conf.remote_addr, 0, BGP_PORT) == -1)
+ &as->local_addr, &as->remote_addr, 0, BGP_PORT) == -1)
goto fail_flow;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_flow;
if (pfkey_flow(pfkey_fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_OUT,
- &p->auth.local_addr, &p->conf.remote_addr, BGP_PORT, 0) == -1)
+ &as->local_addr, &as->remote_addr, BGP_PORT, 0) == -1)
goto fail_flow;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_flow;
if (pfkey_flow(pfkey_fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_IN,
- &p->conf.remote_addr, &p->auth.local_addr, 0, BGP_PORT) == -1)
+ &as->remote_addr, &as->local_addr, 0, BGP_PORT) == -1)
goto fail_flow;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_flow;
if (pfkey_flow(pfkey_fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_IN,
- &p->conf.remote_addr, &p->auth.local_addr, BGP_PORT, 0) == -1)
+ &as->remote_addr, &as->local_addr, BGP_PORT, 0) == -1)
goto fail_flow;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_flow;
- p->auth.established = 0;
- p->auth.spi_out = 0;
- p->auth.spi_in = 0;
+ memset(as, 0, sizeof(*as));
return (0);
fail_key:
- log_peer_warn(&p->conf, "failed to remove ipsec key");
+ log_warn("failed to remove ipsec key");
return (-1);
fail_flow:
- log_peer_warn(&p->conf, "failed to remove ipsec flow");
+ log_warn("failed to remove ipsec flow");
return (-1);
}
int
-pfkey_establish(struct peer *p)
+pfkey_establish(struct auth_state *as, struct auth_config *auth,
+ const struct bgpd_addr *local_addr, const struct bgpd_addr *remote_addr)
{
int rv;
- switch (p->conf.auth.method) {
+ switch (auth->method) {
case AUTH_NONE:
rv = 0;
- if (p->auth.established)
- rv = pfkey_remove(p);
+ if (as->established)
+ rv = pfkey_remove(as);
break;
case AUTH_MD5SIG:
- rv = pfkey_md5sig_establish(p);
+ rv = pfkey_md5sig_establish(as, auth, local_addr, remote_addr);
break;
default:
- rv = pfkey_ipsec_establish(p);
+ rv = pfkey_ipsec_establish(as, auth, local_addr, remote_addr);
break;
}
- /*
- * make sure we keep copies of everything we need to
- * remove SAs and flows later again, even if the
- * info in p->conf changed due to reload.
- * We need: SPIs, method, local_addr, remote_addr.
- * remote_addr cannot change, so no copy, SPI are
- * handled by the method specific functions.
- */
- memcpy(&p->auth.local_addr, pfkey_localaddr(p),
- sizeof(p->auth.local_addr));
- p->auth.method = p->conf.auth.method;
-
return (rv);
}
int
-pfkey_remove(struct peer *p)
+pfkey_remove(struct auth_state *as)
{
- if (p->auth.established == 0)
+ if (as->established == 0)
return (0);
- switch (p->auth.method) {
+ switch (as->method) {
case AUTH_NONE:
return (0);
case AUTH_MD5SIG:
- return (pfkey_md5sig_remove(p));
+ return (pfkey_md5sig_remove(as));
default:
- return (pfkey_ipsec_remove(p));
+ return (pfkey_ipsec_remove(as));
}
}
@@ -847,26 +822,40 @@ pfkey_init(void)
return (pfkey_fd);
}
+int
+pfkey_send_conf(struct imsgbuf *imsgbuf, uint32_t id, struct auth_config *auth)
+{
+ /* SE only needs the auth method */
+ return imsg_compose(imsgbuf, IMSG_RECONF_PEER_AUTH, id, 0, -1,
+ &auth->method, sizeof(auth->method));
+}
+
+int
+pfkey_recv_conf(struct peer *p, struct imsg *imsg)
+{
+ struct auth_config *auth = &p->auth_conf;
+
+ return imsg_get_data(imsg, &auth->method, sizeof(auth->method));
+}
+
/* verify that connection is using TCP MD5UM if required by config */
int
-tcp_md5_check(int fd, struct peer *p)
+tcp_md5_check(int fd, struct auth_config *auth)
{
socklen_t len;
int opt;
- if (p->conf.auth.method == AUTH_MD5SIG) {
+ if (auth->method == AUTH_MD5SIG) {
if (sysdep.no_md5sig) {
- log_peer_warnx(&p->conf,
- "md5sig configured but not available");
+ errno = ENOPROTOOPT;
return -1;
}
len = sizeof(opt);
if (getsockopt(fd, IPPROTO_TCP, TCP_MD5SIG,
&opt, &len) == -1)
- fatal("getsockopt TCP_MD5SIG");
+ return -1;
if (!opt) { /* non-md5'd connection! */
- log_peer_warnx(&p->conf,
- "connection attempt without md5 signature");
+ errno = ECONNREFUSED;
return -1;
}
}
@@ -875,21 +864,18 @@ tcp_md5_check(int fd, struct peer *p)
/* enable or set TCP MD5SIG on a new client connection */
int
-tcp_md5_set(int fd, struct peer *p)
+tcp_md5_set(int fd, struct auth_config *auth, struct bgpd_addr *remote_addr)
{
int opt = 1;
- if (p->conf.auth.method == AUTH_MD5SIG) {
+ if (auth->method == AUTH_MD5SIG) {
if (sysdep.no_md5sig) {
- log_peer_warnx(&p->conf,
- "md5sig configured but not available");
+ errno = ENOPROTOOPT;
return -1;
}
if (setsockopt(fd, IPPROTO_TCP, TCP_MD5SIG,
- &opt, sizeof(opt)) == -1) {
- log_peer_warn(&p->conf, "setsockopt md5sig");
+ &opt, sizeof(opt)) == -1)
return -1;
- }
}
return 0;
}
Index: bgpd/printconf.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v
diff -u -p -r1.174 printconf.c
--- bgpd/printconf.c 14 Aug 2024 19:09:51 -0000 1.174
+++ bgpd/printconf.c 27 Sep 2024 14:54:23 -0000
@@ -45,8 +45,7 @@ void print_originsets(struct prefixset
void print_roa(struct roa_tree *);
void print_aspa(struct aspa_tree *);
void print_rtrs(struct rtr_config_head *);
-void print_peer(struct peer_config *, struct bgpd_config *,
- const char *);
+void print_peer(struct peer *, struct bgpd_config *, const char *);
const char *print_auth_alg(enum auth_alg);
const char *print_enc_alg(enum auth_enc_alg);
void print_announce(struct peer_config *, const char *);
@@ -729,10 +728,12 @@ print_rtrs(struct rtr_config_head *rh)
}
void
-print_peer(struct peer_config *p, struct bgpd_config *conf, const char *c)
+print_peer(struct peer *peer, struct bgpd_config *conf, const char *c)
{
- char *method;
- struct in_addr ina;
+ struct in_addr ina;
+ char *method;
+ struct peer_config *p = &peer->conf;
+ struct auth_config *auth = &peer->auth_conf;
if ((p->remote_addr.aid == AID_INET && p->remote_masklen != 32) ||
(p->remote_addr.aid == AID_INET6 && p->remote_masklen != 128))
@@ -831,30 +832,30 @@ print_peer(struct peer_config *p, struct
if (p->flags & PEERFLAG_LOG_UPDATES)
printf("%s\tlog updates\n", c);
- if (p->auth.method == AUTH_MD5SIG)
+ if (auth->method == AUTH_MD5SIG)
printf("%s\ttcp md5sig\n", c);
- else if (p->auth.method == AUTH_IPSEC_MANUAL_ESP ||
- p->auth.method == AUTH_IPSEC_MANUAL_AH) {
- if (p->auth.method == AUTH_IPSEC_MANUAL_ESP)
+ else if (auth->method == AUTH_IPSEC_MANUAL_ESP ||
+ auth->method == AUTH_IPSEC_MANUAL_AH) {
+ if (auth->method == AUTH_IPSEC_MANUAL_ESP)
method = "esp";
else
method = "ah";
printf("%s\tipsec %s in spi %u %s XXXXXX", c, method,
- p->auth.spi_in, print_auth_alg(p->auth.auth_alg_in));
- if (p->auth.enc_alg_in)
- printf(" %s XXXXXX", print_enc_alg(p->auth.enc_alg_in));
+ auth->spi_in, print_auth_alg(auth->auth_alg_in));
+ if (auth->enc_alg_in)
+ printf(" %s XXXXXX", print_enc_alg(auth->enc_alg_in));
printf("\n");
printf("%s\tipsec %s out spi %u %s XXXXXX", c, method,
- p->auth.spi_out, print_auth_alg(p->auth.auth_alg_out));
- if (p->auth.enc_alg_out)
+ auth->spi_out, print_auth_alg(auth->auth_alg_out));
+ if (auth->enc_alg_out)
printf(" %s XXXXXX",
- print_enc_alg(p->auth.enc_alg_out));
+ print_enc_alg(auth->enc_alg_out));
printf("\n");
- } else if (p->auth.method == AUTH_IPSEC_IKE_AH)
+ } else if (auth->method == AUTH_IPSEC_IKE_AH)
printf("%s\tipsec ah ike\n", c);
- else if (p->auth.method == AUTH_IPSEC_IKE_ESP)
+ else if (auth->method == AUTH_IPSEC_IKE_ESP)
printf("%s\tipsec esp ike\n", c);
if (p->ttlsec)
@@ -1196,39 +1197,36 @@ print_mrt(struct bgpd_config *conf, uint
void
print_groups(struct bgpd_config *conf)
{
- struct peer_config **peerlist;
- struct peer *p;
- u_int peer_cnt, i;
- uint32_t prev_groupid;
- const char *tab = "\t";
- const char *nada = "";
- const char *c;
+ struct peer **peerlist;
+ struct peer *p;
+ u_int peer_cnt, i;
+ uint32_t prev_groupid;
+ const char *c;
peer_cnt = 0;
RB_FOREACH(p, peer_head, &conf->peers)
peer_cnt++;
-
- if ((peerlist = calloc(peer_cnt, sizeof(struct peer_config *))) == NULL)
+ if ((peerlist = calloc(peer_cnt, sizeof(*peerlist))) == NULL)
fatal("print_groups calloc");
-
i = 0;
RB_FOREACH(p, peer_head, &conf->peers)
- peerlist[i++] = &p->conf;
+ peerlist[i++] = p;
- qsort(peerlist, peer_cnt, sizeof(struct peer_config *), peer_compare);
+ qsort(peerlist, peer_cnt, sizeof(*peerlist), peer_compare);
prev_groupid = 0;
for (i = 0; i < peer_cnt; i++) {
- if (peerlist[i]->groupid) {
- c = tab;
- if (peerlist[i]->groupid != prev_groupid) {
+ if (peerlist[i]->conf.groupid) {
+ c = "\t";
+ if (peerlist[i]->conf.groupid != prev_groupid) {
if (prev_groupid)
printf("}\n\n");
- printf("group \"%s\" {\n", peerlist[i]->group);
- prev_groupid = peerlist[i]->groupid;
+ printf("group \"%s\" {\n",
+ peerlist[i]->conf.group);
+ prev_groupid = peerlist[i]->conf.groupid;
}
} else
- c = nada;
+ c = "";
print_peer(peerlist[i], conf, c);
}
@@ -1242,13 +1240,13 @@ print_groups(struct bgpd_config *conf)
int
peer_compare(const void *aa, const void *bb)
{
- const struct peer_config * const *a;
- const struct peer_config * const *b;
+ const struct peer * const *a;
+ const struct peer * const *b;
a = aa;
b = bb;
- return ((*a)->groupid - (*b)->groupid);
+ return ((*a)->conf.groupid - (*b)->conf.groupid);
}
void
Index: bgpd/session.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
diff -u -p -r1.482 session.c
--- bgpd/session.c 9 Sep 2024 12:59:49 -0000 1.482
+++ bgpd/session.c 27 Sep 2024 14:54:23 -0000
@@ -1032,14 +1032,15 @@ session_accept(int listenfd)
}
open:
- if (p->conf.auth.method != AUTH_NONE && sysdep.no_pfkey) {
+ if (p->auth_conf.method != AUTH_NONE && sysdep.no_pfkey) {
log_peer_warnx(&p->conf,
"ipsec or md5sig configured but not available");
close(connfd);
return;
}
- if (tcp_md5_check(connfd, p) == -1) {
+ if (tcp_md5_check(connfd, &p->auth_conf) == -1) {
+ log_peer_warnx(&p->conf, "check md5sig");
close(connfd);
return;
}
@@ -1066,7 +1067,7 @@ int
session_connect(struct peer *peer)
{
struct sockaddr *sa;
- struct bgpd_addr *bind_addr = NULL;
+ struct bgpd_addr *bind_addr;
socklen_t sa_len;
/*
@@ -1084,25 +1085,20 @@ session_connect(struct peer *peer)
return (-1);
}
- if (peer->conf.auth.method != AUTH_NONE && sysdep.no_pfkey) {
+ if (peer->auth_conf.method != AUTH_NONE && sysdep.no_pfkey) {
log_peer_warnx(&peer->conf,
"ipsec or md5sig configured but not available");
bgp_fsm(peer, EVNT_CON_OPENFAIL);
return (-1);
}
- tcp_md5_set(peer->fd, peer);
+ if (tcp_md5_set(peer->fd, &peer->auth_conf,
+ &peer->conf.remote_addr) == -1)
+ log_peer_warn(&peer->conf, "setting md5sig");
peer->wbuf.fd = peer->fd;
/* if local-address is set we need to bind() */
- switch (peer->conf.remote_addr.aid) {
- case AID_INET:
- bind_addr = &peer->conf.local_addr_v4;
- break;
- case AID_INET6:
- bind_addr = &peer->conf.local_addr_v6;
- break;
- }
+ bind_addr = session_localaddr(peer);
if ((sa = addr2sa(bind_addr, 0, &sa_len)) != NULL) {
if (bind(peer->fd, sa, sa_len) == -1) {
log_peer_warn(&peer->conf, "session_connect bind");
@@ -3003,6 +2999,16 @@ session_dispatch_imsg(struct imsgbuf *im
if (RB_INSERT(peer_head, &nconf->peers, p) != NULL)
fatalx("%s: peer tree is corrupt", __func__);
break;
+ case IMSG_RECONF_PEER_AUTH:
+ if (idx != PFD_PIPE_MAIN)
+ fatalx("reconf request not from parent");
+ if ((p = getpeerbyid(nconf, peerid)) == NULL) {
+ log_warnx("no such peer: id=%u", peerid);
+ break;
+ }
+ if (pfkey_recv_conf(p, &imsg) == -1)
+ fatal("pfkey_recv_conf");
+ break;
case IMSG_RECONF_LISTENER:
if (idx != PFD_PIPE_MAIN)
fatalx("reconf request not from parent");
@@ -3641,6 +3647,18 @@ session_stop(struct peer *peer, uint8_t
bgp_fsm(peer, EVNT_STOP);
}
+struct bgpd_addr *
+session_localaddr(struct peer *p)
+{
+ switch (p->conf.remote_addr.aid) {
+ case AID_INET:
+ return &p->conf.local_addr_v4;
+ case AID_INET6:
+ return &p->conf.local_addr_v6;
+ }
+ fatalx("Unknown AID in %s", __func__);
+}
+
void
merge_peers(struct bgpd_config *c, struct bgpd_config *nc)
{
@@ -3657,10 +3675,10 @@ merge_peers(struct bgpd_config *c, struc
}
/* peer no longer uses TCP MD5SIG so deconfigure */
- if (p->conf.auth.method == AUTH_MD5SIG &&
- np->conf.auth.method != AUTH_MD5SIG)
+ if (p->auth_conf.method == AUTH_MD5SIG &&
+ np->auth_conf.method != AUTH_MD5SIG)
tcp_md5_del_listener(c, p);
- else if (np->conf.auth.method == AUTH_MD5SIG)
+ else if (np->auth_conf.method == AUTH_MD5SIG)
tcp_md5_add_listener(c, np);
memcpy(&p->conf, &np->conf, sizeof(p->conf));
@@ -3706,7 +3724,7 @@ merge_peers(struct bgpd_config *c, struc
RB_REMOVE(peer_head, &nc->peers, np);
if (RB_INSERT(peer_head, &c->peers, np) != NULL)
fatalx("%s: peer tree is corrupt", __func__);
- if (np->conf.auth.method == AUTH_MD5SIG)
+ if (np->auth_conf.method == AUTH_MD5SIG)
tcp_md5_add_listener(c, np);
}
}
Index: bgpd/session.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.h,v
diff -u -p -r1.173 session.h
--- bgpd/session.h 4 Sep 2024 13:30:10 -0000 1.173
+++ bgpd/session.h 27 Sep 2024 14:54:23 -0000
@@ -163,6 +163,15 @@ struct peer_stats {
char last_reason[REASON_LEN];
};
+struct auth_state {
+ struct bgpd_addr local_addr;
+ struct bgpd_addr remote_addr;
+ uint32_t spi_in;
+ uint32_t spi_out;
+ enum auth_method method;
+ uint8_t established;
+};
+
enum Timer {
Timer_None,
Timer_ConnectRetry,
@@ -197,13 +206,8 @@ struct peer {
struct capabilities peer;
struct capabilities neg;
} capa;
- struct {
- struct bgpd_addr local_addr;
- uint32_t spi_in;
- uint32_t spi_out;
- enum auth_method method;
- uint8_t established;
- } auth;
+ struct auth_state auth_state;
+ struct auth_config auth_conf;
struct bgpd_addr local;
struct bgpd_addr local_alt;
struct bgpd_addr remote;
@@ -278,11 +282,14 @@ void mrt_done(struct mrt *);
/* pfkey.c */
struct sadb_msg;
int pfkey_read(int, struct sadb_msg *);
-int pfkey_establish(struct peer *);
-int pfkey_remove(struct peer *);
+int pfkey_establish(struct auth_state *, struct auth_config *,
+ const struct bgpd_addr *, const struct bgpd_addr *);
+int pfkey_remove(struct auth_state *);
int pfkey_init(void);
-int tcp_md5_check(int, struct peer *);
-int tcp_md5_set(int, struct peer *);
+int pfkey_send_conf(struct imsgbuf *, uint32_t, struct auth_config *);
+int pfkey_recv_conf(struct peer *, struct imsg *);
+int tcp_md5_check(int, struct auth_config *);
+int tcp_md5_set(int, struct auth_config *, struct bgpd_addr *);
int tcp_md5_prep_listener(struct listen_addr *, struct peer_head *);
void tcp_md5_add_listener(struct bgpd_config *, struct peer *);
void tcp_md5_del_listener(struct bgpd_config *, struct peer *);
@@ -334,6 +341,7 @@ int imsg_ctl_parent(struct imsg *);
int imsg_ctl_rde(struct imsg *);
int imsg_ctl_rde_msg(int, uint32_t, pid_t);
void session_stop(struct peer *, uint8_t, const char *);
+struct bgpd_addr *session_localaddr(struct peer *);
/* timer.c */
struct timer *timer_get(struct timer_head *, enum Timer);
bgpd: rework pfkey (ipsec/tcpmd5) code