xref: /aosp_15_r20/external/libnl/lib/xfrm/ae.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker  * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
4*4dc78e53SAndroid Build Coastguard Worker  *
5*4dc78e53SAndroid Build Coastguard Worker  *
6*4dc78e53SAndroid Build Coastguard Worker  *  Redistribution and use in source and binary forms, with or without
7*4dc78e53SAndroid Build Coastguard Worker  *  modification, are permitted provided that the following conditions
8*4dc78e53SAndroid Build Coastguard Worker  *  are met:
9*4dc78e53SAndroid Build Coastguard Worker  *
10*4dc78e53SAndroid Build Coastguard Worker  *    Redistributions of source code must retain the above copyright
11*4dc78e53SAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
12*4dc78e53SAndroid Build Coastguard Worker  *
13*4dc78e53SAndroid Build Coastguard Worker  *    Redistributions in binary form must reproduce the above copyright
14*4dc78e53SAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
15*4dc78e53SAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the
16*4dc78e53SAndroid Build Coastguard Worker  *    distribution.
17*4dc78e53SAndroid Build Coastguard Worker  *
18*4dc78e53SAndroid Build Coastguard Worker  *    Neither the name of Texas Instruments Incorporated nor the names of
19*4dc78e53SAndroid Build Coastguard Worker  *    its contributors may be used to endorse or promote products derived
20*4dc78e53SAndroid Build Coastguard Worker  *    from this software without specific prior written permission.
21*4dc78e53SAndroid Build Coastguard Worker  *
22*4dc78e53SAndroid Build Coastguard Worker  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23*4dc78e53SAndroid Build Coastguard Worker  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24*4dc78e53SAndroid Build Coastguard Worker  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25*4dc78e53SAndroid Build Coastguard Worker  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26*4dc78e53SAndroid Build Coastguard Worker  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27*4dc78e53SAndroid Build Coastguard Worker  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28*4dc78e53SAndroid Build Coastguard Worker  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29*4dc78e53SAndroid Build Coastguard Worker  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30*4dc78e53SAndroid Build Coastguard Worker  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31*4dc78e53SAndroid Build Coastguard Worker  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32*4dc78e53SAndroid Build Coastguard Worker  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*4dc78e53SAndroid Build Coastguard Worker  *
34*4dc78e53SAndroid Build Coastguard Worker  */
35*4dc78e53SAndroid Build Coastguard Worker 
36*4dc78e53SAndroid Build Coastguard Worker /**
37*4dc78e53SAndroid Build Coastguard Worker  * @ingroup xfrmnl
38*4dc78e53SAndroid Build Coastguard Worker  * @defgroup ae Attribute Element
39*4dc78e53SAndroid Build Coastguard Worker  * @brief
40*4dc78e53SAndroid Build Coastguard Worker  *
41*4dc78e53SAndroid Build Coastguard Worker  * The AE interface allows a user to retrieve and update various
42*4dc78e53SAndroid Build Coastguard Worker  * Security Association (SA) attributes such as lifetime, replay state etc.
43*4dc78e53SAndroid Build Coastguard Worker  *
44*4dc78e53SAndroid Build Coastguard Worker  * @par AE Flags
45*4dc78e53SAndroid Build Coastguard Worker  * @code
46*4dc78e53SAndroid Build Coastguard Worker  * XFRM_AE_UNSPEC
47*4dc78e53SAndroid Build Coastguard Worker  * XFRM_AE_RTHR=1
48*4dc78e53SAndroid Build Coastguard Worker  * XFRM_AE_RVAL=2
49*4dc78e53SAndroid Build Coastguard Worker  * XFRM_AE_LVAL=4
50*4dc78e53SAndroid Build Coastguard Worker  * XFRM_AE_ETHR=8
51*4dc78e53SAndroid Build Coastguard Worker  * XFRM_AE_CR=16
52*4dc78e53SAndroid Build Coastguard Worker  * XFRM_AE_CE=32
53*4dc78e53SAndroid Build Coastguard Worker  * XFRM_AE_CU=64
54*4dc78e53SAndroid Build Coastguard Worker  * @endcode
55*4dc78e53SAndroid Build Coastguard Worker  *
56*4dc78e53SAndroid Build Coastguard Worker  * @par AE Identification
57*4dc78e53SAndroid Build Coastguard Worker  * An AE is uniquely identified by the attributes listed below, whenever
58*4dc78e53SAndroid Build Coastguard Worker  * you refer to an existing AE all of the attributes must be set. There is
59*4dc78e53SAndroid Build Coastguard Worker  * no cache support for AE since you can retrieve the AE for any given combination
60*4dc78e53SAndroid Build Coastguard Worker  * of attributes mentioned below, but not all at once since they just characterize
61*4dc78e53SAndroid Build Coastguard Worker  * an SA.
62*4dc78e53SAndroid Build Coastguard Worker  *   - destination address (xfrmnl_ae_set_daddr())
63*4dc78e53SAndroid Build Coastguard Worker  *   - SPI (xfrmnl_ae_set_spi)
64*4dc78e53SAndroid Build Coastguard Worker  *   - protocol (xfrmnl_ae_set_proto)
65*4dc78e53SAndroid Build Coastguard Worker  *   - mark (xfrmnl_ae_set_mark)
66*4dc78e53SAndroid Build Coastguard Worker  *
67*4dc78e53SAndroid Build Coastguard Worker  * @par Changeable Attributes
68*4dc78e53SAndroid Build Coastguard Worker  * \anchor ae_changeable
69*4dc78e53SAndroid Build Coastguard Worker  *  - current lifetime (xfrmnl_ae_set_curlifetime())
70*4dc78e53SAndroid Build Coastguard Worker  *  - replay properties (xfrmnl_ae_set_replay_maxage(), xfrmnl_ae_set_replay_maxdiff())
71*4dc78e53SAndroid Build Coastguard Worker  *  - replay state (xfrmnl_ae_set_replay_state(), xfrmnl_ae_set_replay_state_esn))
72*4dc78e53SAndroid Build Coastguard Worker  *
73*4dc78e53SAndroid Build Coastguard Worker  * @par Required Caches for Dumping
74*4dc78e53SAndroid Build Coastguard Worker  * None
75*4dc78e53SAndroid Build Coastguard Worker  *
76*4dc78e53SAndroid Build Coastguard Worker  * @par TODO
77*4dc78e53SAndroid Build Coastguard Worker  * None
78*4dc78e53SAndroid Build Coastguard Worker  *
79*4dc78e53SAndroid Build Coastguard Worker  * @par 1) Retrieving AE information for a given SA tuple
80*4dc78e53SAndroid Build Coastguard Worker  * @code
81*4dc78e53SAndroid Build Coastguard Worker  * // Create a netlink socket and connect it to XFRM subsystem in
82*4dc78e53SAndroid Build Coastguard Worker  * the kernel to be able to send/receive info from userspace.
83*4dc78e53SAndroid Build Coastguard Worker  * struct nl_sock* sk = nl_socket_alloc ();
84*4dc78e53SAndroid Build Coastguard Worker  * nl_connect (sk, NETLINK_XFRM);
85*4dc78e53SAndroid Build Coastguard Worker  *
86*4dc78e53SAndroid Build Coastguard Worker  * // AEs can then be looked up by the SA tuple, destination address,
87*4dc78e53SAndroid Build Coastguard Worker  * SPI, protocol, mark:
88*4dc78e53SAndroid Build Coastguard Worker  * struct xfrmnl_ae *ae;
89*4dc78e53SAndroid Build Coastguard Worker  * xfrmnl_ae_get_kernel(sk, dst_addr, spi, proto,mark_mask, mark_value, &ae);
90*4dc78e53SAndroid Build Coastguard Worker  *
91*4dc78e53SAndroid Build Coastguard Worker  * // After successful usage, the object must be freed
92*4dc78e53SAndroid Build Coastguard Worker  * xfrmnl_ae_put(ae);
93*4dc78e53SAndroid Build Coastguard Worker  * @endcode
94*4dc78e53SAndroid Build Coastguard Worker  *
95*4dc78e53SAndroid Build Coastguard Worker  * @par 2) Updating AE
96*4dc78e53SAndroid Build Coastguard Worker  * @code
97*4dc78e53SAndroid Build Coastguard Worker  * // Allocate an empty AE handle to be filled out with the attributes
98*4dc78e53SAndroid Build Coastguard Worker  * // of the new AE.
99*4dc78e53SAndroid Build Coastguard Worker  * struct xfrmnl_ae *ae = xfrmnl_ae_alloc();
100*4dc78e53SAndroid Build Coastguard Worker  *
101*4dc78e53SAndroid Build Coastguard Worker  * // Fill out the attributes of the new AE
102*4dc78e53SAndroid Build Coastguard Worker  * xfrmnl_ae_set_daddr(ae, dst_addr);
103*4dc78e53SAndroid Build Coastguard Worker  * xfrmnl_ae_set_spi(ae, 0xDEADBEEF);
104*4dc78e53SAndroid Build Coastguard Worker  * xfrmnl_ae_set_proto(ae, 50);
105*4dc78e53SAndroid Build Coastguard Worker  * xfrmnl_ae_set_mark(ae, 0x0);
106*4dc78e53SAndroid Build Coastguard Worker  * xfrmnl_ae_set_saddr(ae, src_addr);
107*4dc78e53SAndroid Build Coastguard Worker  * xfrmnl_ae_set_curlifetime(ae, 540, 10, 0xAABB1122, 0x0);
108*4dc78e53SAndroid Build Coastguard Worker  *
109*4dc78e53SAndroid Build Coastguard Worker  * // Build the netlink message and send it to the kernel, the operation will
110*4dc78e53SAndroid Build Coastguard Worker  * // block until the operation has been completed. Alternatively, a netlink message
111*4dc78e53SAndroid Build Coastguard Worker  * // can be built using xfrmnl_ae_build_get_request () API and be sent using
112*4dc78e53SAndroid Build Coastguard Worker  * // nl_send_auto(). Further the result from the kernel can be parsed using
113*4dc78e53SAndroid Build Coastguard Worker  * // xfrmnl_ae_parse() API.
114*4dc78e53SAndroid Build Coastguard Worker  * xfrmnl_ae_set(sk, ae, NLM_F_REPLACE);
115*4dc78e53SAndroid Build Coastguard Worker  *
116*4dc78e53SAndroid Build Coastguard Worker  * // Free the memory
117*4dc78e53SAndroid Build Coastguard Worker  * xfrmnl_ae_put(ae);
118*4dc78e53SAndroid Build Coastguard Worker  * @endcode
119*4dc78e53SAndroid Build Coastguard Worker  *
120*4dc78e53SAndroid Build Coastguard Worker  * @{
121*4dc78e53SAndroid Build Coastguard Worker  */
122*4dc78e53SAndroid Build Coastguard Worker 
123*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
124*4dc78e53SAndroid Build Coastguard Worker 
125*4dc78e53SAndroid Build Coastguard Worker #include <time.h>
126*4dc78e53SAndroid Build Coastguard Worker #include <linux/xfrm.h>
127*4dc78e53SAndroid Build Coastguard Worker 
128*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
129*4dc78e53SAndroid Build Coastguard Worker #include <netlink/cache.h>
130*4dc78e53SAndroid Build Coastguard Worker #include <netlink/object.h>
131*4dc78e53SAndroid Build Coastguard Worker #include <netlink/xfrm/ae.h>
132*4dc78e53SAndroid Build Coastguard Worker 
133*4dc78e53SAndroid Build Coastguard Worker #include "nl-xfrm.h"
134*4dc78e53SAndroid Build Coastguard Worker #include "nl-priv-dynamic-core/object-api.h"
135*4dc78e53SAndroid Build Coastguard Worker #include "nl-priv-dynamic-core/nl-core.h"
136*4dc78e53SAndroid Build Coastguard Worker #include "nl-priv-dynamic-core/cache-api.h"
137*4dc78e53SAndroid Build Coastguard Worker #include "nl-aux-core/nl-core.h"
138*4dc78e53SAndroid Build Coastguard Worker #include "nl-aux-xfrm/nl-xfrm.h"
139*4dc78e53SAndroid Build Coastguard Worker 
140*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
141*4dc78e53SAndroid Build Coastguard Worker 
142*4dc78e53SAndroid Build Coastguard Worker struct xfrmnl_sa_id {
143*4dc78e53SAndroid Build Coastguard Worker 	struct nl_addr* daddr;
144*4dc78e53SAndroid Build Coastguard Worker 	uint32_t        spi;
145*4dc78e53SAndroid Build Coastguard Worker 	uint16_t        family;
146*4dc78e53SAndroid Build Coastguard Worker 	uint8_t         proto;
147*4dc78e53SAndroid Build Coastguard Worker };
148*4dc78e53SAndroid Build Coastguard Worker 
149*4dc78e53SAndroid Build Coastguard Worker struct xfrmnl_ae {
150*4dc78e53SAndroid Build Coastguard Worker 	NLHDR_COMMON
151*4dc78e53SAndroid Build Coastguard Worker 
152*4dc78e53SAndroid Build Coastguard Worker 	struct xfrmnl_sa_id             sa_id;
153*4dc78e53SAndroid Build Coastguard Worker 	struct nl_addr*                 saddr;
154*4dc78e53SAndroid Build Coastguard Worker 	uint32_t                        flags;
155*4dc78e53SAndroid Build Coastguard Worker 	uint32_t                        reqid;
156*4dc78e53SAndroid Build Coastguard Worker 	struct xfrmnl_mark              mark;
157*4dc78e53SAndroid Build Coastguard Worker 	struct xfrmnl_lifetime_cur      lifetime_cur;
158*4dc78e53SAndroid Build Coastguard Worker 	uint32_t                        replay_maxage;
159*4dc78e53SAndroid Build Coastguard Worker 	uint32_t                        replay_maxdiff;
160*4dc78e53SAndroid Build Coastguard Worker 	struct xfrmnl_replay_state      replay_state;
161*4dc78e53SAndroid Build Coastguard Worker 	struct xfrmnl_replay_state_esn* replay_state_esn;
162*4dc78e53SAndroid Build Coastguard Worker };
163*4dc78e53SAndroid Build Coastguard Worker 
164*4dc78e53SAndroid Build Coastguard Worker #define XFRM_AE_ATTR_DADDR          0x01
165*4dc78e53SAndroid Build Coastguard Worker #define XFRM_AE_ATTR_SPI            0x02
166*4dc78e53SAndroid Build Coastguard Worker #define XFRM_AE_ATTR_PROTO          0x04
167*4dc78e53SAndroid Build Coastguard Worker #define XFRM_AE_ATTR_SADDR          0x08
168*4dc78e53SAndroid Build Coastguard Worker #define XFRM_AE_ATTR_FLAGS          0x10
169*4dc78e53SAndroid Build Coastguard Worker #define XFRM_AE_ATTR_REQID          0x20
170*4dc78e53SAndroid Build Coastguard Worker #define XFRM_AE_ATTR_MARK           0x40
171*4dc78e53SAndroid Build Coastguard Worker #define XFRM_AE_ATTR_LIFETIME       0x80
172*4dc78e53SAndroid Build Coastguard Worker #define XFRM_AE_ATTR_REPLAY_MAXAGE  0x100
173*4dc78e53SAndroid Build Coastguard Worker #define XFRM_AE_ATTR_REPLAY_MAXDIFF 0x200
174*4dc78e53SAndroid Build Coastguard Worker #define XFRM_AE_ATTR_REPLAY_STATE   0x400
175*4dc78e53SAndroid Build Coastguard Worker #define XFRM_AE_ATTR_FAMILY         0x800
176*4dc78e53SAndroid Build Coastguard Worker 
177*4dc78e53SAndroid Build Coastguard Worker static struct nl_object_ops xfrm_ae_obj_ops;
178*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
179*4dc78e53SAndroid Build Coastguard Worker 
180*4dc78e53SAndroid Build Coastguard Worker 
xfrm_ae_free_data(struct nl_object * c)181*4dc78e53SAndroid Build Coastguard Worker static void xfrm_ae_free_data(struct nl_object *c)
182*4dc78e53SAndroid Build Coastguard Worker {
183*4dc78e53SAndroid Build Coastguard Worker 	struct xfrmnl_ae* ae =   nl_object_priv (c);
184*4dc78e53SAndroid Build Coastguard Worker 
185*4dc78e53SAndroid Build Coastguard Worker 	if (ae == NULL)
186*4dc78e53SAndroid Build Coastguard Worker 		return;
187*4dc78e53SAndroid Build Coastguard Worker 
188*4dc78e53SAndroid Build Coastguard Worker 	nl_addr_put (ae->sa_id.daddr);
189*4dc78e53SAndroid Build Coastguard Worker 	nl_addr_put (ae->saddr);
190*4dc78e53SAndroid Build Coastguard Worker 
191*4dc78e53SAndroid Build Coastguard Worker 	if (ae->replay_state_esn)
192*4dc78e53SAndroid Build Coastguard Worker 		free (ae->replay_state_esn);
193*4dc78e53SAndroid Build Coastguard Worker }
194*4dc78e53SAndroid Build Coastguard Worker 
xfrm_ae_clone(struct nl_object * _dst,struct nl_object * _src)195*4dc78e53SAndroid Build Coastguard Worker static int xfrm_ae_clone(struct nl_object *_dst, struct nl_object *_src)
196*4dc78e53SAndroid Build Coastguard Worker {
197*4dc78e53SAndroid Build Coastguard Worker 	struct xfrmnl_ae* dst = nl_object_priv(_dst);
198*4dc78e53SAndroid Build Coastguard Worker 	struct xfrmnl_ae* src = nl_object_priv(_src);
199*4dc78e53SAndroid Build Coastguard Worker 
200*4dc78e53SAndroid Build Coastguard Worker 	dst->sa_id.daddr = NULL;
201*4dc78e53SAndroid Build Coastguard Worker 	dst->saddr = NULL;
202*4dc78e53SAndroid Build Coastguard Worker 	dst->replay_state_esn = NULL;
203*4dc78e53SAndroid Build Coastguard Worker 
204*4dc78e53SAndroid Build Coastguard Worker 	if (src->sa_id.daddr) {
205*4dc78e53SAndroid Build Coastguard Worker 		if ((dst->sa_id.daddr = nl_addr_clone (src->sa_id.daddr)) == NULL)
206*4dc78e53SAndroid Build Coastguard Worker 			return -NLE_NOMEM;
207*4dc78e53SAndroid Build Coastguard Worker 	}
208*4dc78e53SAndroid Build Coastguard Worker 
209*4dc78e53SAndroid Build Coastguard Worker 	if (src->saddr) {
210*4dc78e53SAndroid Build Coastguard Worker 		if ((dst->saddr = nl_addr_clone (src->saddr)) == NULL)
211*4dc78e53SAndroid Build Coastguard Worker 			return -NLE_NOMEM;
212*4dc78e53SAndroid Build Coastguard Worker 	}
213*4dc78e53SAndroid Build Coastguard Worker 
214*4dc78e53SAndroid Build Coastguard Worker 	if (src->replay_state_esn) {
215*4dc78e53SAndroid Build Coastguard Worker 		uint32_t len = sizeof (struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * src->replay_state_esn->bmp_len);
216*4dc78e53SAndroid Build Coastguard Worker 
217*4dc78e53SAndroid Build Coastguard Worker 		if ((dst->replay_state_esn = malloc (len)) == NULL)
218*4dc78e53SAndroid Build Coastguard Worker 			return -NLE_NOMEM;
219*4dc78e53SAndroid Build Coastguard Worker 		memcpy (dst->replay_state_esn, src->replay_state_esn, len);
220*4dc78e53SAndroid Build Coastguard Worker 	}
221*4dc78e53SAndroid Build Coastguard Worker 
222*4dc78e53SAndroid Build Coastguard Worker 	return 0;
223*4dc78e53SAndroid Build Coastguard Worker }
224*4dc78e53SAndroid Build Coastguard Worker 
xfrm_ae_compare(struct nl_object * _a,struct nl_object * _b,uint64_t attrs,int flags)225*4dc78e53SAndroid Build Coastguard Worker static uint64_t xfrm_ae_compare(struct nl_object *_a, struct nl_object *_b,
226*4dc78e53SAndroid Build Coastguard Worker 				uint64_t attrs, int flags)
227*4dc78e53SAndroid Build Coastguard Worker {
228*4dc78e53SAndroid Build Coastguard Worker 	struct xfrmnl_ae* a  =   (struct xfrmnl_ae *) _a;
229*4dc78e53SAndroid Build Coastguard Worker 	struct xfrmnl_ae* b  =   (struct xfrmnl_ae *) _b;
230*4dc78e53SAndroid Build Coastguard Worker 	uint64_t diff = 0;
231*4dc78e53SAndroid Build Coastguard Worker 	int found = 0;
232*4dc78e53SAndroid Build Coastguard Worker 
233*4dc78e53SAndroid Build Coastguard Worker #define _DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ATTR, a, b, EXPR)
234*4dc78e53SAndroid Build Coastguard Worker 	diff |= _DIFF(XFRM_AE_ATTR_DADDR,
235*4dc78e53SAndroid Build Coastguard Worker 		      nl_addr_cmp(a->sa_id.daddr, b->sa_id.daddr));
236*4dc78e53SAndroid Build Coastguard Worker 	diff |= _DIFF(XFRM_AE_ATTR_SPI, a->sa_id.spi != b->sa_id.spi);
237*4dc78e53SAndroid Build Coastguard Worker 	diff |= _DIFF(XFRM_AE_ATTR_PROTO, a->sa_id.proto != b->sa_id.proto);
238*4dc78e53SAndroid Build Coastguard Worker 	diff |= _DIFF(XFRM_AE_ATTR_SADDR, nl_addr_cmp(a->saddr, b->saddr));
239*4dc78e53SAndroid Build Coastguard Worker 	diff |= _DIFF(XFRM_AE_ATTR_FLAGS, a->flags != b->flags);
240*4dc78e53SAndroid Build Coastguard Worker 	diff |= _DIFF(XFRM_AE_ATTR_REQID, a->reqid != b->reqid);
241*4dc78e53SAndroid Build Coastguard Worker 	diff |= _DIFF(XFRM_AE_ATTR_MARK,
242*4dc78e53SAndroid Build Coastguard Worker 		      (a->mark.v & a->mark.m) != (b->mark.v & b->mark.m));
243*4dc78e53SAndroid Build Coastguard Worker 	diff |= _DIFF(XFRM_AE_ATTR_REPLAY_MAXAGE,
244*4dc78e53SAndroid Build Coastguard Worker 		      a->replay_maxage != b->replay_maxage);
245*4dc78e53SAndroid Build Coastguard Worker 	diff |= _DIFF(XFRM_AE_ATTR_REPLAY_MAXDIFF,
246*4dc78e53SAndroid Build Coastguard Worker 		      a->replay_maxdiff != b->replay_maxdiff);
247*4dc78e53SAndroid Build Coastguard Worker 
248*4dc78e53SAndroid Build Coastguard Worker 	/* Compare replay states */
249*4dc78e53SAndroid Build Coastguard Worker 	found = AVAILABLE_MISMATCH (a, b, XFRM_AE_ATTR_REPLAY_STATE);
250*4dc78e53SAndroid Build Coastguard Worker 	if (found == 0) // attribute exists in both objects
251*4dc78e53SAndroid Build Coastguard Worker 	{
252*4dc78e53SAndroid Build Coastguard Worker 		if (((a->replay_state_esn != NULL) && (b->replay_state_esn == NULL)) ||
253*4dc78e53SAndroid Build Coastguard Worker 			((a->replay_state_esn == NULL) && (b->replay_state_esn != NULL)))
254*4dc78e53SAndroid Build Coastguard Worker 			found |= 1;
255*4dc78e53SAndroid Build Coastguard Worker 
256*4dc78e53SAndroid Build Coastguard Worker 		if (found == 0) // same replay type. compare actual values
257*4dc78e53SAndroid Build Coastguard Worker 		{
258*4dc78e53SAndroid Build Coastguard Worker 			if (a->replay_state_esn)
259*4dc78e53SAndroid Build Coastguard Worker 			{
260*4dc78e53SAndroid Build Coastguard Worker 				if (a->replay_state_esn->bmp_len != b->replay_state_esn->bmp_len)
261*4dc78e53SAndroid Build Coastguard Worker 					diff |= 1;
262*4dc78e53SAndroid Build Coastguard Worker 				else
263*4dc78e53SAndroid Build Coastguard Worker 				{
264*4dc78e53SAndroid Build Coastguard Worker 					uint32_t len = sizeof (struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * a->replay_state_esn->bmp_len);
265*4dc78e53SAndroid Build Coastguard Worker 					diff |= memcmp (a->replay_state_esn, b->replay_state_esn, len);
266*4dc78e53SAndroid Build Coastguard Worker 				}
267*4dc78e53SAndroid Build Coastguard Worker 			}
268*4dc78e53SAndroid Build Coastguard Worker 			else
269*4dc78e53SAndroid Build Coastguard Worker 			{
270*4dc78e53SAndroid Build Coastguard Worker 				if ((a->replay_state.oseq != b->replay_state.oseq) ||
271*4dc78e53SAndroid Build Coastguard Worker 				    (a->replay_state.seq != b->replay_state.seq) ||
272*4dc78e53SAndroid Build Coastguard Worker 				    (a->replay_state.bitmap != b->replay_state.bitmap))
273*4dc78e53SAndroid Build Coastguard Worker 					diff |= 1;
274*4dc78e53SAndroid Build Coastguard Worker 			}
275*4dc78e53SAndroid Build Coastguard Worker 		}
276*4dc78e53SAndroid Build Coastguard Worker 	}
277*4dc78e53SAndroid Build Coastguard Worker #undef _DIFF
278*4dc78e53SAndroid Build Coastguard Worker 
279*4dc78e53SAndroid Build Coastguard Worker 	return diff;
280*4dc78e53SAndroid Build Coastguard Worker }
281*4dc78e53SAndroid Build Coastguard Worker 
282*4dc78e53SAndroid Build Coastguard Worker /**
283*4dc78e53SAndroid Build Coastguard Worker  * @name XFRM AE Attribute Translations
284*4dc78e53SAndroid Build Coastguard Worker  * @{
285*4dc78e53SAndroid Build Coastguard Worker  */
286*4dc78e53SAndroid Build Coastguard Worker static const struct trans_tbl ae_attrs[] =
287*4dc78e53SAndroid Build Coastguard Worker {
288*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_ATTR_DADDR, daddr),
289*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_ATTR_SPI, spi),
290*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_ATTR_PROTO, protocol),
291*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_ATTR_SADDR, saddr),
292*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_ATTR_FLAGS, flags),
293*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_ATTR_REQID, reqid),
294*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_ATTR_MARK, mark),
295*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_ATTR_LIFETIME, cur_lifetime),
296*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_ATTR_REPLAY_MAXAGE, replay_maxage),
297*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_ATTR_REPLAY_MAXDIFF, replay_maxdiff),
298*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_ATTR_REPLAY_STATE, replay_state),
299*4dc78e53SAndroid Build Coastguard Worker };
300*4dc78e53SAndroid Build Coastguard Worker 
xfrm_ae_attrs2str(int attrs,char * buf,size_t len)301*4dc78e53SAndroid Build Coastguard Worker static char* xfrm_ae_attrs2str (int attrs, char *buf, size_t len)
302*4dc78e53SAndroid Build Coastguard Worker {
303*4dc78e53SAndroid Build Coastguard Worker 	return __flags2str(attrs, buf, len, ae_attrs, ARRAY_SIZE(ae_attrs));
304*4dc78e53SAndroid Build Coastguard Worker }
305*4dc78e53SAndroid Build Coastguard Worker /** @} */
306*4dc78e53SAndroid Build Coastguard Worker 
307*4dc78e53SAndroid Build Coastguard Worker /**
308*4dc78e53SAndroid Build Coastguard Worker  * @name XFRM AE Flags Translations
309*4dc78e53SAndroid Build Coastguard Worker  * @{
310*4dc78e53SAndroid Build Coastguard Worker  */
311*4dc78e53SAndroid Build Coastguard Worker 
312*4dc78e53SAndroid Build Coastguard Worker static const struct trans_tbl ae_flags[] = {
313*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_UNSPEC, unspecified),
314*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_RTHR, replay threshold),
315*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_RVAL, replay value),
316*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_LVAL, lifetime value),
317*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_ETHR, expiry time threshold),
318*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_CR, replay update event),
319*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_CE, timer expiry event),
320*4dc78e53SAndroid Build Coastguard Worker 	__ADD(XFRM_AE_CU, policy update event),
321*4dc78e53SAndroid Build Coastguard Worker };
322*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_flags2str(int flags,char * buf,size_t len)323*4dc78e53SAndroid Build Coastguard Worker char* xfrmnl_ae_flags2str(int flags, char *buf, size_t len)
324*4dc78e53SAndroid Build Coastguard Worker {
325*4dc78e53SAndroid Build Coastguard Worker 	return __flags2str (flags, buf, len, ae_flags, ARRAY_SIZE(ae_flags));
326*4dc78e53SAndroid Build Coastguard Worker }
327*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_str2flag(const char * name)328*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_str2flag(const char *name)
329*4dc78e53SAndroid Build Coastguard Worker {
330*4dc78e53SAndroid Build Coastguard Worker 	return __str2flags(name, ae_flags, ARRAY_SIZE(ae_flags));
331*4dc78e53SAndroid Build Coastguard Worker }
332*4dc78e53SAndroid Build Coastguard Worker /** @} */
333*4dc78e53SAndroid Build Coastguard Worker 
xfrm_ae_dump_line(struct nl_object * a,struct nl_dump_params * p)334*4dc78e53SAndroid Build Coastguard Worker static void xfrm_ae_dump_line(struct nl_object *a, struct nl_dump_params *p)
335*4dc78e53SAndroid Build Coastguard Worker {
336*4dc78e53SAndroid Build Coastguard Worker 	char                dst[INET6_ADDRSTRLEN+5], src[INET6_ADDRSTRLEN+5];
337*4dc78e53SAndroid Build Coastguard Worker 	struct xfrmnl_ae*   ae  =   (struct xfrmnl_ae *) a;
338*4dc78e53SAndroid Build Coastguard Worker 	char                flags[128], buf[128];
339*4dc78e53SAndroid Build Coastguard Worker 	time_t              add_time, use_time;
340*4dc78e53SAndroid Build Coastguard Worker 	struct tm           *add_time_tm, *use_time_tm;
341*4dc78e53SAndroid Build Coastguard Worker 	struct tm           tm_buf;
342*4dc78e53SAndroid Build Coastguard Worker 
343*4dc78e53SAndroid Build Coastguard Worker 	nl_dump_line(p, "src %s dst %s \n", nl_addr2str(ae->saddr, src, sizeof(src)),
344*4dc78e53SAndroid Build Coastguard Worker 				nl_addr2str(ae->sa_id.daddr, dst, sizeof(dst)));
345*4dc78e53SAndroid Build Coastguard Worker 
346*4dc78e53SAndroid Build Coastguard Worker 	nl_dump_line(p, "\tproto %s spi 0x%x reqid %u ",
347*4dc78e53SAndroid Build Coastguard Worker 				nl_ip_proto2str (ae->sa_id.proto, buf, sizeof (buf)),
348*4dc78e53SAndroid Build Coastguard Worker 				ae->sa_id.spi, ae->reqid);
349*4dc78e53SAndroid Build Coastguard Worker 
350*4dc78e53SAndroid Build Coastguard Worker 	xfrmnl_ae_flags2str(ae->flags, flags, sizeof (flags));
351*4dc78e53SAndroid Build Coastguard Worker 	nl_dump_line(p, "flags %s(0x%x) mark mask/value 0x%x/0x%x \n", flags,
352*4dc78e53SAndroid Build Coastguard Worker 				ae->flags, ae->mark.m, ae->mark.v);
353*4dc78e53SAndroid Build Coastguard Worker 
354*4dc78e53SAndroid Build Coastguard Worker 	nl_dump_line(p, "\tlifetime current: \n");
355*4dc78e53SAndroid Build Coastguard Worker 	nl_dump_line(p, "\t\tbytes %llu packets %llu \n",
356*4dc78e53SAndroid Build Coastguard Worker 		     (long long unsigned)ae->lifetime_cur.bytes,
357*4dc78e53SAndroid Build Coastguard Worker 		     (long long unsigned)ae->lifetime_cur.packets);
358*4dc78e53SAndroid Build Coastguard Worker 	if (ae->lifetime_cur.add_time != 0)
359*4dc78e53SAndroid Build Coastguard Worker 	{
360*4dc78e53SAndroid Build Coastguard Worker 		add_time = ae->lifetime_cur.add_time;
361*4dc78e53SAndroid Build Coastguard Worker 		add_time_tm = gmtime_r (&add_time, &tm_buf);
362*4dc78e53SAndroid Build Coastguard Worker 		strftime (flags, 128, "%Y-%m-%d %H-%M-%S", add_time_tm);
363*4dc78e53SAndroid Build Coastguard Worker 	}
364*4dc78e53SAndroid Build Coastguard Worker 	else
365*4dc78e53SAndroid Build Coastguard Worker 	{
366*4dc78e53SAndroid Build Coastguard Worker 		sprintf (flags, "%s", "-");
367*4dc78e53SAndroid Build Coastguard Worker 	}
368*4dc78e53SAndroid Build Coastguard Worker 
369*4dc78e53SAndroid Build Coastguard Worker 	if (ae->lifetime_cur.use_time != 0)
370*4dc78e53SAndroid Build Coastguard Worker 	{
371*4dc78e53SAndroid Build Coastguard Worker 		use_time = ae->lifetime_cur.use_time;
372*4dc78e53SAndroid Build Coastguard Worker 		use_time_tm = gmtime_r (&use_time, &tm_buf);
373*4dc78e53SAndroid Build Coastguard Worker 		strftime (buf, 128, "%Y-%m-%d %H-%M-%S", use_time_tm);
374*4dc78e53SAndroid Build Coastguard Worker 	}
375*4dc78e53SAndroid Build Coastguard Worker 	else
376*4dc78e53SAndroid Build Coastguard Worker 	{
377*4dc78e53SAndroid Build Coastguard Worker 		sprintf (buf, "%s", "-");
378*4dc78e53SAndroid Build Coastguard Worker 	}
379*4dc78e53SAndroid Build Coastguard Worker 	nl_dump_line(p, "\t\tadd_time: %s, use_time: %s\n", flags, buf);
380*4dc78e53SAndroid Build Coastguard Worker 
381*4dc78e53SAndroid Build Coastguard Worker 	nl_dump_line(p, "\treplay info: \n");
382*4dc78e53SAndroid Build Coastguard Worker 	nl_dump_line(p, "\t\tmax age %u max diff %u \n", ae->replay_maxage, ae->replay_maxdiff);
383*4dc78e53SAndroid Build Coastguard Worker 
384*4dc78e53SAndroid Build Coastguard Worker 	nl_dump_line(p, "\treplay state info: \n");
385*4dc78e53SAndroid Build Coastguard Worker 	if (ae->replay_state_esn)
386*4dc78e53SAndroid Build Coastguard Worker 	{
387*4dc78e53SAndroid Build Coastguard Worker 		nl_dump_line(p, "\t\toseq %u seq %u oseq_hi %u seq_hi %u replay window: %u \n",
388*4dc78e53SAndroid Build Coastguard Worker 					ae->replay_state_esn->oseq, ae->replay_state_esn->seq,
389*4dc78e53SAndroid Build Coastguard Worker 					ae->replay_state_esn->oseq_hi, ae->replay_state_esn->seq_hi,
390*4dc78e53SAndroid Build Coastguard Worker 					ae->replay_state_esn->replay_window);
391*4dc78e53SAndroid Build Coastguard Worker 	}
392*4dc78e53SAndroid Build Coastguard Worker 	else
393*4dc78e53SAndroid Build Coastguard Worker 	{
394*4dc78e53SAndroid Build Coastguard Worker 		nl_dump_line(p, "\t\toseq %u seq %u bitmap: %u \n", ae->replay_state.oseq,
395*4dc78e53SAndroid Build Coastguard Worker 					ae->replay_state.seq, ae->replay_state.bitmap);
396*4dc78e53SAndroid Build Coastguard Worker 	}
397*4dc78e53SAndroid Build Coastguard Worker 
398*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, "\n");
399*4dc78e53SAndroid Build Coastguard Worker }
400*4dc78e53SAndroid Build Coastguard Worker 
xfrm_ae_dump_details(struct nl_object * a,struct nl_dump_params * p)401*4dc78e53SAndroid Build Coastguard Worker static void xfrm_ae_dump_details(struct nl_object *a, struct nl_dump_params *p)
402*4dc78e53SAndroid Build Coastguard Worker {
403*4dc78e53SAndroid Build Coastguard Worker 	xfrm_ae_dump_line(a, p);
404*4dc78e53SAndroid Build Coastguard Worker }
405*4dc78e53SAndroid Build Coastguard Worker 
xfrm_ae_dump_stats(struct nl_object * a,struct nl_dump_params * p)406*4dc78e53SAndroid Build Coastguard Worker static void xfrm_ae_dump_stats(struct nl_object *a, struct nl_dump_params *p)
407*4dc78e53SAndroid Build Coastguard Worker {
408*4dc78e53SAndroid Build Coastguard Worker 	xfrm_ae_dump_details(a, p);
409*4dc78e53SAndroid Build Coastguard Worker }
410*4dc78e53SAndroid Build Coastguard Worker 
411*4dc78e53SAndroid Build Coastguard Worker 
build_xfrm_ae_message(struct xfrmnl_ae * tmpl,int cmd,int flags,struct nl_msg ** result)412*4dc78e53SAndroid Build Coastguard Worker static int build_xfrm_ae_message(struct xfrmnl_ae *tmpl, int cmd, int flags,
413*4dc78e53SAndroid Build Coastguard Worker 			   struct nl_msg **result)
414*4dc78e53SAndroid Build Coastguard Worker {
415*4dc78e53SAndroid Build Coastguard Worker 	struct nl_msg*          msg;
416*4dc78e53SAndroid Build Coastguard Worker 	struct xfrm_aevent_id   ae_id;
417*4dc78e53SAndroid Build Coastguard Worker 
418*4dc78e53SAndroid Build Coastguard Worker 	if (!(tmpl->ce_mask & XFRM_AE_ATTR_DADDR) ||
419*4dc78e53SAndroid Build Coastguard Worker 		!(tmpl->ce_mask & XFRM_AE_ATTR_SPI) ||
420*4dc78e53SAndroid Build Coastguard Worker 		!(tmpl->ce_mask & XFRM_AE_ATTR_PROTO))
421*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
422*4dc78e53SAndroid Build Coastguard Worker 
423*4dc78e53SAndroid Build Coastguard Worker 	memset(&ae_id, 0, sizeof(ae_id));
424*4dc78e53SAndroid Build Coastguard Worker 
425*4dc78e53SAndroid Build Coastguard Worker 	memcpy (&ae_id.sa_id.daddr, nl_addr_get_binary_addr (tmpl->sa_id.daddr), sizeof (uint8_t) * nl_addr_get_len (tmpl->sa_id.daddr));
426*4dc78e53SAndroid Build Coastguard Worker 	ae_id.sa_id.spi    = htonl(tmpl->sa_id.spi);
427*4dc78e53SAndroid Build Coastguard Worker 	ae_id.sa_id.family = tmpl->sa_id.family;
428*4dc78e53SAndroid Build Coastguard Worker 	ae_id.sa_id.proto  = tmpl->sa_id.proto;
429*4dc78e53SAndroid Build Coastguard Worker 
430*4dc78e53SAndroid Build Coastguard Worker 	if (tmpl->ce_mask & XFRM_AE_ATTR_SADDR)
431*4dc78e53SAndroid Build Coastguard Worker 		memcpy (&ae_id.saddr, nl_addr_get_binary_addr (tmpl->saddr), sizeof (uint8_t) * nl_addr_get_len (tmpl->saddr));
432*4dc78e53SAndroid Build Coastguard Worker 
433*4dc78e53SAndroid Build Coastguard Worker 	if (tmpl->ce_mask & XFRM_AE_ATTR_FLAGS)
434*4dc78e53SAndroid Build Coastguard Worker 		ae_id.flags    = tmpl->flags;
435*4dc78e53SAndroid Build Coastguard Worker 
436*4dc78e53SAndroid Build Coastguard Worker 	if (tmpl->ce_mask & XFRM_AE_ATTR_REQID)
437*4dc78e53SAndroid Build Coastguard Worker 		ae_id.reqid    = tmpl->reqid;
438*4dc78e53SAndroid Build Coastguard Worker 
439*4dc78e53SAndroid Build Coastguard Worker 	msg = nlmsg_alloc_simple(cmd, flags);
440*4dc78e53SAndroid Build Coastguard Worker 	if (!msg)
441*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
442*4dc78e53SAndroid Build Coastguard Worker 
443*4dc78e53SAndroid Build Coastguard Worker 	if (nlmsg_append(msg, &ae_id, sizeof(ae_id), NLMSG_ALIGNTO) < 0)
444*4dc78e53SAndroid Build Coastguard Worker 		goto nla_put_failure;
445*4dc78e53SAndroid Build Coastguard Worker 
446*4dc78e53SAndroid Build Coastguard Worker 	if (tmpl->ce_mask & XFRM_AE_ATTR_MARK)
447*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT (msg, XFRMA_MARK, sizeof (struct xfrmnl_mark), &tmpl->mark);
448*4dc78e53SAndroid Build Coastguard Worker 
449*4dc78e53SAndroid Build Coastguard Worker 	if (tmpl->ce_mask & XFRM_AE_ATTR_LIFETIME)
450*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT (msg, XFRMA_LTIME_VAL, sizeof (struct xfrmnl_lifetime_cur), &tmpl->lifetime_cur);
451*4dc78e53SAndroid Build Coastguard Worker 
452*4dc78e53SAndroid Build Coastguard Worker 	if (tmpl->ce_mask & XFRM_AE_ATTR_REPLAY_MAXAGE)
453*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT_U32 (msg, XFRMA_ETIMER_THRESH, tmpl->replay_maxage);
454*4dc78e53SAndroid Build Coastguard Worker 
455*4dc78e53SAndroid Build Coastguard Worker 	if (tmpl->ce_mask & XFRM_AE_ATTR_REPLAY_MAXDIFF)
456*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT_U32 (msg, XFRMA_REPLAY_THRESH, tmpl->replay_maxdiff);
457*4dc78e53SAndroid Build Coastguard Worker 
458*4dc78e53SAndroid Build Coastguard Worker 	if (tmpl->ce_mask & XFRM_AE_ATTR_REPLAY_STATE) {
459*4dc78e53SAndroid Build Coastguard Worker 		if (tmpl->replay_state_esn) {
460*4dc78e53SAndroid Build Coastguard Worker 			uint32_t len = sizeof (struct xfrm_replay_state_esn) + (sizeof (uint32_t) * tmpl->replay_state_esn->bmp_len);
461*4dc78e53SAndroid Build Coastguard Worker 			NLA_PUT (msg, XFRMA_REPLAY_ESN_VAL, len, tmpl->replay_state_esn);
462*4dc78e53SAndroid Build Coastguard Worker 		}
463*4dc78e53SAndroid Build Coastguard Worker 		else {
464*4dc78e53SAndroid Build Coastguard Worker 			NLA_PUT (msg, XFRMA_REPLAY_VAL, sizeof (struct xfrmnl_replay_state), &tmpl->replay_state);
465*4dc78e53SAndroid Build Coastguard Worker 		}
466*4dc78e53SAndroid Build Coastguard Worker 	}
467*4dc78e53SAndroid Build Coastguard Worker 
468*4dc78e53SAndroid Build Coastguard Worker 	*result = msg;
469*4dc78e53SAndroid Build Coastguard Worker 	return 0;
470*4dc78e53SAndroid Build Coastguard Worker 
471*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
472*4dc78e53SAndroid Build Coastguard Worker 	nlmsg_free(msg);
473*4dc78e53SAndroid Build Coastguard Worker 	return -NLE_MSGSIZE;
474*4dc78e53SAndroid Build Coastguard Worker }
475*4dc78e53SAndroid Build Coastguard Worker 
476*4dc78e53SAndroid Build Coastguard Worker /**
477*4dc78e53SAndroid Build Coastguard Worker  * @name XFRM AE Update
478*4dc78e53SAndroid Build Coastguard Worker  * @{
479*4dc78e53SAndroid Build Coastguard Worker  */
480*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_set(struct nl_sock * sk,struct xfrmnl_ae * ae,int flags)481*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_set(struct nl_sock* sk, struct xfrmnl_ae* ae, int flags)
482*4dc78e53SAndroid Build Coastguard Worker {
483*4dc78e53SAndroid Build Coastguard Worker 	int err;
484*4dc78e53SAndroid Build Coastguard Worker 	struct nl_msg *msg;
485*4dc78e53SAndroid Build Coastguard Worker 
486*4dc78e53SAndroid Build Coastguard Worker 	if ((err = build_xfrm_ae_message(ae, XFRM_MSG_NEWAE, flags|NLM_F_REPLACE, &msg)) < 0)
487*4dc78e53SAndroid Build Coastguard Worker 		return err;
488*4dc78e53SAndroid Build Coastguard Worker 
489*4dc78e53SAndroid Build Coastguard Worker 	err = nl_send_auto_complete(sk, msg);
490*4dc78e53SAndroid Build Coastguard Worker 	nlmsg_free(msg);
491*4dc78e53SAndroid Build Coastguard Worker 	if (err < 0)
492*4dc78e53SAndroid Build Coastguard Worker 		return err;
493*4dc78e53SAndroid Build Coastguard Worker 
494*4dc78e53SAndroid Build Coastguard Worker 	return nl_wait_for_ack(sk);
495*4dc78e53SAndroid Build Coastguard Worker }
496*4dc78e53SAndroid Build Coastguard Worker 
497*4dc78e53SAndroid Build Coastguard Worker /** @} */
498*4dc78e53SAndroid Build Coastguard Worker 
499*4dc78e53SAndroid Build Coastguard Worker /**
500*4dc78e53SAndroid Build Coastguard Worker  * @name XFRM AE Object Allocation/Freeage
501*4dc78e53SAndroid Build Coastguard Worker  * @{
502*4dc78e53SAndroid Build Coastguard Worker  */
503*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_alloc(void)504*4dc78e53SAndroid Build Coastguard Worker struct xfrmnl_ae* xfrmnl_ae_alloc(void)
505*4dc78e53SAndroid Build Coastguard Worker {
506*4dc78e53SAndroid Build Coastguard Worker 	return (struct xfrmnl_ae*) nl_object_alloc(&xfrm_ae_obj_ops);
507*4dc78e53SAndroid Build Coastguard Worker }
508*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_put(struct xfrmnl_ae * ae)509*4dc78e53SAndroid Build Coastguard Worker void xfrmnl_ae_put(struct xfrmnl_ae* ae)
510*4dc78e53SAndroid Build Coastguard Worker {
511*4dc78e53SAndroid Build Coastguard Worker 	nl_object_put((struct nl_object *) ae);
512*4dc78e53SAndroid Build Coastguard Worker }
513*4dc78e53SAndroid Build Coastguard Worker 
514*4dc78e53SAndroid Build Coastguard Worker /** @} */
515*4dc78e53SAndroid Build Coastguard Worker 
516*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy xfrm_ae_policy[XFRMA_MAX+1] = {
517*4dc78e53SAndroid Build Coastguard Worker 	[XFRMA_LTIME_VAL]       = { .minlen = sizeof(struct xfrm_lifetime_cur) },
518*4dc78e53SAndroid Build Coastguard Worker 	[XFRMA_REPLAY_VAL]      = { .minlen = sizeof(struct xfrm_replay_state) },
519*4dc78e53SAndroid Build Coastguard Worker 	[XFRMA_REPLAY_THRESH]   = { .type = NLA_U32 },
520*4dc78e53SAndroid Build Coastguard Worker 	[XFRMA_ETIMER_THRESH]   = { .type = NLA_U32 },
521*4dc78e53SAndroid Build Coastguard Worker 	[XFRMA_SRCADDR]         = { .minlen = sizeof(xfrm_address_t) },
522*4dc78e53SAndroid Build Coastguard Worker 	[XFRMA_MARK]            = { .minlen = sizeof(struct xfrm_mark) },
523*4dc78e53SAndroid Build Coastguard Worker 	[XFRMA_REPLAY_ESN_VAL]  = { .minlen = sizeof(struct xfrm_replay_state_esn) },
524*4dc78e53SAndroid Build Coastguard Worker };
525*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_parse(struct nlmsghdr * n,struct xfrmnl_ae ** result)526*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_parse(struct nlmsghdr *n, struct xfrmnl_ae **result)
527*4dc78e53SAndroid Build Coastguard Worker {
528*4dc78e53SAndroid Build Coastguard Worker 	_nl_auto_xfrmnl_ae struct xfrmnl_ae *ae = NULL;
529*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr           *tb[XFRMA_MAX + 1];
530*4dc78e53SAndroid Build Coastguard Worker 	struct xfrm_aevent_id*  ae_id;
531*4dc78e53SAndroid Build Coastguard Worker 	int err;
532*4dc78e53SAndroid Build Coastguard Worker 
533*4dc78e53SAndroid Build Coastguard Worker 	ae = xfrmnl_ae_alloc();
534*4dc78e53SAndroid Build Coastguard Worker 	if (!ae)
535*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
536*4dc78e53SAndroid Build Coastguard Worker 
537*4dc78e53SAndroid Build Coastguard Worker 	ae->ce_msgtype = n->nlmsg_type;
538*4dc78e53SAndroid Build Coastguard Worker 	ae_id = nlmsg_data(n);
539*4dc78e53SAndroid Build Coastguard Worker 
540*4dc78e53SAndroid Build Coastguard Worker 	err = nlmsg_parse(n, sizeof(struct xfrm_aevent_id), tb, XFRMA_MAX, xfrm_ae_policy);
541*4dc78e53SAndroid Build Coastguard Worker 	if (err < 0)
542*4dc78e53SAndroid Build Coastguard Worker 		return err;
543*4dc78e53SAndroid Build Coastguard Worker 
544*4dc78e53SAndroid Build Coastguard Worker 	if (!(ae->sa_id.daddr =
545*4dc78e53SAndroid Build Coastguard Worker 		      _nl_addr_build(ae_id->sa_id.family, &ae_id->sa_id.daddr)))
546*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
547*4dc78e53SAndroid Build Coastguard Worker 	ae->sa_id.family= ae_id->sa_id.family;
548*4dc78e53SAndroid Build Coastguard Worker 	ae->sa_id.spi   = ntohl(ae_id->sa_id.spi);
549*4dc78e53SAndroid Build Coastguard Worker 	ae->sa_id.proto = ae_id->sa_id.proto;
550*4dc78e53SAndroid Build Coastguard Worker 	if (!(ae->saddr = _nl_addr_build(ae_id->sa_id.family, &ae_id->saddr)))
551*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
552*4dc78e53SAndroid Build Coastguard Worker 	ae->reqid       = ae_id->reqid;
553*4dc78e53SAndroid Build Coastguard Worker 	ae->flags       = ae_id->flags;
554*4dc78e53SAndroid Build Coastguard Worker 	ae->ce_mask |= (XFRM_AE_ATTR_DADDR | XFRM_AE_ATTR_FAMILY | XFRM_AE_ATTR_SPI |
555*4dc78e53SAndroid Build Coastguard Worker 					XFRM_AE_ATTR_PROTO | XFRM_AE_ATTR_SADDR | XFRM_AE_ATTR_REQID |
556*4dc78e53SAndroid Build Coastguard Worker 					XFRM_AE_ATTR_FLAGS);
557*4dc78e53SAndroid Build Coastguard Worker 
558*4dc78e53SAndroid Build Coastguard Worker 	if (tb[XFRMA_MARK]) {
559*4dc78e53SAndroid Build Coastguard Worker 		struct xfrm_mark* m =   nla_data(tb[XFRMA_MARK]);
560*4dc78e53SAndroid Build Coastguard Worker 		ae->mark.m  =   m->m;
561*4dc78e53SAndroid Build Coastguard Worker 		ae->mark.v  =   m->v;
562*4dc78e53SAndroid Build Coastguard Worker 		ae->ce_mask |= XFRM_AE_ATTR_MARK;
563*4dc78e53SAndroid Build Coastguard Worker 	}
564*4dc78e53SAndroid Build Coastguard Worker 
565*4dc78e53SAndroid Build Coastguard Worker 	if (tb[XFRMA_LTIME_VAL]) {
566*4dc78e53SAndroid Build Coastguard Worker 		struct xfrm_lifetime_cur* cur =   nla_data(tb[XFRMA_LTIME_VAL]);
567*4dc78e53SAndroid Build Coastguard Worker 
568*4dc78e53SAndroid Build Coastguard Worker 		ae->lifetime_cur.bytes      =   cur->bytes;
569*4dc78e53SAndroid Build Coastguard Worker 		ae->lifetime_cur.packets    =   cur->packets;
570*4dc78e53SAndroid Build Coastguard Worker 		ae->lifetime_cur.add_time   =   cur->add_time;
571*4dc78e53SAndroid Build Coastguard Worker 		ae->lifetime_cur.use_time   =   cur->use_time;
572*4dc78e53SAndroid Build Coastguard Worker 		ae->ce_mask |= XFRM_AE_ATTR_LIFETIME;
573*4dc78e53SAndroid Build Coastguard Worker 	}
574*4dc78e53SAndroid Build Coastguard Worker 
575*4dc78e53SAndroid Build Coastguard Worker 	if (tb[XFRM_AE_ETHR]) {
576*4dc78e53SAndroid Build Coastguard Worker 		ae->replay_maxage       =   *(uint32_t*)nla_data(tb[XFRM_AE_ETHR]);
577*4dc78e53SAndroid Build Coastguard Worker 		ae->ce_mask |= XFRM_AE_ATTR_REPLAY_MAXAGE;
578*4dc78e53SAndroid Build Coastguard Worker 	}
579*4dc78e53SAndroid Build Coastguard Worker 
580*4dc78e53SAndroid Build Coastguard Worker 	if (tb[XFRM_AE_RTHR]) {
581*4dc78e53SAndroid Build Coastguard Worker 		ae->replay_maxdiff      =   *(uint32_t*)nla_data(tb[XFRM_AE_RTHR]);
582*4dc78e53SAndroid Build Coastguard Worker 		ae->ce_mask |= XFRM_AE_ATTR_REPLAY_MAXDIFF;
583*4dc78e53SAndroid Build Coastguard Worker 	}
584*4dc78e53SAndroid Build Coastguard Worker 
585*4dc78e53SAndroid Build Coastguard Worker 	if (tb[XFRMA_REPLAY_ESN_VAL]) {
586*4dc78e53SAndroid Build Coastguard Worker 		struct xfrm_replay_state_esn* esn =  nla_data (tb[XFRMA_REPLAY_ESN_VAL]);
587*4dc78e53SAndroid Build Coastguard Worker 		uint32_t len = sizeof (struct xfrmnl_replay_state_esn) +  (sizeof (uint32_t) * esn->bmp_len);
588*4dc78e53SAndroid Build Coastguard Worker 
589*4dc78e53SAndroid Build Coastguard Worker 		if ((ae->replay_state_esn = calloc (1, len)) == NULL)
590*4dc78e53SAndroid Build Coastguard Worker 			return -NLE_NOMEM;
591*4dc78e53SAndroid Build Coastguard Worker 		ae->replay_state_esn->oseq       =  esn->oseq;
592*4dc78e53SAndroid Build Coastguard Worker 		ae->replay_state_esn->seq        =  esn->seq;
593*4dc78e53SAndroid Build Coastguard Worker 		ae->replay_state_esn->oseq_hi    =  esn->oseq_hi;
594*4dc78e53SAndroid Build Coastguard Worker 		ae->replay_state_esn->seq_hi     =  esn->seq_hi;
595*4dc78e53SAndroid Build Coastguard Worker 		ae->replay_state_esn->replay_window   =   esn->replay_window;
596*4dc78e53SAndroid Build Coastguard Worker 		ae->replay_state_esn->bmp_len    =   esn->bmp_len;
597*4dc78e53SAndroid Build Coastguard Worker 		memcpy (ae->replay_state_esn->bmp, esn->bmp, sizeof (uint32_t) * esn->bmp_len);
598*4dc78e53SAndroid Build Coastguard Worker 		ae->ce_mask |= XFRM_AE_ATTR_REPLAY_STATE;
599*4dc78e53SAndroid Build Coastguard Worker 	}
600*4dc78e53SAndroid Build Coastguard Worker 	else
601*4dc78e53SAndroid Build Coastguard Worker 	{
602*4dc78e53SAndroid Build Coastguard Worker 		struct xfrm_replay_state* replay_state = nla_data (tb[XFRMA_REPLAY_VAL]);
603*4dc78e53SAndroid Build Coastguard Worker 		ae->replay_state.oseq       =   replay_state->oseq;
604*4dc78e53SAndroid Build Coastguard Worker 		ae->replay_state.seq        =   replay_state->seq;
605*4dc78e53SAndroid Build Coastguard Worker 		ae->replay_state.bitmap     =   replay_state->bitmap;
606*4dc78e53SAndroid Build Coastguard Worker 		ae->ce_mask |= XFRM_AE_ATTR_REPLAY_STATE;
607*4dc78e53SAndroid Build Coastguard Worker 
608*4dc78e53SAndroid Build Coastguard Worker 		ae->replay_state_esn = NULL;
609*4dc78e53SAndroid Build Coastguard Worker 	}
610*4dc78e53SAndroid Build Coastguard Worker 
611*4dc78e53SAndroid Build Coastguard Worker 	*result = _nl_steal_pointer(&ae);
612*4dc78e53SAndroid Build Coastguard Worker 	return 0;
613*4dc78e53SAndroid Build Coastguard Worker }
614*4dc78e53SAndroid Build Coastguard Worker 
xfrm_ae_msg_parser(struct nl_cache_ops * ops,struct sockaddr_nl * who,struct nlmsghdr * n,struct nl_parser_param * pp)615*4dc78e53SAndroid Build Coastguard Worker static int xfrm_ae_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
616*4dc78e53SAndroid Build Coastguard Worker 				struct nlmsghdr *n, struct nl_parser_param *pp)
617*4dc78e53SAndroid Build Coastguard Worker {
618*4dc78e53SAndroid Build Coastguard Worker 	struct xfrmnl_ae*    ae;
619*4dc78e53SAndroid Build Coastguard Worker 	int err;
620*4dc78e53SAndroid Build Coastguard Worker 
621*4dc78e53SAndroid Build Coastguard Worker 	if ((err = xfrmnl_ae_parse(n, &ae)) < 0)
622*4dc78e53SAndroid Build Coastguard Worker 		return err;
623*4dc78e53SAndroid Build Coastguard Worker 
624*4dc78e53SAndroid Build Coastguard Worker 	err = pp->pp_cb((struct nl_object *) ae, pp);
625*4dc78e53SAndroid Build Coastguard Worker 
626*4dc78e53SAndroid Build Coastguard Worker 	xfrmnl_ae_put(ae);
627*4dc78e53SAndroid Build Coastguard Worker 	return err;
628*4dc78e53SAndroid Build Coastguard Worker }
629*4dc78e53SAndroid Build Coastguard Worker 
630*4dc78e53SAndroid Build Coastguard Worker /**
631*4dc78e53SAndroid Build Coastguard Worker  * @name XFRM AE Get
632*4dc78e53SAndroid Build Coastguard Worker  * @{
633*4dc78e53SAndroid Build Coastguard Worker  */
634*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_build_get_request(struct nl_addr * daddr,unsigned int spi,unsigned int protocol,unsigned int mark_mask,unsigned int mark_value,struct nl_msg ** result)635*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_build_get_request(struct nl_addr* daddr, unsigned int spi, unsigned int protocol,
636*4dc78e53SAndroid Build Coastguard Worker                                 unsigned int mark_mask, unsigned int mark_value, struct nl_msg **result)
637*4dc78e53SAndroid Build Coastguard Worker {
638*4dc78e53SAndroid Build Coastguard Worker 	struct nl_msg *msg;
639*4dc78e53SAndroid Build Coastguard Worker 	struct xfrm_aevent_id   ae_id;
640*4dc78e53SAndroid Build Coastguard Worker 	struct xfrmnl_mark   mark;
641*4dc78e53SAndroid Build Coastguard Worker 
642*4dc78e53SAndroid Build Coastguard Worker 	if (!daddr || !spi)
643*4dc78e53SAndroid Build Coastguard Worker 	{
644*4dc78e53SAndroid Build Coastguard Worker 		fprintf(stderr, "APPLICATION BUG: %s:%d:%s: A valid destination address, spi must be specified\n",
645*4dc78e53SAndroid Build Coastguard Worker 				__FILE__, __LINE__, __func__);
646*4dc78e53SAndroid Build Coastguard Worker 		assert(0);
647*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
648*4dc78e53SAndroid Build Coastguard Worker 	}
649*4dc78e53SAndroid Build Coastguard Worker 
650*4dc78e53SAndroid Build Coastguard Worker 	memset(&ae_id, 0, sizeof(ae_id));
651*4dc78e53SAndroid Build Coastguard Worker 	memcpy (&ae_id.sa_id.daddr, nl_addr_get_binary_addr (daddr), sizeof (uint8_t) * nl_addr_get_len (daddr));
652*4dc78e53SAndroid Build Coastguard Worker 	ae_id.sa_id.spi    = htonl(spi);
653*4dc78e53SAndroid Build Coastguard Worker 	ae_id.sa_id.family = nl_addr_get_family (daddr);
654*4dc78e53SAndroid Build Coastguard Worker 	ae_id.sa_id.proto  = protocol;
655*4dc78e53SAndroid Build Coastguard Worker 
656*4dc78e53SAndroid Build Coastguard Worker 	if (!(msg = nlmsg_alloc_simple(XFRM_MSG_GETAE, 0)))
657*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
658*4dc78e53SAndroid Build Coastguard Worker 
659*4dc78e53SAndroid Build Coastguard Worker 	if (nlmsg_append(msg, &ae_id, sizeof(ae_id), NLMSG_ALIGNTO) < 0)
660*4dc78e53SAndroid Build Coastguard Worker 		goto nla_put_failure;
661*4dc78e53SAndroid Build Coastguard Worker 
662*4dc78e53SAndroid Build Coastguard Worker 	mark.m  =   mark_mask;
663*4dc78e53SAndroid Build Coastguard Worker 	mark.v  =   mark_value;
664*4dc78e53SAndroid Build Coastguard Worker 	NLA_PUT (msg, XFRMA_MARK, sizeof (struct xfrmnl_mark), &mark);
665*4dc78e53SAndroid Build Coastguard Worker 
666*4dc78e53SAndroid Build Coastguard Worker 	*result = msg;
667*4dc78e53SAndroid Build Coastguard Worker 	return 0;
668*4dc78e53SAndroid Build Coastguard Worker 
669*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
670*4dc78e53SAndroid Build Coastguard Worker 	nlmsg_free(msg);
671*4dc78e53SAndroid Build Coastguard Worker 	return -NLE_MSGSIZE;
672*4dc78e53SAndroid Build Coastguard Worker }
673*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_get_kernel(struct nl_sock * sock,struct nl_addr * daddr,unsigned int spi,unsigned int protocol,unsigned int mark_mask,unsigned int mark_value,struct xfrmnl_ae ** result)674*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_get_kernel(struct nl_sock* sock, struct nl_addr* daddr, unsigned int spi, unsigned int protocol,
675*4dc78e53SAndroid Build Coastguard Worker                          unsigned int mark_mask, unsigned int mark_value, struct xfrmnl_ae** result)
676*4dc78e53SAndroid Build Coastguard Worker {
677*4dc78e53SAndroid Build Coastguard Worker 	struct nl_msg *msg = NULL;
678*4dc78e53SAndroid Build Coastguard Worker 	struct nl_object *obj;
679*4dc78e53SAndroid Build Coastguard Worker 	int err;
680*4dc78e53SAndroid Build Coastguard Worker 
681*4dc78e53SAndroid Build Coastguard Worker 	if ((err = xfrmnl_ae_build_get_request(daddr, spi, protocol, mark_mask, mark_value, &msg)) < 0)
682*4dc78e53SAndroid Build Coastguard Worker 		return err;
683*4dc78e53SAndroid Build Coastguard Worker 
684*4dc78e53SAndroid Build Coastguard Worker 	err = nl_send_auto(sock, msg);
685*4dc78e53SAndroid Build Coastguard Worker 	nlmsg_free(msg);
686*4dc78e53SAndroid Build Coastguard Worker 	if (err < 0)
687*4dc78e53SAndroid Build Coastguard Worker 		return err;
688*4dc78e53SAndroid Build Coastguard Worker 
689*4dc78e53SAndroid Build Coastguard Worker 	if ((err = nl_pickup(sock, &xfrm_ae_msg_parser, &obj)) < 0)
690*4dc78e53SAndroid Build Coastguard Worker 		return err;
691*4dc78e53SAndroid Build Coastguard Worker 
692*4dc78e53SAndroid Build Coastguard Worker 	/* We have used xfrm_ae_msg_parser(), object is definitely a xfrm ae */
693*4dc78e53SAndroid Build Coastguard Worker 	*result = (struct xfrmnl_ae *) obj;
694*4dc78e53SAndroid Build Coastguard Worker 
695*4dc78e53SAndroid Build Coastguard Worker 	/* If an object has been returned, we also need to wait for the ACK */
696*4dc78e53SAndroid Build Coastguard Worker 	if (err == 0 && obj)
697*4dc78e53SAndroid Build Coastguard Worker 		nl_wait_for_ack(sock);
698*4dc78e53SAndroid Build Coastguard Worker 
699*4dc78e53SAndroid Build Coastguard Worker 	return 0;
700*4dc78e53SAndroid Build Coastguard Worker }
701*4dc78e53SAndroid Build Coastguard Worker 
702*4dc78e53SAndroid Build Coastguard Worker /** @} */
703*4dc78e53SAndroid Build Coastguard Worker 
704*4dc78e53SAndroid Build Coastguard Worker /**
705*4dc78e53SAndroid Build Coastguard Worker  * @name Attributes
706*4dc78e53SAndroid Build Coastguard Worker  * @{
707*4dc78e53SAndroid Build Coastguard Worker  */
708*4dc78e53SAndroid Build Coastguard Worker 
__assign_addr(struct xfrmnl_ae * ae,struct nl_addr ** pos,struct nl_addr * new,int flag,int nocheck)709*4dc78e53SAndroid Build Coastguard Worker static inline int __assign_addr(struct xfrmnl_ae* ae, struct nl_addr **pos,
710*4dc78e53SAndroid Build Coastguard Worker 					struct nl_addr *new, int flag, int nocheck)
711*4dc78e53SAndroid Build Coastguard Worker {
712*4dc78e53SAndroid Build Coastguard Worker 	if (!nocheck) {
713*4dc78e53SAndroid Build Coastguard Worker 		if (ae->ce_mask & XFRM_AE_ATTR_FAMILY) {
714*4dc78e53SAndroid Build Coastguard Worker 			if (nl_addr_get_family (new) != ae->sa_id.family)
715*4dc78e53SAndroid Build Coastguard Worker 				return -NLE_AF_MISMATCH;
716*4dc78e53SAndroid Build Coastguard Worker 		} else {
717*4dc78e53SAndroid Build Coastguard Worker 			ae->sa_id.family = nl_addr_get_family (new);
718*4dc78e53SAndroid Build Coastguard Worker 			ae->ce_mask |= XFRM_AE_ATTR_FAMILY;
719*4dc78e53SAndroid Build Coastguard Worker 		}
720*4dc78e53SAndroid Build Coastguard Worker 	}
721*4dc78e53SAndroid Build Coastguard Worker 
722*4dc78e53SAndroid Build Coastguard Worker 	if (*pos)
723*4dc78e53SAndroid Build Coastguard Worker 		nl_addr_put(*pos);
724*4dc78e53SAndroid Build Coastguard Worker 
725*4dc78e53SAndroid Build Coastguard Worker 	nl_addr_get(new);
726*4dc78e53SAndroid Build Coastguard Worker 	*pos = new;
727*4dc78e53SAndroid Build Coastguard Worker 
728*4dc78e53SAndroid Build Coastguard Worker 	ae->ce_mask |= flag;
729*4dc78e53SAndroid Build Coastguard Worker 
730*4dc78e53SAndroid Build Coastguard Worker 	return 0;
731*4dc78e53SAndroid Build Coastguard Worker }
732*4dc78e53SAndroid Build Coastguard Worker 
733*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_get_daddr(struct xfrmnl_ae * ae)734*4dc78e53SAndroid Build Coastguard Worker struct nl_addr* xfrmnl_ae_get_daddr (struct xfrmnl_ae* ae)
735*4dc78e53SAndroid Build Coastguard Worker {
736*4dc78e53SAndroid Build Coastguard Worker 	if (ae->ce_mask & XFRM_AE_ATTR_DADDR)
737*4dc78e53SAndroid Build Coastguard Worker 		return ae->sa_id.daddr;
738*4dc78e53SAndroid Build Coastguard Worker 	else
739*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
740*4dc78e53SAndroid Build Coastguard Worker }
741*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_set_daddr(struct xfrmnl_ae * ae,struct nl_addr * addr)742*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_set_daddr (struct xfrmnl_ae* ae, struct nl_addr* addr)
743*4dc78e53SAndroid Build Coastguard Worker {
744*4dc78e53SAndroid Build Coastguard Worker 	return __assign_addr(ae, &ae->sa_id.daddr, addr, XFRM_AE_ATTR_DADDR, 0);
745*4dc78e53SAndroid Build Coastguard Worker }
746*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_get_spi(struct xfrmnl_ae * ae)747*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_get_spi (struct xfrmnl_ae* ae)
748*4dc78e53SAndroid Build Coastguard Worker {
749*4dc78e53SAndroid Build Coastguard Worker 	if (ae->ce_mask & XFRM_AE_ATTR_SPI)
750*4dc78e53SAndroid Build Coastguard Worker 		return ae->sa_id.spi;
751*4dc78e53SAndroid Build Coastguard Worker 	else
752*4dc78e53SAndroid Build Coastguard Worker 		return -1;
753*4dc78e53SAndroid Build Coastguard Worker }
754*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_set_spi(struct xfrmnl_ae * ae,unsigned int spi)755*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_set_spi (struct xfrmnl_ae* ae, unsigned int spi)
756*4dc78e53SAndroid Build Coastguard Worker {
757*4dc78e53SAndroid Build Coastguard Worker 	ae->sa_id.spi = spi;
758*4dc78e53SAndroid Build Coastguard Worker 	ae->ce_mask |= XFRM_AE_ATTR_SPI;
759*4dc78e53SAndroid Build Coastguard Worker 
760*4dc78e53SAndroid Build Coastguard Worker 	return 0;
761*4dc78e53SAndroid Build Coastguard Worker }
762*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_get_family(struct xfrmnl_ae * ae)763*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_get_family (struct xfrmnl_ae* ae)
764*4dc78e53SAndroid Build Coastguard Worker {
765*4dc78e53SAndroid Build Coastguard Worker 	if (ae->ce_mask & XFRM_AE_ATTR_FAMILY)
766*4dc78e53SAndroid Build Coastguard Worker 		return ae->sa_id.family;
767*4dc78e53SAndroid Build Coastguard Worker 	else
768*4dc78e53SAndroid Build Coastguard Worker 		return -1;
769*4dc78e53SAndroid Build Coastguard Worker }
770*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_set_family(struct xfrmnl_ae * ae,unsigned int family)771*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_set_family (struct xfrmnl_ae* ae, unsigned int family)
772*4dc78e53SAndroid Build Coastguard Worker {
773*4dc78e53SAndroid Build Coastguard Worker 	ae->sa_id.family = family;
774*4dc78e53SAndroid Build Coastguard Worker 	ae->ce_mask |= XFRM_AE_ATTR_FAMILY;
775*4dc78e53SAndroid Build Coastguard Worker 
776*4dc78e53SAndroid Build Coastguard Worker 	return 0;
777*4dc78e53SAndroid Build Coastguard Worker }
778*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_get_proto(struct xfrmnl_ae * ae)779*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_get_proto (struct xfrmnl_ae* ae)
780*4dc78e53SAndroid Build Coastguard Worker {
781*4dc78e53SAndroid Build Coastguard Worker 	if (ae->ce_mask & XFRM_AE_ATTR_PROTO)
782*4dc78e53SAndroid Build Coastguard Worker 		return ae->sa_id.proto;
783*4dc78e53SAndroid Build Coastguard Worker 	else
784*4dc78e53SAndroid Build Coastguard Worker 		return -1;
785*4dc78e53SAndroid Build Coastguard Worker }
786*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_set_proto(struct xfrmnl_ae * ae,unsigned int protocol)787*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_set_proto (struct xfrmnl_ae* ae, unsigned int protocol)
788*4dc78e53SAndroid Build Coastguard Worker {
789*4dc78e53SAndroid Build Coastguard Worker 	ae->sa_id.proto = protocol;
790*4dc78e53SAndroid Build Coastguard Worker 	ae->ce_mask |= XFRM_AE_ATTR_PROTO;
791*4dc78e53SAndroid Build Coastguard Worker 
792*4dc78e53SAndroid Build Coastguard Worker 	return 0;
793*4dc78e53SAndroid Build Coastguard Worker }
794*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_get_saddr(struct xfrmnl_ae * ae)795*4dc78e53SAndroid Build Coastguard Worker struct nl_addr* xfrmnl_ae_get_saddr (struct xfrmnl_ae* ae)
796*4dc78e53SAndroid Build Coastguard Worker {
797*4dc78e53SAndroid Build Coastguard Worker 	if (ae->ce_mask & XFRM_AE_ATTR_SADDR)
798*4dc78e53SAndroid Build Coastguard Worker 		return ae->saddr;
799*4dc78e53SAndroid Build Coastguard Worker 	else
800*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
801*4dc78e53SAndroid Build Coastguard Worker }
802*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_set_saddr(struct xfrmnl_ae * ae,struct nl_addr * addr)803*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_set_saddr (struct xfrmnl_ae* ae, struct nl_addr* addr)
804*4dc78e53SAndroid Build Coastguard Worker {
805*4dc78e53SAndroid Build Coastguard Worker 	return 	__assign_addr(ae, &ae->saddr, addr, XFRM_AE_ATTR_SADDR, 1);
806*4dc78e53SAndroid Build Coastguard Worker }
807*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_get_flags(struct xfrmnl_ae * ae)808*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_get_flags (struct xfrmnl_ae* ae)
809*4dc78e53SAndroid Build Coastguard Worker {
810*4dc78e53SAndroid Build Coastguard Worker 	if (ae->ce_mask & XFRM_AE_ATTR_FLAGS)
811*4dc78e53SAndroid Build Coastguard Worker 		return ae->flags;
812*4dc78e53SAndroid Build Coastguard Worker 	else
813*4dc78e53SAndroid Build Coastguard Worker 		return -1;
814*4dc78e53SAndroid Build Coastguard Worker }
815*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_set_flags(struct xfrmnl_ae * ae,unsigned int flags)816*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_set_flags (struct xfrmnl_ae* ae, unsigned int flags)
817*4dc78e53SAndroid Build Coastguard Worker {
818*4dc78e53SAndroid Build Coastguard Worker 	ae->flags = flags;
819*4dc78e53SAndroid Build Coastguard Worker 	ae->ce_mask |= XFRM_AE_ATTR_FLAGS;
820*4dc78e53SAndroid Build Coastguard Worker 
821*4dc78e53SAndroid Build Coastguard Worker 	return 0;
822*4dc78e53SAndroid Build Coastguard Worker }
823*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_get_reqid(struct xfrmnl_ae * ae)824*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_get_reqid (struct xfrmnl_ae* ae)
825*4dc78e53SAndroid Build Coastguard Worker {
826*4dc78e53SAndroid Build Coastguard Worker 	if (ae->ce_mask & XFRM_AE_ATTR_REQID)
827*4dc78e53SAndroid Build Coastguard Worker 		return ae->reqid;
828*4dc78e53SAndroid Build Coastguard Worker 	else
829*4dc78e53SAndroid Build Coastguard Worker 		return -1;
830*4dc78e53SAndroid Build Coastguard Worker }
831*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_set_reqid(struct xfrmnl_ae * ae,unsigned int reqid)832*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_set_reqid (struct xfrmnl_ae* ae, unsigned int reqid)
833*4dc78e53SAndroid Build Coastguard Worker {
834*4dc78e53SAndroid Build Coastguard Worker 	ae->reqid = reqid;
835*4dc78e53SAndroid Build Coastguard Worker 	ae->ce_mask |= XFRM_AE_ATTR_REQID;
836*4dc78e53SAndroid Build Coastguard Worker 
837*4dc78e53SAndroid Build Coastguard Worker 	return 0;
838*4dc78e53SAndroid Build Coastguard Worker }
839*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_get_mark(struct xfrmnl_ae * ae,unsigned int * mark_mask,unsigned int * mark_value)840*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_get_mark (struct xfrmnl_ae* ae, unsigned int* mark_mask, unsigned int* mark_value)
841*4dc78e53SAndroid Build Coastguard Worker {
842*4dc78e53SAndroid Build Coastguard Worker 	if (mark_mask == NULL || mark_value == NULL)
843*4dc78e53SAndroid Build Coastguard Worker 		return -1;
844*4dc78e53SAndroid Build Coastguard Worker 
845*4dc78e53SAndroid Build Coastguard Worker 	if (ae->ce_mask & XFRM_AE_ATTR_MARK)
846*4dc78e53SAndroid Build Coastguard Worker 	{
847*4dc78e53SAndroid Build Coastguard Worker 		*mark_mask  =   ae->mark.m;
848*4dc78e53SAndroid Build Coastguard Worker 		*mark_value  =   ae->mark.v;
849*4dc78e53SAndroid Build Coastguard Worker 
850*4dc78e53SAndroid Build Coastguard Worker 		return 0;
851*4dc78e53SAndroid Build Coastguard Worker 	}
852*4dc78e53SAndroid Build Coastguard Worker 	else
853*4dc78e53SAndroid Build Coastguard Worker 		return -1;
854*4dc78e53SAndroid Build Coastguard Worker }
855*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_set_mark(struct xfrmnl_ae * ae,unsigned int value,unsigned int mask)856*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_set_mark (struct xfrmnl_ae* ae, unsigned int value, unsigned int mask)
857*4dc78e53SAndroid Build Coastguard Worker {
858*4dc78e53SAndroid Build Coastguard Worker 	ae->mark.v  = value;
859*4dc78e53SAndroid Build Coastguard Worker 	ae->mark.m  = mask;
860*4dc78e53SAndroid Build Coastguard Worker 	ae->ce_mask |= XFRM_AE_ATTR_MARK;
861*4dc78e53SAndroid Build Coastguard Worker 
862*4dc78e53SAndroid Build Coastguard Worker 	return 0;
863*4dc78e53SAndroid Build Coastguard Worker }
864*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_get_curlifetime(struct xfrmnl_ae * ae,unsigned long long int * curr_bytes,unsigned long long int * curr_packets,unsigned long long int * curr_add_time,unsigned long long int * curr_use_time)865*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_get_curlifetime (struct xfrmnl_ae* ae, unsigned long long int* curr_bytes,
866*4dc78e53SAndroid Build Coastguard Worker                                unsigned long long int* curr_packets, unsigned long long int* curr_add_time,
867*4dc78e53SAndroid Build Coastguard Worker                                unsigned long long int* curr_use_time)
868*4dc78e53SAndroid Build Coastguard Worker {
869*4dc78e53SAndroid Build Coastguard Worker 	if (curr_bytes == NULL || curr_packets == NULL || curr_add_time == NULL || curr_use_time == NULL)
870*4dc78e53SAndroid Build Coastguard Worker 		return -1;
871*4dc78e53SAndroid Build Coastguard Worker 
872*4dc78e53SAndroid Build Coastguard Worker 	if (ae->ce_mask & XFRM_AE_ATTR_LIFETIME)
873*4dc78e53SAndroid Build Coastguard Worker 	{
874*4dc78e53SAndroid Build Coastguard Worker 		*curr_bytes     =   ae->lifetime_cur.bytes;
875*4dc78e53SAndroid Build Coastguard Worker 		*curr_packets   =   ae->lifetime_cur.packets;
876*4dc78e53SAndroid Build Coastguard Worker 		*curr_add_time  =   ae->lifetime_cur.add_time;
877*4dc78e53SAndroid Build Coastguard Worker 		*curr_use_time  =   ae->lifetime_cur.use_time;
878*4dc78e53SAndroid Build Coastguard Worker 
879*4dc78e53SAndroid Build Coastguard Worker 		return 0;
880*4dc78e53SAndroid Build Coastguard Worker 	}
881*4dc78e53SAndroid Build Coastguard Worker 	else
882*4dc78e53SAndroid Build Coastguard Worker 		return -1;
883*4dc78e53SAndroid Build Coastguard Worker }
884*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_set_curlifetime(struct xfrmnl_ae * ae,unsigned long long int curr_bytes,unsigned long long int curr_packets,unsigned long long int curr_add_time,unsigned long long int curr_use_time)885*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_set_curlifetime (struct xfrmnl_ae* ae, unsigned long long int curr_bytes,
886*4dc78e53SAndroid Build Coastguard Worker                                unsigned long long int curr_packets, unsigned long long int curr_add_time,
887*4dc78e53SAndroid Build Coastguard Worker                                unsigned long long int curr_use_time)
888*4dc78e53SAndroid Build Coastguard Worker {
889*4dc78e53SAndroid Build Coastguard Worker 	ae->lifetime_cur.bytes = curr_bytes;
890*4dc78e53SAndroid Build Coastguard Worker 	ae->lifetime_cur.packets = curr_packets;
891*4dc78e53SAndroid Build Coastguard Worker 	ae->lifetime_cur.add_time = curr_add_time;
892*4dc78e53SAndroid Build Coastguard Worker 	ae->lifetime_cur.use_time = curr_use_time;
893*4dc78e53SAndroid Build Coastguard Worker 	ae->ce_mask |= XFRM_AE_ATTR_LIFETIME;
894*4dc78e53SAndroid Build Coastguard Worker 
895*4dc78e53SAndroid Build Coastguard Worker 	return 0;
896*4dc78e53SAndroid Build Coastguard Worker }
897*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_get_replay_maxage(struct xfrmnl_ae * ae)898*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_get_replay_maxage (struct xfrmnl_ae* ae)
899*4dc78e53SAndroid Build Coastguard Worker {
900*4dc78e53SAndroid Build Coastguard Worker 	if (ae->ce_mask & XFRM_AE_ATTR_REPLAY_MAXAGE)
901*4dc78e53SAndroid Build Coastguard Worker 		return ae->replay_maxage;
902*4dc78e53SAndroid Build Coastguard Worker 	else
903*4dc78e53SAndroid Build Coastguard Worker 		return -1;
904*4dc78e53SAndroid Build Coastguard Worker }
905*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_set_replay_maxage(struct xfrmnl_ae * ae,unsigned int replay_maxage)906*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_set_replay_maxage (struct xfrmnl_ae* ae, unsigned int replay_maxage)
907*4dc78e53SAndroid Build Coastguard Worker {
908*4dc78e53SAndroid Build Coastguard Worker 	ae->replay_maxage  = replay_maxage;
909*4dc78e53SAndroid Build Coastguard Worker 	ae->ce_mask |= XFRM_AE_ATTR_REPLAY_MAXAGE;
910*4dc78e53SAndroid Build Coastguard Worker 
911*4dc78e53SAndroid Build Coastguard Worker 	return 0;
912*4dc78e53SAndroid Build Coastguard Worker }
913*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_get_replay_maxdiff(struct xfrmnl_ae * ae)914*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_get_replay_maxdiff (struct xfrmnl_ae* ae)
915*4dc78e53SAndroid Build Coastguard Worker {
916*4dc78e53SAndroid Build Coastguard Worker 	if (ae->ce_mask & XFRM_AE_ATTR_REPLAY_MAXDIFF)
917*4dc78e53SAndroid Build Coastguard Worker 		return ae->replay_maxdiff;
918*4dc78e53SAndroid Build Coastguard Worker 	else
919*4dc78e53SAndroid Build Coastguard Worker 		return -1;
920*4dc78e53SAndroid Build Coastguard Worker }
921*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_set_replay_maxdiff(struct xfrmnl_ae * ae,unsigned int replay_maxdiff)922*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_set_replay_maxdiff (struct xfrmnl_ae* ae, unsigned int replay_maxdiff)
923*4dc78e53SAndroid Build Coastguard Worker {
924*4dc78e53SAndroid Build Coastguard Worker 	ae->replay_maxdiff  = replay_maxdiff;
925*4dc78e53SAndroid Build Coastguard Worker 	ae->ce_mask |= XFRM_AE_ATTR_REPLAY_MAXDIFF;
926*4dc78e53SAndroid Build Coastguard Worker 
927*4dc78e53SAndroid Build Coastguard Worker 	return 0;
928*4dc78e53SAndroid Build Coastguard Worker }
929*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_get_replay_state(struct xfrmnl_ae * ae,unsigned int * oseq,unsigned int * seq,unsigned int * bmp)930*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_get_replay_state (struct xfrmnl_ae* ae, unsigned int* oseq, unsigned int* seq, unsigned int* bmp)
931*4dc78e53SAndroid Build Coastguard Worker {
932*4dc78e53SAndroid Build Coastguard Worker 	if (ae->ce_mask & XFRM_AE_ATTR_REPLAY_STATE)
933*4dc78e53SAndroid Build Coastguard Worker 	{
934*4dc78e53SAndroid Build Coastguard Worker 		if (ae->replay_state_esn == NULL)
935*4dc78e53SAndroid Build Coastguard Worker 		{
936*4dc78e53SAndroid Build Coastguard Worker 			*oseq   =   ae->replay_state.oseq;
937*4dc78e53SAndroid Build Coastguard Worker 			*seq    =   ae->replay_state.seq;
938*4dc78e53SAndroid Build Coastguard Worker 			*bmp    =   ae->replay_state.bitmap;
939*4dc78e53SAndroid Build Coastguard Worker 
940*4dc78e53SAndroid Build Coastguard Worker 			return 0;
941*4dc78e53SAndroid Build Coastguard Worker 		}
942*4dc78e53SAndroid Build Coastguard Worker 		else
943*4dc78e53SAndroid Build Coastguard Worker 		{
944*4dc78e53SAndroid Build Coastguard Worker 			return -1;
945*4dc78e53SAndroid Build Coastguard Worker 		}
946*4dc78e53SAndroid Build Coastguard Worker 	}
947*4dc78e53SAndroid Build Coastguard Worker 	else
948*4dc78e53SAndroid Build Coastguard Worker 		return -1;
949*4dc78e53SAndroid Build Coastguard Worker }
950*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_set_replay_state(struct xfrmnl_ae * ae,unsigned int oseq,unsigned int seq,unsigned int bitmap)951*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_set_replay_state (struct xfrmnl_ae* ae, unsigned int oseq, unsigned int seq, unsigned int bitmap)
952*4dc78e53SAndroid Build Coastguard Worker {
953*4dc78e53SAndroid Build Coastguard Worker 	ae->replay_state.oseq = oseq;
954*4dc78e53SAndroid Build Coastguard Worker 	ae->replay_state.seq = seq;
955*4dc78e53SAndroid Build Coastguard Worker 	ae->replay_state.bitmap = bitmap;
956*4dc78e53SAndroid Build Coastguard Worker 	ae->ce_mask |= XFRM_AE_ATTR_REPLAY_STATE;
957*4dc78e53SAndroid Build Coastguard Worker 
958*4dc78e53SAndroid Build Coastguard Worker 	return 0;
959*4dc78e53SAndroid Build Coastguard Worker }
960*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_get_replay_state_esn(struct xfrmnl_ae * ae,unsigned int * oseq,unsigned int * seq,unsigned int * oseq_hi,unsigned int * seq_hi,unsigned int * replay_window,unsigned int * bmp_len,unsigned int * bmp)961*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_get_replay_state_esn(struct xfrmnl_ae* ae, unsigned int* oseq, unsigned int* seq, unsigned int* oseq_hi,
962*4dc78e53SAndroid Build Coastguard Worker                                    unsigned int* seq_hi, unsigned int* replay_window, unsigned int* bmp_len, unsigned int* bmp)
963*4dc78e53SAndroid Build Coastguard Worker {
964*4dc78e53SAndroid Build Coastguard Worker 	if (ae->ce_mask & XFRM_AE_ATTR_REPLAY_STATE)
965*4dc78e53SAndroid Build Coastguard Worker 	{
966*4dc78e53SAndroid Build Coastguard Worker 		if (ae->replay_state_esn)
967*4dc78e53SAndroid Build Coastguard Worker 		{
968*4dc78e53SAndroid Build Coastguard Worker 			*oseq   =   ae->replay_state_esn->oseq;
969*4dc78e53SAndroid Build Coastguard Worker 			*seq    =   ae->replay_state_esn->seq;
970*4dc78e53SAndroid Build Coastguard Worker 			*oseq_hi=   ae->replay_state_esn->oseq_hi;
971*4dc78e53SAndroid Build Coastguard Worker 			*seq_hi =   ae->replay_state_esn->seq_hi;
972*4dc78e53SAndroid Build Coastguard Worker 			*replay_window  =   ae->replay_state_esn->replay_window;
973*4dc78e53SAndroid Build Coastguard Worker 			*bmp_len        =   ae->replay_state_esn->bmp_len; // In number of 32 bit words
974*4dc78e53SAndroid Build Coastguard Worker 			memcpy (bmp, ae->replay_state_esn->bmp, ae->replay_state_esn->bmp_len * sizeof (uint32_t));
975*4dc78e53SAndroid Build Coastguard Worker 
976*4dc78e53SAndroid Build Coastguard Worker 			return 0;
977*4dc78e53SAndroid Build Coastguard Worker 		}
978*4dc78e53SAndroid Build Coastguard Worker 		else
979*4dc78e53SAndroid Build Coastguard Worker 		{
980*4dc78e53SAndroid Build Coastguard Worker 			return -1;
981*4dc78e53SAndroid Build Coastguard Worker 		}
982*4dc78e53SAndroid Build Coastguard Worker 	}
983*4dc78e53SAndroid Build Coastguard Worker 	else
984*4dc78e53SAndroid Build Coastguard Worker 		return -1;
985*4dc78e53SAndroid Build Coastguard Worker }
986*4dc78e53SAndroid Build Coastguard Worker 
xfrmnl_ae_set_replay_state_esn(struct xfrmnl_ae * ae,unsigned int oseq,unsigned int seq,unsigned int oseq_hi,unsigned int seq_hi,unsigned int replay_window,unsigned int bmp_len,unsigned int * bmp)987*4dc78e53SAndroid Build Coastguard Worker int xfrmnl_ae_set_replay_state_esn(struct xfrmnl_ae* ae, unsigned int oseq, unsigned int seq,
988*4dc78e53SAndroid Build Coastguard Worker                                    unsigned int oseq_hi, unsigned int seq_hi, unsigned int replay_window,
989*4dc78e53SAndroid Build Coastguard Worker                                    unsigned int bmp_len, unsigned int* bmp)
990*4dc78e53SAndroid Build Coastguard Worker {
991*4dc78e53SAndroid Build Coastguard Worker 	/* Free the old replay ESN state and allocate new one */
992*4dc78e53SAndroid Build Coastguard Worker 	if (ae->replay_state_esn)
993*4dc78e53SAndroid Build Coastguard Worker 		free (ae->replay_state_esn);
994*4dc78e53SAndroid Build Coastguard Worker 
995*4dc78e53SAndroid Build Coastguard Worker 	if ((ae->replay_state_esn = calloc (1, sizeof (struct xfrmnl_replay_state_esn) + sizeof (uint32_t) * bmp_len)) == NULL)
996*4dc78e53SAndroid Build Coastguard Worker 		return -1;
997*4dc78e53SAndroid Build Coastguard Worker 
998*4dc78e53SAndroid Build Coastguard Worker 	ae->replay_state_esn->oseq = oseq;
999*4dc78e53SAndroid Build Coastguard Worker 	ae->replay_state_esn->seq = seq;
1000*4dc78e53SAndroid Build Coastguard Worker 	ae->replay_state_esn->oseq_hi = oseq_hi;
1001*4dc78e53SAndroid Build Coastguard Worker 	ae->replay_state_esn->seq_hi = seq_hi;
1002*4dc78e53SAndroid Build Coastguard Worker 	ae->replay_state_esn->replay_window = replay_window;
1003*4dc78e53SAndroid Build Coastguard Worker 	ae->replay_state_esn->bmp_len = bmp_len; // In number of 32 bit words
1004*4dc78e53SAndroid Build Coastguard Worker 	memcpy (ae->replay_state_esn->bmp, bmp, bmp_len * sizeof (uint32_t));
1005*4dc78e53SAndroid Build Coastguard Worker 	ae->ce_mask |= XFRM_AE_ATTR_REPLAY_STATE;
1006*4dc78e53SAndroid Build Coastguard Worker 
1007*4dc78e53SAndroid Build Coastguard Worker 	return 0;
1008*4dc78e53SAndroid Build Coastguard Worker }
1009*4dc78e53SAndroid Build Coastguard Worker 
1010*4dc78e53SAndroid Build Coastguard Worker /** @} */
1011*4dc78e53SAndroid Build Coastguard Worker 
1012*4dc78e53SAndroid Build Coastguard Worker static struct nl_object_ops xfrm_ae_obj_ops = {
1013*4dc78e53SAndroid Build Coastguard Worker 	.oo_name        =   "xfrm/ae",
1014*4dc78e53SAndroid Build Coastguard Worker 	.oo_size        =   sizeof(struct xfrmnl_ae),
1015*4dc78e53SAndroid Build Coastguard Worker 	.oo_free_data   =   xfrm_ae_free_data,
1016*4dc78e53SAndroid Build Coastguard Worker 	.oo_clone       =   xfrm_ae_clone,
1017*4dc78e53SAndroid Build Coastguard Worker 	.oo_dump        =   {
1018*4dc78e53SAndroid Build Coastguard Worker 	                        [NL_DUMP_LINE]      =   xfrm_ae_dump_line,
1019*4dc78e53SAndroid Build Coastguard Worker 	                        [NL_DUMP_DETAILS]   =   xfrm_ae_dump_details,
1020*4dc78e53SAndroid Build Coastguard Worker 	                        [NL_DUMP_STATS]     =   xfrm_ae_dump_stats,
1021*4dc78e53SAndroid Build Coastguard Worker 	                    },
1022*4dc78e53SAndroid Build Coastguard Worker 	.oo_compare     =   xfrm_ae_compare,
1023*4dc78e53SAndroid Build Coastguard Worker 	.oo_attrs2str   =   xfrm_ae_attrs2str,
1024*4dc78e53SAndroid Build Coastguard Worker 	.oo_id_attrs    =   (XFRM_AE_ATTR_DADDR | XFRM_AE_ATTR_SPI | XFRM_AE_ATTR_PROTO),
1025*4dc78e53SAndroid Build Coastguard Worker };
1026*4dc78e53SAndroid Build Coastguard Worker 
1027*4dc78e53SAndroid Build Coastguard Worker /** @} */
1028*4dc78e53SAndroid Build Coastguard Worker 
1029