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(