Merge changes Ibd38e3c0,I0e9f52aa into main

* changes:
  [XFRM_MSG_NEWSA] Support xfrm_lifetime_cfg and xfrm_lifetime_cur
  [XFRM_MSG_NEWSA] Support xfrm_selector and xfrm_id
This commit is contained in:
Yan Yan 2023-11-28 22:51:44 +00:00 • committed by Gerrit Code Review
commit 7475acf7e2
9 changed files with 677 additions and 0 deletions

View file

@ -0,0 +1,72 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.net.module.util.netlink.xfrm;
import androidx.annotation.NonNull;
import com.android.net.module.util.Struct;
import java.net.InetAddress;
/**
* Struct xfrm_id
*
* <p>see include/uapi/linux/xfrm.h
*
* <pre>
* struct xfrm_id {
* xfrm_address_t daddr;
* __be32 spi;
* __u8 proto;
* };
* </pre>
*
* @hide
*/
public class StructXfrmId extends Struct {
public static final int STRUCT_SIZE = 24;
@Field(order = 0, type = Type.ByteArray, arraysize = 16)
public final byte[] nestedStructDAddr;
@Field(order = 1, type = Type.UBE32)
public final long spi;
@Field(order = 2, type = Type.U8, padding = 3)
public final short proto;
@Computed private final StructXfrmAddressT mDestXfrmAddressT;
// Constructor that allows Strutc.parse(Class<T>, ByteBuffer) to work
public StructXfrmId(@NonNull final byte[] nestedStructDAddr, long spi, short proto) {
this.nestedStructDAddr = nestedStructDAddr.clone();
this.spi = spi;
this.proto = proto;
mDestXfrmAddressT = new StructXfrmAddressT(this.nestedStructDAddr);
}
// Constructor to build a new message
public StructXfrmId(@NonNull final InetAddress destAddress, long spi, short proto) {
this(new StructXfrmAddressT(destAddress).writeToBytes(), spi, proto);
}
/** Return the destination address */
public InetAddress getDestAddress(int family) {
return mDestXfrmAddressT.getAddress(family);
}
}

View file

