1*2f2c4c7aSAndroid Build Coastguard Worker#!/usr/bin/python3 2*2f2c4c7aSAndroid Build Coastguard Worker# 3*2f2c4c7aSAndroid Build Coastguard Worker# Copyright 2016 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"""Partial implementation of xfrm netlink code and socket options.""" 18*2f2c4c7aSAndroid Build Coastguard Worker 19*2f2c4c7aSAndroid Build Coastguard Worker# pylint: disable=g-bad-todo 20*2f2c4c7aSAndroid Build Coastguard Worker 21*2f2c4c7aSAndroid Build Coastguard Workerimport os 22*2f2c4c7aSAndroid Build Coastguard Workerfrom socket import * # pylint: disable=wildcard-import 23*2f2c4c7aSAndroid Build Coastguard Workerimport struct 24*2f2c4c7aSAndroid Build Coastguard Worker 25*2f2c4c7aSAndroid Build Coastguard Workerimport net_test 26*2f2c4c7aSAndroid Build Coastguard Workerimport csocket 27*2f2c4c7aSAndroid Build Coastguard Workerimport cstruct 28*2f2c4c7aSAndroid Build Coastguard Workerimport netlink 29*2f2c4c7aSAndroid Build Coastguard Worker 30*2f2c4c7aSAndroid Build Coastguard Worker 31*2f2c4c7aSAndroid Build Coastguard Worker# Netlink constants. See include/uapi/linux/xfrm.h. 32*2f2c4c7aSAndroid Build Coastguard Worker# Message types. 33*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_NEWSA = 16 34*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_DELSA = 17 35*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_GETSA = 18 36*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_NEWPOLICY = 19 37*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_DELPOLICY = 20 38*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_GETPOLICY = 21 39*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_ALLOCSPI = 22 40*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_ACQUIRE = 23 41*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_EXPIRE = 24 42*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_UPDPOLICY = 25 43*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_UPDSA = 26 44*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_POLEXPIRE = 27 45*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_FLUSHSA = 28 46*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_FLUSHPOLICY = 29 47*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_NEWAE = 30 48*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_GETAE = 31 49*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_REPORT = 32 50*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_MIGRATE = 33 51*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_NEWSADINFO = 34 52*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_GETSADINFO = 35 53*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_NEWSPDINFO = 36 54*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_GETSPDINFO = 37 55*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MSG_MAPPING = 38 56*2f2c4c7aSAndroid Build Coastguard Worker 57*2f2c4c7aSAndroid Build Coastguard Worker# Attributes. 58*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_UNSPEC = 0 59*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_ALG_AUTH = 1 60*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_ALG_CRYPT = 2 61*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_ALG_COMP = 3 62*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_ENCAP = 4 63*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_TMPL = 5 64*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_SA = 6 65*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_POLICY = 7 66*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_SEC_CTX = 8 67*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_LTIME_VAL = 9 68*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_REPLAY_VAL = 10 69*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_REPLAY_THRESH = 11 70*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_ETIMER_THRESH = 12 71*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_SRCADDR = 13 72*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_COADDR = 14 73*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_LASTUSED = 15 74*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_POLICY_TYPE = 16 75*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_MIGRATE = 17 76*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_ALG_AEAD = 18 77*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_KMADDRESS = 19 78*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_ALG_AUTH_TRUNC = 20 79*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_MARK = 21 80*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_TFCPAD = 22 81*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_REPLAY_ESN_VAL = 23 82*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_SA_EXTRA_FLAGS = 24 83*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_PROTO = 25 84*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_ADDRESS_FILTER = 26 85*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_PAD = 27 86*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_OFFLOAD_DEV = 28 87*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_OUTPUT_MARK = 29 88*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_INPUT_MARK = 30 89*2f2c4c7aSAndroid Build Coastguard WorkerXFRMA_IF_ID = 31 90*2f2c4c7aSAndroid Build Coastguard Worker 91*2f2c4c7aSAndroid Build Coastguard Worker# Other netlink constants. See include/uapi/linux/xfrm.h. 92*2f2c4c7aSAndroid Build Coastguard Worker 93*2f2c4c7aSAndroid Build Coastguard Worker# Directions. 94*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_POLICY_IN = 0 95*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_POLICY_OUT = 1 96*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_POLICY_FWD = 2 97*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_POLICY_MASK = 3 98*2f2c4c7aSAndroid Build Coastguard Worker 99*2f2c4c7aSAndroid Build Coastguard Worker# Policy sharing. 100*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_SHARE_ANY = 0 # /* No limitations */ 101*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_SHARE_SESSION = 1 # /* For this session only */ 102*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_SHARE_USER = 2 # /* For this user only */ 103*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_SHARE_UNIQUE = 3 # /* Use once */ 104*2f2c4c7aSAndroid Build Coastguard Worker 105*2f2c4c7aSAndroid Build Coastguard Worker# Modes. 106*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MODE_TRANSPORT = 0 107*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MODE_TUNNEL = 1 108*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MODE_ROUTEOPTIMIZATION = 2 109*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MODE_IN_TRIGGER = 3 110*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MODE_BEET = 4 111*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_MODE_MAX = 5 112*2f2c4c7aSAndroid Build Coastguard Worker 113*2f2c4c7aSAndroid Build Coastguard Worker# Actions. 114*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_POLICY_ALLOW = 0 115*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_POLICY_BLOCK = 1 116*2f2c4c7aSAndroid Build Coastguard Worker 117*2f2c4c7aSAndroid Build Coastguard Worker# Policy flags. 118*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_POLICY_LOCALOK = 1 119*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_POLICY_ICMP = 2 120*2f2c4c7aSAndroid Build Coastguard Worker 121*2f2c4c7aSAndroid Build Coastguard Worker# State flags. 122*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_STATE_AF_UNSPEC = 32 123*2f2c4c7aSAndroid Build Coastguard Worker 124*2f2c4c7aSAndroid Build Coastguard Worker# XFRM algorithm names, as defined in net/xfrm/xfrm_algo.c. 125*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_EALG_CBC_AES = b"cbc(aes)" 126*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_EALG_CTR_AES = b"rfc3686(ctr(aes))" 127*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_AALG_HMAC_MD5 = b"hmac(md5)" 128*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_AALG_HMAC_SHA1 = b"hmac(sha1)" 129*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_AALG_HMAC_SHA256 = b"hmac(sha256)" 130*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_AALG_HMAC_SHA384 = b"hmac(sha384)" 131*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_AALG_HMAC_SHA512 = b"hmac(sha512)" 132*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_AALG_AUTH_XCBC_AES = b"xcbc(aes)" 133*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_AEAD_GCM_AES = b"rfc4106(gcm(aes))" 134*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_AEAD_CHACHA20_POLY1305 = b"rfc7539esp(chacha20,poly1305)" 135*2f2c4c7aSAndroid Build Coastguard Worker 136*2f2c4c7aSAndroid Build Coastguard Worker# Data structure formats. 137*2f2c4c7aSAndroid Build Coastguard Worker# These aren't constants, they're classes. So, pylint: disable=invalid-name 138*2f2c4c7aSAndroid Build Coastguard WorkerXfrmSelector = cstruct.Struct( 139*2f2c4c7aSAndroid Build Coastguard Worker "XfrmSelector", "=16s16sHHHHHBBBxxxiI", 140*2f2c4c7aSAndroid Build Coastguard Worker "daddr saddr dport dport_mask sport sport_mask " 141*2f2c4c7aSAndroid Build Coastguard Worker "family prefixlen_d prefixlen_s proto ifindex user") 142*2f2c4c7aSAndroid Build Coastguard Worker 143*2f2c4c7aSAndroid Build Coastguard WorkerXfrmMigrate = cstruct.Struct( 144*2f2c4c7aSAndroid Build Coastguard Worker "XfrmMigrate", "=16s16s16s16sBBxxIHH", 145*2f2c4c7aSAndroid Build Coastguard Worker "old_daddr old_saddr new_daddr new_saddr proto " 146*2f2c4c7aSAndroid Build Coastguard Worker "mode reqid old_family new_family") 147*2f2c4c7aSAndroid Build Coastguard Worker 148*2f2c4c7aSAndroid Build Coastguard WorkerXfrmLifetimeCfg = cstruct.Struct( 149*2f2c4c7aSAndroid Build Coastguard Worker "XfrmLifetimeCfg", "=QQQQQQQQ", 150*2f2c4c7aSAndroid Build Coastguard Worker "soft_byte hard_byte soft_packet hard_packet " 151*2f2c4c7aSAndroid Build Coastguard Worker "soft_add_expires hard_add_expires soft_use_expires hard_use_expires") 152*2f2c4c7aSAndroid Build Coastguard Worker 153*2f2c4c7aSAndroid Build Coastguard WorkerXfrmLifetimeCur = cstruct.Struct( 154*2f2c4c7aSAndroid Build Coastguard Worker "XfrmLifetimeCur", "=QQQQ", "bytes packets add_time use_time") 155*2f2c4c7aSAndroid Build Coastguard Worker 156*2f2c4c7aSAndroid Build Coastguard WorkerXfrmAlgo = cstruct.Struct("XfrmAlgo", "=64AI", "name key_len") 157*2f2c4c7aSAndroid Build Coastguard Worker 158*2f2c4c7aSAndroid Build Coastguard WorkerXfrmAlgoAuth = cstruct.Struct("XfrmAlgoAuth", "=64AII", 159*2f2c4c7aSAndroid Build Coastguard Worker "name key_len trunc_len") 160*2f2c4c7aSAndroid Build Coastguard Worker 161*2f2c4c7aSAndroid Build Coastguard WorkerXfrmAlgoAead = cstruct.Struct("XfrmAlgoAead", "=64AII", "name key_len icv_len") 162*2f2c4c7aSAndroid Build Coastguard Worker 163*2f2c4c7aSAndroid Build Coastguard WorkerXfrmStats = cstruct.Struct( 164*2f2c4c7aSAndroid Build Coastguard Worker "XfrmStats", "=III", "replay_window replay integrity_failed") 165*2f2c4c7aSAndroid Build Coastguard Worker 166*2f2c4c7aSAndroid Build Coastguard WorkerXfrmId = cstruct.Struct("XfrmId", "!16sIBxxx", "daddr spi proto") 167*2f2c4c7aSAndroid Build Coastguard Worker 168*2f2c4c7aSAndroid Build Coastguard WorkerXfrmUserTmpl = cstruct.Struct( 169*2f2c4c7aSAndroid Build Coastguard Worker "XfrmUserTmpl", "=SHxx16sIBBBxIII", 170*2f2c4c7aSAndroid Build Coastguard Worker "id family saddr reqid mode share optional aalgos ealgos calgos", 171*2f2c4c7aSAndroid Build Coastguard Worker [XfrmId]) 172*2f2c4c7aSAndroid Build Coastguard Worker 173*2f2c4c7aSAndroid Build Coastguard WorkerXfrmEncapTmpl = cstruct.Struct( 174*2f2c4c7aSAndroid Build Coastguard Worker "XfrmEncapTmpl", "=HHHxx16s", "type sport dport oa") 175*2f2c4c7aSAndroid Build Coastguard Worker 176*2f2c4c7aSAndroid Build Coastguard WorkerXfrmUsersaInfo = cstruct.Struct( 177*2f2c4c7aSAndroid Build Coastguard Worker "XfrmUsersaInfo", "=SS16sSSSIIHBBB7x", 178*2f2c4c7aSAndroid Build Coastguard Worker "sel id saddr lft curlft stats seq reqid family mode replay_window flags", 179*2f2c4c7aSAndroid Build Coastguard Worker [XfrmSelector, XfrmId, XfrmLifetimeCfg, XfrmLifetimeCur, XfrmStats]) 180*2f2c4c7aSAndroid Build Coastguard Worker 181*2f2c4c7aSAndroid Build Coastguard WorkerXfrmUserSpiInfo = cstruct.Struct( 182*2f2c4c7aSAndroid Build Coastguard Worker "XfrmUserSpiInfo", "=SII", "info min max", [XfrmUsersaInfo]) 183*2f2c4c7aSAndroid Build Coastguard Worker 184*2f2c4c7aSAndroid Build Coastguard Worker# Technically the family is a 16-bit field, but only a few families are in use, 185*2f2c4c7aSAndroid Build Coastguard Worker# and if we pretend it's 8 bits (i.e., use "Bx" instead of "H") we can think 186*2f2c4c7aSAndroid Build Coastguard Worker# of the whole structure as being in network byte order. 187*2f2c4c7aSAndroid Build Coastguard WorkerXfrmUsersaId = cstruct.Struct( 188*2f2c4c7aSAndroid Build Coastguard Worker "XfrmUsersaId", "!16sIBxBx", "daddr spi family proto") 189*2f2c4c7aSAndroid Build Coastguard Worker 190*2f2c4c7aSAndroid Build Coastguard Worker# xfrm.h - struct xfrm_userpolicy_info 191*2f2c4c7aSAndroid Build Coastguard WorkerXfrmUserpolicyInfo = cstruct.Struct( 192*2f2c4c7aSAndroid Build Coastguard Worker "XfrmUserpolicyInfo", "=SSSIIBBBBxxxx", 193*2f2c4c7aSAndroid Build Coastguard Worker "sel lft curlft priority index dir action flags share", 194*2f2c4c7aSAndroid Build Coastguard Worker [XfrmSelector, XfrmLifetimeCfg, XfrmLifetimeCur]) 195*2f2c4c7aSAndroid Build Coastguard Worker 196*2f2c4c7aSAndroid Build Coastguard WorkerXfrmUserpolicyId = cstruct.Struct( 197*2f2c4c7aSAndroid Build Coastguard Worker "XfrmUserpolicyId", "=SIBxxx", "sel index dir", [XfrmSelector]) 198*2f2c4c7aSAndroid Build Coastguard Worker 199*2f2c4c7aSAndroid Build Coastguard WorkerXfrmUsersaFlush = cstruct.Struct("XfrmUsersaFlush", "=B", "proto") 200*2f2c4c7aSAndroid Build Coastguard Worker 201*2f2c4c7aSAndroid Build Coastguard WorkerXfrmMark = cstruct.Struct("XfrmMark", "=II", "mark mask") 202*2f2c4c7aSAndroid Build Coastguard Worker 203*2f2c4c7aSAndroid Build Coastguard Worker# Socket options. See include/uapi/linux/in.h. 204*2f2c4c7aSAndroid Build Coastguard WorkerIP_IPSEC_POLICY = 16 205*2f2c4c7aSAndroid Build Coastguard WorkerIP_XFRM_POLICY = 17 206*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_IPSEC_POLICY = 34 207*2f2c4c7aSAndroid Build Coastguard WorkerIPV6_XFRM_POLICY = 35 208*2f2c4c7aSAndroid Build Coastguard Worker 209*2f2c4c7aSAndroid Build Coastguard Worker# UDP encapsulation constants. See include/uapi/linux/udp.h. 210*2f2c4c7aSAndroid Build Coastguard WorkerUDP_ENCAP = 100 211*2f2c4c7aSAndroid Build Coastguard WorkerUDP_ENCAP_ESPINUDP_NON_IKE = 1 212*2f2c4c7aSAndroid Build Coastguard WorkerUDP_ENCAP_ESPINUDP = 2 213*2f2c4c7aSAndroid Build Coastguard Worker 214*2f2c4c7aSAndroid Build Coastguard Worker_INF = 2 ** 64 -1 215*2f2c4c7aSAndroid Build Coastguard WorkerNO_LIFETIME_CFG = XfrmLifetimeCfg((_INF, _INF, _INF, _INF, 0, 0, 0, 0)) 216*2f2c4c7aSAndroid Build Coastguard WorkerNO_LIFETIME_CUR = b"\x00" * len(XfrmLifetimeCur) 217*2f2c4c7aSAndroid Build Coastguard Worker 218*2f2c4c7aSAndroid Build Coastguard Worker# IPsec constants. 219*2f2c4c7aSAndroid Build Coastguard WorkerIPSEC_PROTO_ANY = 255 220*2f2c4c7aSAndroid Build Coastguard Worker 221*2f2c4c7aSAndroid Build Coastguard Worker# ESP header, not technically XFRM but we need a place for a protocol 222*2f2c4c7aSAndroid Build Coastguard Worker# header and this is the only one we have. 223*2f2c4c7aSAndroid Build Coastguard Worker# TODO: move this somewhere more appropriate when possible 224*2f2c4c7aSAndroid Build Coastguard WorkerEspHdr = cstruct.Struct("EspHdr", "!II", "spi seqnum") 225*2f2c4c7aSAndroid Build Coastguard Worker 226*2f2c4c7aSAndroid Build Coastguard Worker# Local constants. 227*2f2c4c7aSAndroid Build Coastguard Worker_DEFAULT_REPLAY_WINDOW = 32 228*2f2c4c7aSAndroid Build Coastguard WorkerALL_ALGORITHMS = 0xffffffff 229*2f2c4c7aSAndroid Build Coastguard Worker 230*2f2c4c7aSAndroid Build Coastguard Worker# Policy-SA match method (for VTI/XFRM-I). 231*2f2c4c7aSAndroid Build Coastguard WorkerMATCH_METHOD_ALL = "all" 232*2f2c4c7aSAndroid Build Coastguard WorkerMATCH_METHOD_MARK = "mark" 233*2f2c4c7aSAndroid Build Coastguard WorkerMATCH_METHOD_IFID = "ifid" 234*2f2c4c7aSAndroid Build Coastguard Worker 235*2f2c4c7aSAndroid Build Coastguard Worker 236*2f2c4c7aSAndroid Build Coastguard Workerdef RawAddress(addr): 237*2f2c4c7aSAndroid Build Coastguard Worker """Converts an IP address string to binary format.""" 238*2f2c4c7aSAndroid Build Coastguard Worker family = AF_INET6 if ":" in addr else AF_INET 239*2f2c4c7aSAndroid Build Coastguard Worker return inet_pton(family, addr) 240*2f2c4c7aSAndroid Build Coastguard Worker 241*2f2c4c7aSAndroid Build Coastguard Worker 242*2f2c4c7aSAndroid Build Coastguard Workerdef PaddedAddress(addr): 243*2f2c4c7aSAndroid Build Coastguard Worker """Converts an IP address string to binary format for InetDiagSockId.""" 244*2f2c4c7aSAndroid Build Coastguard Worker padded = RawAddress(addr) 245*2f2c4c7aSAndroid Build Coastguard Worker if len(padded) < 16: 246*2f2c4c7aSAndroid Build Coastguard Worker padded += b"\x00" * (16 - len(padded)) 247*2f2c4c7aSAndroid Build Coastguard Worker return padded 248*2f2c4c7aSAndroid Build Coastguard Worker 249*2f2c4c7aSAndroid Build Coastguard Worker 250*2f2c4c7aSAndroid Build Coastguard WorkerXFRM_ADDR_ANY = PaddedAddress("::") 251*2f2c4c7aSAndroid Build Coastguard Worker 252*2f2c4c7aSAndroid Build Coastguard Worker 253*2f2c4c7aSAndroid Build Coastguard Workerdef EmptySelector(family): 254*2f2c4c7aSAndroid Build Coastguard Worker """A selector that matches all packets of the specified address family.""" 255*2f2c4c7aSAndroid Build Coastguard Worker return XfrmSelector(family=family) 256*2f2c4c7aSAndroid Build Coastguard Worker 257*2f2c4c7aSAndroid Build Coastguard Worker 258*2f2c4c7aSAndroid Build Coastguard Workerdef SrcDstSelector(src, dst): 259*2f2c4c7aSAndroid Build Coastguard Worker """A selector that matches packets between the specified IP addresses.""" 260*2f2c4c7aSAndroid Build Coastguard Worker srcver = csocket.AddressVersion(src) 261*2f2c4c7aSAndroid Build Coastguard Worker dstver = csocket.AddressVersion(dst) 262*2f2c4c7aSAndroid Build Coastguard Worker if srcver != dstver: 263*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Cross-address family selector specified: %s -> %s" % 264*2f2c4c7aSAndroid Build Coastguard Worker (src, dst)) 265*2f2c4c7aSAndroid Build Coastguard Worker prefixlen = net_test.AddressLengthBits(srcver) 266*2f2c4c7aSAndroid Build Coastguard Worker family = net_test.GetAddressFamily(srcver) 267*2f2c4c7aSAndroid Build Coastguard Worker return XfrmSelector(saddr=PaddedAddress(src), daddr=PaddedAddress(dst), 268*2f2c4c7aSAndroid Build Coastguard Worker prefixlen_s=prefixlen, prefixlen_d=prefixlen, family=family) 269*2f2c4c7aSAndroid Build Coastguard Worker 270*2f2c4c7aSAndroid Build Coastguard Worker 271*2f2c4c7aSAndroid Build Coastguard Workerdef UserPolicy(direction, selector): 272*2f2c4c7aSAndroid Build Coastguard Worker """Create an IPsec policy. 273*2f2c4c7aSAndroid Build Coastguard Worker 274*2f2c4c7aSAndroid Build Coastguard Worker Args: 275*2f2c4c7aSAndroid Build Coastguard Worker direction: XFRM_POLICY_IN or XFRM_POLICY_OUT 276*2f2c4c7aSAndroid Build Coastguard Worker selector: An XfrmSelector, the packets to transform. 277*2f2c4c7aSAndroid Build Coastguard Worker 278*2f2c4c7aSAndroid Build Coastguard Worker Return: a XfrmUserpolicyInfo cstruct. 279*2f2c4c7aSAndroid Build Coastguard Worker """ 280*2f2c4c7aSAndroid Build Coastguard Worker # Create a user policy that specifies that all packets in the specified 281*2f2c4c7aSAndroid Build Coastguard Worker # direction matching the selector should be encrypted. 282*2f2c4c7aSAndroid Build Coastguard Worker return XfrmUserpolicyInfo( 283*2f2c4c7aSAndroid Build Coastguard Worker sel=selector, 284*2f2c4c7aSAndroid Build Coastguard Worker lft=NO_LIFETIME_CFG, 285*2f2c4c7aSAndroid Build Coastguard Worker curlft=NO_LIFETIME_CUR, 286*2f2c4c7aSAndroid Build Coastguard Worker dir=direction, 287*2f2c4c7aSAndroid Build Coastguard Worker action=XFRM_POLICY_ALLOW, 288*2f2c4c7aSAndroid Build Coastguard Worker flags=XFRM_POLICY_LOCALOK, 289*2f2c4c7aSAndroid Build Coastguard Worker share=XFRM_SHARE_UNIQUE) 290*2f2c4c7aSAndroid Build Coastguard Worker 291*2f2c4c7aSAndroid Build Coastguard Worker 292*2f2c4c7aSAndroid Build Coastguard Workerdef UserTemplate(family, spi, reqid, tun_addrs): 293*2f2c4c7aSAndroid Build Coastguard Worker """Create an ESP policy and template. 294*2f2c4c7aSAndroid Build Coastguard Worker 295*2f2c4c7aSAndroid Build Coastguard Worker Args: 296*2f2c4c7aSAndroid Build Coastguard Worker spi: 32-bit SPI in host byte order 297*2f2c4c7aSAndroid Build Coastguard Worker reqid: 32-bit ID matched against SAs 298*2f2c4c7aSAndroid Build Coastguard Worker tun_addrs: A tuple of (local, remote) addresses for tunnel mode, or None 299*2f2c4c7aSAndroid Build Coastguard Worker to request a transport mode SA. 300*2f2c4c7aSAndroid Build Coastguard Worker 301*2f2c4c7aSAndroid Build Coastguard Worker Return: a tuple of XfrmUserpolicyInfo, XfrmUserTmpl 302*2f2c4c7aSAndroid Build Coastguard Worker """ 303*2f2c4c7aSAndroid Build Coastguard Worker # For transport mode, set template source and destination are empty. 304*2f2c4c7aSAndroid Build Coastguard Worker # For tunnel mode, explicitly specify source and destination addresses. 305*2f2c4c7aSAndroid Build Coastguard Worker if tun_addrs is None: 306*2f2c4c7aSAndroid Build Coastguard Worker mode = XFRM_MODE_TRANSPORT 307*2f2c4c7aSAndroid Build Coastguard Worker saddr = XFRM_ADDR_ANY 308*2f2c4c7aSAndroid Build Coastguard Worker daddr = XFRM_ADDR_ANY 309*2f2c4c7aSAndroid Build Coastguard Worker else: 310*2f2c4c7aSAndroid Build Coastguard Worker mode = XFRM_MODE_TUNNEL 311*2f2c4c7aSAndroid Build Coastguard Worker saddr = PaddedAddress(tun_addrs[0]) 312*2f2c4c7aSAndroid Build Coastguard Worker daddr = PaddedAddress(tun_addrs[1]) 313*2f2c4c7aSAndroid Build Coastguard Worker 314*2f2c4c7aSAndroid Build Coastguard Worker # Create a template that specifies the SPI and the protocol. 315*2f2c4c7aSAndroid Build Coastguard Worker xfrmid = XfrmId(daddr=daddr, spi=spi, proto=IPPROTO_ESP) 316*2f2c4c7aSAndroid Build Coastguard Worker template = XfrmUserTmpl( 317*2f2c4c7aSAndroid Build Coastguard Worker id=xfrmid, 318*2f2c4c7aSAndroid Build Coastguard Worker family=family, 319*2f2c4c7aSAndroid Build Coastguard Worker saddr=saddr, 320*2f2c4c7aSAndroid Build Coastguard Worker reqid=reqid, 321*2f2c4c7aSAndroid Build Coastguard Worker mode=mode, 322*2f2c4c7aSAndroid Build Coastguard Worker share=XFRM_SHARE_UNIQUE, 323*2f2c4c7aSAndroid Build Coastguard Worker optional=0, #require 324*2f2c4c7aSAndroid Build Coastguard Worker aalgos=ALL_ALGORITHMS, 325*2f2c4c7aSAndroid Build Coastguard Worker ealgos=ALL_ALGORITHMS, 326*2f2c4c7aSAndroid Build Coastguard Worker calgos=ALL_ALGORITHMS) 327*2f2c4c7aSAndroid Build Coastguard Worker 328*2f2c4c7aSAndroid Build Coastguard Worker return template 329*2f2c4c7aSAndroid Build Coastguard Worker 330*2f2c4c7aSAndroid Build Coastguard Worker 331*2f2c4c7aSAndroid Build Coastguard Workerdef ExactMatchMark(mark): 332*2f2c4c7aSAndroid Build Coastguard Worker """An XfrmMark that matches only the specified mark.""" 333*2f2c4c7aSAndroid Build Coastguard Worker return XfrmMark((mark, 0xffffffff)) 334*2f2c4c7aSAndroid Build Coastguard Worker 335*2f2c4c7aSAndroid Build Coastguard Worker 336*2f2c4c7aSAndroid Build Coastguard Workerclass Xfrm(netlink.NetlinkSocket): 337*2f2c4c7aSAndroid Build Coastguard Worker """Netlink interface to xfrm.""" 338*2f2c4c7aSAndroid Build Coastguard Worker 339*2f2c4c7aSAndroid Build Coastguard Worker DEBUG = False 340*2f2c4c7aSAndroid Build Coastguard Worker 341*2f2c4c7aSAndroid Build Coastguard Worker def __init__(self): 342*2f2c4c7aSAndroid Build Coastguard Worker super(Xfrm, self).__init__(netlink.NETLINK_XFRM) 343*2f2c4c7aSAndroid Build Coastguard Worker 344*2f2c4c7aSAndroid Build Coastguard Worker def _GetConstantName(self, value, prefix): 345*2f2c4c7aSAndroid Build Coastguard Worker return super(Xfrm, self)._GetConstantName(__name__, value, prefix) 346*2f2c4c7aSAndroid Build Coastguard Worker 347*2f2c4c7aSAndroid Build Coastguard Worker def MaybeDebugCommand(self, command, flags, data): 348*2f2c4c7aSAndroid Build Coastguard Worker if "ALL" not in self.NL_DEBUG and "XFRM" not in self.NL_DEBUG: 349*2f2c4c7aSAndroid Build Coastguard Worker return 350*2f2c4c7aSAndroid Build Coastguard Worker 351*2f2c4c7aSAndroid Build Coastguard Worker if command == XFRM_MSG_GETSA: 352*2f2c4c7aSAndroid Build Coastguard Worker if flags & netlink.NLM_F_DUMP: 353*2f2c4c7aSAndroid Build Coastguard Worker struct_type = XfrmUsersaInfo 354*2f2c4c7aSAndroid Build Coastguard Worker else: 355*2f2c4c7aSAndroid Build Coastguard Worker struct_type = XfrmUsersaId 356*2f2c4c7aSAndroid Build Coastguard Worker elif command == XFRM_MSG_DELSA: 357*2f2c4c7aSAndroid Build Coastguard Worker struct_type = XfrmUsersaId 358*2f2c4c7aSAndroid Build Coastguard Worker elif command == XFRM_MSG_ALLOCSPI: 359*2f2c4c7aSAndroid Build Coastguard Worker struct_type = XfrmUserSpiInfo 360*2f2c4c7aSAndroid Build Coastguard Worker elif command == XFRM_MSG_NEWPOLICY: 361*2f2c4c7aSAndroid Build Coastguard Worker struct_type = XfrmUserpolicyInfo 362*2f2c4c7aSAndroid Build Coastguard Worker else: 363*2f2c4c7aSAndroid Build Coastguard Worker struct_type = None 364*2f2c4c7aSAndroid Build Coastguard Worker 365*2f2c4c7aSAndroid Build Coastguard Worker cmdname = self._GetConstantName(command, "XFRM_MSG_") 366*2f2c4c7aSAndroid Build Coastguard Worker if struct_type: 367*2f2c4c7aSAndroid Build Coastguard Worker print("%s %s" % (cmdname, str(self._ParseNLMsg(data, struct_type)))) 368*2f2c4c7aSAndroid Build Coastguard Worker else: 369*2f2c4c7aSAndroid Build Coastguard Worker print("%s" % cmdname) 370*2f2c4c7aSAndroid Build Coastguard Worker 371*2f2c4c7aSAndroid Build Coastguard Worker def _Decode(self, command, unused_msg, nla_type, nla_data, nested): 372*2f2c4c7aSAndroid Build Coastguard Worker """Decodes netlink attributes to Python types.""" 373*2f2c4c7aSAndroid Build Coastguard Worker name = self._GetConstantName(nla_type, "XFRMA_") 374*2f2c4c7aSAndroid Build Coastguard Worker 375*2f2c4c7aSAndroid Build Coastguard Worker if name in ["XFRMA_ALG_CRYPT", "XFRMA_ALG_AUTH"]: 376*2f2c4c7aSAndroid Build Coastguard Worker data = cstruct.Read(nla_data, XfrmAlgo)[0] 377*2f2c4c7aSAndroid Build Coastguard Worker elif name == "XFRMA_ALG_AUTH_TRUNC": 378*2f2c4c7aSAndroid Build Coastguard Worker data = cstruct.Read(nla_data, XfrmAlgoAuth)[0] 379*2f2c4c7aSAndroid Build Coastguard Worker elif name == "XFRMA_ENCAP": 380*2f2c4c7aSAndroid Build Coastguard Worker data = cstruct.Read(nla_data, XfrmEncapTmpl)[0] 381*2f2c4c7aSAndroid Build Coastguard Worker elif name == "XFRMA_MARK": 382*2f2c4c7aSAndroid Build Coastguard Worker data = cstruct.Read(nla_data, XfrmMark)[0] 383*2f2c4c7aSAndroid Build Coastguard Worker elif name == "XFRMA_OUTPUT_MARK": 384*2f2c4c7aSAndroid Build Coastguard Worker data = struct.unpack("=I", nla_data)[0] 385*2f2c4c7aSAndroid Build Coastguard Worker elif name == "XFRMA_TMPL": 386*2f2c4c7aSAndroid Build Coastguard Worker data = cstruct.Read(nla_data, XfrmUserTmpl)[0] 387*2f2c4c7aSAndroid Build Coastguard Worker elif name == "XFRMA_IF_ID": 388*2f2c4c7aSAndroid Build Coastguard Worker data = struct.unpack("=I", nla_data)[0] 389*2f2c4c7aSAndroid Build Coastguard Worker else: 390*2f2c4c7aSAndroid Build Coastguard Worker data = nla_data 391*2f2c4c7aSAndroid Build Coastguard Worker 392*2f2c4c7aSAndroid Build Coastguard Worker return name, data 393*2f2c4c7aSAndroid Build Coastguard Worker 394*2f2c4c7aSAndroid Build Coastguard Worker def _UpdatePolicyInfo(self, msg, policy, tmpl, mark, xfrm_if_id): 395*2f2c4c7aSAndroid Build Coastguard Worker """Send a policy to the Security Policy Database""" 396*2f2c4c7aSAndroid Build Coastguard Worker nlattrs = [] 397*2f2c4c7aSAndroid Build Coastguard Worker if tmpl is not None: 398*2f2c4c7aSAndroid Build Coastguard Worker nlattrs.append((XFRMA_TMPL, tmpl)) 399*2f2c4c7aSAndroid Build Coastguard Worker if mark is not None: 400*2f2c4c7aSAndroid Build Coastguard Worker nlattrs.append((XFRMA_MARK, mark)) 401*2f2c4c7aSAndroid Build Coastguard Worker if xfrm_if_id is not None: 402*2f2c4c7aSAndroid Build Coastguard Worker nlattrs.append((XFRMA_IF_ID, struct.pack("=I", xfrm_if_id))) 403*2f2c4c7aSAndroid Build Coastguard Worker self.SendXfrmNlRequest(msg, policy, nlattrs) 404*2f2c4c7aSAndroid Build Coastguard Worker 405*2f2c4c7aSAndroid Build Coastguard Worker def AddPolicyInfo(self, policy, tmpl, mark, xfrm_if_id=None): 406*2f2c4c7aSAndroid Build Coastguard Worker """Add a new policy to the Security Policy Database 407*2f2c4c7aSAndroid Build Coastguard Worker 408*2f2c4c7aSAndroid Build Coastguard Worker If the policy exists, then return an error (EEXIST). 409*2f2c4c7aSAndroid Build Coastguard Worker 410*2f2c4c7aSAndroid Build Coastguard Worker Args: 411*2f2c4c7aSAndroid Build Coastguard Worker policy: an unpacked XfrmUserpolicyInfo 412*2f2c4c7aSAndroid Build Coastguard Worker tmpl: an unpacked XfrmUserTmpl 413*2f2c4c7aSAndroid Build Coastguard Worker mark: an unpacked XfrmMark 414*2f2c4c7aSAndroid Build Coastguard Worker xfrm_if_id: the XFRM interface ID as an integer, or None 415*2f2c4c7aSAndroid Build Coastguard Worker """ 416*2f2c4c7aSAndroid Build Coastguard Worker self._UpdatePolicyInfo(XFRM_MSG_NEWPOLICY, policy, tmpl, mark, xfrm_if_id) 417*2f2c4c7aSAndroid Build Coastguard Worker 418*2f2c4c7aSAndroid Build Coastguard Worker def UpdatePolicyInfo(self, policy, tmpl, mark, xfrm_if_id): 419*2f2c4c7aSAndroid Build Coastguard Worker """Update an existing policy in the Security Policy Database 420*2f2c4c7aSAndroid Build Coastguard Worker 421*2f2c4c7aSAndroid Build Coastguard Worker If the policy does not exist, then create it; otherwise, update the 422*2f2c4c7aSAndroid Build Coastguard Worker existing policy record. 423*2f2c4c7aSAndroid Build Coastguard Worker 424*2f2c4c7aSAndroid Build Coastguard Worker Args: 425*2f2c4c7aSAndroid Build Coastguard Worker policy: an unpacked XfrmUserpolicyInfo 426*2f2c4c7aSAndroid Build Coastguard Worker tmpl: an unpacked XfrmUserTmpl to update 427*2f2c4c7aSAndroid Build Coastguard Worker mark: an unpacked XfrmMark to match the existing policy or None 428*2f2c4c7aSAndroid Build Coastguard Worker xfrm_if_id: an XFRM interface ID or None 429*2f2c4c7aSAndroid Build Coastguard Worker """ 430*2f2c4c7aSAndroid Build Coastguard Worker self._UpdatePolicyInfo(XFRM_MSG_UPDPOLICY, policy, tmpl, mark, xfrm_if_id) 431*2f2c4c7aSAndroid Build Coastguard Worker 432*2f2c4c7aSAndroid Build Coastguard Worker def DeletePolicyInfo(self, selector, direction, mark, xfrm_if_id=None): 433*2f2c4c7aSAndroid Build Coastguard Worker """Delete a policy from the Security Policy Database 434*2f2c4c7aSAndroid Build Coastguard Worker 435*2f2c4c7aSAndroid Build Coastguard Worker Args: 436*2f2c4c7aSAndroid Build Coastguard Worker selector: an XfrmSelector matching the policy to delete 437*2f2c4c7aSAndroid Build Coastguard Worker direction: policy direction 438*2f2c4c7aSAndroid Build Coastguard Worker mark: an unpacked XfrmMark to match the policy or None 439*2f2c4c7aSAndroid Build Coastguard Worker """ 440*2f2c4c7aSAndroid Build Coastguard Worker nlattrs = [] 441*2f2c4c7aSAndroid Build Coastguard Worker if mark is not None: 442*2f2c4c7aSAndroid Build Coastguard Worker nlattrs.append((XFRMA_MARK, mark)) 443*2f2c4c7aSAndroid Build Coastguard Worker if xfrm_if_id is not None: 444*2f2c4c7aSAndroid Build Coastguard Worker nlattrs.append((XFRMA_IF_ID, struct.pack("=I", xfrm_if_id))) 445*2f2c4c7aSAndroid Build Coastguard Worker self.SendXfrmNlRequest(XFRM_MSG_DELPOLICY, 446*2f2c4c7aSAndroid Build Coastguard Worker XfrmUserpolicyId(sel=selector, dir=direction), 447*2f2c4c7aSAndroid Build Coastguard Worker nlattrs) 448*2f2c4c7aSAndroid Build Coastguard Worker 449*2f2c4c7aSAndroid Build Coastguard Worker # TODO: this function really needs to be in netlink.py 450*2f2c4c7aSAndroid Build Coastguard Worker def SendXfrmNlRequest(self, msg_type, req, nlattrs=None, 451*2f2c4c7aSAndroid Build Coastguard Worker flags=netlink.NLM_F_ACK|netlink.NLM_F_REQUEST): 452*2f2c4c7aSAndroid Build Coastguard Worker """Sends a netlink request message 453*2f2c4c7aSAndroid Build Coastguard Worker 454*2f2c4c7aSAndroid Build Coastguard Worker Args: 455*2f2c4c7aSAndroid Build Coastguard Worker msg_type: an XFRM_MSG_* type 456*2f2c4c7aSAndroid Build Coastguard Worker req: an unpacked netlink request message body cstruct 457*2f2c4c7aSAndroid Build Coastguard Worker nlattrs: an unpacked list of two-tuples of (NLATTR_* type, body) where 458*2f2c4c7aSAndroid Build Coastguard Worker the body is an unpacked cstruct 459*2f2c4c7aSAndroid Build Coastguard Worker flags: a list of flags for the expected handling; if no flags are 460*2f2c4c7aSAndroid Build Coastguard Worker provided, an ACK response is assumed. 461*2f2c4c7aSAndroid Build Coastguard Worker """ 462*2f2c4c7aSAndroid Build Coastguard Worker msg = req.Pack() 463*2f2c4c7aSAndroid Build Coastguard Worker if nlattrs is None: 464*2f2c4c7aSAndroid Build Coastguard Worker nlattrs = [] 465*2f2c4c7aSAndroid Build Coastguard Worker for attr_type, attr_msg in nlattrs: 466*2f2c4c7aSAndroid Build Coastguard Worker # TODO: find a better way to deal with the fact that many XFRM messages 467*2f2c4c7aSAndroid Build Coastguard Worker # use nlattrs that aren't cstructs. 468*2f2c4c7aSAndroid Build Coastguard Worker # 469*2f2c4c7aSAndroid Build Coastguard Worker # This code allows callers to pass in either something that has a Pack() 470*2f2c4c7aSAndroid Build Coastguard Worker # method or a packed netlink attr, but not other types of attributes. 471*2f2c4c7aSAndroid Build Coastguard Worker # Alternatives include: 472*2f2c4c7aSAndroid Build Coastguard Worker # 473*2f2c4c7aSAndroid Build Coastguard Worker # 1. Require callers to marshal netlink attributes themselves and call 474*2f2c4c7aSAndroid Build Coastguard Worker # _SendNlRequest directly. Delete this method. 475*2f2c4c7aSAndroid Build Coastguard Worker # 2. Rename this function to _SendXfrmNlRequestCstructOnly (or other name 476*2f2c4c7aSAndroid Build Coastguard Worker # that makes it clear that this only takes cstructs). Switch callers 477*2f2c4c7aSAndroid Build Coastguard Worker # that need non-cstruct elements to calling _SendNlRequest directly. 478*2f2c4c7aSAndroid Build Coastguard Worker # 3. Make this function somehow automatically detect what to do for 479*2f2c4c7aSAndroid Build Coastguard Worker # all types of XFRM attributes today and in the future. This may be 480*2f2c4c7aSAndroid Build Coastguard Worker # feasible because all XFRM attributes today occupy the same number 481*2f2c4c7aSAndroid Build Coastguard Worker # space, but what about nested attributes? It is unlikley feasible via 482*2f2c4c7aSAndroid Build Coastguard Worker # things like "if isinstance(attr_msg, str): ...", because that would 483*2f2c4c7aSAndroid Build Coastguard Worker # not be able to determine the right size or byte order for non-struct 484*2f2c4c7aSAndroid Build Coastguard Worker # types such as int. 485*2f2c4c7aSAndroid Build Coastguard Worker # 4. Define fictitious cstructs which have no correspondence to actual 486*2f2c4c7aSAndroid Build Coastguard Worker # kernel structs such as the following to represent a raw integer. 487*2f2c4c7aSAndroid Build Coastguard Worker # XfrmAttrOutputMark = cstruct.Struct("=I", mark) 488*2f2c4c7aSAndroid Build Coastguard Worker if hasattr(attr_msg, "Pack"): 489*2f2c4c7aSAndroid Build Coastguard Worker attr_msg = attr_msg.Pack() 490*2f2c4c7aSAndroid Build Coastguard Worker msg += self._NlAttr(attr_type, attr_msg) 491*2f2c4c7aSAndroid Build Coastguard Worker return self._SendNlRequest(msg_type, msg, flags) 492*2f2c4c7aSAndroid Build Coastguard Worker 493*2f2c4c7aSAndroid Build Coastguard Worker def AddSaInfo(self, src, dst, spi, mode, reqid, encryption, auth_trunc, aead, 494*2f2c4c7aSAndroid Build Coastguard Worker encap, mark, output_mark, is_update=False, xfrm_if_id=None): 495*2f2c4c7aSAndroid Build Coastguard Worker """Adds an IPsec security association. 496*2f2c4c7aSAndroid Build Coastguard Worker 497*2f2c4c7aSAndroid Build Coastguard Worker Args: 498*2f2c4c7aSAndroid Build Coastguard Worker src: A string, the source IP address. May be a wildcard in transport mode. 499*2f2c4c7aSAndroid Build Coastguard Worker dst: A string, the destination IP address. Forms part of the XFRM ID, and 500*2f2c4c7aSAndroid Build Coastguard Worker must match the destination address of the packets sent by this SA. 501*2f2c4c7aSAndroid Build Coastguard Worker spi: An integer, the SPI. 502*2f2c4c7aSAndroid Build Coastguard Worker mode: An IPsec mode such as XFRM_MODE_TRANSPORT. 503*2f2c4c7aSAndroid Build Coastguard Worker reqid: A request ID. Can be used in policies to match the SA. 504*2f2c4c7aSAndroid Build Coastguard Worker encryption: A tuple of an XfrmAlgo and raw key bytes, or None. 505*2f2c4c7aSAndroid Build Coastguard Worker auth_trunc: A tuple of an XfrmAlgoAuth and raw key bytes, or None. 506*2f2c4c7aSAndroid Build Coastguard Worker aead: A tuple of an XfrmAlgoAead and raw key bytes, or None. 507*2f2c4c7aSAndroid Build Coastguard Worker encap: An XfrmEncapTmpl structure, or None. 508*2f2c4c7aSAndroid Build Coastguard Worker mark: A mark match specifier, such as returned by ExactMatchMark(), or 509*2f2c4c7aSAndroid Build Coastguard Worker None for an SA that matches all possible marks. 510*2f2c4c7aSAndroid Build Coastguard Worker output_mark: An integer, the output mark. 0 means unset. 511*2f2c4c7aSAndroid Build Coastguard Worker is_update: If true, update an existing SA otherwise create a new SA. For 512*2f2c4c7aSAndroid Build Coastguard Worker compatibility reasons, this value defaults to False. 513*2f2c4c7aSAndroid Build Coastguard Worker xfrm_if_id: The XFRM interface ID, or None. 514*2f2c4c7aSAndroid Build Coastguard Worker """ 515*2f2c4c7aSAndroid Build Coastguard Worker proto = IPPROTO_ESP 516*2f2c4c7aSAndroid Build Coastguard Worker xfrm_id = XfrmId((PaddedAddress(dst), spi, proto)) 517*2f2c4c7aSAndroid Build Coastguard Worker family = AF_INET6 if ":" in dst else AF_INET 518*2f2c4c7aSAndroid Build Coastguard Worker 519*2f2c4c7aSAndroid Build Coastguard Worker nlattrs = b"" 520*2f2c4c7aSAndroid Build Coastguard Worker if encryption is not None: 521*2f2c4c7aSAndroid Build Coastguard Worker enc, key = encryption 522*2f2c4c7aSAndroid Build Coastguard Worker nlattrs += self._NlAttr(XFRMA_ALG_CRYPT, enc.Pack() + key) 523*2f2c4c7aSAndroid Build Coastguard Worker 524*2f2c4c7aSAndroid Build Coastguard Worker if auth_trunc is not None: 525*2f2c4c7aSAndroid Build Coastguard Worker auth, key = auth_trunc 526*2f2c4c7aSAndroid Build Coastguard Worker nlattrs += self._NlAttr(XFRMA_ALG_AUTH_TRUNC, auth.Pack() + key) 527*2f2c4c7aSAndroid Build Coastguard Worker 528*2f2c4c7aSAndroid Build Coastguard Worker if aead is not None: 529*2f2c4c7aSAndroid Build Coastguard Worker aead_alg, key = aead 530*2f2c4c7aSAndroid Build Coastguard Worker nlattrs += self._NlAttr(XFRMA_ALG_AEAD, aead_alg.Pack() + key) 531*2f2c4c7aSAndroid Build Coastguard Worker 532*2f2c4c7aSAndroid Build Coastguard Worker # if a user provides either mark or mask, then we send the mark attribute 533*2f2c4c7aSAndroid Build Coastguard Worker if mark is not None: 534*2f2c4c7aSAndroid Build Coastguard Worker nlattrs += self._NlAttr(XFRMA_MARK, mark.Pack()) 535*2f2c4c7aSAndroid Build Coastguard Worker if encap is not None: 536*2f2c4c7aSAndroid Build Coastguard Worker nlattrs += self._NlAttr(XFRMA_ENCAP, encap.Pack()) 537*2f2c4c7aSAndroid Build Coastguard Worker if output_mark is not None: 538*2f2c4c7aSAndroid Build Coastguard Worker nlattrs += self._NlAttrU32(XFRMA_OUTPUT_MARK, output_mark) 539*2f2c4c7aSAndroid Build Coastguard Worker if xfrm_if_id is not None: 540*2f2c4c7aSAndroid Build Coastguard Worker nlattrs += self._NlAttrU32(XFRMA_IF_ID, xfrm_if_id) 541*2f2c4c7aSAndroid Build Coastguard Worker 542*2f2c4c7aSAndroid Build Coastguard Worker # The kernel ignores these on input, so make them empty. 543*2f2c4c7aSAndroid Build Coastguard Worker cur = XfrmLifetimeCur() 544*2f2c4c7aSAndroid Build Coastguard Worker stats = XfrmStats() 545*2f2c4c7aSAndroid Build Coastguard Worker seq = 0 546*2f2c4c7aSAndroid Build Coastguard Worker replay = _DEFAULT_REPLAY_WINDOW 547*2f2c4c7aSAndroid Build Coastguard Worker 548*2f2c4c7aSAndroid Build Coastguard Worker # The XFRM_STATE_AF_UNSPEC flag determines how AF_UNSPEC selectors behave. 549*2f2c4c7aSAndroid Build Coastguard Worker # 550*2f2c4c7aSAndroid Build Coastguard Worker # - If the flag is not set, an AF_UNSPEC selector has its family changed to 551*2f2c4c7aSAndroid Build Coastguard Worker # the SA family, which in our case is the address family of dst. 552*2f2c4c7aSAndroid Build Coastguard Worker # - If the flag is set, an AF_UNSPEC selector is left as is. In transport 553*2f2c4c7aSAndroid Build Coastguard Worker # mode this fails with EPROTONOSUPPORT, but in tunnel mode, it results in 554*2f2c4c7aSAndroid Build Coastguard Worker # a dual-stack SA that can tunnel both IPv4 and IPv6 packets. 555*2f2c4c7aSAndroid Build Coastguard Worker # 556*2f2c4c7aSAndroid Build Coastguard Worker # This allows us to pass an empty selector to the kernel regardless of which 557*2f2c4c7aSAndroid Build Coastguard Worker # mode we're in: when creating transport mode SAs, the kernel will pick the 558*2f2c4c7aSAndroid Build Coastguard Worker # selector family based on the SA family, and when creating tunnel mode SAs, 559*2f2c4c7aSAndroid Build Coastguard Worker # we'll just create SAs that select both IPv4 and IPv6 traffic, and leave it 560*2f2c4c7aSAndroid Build Coastguard Worker # up to the policy selectors to determine what traffic we actually want to 561*2f2c4c7aSAndroid Build Coastguard Worker # transform. 562*2f2c4c7aSAndroid Build Coastguard Worker flags = XFRM_STATE_AF_UNSPEC if mode == XFRM_MODE_TUNNEL else 0 563*2f2c4c7aSAndroid Build Coastguard Worker selector = EmptySelector(AF_UNSPEC) 564*2f2c4c7aSAndroid Build Coastguard Worker 565*2f2c4c7aSAndroid Build Coastguard Worker sa = XfrmUsersaInfo((selector, xfrm_id, PaddedAddress(src), NO_LIFETIME_CFG, 566*2f2c4c7aSAndroid Build Coastguard Worker cur, stats, seq, reqid, family, mode, replay, flags)) 567*2f2c4c7aSAndroid Build Coastguard Worker msg = sa.Pack() + nlattrs 568*2f2c4c7aSAndroid Build Coastguard Worker flags = netlink.NLM_F_REQUEST | netlink.NLM_F_ACK 569*2f2c4c7aSAndroid Build Coastguard Worker nl_msg_type = XFRM_MSG_UPDSA if is_update else XFRM_MSG_NEWSA 570*2f2c4c7aSAndroid Build Coastguard Worker self._SendNlRequest(nl_msg_type, msg, flags) 571*2f2c4c7aSAndroid Build Coastguard Worker 572*2f2c4c7aSAndroid Build Coastguard Worker def DeleteSaInfo(self, dst, spi, proto, mark=None, xfrm_if_id=None): 573*2f2c4c7aSAndroid Build Coastguard Worker """Delete an SA from the SAD 574*2f2c4c7aSAndroid Build Coastguard Worker 575*2f2c4c7aSAndroid Build Coastguard Worker Args: 576*2f2c4c7aSAndroid Build Coastguard Worker dst: A string, the destination IP address. Forms part of the XFRM ID, and 577*2f2c4c7aSAndroid Build Coastguard Worker must match the destination address of the packets sent by this SA. 578*2f2c4c7aSAndroid Build Coastguard Worker spi: An integer, the SPI. 579*2f2c4c7aSAndroid Build Coastguard Worker proto: The protocol DB of the SA, such as IPPROTO_ESP. 580*2f2c4c7aSAndroid Build Coastguard Worker mark: A mark match specifier, such as returned by ExactMatchMark(), or 581*2f2c4c7aSAndroid Build Coastguard Worker None for an SA without a Mark attribute. 582*2f2c4c7aSAndroid Build Coastguard Worker """ 583*2f2c4c7aSAndroid Build Coastguard Worker family = AF_INET6 if ":" in dst else AF_INET 584*2f2c4c7aSAndroid Build Coastguard Worker usersa_id = XfrmUsersaId((PaddedAddress(dst), spi, family, proto)) 585*2f2c4c7aSAndroid Build Coastguard Worker nlattrs = [] 586*2f2c4c7aSAndroid Build Coastguard Worker if mark is not None: 587*2f2c4c7aSAndroid Build Coastguard Worker nlattrs.append((XFRMA_MARK, mark)) 588*2f2c4c7aSAndroid Build Coastguard Worker if xfrm_if_id is not None: 589*2f2c4c7aSAndroid Build Coastguard Worker nlattrs.append((XFRMA_IF_ID, struct.pack("=I", xfrm_if_id))) 590*2f2c4c7aSAndroid Build Coastguard Worker self.SendXfrmNlRequest(XFRM_MSG_DELSA, usersa_id, nlattrs) 591*2f2c4c7aSAndroid Build Coastguard Worker 592*2f2c4c7aSAndroid Build Coastguard Worker def AllocSpi(self, dst, proto, min_spi, max_spi): 593*2f2c4c7aSAndroid Build Coastguard Worker """Allocate (reserve) an SPI. 594*2f2c4c7aSAndroid Build Coastguard Worker 595*2f2c4c7aSAndroid Build Coastguard Worker This sends an XFRM_MSG_ALLOCSPI message and returns the resulting 596*2f2c4c7aSAndroid Build Coastguard Worker XfrmUsersaInfo struct. 597*2f2c4c7aSAndroid Build Coastguard Worker 598*2f2c4c7aSAndroid Build Coastguard Worker Args: 599*2f2c4c7aSAndroid Build Coastguard Worker dst: A string, the destination IP address. Forms part of the XFRM ID, and 600*2f2c4c7aSAndroid Build Coastguard Worker must match the destination address of the packets sent by this SA. 601*2f2c4c7aSAndroid Build Coastguard Worker proto: the protocol DB of the SA, such as IPPROTO_ESP. 602*2f2c4c7aSAndroid Build Coastguard Worker min_spi: The minimum value of the acceptable SPI range (inclusive). 603*2f2c4c7aSAndroid Build Coastguard Worker max_spi: The maximum value of the acceptable SPI range (inclusive). 604*2f2c4c7aSAndroid Build Coastguard Worker """ 605*2f2c4c7aSAndroid Build Coastguard Worker spi = XfrmUserSpiInfo(b"\x00" * len(XfrmUserSpiInfo)) 606*2f2c4c7aSAndroid Build Coastguard Worker spi.min = min_spi 607*2f2c4c7aSAndroid Build Coastguard Worker spi.max = max_spi 608*2f2c4c7aSAndroid Build Coastguard Worker spi.info.id.daddr = PaddedAddress(dst) 609*2f2c4c7aSAndroid Build Coastguard Worker spi.info.id.proto = proto 610*2f2c4c7aSAndroid Build Coastguard Worker spi.info.family = AF_INET6 if ":" in dst else AF_INET 611*2f2c4c7aSAndroid Build Coastguard Worker 612*2f2c4c7aSAndroid Build Coastguard Worker msg = spi.Pack() 613*2f2c4c7aSAndroid Build Coastguard Worker flags = netlink.NLM_F_REQUEST 614*2f2c4c7aSAndroid Build Coastguard Worker self._SendNlRequest(XFRM_MSG_ALLOCSPI, msg, flags) 615*2f2c4c7aSAndroid Build Coastguard Worker # Read the response message. 616*2f2c4c7aSAndroid Build Coastguard Worker data = self._Recv() 617*2f2c4c7aSAndroid Build Coastguard Worker nl_hdr, data = cstruct.Read(data, netlink.NLMsgHdr) 618*2f2c4c7aSAndroid Build Coastguard Worker if nl_hdr.type == XFRM_MSG_NEWSA: 619*2f2c4c7aSAndroid Build Coastguard Worker return XfrmUsersaInfo(data) 620*2f2c4c7aSAndroid Build Coastguard Worker if nl_hdr.type == netlink.NLMSG_ERROR: 621*2f2c4c7aSAndroid Build Coastguard Worker error = -netlink.NLMsgErr(data).error 622*2f2c4c7aSAndroid Build Coastguard Worker raise IOError(error, os.strerror(error)) 623*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Unexpected netlink message type: %d" % nl_hdr.type) 624*2f2c4c7aSAndroid Build Coastguard Worker 625*2f2c4c7aSAndroid Build Coastguard Worker def DumpSaInfo(self): 626*2f2c4c7aSAndroid Build Coastguard Worker return self._Dump(XFRM_MSG_GETSA, None, XfrmUsersaInfo) 627*2f2c4c7aSAndroid Build Coastguard Worker 628*2f2c4c7aSAndroid Build Coastguard Worker def DumpPolicyInfo(self): 629*2f2c4c7aSAndroid Build Coastguard Worker return self._Dump(XFRM_MSG_GETPOLICY, None, XfrmUserpolicyInfo) 630*2f2c4c7aSAndroid Build Coastguard Worker 631*2f2c4c7aSAndroid Build Coastguard Worker def FindSaInfo(self, spi): 632*2f2c4c7aSAndroid Build Coastguard Worker sainfo = [sa for sa, attrs in self.DumpSaInfo() if sa.id.spi == spi] 633*2f2c4c7aSAndroid Build Coastguard Worker return sainfo[0] if sainfo else None 634*2f2c4c7aSAndroid Build Coastguard Worker 635*2f2c4c7aSAndroid Build Coastguard Worker def FlushPolicyInfo(self): 636*2f2c4c7aSAndroid Build Coastguard Worker """Send a Netlink Request to Flush all records from the SPD""" 637*2f2c4c7aSAndroid Build Coastguard Worker flags = netlink.NLM_F_REQUEST | netlink.NLM_F_ACK 638*2f2c4c7aSAndroid Build Coastguard Worker self._SendNlRequest(XFRM_MSG_FLUSHPOLICY, b"", flags) 639*2f2c4c7aSAndroid Build Coastguard Worker 640*2f2c4c7aSAndroid Build Coastguard Worker def FlushSaInfo(self): 641*2f2c4c7aSAndroid Build Coastguard Worker usersa_flush = XfrmUsersaFlush((IPSEC_PROTO_ANY,)) 642*2f2c4c7aSAndroid Build Coastguard Worker flags = netlink.NLM_F_REQUEST | netlink.NLM_F_ACK 643*2f2c4c7aSAndroid Build Coastguard Worker self._SendNlRequest(XFRM_MSG_FLUSHSA, usersa_flush.Pack(), flags) 644*2f2c4c7aSAndroid Build Coastguard Worker 645*2f2c4c7aSAndroid Build Coastguard Worker def CreateTunnel(self, direction, selector, src, dst, spi, encryption, 646*2f2c4c7aSAndroid Build Coastguard Worker auth_trunc, mark, output_mark, xfrm_if_id, match_method): 647*2f2c4c7aSAndroid Build Coastguard Worker """Create an XFRM Tunnel Consisting of a Policy and an SA. 648*2f2c4c7aSAndroid Build Coastguard Worker 649*2f2c4c7aSAndroid Build Coastguard Worker Create a unidirectional XFRM tunnel, which entails one Policy and one 650*2f2c4c7aSAndroid Build Coastguard Worker security association. 651*2f2c4c7aSAndroid Build Coastguard Worker 652*2f2c4c7aSAndroid Build Coastguard Worker Args: 653*2f2c4c7aSAndroid Build Coastguard Worker direction: XFRM_POLICY_IN or XFRM_POLICY_OUT 654*2f2c4c7aSAndroid Build Coastguard Worker selector: An XfrmSelector that specifies the packets to be transformed. 655*2f2c4c7aSAndroid Build Coastguard Worker This is only applied to the policy; the selector in the SA is always 656*2f2c4c7aSAndroid Build Coastguard Worker empty. If the passed-in selector is None, then the tunnel is made 657*2f2c4c7aSAndroid Build Coastguard Worker dual-stack. This requires two policies, one for IPv4 and one for IPv6. 658*2f2c4c7aSAndroid Build Coastguard Worker src: The source address of the tunneled packets 659*2f2c4c7aSAndroid Build Coastguard Worker dst: The destination address of the tunneled packets 660*2f2c4c7aSAndroid Build Coastguard Worker spi: The SPI for the IPsec SA that encapsulates the tunneled packet 661*2f2c4c7aSAndroid Build Coastguard Worker encryption: A tuple (XfrmAlgo, key), the encryption parameters. 662*2f2c4c7aSAndroid Build Coastguard Worker auth_trunc: A tuple (XfrmAlgoAuth, key), the authentication parameters. 663*2f2c4c7aSAndroid Build Coastguard Worker mark: An XfrmMark, the mark used for selecting packets to be tunneled, and 664*2f2c4c7aSAndroid Build Coastguard Worker for matching the security policy. None means unspecified. 665*2f2c4c7aSAndroid Build Coastguard Worker output_mark: The mark used to select the underlying network for packets 666*2f2c4c7aSAndroid Build Coastguard Worker outbound from xfrm. None means unspecified. 667*2f2c4c7aSAndroid Build Coastguard Worker xfrm_if_id: The ID of the XFRM interface to use or None. 668*2f2c4c7aSAndroid Build Coastguard Worker match_method: One of MATCH_METHOD_[MARK | ALL | IFID]. This determines how 669*2f2c4c7aSAndroid Build Coastguard Worker SAs and policies are matched. 670*2f2c4c7aSAndroid Build Coastguard Worker """ 671*2f2c4c7aSAndroid Build Coastguard Worker outer_family = net_test.GetAddressFamily(net_test.GetAddressVersion(dst)) 672*2f2c4c7aSAndroid Build Coastguard Worker 673*2f2c4c7aSAndroid Build Coastguard Worker # SA mark is currently unused due to UPDSA not updating marks. 674*2f2c4c7aSAndroid Build Coastguard Worker # Kept as documentation of ideal/desired behavior. 675*2f2c4c7aSAndroid Build Coastguard Worker if match_method == MATCH_METHOD_MARK: 676*2f2c4c7aSAndroid Build Coastguard Worker # sa_mark = mark 677*2f2c4c7aSAndroid Build Coastguard Worker tmpl_spi = 0 678*2f2c4c7aSAndroid Build Coastguard Worker if_id = None 679*2f2c4c7aSAndroid Build Coastguard Worker elif match_method == MATCH_METHOD_ALL: 680*2f2c4c7aSAndroid Build Coastguard Worker # sa_mark = mark 681*2f2c4c7aSAndroid Build Coastguard Worker tmpl_spi = spi 682*2f2c4c7aSAndroid Build Coastguard Worker if_id = xfrm_if_id 683*2f2c4c7aSAndroid Build Coastguard Worker elif match_method == MATCH_METHOD_IFID: 684*2f2c4c7aSAndroid Build Coastguard Worker # sa_mark = None 685*2f2c4c7aSAndroid Build Coastguard Worker tmpl_spi = 0 686*2f2c4c7aSAndroid Build Coastguard Worker if_id = xfrm_if_id 687*2f2c4c7aSAndroid Build Coastguard Worker else: 688*2f2c4c7aSAndroid Build Coastguard Worker raise ValueError("Unknown match_method supplied: %s" % match_method) 689*2f2c4c7aSAndroid Build Coastguard Worker 690*2f2c4c7aSAndroid Build Coastguard Worker # Device code does not use mark; during AllocSpi, the mark is unset, and 691*2f2c4c7aSAndroid Build Coastguard Worker # UPDSA does not update marks at this time. Actual use case will have no 692*2f2c4c7aSAndroid Build Coastguard Worker # mark set. Test this use case. 693*2f2c4c7aSAndroid Build Coastguard Worker self.AddSaInfo(src, dst, spi, XFRM_MODE_TUNNEL, 0, encryption, auth_trunc, 694*2f2c4c7aSAndroid Build Coastguard Worker None, None, None, output_mark, xfrm_if_id=xfrm_if_id) 695*2f2c4c7aSAndroid Build Coastguard Worker 696*2f2c4c7aSAndroid Build Coastguard Worker if selector is None: 697*2f2c4c7aSAndroid Build Coastguard Worker selectors = [EmptySelector(AF_INET), EmptySelector(AF_INET6)] 698*2f2c4c7aSAndroid Build Coastguard Worker else: 699*2f2c4c7aSAndroid Build Coastguard Worker selectors = [selector] 700*2f2c4c7aSAndroid Build Coastguard Worker 701*2f2c4c7aSAndroid Build Coastguard Worker for selector in selectors: 702*2f2c4c7aSAndroid Build Coastguard Worker policy = UserPolicy(direction, selector) 703*2f2c4c7aSAndroid Build Coastguard Worker tmpl = UserTemplate(outer_family, tmpl_spi, 0, (src, dst)) 704*2f2c4c7aSAndroid Build Coastguard Worker self.AddPolicyInfo(policy, tmpl, mark, xfrm_if_id=xfrm_if_id) 705*2f2c4c7aSAndroid Build Coastguard Worker 706*2f2c4c7aSAndroid Build Coastguard Worker def DeleteTunnel(self, direction, selector, dst, spi, mark, xfrm_if_id): 707*2f2c4c7aSAndroid Build Coastguard Worker if mark is not None: 708*2f2c4c7aSAndroid Build Coastguard Worker mark = ExactMatchMark(mark) 709*2f2c4c7aSAndroid Build Coastguard Worker 710*2f2c4c7aSAndroid Build Coastguard Worker self.DeleteSaInfo(dst, spi, IPPROTO_ESP, mark, xfrm_if_id) 711*2f2c4c7aSAndroid Build Coastguard Worker if selector is None: 712*2f2c4c7aSAndroid Build Coastguard Worker selectors = [EmptySelector(AF_INET), EmptySelector(AF_INET6)] 713*2f2c4c7aSAndroid Build Coastguard Worker else: 714*2f2c4c7aSAndroid Build Coastguard Worker selectors = [selector] 715*2f2c4c7aSAndroid Build Coastguard Worker for selector in selectors: 716*2f2c4c7aSAndroid Build Coastguard Worker self.DeletePolicyInfo(selector, direction, mark, xfrm_if_id) 717*2f2c4c7aSAndroid Build Coastguard Worker 718*2f2c4c7aSAndroid Build Coastguard Worker def MigrateTunnel(self, direction, selector, old_saddr, old_daddr, 719*2f2c4c7aSAndroid Build Coastguard Worker new_saddr, new_daddr, spi, 720*2f2c4c7aSAndroid Build Coastguard Worker encryption, auth_trunc, aead, 721*2f2c4c7aSAndroid Build Coastguard Worker encap, new_output_mark, xfrm_if_id): 722*2f2c4c7aSAndroid Build Coastguard Worker """Update addresses and underlying network of Policies and an SA 723*2f2c4c7aSAndroid Build Coastguard Worker 724*2f2c4c7aSAndroid Build Coastguard Worker Args: 725*2f2c4c7aSAndroid Build Coastguard Worker direction: XFRM_POLICY_IN or XFRM_POLICY_OUT 726*2f2c4c7aSAndroid Build Coastguard Worker selector: An XfrmSelector of the tunnel that needs to be updated. 727*2f2c4c7aSAndroid Build Coastguard Worker If the passed-in selector is None, it means the tunnel is 728*2f2c4c7aSAndroid Build Coastguard Worker dual-stack and thus both IPv4 and IPv6 policies will be updated. 729*2f2c4c7aSAndroid Build Coastguard Worker old_saddr: the old (current) source address of the tunnel 730*2f2c4c7aSAndroid Build Coastguard Worker old_daddr: the old (current) destination address of the tunnel 731*2f2c4c7aSAndroid Build Coastguard Worker new_saddr: the new source address the IPsec SA will be migrated to 732*2f2c4c7aSAndroid Build Coastguard Worker new_daddr: the new destination address the tunnel will be migrated to 733*2f2c4c7aSAndroid Build Coastguard Worker spi: The SPI for the IPsec SA that encapsulates the tunneled packets 734*2f2c4c7aSAndroid Build Coastguard Worker encryption: A tuple of an XfrmAlgo and raw key bytes, or None. 735*2f2c4c7aSAndroid Build Coastguard Worker auth_trunc: A tuple of an XfrmAlgoAuth and raw key bytes, or None. 736*2f2c4c7aSAndroid Build Coastguard Worker aead: A tuple of an XfrmAlgoAead and raw key bytes, or None. 737*2f2c4c7aSAndroid Build Coastguard Worker encap: An XfrmEncapTmpl structure, or None. 738*2f2c4c7aSAndroid Build Coastguard Worker new_output_mark: The mark used to select the new underlying network 739*2f2c4c7aSAndroid Build Coastguard Worker for packets outbound from xfrm. None means unspecified. 740*2f2c4c7aSAndroid Build Coastguard Worker xfrm_if_id: The XFRM interface ID 741*2f2c4c7aSAndroid Build Coastguard Worker """ 742*2f2c4c7aSAndroid Build Coastguard Worker 743*2f2c4c7aSAndroid Build Coastguard Worker if selector is None: 744*2f2c4c7aSAndroid Build Coastguard Worker selectors = [EmptySelector(AF_INET), EmptySelector(AF_INET6)] 745*2f2c4c7aSAndroid Build Coastguard Worker else: 746*2f2c4c7aSAndroid Build Coastguard Worker selectors = [selector] 747*2f2c4c7aSAndroid Build Coastguard Worker 748*2f2c4c7aSAndroid Build Coastguard Worker nlattrs = [] 749*2f2c4c7aSAndroid Build Coastguard Worker xfrmMigrate = XfrmMigrate((PaddedAddress(old_daddr), PaddedAddress(old_saddr), 750*2f2c4c7aSAndroid Build Coastguard Worker PaddedAddress(new_daddr), PaddedAddress(new_saddr), 751*2f2c4c7aSAndroid Build Coastguard Worker IPPROTO_ESP, XFRM_MODE_TUNNEL, 0, 752*2f2c4c7aSAndroid Build Coastguard Worker net_test.GetAddressFamily(net_test.GetAddressVersion(old_saddr)), 753*2f2c4c7aSAndroid Build Coastguard Worker net_test.GetAddressFamily(net_test.GetAddressVersion(new_saddr)))) 754*2f2c4c7aSAndroid Build Coastguard Worker nlattrs.append((XFRMA_MIGRATE, xfrmMigrate)) 755*2f2c4c7aSAndroid Build Coastguard Worker 756*2f2c4c7aSAndroid Build Coastguard Worker if xfrm_if_id is not None: 757*2f2c4c7aSAndroid Build Coastguard Worker nlattrs.append((XFRMA_IF_ID, struct.pack("=I", xfrm_if_id))) 758*2f2c4c7aSAndroid Build Coastguard Worker 759*2f2c4c7aSAndroid Build Coastguard Worker for selector in selectors: 760*2f2c4c7aSAndroid Build Coastguard Worker self.SendXfrmNlRequest(XFRM_MSG_MIGRATE, 761*2f2c4c7aSAndroid Build Coastguard Worker XfrmUserpolicyId(sel=selector, dir=direction), nlattrs) 762*2f2c4c7aSAndroid Build Coastguard Worker 763*2f2c4c7aSAndroid Build Coastguard Worker # UPDSA is called exclusively to update the set_mark=new_output_mark. 764*2f2c4c7aSAndroid Build Coastguard Worker self.AddSaInfo(new_saddr, new_daddr, spi, XFRM_MODE_TUNNEL, 0, encryption, 765*2f2c4c7aSAndroid Build Coastguard Worker auth_trunc, aead, encap, None, new_output_mark, True, xfrm_if_id) 766*2f2c4c7aSAndroid Build Coastguard Worker 767*2f2c4c7aSAndroid Build Coastguard Worker 768*2f2c4c7aSAndroid Build Coastguard Workerif __name__ == "__main__": 769*2f2c4c7aSAndroid Build Coastguard Worker x = Xfrm() 770*2f2c4c7aSAndroid Build Coastguard Worker print(x.DumpSaInfo()) 771*2f2c4c7aSAndroid Build Coastguard Worker print(x.DumpPolicyInfo()) 772