Group the parameters passed in to create SAs.
This change groups encryption parameters, authentication
parameters, and mark match parameters into three parameters,
encryption, auth_trundc, and mark.
This removes a fair bit of boilerplate code and allows callers
to be more explicit about what they want.
Test: all xfrm tests pass on android-4.9
Change-Id: Ia8e084d49db91aff746f4ffbc2c62cfb2e399f63
diff --git a/net/test/xfrm.py b/net/test/xfrm.py
index 4f7e578..e12eb79 100755
--- a/net/test/xfrm.py
+++ b/net/test/xfrm.py
@@ -206,6 +206,9 @@
# TODO: move this somewhere more appropriate when possible
EspHdr = cstruct.Struct("EspHdr", "!II", "spi seqnum")
+# Local constants.
+_DEFAULT_REPLAY_WINDOW = 4
+
def RawAddress(addr):
"""Converts an IP address string to binary format."""
@@ -239,6 +242,11 @@
prefixlen_s=prefixlen, prefixlen_d=prefixlen, family=family)
+def ExactMatchMark(mark):
+ """An XfrmMark that matches only the specified mark."""
+ return XfrmMark((mark, 0xffffffff))
+
+
class Xfrm(netlink.NetlinkSocket):
"""Netlink interface to xfrm."""
@@ -342,39 +350,62 @@
msg += self._NlAttr(attr_type, attr_msg.Pack())
return self._SendNlRequest(msg_type, msg, flags)
- def AddSaInfo(self, selector, xfrm_id, saddr, lifetimes, reqid, family, mode,
- replay_window, flags, nlattrs):
- # The kernel ignores these on input.
- cur = "\x00" * len(XfrmLifetimeCur)
- stats = "\x00" * len(XfrmStats)
- seq = 0
- sa = XfrmUsersaInfo((selector, xfrm_id, saddr, lifetimes, cur, stats, seq,
- reqid, family, mode, replay_window, flags))
- msg = sa.Pack() + nlattrs
- flags = netlink.NLM_F_REQUEST | netlink.NLM_F_ACK
- self._SendNlRequest(XFRM_MSG_NEWSA, msg, flags)
+ def AddSaInfo(self, src, dst, spi, mode, reqid, selector, encryption,
+ auth_trunc, encap, mark, output_mark):
+ """Adds an IPsec security association.
- def AddMinimalSaInfo(self, src, dst, spi, proto, mode, reqid,
- encryption, encryption_key,
- auth_trunc, auth_trunc_key, encap,
- mark, mark_mask, output_mark, selector=None):
- if selector is None:
- selector = EmptySelector(AF_UNSPEC)
+ Args:
+ src: A string, the source IP address. May be a wildcard in transport mode.
+ dst: A string, the destination IP address. Forms part of the XFRM ID, and
+ must match the destination address of the packets sent by this SA.
+ spi: An integer, the SPI.
+ mode: An IPsec mode such as XFRM_MODE_TRANSPORT.
+ reqid: A request ID. Can be used in policies to match the SA.
+ selector: An XfrmSelector (e.g., as returned by EmptySelector or
+ SrcDstSelector). Decides which packets will be transformed. If None,
+ matches all packets.
+ encryption: A tuple of an XfrmAlgo and raw key bytes, or None.
+ auth_trunc: A tuple of an XfrmAlgoAuth and raw key bytes, or None.
+ encap: An XfrmEncapTmpl structure, or None.
+ mark: A mark match specifier, such as returned by ExactMatchMark(), or
+ None for an SA that matches all possible marks.
+ output_mark: An integer, the output mark. 0 means unset.
+ """
+ proto = IPPROTO_ESP
xfrm_id = XfrmId((PaddedAddress(dst), spi, proto))
family = AF_INET6 if ":" in dst else AF_INET
- nlattrs = self._NlAttr(XFRMA_ALG_CRYPT,
- encryption.Pack() + encryption_key)
- nlattrs += self._NlAttr(XFRMA_ALG_AUTH_TRUNC,
- auth_trunc.Pack() + auth_trunc_key)
+
+ if selector is None:
+ selector = EmptySelector(AF_UNSPEC)
+
+ nlattrs = ""
+ if encryption is not None:
+ enc, key = encryption
+ nlattrs += self._NlAttr(XFRMA_ALG_CRYPT, enc.Pack() + key)
+
+ if auth_trunc is not None:
+ auth, key = auth_trunc
+ nlattrs += self._NlAttr(XFRMA_ALG_AUTH_TRUNC, auth.Pack() + key)
+
# if a user provides either mark or mask, then we send the mark attribute
- if mark or mark_mask:
- nlattrs += self._NlAttr(XFRMA_MARK, XfrmMark((mark, mark_mask)).Pack())
+ if mark is not None:
+ nlattrs += self._NlAttr(XFRMA_MARK, mark.Pack())
if encap is not None:
nlattrs += self._NlAttr(XFRMA_ENCAP, encap.Pack())
if output_mark is not None:
nlattrs += self._NlAttrU32(XFRMA_OUTPUT_MARK, output_mark)
- self.AddSaInfo(selector, xfrm_id, PaddedAddress(src), NO_LIFETIME_CFG,
- reqid, family, mode, 4, 0, nlattrs)
+
+ # The kernel ignores these on input, so make them empty.
+ cur = XfrmLifetimeCur()
+ stats = XfrmStats()
+ seq = 0
+ replay = _DEFAULT_REPLAY_WINDOW
+ flags = 0
+ sa = XfrmUsersaInfo((selector, xfrm_id, PaddedAddress(src), NO_LIFETIME_CFG,
+ cur, stats, seq, reqid, family, mode, replay, flags))
+ msg = sa.Pack() + nlattrs
+ flags = netlink.NLM_F_REQUEST | netlink.NLM_F_ACK
+ self._SendNlRequest(XFRM_MSG_NEWSA, msg, flags)
def DeleteSaInfo(self, daddr, spi, proto):
# TODO: deletes take a mark as well.
diff --git a/net/test/xfrm_algorithm_test.py b/net/test/xfrm_algorithm_test.py
index 1766562..66b671d 100755
--- a/net/test/xfrm_algorithm_test.py
+++ b/net/test/xfrm_algorithm_test.py
@@ -118,77 +118,77 @@
family = net_test.GetAddressFamily(params["version"])
local_addr = self.MyAddress(params["version"], netid)
remote_addr = self.GetRemoteAddress(params["version"])
- ekey_left = os.urandom(params["crypt"].key_len / 8)
- akey_left = os.urandom(params["auth"].key_len / 8)
- ekey_right = os.urandom(params["crypt"].key_len / 8)
- akey_right = os.urandom(params["auth"].key_len / 8)
+ crypt_left = (xfrm.XfrmAlgo((params["crypt"].name,
+ params["crypt"].key_len)),
+ os.urandom(params["crypt"].key_len / 8))
+ crypt_right = (xfrm.XfrmAlgo((params["crypt"].name,
+ params["crypt"].key_len)),
+ os.urandom(params["crypt"].key_len / 8))
+ auth_left = (xfrm.XfrmAlgoAuth((
+ params["auth"].name,
+ params["auth"].key_len,
+ params["auth"].trunc_len)),
+ os.urandom(params["auth"].key_len / 8))
+ auth_right = (xfrm.XfrmAlgoAuth((
+ params["auth"].name,
+ params["auth"].key_len,
+ params["auth"].trunc_len)),
+ os.urandom(params["auth"].key_len / 8))
spi_left = htonl(0xbeefface)
spi_right = htonl(0xcafed00d)
req_ids = [100, 200, 300, 400] # Used to match templates and SAs.
# Left outbound SA
- self.xfrm.AddMinimalSaInfo(
+ self.xfrm.AddSaInfo(
src=local_addr,
dst=remote_addr,
spi=spi_right,
- proto=IPPROTO_ESP,
mode=xfrm.XFRM_MODE_TRANSPORT,
reqid=req_ids[0],
- encryption=params["crypt"],
- encryption_key=ekey_right,
- auth_trunc=params["auth"],
- auth_trunc_key=akey_right,
+ selector=None,
+ encryption=crypt_right,
+ auth_trunc=auth_right,
encap=None,
mark=None,
- mark_mask=None,
output_mark=None)
# Right inbound SA
- self.xfrm.AddMinimalSaInfo(
+ self.xfrm.AddSaInfo(
src=remote_addr,
dst=local_addr,
spi=spi_right,
- proto=IPPROTO_ESP,
mode=xfrm.XFRM_MODE_TRANSPORT,
reqid=req_ids[1],
- encryption=params["crypt"],
- encryption_key=ekey_right,
- auth_trunc=params["auth"],
- auth_trunc_key=akey_right,
+ selector=None,
+ encryption=crypt_right,
+ auth_trunc=auth_right,
encap=None,
mark=None,
- mark_mask=None,
output_mark=None)
# Right outbound SA
- self.xfrm.AddMinimalSaInfo(
+ self.xfrm.AddSaInfo(
src=local_addr,
dst=remote_addr,
spi=spi_left,
- proto=IPPROTO_ESP,
mode=xfrm.XFRM_MODE_TRANSPORT,
reqid=req_ids[2],
- encryption=params["crypt"],
- encryption_key=ekey_left,
- auth_trunc=params["auth"],
- auth_trunc_key=akey_left,
+ selector=None,
+ encryption=crypt_left,
+ auth_trunc=auth_left,
encap=None,
mark=None,
- mark_mask=None,
output_mark=None)
# Left inbound SA
- self.xfrm.AddMinimalSaInfo(
+ self.xfrm.AddSaInfo(
src=remote_addr,
dst=local_addr,
spi=spi_left,
- proto=IPPROTO_ESP,
mode=xfrm.XFRM_MODE_TRANSPORT,
reqid=req_ids[3],
- encryption=params["crypt"],
- encryption_key=ekey_left,
- auth_trunc=params["auth"],
- auth_trunc_key=akey_left,
+ selector=None,
+ encryption=crypt_left,
+ auth_trunc=auth_left,
encap=None,
mark=None,
- mark_mask=None,
output_mark=None)
# Make two sockets.
diff --git a/net/test/xfrm_base.py b/net/test/xfrm_base.py
index 89cf114..7aba01c 100644
--- a/net/test/xfrm_base.py
+++ b/net/test/xfrm_base.py
@@ -27,10 +27,12 @@
"57c7d4fe567a2120f35bae0f9869ec22".decode("hex"))
_AUTHENTICATION_KEY_128 = "af442892cdcd0ef650e9c299f9a8436a".decode("hex")
-_ALGO_AUTH_NULL = xfrm.XfrmAlgoAuth(("digest_null", 0, 0))
-_ALGO_CBC_AES_256 = xfrm.XfrmAlgo(("cbc(aes)", 256))
-_ALGO_CRYPT_NULL = xfrm.XfrmAlgo(("ecb(cipher_null)", 0))
-_ALGO_HMAC_SHA1 = xfrm.XfrmAlgoAuth(("hmac(sha1)", 128, 96))
+_ALGO_AUTH_NULL = (xfrm.XfrmAlgoAuth(("digest_null", 0, 0)), "")
+_ALGO_CBC_AES_256 = (xfrm.XfrmAlgo((xfrm.XFRM_EALG_CBC_AES, 256)),
+ _ENCRYPTION_KEY_256)
+_ALGO_CRYPT_NULL = (xfrm.XfrmAlgo(("ecb(cipher_null)", 0)), "")
+_ALGO_HMAC_SHA1 = (xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA1, 128, 96)),
+ _AUTHENTICATION_KEY_128)
# Match all bits of the mark
MARK_MASK_ALL = 0xffffffff
diff --git a/net/test/xfrm_test.py b/net/test/xfrm_test.py
index 7429dfe..04ae2e6 100755
--- a/net/test/xfrm_test.py
+++ b/net/test/xfrm_test.py
@@ -43,8 +43,6 @@
TEST_SPI = 0x1234
-ALGO_CBC_AES_256 = xfrm.XfrmAlgo(("cbc(aes)", 256))
-ALGO_HMAC_SHA1 = xfrm.XfrmAlgoAuth(("hmac(sha1)", 128, 96))
class XfrmFunctionalTest(xfrm_base.XfrmBaseTest):
@@ -60,13 +58,10 @@
self.assertEquals(xfrm.EspHdr((ntohl(spi), seq)), esp_hdr)
def testAddSa(self):
- self.xfrm.AddMinimalSaInfo("::", TEST_ADDR1, htonl(TEST_SPI), IPPROTO_ESP,
- xfrm.XFRM_MODE_TRANSPORT, 3320,
- xfrm_base._ALGO_CBC_AES_256,
- xfrm_base._ENCRYPTION_KEY_256,
- xfrm_base._ALGO_HMAC_SHA1,
- xfrm_base._AUTHENTICATION_KEY_128,
- None, None, None, None)
+ self.xfrm.AddSaInfo("::", TEST_ADDR1, htonl(TEST_SPI),
+ xfrm.XFRM_MODE_TRANSPORT, 3320, None,
+ xfrm_base._ALGO_CBC_AES_256, xfrm_base._ALGO_HMAC_SHA1,
+ None, None, None)
expected = (
"src :: dst 2001:4860:4860::8888\n"
"\tproto esp spi 0x00001234 reqid 3320 mode transport\n"
@@ -85,20 +80,14 @@
def testFlush(self):
self.assertEquals(0, len(self.xfrm.DumpSaInfo()))
- self.xfrm.AddMinimalSaInfo("::", "2000::", htonl(TEST_SPI),
- IPPROTO_ESP, xfrm.XFRM_MODE_TRANSPORT, 1234,
- xfrm_base._ALGO_CBC_AES_256,
- xfrm_base._ENCRYPTION_KEY_256,
- xfrm_base._ALGO_HMAC_SHA1,
- xfrm_base._AUTHENTICATION_KEY_128,
- None, None, None, None)
- self.xfrm.AddMinimalSaInfo("0.0.0.0", "192.0.2.1", htonl(TEST_SPI),
- IPPROTO_ESP, xfrm.XFRM_MODE_TRANSPORT, 4321,
- xfrm_base._ALGO_CBC_AES_256,
- xfrm_base._ENCRYPTION_KEY_256,
- xfrm_base._ALGO_HMAC_SHA1,
- xfrm_base._AUTHENTICATION_KEY_128,
- None, None, None, None)
+ self.xfrm.AddSaInfo("::", "2000::", htonl(TEST_SPI),
+ xfrm.XFRM_MODE_TRANSPORT, 1234, None,
+ xfrm_base._ALGO_CBC_AES_256, xfrm_base._ALGO_HMAC_SHA1,
+ None, None, None)
+ self.xfrm.AddSaInfo("0.0.0.0", "192.0.2.1", htonl(TEST_SPI),
+ xfrm.XFRM_MODE_TRANSPORT, 4321, None,
+ xfrm_base._ALGO_CBC_AES_256, xfrm_base._ALGO_HMAC_SHA1,
+ None, None, None)
self.assertEquals(2, len(self.xfrm.DumpSaInfo()))
self.xfrm.FlushSaInfo()
self.assertEquals(0, len(self.xfrm.DumpSaInfo()))
@@ -127,13 +116,10 @@
# SPI must match the one in our template, and the destination address must
# match the packet's destination address (in tunnel mode, it has to match
# the tunnel destination).
- self.xfrm.AddMinimalSaInfo("::", TEST_ADDR1, htonl(TEST_SPI), IPPROTO_ESP,
- xfrm.XFRM_MODE_TRANSPORT, reqid,
- xfrm_base._ALGO_CBC_AES_256,
- xfrm_base._ENCRYPTION_KEY_256,
- xfrm_base._ALGO_HMAC_SHA1,
- xfrm_base._AUTHENTICATION_KEY_128,
- None, None, None, None)
+ self.xfrm.AddSaInfo("::", TEST_ADDR1, htonl(TEST_SPI),
+ xfrm.XFRM_MODE_TRANSPORT, reqid, None,
+ xfrm_base._ALGO_CBC_AES_256, xfrm_base._ALGO_HMAC_SHA1,
+ None, None, None)
s.sendto(net_test.UDP_PAYLOAD, (TEST_ADDR1, 53))
expected_length = xfrm_base.GetEspPacketLength(xfrm.XFRM_MODE_TRANSPORT, 6,
None, net_test.UDP_PAYLOAD)
@@ -200,23 +186,16 @@
# Create inbound and outbound SAs that specify UDP encapsulation.
encaptmpl = xfrm.XfrmEncapTmpl((xfrm.UDP_ENCAP_ESPINUDP, htons(encap_port),
htons(4500), 16 * "\x00"))
- self.xfrm.AddMinimalSaInfo(myaddr, remoteaddr, out_spi, IPPROTO_ESP,
- xfrm.XFRM_MODE_TRANSPORT, out_reqid,
- xfrm_base._ALGO_CBC_AES_256,
- xfrm_base._ENCRYPTION_KEY_256,
- xfrm_base._ALGO_HMAC_SHA1,
- xfrm_base._AUTHENTICATION_KEY_128,
- encaptmpl, None, None, None)
+ self.xfrm.AddSaInfo(myaddr, remoteaddr, out_spi,
+ xfrm.XFRM_MODE_TRANSPORT, out_reqid, None,
+ xfrm_base._ALGO_CBC_AES_256, xfrm_base._ALGO_HMAC_SHA1,
+ encaptmpl, None, None)
# Add an encap template that's the mirror of the outbound one.
encaptmpl.sport, encaptmpl.dport = encaptmpl.dport, encaptmpl.sport
- self.xfrm.AddMinimalSaInfo(remoteaddr, myaddr, in_spi, IPPROTO_ESP,
- xfrm.XFRM_MODE_TRANSPORT, in_reqid,
- xfrm_base._ALGO_CBC_AES_256,
- xfrm_base._ENCRYPTION_KEY_256,
- xfrm_base._ALGO_HMAC_SHA1,
- xfrm_base._AUTHENTICATION_KEY_128,
- encaptmpl, None, None, None)
+ self.xfrm.AddSaInfo(remoteaddr, myaddr, in_spi, xfrm.XFRM_MODE_TRANSPORT,
+ in_reqid, None, xfrm_base._ALGO_CBC_AES_256,
+ xfrm_base._ALGO_HMAC_SHA1, encaptmpl, None, None)
# Uncomment for debugging.
# subprocess.call("ip xfrm state".split())
@@ -355,15 +334,13 @@
remote_addr = self.GetRemoteAddress(version)
# Output
- self.xfrm.AddMinimalSaInfo(
- local_addr, remote_addr, 0xABCD, IPPROTO_ESP, xfrm.XFRM_MODE_TRANSPORT,
- 123, xfrm_base._ALGO_CRYPT_NULL, "", xfrm_base._ALGO_AUTH_NULL, "",
- None, None, None, None)
+ self.xfrm.AddSaInfo(
+ local_addr, remote_addr, 0xABCD, xfrm.XFRM_MODE_TRANSPORT, 123, None,
+ xfrm_base._ALGO_CRYPT_NULL, xfrm_base._ALGO_AUTH_NULL, None, None, None)
# Input
- self.xfrm.AddMinimalSaInfo(
- remote_addr, local_addr, 0x9876, IPPROTO_ESP, xfrm.XFRM_MODE_TRANSPORT,
- 456, xfrm_base._ALGO_CRYPT_NULL, "", xfrm_base._ALGO_AUTH_NULL, "",
- None, None, None, None)
+ self.xfrm.AddSaInfo(
+ remote_addr, local_addr, 0x9876, xfrm.XFRM_MODE_TRANSPORT, 456, None,
+ xfrm_base._ALGO_CRYPT_NULL, xfrm_base._ALGO_AUTH_NULL, None, None, None)
sock = net_test.UDPSocket(family)
self.SelectInterface(sock, netid, "mark")
@@ -435,14 +412,9 @@
# Create a tunnel mode SA and use XFRM_OUTPUT_MARK to bind it to netid.
spi = htonl(TEST_SPI * mark)
reqid = 100 + spi
- self.xfrm.AddMinimalSaInfo(tunsrc, tundst, spi,
- IPPROTO_ESP, xfrm.XFRM_MODE_TUNNEL, reqid,
- xfrm_base._ALGO_CBC_AES_256,
- xfrm_base._ENCRYPTION_KEY_256,
- xfrm_base._ALGO_HMAC_SHA1,
- xfrm_base._AUTHENTICATION_KEY_128,
- None, None, None, mark)
-
+ self.xfrm.AddSaInfo(tunsrc, tundst, spi, xfrm.XFRM_MODE_TUNNEL, reqid, None,
+ xfrm_base._ALGO_CBC_AES_256, xfrm_base._ALGO_HMAC_SHA1,
+ None, None, mark)
# Set a socket policy to use it.
xfrm_base.ApplySocketPolicy(s, family, xfrm.XFRM_POLICY_OUT, spi, reqid,
@@ -489,18 +461,15 @@
self._CheckTunnelModeOutputMark(6, tunsrc, 9999, None)
def testTunnelModeOutputMarkAttributes(self):
- mark = 1234567
- self.xfrm.AddMinimalSaInfo(TEST_ADDR1, TUNNEL_ENDPOINTS[6], 0x1234,
- IPPROTO_ESP, xfrm.XFRM_MODE_TUNNEL, 100,
- xfrm_base._ALGO_CBC_AES_256,
- xfrm_base._ENCRYPTION_KEY_256,
- xfrm_base._ALGO_HMAC_SHA1,
- xfrm_base._AUTHENTICATION_KEY_128,
- None, None, None, mark)
- dump = self.xfrm.DumpSaInfo()
- self.assertEquals(1, len(dump))
- sainfo, attributes = dump[0]
- self.assertEquals(mark, attributes["XFRMA_OUTPUT_MARK"])
+ mark = 1234567
+ self.xfrm.AddSaInfo(TEST_ADDR1, TUNNEL_ENDPOINTS[6], 0x1234,
+ xfrm.XFRM_MODE_TUNNEL, 100, None,
+ xfrm_base._ALGO_CBC_AES_256, xfrm_base._ALGO_HMAC_SHA1,
+ None, None, mark)
+ dump = self.xfrm.DumpSaInfo()
+ self.assertEquals(1, len(dump))
+ sainfo, attributes = dump[0]
+ self.assertEquals(mark, attributes["XFRMA_OUTPUT_MARK"])
if __name__ == "__main__":
diff --git a/net/test/xfrm_tunnel_test.py b/net/test/xfrm_tunnel_test.py
index 0fb4aeb..f05970b 100755
--- a/net/test/xfrm_tunnel_test.py
+++ b/net/test/xfrm_tunnel_test.py
@@ -115,22 +115,14 @@
output_mark: The mark used to select the underlying network for packets
outbound from xfrm.
"""
- self.xfrm.AddMinimalSaInfo(
- tsrc_addr,
- tdst_addr,
- htonl(spi),
- IPPROTO_ESP,
- xfrm.XFRM_MODE_TUNNEL,
- 0,
+ self.xfrm.AddSaInfo(
+ tsrc_addr, tdst_addr,
+ htonl(spi), xfrm.XFRM_MODE_TUNNEL, 0, selector,
xfrm_base._ALGO_CBC_AES_256,
- xfrm_base._ENCRYPTION_KEY_256,
xfrm_base._ALGO_HMAC_SHA1,
- xfrm_base._AUTHENTICATION_KEY_128,
None,
mark,
- xfrm_base.MARK_MASK_ALL if mark is not None else None,
- output_mark,
- selector=selector)
+ output_mark)
policy = xfrm.XfrmUserpolicyInfo(
sel=selector,
@@ -158,9 +150,7 @@
ealgos=xfrm_base.ALL_ALGORITHMS, # encryption algos
calgos=xfrm_base.ALL_ALGORITHMS) # compression algos
- self.xfrm.AddPolicyInfo(policy, tmpl,
- xfrm.XfrmMark((mark, xfrm_base.MARK_MASK_ALL))
- if mark else None)
+ self.xfrm.AddPolicyInfo(policy, tmpl, mark)
def _CheckTunnelOutput(self, inner_version, outer_version):
"""Test a bi-directional XFRM Tunnel with explicit selectors"""
@@ -182,7 +172,6 @@
outer_family=net_test.GetAddressFamily(outer_version),
tsrc_addr=local_outer,
tdst_addr=remote_outer,
- mark=None,
spi=_TEST_OUT_SPI,
output_mark=underlying_netid)
@@ -305,7 +294,7 @@
outer_family=net_test.GetAddressFamily(outer_version),
tsrc_addr=local_outer,
tdst_addr=remote_outer,
- mark=_TEST_OKEY,
+ mark=xfrm.ExactMatchMark(_TEST_OKEY),
spi=_TEST_OUT_SPI,
output_mark=netid)
@@ -315,8 +304,9 @@
outer_family=net_test.GetAddressFamily(outer_version),
tsrc_addr=remote_outer,
tdst_addr=local_outer,
- mark=_TEST_IKEY,
- spi=_TEST_IN_SPI)
+ mark=xfrm.ExactMatchMark(_TEST_IKEY),
+ spi=_TEST_IN_SPI,
+ output_mark=netid)
# Create a socket to receive packets.
read_sock = socket(