1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.net.module.util.netlink.xfrm; 18 19 import androidx.annotation.NonNull; 20 import androidx.annotation.Nullable; 21 22 import com.android.net.module.util.netlink.NetlinkMessage; 23 import com.android.net.module.util.netlink.StructNlMsgHdr; 24 25 import java.math.BigInteger; 26 import java.nio.ByteBuffer; 27 28 /** Base calss for XFRM netlink messages */ 29 // Developer notes: The Linux kernel includes a number of XFRM structs that are not standard netlink 30 // attributes (e.g., xfrm_usersa_id). These structs are unlikely to change size, so this XFRM 31 // netlink message implementation assumes their sizes will remain stable. If any non-attribute 32 // struct size changes, it should be caught by CTS and then developers should add 33 // kernel-version-based behvaiours. 34 public abstract class XfrmNetlinkMessage extends NetlinkMessage { 35 // TODO: b/312498032 Remove it when OsConstants.IPPROTO_ESP is stable 36 public static final int IPPROTO_ESP = 50; 37 // TODO: b/312498032 Remove it when OsConstants.NETLINK_XFRM is stable 38 public static final int NETLINK_XFRM = 6; 39 40 /* see include/uapi/linux/xfrm.h */ 41 public static final short XFRM_MSG_NEWSA = 16; 42 public static final short XFRM_MSG_GETSA = 18; 43 44 public static final int XFRM_MODE_TRANSPORT = 0; 45 public static final int XFRM_MODE_TUNNEL = 1; 46 47 public static final short XFRMA_REPLAY_VAL = 10; 48 public static final short XFRMA_REPLAY_ESN_VAL = 23; 49 50 public static final BigInteger XFRM_INF = new BigInteger("FFFFFFFFFFFFFFFF", 16); 51 XfrmNetlinkMessage(@onNull final StructNlMsgHdr header)52 public XfrmNetlinkMessage(@NonNull final StructNlMsgHdr header) { 53 super(header); 54 } 55 56 /** 57 * Parse XFRM message from ByteBuffer. 58 * 59 * <p>This method should be called from NetlinkMessage#parse(ByteBuffer, int) for generic 60 * message validation and processing 61 * 62 * @param nlmsghdr netlink message header. 63 * @param byteBuffer the ByteBuffer instance that wraps the raw netlink message bytes. MUST be 64 * host order 65 */ 66 @Nullable parseXfrmInternal( @onNull final StructNlMsgHdr nlmsghdr, @NonNull final ByteBuffer byteBuffer)67 public static XfrmNetlinkMessage parseXfrmInternal( 68 @NonNull final StructNlMsgHdr nlmsghdr, @NonNull final ByteBuffer byteBuffer) { 69 switch (nlmsghdr.nlmsg_type) { 70 case XFRM_MSG_NEWSA: 71 return XfrmNetlinkNewSaMessage.parseInternal(nlmsghdr, byteBuffer); 72 case XFRM_MSG_GETSA: 73 return XfrmNetlinkGetSaMessage.parseInternal(nlmsghdr, byteBuffer); 74 default: 75 return null; 76 } 77 } 78 packPayload(@onNull final ByteBuffer byteBuffer)79 protected abstract void packPayload(@NonNull final ByteBuffer byteBuffer); 80 81 /** Write a XFRM message to {@link ByteBuffer}. */ pack(@onNull final ByteBuffer byteBuffer)82 public void pack(@NonNull final ByteBuffer byteBuffer) { 83 getHeader().pack(byteBuffer); 84 packPayload(byteBuffer); 85 } 86 } 87