Merge branch 'starter-kernel-flush'

Removes flushing of the IPsec state in the kernel when starter
terminates.  We can't easily flush only the policies created for
IPsec SAs (and if installpolicies=no is used we don't want to flush
policies anyway).  Also, since existing policies don't cause errors
anymore these aren't really an issue anymore (I think this was one of
the main reasons to flush the state).  This behavior is also specific to
starter, so nothing is flushed when charon is used via systemd/swanctl.
This will also allow us to merge libhydra with libcharon in a future
release.

If the previous behavior is needed it can easily be replicated with some
external tools (we could also write a simple utility that does this).

Additional checks in the test environment make sure that the daemon
cleans up the state properly.
This commit is contained in:
Tobias Brunner
2015-08-21 18:27:12 +02:00
6 changed files with 71 additions and 34 deletions
@@ -2024,23 +2024,36 @@ METHOD(kernel_ipsec_t, flush_sas, status_t,
netlink_buf_t request;
struct nlmsghdr *hdr;
struct xfrm_usersa_flush *flush;
struct {
u_int8_t proto;
char *name;
} protos[] = {
{ IPPROTO_AH, "AH" },
{ IPPROTO_ESP, "ESP" },
{ IPPROTO_COMP, "IPComp" },
};
int i;
memset(&request, 0, sizeof(request));
DBG2(DBG_KNL, "flushing all SAD entries");
hdr = &request.hdr;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
hdr->nlmsg_type = XFRM_MSG_FLUSHSA;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush));
flush = NLMSG_DATA(hdr);
flush->proto = IPSEC_PROTO_ANY;
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
for (i = 0; i < countof(protos); i++)
{
DBG1(DBG_KNL, "unable to flush SAD entries");
return FAILED;
DBG2(DBG_KNL, "flushing all %s SAD entries", protos[i].name);
flush->proto = protos[i].proto;
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
{
DBG1(DBG_KNL, "unable to flush %s SAD entries", protos[i].name);
return FAILED;
}
}
return SUCCESS;
}
@@ -2086,31 +2086,44 @@ METHOD(kernel_ipsec_t, flush_sas, status_t,
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
struct {
u_int8_t proto;
char *name;
} protos[] = {
{ SADB_SATYPE_AH, "AH" },
{ SADB_SATYPE_ESP, "ESP" },
{ SADB_X_SATYPE_IPCOMP, "IPComp" },
};
size_t len;
int i;
memset(&request, 0, sizeof(request));
DBG2(DBG_KNL, "flushing all SAD entries");
msg = (struct sadb_msg*)request;
msg->sadb_msg_version = PF_KEY_V2;
msg->sadb_msg_type = SADB_FLUSH;
msg->sadb_msg_satype = SADB_SATYPE_UNSPEC;
msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
if (pfkey_send(this, msg, &out, &len) != SUCCESS)
for (i = 0; i < countof(protos); i++)
{
DBG1(DBG_KNL, "unable to flush SAD entries");
return FAILED;
}
else if (out->sadb_msg_errno)
{
DBG1(DBG_KNL, "unable to flush SAD entries: %s (%d)",
strerror(out->sadb_msg_errno), out->sadb_msg_errno);
DBG2(DBG_KNL, "flushing all %s SAD entries", protos[i].name);
msg->sadb_msg_satype = protos[i].proto;
if (pfkey_send(this, msg, &out, &len) != SUCCESS)
{
DBG1(DBG_KNL, "unable to flush %s SAD entries", protos[i].name);
return FAILED;
}
else if (out->sadb_msg_errno)
{
DBG1(DBG_KNL, "unable to flush %s SAD entries: %s (%d)",
protos[i].name, strerror(out->sadb_msg_errno),
out->sadb_msg_errno);
free(out);
return FAILED;
}
free(out);
return FAILED;
}
free(out);
return SUCCESS;
}
-13
View File
@@ -55,16 +55,3 @@ bool starter_netkey_init(void)
DBG2(DBG_APP, "found netkey IPsec stack");
return TRUE;
}
void starter_netkey_cleanup(void)
{
if (!lib->plugins->load(lib->plugins,
lib->settings->get_str(lib->settings, "starter.load", PLUGINS)))
{
DBG1(DBG_APP, "unable to load kernel plugins");
return;
}
hydra->kernel_interface->flush_sas(hydra->kernel_interface);
hydra->kernel_interface->flush_policies(hydra->kernel_interface);
lib->plugins->unload(lib->plugins);
}
-1
View File
@@ -16,7 +16,6 @@
#define _STARTER_NETKEY_H_
extern bool starter_netkey_init (void);
extern void starter_netkey_cleanup (void);
#endif /* _STARTER_NETKEY_H_ */
-1
View File
@@ -703,7 +703,6 @@ int main (int argc, char **argv)
{
starter_stop_charon();
}
starter_netkey_cleanup();
confread_free(cfg);
unlink(starter_pid_file);
cleanup();
+26
View File
@@ -364,6 +364,14 @@ do
ssh $SSHCONF root@`eval echo \\\$ipv4_$host` 'conntrack -F' >/dev/null 2>&1
done
##########################################################################
# flush IPsec state on all hosts
#
for host in $STRONGSWANHOSTS
do
ssh $SSHCONF root@`eval echo \\\$ipv4_$host` 'ip xfrm state flush; ip xfrm policy flush' >/dev/null 2>&1
done
##########################################################################
# execute pre-test commands
@@ -718,6 +726,24 @@ do
}
}' $TESTDIR/posttest.dat` >> $CONSOLE_LOG 2>&1
##########################################################################
# check that IPsec state was cleaned up properly
#
for host in $IPSECHOSTS
do
eval HOSTLOGIN=root@\$ipv4_${host}
IPSECSTATE=`ssh $SSHCONF $HOSTLOGIN 'ip xfrm state'`
IPSECPOLICY=`ssh $SSHCONF $HOSTLOGIN 'ip xfrm policy'`
if [ -n "$IPSECSTATE" -o -n "$IPSECPOLICY" ]
then
echo -e "\n$host# ip xfrm state [NO]" >> $CONSOLE_LOG
echo "$IPSECSTATE" >> $CONSOLE_LOG
echo -e "\n$host# ip xfrm policy [NO]" >> $CONSOLE_LOG
echo "$IPSECPOLICY" >> $CONSOLE_LOG
STATUS="failed"
fi
done
##########################################################################
# get a copy of /var/log/auth.log