[LTP] [PATCH 5/6] xfrm02: Configure xfrm using direct netlink request
Martin Doucha
mdoucha@suse.cz
Wed May 27 13:47:04 CEST 2026
Some kernels may not support ESP-in-TCP even though the necessary
modules are enabled in kernel config. Rewrite the xfrm setup using
direct netlink request so that the test can check errno and exit
with TCONF if the support is missing.
Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
testcases/network/sockets/xfrm02.c | 87 ++++++++++++++++++++++--------
1 file changed, 64 insertions(+), 23 deletions(-)
diff --git a/testcases/network/sockets/xfrm02.c b/testcases/network/sockets/xfrm02.c
index 86110bf4e..35c4dee52 100644
--- a/testcases/network/sockets/xfrm02.c
+++ b/testcases/network/sockets/xfrm02.c
@@ -26,9 +26,11 @@
#define _GNU_SOURCE
+#include "lapi/xfrm.h"
#include "tst_test.h"
#include "tst_net.h"
#include "tst_netdevice.h"
+#include "lapi/udp.h"
#include "lapi/tcp.h"
#include "lapi/splice.h"
@@ -46,6 +48,45 @@
/* ESP-in-TCP frame prefix: 2-byte length + ESP header */
#define PREFIX_SIZE (2 + ESP_HDR_SIZE)
+static struct xfrm_usersa_info xs_payload = {
+ .family = AF_INET6,
+ .mode = XFRM_MODE_TRANSPORT,
+ .reqid = 1,
+ .saddr.in6 = IN6ADDR_LOOPBACK_INIT,
+ .id = {
+ .proto = (uint8_t)IPPROTO_ESP,
+ .daddr.in6 = IN6ADDR_LOOPBACK_INIT
+ },
+ .lft = {
+ .soft_byte_limit = XFRM_INF,
+ .hard_byte_limit = XFRM_INF,
+ .soft_packet_limit = XFRM_INF,
+ .hard_packet_limit = XFRM_INF,
+ },
+};
+
+static struct xfrm_encap_tmpl esp_encap = {
+ .encap_type = TCP_ENCAP_ESPINTCP
+};
+
+static struct {
+ struct xfrm_algo_aead alg;
+ char buf[KEYTOTAL];
+} aead_alg_info = {
+ .alg = {
+ .alg_name = "rfc4106(gcm(aes))",
+ .alg_key_len = KEYTOTAL * 8,
+ .alg_icv_len = 128
+ }
+};
+
+static const struct tst_netlink_attr_list alg_config[] = {
+ {XFRMA_ENCAP, &esp_encap, sizeof(esp_encap), NULL},
+ {XFRMA_ALG_AEAD, &aead_alg_info, sizeof(aead_alg_info.alg) + KEYTOTAL,
+ NULL},
+ {0, NULL, -1, NULL}
+};
+
static const uint8_t aead_key[KEYTOTAL] = {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -58,35 +99,35 @@ static int srv_fd = -1;
static void setup(void)
{
- char keyhex[KEYTOTAL * 2 + 3];
- char spihex[16];
- char port_str[8];
int i, ret;
+ struct tst_netlink_context *ctx;
+ struct nlmsghdr header = {
+ .nlmsg_type = XFRM_MSG_NEWSA,
+ .nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL |
+ NLM_F_ACK
+ };
tst_setup_netns();
NETDEV_SET_STATE("lo", 1);
- keyhex[0] = '0';
- keyhex[1] = 'x';
- for (i = 0; i < KEYTOTAL; i++)
- sprintf(keyhex + 2 + i * 2, "%02x", aead_key[i]);
-
- snprintf(spihex, sizeof(spihex), "0x%08x", SPI);
- snprintf(port_str, sizeof(port_str), "%d", TCP_PORT);
-
- const char *const xfrm_cmd[] = {
- "ip", "xfrm", "state", "add",
- "src", "::1", "dst", "::1",
- "proto", "esp", "spi", spihex,
- "encap", "espintcp", port_str, port_str, "::",
- "aead", "rfc4106(gcm(aes))", keyhex, "128",
- "mode", "transport",
- NULL
- };
+ memcpy(aead_alg_info.alg.alg_key, aead_key, KEYTOTAL);
+ xs_payload.id.spi = htonl(SPI);
+ esp_encap.encap_sport = htons(TCP_PORT);
+ esp_encap.encap_dport = htons(TCP_PORT);
+
+ ctx = NETLINK_CREATE_CONTEXT(NETLINK_XFRM);
+ NETLINK_ADD_MESSAGE(ctx, &header, &xs_payload, sizeof(xs_payload));
+ NETLINK_ADD_ATTR_LIST(ctx, alg_config);
+ ret = NETLINK_SEND_VALIDATE(ctx);
+ TST_ERR = tst_netlink_errno;
+ NETLINK_DESTROY_CONTEXT(ctx);
- ret = tst_cmd(xfrm_cmd, NULL, NULL, TST_CMD_PASS_RETVAL);
- if (ret)
- tst_brk(TBROK, "Failed to install xfrm ESP-in-TCP state");
+ if (!ret) {
+ if (TST_ERR == EPROTONOSUPPORT)
+ tst_brk(TCONF, "xfrm ESP is not supported by kernel");
+
+ tst_brk(TBROK | TTERRNO, "Failed to install xfrm ESP state");
+ }
for (i = 0; i < DATA_SIZE; i++)
original[i] = (uint8_t)(i & 0xff);
--
2.54.0
More information about the ltp
mailing list