summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/kernel_netlink
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins/kernel_netlink')
-rw-r--r--src/libcharon/plugins/kernel_netlink/Makefile.in11
-rw-r--r--src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c80
-rw-r--r--src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c12
-rw-r--r--src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c44
-rw-r--r--src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h7
5 files changed, 120 insertions, 34 deletions
diff --git a/src/libcharon/plugins/kernel_netlink/Makefile.in b/src/libcharon/plugins/kernel_netlink/Makefile.in
index 7ec64084b..b6b3af6d5 100644
--- a/src/libcharon/plugins/kernel_netlink/Makefile.in
+++ b/src/libcharon/plugins/kernel_netlink/Makefile.in
@@ -355,7 +355,6 @@ PYTHON_VERSION = @PYTHON_VERSION@
PY_TEST = @PY_TEST@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
-RUBY = @RUBY@
RUBYGEMDIR = @RUBYGEMDIR@
SED = @SED@
SET_MAKE = @SET_MAKE@
@@ -381,6 +380,8 @@ am__tar = @am__tar@
am__untar = @am__untar@
attest_plugins = @attest_plugins@
bindir = @bindir@
+botan_CFLAGS = @botan_CFLAGS@
+botan_LIBS = @botan_LIBS@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
@@ -401,8 +402,6 @@ dvidir = @dvidir@
exec_prefix = @exec_prefix@
fips_mode = @fips_mode@
fuzz_plugins = @fuzz_plugins@
-gtk_CFLAGS = @gtk_CFLAGS@
-gtk_LIBS = @gtk_LIBS@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -457,8 +456,6 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
-ruby_CFLAGS = @ruby_CFLAGS@
-ruby_LIBS = @ruby_LIBS@
runstatedir = @runstatedir@
s_plugins = @s_plugins@
sbindir = @sbindir@
@@ -487,8 +484,12 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
tss2_CFLAGS = @tss2_CFLAGS@
tss2_LIBS = @tss2_LIBS@
+tss2_esys_CFLAGS = @tss2_esys_CFLAGS@
+tss2_esys_LIBS = @tss2_esys_LIBS@
tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_sys_CFLAGS = @tss2_sys_CFLAGS@
+tss2_sys_LIBS = @tss2_sys_LIBS@
tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
urandom_device = @urandom_device@
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
index 4926c3de8..1292e0895 100644
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -1131,7 +1131,7 @@ static void process_mapping(private_kernel_netlink_ipsec_t *this,
static bool receive_events(private_kernel_netlink_ipsec_t *this, int fd,
watcher_event_t event)
{
- char response[1024];
+ char response[netlink_get_buflen()];
struct nlmsghdr *hdr = (struct nlmsghdr*)response;
struct sockaddr_nl addr;
socklen_t addr_len = sizeof(addr);
@@ -1336,6 +1336,23 @@ static bool add_mark(struct nlmsghdr *hdr, int buflen, mark_t mark)
}
/**
+ * Add a uint32 attribute to message
+ */
+static bool add_uint32(struct nlmsghdr *hdr, int buflen,
+ enum xfrm_attr_type_t type, uint32_t value)
+{
+ uint32_t *xvalue;
+
+ xvalue = netlink_reserve(hdr, buflen, type, sizeof(*xvalue));
+ if (!xvalue)
+ {
+ return FALSE;
+ }
+ *xvalue = value;
+ return TRUE;
+}
+
+/**
* Check if kernel supports HW offload
*/
static void netlink_find_offload_feature(const char *ifname, int query_socket)
@@ -1586,6 +1603,49 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
sa->id.proto = id->proto;
sa->family = id->src->get_family(id->src);
sa->mode = mode2kernel(mode);
+
+ if (!data->copy_df)
+ {
+ sa->flags |= XFRM_STATE_NOPMTUDISC;
+ }
+
+ if (!data->copy_ecn)
+ {
+ sa->flags |= XFRM_STATE_NOECN;
+ }
+
+ if (data->inbound)
+ {
+ switch (data->copy_dscp)
+ {
+ case DSCP_COPY_YES:
+ case DSCP_COPY_IN_ONLY:
+ sa->flags |= XFRM_STATE_DECAP_DSCP;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ switch (data->copy_dscp)
+ {
+ case DSCP_COPY_IN_ONLY:
+ case DSCP_COPY_NO:
+ {
+ /* currently the only extra flag */
+ if (!add_uint32(hdr, sizeof(request), XFRMA_SA_EXTRA_FLAGS,
+ XFRM_SA_XFLAG_DONT_ENCAP_DSCP))
+ {
+ goto failed;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
switch (mode)
{
case MODE_TUNNEL:
@@ -1829,17 +1889,23 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
goto failed;
}
+ if (ipcomp == IPCOMP_NONE && (data->mark.value | data->mark.mask))
+ {
+ if (!add_uint32(hdr, sizeof(request), XFRMA_SET_MARK,
+ data->mark.value) ||
+ !add_uint32(hdr, sizeof(request), XFRMA_SET_MARK_MASK,
+ data->mark.mask))
+ {
+ goto failed;
+ }
+ }
+
if (data->tfc && id->proto == IPPROTO_ESP && mode == MODE_TUNNEL)
{ /* the kernel supports TFC padding only for tunnel mode ESP SAs */
- uint32_t *tfcpad;
-
- tfcpad = netlink_reserve(hdr, sizeof(request), XFRMA_TFCPAD,
- sizeof(*tfcpad));
- if (!tfcpad)
+ if (!add_uint32(hdr, sizeof(request), XFRMA_TFCPAD, data->tfc))
{
goto failed;
}
- *tfcpad = data->tfc;
}
if (id->proto != IPPROTO_COMP)
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c
index b6eb54370..760a875ca 100644
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c
+++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c
@@ -1504,7 +1504,7 @@ static void process_rule(private_kernel_netlink_net_t *this, struct nlmsghdr *hd
static bool receive_events(private_kernel_netlink_net_t *this, int fd,
watcher_event_t event)
{
- char response[1536];
+ char response[netlink_get_buflen()];
struct nlmsghdr *hdr = (struct nlmsghdr*)response;
struct sockaddr_nl addr;
socklen_t addr_len = sizeof(addr);
@@ -2586,11 +2586,11 @@ static status_t manage_srcroute(private_kernel_netlink_net_t *this,
memset(half_net.ptr, 0, half_net.len);
half_prefixlen = 1;
- status = manage_srcroute(this, nlmsg_type, flags, half_net, half_prefixlen,
- gateway, src_ip, if_name);
+ status = manage_srcroute(this, nlmsg_type, flags, half_net,
+ half_prefixlen, gateway, src_ip, if_name);
half_net.ptr[0] |= 0x80;
- status = manage_srcroute(this, nlmsg_type, flags, half_net, half_prefixlen,
- gateway, src_ip, if_name);
+ status |= manage_srcroute(this, nlmsg_type, flags, half_net,
+ half_prefixlen, gateway, src_ip, if_name);
return status;
}
@@ -2925,7 +2925,7 @@ static status_t manage_rule(private_kernel_netlink_net_t *this, int nlmsg_type,
msg->rtm_flags |= FIB_RULE_INVERT;
fwmark++;
}
- if (mark_from_string(fwmark, &mark))
+ if (mark_from_string(fwmark, MARK_OP_NONE, &mark))
{
chunk = chunk_from_thing(mark.value);
netlink_add_attribute(hdr, FRA_FWMARK, chunk, sizeof(request));
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c
index 441c0c482..84d78eca2 100644
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c
+++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c
@@ -381,7 +381,7 @@ static status_t send_once(private_netlink_socket_t *this, struct nlmsghdr *in,
for (i = 0, *out_len = 0; i < array_count(entry->hdrs); i++)
{
array_get(entry->hdrs, i, &hdr);
- *out_len += hdr->nlmsg_len;
+ *out_len += NLMSG_ALIGN(hdr->nlmsg_len);
}
ptr = malloc(*out_len);
*out = (struct nlmsghdr*)ptr;
@@ -394,7 +394,7 @@ static status_t send_once(private_netlink_socket_t *this, struct nlmsghdr *in,
hdr->nlmsg_seq, hdr, hdr->nlmsg_len);
}
memcpy(ptr, hdr, hdr->nlmsg_len);
- ptr += hdr->nlmsg_len;
+ ptr += NLMSG_ALIGN(hdr->nlmsg_len);
free(hdr);
}
destroy_entry(entry);
@@ -587,8 +587,31 @@ METHOD(netlink_socket_t, destroy, void,
free(this);
}
-/**
- * Described in header.
+/*
+ * Described in header
+ */
+u_int netlink_get_buflen()
+{
+ u_int buflen;
+
+ buflen = lib->settings->get_int(lib->settings,
+ "%s.plugins.kernel-netlink.buflen", 0, lib->ns);
+ if (!buflen)
+ {
+ long pagesize = sysconf(_SC_PAGESIZE);
+
+ if (pagesize == -1)
+ {
+ pagesize = 4096;
+ }
+ /* base this on NLMSG_GOODSIZE */
+ buflen = min(pagesize, 8192);
+ }
+ return buflen;
+}
+
+/*
+ * Described in header
*/
netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names,
bool parallel)
@@ -612,8 +635,7 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names,
.entries = hashtable_create(hashtable_hash_ptr, hashtable_equals_ptr, 4),
.protocol = protocol,
.names = names,
- .buflen = lib->settings->get_int(lib->settings,
- "%s.plugins.kernel-netlink.buflen", 0, lib->ns),
+ .buflen = netlink_get_buflen(),
.timeout = lib->settings->get_int(lib->settings,
"%s.plugins.kernel-netlink.timeout", 0, lib->ns),
.retries = lib->settings->get_int(lib->settings,
@@ -624,16 +646,6 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names,
.parallel = parallel,
);
- if (!this->buflen)
- {
- long pagesize = sysconf(_SC_PAGESIZE);
- if (pagesize == -1)
- {
- pagesize = 4096;
- }
- /* base this on NLMSG_GOODSIZE */
- this->buflen = min(pagesize, 8192);
- }
if (this->socket == -1)
{
DBG1(DBG_KNL, "unable to create netlink socket: %s (%d)",
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h
index 7056e6ccc..82dce4c5c 100644
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h
+++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h
@@ -101,4 +101,11 @@ void netlink_add_attribute(struct nlmsghdr *hdr, int rta_type, chunk_t data,
*/
void* netlink_reserve(struct nlmsghdr *hdr, int buflen, int type, int len);
+/**
+ * Determine buffer size for received messages (e.g. events).
+ *
+ * @return buffer size
+ */
+u_int netlink_get_buflen();
+
#endif /* KERNEL_NETLINK_SHARED_H_ */