Add fallback logic and enable XFRM-I support in netd
This patch adds fallback logic, checking for XFRM-I kernel support, and
switching to use XFRM-I if supported. Fallbacks to VTIs are provided for
backward compatibility with 4.4 kernels. Parameters for VTI versus
XFRM-I are selected based on the kernel support for XFRM interfaces.
This is part of a patch set to enable XFRM-I support, with automatic
fallbacks to VTI in XfrmController (3/3)
Bug: 77856928
Test: Binder tests updated, passing. CTS & unit tests also passing
Change-Id: Idf90adeec0d499fe4d566e4203f0eabb2b94fffa
diff --git a/server/XfrmControllerTest.cpp b/server/XfrmControllerTest.cpp
index be819d8..5f74e32 100644
--- a/server/XfrmControllerTest.cpp
+++ b/server/XfrmControllerTest.cpp
@@ -136,20 +136,6 @@
testing::StrictMock<netdutils::ScopedMockSyscalls> mockSyscalls;
};
-// Test class allowing IPv4/IPv6 parameterized tests.
-class XfrmControllerParameterizedTest : public XfrmControllerTest,
- public ::testing::WithParamInterface<int> {};
-
-// Helper to make generated test names readable.
-std::string FamilyName(::testing::TestParamInfo<int> info) {
- switch(info.param) {
- case 4: return "IPv4";
- case 5: return "IPv64DualStack";
- case 6: return "IPv6";
- }
- return android::base::StringPrintf("UNKNOWN family type: %d", info.param);
-}
-
/* Generate function to set value refered to by 3rd argument.
*
* This allows us to mock functions that pass in a pointer, expecting the result to be put into
@@ -217,12 +203,62 @@
EXPECT_EQ(netdutils::statusFromErrno(EINVAL, "Socket did not have UDP-encap sockopt set"), res);
}
+struct testCaseParams {
+ const int version;
+ const bool xfrmInterfacesEnabled;
+
+ int getTunnelInterfaceNlAttrsLen() {
+ if (xfrmInterfacesEnabled) {
+ return NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_interface_id));
+ } else {
+ return NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark));
+ }
+ }
+};
+
+// Test class allowing IPv4/IPv6 parameterized tests.
+class XfrmControllerParameterizedTest : public XfrmControllerTest,
+ public ::testing::WithParamInterface<testCaseParams> {};
+
+// Helper to make generated test names readable.
+std::string TestNameGenerator(::testing::TestParamInfo<testCaseParams> info) {
+ std::string name = "";
+ switch (info.param.version) {
+ case 4:
+ name += "IPv4";
+ break;
+ case 5:
+ name += "IPv64DualStack";
+ break;
+ case 6:
+ name += "IPv6";
+ break;
+ default:
+ name += android::base::StringPrintf("UNKNOWN family type: %d", info.param.version);
+ break;
+ }
+
+ name += "_";
+
+ if (info.param.xfrmInterfacesEnabled) {
+ name += "XFRMI";
+ } else {
+ name += "VTI";
+ }
+
+ return name;
+}
+
// The TEST_P cases below will run with each of the following value parameters.
-INSTANTIATE_TEST_CASE_P(ByFamily, XfrmControllerParameterizedTest, Values(4, 5, 6),
- FamilyName);
+INSTANTIATE_TEST_CASE_P(ByFamily, XfrmControllerParameterizedTest,
+ Values(testCaseParams{4, false}, testCaseParams{4, true},
+ testCaseParams{5, false}, testCaseParams{5, true},
+ testCaseParams{6, false}, testCaseParams{6, true}),
+ TestNameGenerator);
TEST_P(XfrmControllerParameterizedTest, TestIpSecAllocateSpi) {
- const int version = GetParam();
+ testCaseParams params = GetParam();
+ const int version = params.version;
const int family = (version == 6) ? AF_INET6 : AF_INET;
const std::string localAddr = (version == 6) ? LOCALHOST_V6 : LOCALHOST_V4;
const std::string remoteAddr = (version == 6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
@@ -231,6 +267,7 @@
response.hdr.nlmsg_type = XFRM_MSG_ALLOCSPI;
Slice responseSlice = netdutils::makeSlice(response);
+ // No IF_ID expected for allocSPI.
size_t expectedMsgLength = NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(xfrm_userspi_info));
// A vector to hold the flattened netlink message for nlMsgSlice
@@ -240,7 +277,7 @@
EXPECT_CALL(mockSyscalls, read(_, _))
.WillOnce(DoAll(SetArgSlice<1>(responseSlice), Return(responseSlice)));
- XfrmController ctrl;
+ XfrmController ctrl(params.xfrmInterfacesEnabled);
int outSpi = 0;
Status res = ctrl.ipSecAllocateSpi(1 /* resourceId */, localAddr,
remoteAddr, DROID_SPI, &outSpi);
@@ -263,8 +300,23 @@
EXPECT_EQ(DROID_SPI, static_cast<int>(userspi.max));
}
-void testIpSecAddSecurityAssociation(int version, const MockSyscalls& mockSyscalls,
- const XfrmMode& mode, __u32 underlying_netid) {
+void verifyXfrmiArguments(int mark, int mask, int ifId) {
+ // Check that correct arguments (and only those) are non-zero, and correct.
+ EXPECT_EQ(0, mark);
+ EXPECT_EQ(0, mask);
+ EXPECT_EQ(TEST_XFRM_IF_ID, ifId);
+}
+
+void verifyVtiArguments(int mark, int mask, int ifId) {
+ // Check that correct arguments (and only those) are non-zero, and correct.
+ EXPECT_EQ(TEST_XFRM_MARK, mark);
+ EXPECT_EQ(TEST_XFRM_MASK, mask);
+ EXPECT_EQ(0, ifId);
+}
+
+void testIpSecAddSecurityAssociation(testCaseParams params, const MockSyscalls& mockSyscalls,
+ const XfrmMode& mode) {
+ const int version = params.version;
const int family = (version == 6) ? AF_INET6 : AF_INET;
const std::string localAddr = (version == 6) ? LOCALHOST_V6 : LOCALHOST_V4;
const std::string remoteAddr = (version == 6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
@@ -280,17 +332,20 @@
size_t expectedMsgLength =
NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(xfrm_usersa_info)) +
NLA_ALIGN(offsetof(XfrmController::nlattr_algo_crypt, key) + KEY_LENGTH) +
- NLA_ALIGN(offsetof(XfrmController::nlattr_algo_auth, key) + KEY_LENGTH) +
- NLA_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark));
+ NLA_ALIGN(offsetof(XfrmController::nlattr_algo_auth, key) + KEY_LENGTH);
uint32_t testIfId = 0;
+ uint32_t testMark = 0;
+ uint32_t testMarkMask = 0;
+ uint32_t testOutputNetid = 0;
if (mode == XfrmMode::TUNNEL) {
- expectedMsgLength += NLA_ALIGN(sizeof(XfrmController::nlattr_xfrm_interface_id));
- testIfId = TEST_XFRM_IF_ID;
- }
-
- if (underlying_netid) {
+ expectedMsgLength += params.getTunnelInterfaceNlAttrsLen();
expectedMsgLength += NLA_ALIGN(sizeof(XfrmController::nlattr_xfrm_output_mark));
+
+ testIfId = TEST_XFRM_IF_ID;
+ testMark = TEST_XFRM_MARK;
+ testMarkMask = TEST_XFRM_MASK;
+ testOutputNetid = TEST_XFRM_UNDERLYING_NET;
}
std::vector<uint8_t> nlMsgBuf;
@@ -299,11 +354,11 @@
EXPECT_CALL(mockSyscalls, read(_, _))
.WillOnce(DoAll(SetArgSlice<1>(responseSlice), Return(responseSlice)));
- XfrmController ctrl;
+ XfrmController ctrl(params.xfrmInterfacesEnabled);
Status res = ctrl.ipSecAddSecurityAssociation(
1 /* resourceId */, static_cast<int>(mode), localAddr, remoteAddr,
- underlying_netid /* underlying netid */, DROID_SPI, TEST_XFRM_MARK /* mark */,
- TEST_XFRM_MASK /* mask */, "hmac(sha256)" /* auth algo */, authKey,
+ testOutputNetid /* underlying netid */, DROID_SPI, testMark /* mark */,
+ testMarkMask /* mask */, "hmac(sha256)" /* auth algo */, authKey,
128 /* auth trunc length */, "cbc(aes)" /* encryption algo */, cryptKey,
0 /* crypt trunc length? */, "" /* AEAD algo */, {}, 0,
static_cast<int>(XfrmEncapType::NONE), 0 /* local port */, 0 /* remote port */,
@@ -376,34 +431,36 @@
reinterpret_cast<void*>(&encryptAlgo.key), KEY_LENGTH));
EXPECT_EQ(0, memcmp(reinterpret_cast<void*>(authKey.data()),
reinterpret_cast<void*>(&authAlgo.key), KEY_LENGTH));
- EXPECT_EQ(TEST_XFRM_MARK, mark.mark.v);
- EXPECT_EQ(TEST_XFRM_MASK, mark.mark.m);
- EXPECT_EQ(testIfId, xfrm_if_id.if_id);
- if (underlying_netid) {
+ if (mode == XfrmMode::TUNNEL) {
+ if (params.xfrmInterfacesEnabled) {
+ verifyXfrmiArguments(mark.mark.v, mark.mark.m, xfrm_if_id.if_id);
+ } else {
+ verifyVtiArguments(mark.mark.v, mark.mark.m, xfrm_if_id.if_id);
+ }
+
Fwmark fwmark;
fwmark.intValue = outputmark.outputMark;
- EXPECT_EQ(underlying_netid, fwmark.netId);
+ EXPECT_EQ(testOutputNetid, fwmark.netId);
EXPECT_EQ(PERMISSION_SYSTEM, fwmark.permission);
EXPECT_TRUE(fwmark.explicitlySelected);
EXPECT_TRUE(fwmark.protectedFromVpn);
+ } else {
+ EXPECT_EQ(0, outputmark.outputMark);
+ EXPECT_EQ(0, mark.mark.v);
+ EXPECT_EQ(0, mark.mark.m);
+ EXPECT_EQ(0, xfrm_if_id.if_id);
}
}
TEST_P(XfrmControllerParameterizedTest, TestTransportModeIpSecAddSecurityAssociation) {
- const int version = GetParam();
- testIpSecAddSecurityAssociation(version, mockSyscalls, XfrmMode::TRANSPORT, 0);
+ testCaseParams params = GetParam();
+ testIpSecAddSecurityAssociation(params, mockSyscalls, XfrmMode::TRANSPORT);
}
TEST_P(XfrmControllerParameterizedTest, TestTunnelModeIpSecAddSecurityAssociation) {
- const int version = GetParam();
- testIpSecAddSecurityAssociation(version, mockSyscalls, XfrmMode::TUNNEL, 0);
-}
-
-TEST_P(XfrmControllerParameterizedTest, TestTunnelModeIpSecAddSecurityAssociationWithOutputMark) {
- const int version = GetParam();
- testIpSecAddSecurityAssociation(version, mockSyscalls, XfrmMode::TUNNEL,
- TEST_XFRM_UNDERLYING_NET);
+ testCaseParams params = GetParam();
+ testIpSecAddSecurityAssociation(params, mockSyscalls, XfrmMode::TUNNEL);
}
TEST_F(XfrmControllerTest, TestIpSecAddSecurityAssociationIPv4Encap) {
@@ -442,7 +499,8 @@
}
TEST_P(XfrmControllerParameterizedTest, TestIpSecApplyTransportModeTransform) {
- const int version = GetParam();
+ testCaseParams params = GetParam();
+ const int version = params.version;
const int sockFamily = (version == 4) ? AF_INET : AF_INET6;
const int xfrmFamily = (version == 6) ? AF_INET6: AF_INET;
const std::string localAddr = (version == 6) ? LOCALHOST_V6 : LOCALHOST_V4;
@@ -468,7 +526,7 @@
.WillOnce(DoAll(WithArg<3>(Invoke(SavePolicy)), SaveArg<4>(&optlen),
Return(netdutils::status::ok)));
- XfrmController ctrl;
+ XfrmController ctrl(params.xfrmInterfacesEnabled);
Status res = ctrl.ipSecApplyTransportModeTransform(sock, 1 /* resourceId */,
static_cast<int>(XfrmDirection::OUT),
localAddr, remoteAddr, DROID_SPI);
@@ -484,7 +542,8 @@
}
TEST_P(XfrmControllerParameterizedTest, TestIpSecRemoveTransportModeTransform) {
- const int version = GetParam();
+ testCaseParams params = GetParam();
+ const int version = params.version;
const int family = (version == 6) ? AF_INET6 : AF_INET;
const std::string localAddr = (version == 6) ? LOCALHOST_V6 : LOCALHOST_V4;
const std::string remoteAddr = (version == 6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
@@ -503,7 +562,7 @@
EXPECT_CALL(mockSyscalls, setsockopt(_, _, _, _, _))
.WillOnce(DoAll(SaveArg<3>(&optval), SaveArg<4>(&optlen),
Return(netdutils::status::ok)));
- XfrmController ctrl;
+ XfrmController ctrl(params.xfrmInterfacesEnabled);
Status res = ctrl.ipSecRemoveTransportModeTransform(sock);
EXPECT_TRUE(isOk(res)) << res;
@@ -511,8 +570,26 @@
EXPECT_EQ(static_cast<socklen_t>(0), optlen);
}
+void parseTunnelNetlinkAttrs(XfrmController::nlattr_xfrm_mark* mark,
+ XfrmController::nlattr_xfrm_interface_id* xfrm_if_id, Slice attr_buf) {
+ auto attrHandler = [mark, xfrm_if_id](const nlattr& attr, const Slice& attr_payload) {
+ Slice buf = attr_payload;
+ if (attr.nla_type == XFRMA_MARK) {
+ mark->hdr = attr;
+ netdutils::extract(buf, mark->mark);
+ } else if (attr.nla_type == XFRMA_IF_ID) {
+ xfrm_if_id->hdr = attr;
+ netdutils::extract(buf, xfrm_if_id->if_id);
+ } else {
+ FAIL() << "Unexpected nlattr type: " << attr.nla_type;
+ }
+ };
+ forEachNetlinkAttribute(attr_buf, attrHandler);
+}
+
TEST_P(XfrmControllerParameterizedTest, TestIpSecDeleteSecurityAssociation) {
- const int version = GetParam();
+ testCaseParams params = GetParam();
+ const int version = params.version;
const int family = (version == 6) ? AF_INET6 : AF_INET;
const std::string localAddr = (version == 6) ? LOCALHOST_V6 : LOCALHOST_V4;
const std::string remoteAddr = (version == 6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
@@ -522,8 +599,7 @@
Slice responseSlice = netdutils::makeSlice(response);
size_t expectedMsgLength = NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(xfrm_usersa_id)) +
- NLA_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark)) +
- NLA_ALIGN(sizeof(XfrmController::nlattr_xfrm_interface_id));
+ params.getTunnelInterfaceNlAttrsLen();
std::vector<uint8_t> nlMsgBuf;
EXPECT_CALL(mockSyscalls, writev(_, _))
@@ -531,7 +607,7 @@
EXPECT_CALL(mockSyscalls, read(_, _))
.WillOnce(DoAll(SetArgSlice<1>(responseSlice), Return(responseSlice)));
- XfrmController ctrl;
+ XfrmController ctrl(params.xfrmInterfacesEnabled);
Status res = ctrl.ipSecDeleteSecurityAssociation(1 /* resourceId */, localAddr, remoteAddr,
DROID_SPI, TEST_XFRM_MARK, TEST_XFRM_MASK,
TEST_XFRM_IF_ID);
@@ -549,21 +625,21 @@
EXPECT_EQ(htonl(DROID_SPI), said.spi);
expectAddressEquals(family, remoteAddr, said.daddr);
- // Extract and check the mark.
+ // Extract and check the marks and xfrm_if_id
XfrmController::nlattr_xfrm_mark mark{};
- netdutils::extract(nlMsgSlice, mark);
- nlMsgSlice = drop(nlMsgSlice, sizeof(XfrmController::nlattr_xfrm_mark));
- EXPECT_EQ(TEST_XFRM_MARK, mark.mark.v);
- EXPECT_EQ(TEST_XFRM_MASK, mark.mark.m);
-
- // Extract and check the interface id.
XfrmController::nlattr_xfrm_interface_id xfrm_if_id{};
- netdutils::extract(nlMsgSlice, xfrm_if_id);
- EXPECT_EQ(TEST_XFRM_IF_ID, xfrm_if_id.if_id);
+ parseTunnelNetlinkAttrs(&mark, &xfrm_if_id, nlMsgSlice);
+
+ if (params.xfrmInterfacesEnabled) {
+ verifyXfrmiArguments(mark.mark.v, mark.mark.m, xfrm_if_id.if_id);
+ } else {
+ verifyVtiArguments(mark.mark.v, mark.mark.m, xfrm_if_id.if_id);
+ }
}
TEST_P(XfrmControllerParameterizedTest, TestIpSecAddSecurityPolicy) {
- const int version = GetParam();
+ testCaseParams params = GetParam();
+ const int version = params.version;
const int family = (version == 6) ? AF_INET6 : AF_INET;
const std::string localAddr = (version == 6) ? LOCALHOST_V6 : LOCALHOST_V4;
const std::string remoteAddr = (version == 6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
@@ -574,8 +650,7 @@
size_t expectedMsgLength = NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(xfrm_userpolicy_info)) +
NLMSG_ALIGN(sizeof(XfrmController::nlattr_user_tmpl)) +
- NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark)) +
- NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_interface_id));
+ params.getTunnelInterfaceNlAttrsLen();
std::vector<uint8_t> nlMsgBuf;
EXPECT_CALL(mockSyscalls, writev(_, _))
@@ -583,7 +658,7 @@
EXPECT_CALL(mockSyscalls, read(_, _))
.WillOnce(DoAll(SetArgSlice<1>(responseSlice), Return(responseSlice)));
- XfrmController ctrl;
+ XfrmController ctrl(params.xfrmInterfacesEnabled);
Status res = ctrl.ipSecAddSecurityPolicy(
1 /* resourceId */, family, static_cast<int>(XfrmDirection::OUT), localAddr, remoteAddr,
0 /* SPI */, TEST_XFRM_MARK, TEST_XFRM_MASK, TEST_XFRM_IF_ID);
@@ -628,13 +703,17 @@
forEachNetlinkAttribute(attr_buf, attrHandler);
expectAddressEquals(family, remoteAddr, usertmpl.tmpl.id.daddr);
- EXPECT_EQ(TEST_XFRM_MARK, mark.mark.v);
- EXPECT_EQ(TEST_XFRM_MASK, mark.mark.m);
- EXPECT_EQ(TEST_XFRM_IF_ID, xfrm_if_id.if_id);
+
+ if (params.xfrmInterfacesEnabled) {
+ verifyXfrmiArguments(mark.mark.v, mark.mark.m, xfrm_if_id.if_id);
+ } else {
+ verifyVtiArguments(mark.mark.v, mark.mark.m, xfrm_if_id.if_id);
+ }
}
TEST_P(XfrmControllerParameterizedTest, TestIpSecUpdateSecurityPolicy) {
- const int version = GetParam();
+ testCaseParams params = GetParam();
+ const int version = params.version;
const int family = (version == 6) ? AF_INET6 : AF_INET;
const std::string localAddr = (version == 6) ? LOCALHOST_V6 : LOCALHOST_V4;
const std::string remoteAddr = (version == 6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
@@ -645,8 +724,7 @@
size_t expectedMsgLength = NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(xfrm_userpolicy_info)) +
NLMSG_ALIGN(sizeof(XfrmController::nlattr_user_tmpl)) +
- NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark)) +
- NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_interface_id));
+ params.getTunnelInterfaceNlAttrsLen();
std::vector<uint8_t> nlMsgBuf;
EXPECT_CALL(mockSyscalls, writev(_, _))
@@ -654,10 +732,11 @@
EXPECT_CALL(mockSyscalls, read(_, _))
.WillOnce(DoAll(SetArgSlice<1>(responseSlice), Return(responseSlice)));
- XfrmController ctrl;
+ XfrmController ctrl(params.xfrmInterfacesEnabled);
Status res = ctrl.ipSecUpdateSecurityPolicy(
1 /* resourceId */, family, static_cast<int>(XfrmDirection::OUT), localAddr, remoteAddr,
- 0 /* SPI */, 0 /* Mark */, 0 /* Mask */, TEST_XFRM_IF_ID /* xfrm_if_id */);
+ 0 /* SPI */, TEST_XFRM_MARK /* Mark */, TEST_XFRM_MARK /* Mask */,
+ TEST_XFRM_IF_ID /* xfrm_if_id */);
EXPECT_TRUE(isOk(res)) << res;
EXPECT_EQ(expectedMsgLength, nlMsgBuf.size());
@@ -669,7 +748,8 @@
}
TEST_P(XfrmControllerParameterizedTest, TestIpSecDeleteSecurityPolicy) {
- const int version = GetParam();
+ testCaseParams params = GetParam();
+ const int version = params.version;
const int family = (version == 6) ? AF_INET6 : AF_INET;
const std::string localAddr = (version == 6) ? LOCALHOST_V6 : LOCALHOST_V4;
const std::string remoteAddr = (version == 6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
@@ -679,8 +759,7 @@
Slice responseSlice = netdutils::makeSlice(response);
size_t expectedMsgLength = NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(xfrm_userpolicy_id)) +
- NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_mark)) +
- NLMSG_ALIGN(sizeof(XfrmController::nlattr_xfrm_interface_id));
+ params.getTunnelInterfaceNlAttrsLen();
std::vector<uint8_t> nlMsgBuf;
EXPECT_CALL(mockSyscalls, writev(_, _))
@@ -688,7 +767,7 @@
EXPECT_CALL(mockSyscalls, read(_, _))
.WillOnce(DoAll(SetArgSlice<1>(responseSlice), Return(responseSlice)));
- XfrmController ctrl;
+ XfrmController ctrl(params.xfrmInterfacesEnabled);
Status res = ctrl.ipSecDeleteSecurityPolicy(1 /* resourceId */, family,
static_cast<int>(XfrmDirection::OUT),
TEST_XFRM_MARK, TEST_XFRM_MASK, TEST_XFRM_IF_ID);
@@ -707,17 +786,16 @@
// Drop the user policy id.
nlMsgSlice = drop(nlMsgSlice, NLA_ALIGN(sizeof(xfrm_userpolicy_id)));
- // Extract and check the mark.
+ // Extract and check the marks and xfrm_if_id
XfrmController::nlattr_xfrm_mark mark{};
- netdutils::extract(nlMsgSlice, mark);
- nlMsgSlice = drop(nlMsgSlice, sizeof(XfrmController::nlattr_xfrm_mark));
- EXPECT_EQ(TEST_XFRM_MARK, mark.mark.v);
- EXPECT_EQ(TEST_XFRM_MASK, mark.mark.m);
-
- // Extract and check the interface id.
XfrmController::nlattr_xfrm_interface_id xfrm_if_id{};
- netdutils::extract(nlMsgSlice, xfrm_if_id);
- EXPECT_EQ(TEST_XFRM_IF_ID, xfrm_if_id.if_id);
+ parseTunnelNetlinkAttrs(&mark, &xfrm_if_id, nlMsgSlice);
+
+ if (params.xfrmInterfacesEnabled) {
+ verifyXfrmiArguments(mark.mark.v, mark.mark.m, xfrm_if_id.if_id);
+ } else {
+ verifyVtiArguments(mark.mark.v, mark.mark.m, xfrm_if_id.if_id);
+ }
}
// TODO: Add tests for VTIs, ensuring that we are sending the correct data over netlink.