kernel-netlink: Add support for setting mark/mask an SA should apply to processed traffic

This commit is contained in:
Tobias Brunner 2018-04-20 14:01:12 +02:00
parent c5b94b2483
commit 9cee688f78
3 changed files with 40 additions and 16 deletions

View File

@ -302,8 +302,11 @@ enum xfrm_attr_type_t {
XFRMA_ADDRESS_FILTER, /* struct xfrm_address_filter */ XFRMA_ADDRESS_FILTER, /* struct xfrm_address_filter */
XFRMA_PAD, XFRMA_PAD,
XFRMA_OFFLOAD_DEV, /* struct xfrm_state_offload */ XFRMA_OFFLOAD_DEV, /* struct xfrm_state_offload */
XFRMA_SET_MARK, /* __u32 */
XFRMA_SET_MARK_MASK, /* __u32 */
__XFRMA_MAX __XFRMA_MAX
#define XFRMA_OUTPUT_MARK XFRMA_SET_MARK /* Compatibility */
#define XFRMA_MAX (__XFRMA_MAX - 1) #define XFRMA_MAX (__XFRMA_MAX - 1)
}; };

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2016 Andreas Steffen * Copyright (C) 2016 Andreas Steffen
* Copyright (C) 2006-2016 Tobias Brunner * Copyright (C) 2006-2018 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter * Copyright (C) 2005 Jan Hutter
@ -93,6 +93,8 @@ struct kernel_ipsec_add_sa_t {
bool encap; bool encap;
/** no (disabled), yes (enabled), auto (enabled if supported) */ /** no (disabled), yes (enabled), auto (enabled if supported) */
hw_offload_t hw_offload; hw_offload_t hw_offload;
/** Mark the SA should apply to packets after processing */
mark_t mark;
/** TRUE to use Extended Sequence Numbers */ /** TRUE to use Extended Sequence Numbers */
bool esn; bool esn;
/** TRUE to copy the DF bit to the outer IPv4 header in tunnel mode */ /** TRUE to copy the DF bit to the outer IPv4 header in tunnel mode */

View File

@ -1335,6 +1335,23 @@ static bool add_mark(struct nlmsghdr *hdr, int buflen, mark_t mark)
return TRUE; return TRUE;
} }
/**
* 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 * Check if kernel supports HW offload
*/ */
@ -1616,16 +1633,12 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
case DSCP_COPY_IN_ONLY: case DSCP_COPY_IN_ONLY:
case DSCP_COPY_NO: case DSCP_COPY_NO:
{ {
uint32_t *xflags; /* currently the only extra flag */
if (!add_uint32(hdr, sizeof(request), XFRMA_SA_EXTRA_FLAGS,
xflags = netlink_reserve(hdr, sizeof(request), XFRM_SA_XFLAG_DONT_ENCAP_DSCP))
XFRMA_SA_EXTRA_FLAGS, sizeof(*xflags));
if (!xflags)
{ {
goto failed; goto failed;
} }
/* currently the only extra flag */
*xflags |= XFRM_SA_XFLAG_DONT_ENCAP_DSCP;
break; break;
} }
default: default:
@ -1876,17 +1889,23 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
goto failed; goto failed;
} }
if (data->tfc && id->proto == IPPROTO_ESP && mode == MODE_TUNNEL) if (ipcomp == IPCOMP_NONE && (data->mark.value | data->mark.mask))
{ /* the kernel supports TFC padding only for tunnel mode ESP SAs */ {
uint32_t *tfcpad; if (!add_uint32(hdr, sizeof(request), XFRMA_SET_MARK,
data->mark.value) ||
tfcpad = netlink_reserve(hdr, sizeof(request), XFRMA_TFCPAD, !add_uint32(hdr, sizeof(request), XFRMA_SET_MARK_MASK,
sizeof(*tfcpad)); data->mark.mask))
if (!tfcpad) {
goto failed;
}
}
if (data->tfc && id->proto == IPPROTO_ESP && mode == MODE_TUNNEL)
{ /* the kernel supports TFC padding only for tunnel mode ESP SAs */
if (!add_uint32(hdr, sizeof(request), XFRMA_TFCPAD, data->tfc))
{ {
goto failed; goto failed;
} }
*tfcpad = data->tfc;
} }
if (id->proto != IPPROTO_COMP) if (id->proto != IPPROTO_COMP)