• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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