1/*
2 **************************************************************************
3 * Copyright (c) 2014,2015, The Linux Foundation. All rights reserved.
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all copies.
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 **************************************************************************
15 */
16
17/*
18 * nss_ipsec.h
19 *	NSS to HLOS IPSec interface definitions.
20 */
21
22#ifndef __NSS_IPSEC_H
23#define __NSS_IPSEC_H
24
25/*
26 * For some reason Linux doesn't define this in if_arp.h,
27 * refer http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml
28 * for the full list
29 */
30#define NSS_IPSEC_ARPHRD_IPSEC 31	/**< iana.org ARP Hardware type for IPsec tunnel*/
31#define NSS_IPSEC_MAX_RULES 256 	/**< maximum rules supported */
32#define NSS_IPSEC_MAX_SA NSS_CRYPTO_MAX_IDXS /**< maximum SAs supported */
33
34#if (~(NSS_IPSEC_MAX_RULES - 1) & (NSS_IPSEC_MAX_RULES >> 1))
35#error "NSS Max SA should be a power of 2"
36#endif
37
38#define NSS_IPSEC_MSG_LEN (sizeof(struct nss_ipsec_msg) - sizeof(struct nss_cmn_msg))
39
40/*
41 * @brief IPsec rule types
42 */
43enum nss_ipsec_msg_type {
44	NSS_IPSEC_MSG_TYPE_NONE = 0,		/**< nothing to do */
45	NSS_IPSEC_MSG_TYPE_ADD_RULE = 1,	/**< add rule to the table */
46	NSS_IPSEC_MSG_TYPE_DEL_RULE = 2,	/**< delete rule from the table */
47	NSS_IPSEC_MSG_TYPE_SYNC_STATS = 3,	/**< stats sync message */
48	NSS_IPSEC_MSG_TYPE_FLUSH_TUN = 4,	/**< delete all SA(s) for a tunnel */
49	NSS_IPSEC_MSG_TYPE_MAX
50};
51
52/**
53 * @brief NSS IPsec status
54 */
55typedef enum nss_ipsec_status {
56	NSS_IPSEC_STATUS_OK = 0,
57	NSS_IPSEC_STATUS_ENOMEM = 1,
58	NSS_IPSEC_STATUS_ENOENT = 2,
59	NSS_IPSEC_STATUS_MAX
60} nss_ipsec_status_t;
61
62/*
63 * @brief IPsec rule selector tuple for encap & decap
64 *
65 * @note This is a common selector which is used for preparing
66 * a lookup tuple for incoming packets. The tuple is used
67 * for deriving the index into the rule table. Choosing the
68 * selector fields is dependent upon IPsec encap or
69 * decap package itself. Host has zero understanding of
70 * these index derivation from the selector fields and
71 * hence provides information for all entries in the structure.
72 * The packages {Encap or Decap} returns the index into their
73 * respective tables to the Host for storing the rule which can
74 * be referenced by host in future
75 */
76struct nss_ipsec_rule_sel {
77	uint32_t ipv4_dst;	/**< IPv4 destination to use */
78	uint32_t ipv4_src;	/**< IPv4 source to use */
79	uint32_t esp_spi;	/**< SPI index */
80
81	uint16_t dst_port;	/**< destination port (UDP or TCP) */
82	uint16_t src_port;	/**< source port (UDP or TCP) */
83
84	uint8_t ipv4_proto;	/**< IPv4 protocol types */
85	uint8_t res[3];
86};
87
88/**
89 * @brief IPsec rule outer IP header info to be applied for encapsulation
90 */
91struct nss_ipsec_rule_oip {
92	uint32_t ipv4_dst;		/**< IPv4 destination address to apply */
93	uint32_t ipv4_src;		/**< IPv4 source address to apply */
94	uint32_t esp_spi;		/**< ESP SPI index to apply */
95
96	uint8_t ipv4_ttl;		/**< IPv4 Time-to-Live value to apply */
97	uint8_t res[3];			/**< reserve for 4-byte alignment */
98};
99
100/**
101 * @brief IPsec rule data to be used for per packet transformation
102 */
103struct nss_ipsec_rule_data {
104
105	uint16_t crypto_index;		/**< crypto index for the SA */
106	uint16_t window_size;		/**< ESP sequence number window */
107
108	uint8_t cipher_algo;		/**< Cipher algorithm */
109	uint8_t auth_algo;		/**< Authentication algorithm */
110	uint8_t nat_t_req;		/**< NAT-T required */
111	uint8_t esp_icv_len;		/**< ESP trailers ICV length to apply */
112
113	uint8_t esp_seq_skip;		/**< Skip ESP sequence number */
114	uint8_t esp_tail_skip;		/**< Skip ESP trailer */
115	uint8_t use_pattern;		/**< Use random pattern in hash calculation */
116	uint8_t res;			/**< Reserve bytes for alignment */
117};
118
119/*
120 * @brief IPsec rule push message, sent from Host --> NSS for
121 * 	  performing a operation on NSS rule tables
122 */
123struct nss_ipsec_rule {
124	struct nss_ipsec_rule_sel sel;		/**< rule selector */
125	struct nss_ipsec_rule_oip oip;		/**< per rule outer IP info */
126	struct nss_ipsec_rule_data data;	/**< per rule data */
127
128	uint32_t rule_idx;			/**< rule index provided by NSS */
129	uint32_t sa_idx;			/**< index into SA table */
130};
131
132/**
133 * @brief Packet stats for individual SA
134 */
135struct nss_ipsec_pkt_stats {
136	uint32_t processed;			/**< packets processed */
137	uint32_t dropped;			/**< packets dropped */
138	uint32_t failed;			/**< processing failed */
139};
140
141/**
142 * @brief NSS IPsec per SA statistics
143 */
144struct nss_ipsec_sa_stats {
145	uint32_t seqnum;			/**< SA sequence number */
146	uint32_t sa_idx;			/**< index into SA table */
147	struct nss_ipsec_pkt_stats pkts;	/**< packet statistics */
148};
149
150/*
151 * @brief Message structure to send/receive ipsec messages
152 */
153struct nss_ipsec_msg {
154	struct nss_cmn_msg cm;				/**< Message Header */
155
156	uint32_t tunnel_id;				/**< tunnel index associated with the message */
157	union {
158		struct nss_ipsec_rule push;		/**< Message: IPsec rule */
159		struct nss_ipsec_sa_stats stats;	/**< Message: Retreive stats for tunnel */
160	} msg;
161};
162
163/**
164 * @brief Message notification callback
165 *
166 * @param app_data[IN] context of the callback user
167 * @param msg[IN] notification event data
168 *
169 * @return
170 */
171typedef void (*nss_ipsec_msg_callback_t)(void *app_data, struct nss_ipsec_msg *msg);
172
173/**
174 * @brief data callback
175 *
176 * @param app_data[IN] context of the callback user
177 * @param skb[IN] data buffer
178 *
179 * @return
180 */
181typedef void (*nss_ipsec_buf_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi);
182
183/**
184 * @brief send an IPsec message
185 *
186 * @param nss_ctx[IN] NSS HLOS driver's context
187 * @param msg[IN] control message
188 *
189 * @return
190 */
191extern nss_tx_status_t nss_ipsec_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ipsec_msg *msg);
192
193/**
194 * @brief send an IPsec process request
195 *
196 * @param skb Data buffer
197 * @param if_num NSS interface number
198 *
199 * @return Status
200 */
201extern nss_tx_status_t nss_ipsec_tx_buf(struct sk_buff *skb, uint32_t if_num);
202
203/**
204 * @brief register a event callback handler with HLOS driver
205 *
206 * @param if_num[IN] receive events from this interface (Encap, Decap or C2C)
207 * @param cb[IN] event callback function
208 * @param app_data[IN] context of the callback user
209 *
210 * @return
211 */
212extern struct nss_ctx_instance *nss_ipsec_notify_register(uint32_t if_num, nss_ipsec_msg_callback_t cb, void *app_data);
213
214/**
215 * @brief register a data callback handler with HLOS driver
216 *
217 * @param if_num[IN] receive data from this interface (Encap, Decap or C2C)
218 * @param cb[IN] data callback function
219 * @param netdev associated netdevice.
220 * @param features denote the skb types supported by this interface.
221 *
222 * @return
223 */
224extern struct nss_ctx_instance *nss_ipsec_data_register(uint32_t if_num, nss_ipsec_buf_callback_t cb, struct net_device *netdev, uint32_t features);
225
226/**
227 * @brief unregister the message notifier
228 *
229 * @param ctx[IN] HLOS driver's context
230 * @param if_num[IN] interface number to unregister from
231 *
232 * @return
233 */
234extern void nss_ipsec_notify_unregister(struct nss_ctx_instance *ctx, uint32_t if_num);
235
236/**
237 * @brief unregister the data notifier
238 *
239 * @param ctx[IN] HLOS driver's context
240 * @param if_num[IN] interface number to unregister from
241 *
242 * @return
243 */
244extern void nss_ipsec_data_unregister(struct nss_ctx_instance *ctx, uint32_t if_num);
245
246/**
247 * @brief get the NSS context for the IPsec handle
248 *
249 * @return nss_ctx_instance
250 */
251extern struct nss_ctx_instance *nss_ipsec_get_context(void);
252
253/**
254 * @brief Initialize ipsec message
255 *
256 * @return void
257 */
258extern void nss_ipsec_msg_init(struct nss_ipsec_msg *nim, uint16_t if_num, uint32_t type, uint32_t len,
259				nss_ipsec_msg_callback_t cb, void *app_data);
260
261/*
262 * @brief get the NSS interface number to be used for IPsec requests
263 *
264 * @param ctx[IN] HLOS driver's context
265 *
266 * @return interface number
267 */
268extern int32_t nss_ipsec_get_interface(struct nss_ctx_instance *ctx);
269#endif /* __NSS_IPSEC_H */
270