@ -0,0 +1,106 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.net.module.util.netlink.xfrm;
import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.XFRM_INF;
import androidx.annotation.NonNull;
import com.android.net.module.util.Struct;
import java.math.BigInteger;
/**
* Struct xfrm_lifetime_cfg
*
* <p>see include/uapi/linux/xfrm.h
*
* <pre>
* struct xfrm_lifetime_cfg {
* __u64 soft_byte_limit;
* __u64 hard_byte_limit;
* __u64 soft_packet_limit;
* __u64 hard_packet_limit;
* __u64 soft_add_expires_seconds;
* __u64 hard_add_expires_seconds;
* __u64 soft_use_expires_seconds;
* __u64 hard_use_expires_seconds;
* };
* </pre>
*
* @hide
*/
public class StructXfrmLifetimeCfg extends Struct {
public static final int STRUCT_SIZE = 64;
@Field(order = 0, type = Type.U64)
public final BigInteger softByteLimit;
@Field(order = 1, type = Type.U64)
public final BigInteger hardByteLimit;
@Field(order = 2, type = Type.U64)
public final BigInteger softPacketLimit;
@Field(order = 3, type = Type.U64)
public final BigInteger hardPacketLimit;
@Field(order = 4, type = Type.U64)
public final BigInteger softAddExpiresSeconds;
@Field(order = 5, type = Type.U64)
public final BigInteger hardAddExpiresSeconds;
@Field(order = 6, type = Type.U64)
public final BigInteger softUseExpiresSeconds;
@Field(order = 7, type = Type.U64)
public final BigInteger hardUseExpiresSeconds;
// Constructor that allows Strutc.parse(Class<T>, ByteBuffer) to work
public StructXfrmLifetimeCfg(
@NonNull final BigInteger softByteLimit,
@NonNull final BigInteger hardByteLimit,
@NonNull final BigInteger softPacketLimit,
@NonNull final BigInteger hardPacketLimit,
@NonNull final BigInteger softAddExpiresSeconds,
@NonNull final BigInteger hardAddExpiresSeconds,
@NonNull final BigInteger softUseExpiresSeconds,
@NonNull final BigInteger hardUseExpiresSeconds) {
this.softByteLimit = softByteLimit;
this.hardByteLimit = hardByteLimit;
this.softPacketLimit = softPacketLimit;
this.hardPacketLimit = hardPacketLimit;
this.softAddExpiresSeconds = softAddExpiresSeconds;
this.hardAddExpiresSeconds = hardAddExpiresSeconds;
this.softUseExpiresSeconds = softUseExpiresSeconds;
this.hardUseExpiresSeconds = hardUseExpiresSeconds;
}
// Constructor to build a new message
public StructXfrmLifetimeCfg() {
this(
XFRM_INF,
XFRM_INF,
XFRM_INF,
XFRM_INF,
BigInteger.ZERO,
BigInteger.ZERO,
BigInteger.ZERO,
BigInteger.ZERO);
}
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.net.module.util.netlink.xfrm;
import androidx.annotation.NonNull;
import com.android.net.module.util.Struct;
import java.math.BigInteger;
/**
* Struct xfrm_lifetime_cur
*
* <p>see include/uapi/linux/xfrm.h
*
* <pre>
* struct xfrm_lifetime_cur {
* __u64 bytes;
* __u64 packets;
* __u64 add_time;
* __u64 use_time;
* };
* </pre>
*
* @hide
*/
public class StructXfrmLifetimeCur extends Struct {
public static final int STRUCT_SIZE = 32;
@Field(order = 0, type = Type.U64)
public final BigInteger bytes;
@Field(order = 1, type = Type.U64)
public final BigInteger packets;
@Field(order = 2, type = Type.U64)
public final BigInteger addTime;
@Field(order = 3, type = Type.U64)
public final BigInteger useTime;
public StructXfrmLifetimeCur(
@NonNull final BigInteger bytes,
@NonNull final BigInteger packets,
@NonNull final BigInteger addTime,
@NonNull final BigInteger useTime) {
this.bytes = bytes;
this.packets = packets;
this.addTime = addTime;
this.useTime = useTime;
}
}

View file

@ -0,0 +1,132 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.net.module.util.netlink.xfrm;
import androidx.annotation.NonNull;
import com.android.net.module.util.Struct;
import com.android.net.module.util.Struct.Field;
import com.android.net.module.util.Struct.Type;
/**
* Struct xfrm_selector
*
* <p>see include/uapi/linux/xfrm.h
*
* <pre>
* struct xfrm_selector {
* xfrm_address_t daddr;
* xfrm_address_t saddr;
* __be16 dport;
* __be16 dport_mask;
* __be16 sport;
* __be16 sport_mask;
* __u16 family;
* __u8 prefixlen_d;
* __u8 prefixlen_s;
* __u8 proto;
* int ifindex;
* __kernel_uid32_t user;
* };
* </pre>
*
* @hide
*/
public class StructXfrmSelector extends Struct {
public static final int STRUCT_SIZE = 56;
@Field(order = 0, type = Type.ByteArray, arraysize = 16)
public final byte[] nestedStructDAddr;
@Field(order = 1, type = Type.ByteArray, arraysize = 16)
public final byte[] nestedStructSAddr;
@Field(order = 2, type = Type.UBE16)
public final int dPort;
@Field(order = 3, type = Type.UBE16)
public final int dPortMask;
@Field(order = 4, type = Type.UBE16)
public final int sPort;
@Field(order = 5, type = Type.UBE16)
public final int sPortMask;
@Field(order = 6, type = Type.U16)
public final int selectorFamily;
@Field(order = 7, type = Type.U8, padding = 1)
public final short prefixlenD;
@Field(order = 8, type = Type.U8, padding = 1)
public final short prefixlenS;
@Field(order = 9, type = Type.U8, padding = 1)
public final short proto;
@Field(order = 10, type = Type.S32)
public final int ifIndex;
@Field(order = 11, type = Type.S32)
public final int user;
// Constructor that allows Strutc.parse(Class<T>, ByteBuffer) to work
public StructXfrmSelector(
@NonNull final byte[] nestedStructDAddr,
@NonNull final byte[] nestedStructSAddr,
int dPort,
int dPortMask,
int sPort,
int sPortMask,
int selectorFamily,
short prefixlenD,
short prefixlenS,
short proto,
int ifIndex,
int user) {
this.nestedStructDAddr = nestedStructDAddr.clone();
this.nestedStructSAddr = nestedStructSAddr.clone();
this.dPort = dPort;
this.dPortMask = dPortMask;
this.sPort = sPort;
this.sPortMask = sPortMask;
this.selectorFamily = selectorFamily;
this.prefixlenD = prefixlenD;
this.prefixlenS = prefixlenS;
this.proto = proto;
this.ifIndex = ifIndex;
this.user = user;
}
// Constructor to build a new message
public StructXfrmSelector(int selectorFamily) {
this(
new byte[StructXfrmAddressT.STRUCT_SIZE],
new byte[StructXfrmAddressT.STRUCT_SIZE],
0 /* dPort */,
0 /* dPortMask */,
0 /* sPort */,
0 /* sPortMask */,
selectorFamily,
(short) 0 /* prefixlenD */,
(short) 0 /* prefixlenS */,
(short) 0 /* proto */,
0 /* ifIndex */,
0 /* user */);
}
}

View file

@ -22,6 +22,7 @@ import androidx.annotation.Nullable;
import com.android.net.module.util.netlink.NetlinkMessage;
import com.android.net.module.util.netlink.StructNlMsgHdr;
import java.math.BigInteger;
import java.nio.ByteBuffer;
/** Base calss for XFRM netlink messages */
@ -40,6 +41,8 @@ public abstract class XfrmNetlinkMessage extends NetlinkMessage {
public static final short XFRM_MSG_NEWSA = 16;
public static final short XFRM_MSG_GETSA = 18;
public static final BigInteger XFRM_INF = new BigInteger("FFFFFFFFFFFFFFFF", 16);
public XfrmNetlinkMessage(@NonNull final StructNlMsgHdr header) {
super(header);
}

View file

@ -0,0 +1,70 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.net.module.util.netlink.xfrm;
import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.IPPROTO_ESP;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import android.net.InetAddresses;
import android.system.OsConstants;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.net.module.util.HexDump;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class StructXfrmIdTest {
private static final String EXPECTED_HEX_STRING =
"C0000201000000000000000000000000" + "53FA0FDD32000000";
private static final byte[] EXPECTED_HEX = HexDump.hexStringToByteArray(EXPECTED_HEX_STRING);
private static final InetAddress DEST_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.1");
private static final long SPI = 0x53fa0fdd;
private static final short PROTO = IPPROTO_ESP;
@Test
public void testEncode() throws Exception {
final StructXfrmId struct = new StructXfrmId(DEST_ADDRESS, SPI, PROTO);
final ByteBuffer buffer = ByteBuffer.allocate(EXPECTED_HEX.length);
buffer.order(ByteOrder.nativeOrder());
struct.writeToByteBuffer(buffer);
assertArrayEquals(EXPECTED_HEX, buffer.array());
}
@Test
public void testDecode() throws Exception {
final ByteBuffer buffer = ByteBuffer.wrap(EXPECTED_HEX);
buffer.order(ByteOrder.nativeOrder());
final StructXfrmId struct = StructXfrmId.parse(StructXfrmId.class, buffer);
assertEquals(DEST_ADDRESS, struct.getDestAddress(OsConstants.AF_INET));
assertEquals(SPI, struct.spi);
assertEquals(PROTO, struct.proto);
}
}

View file

@ -0,0 +1,73 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.net.module.util.netlink.xfrm;
import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.XFRM_INF;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.net.module.util.HexDump;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class StructXfrmLifetimeCfgTest {
private static final String EXPECTED_HEX_STRING =
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000";
private static final byte[] EXPECTED_HEX = HexDump.hexStringToByteArray(EXPECTED_HEX_STRING);
@Test
public void testEncode() throws Exception {
final StructXfrmLifetimeCfg struct = new StructXfrmLifetimeCfg();
final ByteBuffer buffer = ByteBuffer.allocate(EXPECTED_HEX.length);
buffer.order(ByteOrder.nativeOrder());
struct.writeToByteBuffer(buffer);
assertArrayEquals(EXPECTED_HEX, buffer.array());
}
@Test
public void testDecode() throws Exception {
final ByteBuffer buffer = ByteBuffer.wrap(EXPECTED_HEX);
buffer.order(ByteOrder.nativeOrder());
final StructXfrmLifetimeCfg struct =
StructXfrmLifetimeCfg.parse(StructXfrmLifetimeCfg.class, buffer);
assertEquals(XFRM_INF, struct.softByteLimit);
assertEquals(XFRM_INF, struct.hardByteLimit);
assertEquals(XFRM_INF, struct.softPacketLimit);
assertEquals(XFRM_INF, struct.hardPacketLimit);
assertEquals(BigInteger.ZERO, struct.softAddExpiresSeconds);
assertEquals(BigInteger.ZERO, struct.hardAddExpiresSeconds);
assertEquals(BigInteger.ZERO, struct.softUseExpiresSeconds);
assertEquals(BigInteger.ZERO, struct.hardUseExpiresSeconds);
}
}

View file

@ -0,0 +1,76 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.net.module.util.netlink.xfrm;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.net.module.util.HexDump;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class StructXfrmLifetimeCurTest {
private static final String EXPECTED_HEX_STRING =
"00000000000000000000000000000000" + "8CFE4265000000000000000000000000";
private static final byte[] EXPECTED_HEX = HexDump.hexStringToByteArray(EXPECTED_HEX_STRING);
private static final BigInteger ADD_TIME;
static {
final Calendar cal = Calendar.getInstance();
cal.set(2023, Calendar.NOVEMBER, 2, 1, 42, 36);
final long timestampSeconds = TimeUnit.MILLISECONDS.toSeconds(cal.getTimeInMillis());
ADD_TIME = BigInteger.valueOf(timestampSeconds);
}
@Test
public void testEncode() throws Exception {
final StructXfrmLifetimeCur struct =
new StructXfrmLifetimeCur(
BigInteger.ZERO, BigInteger.ZERO, ADD_TIME, BigInteger.ZERO);
final ByteBuffer buffer = ByteBuffer.allocate(EXPECTED_HEX.length);
buffer.order(ByteOrder.nativeOrder());
struct.writeToByteBuffer(buffer);
assertArrayEquals(EXPECTED_HEX, buffer.array());
}
@Test
public void testDecode() throws Exception {
final ByteBuffer buffer = ByteBuffer.wrap(EXPECTED_HEX);
buffer.order(ByteOrder.nativeOrder());
final StructXfrmLifetimeCur struct =
StructXfrmLifetimeCur.parse(StructXfrmLifetimeCur.class, buffer);
assertEquals(BigInteger.ZERO, struct.bytes);
assertEquals(BigInteger.ZERO, struct.packets);
assertEquals(ADD_TIME, struct.addTime);
assertEquals(BigInteger.ZERO, struct.useTime);
}
}

View file

@ -0,0 +1,79 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.net.module.util.netlink.xfrm;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import android.system.OsConstants;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.net.module.util.HexDump;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class StructXfrmSelectorTest {
private static final String EXPECTED_HEX_STRING =
"00000000000000000000000000000000"
+ "00000000000000000000000000000000"
+ "00000000000000000200000000000000"
+ "0000000000000000";
private static final byte[] EXPECTED_HEX = HexDump.hexStringToByteArray(EXPECTED_HEX_STRING);
private static final byte[] XFRM_ADDRESS_T_ANY_BYTES = new byte[16];
private static final int FAMILY = OsConstants.AF_INET;
@Test
public void testEncode() throws Exception {
final StructXfrmSelector struct = new StructXfrmSelector(FAMILY);
final ByteBuffer buffer = ByteBuffer.allocate(EXPECTED_HEX.length);
buffer.order(ByteOrder.nativeOrder());
struct.writeToByteBuffer(buffer);
assertArrayEquals(EXPECTED_HEX, buffer.array());
}
@Test
public void testDecode() throws Exception {
final ByteBuffer buffer = ByteBuffer.wrap(EXPECTED_HEX);
buffer.order(ByteOrder.nativeOrder());
final StructXfrmSelector struct =
StructXfrmSelector.parse(StructXfrmSelector.class, buffer);
assertArrayEquals(XFRM_ADDRESS_T_ANY_BYTES, struct.nestedStructDAddr);
assertArrayEquals(XFRM_ADDRESS_T_ANY_BYTES, struct.nestedStructSAddr);
assertEquals(0, struct.dPort);
assertEquals(0, struct.dPortMask);
assertEquals(0, struct.sPort);
assertEquals(0, struct.sPortMask);
assertEquals(FAMILY, struct.selectorFamily);
assertEquals(0, struct.prefixlenD);
assertEquals(0, struct.prefixlenS);
assertEquals(0, struct.proto);
assertEquals(0, struct.ifIndex);
assertEquals(0, struct.user);
}
}