xref: /aosp_15_r20/system/netd/server/XfrmController.h (revision 8542734a0dd1db395a4d42aae09c37f3c3c3e7a1)
1*8542734aSAndroid Build Coastguard Worker /*
2*8542734aSAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*8542734aSAndroid Build Coastguard Worker  *
4*8542734aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*8542734aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*8542734aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*8542734aSAndroid Build Coastguard Worker  *
8*8542734aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*8542734aSAndroid Build Coastguard Worker  *
10*8542734aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*8542734aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*8542734aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8542734aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*8542734aSAndroid Build Coastguard Worker  * limitations under the License.
15*8542734aSAndroid Build Coastguard Worker  */
16*8542734aSAndroid Build Coastguard Worker #ifndef _XFRM_CONTROLLER_H
17*8542734aSAndroid Build Coastguard Worker #define _XFRM_CONTROLLER_H
18*8542734aSAndroid Build Coastguard Worker 
19*8542734aSAndroid Build Coastguard Worker #include <atomic>
20*8542734aSAndroid Build Coastguard Worker #include <list>
21*8542734aSAndroid Build Coastguard Worker #include <map>
22*8542734aSAndroid Build Coastguard Worker #include <string>
23*8542734aSAndroid Build Coastguard Worker #include <utility> // for pair
24*8542734aSAndroid Build Coastguard Worker 
25*8542734aSAndroid Build Coastguard Worker #include <linux/if.h>
26*8542734aSAndroid Build Coastguard Worker #include <linux/if_link.h>
27*8542734aSAndroid Build Coastguard Worker #include <linux/if_tunnel.h>
28*8542734aSAndroid Build Coastguard Worker #include <linux/netlink.h>
29*8542734aSAndroid Build Coastguard Worker #include <linux/udp.h>
30*8542734aSAndroid Build Coastguard Worker #include <linux/xfrm.h>
31*8542734aSAndroid Build Coastguard Worker #include <unistd.h>
32*8542734aSAndroid Build Coastguard Worker 
33*8542734aSAndroid Build Coastguard Worker #include "NetdConstants.h"
34*8542734aSAndroid Build Coastguard Worker #include "android-base/unique_fd.h"
35*8542734aSAndroid Build Coastguard Worker #include "netdutils/DumpWriter.h"
36*8542734aSAndroid Build Coastguard Worker #include "netdutils/Slice.h"
37*8542734aSAndroid Build Coastguard Worker #include "netdutils/Status.h"
38*8542734aSAndroid Build Coastguard Worker #include "sysutils/SocketClient.h"
39*8542734aSAndroid Build Coastguard Worker 
40*8542734aSAndroid Build Coastguard Worker namespace android {
41*8542734aSAndroid Build Coastguard Worker namespace net {
42*8542734aSAndroid Build Coastguard Worker 
43*8542734aSAndroid Build Coastguard Worker // Exposed for testing
44*8542734aSAndroid Build Coastguard Worker extern const uint32_t ALGO_MASK_AUTH_ALL;
45*8542734aSAndroid Build Coastguard Worker // Exposed for testing
46*8542734aSAndroid Build Coastguard Worker extern const uint32_t ALGO_MASK_CRYPT_ALL;
47*8542734aSAndroid Build Coastguard Worker // Exposed for testing
48*8542734aSAndroid Build Coastguard Worker extern const uint32_t ALGO_MASK_AEAD_ALL;
49*8542734aSAndroid Build Coastguard Worker // Exposed for testing
50*8542734aSAndroid Build Coastguard Worker extern const uint8_t REPLAY_WINDOW_SIZE;
51*8542734aSAndroid Build Coastguard Worker // Exposed for testing
52*8542734aSAndroid Build Coastguard Worker extern const uint32_t REPLAY_WINDOW_SIZE_ESN;
53*8542734aSAndroid Build Coastguard Worker 
54*8542734aSAndroid Build Coastguard Worker // Suggest we avoid the smallest and largest ints
55*8542734aSAndroid Build Coastguard Worker class XfrmMessage;
56*8542734aSAndroid Build Coastguard Worker class TransportModeSecurityAssociation;
57*8542734aSAndroid Build Coastguard Worker 
58*8542734aSAndroid Build Coastguard Worker class XfrmSocket {
59*8542734aSAndroid Build Coastguard Worker public:
60*8542734aSAndroid Build Coastguard Worker     // called from destructor and thus cannot be virtual
close()61*8542734aSAndroid Build Coastguard Worker     void close() {
62*8542734aSAndroid Build Coastguard Worker         if (mSock >= 0) {
63*8542734aSAndroid Build Coastguard Worker             ::close(mSock);
64*8542734aSAndroid Build Coastguard Worker         }
65*8542734aSAndroid Build Coastguard Worker         mSock = -1;
66*8542734aSAndroid Build Coastguard Worker     }
67*8542734aSAndroid Build Coastguard Worker 
68*8542734aSAndroid Build Coastguard Worker     virtual netdutils::Status open() = 0;
69*8542734aSAndroid Build Coastguard Worker 
~XfrmSocket()70*8542734aSAndroid Build Coastguard Worker     virtual ~XfrmSocket() { close(); }
71*8542734aSAndroid Build Coastguard Worker 
72*8542734aSAndroid Build Coastguard Worker     // Sends the netlink message contained in iovecs. This populates iovecs[0] with
73*8542734aSAndroid Build Coastguard Worker     // a valid netlink message header.
74*8542734aSAndroid Build Coastguard Worker     virtual netdutils::Status sendMessage(uint16_t nlMsgType, uint16_t nlMsgFlags,
75*8542734aSAndroid Build Coastguard Worker                                           uint16_t nlMsgSeqNum,
76*8542734aSAndroid Build Coastguard Worker                                           std::vector<iovec>* iovecs) const = 0;
77*8542734aSAndroid Build Coastguard Worker 
78*8542734aSAndroid Build Coastguard Worker protected:
79*8542734aSAndroid Build Coastguard Worker     int mSock;
80*8542734aSAndroid Build Coastguard Worker };
81*8542734aSAndroid Build Coastguard Worker 
82*8542734aSAndroid Build Coastguard Worker enum struct XfrmDirection : uint8_t {
83*8542734aSAndroid Build Coastguard Worker     IN = XFRM_POLICY_IN,
84*8542734aSAndroid Build Coastguard Worker     OUT = XFRM_POLICY_OUT,
85*8542734aSAndroid Build Coastguard Worker     FORWARD = XFRM_POLICY_FWD,
86*8542734aSAndroid Build Coastguard Worker     MASK = XFRM_POLICY_MASK,
87*8542734aSAndroid Build Coastguard Worker };
88*8542734aSAndroid Build Coastguard Worker 
89*8542734aSAndroid Build Coastguard Worker enum struct XfrmMode : uint8_t {
90*8542734aSAndroid Build Coastguard Worker     TRANSPORT = XFRM_MODE_TRANSPORT,
91*8542734aSAndroid Build Coastguard Worker     TUNNEL = XFRM_MODE_TUNNEL,
92*8542734aSAndroid Build Coastguard Worker };
93*8542734aSAndroid Build Coastguard Worker 
94*8542734aSAndroid Build Coastguard Worker enum struct XfrmEncapType : uint16_t {
95*8542734aSAndroid Build Coastguard Worker     NONE = 0,
96*8542734aSAndroid Build Coastguard Worker     ESPINUDP_NON_IKE = UDP_ENCAP_ESPINUDP_NON_IKE,
97*8542734aSAndroid Build Coastguard Worker     ESPINUDP = UDP_ENCAP_ESPINUDP
98*8542734aSAndroid Build Coastguard Worker };
99*8542734aSAndroid Build Coastguard Worker 
100*8542734aSAndroid Build Coastguard Worker struct XfrmAlgo {
101*8542734aSAndroid Build Coastguard Worker     std::string name;
102*8542734aSAndroid Build Coastguard Worker     std::vector<uint8_t> key;
103*8542734aSAndroid Build Coastguard Worker     uint16_t truncLenBits;
104*8542734aSAndroid Build Coastguard Worker };
105*8542734aSAndroid Build Coastguard Worker 
106*8542734aSAndroid Build Coastguard Worker struct XfrmEncap {
107*8542734aSAndroid Build Coastguard Worker     XfrmEncapType type;
108*8542734aSAndroid Build Coastguard Worker     uint16_t srcPort;
109*8542734aSAndroid Build Coastguard Worker     uint16_t dstPort;
110*8542734aSAndroid Build Coastguard Worker };
111*8542734aSAndroid Build Coastguard Worker 
112*8542734aSAndroid Build Coastguard Worker struct XfrmEndpointPair {
113*8542734aSAndroid Build Coastguard Worker     xfrm_address_t dstAddr; // network order
114*8542734aSAndroid Build Coastguard Worker     xfrm_address_t srcAddr;
115*8542734aSAndroid Build Coastguard Worker     int addrFamily;  // AF_INET or AF_INET6
116*8542734aSAndroid Build Coastguard Worker };
117*8542734aSAndroid Build Coastguard Worker 
118*8542734aSAndroid Build Coastguard Worker // minimally sufficient structure to match either an SA or a Policy
119*8542734aSAndroid Build Coastguard Worker struct XfrmCommonInfo : XfrmEndpointPair {
120*8542734aSAndroid Build Coastguard Worker     // TODO: b/259298885 rename "transformId" to "requestId" and update
121*8542734aSAndroid Build Coastguard Worker     // all the related methods/fields/logs
122*8542734aSAndroid Build Coastguard Worker     int transformId; // requestId
123*8542734aSAndroid Build Coastguard Worker     int spi;
124*8542734aSAndroid Build Coastguard Worker     xfrm_mark mark;
125*8542734aSAndroid Build Coastguard Worker     int xfrm_if_id;
126*8542734aSAndroid Build Coastguard Worker     XfrmMode mode;
127*8542734aSAndroid Build Coastguard Worker };
128*8542734aSAndroid Build Coastguard Worker 
129*8542734aSAndroid Build Coastguard Worker struct XfrmSaInfo : XfrmCommonInfo {
130*8542734aSAndroid Build Coastguard Worker     XfrmAlgo auth;
131*8542734aSAndroid Build Coastguard Worker     XfrmAlgo crypt;
132*8542734aSAndroid Build Coastguard Worker     XfrmAlgo aead;
133*8542734aSAndroid Build Coastguard Worker     int netId;
134*8542734aSAndroid Build Coastguard Worker     XfrmEncap encap;
135*8542734aSAndroid Build Coastguard Worker };
136*8542734aSAndroid Build Coastguard Worker 
137*8542734aSAndroid Build Coastguard Worker struct XfrmSpInfo : XfrmCommonInfo {
138*8542734aSAndroid Build Coastguard Worker     // Address family in XfrmCommonInfo used for template/SA matching, need separate addrFamily
139*8542734aSAndroid Build Coastguard Worker     // for selectors
140*8542734aSAndroid Build Coastguard Worker     int selAddrFamily;  // AF_INET or AF_INET6
141*8542734aSAndroid Build Coastguard Worker     XfrmDirection direction;
142*8542734aSAndroid Build Coastguard Worker };
143*8542734aSAndroid Build Coastguard Worker 
144*8542734aSAndroid Build Coastguard Worker struct XfrmMigrateInfo : XfrmSpInfo {
145*8542734aSAndroid Build Coastguard Worker     XfrmEndpointPair newEndpointInfo;
146*8542734aSAndroid Build Coastguard Worker };
147*8542734aSAndroid Build Coastguard Worker 
148*8542734aSAndroid Build Coastguard Worker /*
149*8542734aSAndroid Build Coastguard Worker  * This is a workaround for a kernel bug in the 32bit netlink compat layer
150*8542734aSAndroid Build Coastguard Worker  * that has been present on x86_64 kernels since 2010 with no fix on the
151*8542734aSAndroid Build Coastguard Worker  * horizon.
152*8542734aSAndroid Build Coastguard Worker  *
153*8542734aSAndroid Build Coastguard Worker  * Below is a redefinition of the xfrm_usersa_info struct that is part
154*8542734aSAndroid Build Coastguard Worker  * of the Linux uapi <linux/xfrm.h> to align the structures to a 64-bit
155*8542734aSAndroid Build Coastguard Worker  * boundary.
156*8542734aSAndroid Build Coastguard Worker  *
157*8542734aSAndroid Build Coastguard Worker  * Note that we turn this on for all x86 32bit targets, under the assumption
158*8542734aSAndroid Build Coastguard Worker  * that nowadays all x86 targets are running 64bit kernels.
159*8542734aSAndroid Build Coastguard Worker  */
160*8542734aSAndroid Build Coastguard Worker #if defined(__i386__)
161*8542734aSAndroid Build Coastguard Worker // Shadow the kernel definition of xfrm_usersa_info with a 64-bit aligned version
162*8542734aSAndroid Build Coastguard Worker struct xfrm_usersa_info : ::xfrm_usersa_info {
163*8542734aSAndroid Build Coastguard Worker } __attribute__((aligned(8)));
164*8542734aSAndroid Build Coastguard Worker // Shadow the kernel's version, using the aligned version of xfrm_usersa_info
165*8542734aSAndroid Build Coastguard Worker struct xfrm_userspi_info {
166*8542734aSAndroid Build Coastguard Worker     struct xfrm_usersa_info info;
167*8542734aSAndroid Build Coastguard Worker     __u32 min;
168*8542734aSAndroid Build Coastguard Worker     __u32 max;
169*8542734aSAndroid Build Coastguard Worker };
170*8542734aSAndroid Build Coastguard Worker struct xfrm_userpolicy_info : ::xfrm_userpolicy_info {
171*8542734aSAndroid Build Coastguard Worker } __attribute__((aligned(8)));
172*8542734aSAndroid Build Coastguard Worker 
173*8542734aSAndroid Build Coastguard Worker /*
174*8542734aSAndroid Build Coastguard Worker  * Anyone who encounters a failure when sending netlink messages should look here
175*8542734aSAndroid Build Coastguard Worker  * first. Hitting the static_assert() below should be a strong hint that Android
176*8542734aSAndroid Build Coastguard Worker  * IPsec will probably not work with your current settings.
177*8542734aSAndroid Build Coastguard Worker  *
178*8542734aSAndroid Build Coastguard Worker  * Again, experimentally determined, the "flags" field should be the first byte in
179*8542734aSAndroid Build Coastguard Worker  * the final word of the xfrm_usersa_info struct. The check validates the size of
180*8542734aSAndroid Build Coastguard Worker  * the padding to be 7.
181*8542734aSAndroid Build Coastguard Worker  *
182*8542734aSAndroid Build Coastguard Worker  * This padding is verified to be correct on gcc/x86_64 kernel, and clang/x86 userspace.
183*8542734aSAndroid Build Coastguard Worker  */
184*8542734aSAndroid Build Coastguard Worker static_assert(sizeof(::xfrm_usersa_info) % 8 != 0,
185*8542734aSAndroid Build Coastguard Worker               "struct xfrm_usersa_info has changed "
186*8542734aSAndroid Build Coastguard Worker               "alignment. Please consider whether this "
187*8542734aSAndroid Build Coastguard Worker               "patch is needed.");
188*8542734aSAndroid Build Coastguard Worker static_assert(sizeof(xfrm_usersa_info) - offsetof(xfrm_usersa_info, flags) == 8,
189*8542734aSAndroid Build Coastguard Worker               "struct xfrm_usersa_info probably misaligned with kernel struct.");
190*8542734aSAndroid Build Coastguard Worker static_assert(sizeof(xfrm_usersa_info) % 8 == 0,
191*8542734aSAndroid Build Coastguard Worker               "struct xfrm_usersa_info_t is not 64-bit  "
192*8542734aSAndroid Build Coastguard Worker               "aligned. Please consider whether this patch "
193*8542734aSAndroid Build Coastguard Worker               "is needed.");
194*8542734aSAndroid Build Coastguard Worker static_assert(sizeof(::xfrm_userspi_info) - sizeof(::xfrm_usersa_info) ==
195*8542734aSAndroid Build Coastguard Worker                       sizeof(xfrm_userspi_info) - sizeof(xfrm_usersa_info),
196*8542734aSAndroid Build Coastguard Worker               "struct xfrm_userspi_info has changed and does not match the kernel struct.");
197*8542734aSAndroid Build Coastguard Worker static_assert(sizeof(::xfrm_userpolicy_info) % 8 != 0,
198*8542734aSAndroid Build Coastguard Worker               "struct xfrm_userpolicy_info has changed "
199*8542734aSAndroid Build Coastguard Worker               "alignment. Please consider whether this "
200*8542734aSAndroid Build Coastguard Worker               "patch is needed.");
201*8542734aSAndroid Build Coastguard Worker static_assert(sizeof(xfrm_userpolicy_info) - offsetof(xfrm_userpolicy_info, share) == 5,
202*8542734aSAndroid Build Coastguard Worker               "struct xfrm_userpolicy_info probably misaligned with kernel struct.");
203*8542734aSAndroid Build Coastguard Worker static_assert(sizeof(xfrm_userpolicy_info) % 8 == 0,
204*8542734aSAndroid Build Coastguard Worker               "struct xfrm_userpolicy_info is not 64-bit "
205*8542734aSAndroid Build Coastguard Worker               "aligned. Please consider whether this patch "
206*8542734aSAndroid Build Coastguard Worker               "is needed.");
207*8542734aSAndroid Build Coastguard Worker #endif
208*8542734aSAndroid Build Coastguard Worker 
209*8542734aSAndroid Build Coastguard Worker class XfrmController {
210*8542734aSAndroid Build Coastguard Worker public:
211*8542734aSAndroid Build Coastguard Worker     XfrmController();
212*8542734aSAndroid Build Coastguard Worker 
213*8542734aSAndroid Build Coastguard Worker     // Initializer to override XFRM-I support for unit-testing purposes
214*8542734aSAndroid Build Coastguard Worker     explicit XfrmController(bool xfrmIntfSupport);
215*8542734aSAndroid Build Coastguard Worker 
216*8542734aSAndroid Build Coastguard Worker     static netdutils::Status Init();
217*8542734aSAndroid Build Coastguard Worker 
218*8542734aSAndroid Build Coastguard Worker     static netdutils::Status ipSecSetEncapSocketOwner(int socketFd, int newUid, uid_t callerUid);
219*8542734aSAndroid Build Coastguard Worker 
220*8542734aSAndroid Build Coastguard Worker     static netdutils::Status ipSecAllocateSpi(int32_t transformId, const std::string& localAddress,
221*8542734aSAndroid Build Coastguard Worker                                               const std::string& remoteAddress, int32_t inSpi,
222*8542734aSAndroid Build Coastguard Worker                                               int32_t* outSpi);
223*8542734aSAndroid Build Coastguard Worker 
224*8542734aSAndroid Build Coastguard Worker     static netdutils::Status ipSecAddSecurityAssociation(
225*8542734aSAndroid Build Coastguard Worker             int32_t transformId, int32_t mode, const std::string& sourceAddress,
226*8542734aSAndroid Build Coastguard Worker             const std::string& destinationAddress, int32_t underlyingNetId, int32_t spi,
227*8542734aSAndroid Build Coastguard Worker             int32_t markValue, int32_t markMask, const std::string& authAlgo,
228*8542734aSAndroid Build Coastguard Worker             const std::vector<uint8_t>& authKey, int32_t authTruncBits,
229*8542734aSAndroid Build Coastguard Worker             const std::string& cryptAlgo, const std::vector<uint8_t>& cryptKey,
230*8542734aSAndroid Build Coastguard Worker             int32_t cryptTruncBits, const std::string& aeadAlgo,
231*8542734aSAndroid Build Coastguard Worker             const std::vector<uint8_t>& aeadKey, int32_t aeadIcvBits, int32_t encapType,
232*8542734aSAndroid Build Coastguard Worker             int32_t encapLocalPort, int32_t encapRemotePort, int32_t xfrmInterfaceId);
233*8542734aSAndroid Build Coastguard Worker 
234*8542734aSAndroid Build Coastguard Worker     static netdutils::Status ipSecDeleteSecurityAssociation(int32_t transformId,
235*8542734aSAndroid Build Coastguard Worker                                                             const std::string& sourceAddress,
236*8542734aSAndroid Build Coastguard Worker                                                             const std::string& destinationAddress,
237*8542734aSAndroid Build Coastguard Worker                                                             int32_t spi, int32_t markValue,
238*8542734aSAndroid Build Coastguard Worker                                                             int32_t markMask,
239*8542734aSAndroid Build Coastguard Worker                                                             int32_t xfrmInterfaceId);
240*8542734aSAndroid Build Coastguard Worker 
241*8542734aSAndroid Build Coastguard Worker     static netdutils::Status ipSecApplyTransportModeTransform(int socketFd, int32_t transformId,
242*8542734aSAndroid Build Coastguard Worker                                                               int32_t direction,
243*8542734aSAndroid Build Coastguard Worker                                                               const std::string& localAddress,
244*8542734aSAndroid Build Coastguard Worker                                                               const std::string& remoteAddress,
245*8542734aSAndroid Build Coastguard Worker                                                               int32_t spi);
246*8542734aSAndroid Build Coastguard Worker 
247*8542734aSAndroid Build Coastguard Worker     static netdutils::Status ipSecRemoveTransportModeTransform(int socketFd);
248*8542734aSAndroid Build Coastguard Worker 
249*8542734aSAndroid Build Coastguard Worker     static netdutils::Status ipSecAddSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
250*8542734aSAndroid Build Coastguard Worker                                                     int32_t direction,
251*8542734aSAndroid Build Coastguard Worker                                                     const std::string& tmplSrcAddress,
252*8542734aSAndroid Build Coastguard Worker                                                     const std::string& tmplDstAddress, int32_t spi,
253*8542734aSAndroid Build Coastguard Worker                                                     int32_t markValue, int32_t markMask,
254*8542734aSAndroid Build Coastguard Worker                                                     int32_t xfrmInterfaceId);
255*8542734aSAndroid Build Coastguard Worker 
256*8542734aSAndroid Build Coastguard Worker     static netdutils::Status ipSecUpdateSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
257*8542734aSAndroid Build Coastguard Worker                                                        int32_t direction,
258*8542734aSAndroid Build Coastguard Worker                                                        const std::string& tmplSrcAddress,
259*8542734aSAndroid Build Coastguard Worker                                                        const std::string& tmplDstAddress,
260*8542734aSAndroid Build Coastguard Worker                                                        int32_t spi, int32_t markValue,
261*8542734aSAndroid Build Coastguard Worker                                                        int32_t markMask, int32_t xfrmInterfaceId);
262*8542734aSAndroid Build Coastguard Worker 
263*8542734aSAndroid Build Coastguard Worker     static netdutils::Status ipSecDeleteSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
264*8542734aSAndroid Build Coastguard Worker                                                        int32_t direction, int32_t markValue,
265*8542734aSAndroid Build Coastguard Worker                                                        int32_t markMask, int32_t xfrmInterfaceId);
266*8542734aSAndroid Build Coastguard Worker 
267*8542734aSAndroid Build Coastguard Worker     static netdutils::Status ipSecAddTunnelInterface(const std::string& deviceName,
268*8542734aSAndroid Build Coastguard Worker                                                      const std::string& localAddress,
269*8542734aSAndroid Build Coastguard Worker                                                      const std::string& remoteAddress, int32_t ikey,
270*8542734aSAndroid Build Coastguard Worker                                                      int32_t okey, int32_t interfaceId,
271*8542734aSAndroid Build Coastguard Worker                                                      bool isUpdate);
272*8542734aSAndroid Build Coastguard Worker 
273*8542734aSAndroid Build Coastguard Worker     static netdutils::Status ipSecRemoveTunnelInterface(const std::string& deviceName);
274*8542734aSAndroid Build Coastguard Worker 
275*8542734aSAndroid Build Coastguard Worker     // Only available for Tunnel must already have a matching tunnel SA and policy
276*8542734aSAndroid Build Coastguard Worker     static netdutils::Status ipSecMigrate(int32_t transformId, int32_t selAddrFamily,
277*8542734aSAndroid Build Coastguard Worker                                           int32_t direction, const std::string& oldSourceAddress,
278*8542734aSAndroid Build Coastguard Worker                                           const std::string& oldDestinationAddress,
279*8542734aSAndroid Build Coastguard Worker                                           const std::string& newSourceAddress,
280*8542734aSAndroid Build Coastguard Worker                                           const std::string& newDestinationAddress,
281*8542734aSAndroid Build Coastguard Worker                                           int32_t xfrmInterfaceId);
282*8542734aSAndroid Build Coastguard Worker     void dump(netdutils::DumpWriter& dw);
283*8542734aSAndroid Build Coastguard Worker 
284*8542734aSAndroid Build Coastguard Worker     // Some XFRM netlink attributes comprise a header, a struct, and some data
285*8542734aSAndroid Build Coastguard Worker     // after the struct. We wrap all of those in one struct for easier
286*8542734aSAndroid Build Coastguard Worker     // marshalling. The structs below must be ABI compatible with the kernel and
287*8542734aSAndroid Build Coastguard Worker     // are composed from kernel structures; thus, they use the kernel naming
288*8542734aSAndroid Build Coastguard Worker     // convention.
289*8542734aSAndroid Build Coastguard Worker 
290*8542734aSAndroid Build Coastguard Worker     // Exposed for testing
291*8542734aSAndroid Build Coastguard Worker     static constexpr size_t MAX_KEY_LENGTH = 128;
292*8542734aSAndroid Build Coastguard Worker 
293*8542734aSAndroid Build Coastguard Worker     // Disable this warning since avoiding it makes the code unreadable.
294*8542734aSAndroid Build Coastguard Worker #pragma clang diagnostic push
295*8542734aSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wgnu-variable-sized-type-not-at-end"
296*8542734aSAndroid Build Coastguard Worker 
297*8542734aSAndroid Build Coastguard Worker     // Container for the content of an XFRMA_ALG_CRYPT netlink attribute.
298*8542734aSAndroid Build Coastguard Worker     // Exposed for testing
299*8542734aSAndroid Build Coastguard Worker     struct nlattr_algo_crypt {
300*8542734aSAndroid Build Coastguard Worker         nlattr hdr;
301*8542734aSAndroid Build Coastguard Worker         xfrm_algo crypt;
302*8542734aSAndroid Build Coastguard Worker         uint8_t key[MAX_KEY_LENGTH];
303*8542734aSAndroid Build Coastguard Worker     };
304*8542734aSAndroid Build Coastguard Worker 
305*8542734aSAndroid Build Coastguard Worker     // Container for the content of an XFRMA_ALG_AUTH_TRUNC netlink attribute.
306*8542734aSAndroid Build Coastguard Worker     // Exposed for testing
307*8542734aSAndroid Build Coastguard Worker     struct nlattr_algo_auth {
308*8542734aSAndroid Build Coastguard Worker         nlattr hdr;
309*8542734aSAndroid Build Coastguard Worker         xfrm_algo_auth auth;
310*8542734aSAndroid Build Coastguard Worker         uint8_t key[MAX_KEY_LENGTH];
311*8542734aSAndroid Build Coastguard Worker     };
312*8542734aSAndroid Build Coastguard Worker 
313*8542734aSAndroid Build Coastguard Worker     // Container for the content of an XFRMA_TMPL netlink attribute.
314*8542734aSAndroid Build Coastguard Worker     // Exposed for testing
315*8542734aSAndroid Build Coastguard Worker     struct nlattr_algo_aead {
316*8542734aSAndroid Build Coastguard Worker         nlattr hdr;
317*8542734aSAndroid Build Coastguard Worker         xfrm_algo_aead aead;
318*8542734aSAndroid Build Coastguard Worker         uint8_t key[MAX_KEY_LENGTH];
319*8542734aSAndroid Build Coastguard Worker     };
320*8542734aSAndroid Build Coastguard Worker 
321*8542734aSAndroid Build Coastguard Worker     // Container for the content of an XFRMA_REPLAY_ESN_VAL netlink attribute.
322*8542734aSAndroid Build Coastguard Worker     // Exposed for testing
323*8542734aSAndroid Build Coastguard Worker     struct nlattr_xfrm_replay_esn {
324*8542734aSAndroid Build Coastguard Worker         nlattr hdr;
325*8542734aSAndroid Build Coastguard Worker         xfrm_replay_state_esn replay_state;
326*8542734aSAndroid Build Coastguard Worker     };
327*8542734aSAndroid Build Coastguard Worker 
328*8542734aSAndroid Build Coastguard Worker #pragma clang diagnostic pop
329*8542734aSAndroid Build Coastguard Worker 
330*8542734aSAndroid Build Coastguard Worker     // Exposed for testing
331*8542734aSAndroid Build Coastguard Worker     struct nlattr_user_tmpl {
332*8542734aSAndroid Build Coastguard Worker         nlattr hdr;
333*8542734aSAndroid Build Coastguard Worker         xfrm_user_tmpl tmpl;
334*8542734aSAndroid Build Coastguard Worker     };
335*8542734aSAndroid Build Coastguard Worker 
336*8542734aSAndroid Build Coastguard Worker     // Container for the content of an XFRMA_ENCAP netlink attribute.
337*8542734aSAndroid Build Coastguard Worker     // Exposed for testing
338*8542734aSAndroid Build Coastguard Worker     struct nlattr_encap_tmpl {
339*8542734aSAndroid Build Coastguard Worker         nlattr hdr;
340*8542734aSAndroid Build Coastguard Worker         xfrm_encap_tmpl tmpl;
341*8542734aSAndroid Build Coastguard Worker     };
342*8542734aSAndroid Build Coastguard Worker 
343*8542734aSAndroid Build Coastguard Worker     // Container for the content of an XFRMA_MARK netlink attribute.
344*8542734aSAndroid Build Coastguard Worker     // Exposed for testing
345*8542734aSAndroid Build Coastguard Worker     struct nlattr_xfrm_mark {
346*8542734aSAndroid Build Coastguard Worker         nlattr hdr;
347*8542734aSAndroid Build Coastguard Worker         xfrm_mark mark;
348*8542734aSAndroid Build Coastguard Worker     };
349*8542734aSAndroid Build Coastguard Worker 
350*8542734aSAndroid Build Coastguard Worker     // Container for the content of an XFRMA_OUTPUT_MARK netlink attribute.
351*8542734aSAndroid Build Coastguard Worker     // Exposed for testing
352*8542734aSAndroid Build Coastguard Worker     struct nlattr_xfrm_output_mark {
353*8542734aSAndroid Build Coastguard Worker         nlattr hdr;
354*8542734aSAndroid Build Coastguard Worker         __u32 outputMark;
355*8542734aSAndroid Build Coastguard Worker     };
356*8542734aSAndroid Build Coastguard Worker 
357*8542734aSAndroid Build Coastguard Worker     // Container for the content of an XFRMA_IF_ID netlink attribute.
358*8542734aSAndroid Build Coastguard Worker     // Exposed for testing
359*8542734aSAndroid Build Coastguard Worker     struct nlattr_xfrm_interface_id {
360*8542734aSAndroid Build Coastguard Worker         nlattr hdr;
361*8542734aSAndroid Build Coastguard Worker         __u32 if_id;
362*8542734aSAndroid Build Coastguard Worker     };
363*8542734aSAndroid Build Coastguard Worker 
364*8542734aSAndroid Build Coastguard Worker     // Container for the content of an XFRMA_MIGRATE netlink attribute.
365*8542734aSAndroid Build Coastguard Worker     // Exposed for testing
366*8542734aSAndroid Build Coastguard Worker     struct nlattr_xfrm_user_migrate {
367*8542734aSAndroid Build Coastguard Worker         nlattr hdr;
368*8542734aSAndroid Build Coastguard Worker         xfrm_user_migrate migrate;
369*8542734aSAndroid Build Coastguard Worker     };
370*8542734aSAndroid Build Coastguard Worker 
371*8542734aSAndroid Build Coastguard Worker     // Exposed for testing
372*8542734aSAndroid Build Coastguard Worker     struct nlattr_payload_u32 {
373*8542734aSAndroid Build Coastguard Worker         nlattr hdr;
374*8542734aSAndroid Build Coastguard Worker         uint32_t value;
375*8542734aSAndroid Build Coastguard Worker     };
376*8542734aSAndroid Build Coastguard Worker 
377*8542734aSAndroid Build Coastguard Worker   private:
378*8542734aSAndroid Build Coastguard Worker     static bool isXfrmIntfSupported();
379*8542734aSAndroid Build Coastguard Worker 
380*8542734aSAndroid Build Coastguard Worker     static netdutils::Status fillXfrmEndpointPair(const std::string& sourceAddress,
381*8542734aSAndroid Build Coastguard Worker                                                   const std::string& destinationAddress,
382*8542734aSAndroid Build Coastguard Worker                                                   XfrmEndpointPair* info);
383*8542734aSAndroid Build Coastguard Worker     // helper functions for filling in the XfrmCommonInfo (and XfrmSaInfo) structure
384*8542734aSAndroid Build Coastguard Worker     static netdutils::Status fillXfrmCommonInfo(const std::string& sourceAddress,
385*8542734aSAndroid Build Coastguard Worker                                                 const std::string& destinationAddress, int32_t spi,
386*8542734aSAndroid Build Coastguard Worker                                                 int32_t markValue, int32_t markMask,
387*8542734aSAndroid Build Coastguard Worker                                                 int32_t transformId, int32_t xfrmInterfaceId,
388*8542734aSAndroid Build Coastguard Worker                                                 XfrmCommonInfo* info);
389*8542734aSAndroid Build Coastguard Worker     static netdutils::Status fillXfrmCommonInfo(int32_t spi, int32_t markValue, int32_t markMask,
390*8542734aSAndroid Build Coastguard Worker                                                 int32_t transformId, int32_t xfrmInterfaceId,
391*8542734aSAndroid Build Coastguard Worker                                                 XfrmCommonInfo* info);
392*8542734aSAndroid Build Coastguard Worker 
393*8542734aSAndroid Build Coastguard Worker     // Top level functions for managing a Transport Mode Transform
394*8542734aSAndroid Build Coastguard Worker     static netdutils::Status addTransportModeTransform(const XfrmSaInfo& record);
395*8542734aSAndroid Build Coastguard Worker     static int removeTransportModeTransform(const XfrmSaInfo& record);
396*8542734aSAndroid Build Coastguard Worker 
397*8542734aSAndroid Build Coastguard Worker     // TODO(messagerefactor): FACTOR OUT ALL MESSAGE BUILDING CODE BELOW HERE
398*8542734aSAndroid Build Coastguard Worker     // Shared between SA and SP
399*8542734aSAndroid Build Coastguard Worker     static void fillXfrmSelector(const int record, xfrm_selector* selector);
400*8542734aSAndroid Build Coastguard Worker 
401*8542734aSAndroid Build Coastguard Worker     // Shared between Transport and Tunnel Mode
402*8542734aSAndroid Build Coastguard Worker     static int fillNlAttrXfrmAlgoEnc(const XfrmAlgo& in_algo, nlattr_algo_crypt* algo);
403*8542734aSAndroid Build Coastguard Worker     static int fillNlAttrXfrmAlgoAuth(const XfrmAlgo& in_algo, nlattr_algo_auth* algo);
404*8542734aSAndroid Build Coastguard Worker     static int fillNlAttrXfrmAlgoAead(const XfrmAlgo& in_algo, nlattr_algo_aead* algo);
405*8542734aSAndroid Build Coastguard Worker     static int fillNlAttrXfrmEncapTmpl(const XfrmSaInfo& record, nlattr_encap_tmpl* tmpl);
406*8542734aSAndroid Build Coastguard Worker 
407*8542734aSAndroid Build Coastguard Worker     // Functions for updating a Transport Mode SA
408*8542734aSAndroid Build Coastguard Worker     static netdutils::Status updateSecurityAssociation(const XfrmSaInfo& record,
409*8542734aSAndroid Build Coastguard Worker                                                        const XfrmSocket& sock);
410*8542734aSAndroid Build Coastguard Worker     static int fillUserSaInfo(const XfrmSaInfo& record, xfrm_usersa_info* usersa);
411*8542734aSAndroid Build Coastguard Worker 
412*8542734aSAndroid Build Coastguard Worker     // Functions for deleting a Transport Mode SA
413*8542734aSAndroid Build Coastguard Worker     static netdutils::Status deleteSecurityAssociation(const XfrmCommonInfo& record,
414*8542734aSAndroid Build Coastguard Worker                                                        const XfrmSocket& sock);
415*8542734aSAndroid Build Coastguard Worker     static int fillUserSaId(const XfrmCommonInfo& record, xfrm_usersa_id* said);
416*8542734aSAndroid Build Coastguard Worker     static void fillUserTemplate(const XfrmSpInfo& record, xfrm_user_tmpl* tmpl);
417*8542734aSAndroid Build Coastguard Worker 
418*8542734aSAndroid Build Coastguard Worker     static int fillUserSpInfo(const XfrmSpInfo& record, xfrm_userpolicy_info* usersp);
419*8542734aSAndroid Build Coastguard Worker     static int fillNlAttrUserTemplate(const XfrmSpInfo& record, nlattr_user_tmpl* tmpl);
420*8542734aSAndroid Build Coastguard Worker     static int fillUserPolicyId(const XfrmSpInfo& record, xfrm_userpolicy_id* policy_id);
421*8542734aSAndroid Build Coastguard Worker     static int fillNlAttrXfrmMark(const XfrmCommonInfo& record, nlattr_xfrm_mark* mark);
422*8542734aSAndroid Build Coastguard Worker     static int fillNlAttrXfrmOutputMark(const XfrmSaInfo& record,
423*8542734aSAndroid Build Coastguard Worker                                         nlattr_xfrm_output_mark* output_mark);
424*8542734aSAndroid Build Coastguard Worker     static int fillNlAttrXfrmIntfId(const __u32 intf_id_value, nlattr_xfrm_interface_id* intf_id);
425*8542734aSAndroid Build Coastguard Worker     static int fillNlAttrXfrmReplayEsn(nlattr_xfrm_replay_esn* replay_esn);
426*8542734aSAndroid Build Coastguard Worker     static int fillNlAttrXfrmMigrate(const XfrmMigrateInfo& record,
427*8542734aSAndroid Build Coastguard Worker                                      nlattr_xfrm_user_migrate* migrate);
428*8542734aSAndroid Build Coastguard Worker 
429*8542734aSAndroid Build Coastguard Worker     static netdutils::Status allocateSpi(const XfrmSaInfo& record, uint32_t minSpi, uint32_t maxSpi,
430*8542734aSAndroid Build Coastguard Worker                                          uint32_t* outSpi, const XfrmSocket& sock);
431*8542734aSAndroid Build Coastguard Worker 
432*8542734aSAndroid Build Coastguard Worker     static netdutils::Status processSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
433*8542734aSAndroid Build Coastguard Worker                                                    int32_t direction,
434*8542734aSAndroid Build Coastguard Worker                                                    const std::string& tmplSrcAddress,
435*8542734aSAndroid Build Coastguard Worker                                                    const std::string& tmplDstAddress, int32_t spi,
436*8542734aSAndroid Build Coastguard Worker                                                    int32_t markValue, int32_t markMask,
437*8542734aSAndroid Build Coastguard Worker                                                    int32_t xfrmInterfaceId, int32_t msgType);
438*8542734aSAndroid Build Coastguard Worker     static netdutils::Status updateTunnelModeSecurityPolicy(const XfrmSpInfo& record,
439*8542734aSAndroid Build Coastguard Worker                                                             const XfrmSocket& sock,
440*8542734aSAndroid Build Coastguard Worker                                                             uint16_t msgType);
441*8542734aSAndroid Build Coastguard Worker     static netdutils::Status deleteTunnelModeSecurityPolicy(const XfrmSpInfo& record,
442*8542734aSAndroid Build Coastguard Worker                                                             const XfrmSocket& sock);
443*8542734aSAndroid Build Coastguard Worker     static netdutils::Status migrate(const XfrmMigrateInfo& record, const XfrmSocket& sock);
444*8542734aSAndroid Build Coastguard Worker     static netdutils::Status flushInterfaces();
445*8542734aSAndroid Build Coastguard Worker     static netdutils::Status flushSaDb(const XfrmSocket& s);
446*8542734aSAndroid Build Coastguard Worker     static netdutils::Status flushPolicyDb(const XfrmSocket& s);
447*8542734aSAndroid Build Coastguard Worker 
448*8542734aSAndroid Build Coastguard Worker     static netdutils::Status ipSecAddXfrmInterface(const std::string& deviceName,
449*8542734aSAndroid Build Coastguard Worker                                                    int32_t interfaceId, uint16_t flags);
450*8542734aSAndroid Build Coastguard Worker     static netdutils::Status ipSecAddVirtualTunnelInterface(const std::string& deviceName,
451*8542734aSAndroid Build Coastguard Worker                                                             const std::string& localAddress,
452*8542734aSAndroid Build Coastguard Worker                                                             const std::string& remoteAddress,
453*8542734aSAndroid Build Coastguard Worker                                                             int32_t ikey, int32_t okey,
454*8542734aSAndroid Build Coastguard Worker                                                             uint16_t flags);
455*8542734aSAndroid Build Coastguard Worker     // END TODO(messagerefactor)
456*8542734aSAndroid Build Coastguard Worker };
457*8542734aSAndroid Build Coastguard Worker 
458*8542734aSAndroid Build Coastguard Worker } // namespace net
459*8542734aSAndroid Build Coastguard Worker } // namespace android
460*8542734aSAndroid Build Coastguard Worker 
461*8542734aSAndroid Build Coastguard Worker #endif /* !defined(XFRM_CONTROLLER_H) */
462