1*2f2c4c7aSAndroid Build Coastguard Worker#!/usr/bin/python3 2*2f2c4c7aSAndroid Build Coastguard Worker# 3*2f2c4c7aSAndroid Build Coastguard Worker# Copyright 2017 The Android Open Source Project 4*2f2c4c7aSAndroid Build Coastguard Worker# 5*2f2c4c7aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*2f2c4c7aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*2f2c4c7aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*2f2c4c7aSAndroid Build Coastguard Worker# 9*2f2c4c7aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*2f2c4c7aSAndroid Build Coastguard Worker# 11*2f2c4c7aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*2f2c4c7aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*2f2c4c7aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*2f2c4c7aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*2f2c4c7aSAndroid Build Coastguard Worker# limitations under the License. 16*2f2c4c7aSAndroid Build Coastguard Worker 17*2f2c4c7aSAndroid Build Coastguard Worker# pylint: disable=g-bad-todo,g-bad-file-header,wildcard-import 18*2f2c4c7aSAndroid Build Coastguard Workerfrom errno import * # pylint: disable=wildcard-import 19*2f2c4c7aSAndroid Build Coastguard Workerfrom socket import * # pylint: disable=wildcard-import 20*2f2c4c7aSAndroid Build Coastguard Worker 21*2f2c4c7aSAndroid Build Coastguard Workerimport random 22*2f2c4c7aSAndroid Build Coastguard Workerimport itertools 23*2f2c4c7aSAndroid Build Coastguard Workerimport struct 24*2f2c4c7aSAndroid Build Coastguard Workerimport unittest 25*2f2c4c7aSAndroid Build Coastguard Worker 26*2f2c4c7aSAndroid Build Coastguard Workerfrom net_test import LINUX_VERSION 27*2f2c4c7aSAndroid Build Coastguard Workerfrom scapy import all as scapy 28*2f2c4c7aSAndroid Build Coastguard Workerfrom tun_twister import TunTwister 29*2f2c4c7aSAndroid Build Coastguard Workerimport csocket 30*2f2c4c7aSAndroid Build Coastguard Workerimport iproute 31*2f2c4c7aSAndroid Build Coastguard Workerimport multinetwork_base 32*2f2c4c7aSAndroid Build Coastguard Workerimport net_test 33*2f2c4c7aSAndroid Build Coastguard Workerimport packets 34*2f2c4c7aSAndroid Build Coastguard Workerimport util 35*2f2c4c7aSAndroid Build Coastguard Workerimport xfrm 36*2f2c4c7aSAndroid Build Coastguard Workerimport xfrm_base 37*2f2c4c7aSAndroid Build Coastguard Worker 38*2f2c4c7aSAndroid Build Coastguard Worker_LOOPBACK_IFINDEX = 1 39*2f2c4c7aSAndroid Build Coastguard Worker_TEST_XFRM_IFNAME = "ipsec42" 40*2f2c4c7aSAndroid Build Coastguard Worker_TEST_XFRM_IF_ID = 42 41*2f2c4c7aSAndroid Build Coastguard Worker_TEST_SPI = 0x1234 42*2f2c4c7aSAndroid Build Coastguard Worker 43*2f2c4c7aSAndroid Build Coastguard Worker# Two kernel fixes have been added in 5.17 to allow XFRM_MIGRATE to work correctly 44*2f2c4c7aSAndroid Build Coastguard Worker# when (1) there are multiple tunnels with the same selectors; and (2) addresses 45*2f2c4c7aSAndroid Build Coastguard Worker# are updated to a different IP family. These two fixes were pulled into upstream 46*2f2c4c7aSAndroid Build Coastguard Worker# LTS releases 4.14.273, 4.19.236, 5.4.186, 5.10.107 and 5.15.30, from whence they 47*2f2c4c7aSAndroid Build Coastguard Worker# flowed into the Android Common Kernel (via standard LTS merges). 48*2f2c4c7aSAndroid Build Coastguard Worker# 49*2f2c4c7aSAndroid Build Coastguard Worker# Note 'xfrm: Check if_id in xfrm_migrate' did not end up in 4.14 LTS, 50*2f2c4c7aSAndroid Build Coastguard Worker# and is only present in ACK android-4.14-stable after 4.14.320 LTS merge. 51*2f2c4c7aSAndroid Build Coastguard Worker# See https://android-review.git.corp.google.com/c/kernel/common/+/2640243 52*2f2c4c7aSAndroid Build Coastguard Worker# 53*2f2c4c7aSAndroid Build Coastguard Worker# As such we require 4.14.321+, 4.19.236+, 5.4.186+, 5.10.107+, 5.15.30+ or 5.17+ 54*2f2c4c7aSAndroid Build Coastguard Worker# to have these fixes. 55*2f2c4c7aSAndroid Build Coastguard Workerdef HasXfrmMigrateFixes(): 56*2f2c4c7aSAndroid Build Coastguard Worker return net_test.KernelAtLeast([(4, 19, 236), (5, 4, 186), 57*2f2c4c7aSAndroid Build Coastguard Worker (5, 10, 107), (5, 15, 30)]) or net_test.NonGXI(4, 14) 58*2f2c4c7aSAndroid Build Coastguard Worker 59*2f2c4c7aSAndroid Build Coastguard Worker 60*2f2c4c7aSAndroid Build Coastguard Worker# Does the kernel support CONFIG_XFRM_MIGRATE and include the kernel fixes? 61*2f2c4c7aSAndroid Build Coastguard Workerdef SupportsXfrmMigrate(): 62*2f2c4c7aSAndroid Build Coastguard Worker if not HasXfrmMigrateFixes(): 63*2f2c4c7aSAndroid Build Coastguard Worker return False 64*2f2c4c7aSAndroid Build Coastguard Worker 65*2f2c4c7aSAndroid Build Coastguard Worker # 5.10+ must have CONFIG_XFRM_MIGRATE enabled 66*2f2c4c7aSAndroid Build Coastguard Worker if LINUX_VERSION >= (5, 10, 0): 67*2f2c4c7aSAndroid Build Coastguard Worker return True 68*2f2c4c7aSAndroid Build Coastguard Worker 69*2f2c4c7aSAndroid Build Coastguard Worker try: 70*2f2c4c7aSAndroid Build Coastguard Worker x = xfrm.Xfrm() 71*2f2c4c7aSAndroid Build Coastguard Worker wildcard_addr = net_test.GetWildcardAddress(6) 72*2f2c4c7aSAndroid Build Coastguard Worker selector = xfrm.EmptySelector(AF_INET6) 73*2f2c4c7aSAndroid Build Coastguard Worker 74*2f2c4c7aSAndroid Build Coastguard Worker # Expect migration to fail with EINVAL because it is trying to migrate a 75*2f2c4c7aSAndroid Build Coastguard Worker # non-existent SA. 76*2f2c4c7aSAndroid Build Coastguard Worker x.MigrateTunnel(xfrm.XFRM_POLICY_OUT, selector, wildcard_addr, wildcard_addr, 77*2f2c4c7aSAndroid Build Coastguard Worker wildcard_addr, wildcard_addr, _TEST_SPI, 78*2f2c4c7aSAndroid Build Coastguard Worker None, None, None, None, None, None) 79*2f2c4c7aSAndroid Build Coastguard Worker print("Migration succeeded unexpectedly, assuming XFRM_MIGRATE is enabled") 80*2f2c4c7aSAndroid Build Coastguard Worker return True 81*2f2c4c7aSAndroid Build Coastguard Worker except IOError as err: 82*2f2c4c7aSAndroid Build Coastguard Worker if err.errno == ENOPROTOOPT: 83*2f2c4c7aSAndroid Build Coastguard Worker return False 84*2f2c4c7aSAndroid Build Coastguard Worker elif err.errno == EINVAL: 85*2f2c4c7aSAndroid Build Coastguard Worker return True 86*2f2c4c7aSAndroid Build Coastguard Worker else: 87*2f2c4c7aSAndroid Build Coastguard Worker print("Unexpected error, assuming XFRM_MIGRATE is enabled:", err.errno) 88*2f2c4c7aSAndroid Build Coastguard Worker return True 89*2f2c4c7aSAndroid Build Coastguard Worker 90*2f2c4c7aSAndroid Build Coastguard WorkerSUPPORTS_XFRM_MIGRATE = SupportsXfrmMigrate() 91*2f2c4c7aSAndroid Build Coastguard Worker 92*2f2c4c7aSAndroid Build Coastguard Worker# Parameters to setup tunnels as special networks 93*2f2c4c7aSAndroid Build Coastguard Worker_TUNNEL_NETID_OFFSET = 0xFC00 # Matches reserved netid range for IpSecService 94*2f2c4c7aSAndroid Build Coastguard Worker_BASE_TUNNEL_NETID = {4: 40, 6: 60} 95*2f2c4c7aSAndroid Build Coastguard Worker_BASE_VTI_OKEY = 2000000100 96*2f2c4c7aSAndroid Build Coastguard Worker_BASE_VTI_IKEY = 2000000200 97*2f2c4c7aSAndroid Build Coastguard Worker 98*2f2c4c7aSAndroid Build Coastguard Worker_TEST_OUT_SPI = _TEST_SPI 99*2f2c4c7aSAndroid Build Coastguard Worker_TEST_IN_SPI = _TEST_OUT_SPI 100*2f2c4c7aSAndroid Build Coastguard Worker 101*2f2c4c7aSAndroid Build Coastguard Worker_TEST_OKEY = 2000000100 102*2f2c4c7aSAndroid Build Coastguard Worker_TEST_IKEY = 2000000200 103*2f2c4c7aSAndroid Build Coastguard Worker 104*2f2c4c7aSAndroid Build Coastguard Worker_TEST_REMOTE_PORT = 1234 105*2f2c4c7aSAndroid Build Coastguard Worker 106*2f2c4c7aSAndroid Build Coastguard Worker_SCAPY_IP_TYPE = {4: scapy.IP, 6: scapy.IPv6} 107*2f2c4c7aSAndroid Build Coastguard Worker 108*2f2c4c7aSAndroid Build Coastguard Worker 109*2f2c4c7aSAndroid Build Coastguard Workerdef _GetLocalInnerAddress(version): 110*2f2c4c7aSAndroid Build Coastguard Worker return {4: "10.16.5.15", 6: "2001:db8:1::1"}[version] 111*2f2c4c7aSAndroid Build Coastguard Worker 112*2f2c4c7aSAndroid Build Coastguard Worker 113*2f2c4c7aSAndroid Build Coastguard Workerdef _GetRemoteInnerAddress(version): 114*2f2c4c7aSAndroid Build Coastguard Worker return {4: "10.16.5.20", 6: "2001:db8:2::1"}[version] 115*2f2c4c7aSAndroid Build Coastguard Worker 116*2f2c4c7aSAndroid Build Coastguard Worker 117*2f2c4c7aSAndroid Build Coastguard Workerdef _GetRemoteOuterAddress(version): 118*2f2c4c7aSAndroid Build Coastguard Worker return {4: net_test.IPV4_ADDR, 6: net_test.IPV6_ADDR}[version] 119*2f2c4c7aSAndroid Build Coastguard Worker 120*2f2c4c7aSAndroid Build Coastguard Worker 121*2f2c4c7aSAndroid Build Coastguard Workerdef _GetNullAuthCryptTunnelModePkt(inner_version, src_inner, src_outer, 122*2f2c4c7aSAndroid Build Coastguard Worker src_port, dst_inner, dst_outer, 123*2f2c4c7aSAndroid Build Coastguard Worker dst_port, spi, seq_num, ip_hdr_options=None): 124*2f2c4c7aSAndroid Build Coastguard Worker if ip_hdr_options is None: 125*2f2c4c7aSAndroid Build Coastguard Worker ip_hdr_options = {} 126*2f2c4c7aSAndroid Build Coastguard Worker 127*2f2c4c7aSAndroid Build Coastguard Worker ip_hdr_options.update({'src': src_inner, 'dst': dst_inner}) 128*2f2c4c7aSAndroid Build Coastguard Worker 129*2f2c4c7aSAndroid Build Coastguard Worker # Build and receive an ESP packet destined for the inner socket 130*2f2c4c7aSAndroid Build Coastguard Worker IpType = {4: scapy.IP, 6: scapy.IPv6}[inner_version] 131*2f2c4c7aSAndroid Build Coastguard Worker input_pkt = ( 132*2f2c4c7aSAndroid Build Coastguard Worker IpType(**ip_hdr_options) / scapy.UDP(sport=src_port, dport=dst_port) / 133*2f2c4c7aSAndroid Build Coastguard Worker net_test.UDP_PAYLOAD) 134*2f2c4c7aSAndroid Build Coastguard Worker input_pkt = IpType(bytes(input_pkt)) # Compute length, checksum. 135*2f2c4c7aSAndroid Build Coastguard Worker input_pkt = xfrm_base.EncryptPacketWithNull(input_pkt, spi, seq_num, 136*2f2c4c7aSAndroid Build Coastguard Worker (src_outer, dst_outer)) 137*2f2c4c7aSAndroid Build Coastguard Worker 138*2f2c4c7aSAndroid Build Coastguard Worker return input_pkt 139*2f2c4c7aSAndroid Build Coastguard Worker 140*2f2c4c7aSAndroid Build Coastguard Worker 141*2f2c4c7aSAndroid Build Coastguard Workerdef _CreateReceiveSock(version, port=0): 142*2f2c4c7aSAndroid Build Coastguard Worker # Create a socket to receive packets. 143*2f2c4c7aSAndroid Build Coastguard Worker read_sock = socket(net_test.GetAddressFamily(version), SOCK_DGRAM, 0) 144*2f2c4c7aSAndroid Build Coastguard Worker read_sock.bind((net_test.GetWildcardAddress(version), port)) 145*2f2c4c7aSAndroid Build Coastguard Worker # The second parameter of the tuple is the port number regardless of AF. 146*2f2c4c7aSAndroid Build Coastguard Worker local_port = read_sock.getsockname()[1] 147*2f2c4c7aSAndroid Build Coastguard Worker # Guard against the eventuality of the receive failing. 148*2f2c4c7aSAndroid Build Coastguard Worker csocket.SetSocketTimeout(read_sock, 500) 149*2f2c4c7aSAndroid Build Coastguard Worker 150*2f2c4c7aSAndroid Build Coastguard Worker return read_sock, local_port 151*2f2c4c7aSAndroid Build Coastguard Worker 152*2f2c4c7aSAndroid Build Coastguard Worker 153*2f2c4c7aSAndroid Build Coastguard Workerdef _SendPacket(testInstance, netid, version, remote, remote_port): 154*2f2c4c7aSAndroid Build Coastguard Worker # Send a packet out via the tunnel-backed network, bound for the port number 155*2f2c4c7aSAndroid Build Coastguard Worker # of the input socket. 156*2f2c4c7aSAndroid Build Coastguard Worker write_sock = socket(net_test.GetAddressFamily(version), SOCK_DGRAM, 0) 157*2f2c4c7aSAndroid Build Coastguard Worker testInstance.SelectInterface(write_sock, netid, "mark") 158*2f2c4c7aSAndroid Build Coastguard Worker write_sock.sendto(net_test.UDP_PAYLOAD, (remote, remote_port)) 159*2f2c4c7aSAndroid Build Coastguard Worker local_port = write_sock.getsockname()[1] 160*2f2c4c7aSAndroid Build Coastguard Worker write_sock.close() 161*2f2c4c7aSAndroid Build Coastguard Worker 162*2f2c4c7aSAndroid Build Coastguard Worker return local_port 163*2f2c4c7aSAndroid Build Coastguard Worker 164*2f2c4c7aSAndroid Build Coastguard Worker 165*2f2c4c7aSAndroid Build Coastguard Workerdef InjectTests(): 166*2f2c4c7aSAndroid Build Coastguard Worker InjectParameterizedTests(XfrmTunnelTest) 167*2f2c4c7aSAndroid Build Coastguard Worker InjectParameterizedTests(XfrmInterfaceTest) 168*2f2c4c7aSAndroid Build Coastguard Worker InjectParameterizedTests(XfrmVtiTest) 169*2f2c4c7aSAndroid Build Coastguard Worker InjectParameterizedMigrateTests(XfrmInterfaceMigrateTest) 170*2f2c4c7aSAndroid Build Coastguard Worker 171*2f2c4c7aSAndroid Build Coastguard Worker 172*2f2c4c7aSAndroid Build Coastguard Workerdef InjectParameterizedTests(cls): 173*2f2c4c7aSAndroid Build Coastguard Worker VERSIONS = (4, 6) 174*2f2c4c7aSAndroid Build Coastguard Worker param_list = itertools.product(VERSIONS, VERSIONS) 175*2f2c4c7aSAndroid Build Coastguard Worker 176*2f2c4c7aSAndroid Build Coastguard Worker def NameGenerator(*args): 177*2f2c4c7aSAndroid Build Coastguard Worker return "IPv%d_in_IPv%d" % tuple(args) 178*2f2c4c7aSAndroid Build Coastguard Worker 179*2f2c4c7aSAndroid Build Coastguard Worker util.InjectParameterizedTest(cls, param_list, NameGenerator) 180*2f2c4c7aSAndroid Build Coastguard Worker 181*2f2c4c7aSAndroid Build Coastguard Workerdef InjectParameterizedMigrateTests(cls): 182*2f2c4c7aSAndroid Build Coastguard Worker VERSIONS = (4, 6) 183*2f2c4c7aSAndroid Build Coastguard Worker param_list = itertools.product(VERSIONS, VERSIONS, VERSIONS) 184*2f2c4c7aSAndroid Build Coastguard Worker 185*2f2c4c7aSAndroid Build Coastguard Worker def NameGenerator(*args): 186*2f2c4c7aSAndroid Build Coastguard Worker return "IPv%d_in_IPv%d_to_outer_IPv%d" % tuple(args) 187*2f2c4c7aSAndroid Build Coastguard Worker 188*2f2c4c7aSAndroid Build Coastguard Worker util.InjectParameterizedTest(cls, param_list, NameGenerator) 189*2f2c4c7aSAndroid Build Coastguard Worker 190*2f2c4c7aSAndroid Build Coastguard Worker 191*2f2c4c7aSAndroid Build Coastguard Workerclass XfrmTunnelTest(xfrm_base.XfrmLazyTest): 192*2f2c4c7aSAndroid Build Coastguard Worker 193*2f2c4c7aSAndroid Build Coastguard Worker def _CheckTunnelOutput(self, inner_version, outer_version, underlying_netid, 194*2f2c4c7aSAndroid Build Coastguard Worker netid, local_inner, remote_inner, local_outer, 195*2f2c4c7aSAndroid Build Coastguard Worker remote_outer, write_sock): 196*2f2c4c7aSAndroid Build Coastguard Worker 197*2f2c4c7aSAndroid Build Coastguard Worker write_sock.sendto(net_test.UDP_PAYLOAD, (remote_inner, 53)) 198*2f2c4c7aSAndroid Build Coastguard Worker self._ExpectEspPacketOn(underlying_netid, _TEST_OUT_SPI, 1, None, 199*2f2c4c7aSAndroid Build Coastguard Worker local_outer, remote_outer) 200*2f2c4c7aSAndroid Build Coastguard Worker 201*2f2c4c7aSAndroid Build Coastguard Worker def _CheckTunnelInput(self, inner_version, outer_version, underlying_netid, 202*2f2c4c7aSAndroid Build Coastguard Worker netid, local_inner, remote_inner, local_outer, 203*2f2c4c7aSAndroid Build Coastguard Worker remote_outer, read_sock): 204*2f2c4c7aSAndroid Build Coastguard Worker 205*2f2c4c7aSAndroid Build Coastguard Worker # The second parameter of the tuple is the port number regardless of AF. 206*2f2c4c7aSAndroid Build Coastguard Worker local_port = read_sock.getsockname()[1] 207*2f2c4c7aSAndroid Build Coastguard Worker 208*2f2c4c7aSAndroid Build Coastguard Worker # Build and receive an ESP packet destined for the inner socket 209*2f2c4c7aSAndroid Build Coastguard Worker input_pkt = _GetNullAuthCryptTunnelModePkt( 210*2f2c4c7aSAndroid Build Coastguard Worker inner_version, remote_inner, remote_outer, _TEST_REMOTE_PORT, 211*2f2c4c7aSAndroid Build Coastguard Worker local_inner, local_outer, local_port, _TEST_IN_SPI, 1) 212*2f2c4c7aSAndroid Build Coastguard Worker self.ReceivePacketOn(underlying_netid, input_pkt) 213*2f2c4c7aSAndroid Build Coastguard Worker 214*2f2c4c7aSAndroid Build Coastguard Worker # Verify that the packet data and src are correct 215*2f2c4c7aSAndroid Build Coastguard Worker data, src = read_sock.recvfrom(4096) 216*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(net_test.UDP_PAYLOAD, data) 217*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual((remote_inner, _TEST_REMOTE_PORT), src[:2]) 218*2f2c4c7aSAndroid Build Coastguard Worker 219*2f2c4c7aSAndroid Build Coastguard Worker def _TestTunnel(self, inner_version, outer_version, func, direction, 220*2f2c4c7aSAndroid Build Coastguard Worker test_output_mark_unset): 221*2f2c4c7aSAndroid Build Coastguard Worker """Test a unidirectional XFRM Tunnel with explicit selectors""" 222*2f2c4c7aSAndroid Build Coastguard Worker # Select the underlying netid, which represents the external 223*2f2c4c7aSAndroid Build Coastguard Worker # interface from/to which to route ESP packets. 224*2f2c4c7aSAndroid Build Coastguard Worker u_netid = self.RandomNetid() 225*2f2c4c7aSAndroid Build Coastguard Worker # Select a random netid that will originate traffic locally and 226*2f2c4c7aSAndroid Build Coastguard Worker # which represents the netid on which the plaintext is sent 227*2f2c4c7aSAndroid Build Coastguard Worker netid = self.RandomNetid(exclude=u_netid) 228*2f2c4c7aSAndroid Build Coastguard Worker 229*2f2c4c7aSAndroid Build Coastguard Worker local_inner = self.MyAddress(inner_version, netid) 230*2f2c4c7aSAndroid Build Coastguard Worker remote_inner = _GetRemoteInnerAddress(inner_version) 231*2f2c4c7aSAndroid Build Coastguard Worker local_outer = self.MyAddress(outer_version, u_netid) 232*2f2c4c7aSAndroid Build Coastguard Worker remote_outer = _GetRemoteOuterAddress(outer_version) 233*2f2c4c7aSAndroid Build Coastguard Worker 234*2f2c4c7aSAndroid Build Coastguard Worker output_mark = u_netid 235*2f2c4c7aSAndroid Build Coastguard Worker if test_output_mark_unset: 236*2f2c4c7aSAndroid Build Coastguard Worker output_mark = None 237*2f2c4c7aSAndroid Build Coastguard Worker self.SetDefaultNetwork(u_netid) 238*2f2c4c7aSAndroid Build Coastguard Worker 239*2f2c4c7aSAndroid Build Coastguard Worker try: 240*2f2c4c7aSAndroid Build Coastguard Worker # Create input/ouput SPs, SAs and sockets to simulate a more realistic 241*2f2c4c7aSAndroid Build Coastguard Worker # environment. 242*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.CreateTunnel( 243*2f2c4c7aSAndroid Build Coastguard Worker xfrm.XFRM_POLICY_IN, xfrm.SrcDstSelector(remote_inner, local_inner), 244*2f2c4c7aSAndroid Build Coastguard Worker remote_outer, local_outer, _TEST_IN_SPI, xfrm_base._ALGO_CRYPT_NULL, 245*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_AUTH_NULL, None, None, None, xfrm.MATCH_METHOD_ALL) 246*2f2c4c7aSAndroid Build Coastguard Worker 247*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.CreateTunnel( 248*2f2c4c7aSAndroid Build Coastguard Worker xfrm.XFRM_POLICY_OUT, xfrm.SrcDstSelector(local_inner, remote_inner), 249*2f2c4c7aSAndroid Build Coastguard Worker local_outer, remote_outer, _TEST_OUT_SPI, xfrm_base._ALGO_CBC_AES_256, 250*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_HMAC_SHA1, None, output_mark, None, xfrm.MATCH_METHOD_ALL) 251*2f2c4c7aSAndroid Build Coastguard Worker 252*2f2c4c7aSAndroid Build Coastguard Worker write_sock = socket(net_test.GetAddressFamily(inner_version), SOCK_DGRAM, 0) 253*2f2c4c7aSAndroid Build Coastguard Worker self.SelectInterface(write_sock, netid, "mark") 254*2f2c4c7aSAndroid Build Coastguard Worker read_sock, _ = _CreateReceiveSock(inner_version) 255*2f2c4c7aSAndroid Build Coastguard Worker 256*2f2c4c7aSAndroid Build Coastguard Worker sock = write_sock if direction == xfrm.XFRM_POLICY_OUT else read_sock 257*2f2c4c7aSAndroid Build Coastguard Worker func(inner_version, outer_version, u_netid, netid, local_inner, 258*2f2c4c7aSAndroid Build Coastguard Worker remote_inner, local_outer, remote_outer, sock) 259*2f2c4c7aSAndroid Build Coastguard Worker 260*2f2c4c7aSAndroid Build Coastguard Worker write_sock.close() 261*2f2c4c7aSAndroid Build Coastguard Worker read_sock.close() 262*2f2c4c7aSAndroid Build Coastguard Worker finally: 263*2f2c4c7aSAndroid Build Coastguard Worker if test_output_mark_unset: 264*2f2c4c7aSAndroid Build Coastguard Worker self.ClearDefaultNetwork() 265*2f2c4c7aSAndroid Build Coastguard Worker 266*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestTunnelInput(self, inner_version, outer_version): 267*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, self._CheckTunnelInput, 268*2f2c4c7aSAndroid Build Coastguard Worker xfrm.XFRM_POLICY_IN, False) 269*2f2c4c7aSAndroid Build Coastguard Worker 270*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestTunnelOutput(self, inner_version, outer_version): 271*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, self._CheckTunnelOutput, 272*2f2c4c7aSAndroid Build Coastguard Worker xfrm.XFRM_POLICY_OUT, False) 273*2f2c4c7aSAndroid Build Coastguard Worker 274*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestTunnelOutputNoSetMark(self, inner_version, outer_version): 275*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, self._CheckTunnelOutput, 276*2f2c4c7aSAndroid Build Coastguard Worker xfrm.XFRM_POLICY_OUT, True) 277*2f2c4c7aSAndroid Build Coastguard Worker 278*2f2c4c7aSAndroid Build Coastguard Worker 279*2f2c4c7aSAndroid Build Coastguard Workerclass XfrmAddDeleteVtiTest(xfrm_base.XfrmBaseTest): 280*2f2c4c7aSAndroid Build Coastguard Worker def _VerifyVtiInfoData(self, vti_info_data, version, local_addr, remote_addr, 281*2f2c4c7aSAndroid Build Coastguard Worker ikey, okey): 282*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(vti_info_data["IFLA_VTI_IKEY"], ikey) 283*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(vti_info_data["IFLA_VTI_OKEY"], okey) 284*2f2c4c7aSAndroid Build Coastguard Worker 285*2f2c4c7aSAndroid Build Coastguard Worker family = AF_INET if version == 4 else AF_INET6 286*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(inet_ntop(family, vti_info_data["IFLA_VTI_LOCAL"]), 287*2f2c4c7aSAndroid Build Coastguard Worker local_addr) 288*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(inet_ntop(family, vti_info_data["IFLA_VTI_REMOTE"]), 289*2f2c4c7aSAndroid Build Coastguard Worker remote_addr) 290*2f2c4c7aSAndroid Build Coastguard Worker 291*2f2c4c7aSAndroid Build Coastguard Worker def testAddVti(self): 292*2f2c4c7aSAndroid Build Coastguard Worker """Test the creation of a Virtual Tunnel Interface.""" 293*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 6]: 294*2f2c4c7aSAndroid Build Coastguard Worker netid = self.RandomNetid() 295*2f2c4c7aSAndroid Build Coastguard Worker local_addr = self.MyAddress(version, netid) 296*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.CreateVirtualTunnelInterface( 297*2f2c4c7aSAndroid Build Coastguard Worker dev_name=_TEST_XFRM_IFNAME, 298*2f2c4c7aSAndroid Build Coastguard Worker local_addr=local_addr, 299*2f2c4c7aSAndroid Build Coastguard Worker remote_addr=_GetRemoteOuterAddress(version), 300*2f2c4c7aSAndroid Build Coastguard Worker o_key=_TEST_OKEY, 301*2f2c4c7aSAndroid Build Coastguard Worker i_key=_TEST_IKEY) 302*2f2c4c7aSAndroid Build Coastguard Worker self._VerifyVtiInfoData( 303*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.GetIfinfoData(_TEST_XFRM_IFNAME), version, local_addr, 304*2f2c4c7aSAndroid Build Coastguard Worker _GetRemoteOuterAddress(version), _TEST_IKEY, _TEST_OKEY) 305*2f2c4c7aSAndroid Build Coastguard Worker 306*2f2c4c7aSAndroid Build Coastguard Worker new_remote_addr = {4: net_test.IPV4_ADDR2, 6: net_test.IPV6_ADDR2} 307*2f2c4c7aSAndroid Build Coastguard Worker new_okey = _TEST_OKEY + _TEST_XFRM_IF_ID 308*2f2c4c7aSAndroid Build Coastguard Worker new_ikey = _TEST_IKEY + _TEST_XFRM_IF_ID 309*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.CreateVirtualTunnelInterface( 310*2f2c4c7aSAndroid Build Coastguard Worker dev_name=_TEST_XFRM_IFNAME, 311*2f2c4c7aSAndroid Build Coastguard Worker local_addr=local_addr, 312*2f2c4c7aSAndroid Build Coastguard Worker remote_addr=new_remote_addr[version], 313*2f2c4c7aSAndroid Build Coastguard Worker o_key=new_okey, 314*2f2c4c7aSAndroid Build Coastguard Worker i_key=new_ikey, 315*2f2c4c7aSAndroid Build Coastguard Worker is_update=True) 316*2f2c4c7aSAndroid Build Coastguard Worker 317*2f2c4c7aSAndroid Build Coastguard Worker self._VerifyVtiInfoData( 318*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.GetIfinfoData(_TEST_XFRM_IFNAME), version, local_addr, 319*2f2c4c7aSAndroid Build Coastguard Worker new_remote_addr[version], new_ikey, new_okey) 320*2f2c4c7aSAndroid Build Coastguard Worker 321*2f2c4c7aSAndroid Build Coastguard Worker if_index = self.iproute.GetIfIndex(_TEST_XFRM_IFNAME) 322*2f2c4c7aSAndroid Build Coastguard Worker 323*2f2c4c7aSAndroid Build Coastguard Worker # Validate that the netlink interface matches the ioctl interface. 324*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(net_test.GetInterfaceIndex(_TEST_XFRM_IFNAME), if_index) 325*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.DeleteLink(_TEST_XFRM_IFNAME) 326*2f2c4c7aSAndroid Build Coastguard Worker with self.assertRaises(IOError): 327*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.GetIfIndex(_TEST_XFRM_IFNAME) 328*2f2c4c7aSAndroid Build Coastguard Worker 329*2f2c4c7aSAndroid Build Coastguard Worker def _QuietDeleteLink(self, ifname): 330*2f2c4c7aSAndroid Build Coastguard Worker try: 331*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.DeleteLink(ifname) 332*2f2c4c7aSAndroid Build Coastguard Worker except IOError: 333*2f2c4c7aSAndroid Build Coastguard Worker # The link was not present. 334*2f2c4c7aSAndroid Build Coastguard Worker pass 335*2f2c4c7aSAndroid Build Coastguard Worker 336*2f2c4c7aSAndroid Build Coastguard Worker def tearDown(self): 337*2f2c4c7aSAndroid Build Coastguard Worker super(XfrmAddDeleteVtiTest, self).tearDown() 338*2f2c4c7aSAndroid Build Coastguard Worker self._QuietDeleteLink(_TEST_XFRM_IFNAME) 339*2f2c4c7aSAndroid Build Coastguard Worker 340*2f2c4c7aSAndroid Build Coastguard Worker 341*2f2c4c7aSAndroid Build Coastguard Workerclass SaInfo(object): 342*2f2c4c7aSAndroid Build Coastguard Worker 343*2f2c4c7aSAndroid Build Coastguard Worker def __init__(self, spi): 344*2f2c4c7aSAndroid Build Coastguard Worker self.spi = spi 345*2f2c4c7aSAndroid Build Coastguard Worker self.seq_num = 1 346*2f2c4c7aSAndroid Build Coastguard Worker 347*2f2c4c7aSAndroid Build Coastguard Worker 348*2f2c4c7aSAndroid Build Coastguard Workerclass IpSecBaseInterface(object): 349*2f2c4c7aSAndroid Build Coastguard Worker 350*2f2c4c7aSAndroid Build Coastguard Worker def __init__(self, iface, netid, underlying_netid, local, remote, version): 351*2f2c4c7aSAndroid Build Coastguard Worker self.iface = iface 352*2f2c4c7aSAndroid Build Coastguard Worker self.netid = netid 353*2f2c4c7aSAndroid Build Coastguard Worker self.underlying_netid = underlying_netid 354*2f2c4c7aSAndroid Build Coastguard Worker self.local, self.remote = local, remote 355*2f2c4c7aSAndroid Build Coastguard Worker 356*2f2c4c7aSAndroid Build Coastguard Worker # XFRM interfaces technically do not have a version. This keeps track of 357*2f2c4c7aSAndroid Build Coastguard Worker # the IP version of the local and remote addresses. 358*2f2c4c7aSAndroid Build Coastguard Worker self.version = version 359*2f2c4c7aSAndroid Build Coastguard Worker self.rx = self.tx = 0 360*2f2c4c7aSAndroid Build Coastguard Worker self.addrs = {} 361*2f2c4c7aSAndroid Build Coastguard Worker 362*2f2c4c7aSAndroid Build Coastguard Worker self.iproute = iproute.IPRoute() 363*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm = xfrm.Xfrm() 364*2f2c4c7aSAndroid Build Coastguard Worker 365*2f2c4c7aSAndroid Build Coastguard Worker def Teardown(self): 366*2f2c4c7aSAndroid Build Coastguard Worker self.TeardownXfrm() 367*2f2c4c7aSAndroid Build Coastguard Worker self.TeardownInterface() 368*2f2c4c7aSAndroid Build Coastguard Worker 369*2f2c4c7aSAndroid Build Coastguard Worker def TeardownInterface(self): 370*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.DeleteLink(self.iface) 371*2f2c4c7aSAndroid Build Coastguard Worker 372*2f2c4c7aSAndroid Build Coastguard Worker def SetupXfrm(self, use_null_crypt): 373*2f2c4c7aSAndroid Build Coastguard Worker rand_spi = random.randint(0, 0x7fffffff) 374*2f2c4c7aSAndroid Build Coastguard Worker self.in_sa = SaInfo(rand_spi) 375*2f2c4c7aSAndroid Build Coastguard Worker self.out_sa = SaInfo(rand_spi) 376*2f2c4c7aSAndroid Build Coastguard Worker 377*2f2c4c7aSAndroid Build Coastguard Worker # Select algorithms: 378*2f2c4c7aSAndroid Build Coastguard Worker if use_null_crypt: 379*2f2c4c7aSAndroid Build Coastguard Worker auth, crypt = xfrm_base._ALGO_AUTH_NULL, xfrm_base._ALGO_CRYPT_NULL 380*2f2c4c7aSAndroid Build Coastguard Worker else: 381*2f2c4c7aSAndroid Build Coastguard Worker auth, crypt = xfrm_base._ALGO_HMAC_SHA1, xfrm_base._ALGO_CBC_AES_256 382*2f2c4c7aSAndroid Build Coastguard Worker 383*2f2c4c7aSAndroid Build Coastguard Worker self.auth = auth 384*2f2c4c7aSAndroid Build Coastguard Worker self.crypt = crypt 385*2f2c4c7aSAndroid Build Coastguard Worker 386*2f2c4c7aSAndroid Build Coastguard Worker self._SetupXfrmByType(auth, crypt) 387*2f2c4c7aSAndroid Build Coastguard Worker 388*2f2c4c7aSAndroid Build Coastguard Worker def Rekey(self, outer_family, new_out_sa, new_in_sa): 389*2f2c4c7aSAndroid Build Coastguard Worker """Rekeys the Tunnel Interface 390*2f2c4c7aSAndroid Build Coastguard Worker 391*2f2c4c7aSAndroid Build Coastguard Worker Creates new SAs and updates the outbound security policy to use new SAs. 392*2f2c4c7aSAndroid Build Coastguard Worker 393*2f2c4c7aSAndroid Build Coastguard Worker Args: 394*2f2c4c7aSAndroid Build Coastguard Worker outer_family: AF_INET or AF_INET6 395*2f2c4c7aSAndroid Build Coastguard Worker new_out_sa: An SaInfo struct representing the new outbound SA's info 396*2f2c4c7aSAndroid Build Coastguard Worker new_in_sa: An SaInfo struct representing the new inbound SA's info 397*2f2c4c7aSAndroid Build Coastguard Worker """ 398*2f2c4c7aSAndroid Build Coastguard Worker self._Rekey(outer_family, new_out_sa, new_in_sa) 399*2f2c4c7aSAndroid Build Coastguard Worker 400*2f2c4c7aSAndroid Build Coastguard Worker # Update Interface object 401*2f2c4c7aSAndroid Build Coastguard Worker self.out_sa = new_out_sa 402*2f2c4c7aSAndroid Build Coastguard Worker self.in_sa = new_in_sa 403*2f2c4c7aSAndroid Build Coastguard Worker 404*2f2c4c7aSAndroid Build Coastguard Worker def TeardownXfrm(self): 405*2f2c4c7aSAndroid Build Coastguard Worker raise NotImplementedError("Subclasses should implement this") 406*2f2c4c7aSAndroid Build Coastguard Worker 407*2f2c4c7aSAndroid Build Coastguard Worker def _SetupXfrmByType(self, auth_algo, crypt_algo): 408*2f2c4c7aSAndroid Build Coastguard Worker raise NotImplementedError("Subclasses should implement this") 409*2f2c4c7aSAndroid Build Coastguard Worker 410*2f2c4c7aSAndroid Build Coastguard Worker def _Rekey(self, outer_family, new_out_sa, new_in_sa): 411*2f2c4c7aSAndroid Build Coastguard Worker raise NotImplementedError("Subclasses should implement this") 412*2f2c4c7aSAndroid Build Coastguard Worker 413*2f2c4c7aSAndroid Build Coastguard Worker 414*2f2c4c7aSAndroid Build Coastguard Workerclass VtiInterface(IpSecBaseInterface): 415*2f2c4c7aSAndroid Build Coastguard Worker 416*2f2c4c7aSAndroid Build Coastguard Worker def __init__(self, iface, netid, underlying_netid, _, local, remote, version): 417*2f2c4c7aSAndroid Build Coastguard Worker super(VtiInterface, self).__init__(iface, netid, underlying_netid, local, 418*2f2c4c7aSAndroid Build Coastguard Worker remote, version) 419*2f2c4c7aSAndroid Build Coastguard Worker 420*2f2c4c7aSAndroid Build Coastguard Worker self.ikey = _TEST_IKEY + netid 421*2f2c4c7aSAndroid Build Coastguard Worker self.okey = _TEST_OKEY + netid 422*2f2c4c7aSAndroid Build Coastguard Worker 423*2f2c4c7aSAndroid Build Coastguard Worker self.SetupInterface() 424*2f2c4c7aSAndroid Build Coastguard Worker self.SetupXfrm(False) 425*2f2c4c7aSAndroid Build Coastguard Worker 426*2f2c4c7aSAndroid Build Coastguard Worker def SetupInterface(self): 427*2f2c4c7aSAndroid Build Coastguard Worker return self.iproute.CreateVirtualTunnelInterface( 428*2f2c4c7aSAndroid Build Coastguard Worker self.iface, self.local, self.remote, self.ikey, self.okey) 429*2f2c4c7aSAndroid Build Coastguard Worker 430*2f2c4c7aSAndroid Build Coastguard Worker def _SetupXfrmByType(self, auth_algo, crypt_algo): 431*2f2c4c7aSAndroid Build Coastguard Worker # For the VTI, the selectors are wildcard since packets will only 432*2f2c4c7aSAndroid Build Coastguard Worker # be selected if they have the appropriate mark, hence the inner 433*2f2c4c7aSAndroid Build Coastguard Worker # addresses are wildcard. 434*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.CreateTunnel(xfrm.XFRM_POLICY_OUT, None, self.local, self.remote, 435*2f2c4c7aSAndroid Build Coastguard Worker self.out_sa.spi, crypt_algo, auth_algo, 436*2f2c4c7aSAndroid Build Coastguard Worker xfrm.ExactMatchMark(self.okey), 437*2f2c4c7aSAndroid Build Coastguard Worker self.underlying_netid, None, xfrm.MATCH_METHOD_ALL) 438*2f2c4c7aSAndroid Build Coastguard Worker 439*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.CreateTunnel(xfrm.XFRM_POLICY_IN, None, self.remote, self.local, 440*2f2c4c7aSAndroid Build Coastguard Worker self.in_sa.spi, crypt_algo, auth_algo, 441*2f2c4c7aSAndroid Build Coastguard Worker xfrm.ExactMatchMark(self.ikey), None, None, 442*2f2c4c7aSAndroid Build Coastguard Worker xfrm.MATCH_METHOD_MARK) 443*2f2c4c7aSAndroid Build Coastguard Worker 444*2f2c4c7aSAndroid Build Coastguard Worker def TeardownXfrm(self): 445*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteTunnel(xfrm.XFRM_POLICY_OUT, None, self.remote, 446*2f2c4c7aSAndroid Build Coastguard Worker self.out_sa.spi, self.okey, None) 447*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteTunnel(xfrm.XFRM_POLICY_IN, None, self.local, 448*2f2c4c7aSAndroid Build Coastguard Worker self.in_sa.spi, self.ikey, None) 449*2f2c4c7aSAndroid Build Coastguard Worker 450*2f2c4c7aSAndroid Build Coastguard Worker def _Rekey(self, outer_family, new_out_sa, new_in_sa): 451*2f2c4c7aSAndroid Build Coastguard Worker # TODO: Consider ways to share code with xfrm.CreateTunnel(). It's mostly 452*2f2c4c7aSAndroid Build Coastguard Worker # the same, but rekeys are asymmetric, and only update the outbound 453*2f2c4c7aSAndroid Build Coastguard Worker # policy. 454*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo(self.local, self.remote, new_out_sa.spi, 455*2f2c4c7aSAndroid Build Coastguard Worker xfrm.XFRM_MODE_TUNNEL, 0, xfrm_base._ALGO_CRYPT_NULL, 456*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_AUTH_NULL, None, None, 457*2f2c4c7aSAndroid Build Coastguard Worker xfrm.ExactMatchMark(self.okey), self.underlying_netid) 458*2f2c4c7aSAndroid Build Coastguard Worker 459*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo(self.remote, self.local, new_in_sa.spi, 460*2f2c4c7aSAndroid Build Coastguard Worker xfrm.XFRM_MODE_TUNNEL, 0, xfrm_base._ALGO_CRYPT_NULL, 461*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_AUTH_NULL, None, None, 462*2f2c4c7aSAndroid Build Coastguard Worker xfrm.ExactMatchMark(self.ikey), None) 463*2f2c4c7aSAndroid Build Coastguard Worker 464*2f2c4c7aSAndroid Build Coastguard Worker # Create new policies for IPv4 and IPv6. 465*2f2c4c7aSAndroid Build Coastguard Worker for sel in [xfrm.EmptySelector(AF_INET), xfrm.EmptySelector(AF_INET6)]: 466*2f2c4c7aSAndroid Build Coastguard Worker # Add SPI-specific output policy to enforce using new outbound SPI 467*2f2c4c7aSAndroid Build Coastguard Worker policy = xfrm.UserPolicy(xfrm.XFRM_POLICY_OUT, sel) 468*2f2c4c7aSAndroid Build Coastguard Worker tmpl = xfrm.UserTemplate(outer_family, new_out_sa.spi, 0, 469*2f2c4c7aSAndroid Build Coastguard Worker (self.local, self.remote)) 470*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.UpdatePolicyInfo(policy, tmpl, xfrm.ExactMatchMark(self.okey), 471*2f2c4c7aSAndroid Build Coastguard Worker 0) 472*2f2c4c7aSAndroid Build Coastguard Worker 473*2f2c4c7aSAndroid Build Coastguard Worker def DeleteOldSaInfo(self, outer_family, old_in_spi, old_out_spi): 474*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteSaInfo(self.local, old_in_spi, IPPROTO_ESP, 475*2f2c4c7aSAndroid Build Coastguard Worker xfrm.ExactMatchMark(self.ikey)) 476*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteSaInfo(self.remote, old_out_spi, IPPROTO_ESP, 477*2f2c4c7aSAndroid Build Coastguard Worker xfrm.ExactMatchMark(self.okey)) 478*2f2c4c7aSAndroid Build Coastguard Worker 479*2f2c4c7aSAndroid Build Coastguard Worker 480*2f2c4c7aSAndroid Build Coastguard Workerclass XfrmAddDeleteXfrmInterfaceTest(xfrm_base.XfrmBaseTest): 481*2f2c4c7aSAndroid Build Coastguard Worker """Test the creation of an XFRM Interface.""" 482*2f2c4c7aSAndroid Build Coastguard Worker 483*2f2c4c7aSAndroid Build Coastguard Worker def testAddXfrmInterface(self): 484*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.CreateXfrmInterface(_TEST_XFRM_IFNAME, _TEST_XFRM_IF_ID, 485*2f2c4c7aSAndroid Build Coastguard Worker _LOOPBACK_IFINDEX) 486*2f2c4c7aSAndroid Build Coastguard Worker if_index = self.iproute.GetIfIndex(_TEST_XFRM_IFNAME) 487*2f2c4c7aSAndroid Build Coastguard Worker net_test.SetInterfaceUp(_TEST_XFRM_IFNAME) 488*2f2c4c7aSAndroid Build Coastguard Worker 489*2f2c4c7aSAndroid Build Coastguard Worker # Validate that the netlink interface matches the ioctl interface. 490*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(net_test.GetInterfaceIndex(_TEST_XFRM_IFNAME), if_index) 491*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.DeleteLink(_TEST_XFRM_IFNAME) 492*2f2c4c7aSAndroid Build Coastguard Worker with self.assertRaises(IOError): 493*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.GetIfIndex(_TEST_XFRM_IFNAME) 494*2f2c4c7aSAndroid Build Coastguard Worker 495*2f2c4c7aSAndroid Build Coastguard Worker 496*2f2c4c7aSAndroid Build Coastguard Workerclass XfrmInterface(IpSecBaseInterface): 497*2f2c4c7aSAndroid Build Coastguard Worker 498*2f2c4c7aSAndroid Build Coastguard Worker def __init__(self, iface, netid, underlying_netid, ifindex, local, remote, 499*2f2c4c7aSAndroid Build Coastguard Worker version, use_null_crypt=False): 500*2f2c4c7aSAndroid Build Coastguard Worker super(XfrmInterface, self).__init__(iface, netid, underlying_netid, local, 501*2f2c4c7aSAndroid Build Coastguard Worker remote, version) 502*2f2c4c7aSAndroid Build Coastguard Worker 503*2f2c4c7aSAndroid Build Coastguard Worker self.ifindex = ifindex 504*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm_if_id = netid 505*2f2c4c7aSAndroid Build Coastguard Worker 506*2f2c4c7aSAndroid Build Coastguard Worker self.SetupInterface() 507*2f2c4c7aSAndroid Build Coastguard Worker self.SetupXfrm(use_null_crypt) 508*2f2c4c7aSAndroid Build Coastguard Worker 509*2f2c4c7aSAndroid Build Coastguard Worker def SetupInterface(self): 510*2f2c4c7aSAndroid Build Coastguard Worker """Create an XFRM interface.""" 511*2f2c4c7aSAndroid Build Coastguard Worker return self.iproute.CreateXfrmInterface(self.iface, self.netid, self.ifindex) 512*2f2c4c7aSAndroid Build Coastguard Worker 513*2f2c4c7aSAndroid Build Coastguard Worker def _SetupXfrmByType(self, auth_algo, crypt_algo): 514*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.CreateTunnel(xfrm.XFRM_POLICY_OUT, None, self.local, self.remote, 515*2f2c4c7aSAndroid Build Coastguard Worker self.out_sa.spi, crypt_algo, auth_algo, None, 516*2f2c4c7aSAndroid Build Coastguard Worker self.underlying_netid, self.xfrm_if_id, 517*2f2c4c7aSAndroid Build Coastguard Worker xfrm.MATCH_METHOD_ALL) 518*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.CreateTunnel(xfrm.XFRM_POLICY_IN, None, self.remote, self.local, 519*2f2c4c7aSAndroid Build Coastguard Worker self.in_sa.spi, crypt_algo, auth_algo, None, None, 520*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm_if_id, xfrm.MATCH_METHOD_IFID) 521*2f2c4c7aSAndroid Build Coastguard Worker 522*2f2c4c7aSAndroid Build Coastguard Worker def TeardownXfrm(self): 523*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteTunnel(xfrm.XFRM_POLICY_OUT, None, self.remote, 524*2f2c4c7aSAndroid Build Coastguard Worker self.out_sa.spi, None, self.xfrm_if_id) 525*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteTunnel(xfrm.XFRM_POLICY_IN, None, self.local, 526*2f2c4c7aSAndroid Build Coastguard Worker self.in_sa.spi, None, self.xfrm_if_id) 527*2f2c4c7aSAndroid Build Coastguard Worker 528*2f2c4c7aSAndroid Build Coastguard Worker def _Rekey(self, outer_family, new_out_sa, new_in_sa): 529*2f2c4c7aSAndroid Build Coastguard Worker # TODO: Consider ways to share code with xfrm.CreateTunnel(). It's mostly 530*2f2c4c7aSAndroid Build Coastguard Worker # the same, but rekeys are asymmetric, and only update the outbound 531*2f2c4c7aSAndroid Build Coastguard Worker # policy. 532*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo( 533*2f2c4c7aSAndroid Build Coastguard Worker self.local, self.remote, new_out_sa.spi, xfrm.XFRM_MODE_TUNNEL, 0, 534*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CRYPT_NULL, xfrm_base._ALGO_AUTH_NULL, None, None, 535*2f2c4c7aSAndroid Build Coastguard Worker None, self.underlying_netid, xfrm_if_id=self.xfrm_if_id) 536*2f2c4c7aSAndroid Build Coastguard Worker 537*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.AddSaInfo( 538*2f2c4c7aSAndroid Build Coastguard Worker self.remote, self.local, new_in_sa.spi, xfrm.XFRM_MODE_TUNNEL, 0, 539*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base._ALGO_CRYPT_NULL, xfrm_base._ALGO_AUTH_NULL, None, None, 540*2f2c4c7aSAndroid Build Coastguard Worker None, None, xfrm_if_id=self.xfrm_if_id) 541*2f2c4c7aSAndroid Build Coastguard Worker 542*2f2c4c7aSAndroid Build Coastguard Worker # Create new policies for IPv4 and IPv6. 543*2f2c4c7aSAndroid Build Coastguard Worker for sel in [xfrm.EmptySelector(AF_INET), xfrm.EmptySelector(AF_INET6)]: 544*2f2c4c7aSAndroid Build Coastguard Worker # Add SPI-specific output policy to enforce using new outbound SPI 545*2f2c4c7aSAndroid Build Coastguard Worker policy = xfrm.UserPolicy(xfrm.XFRM_POLICY_OUT, sel) 546*2f2c4c7aSAndroid Build Coastguard Worker tmpl = xfrm.UserTemplate(outer_family, new_out_sa.spi, 0, 547*2f2c4c7aSAndroid Build Coastguard Worker (self.local, self.remote)) 548*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.UpdatePolicyInfo(policy, tmpl, None, self.xfrm_if_id) 549*2f2c4c7aSAndroid Build Coastguard Worker 550*2f2c4c7aSAndroid Build Coastguard Worker def DeleteOldSaInfo(self, outer_family, old_in_spi, old_out_spi): 551*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteSaInfo(self.local, old_in_spi, IPPROTO_ESP, None, 552*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm_if_id) 553*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.DeleteSaInfo(self.remote, old_out_spi, IPPROTO_ESP, None, 554*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm_if_id) 555*2f2c4c7aSAndroid Build Coastguard Worker 556*2f2c4c7aSAndroid Build Coastguard Worker def Migrate(self, new_underlying_netid, new_local, new_remote): 557*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.MigrateTunnel(xfrm.XFRM_POLICY_IN, None, self.remote, self.local, 558*2f2c4c7aSAndroid Build Coastguard Worker new_remote, new_local, self.in_sa.spi, 559*2f2c4c7aSAndroid Build Coastguard Worker self.crypt, self.auth, None, None, 560*2f2c4c7aSAndroid Build Coastguard Worker new_underlying_netid, self.xfrm_if_id) 561*2f2c4c7aSAndroid Build Coastguard Worker 562*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm.MigrateTunnel(xfrm.XFRM_POLICY_OUT, None, self.local, self.remote, 563*2f2c4c7aSAndroid Build Coastguard Worker new_local, new_remote, self.out_sa.spi, 564*2f2c4c7aSAndroid Build Coastguard Worker self.crypt, self.auth, None, None, 565*2f2c4c7aSAndroid Build Coastguard Worker new_underlying_netid, self.xfrm_if_id) 566*2f2c4c7aSAndroid Build Coastguard Worker 567*2f2c4c7aSAndroid Build Coastguard Worker self.local = new_local 568*2f2c4c7aSAndroid Build Coastguard Worker self.remote = new_remote 569*2f2c4c7aSAndroid Build Coastguard Worker self.version = net_test.GetAddressVersion(new_local) 570*2f2c4c7aSAndroid Build Coastguard Worker self.underlying_netid = new_underlying_netid 571*2f2c4c7aSAndroid Build Coastguard Worker 572*2f2c4c7aSAndroid Build Coastguard Worker 573*2f2c4c7aSAndroid Build Coastguard Workerclass XfrmTunnelBase(xfrm_base.XfrmBaseTest): 574*2f2c4c7aSAndroid Build Coastguard Worker 575*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 576*2f2c4c7aSAndroid Build Coastguard Worker def setUpClass(cls): 577*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.XfrmBaseTest.setUpClass() 578*2f2c4c7aSAndroid Build Coastguard Worker # Tunnel interfaces use marks extensively, so configure realistic packet 579*2f2c4c7aSAndroid Build Coastguard Worker # marking rules to make the test representative, make PMTUD work, etc. 580*2f2c4c7aSAndroid Build Coastguard Worker cls.SetInboundMarks(True) 581*2f2c4c7aSAndroid Build Coastguard Worker cls.SetMarkReflectSysctls(1) 582*2f2c4c7aSAndroid Build Coastguard Worker 583*2f2c4c7aSAndroid Build Coastguard Worker # Group by tunnel version to ensure that we test at least one IPv4 and one 584*2f2c4c7aSAndroid Build Coastguard Worker # IPv6 tunnel 585*2f2c4c7aSAndroid Build Coastguard Worker cls.tunnelsV4 = {} 586*2f2c4c7aSAndroid Build Coastguard Worker cls.tunnelsV6 = {} 587*2f2c4c7aSAndroid Build Coastguard Worker 588*2f2c4c7aSAndroid Build Coastguard Worker for i, underlying_netid in enumerate(cls.tuns): 589*2f2c4c7aSAndroid Build Coastguard Worker for version in 4, 6: 590*2f2c4c7aSAndroid Build Coastguard Worker netid = _BASE_TUNNEL_NETID[version] + _TUNNEL_NETID_OFFSET + i 591*2f2c4c7aSAndroid Build Coastguard Worker iface = "ipsec%s" % netid 592*2f2c4c7aSAndroid Build Coastguard Worker local = cls.MyAddress(version, underlying_netid) 593*2f2c4c7aSAndroid Build Coastguard Worker if version == 4: 594*2f2c4c7aSAndroid Build Coastguard Worker remote = (net_test.IPV4_ADDR if (i % 2) else net_test.IPV4_ADDR2) 595*2f2c4c7aSAndroid Build Coastguard Worker else: 596*2f2c4c7aSAndroid Build Coastguard Worker remote = (net_test.IPV6_ADDR if (i % 2) else net_test.IPV6_ADDR2) 597*2f2c4c7aSAndroid Build Coastguard Worker 598*2f2c4c7aSAndroid Build Coastguard Worker ifindex = cls.ifindices[underlying_netid] 599*2f2c4c7aSAndroid Build Coastguard Worker tunnel = cls.INTERFACE_CLASS(iface, netid, underlying_netid, ifindex, 600*2f2c4c7aSAndroid Build Coastguard Worker local, remote, version) 601*2f2c4c7aSAndroid Build Coastguard Worker cls._SetInboundMarking(netid, iface, True) 602*2f2c4c7aSAndroid Build Coastguard Worker cls._SetupTunnelNetwork(tunnel, True) 603*2f2c4c7aSAndroid Build Coastguard Worker 604*2f2c4c7aSAndroid Build Coastguard Worker if version == 4: 605*2f2c4c7aSAndroid Build Coastguard Worker cls.tunnelsV4[netid] = tunnel 606*2f2c4c7aSAndroid Build Coastguard Worker else: 607*2f2c4c7aSAndroid Build Coastguard Worker cls.tunnelsV6[netid] = tunnel 608*2f2c4c7aSAndroid Build Coastguard Worker 609*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 610*2f2c4c7aSAndroid Build Coastguard Worker def tearDownClass(cls): 611*2f2c4c7aSAndroid Build Coastguard Worker # The sysctls are restored by MultinetworkBaseTest.tearDownClass. 612*2f2c4c7aSAndroid Build Coastguard Worker cls.SetInboundMarks(False) 613*2f2c4c7aSAndroid Build Coastguard Worker for tunnel in list(cls.tunnelsV4.values()) + list(cls.tunnelsV6.values()): 614*2f2c4c7aSAndroid Build Coastguard Worker cls._SetInboundMarking(tunnel.netid, tunnel.iface, False) 615*2f2c4c7aSAndroid Build Coastguard Worker cls._SetupTunnelNetwork(tunnel, False) 616*2f2c4c7aSAndroid Build Coastguard Worker tunnel.Teardown() 617*2f2c4c7aSAndroid Build Coastguard Worker xfrm_base.XfrmBaseTest.tearDownClass() 618*2f2c4c7aSAndroid Build Coastguard Worker 619*2f2c4c7aSAndroid Build Coastguard Worker def randomTunnel(self, outer_version): 620*2f2c4c7aSAndroid Build Coastguard Worker version_dict = self.tunnelsV4 if outer_version == 4 else self.tunnelsV6 621*2f2c4c7aSAndroid Build Coastguard Worker return random.choice(list(version_dict.values())) 622*2f2c4c7aSAndroid Build Coastguard Worker 623*2f2c4c7aSAndroid Build Coastguard Worker def setUp(self): 624*2f2c4c7aSAndroid Build Coastguard Worker multinetwork_base.MultiNetworkBaseTest.setUp(self) 625*2f2c4c7aSAndroid Build Coastguard Worker self.iproute = iproute.IPRoute() 626*2f2c4c7aSAndroid Build Coastguard Worker self.xfrm = xfrm.Xfrm() 627*2f2c4c7aSAndroid Build Coastguard Worker 628*2f2c4c7aSAndroid Build Coastguard Worker def tearDown(self): 629*2f2c4c7aSAndroid Build Coastguard Worker multinetwork_base.MultiNetworkBaseTest.tearDown(self) 630*2f2c4c7aSAndroid Build Coastguard Worker 631*2f2c4c7aSAndroid Build Coastguard Worker def _SwapInterfaceAddress(self, ifname, old_addr, new_addr): 632*2f2c4c7aSAndroid Build Coastguard Worker """Exchange two addresses on a given interface. 633*2f2c4c7aSAndroid Build Coastguard Worker 634*2f2c4c7aSAndroid Build Coastguard Worker Args: 635*2f2c4c7aSAndroid Build Coastguard Worker ifname: Name of the interface 636*2f2c4c7aSAndroid Build Coastguard Worker old_addr: An address to be removed from the interface 637*2f2c4c7aSAndroid Build Coastguard Worker new_addr: An address to be added to an interface 638*2f2c4c7aSAndroid Build Coastguard Worker """ 639*2f2c4c7aSAndroid Build Coastguard Worker version = 6 if ":" in new_addr else 4 640*2f2c4c7aSAndroid Build Coastguard Worker ifindex = net_test.GetInterfaceIndex(ifname) 641*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.AddAddress(new_addr, 642*2f2c4c7aSAndroid Build Coastguard Worker net_test.AddressLengthBits(version), ifindex) 643*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.DelAddress(old_addr, 644*2f2c4c7aSAndroid Build Coastguard Worker net_test.AddressLengthBits(version), ifindex) 645*2f2c4c7aSAndroid Build Coastguard Worker 646*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 647*2f2c4c7aSAndroid Build Coastguard Worker def _GetLocalAddress(cls, version, netid): 648*2f2c4c7aSAndroid Build Coastguard Worker if version == 4: 649*2f2c4c7aSAndroid Build Coastguard Worker return cls._MyIPv4Address(netid - _TUNNEL_NETID_OFFSET) 650*2f2c4c7aSAndroid Build Coastguard Worker else: 651*2f2c4c7aSAndroid Build Coastguard Worker return cls.OnlinkPrefix(6, netid - _TUNNEL_NETID_OFFSET) + "1" 652*2f2c4c7aSAndroid Build Coastguard Worker 653*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 654*2f2c4c7aSAndroid Build Coastguard Worker def UidRangeForTunnelNetId(cls, netid): 655*2f2c4c7aSAndroid Build Coastguard Worker if netid < _TUNNEL_NETID_OFFSET: 656*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Tunnel netid outside tunnel range") 657*2f2c4c7aSAndroid Build Coastguard Worker netid -= _TUNNEL_NETID_OFFSET 658*2f2c4c7aSAndroid Build Coastguard Worker return (500 + 50 * netid, 500 + 50 * (netid + 1) - 1) 659*2f2c4c7aSAndroid Build Coastguard Worker 660*2f2c4c7aSAndroid Build Coastguard Worker @classmethod 661*2f2c4c7aSAndroid Build Coastguard Worker def _SetupTunnelNetwork(cls, tunnel, is_add): 662*2f2c4c7aSAndroid Build Coastguard Worker """Setup rules and routes for a tunnel Network. 663*2f2c4c7aSAndroid Build Coastguard Worker 664*2f2c4c7aSAndroid Build Coastguard Worker Takes an interface and depending on the boolean 665*2f2c4c7aSAndroid Build Coastguard Worker value of is_add, either adds or removes the rules 666*2f2c4c7aSAndroid Build Coastguard Worker and routes for a tunnel interface to behave like an 667*2f2c4c7aSAndroid Build Coastguard Worker Android Network for purposes of testing. 668*2f2c4c7aSAndroid Build Coastguard Worker 669*2f2c4c7aSAndroid Build Coastguard Worker Args: 670*2f2c4c7aSAndroid Build Coastguard Worker tunnel: A VtiInterface or XfrmInterface, the tunnel to set up. 671*2f2c4c7aSAndroid Build Coastguard Worker is_add: Boolean that causes this method to perform setup if True or 672*2f2c4c7aSAndroid Build Coastguard Worker teardown if False 673*2f2c4c7aSAndroid Build Coastguard Worker """ 674*2f2c4c7aSAndroid Build Coastguard Worker if is_add: 675*2f2c4c7aSAndroid Build Coastguard Worker # Disable router solicitations to avoid occasional spurious packets 676*2f2c4c7aSAndroid Build Coastguard Worker # arriving on the underlying network; there are two possible behaviors 677*2f2c4c7aSAndroid Build Coastguard Worker # when that occurred: either only the RA packet is read, and when it 678*2f2c4c7aSAndroid Build Coastguard Worker # is echoed back to the tunnel, it causes the test to fail by not 679*2f2c4c7aSAndroid Build Coastguard Worker # receiving # the UDP_PAYLOAD; or, two packets may arrive on the 680*2f2c4c7aSAndroid Build Coastguard Worker # underlying # network which fails the assertion that only one ESP packet 681*2f2c4c7aSAndroid Build Coastguard Worker # is received. 682*2f2c4c7aSAndroid Build Coastguard Worker cls.SetSysctl( 683*2f2c4c7aSAndroid Build Coastguard Worker "/proc/sys/net/ipv6/conf/%s/router_solicitations" % tunnel.iface, 0) 684*2f2c4c7aSAndroid Build Coastguard Worker net_test.SetInterfaceUp(tunnel.iface) 685*2f2c4c7aSAndroid Build Coastguard Worker 686*2f2c4c7aSAndroid Build Coastguard Worker for version in [4, 6]: 687*2f2c4c7aSAndroid Build Coastguard Worker ifindex = net_test.GetInterfaceIndex(tunnel.iface) 688*2f2c4c7aSAndroid Build Coastguard Worker table = tunnel.netid 689*2f2c4c7aSAndroid Build Coastguard Worker 690*2f2c4c7aSAndroid Build Coastguard Worker # Set up routing rules. 691*2f2c4c7aSAndroid Build Coastguard Worker start, end = cls.UidRangeForTunnelNetId(tunnel.netid) 692*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.UidRangeRule(version, is_add, start, end, table, 693*2f2c4c7aSAndroid Build Coastguard Worker cls.PRIORITY_UID) 694*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.OifRule(version, is_add, tunnel.iface, table, cls.PRIORITY_OIF) 695*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.FwmarkRule(version, is_add, tunnel.netid, cls.NETID_FWMASK, 696*2f2c4c7aSAndroid Build Coastguard Worker table, cls.PRIORITY_FWMARK) 697*2f2c4c7aSAndroid Build Coastguard Worker 698*2f2c4c7aSAndroid Build Coastguard Worker # Configure IP addresses. 699*2f2c4c7aSAndroid Build Coastguard Worker addr = cls._GetLocalAddress(version, tunnel.netid) 700*2f2c4c7aSAndroid Build Coastguard Worker prefixlen = net_test.AddressLengthBits(version) 701*2f2c4c7aSAndroid Build Coastguard Worker tunnel.addrs[version] = addr 702*2f2c4c7aSAndroid Build Coastguard Worker if is_add: 703*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.AddAddress(addr, prefixlen, ifindex) 704*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.AddRoute(version, table, "default", 0, None, ifindex) 705*2f2c4c7aSAndroid Build Coastguard Worker else: 706*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.DelRoute(version, table, "default", 0, None, ifindex) 707*2f2c4c7aSAndroid Build Coastguard Worker cls.iproute.DelAddress(addr, prefixlen, ifindex) 708*2f2c4c7aSAndroid Build Coastguard Worker 709*2f2c4c7aSAndroid Build Coastguard Worker def assertReceivedPacket(self, tunnel, sa_info): 710*2f2c4c7aSAndroid Build Coastguard Worker tunnel.rx += 1 711*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual((tunnel.rx, tunnel.tx), 712*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.GetRxTxPackets(tunnel.iface)) 713*2f2c4c7aSAndroid Build Coastguard Worker sa_info.seq_num += 1 714*2f2c4c7aSAndroid Build Coastguard Worker 715*2f2c4c7aSAndroid Build Coastguard Worker def assertSentPacket(self, tunnel, sa_info): 716*2f2c4c7aSAndroid Build Coastguard Worker tunnel.tx += 1 717*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual((tunnel.rx, tunnel.tx), 718*2f2c4c7aSAndroid Build Coastguard Worker self.iproute.GetRxTxPackets(tunnel.iface)) 719*2f2c4c7aSAndroid Build Coastguard Worker sa_info.seq_num += 1 720*2f2c4c7aSAndroid Build Coastguard Worker 721*2f2c4c7aSAndroid Build Coastguard Worker def _CheckTunnelInput(self, tunnel, inner_version, local_inner, remote_inner, 722*2f2c4c7aSAndroid Build Coastguard Worker sa_info=None, expect_fail=False): 723*2f2c4c7aSAndroid Build Coastguard Worker """Test null-crypt input path over an IPsec interface.""" 724*2f2c4c7aSAndroid Build Coastguard Worker if sa_info is None: 725*2f2c4c7aSAndroid Build Coastguard Worker sa_info = tunnel.in_sa 726*2f2c4c7aSAndroid Build Coastguard Worker read_sock, local_port = _CreateReceiveSock(inner_version) 727*2f2c4c7aSAndroid Build Coastguard Worker 728*2f2c4c7aSAndroid Build Coastguard Worker input_pkt = _GetNullAuthCryptTunnelModePkt( 729*2f2c4c7aSAndroid Build Coastguard Worker inner_version, remote_inner, tunnel.remote, _TEST_REMOTE_PORT, 730*2f2c4c7aSAndroid Build Coastguard Worker local_inner, tunnel.local, local_port, sa_info.spi, sa_info.seq_num) 731*2f2c4c7aSAndroid Build Coastguard Worker self.ReceivePacketOn(tunnel.underlying_netid, input_pkt) 732*2f2c4c7aSAndroid Build Coastguard Worker 733*2f2c4c7aSAndroid Build Coastguard Worker try: 734*2f2c4c7aSAndroid Build Coastguard Worker if expect_fail: 735*2f2c4c7aSAndroid Build Coastguard Worker self.assertRaisesErrno(EAGAIN, read_sock.recv, 4096) 736*2f2c4c7aSAndroid Build Coastguard Worker else: 737*2f2c4c7aSAndroid Build Coastguard Worker # Verify that the packet data and src are correct 738*2f2c4c7aSAndroid Build Coastguard Worker data, src = read_sock.recvfrom(4096) 739*2f2c4c7aSAndroid Build Coastguard Worker self.assertReceivedPacket(tunnel, sa_info) 740*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(net_test.UDP_PAYLOAD, data) 741*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual((remote_inner, _TEST_REMOTE_PORT), src[:2]) 742*2f2c4c7aSAndroid Build Coastguard Worker finally: 743*2f2c4c7aSAndroid Build Coastguard Worker read_sock.close() 744*2f2c4c7aSAndroid Build Coastguard Worker 745*2f2c4c7aSAndroid Build Coastguard Worker def _CheckTunnelOutput(self, tunnel, inner_version, local_inner, 746*2f2c4c7aSAndroid Build Coastguard Worker remote_inner, sa_info=None): 747*2f2c4c7aSAndroid Build Coastguard Worker """Test null-crypt output path over an IPsec interface.""" 748*2f2c4c7aSAndroid Build Coastguard Worker if sa_info is None: 749*2f2c4c7aSAndroid Build Coastguard Worker sa_info = tunnel.out_sa 750*2f2c4c7aSAndroid Build Coastguard Worker local_port = _SendPacket(self, tunnel.netid, inner_version, remote_inner, 751*2f2c4c7aSAndroid Build Coastguard Worker _TEST_REMOTE_PORT) 752*2f2c4c7aSAndroid Build Coastguard Worker 753*2f2c4c7aSAndroid Build Coastguard Worker # Read a tunneled IP packet on the underlying (outbound) network 754*2f2c4c7aSAndroid Build Coastguard Worker # verifying that it is an ESP packet. 755*2f2c4c7aSAndroid Build Coastguard Worker pkt = self._ExpectEspPacketOn(tunnel.underlying_netid, sa_info.spi, 756*2f2c4c7aSAndroid Build Coastguard Worker sa_info.seq_num, None, tunnel.local, 757*2f2c4c7aSAndroid Build Coastguard Worker tunnel.remote) 758*2f2c4c7aSAndroid Build Coastguard Worker 759*2f2c4c7aSAndroid Build Coastguard Worker # Get and update the IP headers on the inner payload so that we can do a simple 760*2f2c4c7aSAndroid Build Coastguard Worker # comparison of byte data. Unfortunately, due to the scapy version this runs on, 761*2f2c4c7aSAndroid Build Coastguard Worker # we cannot parse past the ESP header to the inner IP header, and thus have to 762*2f2c4c7aSAndroid Build Coastguard Worker # workaround in this manner 763*2f2c4c7aSAndroid Build Coastguard Worker if inner_version == 4: 764*2f2c4c7aSAndroid Build Coastguard Worker ip_hdr_options = { 765*2f2c4c7aSAndroid Build Coastguard Worker 'id': scapy.IP(bytes(pkt.payload)[8:]).id, 766*2f2c4c7aSAndroid Build Coastguard Worker 'flags': scapy.IP(bytes(pkt.payload)[8:]).flags 767*2f2c4c7aSAndroid Build Coastguard Worker } 768*2f2c4c7aSAndroid Build Coastguard Worker else: 769*2f2c4c7aSAndroid Build Coastguard Worker ip_hdr_options = {'fl': scapy.IPv6(bytes(pkt.payload)[8:]).fl} 770*2f2c4c7aSAndroid Build Coastguard Worker 771*2f2c4c7aSAndroid Build Coastguard Worker expected = _GetNullAuthCryptTunnelModePkt( 772*2f2c4c7aSAndroid Build Coastguard Worker inner_version, local_inner, tunnel.local, local_port, remote_inner, 773*2f2c4c7aSAndroid Build Coastguard Worker tunnel.remote, _TEST_REMOTE_PORT, sa_info.spi, sa_info.seq_num, 774*2f2c4c7aSAndroid Build Coastguard Worker ip_hdr_options) 775*2f2c4c7aSAndroid Build Coastguard Worker 776*2f2c4c7aSAndroid Build Coastguard Worker # Check outer header manually (Avoids having to overwrite outer header's 777*2f2c4c7aSAndroid Build Coastguard Worker # id, flags or flow label) 778*2f2c4c7aSAndroid Build Coastguard Worker self.assertSentPacket(tunnel, sa_info) 779*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(expected.src, pkt.src) 780*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(expected.dst, pkt.dst) 781*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(len(expected), len(pkt)) 782*2f2c4c7aSAndroid Build Coastguard Worker 783*2f2c4c7aSAndroid Build Coastguard Worker # Check everything else 784*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(bytes(expected.payload), bytes(pkt.payload)) 785*2f2c4c7aSAndroid Build Coastguard Worker 786*2f2c4c7aSAndroid Build Coastguard Worker def _CheckTunnelEncryption(self, tunnel, inner_version, local_inner, 787*2f2c4c7aSAndroid Build Coastguard Worker remote_inner): 788*2f2c4c7aSAndroid Build Coastguard Worker """Test both input and output paths over an encrypted IPsec interface. 789*2f2c4c7aSAndroid Build Coastguard Worker 790*2f2c4c7aSAndroid Build Coastguard Worker This tests specifically makes sure that the both encryption and decryption 791*2f2c4c7aSAndroid Build Coastguard Worker work together, as opposed to the _CheckTunnel(Input|Output) where the 792*2f2c4c7aSAndroid Build Coastguard Worker input and output paths are tested separately, and using null encryption. 793*2f2c4c7aSAndroid Build Coastguard Worker """ 794*2f2c4c7aSAndroid Build Coastguard Worker src_port = _SendPacket(self, tunnel.netid, inner_version, remote_inner, 795*2f2c4c7aSAndroid Build Coastguard Worker _TEST_REMOTE_PORT) 796*2f2c4c7aSAndroid Build Coastguard Worker 797*2f2c4c7aSAndroid Build Coastguard Worker # Make sure it appeared on the underlying interface 798*2f2c4c7aSAndroid Build Coastguard Worker pkt = self._ExpectEspPacketOn(tunnel.underlying_netid, tunnel.out_sa.spi, 799*2f2c4c7aSAndroid Build Coastguard Worker tunnel.out_sa.seq_num, None, tunnel.local, 800*2f2c4c7aSAndroid Build Coastguard Worker tunnel.remote) 801*2f2c4c7aSAndroid Build Coastguard Worker 802*2f2c4c7aSAndroid Build Coastguard Worker # Check that packet is not sent in plaintext 803*2f2c4c7aSAndroid Build Coastguard Worker self.assertTrue(bytes(net_test.UDP_PAYLOAD) not in bytes(pkt)) 804*2f2c4c7aSAndroid Build Coastguard Worker 805*2f2c4c7aSAndroid Build Coastguard Worker # Check src/dst 806*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(tunnel.local, pkt.src) 807*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(tunnel.remote, pkt.dst) 808*2f2c4c7aSAndroid Build Coastguard Worker 809*2f2c4c7aSAndroid Build Coastguard Worker # Check that the interface statistics recorded the outbound packet 810*2f2c4c7aSAndroid Build Coastguard Worker self.assertSentPacket(tunnel, tunnel.out_sa) 811*2f2c4c7aSAndroid Build Coastguard Worker 812*2f2c4c7aSAndroid Build Coastguard Worker try: 813*2f2c4c7aSAndroid Build Coastguard Worker # Swap the interface addresses to pretend we are the remote 814*2f2c4c7aSAndroid Build Coastguard Worker self._SwapInterfaceAddress( 815*2f2c4c7aSAndroid Build Coastguard Worker tunnel.iface, new_addr=remote_inner, old_addr=local_inner) 816*2f2c4c7aSAndroid Build Coastguard Worker 817*2f2c4c7aSAndroid Build Coastguard Worker # Swap the packet's IP headers and write it back to the underlying 818*2f2c4c7aSAndroid Build Coastguard Worker # network. 819*2f2c4c7aSAndroid Build Coastguard Worker pkt = TunTwister.TwistPacket(pkt) 820*2f2c4c7aSAndroid Build Coastguard Worker read_sock, local_port = _CreateReceiveSock(inner_version, 821*2f2c4c7aSAndroid Build Coastguard Worker _TEST_REMOTE_PORT) 822*2f2c4c7aSAndroid Build Coastguard Worker self.ReceivePacketOn(tunnel.underlying_netid, pkt) 823*2f2c4c7aSAndroid Build Coastguard Worker 824*2f2c4c7aSAndroid Build Coastguard Worker # Verify that the packet data and src are correct 825*2f2c4c7aSAndroid Build Coastguard Worker data, src = read_sock.recvfrom(4096) 826*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(net_test.UDP_PAYLOAD, data) 827*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual((local_inner, src_port), src[:2]) 828*2f2c4c7aSAndroid Build Coastguard Worker 829*2f2c4c7aSAndroid Build Coastguard Worker # Check that the interface statistics recorded the inbound packet 830*2f2c4c7aSAndroid Build Coastguard Worker self.assertReceivedPacket(tunnel, tunnel.in_sa) 831*2f2c4c7aSAndroid Build Coastguard Worker 832*2f2c4c7aSAndroid Build Coastguard Worker read_sock.close() 833*2f2c4c7aSAndroid Build Coastguard Worker finally: 834*2f2c4c7aSAndroid Build Coastguard Worker # Swap the interface addresses to pretend we are the remote 835*2f2c4c7aSAndroid Build Coastguard Worker self._SwapInterfaceAddress( 836*2f2c4c7aSAndroid Build Coastguard Worker tunnel.iface, new_addr=local_inner, old_addr=remote_inner) 837*2f2c4c7aSAndroid Build Coastguard Worker 838*2f2c4c7aSAndroid Build Coastguard Worker def _CheckTunnelIcmp(self, tunnel, inner_version, local_inner, remote_inner, 839*2f2c4c7aSAndroid Build Coastguard Worker sa_info=None): 840*2f2c4c7aSAndroid Build Coastguard Worker """Test ICMP error path over an IPsec interface.""" 841*2f2c4c7aSAndroid Build Coastguard Worker if sa_info is None: 842*2f2c4c7aSAndroid Build Coastguard Worker sa_info = tunnel.out_sa 843*2f2c4c7aSAndroid Build Coastguard Worker # Now attempt to provoke an ICMP error. 844*2f2c4c7aSAndroid Build Coastguard Worker # TODO: deduplicate with multinetwork_test.py. 845*2f2c4c7aSAndroid Build Coastguard Worker dst_prefix, intermediate = { 846*2f2c4c7aSAndroid Build Coastguard Worker 4: ("172.19.", "172.16.9.12"), 847*2f2c4c7aSAndroid Build Coastguard Worker 6: ("2001:db8::", "2001:db8::1") 848*2f2c4c7aSAndroid Build Coastguard Worker }[tunnel.version] 849*2f2c4c7aSAndroid Build Coastguard Worker 850*2f2c4c7aSAndroid Build Coastguard Worker local_port = _SendPacket(self, tunnel.netid, inner_version, remote_inner, 851*2f2c4c7aSAndroid Build Coastguard Worker _TEST_REMOTE_PORT) 852*2f2c4c7aSAndroid Build Coastguard Worker pkt = self._ExpectEspPacketOn(tunnel.underlying_netid, sa_info.spi, 853*2f2c4c7aSAndroid Build Coastguard Worker sa_info.seq_num, None, tunnel.local, 854*2f2c4c7aSAndroid Build Coastguard Worker tunnel.remote) 855*2f2c4c7aSAndroid Build Coastguard Worker self.assertSentPacket(tunnel, sa_info) 856*2f2c4c7aSAndroid Build Coastguard Worker 857*2f2c4c7aSAndroid Build Coastguard Worker myaddr = self.MyAddress(tunnel.version, tunnel.underlying_netid) 858*2f2c4c7aSAndroid Build Coastguard Worker _, toobig = packets.ICMPPacketTooBig(tunnel.version, intermediate, myaddr, 859*2f2c4c7aSAndroid Build Coastguard Worker pkt) 860*2f2c4c7aSAndroid Build Coastguard Worker self.ReceivePacketOn(tunnel.underlying_netid, toobig) 861*2f2c4c7aSAndroid Build Coastguard Worker 862*2f2c4c7aSAndroid Build Coastguard Worker # Check that the packet too big reduced the MTU. 863*2f2c4c7aSAndroid Build Coastguard Worker routes = self.iproute.GetRoutes(tunnel.remote, 0, tunnel.underlying_netid, None) 864*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(1, len(routes)) 865*2f2c4c7aSAndroid Build Coastguard Worker rtmsg, attributes = routes[0] 866*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(iproute.RTN_UNICAST, rtmsg.type) 867*2f2c4c7aSAndroid Build Coastguard Worker self.assertEqual(packets.PTB_MTU, attributes["RTA_METRICS"]["RTAX_MTU"]) 868*2f2c4c7aSAndroid Build Coastguard Worker 869*2f2c4c7aSAndroid Build Coastguard Worker # Clear PMTU information so that future tests don't have to worry about it. 870*2f2c4c7aSAndroid Build Coastguard Worker self.InvalidateDstCache(tunnel.version, tunnel.underlying_netid) 871*2f2c4c7aSAndroid Build Coastguard Worker 872*2f2c4c7aSAndroid Build Coastguard Worker def _CheckTunnelEncryptionWithIcmp(self, tunnel, inner_version, local_inner, 873*2f2c4c7aSAndroid Build Coastguard Worker remote_inner): 874*2f2c4c7aSAndroid Build Coastguard Worker """Test combined encryption path with ICMP errors over an IPsec tunnel""" 875*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelEncryption(tunnel, inner_version, local_inner, 876*2f2c4c7aSAndroid Build Coastguard Worker remote_inner) 877*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelIcmp(tunnel, inner_version, local_inner, remote_inner) 878*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelEncryption(tunnel, inner_version, local_inner, 879*2f2c4c7aSAndroid Build Coastguard Worker remote_inner) 880*2f2c4c7aSAndroid Build Coastguard Worker 881*2f2c4c7aSAndroid Build Coastguard Worker def _RebuildTunnel(self, tunnel, use_null_crypt): 882*2f2c4c7aSAndroid Build Coastguard Worker # Some tests require that the out_seq_num and in_seq_num are the same 883*2f2c4c7aSAndroid Build Coastguard Worker # (Specifically encrypted tests), rebuild SAs to ensure seq_num is 1 884*2f2c4c7aSAndroid Build Coastguard Worker # 885*2f2c4c7aSAndroid Build Coastguard Worker # Until we get better scapy support, the only way we can build an 886*2f2c4c7aSAndroid Build Coastguard Worker # encrypted packet is to send it out, and read the packet from the wire. 887*2f2c4c7aSAndroid Build Coastguard Worker # We then generally use this as the "inbound" encrypted packet, injecting 888*2f2c4c7aSAndroid Build Coastguard Worker # it into the interface for which it is expected on. 889*2f2c4c7aSAndroid Build Coastguard Worker # 890*2f2c4c7aSAndroid Build Coastguard Worker # As such, this is required to ensure that encrypted packets (which we 891*2f2c4c7aSAndroid Build Coastguard Worker # currently have no way to easily modify) are not considered replay 892*2f2c4c7aSAndroid Build Coastguard Worker # attacks by the inbound SA. (eg: received 3 packets, seq_num_in = 3, 893*2f2c4c7aSAndroid Build Coastguard Worker # sent only 1, # seq_num_out = 1, inbound SA would consider this a replay 894*2f2c4c7aSAndroid Build Coastguard Worker # attack) 895*2f2c4c7aSAndroid Build Coastguard Worker tunnel.TeardownXfrm() 896*2f2c4c7aSAndroid Build Coastguard Worker tunnel.SetupXfrm(use_null_crypt) 897*2f2c4c7aSAndroid Build Coastguard Worker 898*2f2c4c7aSAndroid Build Coastguard Worker def _TestTunnel(self, inner_version, outer_version, func, use_null_crypt): 899*2f2c4c7aSAndroid Build Coastguard Worker """Bootstrap method to setup and run tests for the given parameters.""" 900*2f2c4c7aSAndroid Build Coastguard Worker tunnel = self.randomTunnel(outer_version) 901*2f2c4c7aSAndroid Build Coastguard Worker 902*2f2c4c7aSAndroid Build Coastguard Worker try: 903*2f2c4c7aSAndroid Build Coastguard Worker self._RebuildTunnel(tunnel, use_null_crypt) 904*2f2c4c7aSAndroid Build Coastguard Worker 905*2f2c4c7aSAndroid Build Coastguard Worker local_inner = tunnel.addrs[inner_version] 906*2f2c4c7aSAndroid Build Coastguard Worker remote_inner = _GetRemoteInnerAddress(inner_version) 907*2f2c4c7aSAndroid Build Coastguard Worker 908*2f2c4c7aSAndroid Build Coastguard Worker for i in range(2): 909*2f2c4c7aSAndroid Build Coastguard Worker func(tunnel, inner_version, local_inner, remote_inner) 910*2f2c4c7aSAndroid Build Coastguard Worker finally: 911*2f2c4c7aSAndroid Build Coastguard Worker if use_null_crypt: 912*2f2c4c7aSAndroid Build Coastguard Worker tunnel.TeardownXfrm() 913*2f2c4c7aSAndroid Build Coastguard Worker tunnel.SetupXfrm(False) 914*2f2c4c7aSAndroid Build Coastguard Worker 915*2f2c4c7aSAndroid Build Coastguard Worker def _CheckTunnelRekey(self, tunnel, inner_version, local_inner, remote_inner): 916*2f2c4c7aSAndroid Build Coastguard Worker old_out_sa = tunnel.out_sa 917*2f2c4c7aSAndroid Build Coastguard Worker old_in_sa = tunnel.in_sa 918*2f2c4c7aSAndroid Build Coastguard Worker 919*2f2c4c7aSAndroid Build Coastguard Worker # Check to make sure that both directions work before rekey 920*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelInput(tunnel, inner_version, local_inner, remote_inner, 921*2f2c4c7aSAndroid Build Coastguard Worker old_in_sa) 922*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelOutput(tunnel, inner_version, local_inner, remote_inner, 923*2f2c4c7aSAndroid Build Coastguard Worker old_out_sa) 924*2f2c4c7aSAndroid Build Coastguard Worker 925*2f2c4c7aSAndroid Build Coastguard Worker # Rekey 926*2f2c4c7aSAndroid Build Coastguard Worker outer_family = net_test.GetAddressFamily(tunnel.version) 927*2f2c4c7aSAndroid Build Coastguard Worker 928*2f2c4c7aSAndroid Build Coastguard Worker # Create new SA 929*2f2c4c7aSAndroid Build Coastguard Worker # Distinguish the new SAs with new SPIs. 930*2f2c4c7aSAndroid Build Coastguard Worker new_out_sa = SaInfo(old_out_sa.spi + 1) 931*2f2c4c7aSAndroid Build Coastguard Worker new_in_sa = SaInfo(old_in_sa.spi + 1) 932*2f2c4c7aSAndroid Build Coastguard Worker 933*2f2c4c7aSAndroid Build Coastguard Worker # Perform Rekey 934*2f2c4c7aSAndroid Build Coastguard Worker tunnel.Rekey(outer_family, new_out_sa, new_in_sa) 935*2f2c4c7aSAndroid Build Coastguard Worker 936*2f2c4c7aSAndroid Build Coastguard Worker # Expect that the old SPI still works for inbound packets 937*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelInput(tunnel, inner_version, local_inner, remote_inner, 938*2f2c4c7aSAndroid Build Coastguard Worker old_in_sa) 939*2f2c4c7aSAndroid Build Coastguard Worker 940*2f2c4c7aSAndroid Build Coastguard Worker # Test both paths with new SPIs, expect outbound to use new SPI 941*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelInput(tunnel, inner_version, local_inner, remote_inner, 942*2f2c4c7aSAndroid Build Coastguard Worker new_in_sa) 943*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelOutput(tunnel, inner_version, local_inner, remote_inner, 944*2f2c4c7aSAndroid Build Coastguard Worker new_out_sa) 945*2f2c4c7aSAndroid Build Coastguard Worker 946*2f2c4c7aSAndroid Build Coastguard Worker # Delete old SAs 947*2f2c4c7aSAndroid Build Coastguard Worker tunnel.DeleteOldSaInfo(outer_family, old_in_sa.spi, old_out_sa.spi) 948*2f2c4c7aSAndroid Build Coastguard Worker 949*2f2c4c7aSAndroid Build Coastguard Worker # Test both paths with new SPIs; should still work 950*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelInput(tunnel, inner_version, local_inner, remote_inner, 951*2f2c4c7aSAndroid Build Coastguard Worker new_in_sa) 952*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelOutput(tunnel, inner_version, local_inner, remote_inner, 953*2f2c4c7aSAndroid Build Coastguard Worker new_out_sa) 954*2f2c4c7aSAndroid Build Coastguard Worker 955*2f2c4c7aSAndroid Build Coastguard Worker # Expect failure upon trying to receive a packet with the deleted SPI 956*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelInput(tunnel, inner_version, local_inner, remote_inner, 957*2f2c4c7aSAndroid Build Coastguard Worker old_in_sa, True) 958*2f2c4c7aSAndroid Build Coastguard Worker 959*2f2c4c7aSAndroid Build Coastguard Worker def _TestTunnelRekey(self, inner_version, outer_version): 960*2f2c4c7aSAndroid Build Coastguard Worker """Test packet input and output over a Virtual Tunnel Interface.""" 961*2f2c4c7aSAndroid Build Coastguard Worker tunnel = self.randomTunnel(outer_version) 962*2f2c4c7aSAndroid Build Coastguard Worker 963*2f2c4c7aSAndroid Build Coastguard Worker try: 964*2f2c4c7aSAndroid Build Coastguard Worker # Always use null_crypt, so we can check input and output separately 965*2f2c4c7aSAndroid Build Coastguard Worker tunnel.TeardownXfrm() 966*2f2c4c7aSAndroid Build Coastguard Worker tunnel.SetupXfrm(True) 967*2f2c4c7aSAndroid Build Coastguard Worker 968*2f2c4c7aSAndroid Build Coastguard Worker local_inner = tunnel.addrs[inner_version] 969*2f2c4c7aSAndroid Build Coastguard Worker remote_inner = _GetRemoteInnerAddress(inner_version) 970*2f2c4c7aSAndroid Build Coastguard Worker 971*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelRekey(tunnel, inner_version, local_inner, remote_inner) 972*2f2c4c7aSAndroid Build Coastguard Worker finally: 973*2f2c4c7aSAndroid Build Coastguard Worker tunnel.TeardownXfrm() 974*2f2c4c7aSAndroid Build Coastguard Worker tunnel.SetupXfrm(False) 975*2f2c4c7aSAndroid Build Coastguard Worker 976*2f2c4c7aSAndroid Build Coastguard Worker 977*2f2c4c7aSAndroid Build Coastguard Workerclass XfrmVtiTest(XfrmTunnelBase): 978*2f2c4c7aSAndroid Build Coastguard Worker 979*2f2c4c7aSAndroid Build Coastguard Worker INTERFACE_CLASS = VtiInterface 980*2f2c4c7aSAndroid Build Coastguard Worker 981*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestVtiInput(self, inner_version, outer_version): 982*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, self._CheckTunnelInput, True) 983*2f2c4c7aSAndroid Build Coastguard Worker 984*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestVtiOutput(self, inner_version, outer_version): 985*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, self._CheckTunnelOutput, 986*2f2c4c7aSAndroid Build Coastguard Worker True) 987*2f2c4c7aSAndroid Build Coastguard Worker 988*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestVtiInOutEncrypted(self, inner_version, outer_version): 989*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, self._CheckTunnelEncryption, 990*2f2c4c7aSAndroid Build Coastguard Worker False) 991*2f2c4c7aSAndroid Build Coastguard Worker 992*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestVtiIcmp(self, inner_version, outer_version): 993*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, self._CheckTunnelIcmp, False) 994*2f2c4c7aSAndroid Build Coastguard Worker 995*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestVtiEncryptionWithIcmp(self, inner_version, outer_version): 996*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, 997*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelEncryptionWithIcmp, False) 998*2f2c4c7aSAndroid Build Coastguard Worker 999*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestVtiRekey(self, inner_version, outer_version): 1000*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnelRekey(inner_version, outer_version) 1001*2f2c4c7aSAndroid Build Coastguard Worker 1002*2f2c4c7aSAndroid Build Coastguard Worker 1003*2f2c4c7aSAndroid Build Coastguard Workerclass XfrmInterfaceTest(XfrmTunnelBase): 1004*2f2c4c7aSAndroid Build Coastguard Worker 1005*2f2c4c7aSAndroid Build Coastguard Worker INTERFACE_CLASS = XfrmInterface 1006*2f2c4c7aSAndroid Build Coastguard Worker 1007*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestXfrmIntfInput(self, inner_version, outer_version): 1008*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, self._CheckTunnelInput, True) 1009*2f2c4c7aSAndroid Build Coastguard Worker 1010*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestXfrmIntfOutput(self, inner_version, outer_version): 1011*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, self._CheckTunnelOutput, 1012*2f2c4c7aSAndroid Build Coastguard Worker True) 1013*2f2c4c7aSAndroid Build Coastguard Worker 1014*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestXfrmIntfInOutEncrypted(self, inner_version, outer_version): 1015*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, self._CheckTunnelEncryption, 1016*2f2c4c7aSAndroid Build Coastguard Worker False) 1017*2f2c4c7aSAndroid Build Coastguard Worker 1018*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestXfrmIntfIcmp(self, inner_version, outer_version): 1019*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, self._CheckTunnelIcmp, False) 1020*2f2c4c7aSAndroid Build Coastguard Worker 1021*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestXfrmIntfEncryptionWithIcmp(self, inner_version, outer_version): 1022*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, 1023*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelEncryptionWithIcmp, False) 1024*2f2c4c7aSAndroid Build Coastguard Worker 1025*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestXfrmIntfRekey(self, inner_version, outer_version): 1026*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnelRekey(inner_version, outer_version) 1027*2f2c4c7aSAndroid Build Coastguard Worker 1028*2f2c4c7aSAndroid Build Coastguard Worker############################################################################## 1029*2f2c4c7aSAndroid Build Coastguard Worker# 1030*2f2c4c7aSAndroid Build Coastguard Worker# Test for presence of CONFIG_XFRM_MIGRATE and kernel patches 1031*2f2c4c7aSAndroid Build Coastguard Worker# 1032*2f2c4c7aSAndroid Build Coastguard Worker# xfrm: Check if_id in xfrm_migrate 1033*2f2c4c7aSAndroid Build Coastguard Worker# Upstream commit: c1aca3080e382886e2e58e809787441984a2f89b 1034*2f2c4c7aSAndroid Build Coastguard Worker# 1035*2f2c4c7aSAndroid Build Coastguard Worker# xfrm: Fix xfrm migrate issues when address family changes 1036*2f2c4c7aSAndroid Build Coastguard Worker# Upstream commit: e03c3bba351f99ad932e8f06baa9da1afc418e02 1037*2f2c4c7aSAndroid Build Coastguard Worker# 1038*2f2c4c7aSAndroid Build Coastguard Worker# Those two upstream 5.17 fixes above were pulled in to LTS in kernel versions 1039*2f2c4c7aSAndroid Build Coastguard Worker# 4.14.273, 4.19.236, 5.4.186, 5.10.107, 5.15.30. 1040*2f2c4c7aSAndroid Build Coastguard Worker# 1041*2f2c4c7aSAndroid Build Coastguard Worker# Note: the 'Check if_id in xfrm_migrate' fix did not land in 4.14 LTS, 1042*2f2c4c7aSAndroid Build Coastguard Worker# and instead landed in android-4.14-stable after 4.14.320 LTS merge. 1043*2f2c4c7aSAndroid Build Coastguard Worker# 1044*2f2c4c7aSAndroid Build Coastguard Worker@unittest.skipUnless(SUPPORTS_XFRM_MIGRATE, 1045*2f2c4c7aSAndroid Build Coastguard Worker "XFRM migration unsupported or fixes not included") 1046*2f2c4c7aSAndroid Build Coastguard Workerclass XfrmInterfaceMigrateTest(XfrmTunnelBase): 1047*2f2c4c7aSAndroid Build Coastguard Worker INTERFACE_CLASS = XfrmInterface 1048*2f2c4c7aSAndroid Build Coastguard Worker 1049*2f2c4c7aSAndroid Build Coastguard Worker def setUpTunnel(self, outer_version, use_null_crypt): 1050*2f2c4c7aSAndroid Build Coastguard Worker underlying_netid = self.RandomNetid() 1051*2f2c4c7aSAndroid Build Coastguard Worker netid = _BASE_TUNNEL_NETID[outer_version] + _TUNNEL_NETID_OFFSET 1052*2f2c4c7aSAndroid Build Coastguard Worker iface = "ipsec%s" % netid 1053*2f2c4c7aSAndroid Build Coastguard Worker ifindex = self.ifindices[underlying_netid] 1054*2f2c4c7aSAndroid Build Coastguard Worker 1055*2f2c4c7aSAndroid Build Coastguard Worker local = self.MyAddress(outer_version, underlying_netid) 1056*2f2c4c7aSAndroid Build Coastguard Worker remote = net_test.IPV4_ADDR if outer_version == 4 else net_test.IPV6_ADDR 1057*2f2c4c7aSAndroid Build Coastguard Worker 1058*2f2c4c7aSAndroid Build Coastguard Worker tunnel = XfrmInterface(iface, netid, underlying_netid, ifindex, 1059*2f2c4c7aSAndroid Build Coastguard Worker local, remote, outer_version, use_null_crypt) 1060*2f2c4c7aSAndroid Build Coastguard Worker self._SetInboundMarking(netid, iface, True) 1061*2f2c4c7aSAndroid Build Coastguard Worker self._SetupTunnelNetwork(tunnel, True) 1062*2f2c4c7aSAndroid Build Coastguard Worker 1063*2f2c4c7aSAndroid Build Coastguard Worker return tunnel 1064*2f2c4c7aSAndroid Build Coastguard Worker 1065*2f2c4c7aSAndroid Build Coastguard Worker def tearDownTunnel(self, tunnel): 1066*2f2c4c7aSAndroid Build Coastguard Worker self._SetInboundMarking(tunnel.netid, tunnel.iface, False) 1067*2f2c4c7aSAndroid Build Coastguard Worker self._SetupTunnelNetwork(tunnel, False) 1068*2f2c4c7aSAndroid Build Coastguard Worker tunnel.Teardown() 1069*2f2c4c7aSAndroid Build Coastguard Worker 1070*2f2c4c7aSAndroid Build Coastguard Worker def _TestTunnel(self, inner_version, outer_version, new_outer_version, func, 1071*2f2c4c7aSAndroid Build Coastguard Worker use_null_crypt): 1072*2f2c4c7aSAndroid Build Coastguard Worker tunnel = self.randomTunnel(outer_version) 1073*2f2c4c7aSAndroid Build Coastguard Worker 1074*2f2c4c7aSAndroid Build Coastguard Worker old_underlying_netid = tunnel.underlying_netid 1075*2f2c4c7aSAndroid Build Coastguard Worker old_local = tunnel.local 1076*2f2c4c7aSAndroid Build Coastguard Worker old_remote = tunnel.remote 1077*2f2c4c7aSAndroid Build Coastguard Worker 1078*2f2c4c7aSAndroid Build Coastguard Worker 1079*2f2c4c7aSAndroid Build Coastguard Worker try: 1080*2f2c4c7aSAndroid Build Coastguard Worker self._RebuildTunnel(tunnel, use_null_crypt) 1081*2f2c4c7aSAndroid Build Coastguard Worker 1082*2f2c4c7aSAndroid Build Coastguard Worker # Verify functionality before migration 1083*2f2c4c7aSAndroid Build Coastguard Worker local_inner = tunnel.addrs[inner_version] 1084*2f2c4c7aSAndroid Build Coastguard Worker remote_inner = _GetRemoteInnerAddress(inner_version) 1085*2f2c4c7aSAndroid Build Coastguard Worker func(tunnel, inner_version, local_inner, remote_inner) 1086*2f2c4c7aSAndroid Build Coastguard Worker 1087*2f2c4c7aSAndroid Build Coastguard Worker # Migrate tunnel 1088*2f2c4c7aSAndroid Build Coastguard Worker new_underlying_netid = self.RandomNetid(exclude=tunnel.underlying_netid) 1089*2f2c4c7aSAndroid Build Coastguard Worker new_version = new_outer_version 1090*2f2c4c7aSAndroid Build Coastguard Worker new_local = self.MyAddress(new_version, new_underlying_netid) 1091*2f2c4c7aSAndroid Build Coastguard Worker new_remote = net_test.IPV4_ADDR2 if new_version == 4 else net_test.IPV6_ADDR2 1092*2f2c4c7aSAndroid Build Coastguard Worker 1093*2f2c4c7aSAndroid Build Coastguard Worker tunnel.Migrate(new_underlying_netid, new_local, new_remote) 1094*2f2c4c7aSAndroid Build Coastguard Worker 1095*2f2c4c7aSAndroid Build Coastguard Worker # Verify functionality after migration 1096*2f2c4c7aSAndroid Build Coastguard Worker func(tunnel, inner_version, local_inner, remote_inner) 1097*2f2c4c7aSAndroid Build Coastguard Worker finally: 1098*2f2c4c7aSAndroid Build Coastguard Worker # Reset the tunnel to the original configuration 1099*2f2c4c7aSAndroid Build Coastguard Worker tunnel.TeardownXfrm() 1100*2f2c4c7aSAndroid Build Coastguard Worker 1101*2f2c4c7aSAndroid Build Coastguard Worker self.local = old_local 1102*2f2c4c7aSAndroid Build Coastguard Worker self.remote = old_remote 1103*2f2c4c7aSAndroid Build Coastguard Worker self.underlying_netid = old_underlying_netid 1104*2f2c4c7aSAndroid Build Coastguard Worker tunnel.SetupXfrm(False) 1105*2f2c4c7aSAndroid Build Coastguard Worker 1106*2f2c4c7aSAndroid Build Coastguard Worker 1107*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestMigrateXfrmIntfInput(self, inner_version, outer_version, 1108*2f2c4c7aSAndroid Build Coastguard Worker new_outer_version): 1109*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, new_outer_version, 1110*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelInput, True) 1111*2f2c4c7aSAndroid Build Coastguard Worker 1112*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestMigrateXfrmIntfOutput(self, inner_version, outer_version, 1113*2f2c4c7aSAndroid Build Coastguard Worker new_outer_version): 1114*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, new_outer_version, 1115*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelOutput, True) 1116*2f2c4c7aSAndroid Build Coastguard Worker 1117*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestMigrateXfrmIntfInOutEncrypted(self, inner_version, outer_version, 1118*2f2c4c7aSAndroid Build Coastguard Worker new_outer_version): 1119*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, new_outer_version, 1120*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelEncryption, False) 1121*2f2c4c7aSAndroid Build Coastguard Worker 1122*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestMigrateXfrmIntfIcmp(self, inner_version, outer_version, 1123*2f2c4c7aSAndroid Build Coastguard Worker new_outer_version): 1124*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, new_outer_version, 1125*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelIcmp, False) 1126*2f2c4c7aSAndroid Build Coastguard Worker 1127*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestMigrateXfrmIntfEncryptionWithIcmp(self, inner_version, outer_version, 1128*2f2c4c7aSAndroid Build Coastguard Worker new_outer_version): 1129*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, new_outer_version, 1130*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelEncryptionWithIcmp, False) 1131*2f2c4c7aSAndroid Build Coastguard Worker 1132*2f2c4c7aSAndroid Build Coastguard Worker def ParamTestMigrateXfrmIntfRekey(self, inner_version, outer_version, 1133*2f2c4c7aSAndroid Build Coastguard Worker new_outer_version): 1134*2f2c4c7aSAndroid Build Coastguard Worker self._TestTunnel(inner_version, outer_version, new_outer_version, 1135*2f2c4c7aSAndroid Build Coastguard Worker self._CheckTunnelRekey, True) 1136*2f2c4c7aSAndroid Build Coastguard Worker 1137*2f2c4c7aSAndroid Build Coastguard Workerif __name__ == "__main__": 1138*2f2c4c7aSAndroid Build Coastguard Worker InjectTests() 1139*2f2c4c7aSAndroid Build Coastguard Worker unittest.main() 1140