summaryrefslogtreecommitdiff
path: root/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c')
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c86
1 files changed, 49 insertions, 37 deletions
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
index d9b55cfa7..dfd71f3bd 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -310,6 +310,12 @@ struct private_kernel_netlink_ipsec_t {
bool install_routes;
/**
+ * Whether to set protocol and ports on selector installed with transport
+ * mode IPsec SAs
+ */
+ bool proto_port_transport;
+
+ /**
* Whether to track the history of a policy
*/
bool policy_history;
@@ -810,7 +816,7 @@ static void process_acquire(private_kernel_netlink_ipsec_t *this,
u_int32_t reqid = 0;
int proto = 0;
- acquire = (struct xfrm_user_acquire*)NLMSG_DATA(hdr);
+ acquire = NLMSG_DATA(hdr);
rta = XFRM_RTA(hdr, struct xfrm_user_acquire);
rtasize = XFRM_PAYLOAD(hdr, struct xfrm_user_acquire);
@@ -856,7 +862,7 @@ static void process_expire(private_kernel_netlink_ipsec_t *this,
u_int32_t spi, reqid;
u_int8_t protocol;
- expire = (struct xfrm_user_expire*)NLMSG_DATA(hdr);
+ expire = NLMSG_DATA(hdr);
protocol = expire->state.id.proto;
spi = expire->state.id.spi;
reqid = expire->state.reqid;
@@ -890,7 +896,7 @@ static void process_migrate(private_kernel_netlink_ipsec_t *this,
u_int32_t reqid = 0;
policy_dir_t dir;
- policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr);
+ policy_id = NLMSG_DATA(hdr);
rta = XFRM_RTA(hdr, struct xfrm_userpolicy_id);
rtasize = XFRM_PAYLOAD(hdr, struct xfrm_userpolicy_id);
@@ -957,7 +963,7 @@ static void process_mapping(private_kernel_netlink_ipsec_t *this,
struct xfrm_user_mapping *mapping;
u_int32_t spi, reqid;
- mapping = (struct xfrm_user_mapping*)NLMSG_DATA(hdr);
+ mapping = NLMSG_DATA(hdr);
spi = mapping->id.spi;
reqid = mapping->reqid;
@@ -1059,12 +1065,12 @@ static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this,
memset(&request, 0, sizeof(request));
- hdr = (struct nlmsghdr*)request;
+ hdr = &request.hdr;
hdr->nlmsg_flags = NLM_F_REQUEST;
hdr->nlmsg_type = XFRM_MSG_ALLOCSPI;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userspi_info));
- userspi = (struct xfrm_userspi_info*)NLMSG_DATA(hdr);
+ userspi = NLMSG_DATA(hdr);
host2xfrm(src, &userspi->info.saddr);
host2xfrm(dst, &userspi->info.id.daddr);
userspi->info.id.proto = proto;
@@ -1208,12 +1214,12 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u} (mark "
"%u/0x%08x)", ntohl(spi), reqid, mark.value, mark.mask);
- hdr = (struct nlmsghdr*)request;
+ hdr = &request.hdr;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
hdr->nlmsg_type = inbound ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info));
- sa = (struct xfrm_usersa_info*)NLMSG_DATA(hdr);
+ sa = NLMSG_DATA(hdr);
host2xfrm(src, &sa->saddr);
host2xfrm(dst, &sa->id.daddr);
sa->id.spi = spi;
@@ -1235,12 +1241,15 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
if (src_ts && dst_ts)
{
sa->sel = ts2selector(src_ts, dst_ts);
- /* don't install proto/port on SA. This would break
- * potential secondary SAs for the same address using a
- * different prot/port. */
- sa->sel.proto = 0;
- sa->sel.dport = sa->sel.dport_mask = 0;
- sa->sel.sport = sa->sel.sport_mask = 0;
+ if (!this->proto_port_transport)
+ {
+ /* don't install proto/port on SA. This would break
+ * potential secondary SAs for the same address using a
+ * different prot/port. */
+ sa->sel.proto = 0;
+ sa->sel.dport = sa->sel.dport_mask = 0;
+ sa->sel.sport = sa->sel.sport_mask = 0;
+ }
}
break;
default:
@@ -1512,7 +1521,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
status = SUCCESS;
failed:
- memwipe(request, sizeof(request));
+ memwipe(&request, sizeof(request));
return status;
}
@@ -1540,12 +1549,12 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,
DBG2(DBG_KNL, "querying replay state from SAD entry with SPI %.8x",
ntohl(spi));
- hdr = (struct nlmsghdr*)request;
+ hdr = &request.hdr;
hdr->nlmsg_flags = NLM_F_REQUEST;
hdr->nlmsg_type = XFRM_MSG_GETAE;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id));
- aevent_id = (struct xfrm_aevent_id*)NLMSG_DATA(hdr);
+ aevent_id = NLMSG_DATA(hdr);
aevent_id->flags = XFRM_AE_RVAL;
host2xfrm(dst, &aevent_id->sa_id.daddr);
@@ -1632,12 +1641,12 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
DBG2(DBG_KNL, "querying SAD entry with SPI %.8x (mark %u/0x%08x)",
ntohl(spi), mark.value, mark.mask);
- hdr = (struct nlmsghdr*)request;
+ hdr = &request.hdr;
hdr->nlmsg_flags = NLM_F_REQUEST;
hdr->nlmsg_type = XFRM_MSG_GETSA;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
- sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
+ sa_id = NLMSG_DATA(hdr);
host2xfrm(dst, &sa_id->daddr);
sa_id->spi = spi;
sa_id->proto = protocol;
@@ -1657,7 +1666,7 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
{
case XFRM_MSG_NEWSA:
{
- sa = (struct xfrm_usersa_info*)NLMSG_DATA(hdr);
+ sa = NLMSG_DATA(hdr);
break;
}
case NLMSG_ERROR:
@@ -1735,12 +1744,12 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x (mark %u/0x%08x)",
ntohl(spi), mark.value, mark.mask);
- hdr = (struct nlmsghdr*)request;
+ hdr = &request.hdr;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
hdr->nlmsg_type = XFRM_MSG_DELSA;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
- sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
+ sa_id = NLMSG_DATA(hdr);
host2xfrm(dst, &sa_id->daddr);
sa_id->spi = spi;
sa_id->proto = protocol;
@@ -1804,12 +1813,12 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
DBG2(DBG_KNL, "querying SAD entry with SPI %.8x for update", ntohl(spi));
/* query the existing SA first */
- hdr = (struct nlmsghdr*)request;
+ hdr = &request.hdr;
hdr->nlmsg_flags = NLM_F_REQUEST;
hdr->nlmsg_type = XFRM_MSG_GETSA;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
- sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
+ sa_id = NLMSG_DATA(hdr);
host2xfrm(dst, &sa_id->daddr);
sa_id->spi = spi;
sa_id->proto = protocol;
@@ -1867,7 +1876,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
DBG2(DBG_KNL, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H",
ntohl(spi), src, dst, new_src, new_dst);
/* copy over the SA from out to request */
- hdr = (struct nlmsghdr*)request;
+ hdr = &request.hdr;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
hdr->nlmsg_type = XFRM_MSG_NEWSA;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info));
@@ -1958,7 +1967,7 @@ failed:
free(replay);
free(replay_esn);
memwipe(out, len);
- memwipe(request, sizeof(request));
+ memwipe(&request, sizeof(request));
free(out);
return status;
@@ -1975,12 +1984,12 @@ METHOD(kernel_ipsec_t, flush_sas, status_t,
DBG2(DBG_KNL, "flushing all SAD entries");
- hdr = (struct nlmsghdr*)request;
+ 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 = (struct xfrm_usersa_flush*)NLMSG_DATA(hdr);
+ flush = NLMSG_DATA(hdr);
flush->proto = IPSEC_PROTO_ANY;
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
@@ -2011,12 +2020,12 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this,
memcpy(&clone, policy, sizeof(policy_entry_t));
memset(&request, 0, sizeof(request));
- hdr = (struct nlmsghdr*)request;
+ hdr = &request.hdr;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
hdr->nlmsg_type = update ? XFRM_MSG_UPDPOLICY : XFRM_MSG_NEWPOLICY;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info));
- policy_info = (struct xfrm_userpolicy_info*)NLMSG_DATA(hdr);
+ policy_info = NLMSG_DATA(hdr);
policy_info->sel = policy->sel;
policy_info->dir = policy->direction;
@@ -2335,12 +2344,12 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
src_ts, dst_ts, policy_dir_names, direction,
mark.value, mark.mask);
- hdr = (struct nlmsghdr*)request;
+ hdr = &request.hdr;
hdr->nlmsg_flags = NLM_F_REQUEST;
hdr->nlmsg_type = XFRM_MSG_GETPOLICY;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id));
- policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr);
+ policy_id = NLMSG_DATA(hdr);
policy_id->sel = ts2selector(src_ts, dst_ts);
policy_id->dir = direction;
@@ -2358,7 +2367,7 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
{
case XFRM_MSG_NEWPOLICY:
{
- policy = (struct xfrm_userpolicy_info*)NLMSG_DATA(hdr);
+ policy = NLMSG_DATA(hdr);
break;
}
case NLMSG_ERROR:
@@ -2492,12 +2501,12 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
memset(&request, 0, sizeof(request));
- hdr = (struct nlmsghdr*)request;
+ hdr = &request.hdr;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
hdr->nlmsg_type = XFRM_MSG_DELPOLICY;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id));
- policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr);
+ policy_id = NLMSG_DATA(hdr);
policy_id->sel = current->sel;
policy_id->dir = direction;
@@ -2551,7 +2560,7 @@ METHOD(kernel_ipsec_t, flush_policies, status_t,
DBG2(DBG_KNL, "flushing all policies from SPD");
- hdr = (struct nlmsghdr*)request;
+ hdr = &request.hdr;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
hdr->nlmsg_type = XFRM_MSG_FLUSHPOLICY;
hdr->nlmsg_len = NLMSG_LENGTH(0); /* no data associated */
@@ -2683,6 +2692,9 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
.policy_history = TRUE,
.install_routes = lib->settings->get_bool(lib->settings,
"%s.install_routes", TRUE, lib->ns),
+ .proto_port_transport = lib->settings->get_bool(lib->settings,
+ "%s.plugins.kernel-netlink.set_proto_port_transport_sa",
+ FALSE, lib->ns),
);
if (streq(lib->ns, "starter"))
@@ -2699,7 +2711,7 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
fclose(f);
}
- this->socket_xfrm = netlink_socket_create(NETLINK_XFRM);
+ this->socket_xfrm = netlink_socket_create(NETLINK_XFRM, xfrm_msg_names);
if (!this->socket_xfrm)
{
destroy(this);