blob: 40f29aa21ca852c48b549106e1081a958c4d221f [file] [log] [blame]
Xiaoping Fand44a5b42015-05-26 17:37:37 -07001/*
Ratheesh Kannoth24fb1db2021-10-20 07:28:06 +05302 * sfe.h
Xiaoping Fand44a5b42015-05-26 17:37:37 -07003 * Shortcut forwarding engine.
4 *
Ratheesh Kannoth24fb1db2021-10-20 07:28:06 +05305 * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
Guduri Prathyusha5f27e232022-01-06 14:39:04 +05306 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
Ratheesh Kannoth24fb1db2021-10-20 07:28:06 +05307 *
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
Xiaoping Fana42c68b2015-08-07 18:00:39 -070012 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
Ratheesh Kannoth24fb1db2021-10-20 07:28:06 +053017 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Xiaoping Fand44a5b42015-05-26 17:37:37 -070019 */
20
Ratheesh Kannoth7a6a4ae2021-10-20 08:24:05 +053021#ifndef __SFE_H
22#define __SFE_H
23
24/*
25 * Maximum number of accelerated IPv4 or IPv6 connections
26 */
27#if defined(SFE_MEM_PROFILE_LOW)
28#define SFE_MAX_CONNECTION_NUM 512
29#elif defined(SFE_MEM_PROFILE_MEDIUM)
30#define SFE_MAX_CONNECTION_NUM 2048
31#else
32#define SFE_MAX_CONNECTION_NUM 4096
33#endif
34
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +053035#define SFE_L2_PARSE_FLAGS_PPPOE_INGRESS 0x01 /* Indicates presence of a valid PPPoE header */
36
Parikshit Guned31a8202022-01-05 22:15:04 +053037/**
38 * SAWF_metadata information placement in mark field.
39 */
40#define SFE_SAWF_VALID_TAG 0xAA
41#define SFE_SAWF_TAG_SHIFT 0x18
42#define SFE_SAWF_SERVICE_CLASS_SHIFT 0x10
43#define SFE_SAWF_SERVICE_CLASS_MASK 0xff
44#define SFE_SAWF_MSDUQ_MASK 0xffff
45
46/**
47 * SAWF_metadata extraction.
48 */
49#define SFE_GET_SAWF_TAG(x) (x>>SFE_SAWF_TAG_SHIFT)
50#define SFE_GET_SAWF_SERVICE_CLASS(x) ((x>>SFE_SAWF_SERVICE_CLASS_SHIFT) & SFE_SAWF_SERVICE_CLASS_MASK)
51#define SFE_GET_SAWF_MSDUQ(x) (x & SFE_SAWF_MSDUQ_MASK)
52#define SFE_SAWF_TAG_IS_VALID(x) ((x == SFE_SAWF_VALID_TAG) ? true : false)
53
Xiaoping Fand44a5b42015-05-26 17:37:37 -070054/*
Xiaoping Fand44a5b42015-05-26 17:37:37 -070055 * IPv6 address structure
56 */
57struct sfe_ipv6_addr {
58 __be32 addr[4];
59};
60
61typedef union {
62 __be32 ip;
63 struct sfe_ipv6_addr ip6[1];
64} sfe_ip_addr_t;
65
Xiaoping Fan99cb4c12015-08-21 19:07:32 -070066typedef enum sfe_sync_reason {
67 SFE_SYNC_REASON_STATS, /* Sync is to synchronize stats */
68 SFE_SYNC_REASON_FLUSH, /* Sync is to flush a entry */
69 SFE_SYNC_REASON_DESTROY /* Sync is to destroy a entry(requested by connection manager) */
70} sfe_sync_reason_t;
71
Xiaoping Fand44a5b42015-05-26 17:37:37 -070072/*
Wayne Tanbb7f1782021-12-13 11:16:04 -080073 * VLAN header (aka VLAN tag)
74 */
75struct sfe_vlan_hdr {
76 u16 tpid; /* Tag Protocol Identifier */
77 u16 tci; /* Tag Control Information */
78};
79
80/*
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +053081 * Structure used to store L2 information
82 */
83struct sfe_l2_info {
84 u16 parse_flags; /* Flags indicating L2.5 headers presence */
Nitin Shetty9af87d42022-02-11 16:25:29 +053085 u16 pppoe_session_id; /* PPPOE header offset */
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +053086 u16 protocol; /* L3 Protocol */
Wayne Tanbb7f1782021-12-13 11:16:04 -080087 struct sfe_vlan_hdr vlan_hdr[SFE_MAX_VLAN_DEPTH];
88 /* VLAN tag(s) of ingress packet */
89 u8 vlan_hdr_cnt; /* Number of VLAN tags in the ingress packet */
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +053090};
91
92/*
Xiaoping Fand44a5b42015-05-26 17:37:37 -070093 * Structure used to sync connection stats/state back within the system.
94 *
95 * NOTE: The addresses here are NON-NAT addresses, i.e. the true endpoint addressing.
96 * 'src' is the creator of the connection.
97 */
98struct sfe_connection_sync {
99 struct net_device *src_dev;
100 struct net_device *dest_dev;
101 int is_v6; /* Is it for ipv6? */
102 int protocol; /* IP protocol number (IPPROTO_...) */
103 sfe_ip_addr_t src_ip; /* Non-NAT source address, i.e. the creator of the connection */
Xiaoping Fan99cb4c12015-08-21 19:07:32 -0700104 sfe_ip_addr_t src_ip_xlate; /* NATed source address */
Xiaoping Fand44a5b42015-05-26 17:37:37 -0700105 __be16 src_port; /* Non-NAT source port */
Xiaoping Fan99cb4c12015-08-21 19:07:32 -0700106 __be16 src_port_xlate; /* NATed source port */
107 sfe_ip_addr_t dest_ip; /* Non-NAT destination address, i.e. to whom the connection was created */
108 sfe_ip_addr_t dest_ip_xlate; /* NATed destination address */
Xiaoping Fand44a5b42015-05-26 17:37:37 -0700109 __be16 dest_port; /* Non-NAT destination port */
Xiaoping Fan99cb4c12015-08-21 19:07:32 -0700110 __be16 dest_port_xlate; /* NATed destination port */
Xiaoping Fan6a1672f2016-08-17 19:58:12 -0700111 u32 src_td_max_window;
112 u32 src_td_end;
113 u32 src_td_max_end;
114 u64 src_packet_count;
115 u64 src_byte_count;
116 u32 src_new_packet_count;
117 u32 src_new_byte_count;
118 u32 dest_td_max_window;
119 u32 dest_td_end;
120 u32 dest_td_max_end;
121 u64 dest_packet_count;
122 u64 dest_byte_count;
123 u32 dest_new_packet_count;
124 u32 dest_new_byte_count;
Wayne Tanbb7f1782021-12-13 11:16:04 -0800125 u32 reason; /* reason for stats sync message, i.e. destroy, flush, period sync */
Xiaoping Fan6a1672f2016-08-17 19:58:12 -0700126 u64 delta_jiffies; /* Time to be added to the current timeout to keep the connection alive */
Xiaoping Fand44a5b42015-05-26 17:37:37 -0700127};
128
129/*
130 * connection mark structure
131 */
132struct sfe_connection_mark {
133 int protocol;
134 sfe_ip_addr_t src_ip;
135 sfe_ip_addr_t dest_ip;
136 __be16 src_port;
137 __be16 dest_port;
Xiaoping Fan6a1672f2016-08-17 19:58:12 -0700138 u32 mark;
Xiaoping Fand44a5b42015-05-26 17:37:37 -0700139};
140
141/*
Xiaoping Fan6a1672f2016-08-17 19:58:12 -0700142 * Expose the hook for the receive processing.
143 */
144extern int (*athrs_fast_nat_recv)(struct sk_buff *skb);
145
146/*
147 * Expose what should be a static flag in the TCP connection tracker.
148 */
149extern int nf_ct_tcp_no_window_check;
150
151/*
Ken Zhu7e38d1a2021-11-30 17:31:46 -0800152 * Check the fast transmit feasibility.
153 */
154bool sfe_fast_xmit_check(struct sk_buff *skb, netdev_features_t features);
155
156/*
Xiaoping Fan6a1672f2016-08-17 19:58:12 -0700157 * This callback will be called in a timer
158 * at 100 times per second to sync stats back to
159 * Linux connection track.
160 *
161 * A RCU lock is taken to prevent this callback
162 * from unregistering.
Xiaoping Fand44a5b42015-05-26 17:37:37 -0700163 */
164typedef void (*sfe_sync_rule_callback_t)(struct sfe_connection_sync *);
Ken Zhu7a43d882022-01-04 10:51:44 -0800165typedef void (*sfe_ipv4_many_sync_callback_t)(struct sfe_ipv4_msg *msg);
166typedef void (*sfe_ipv6_many_sync_callback_t)(struct sfe_ipv6_msg *msg);
Xiaoping Fand44a5b42015-05-26 17:37:37 -0700167
168/*
169 * IPv4 APIs used by connection manager
170 */
Amitesh Anand63be37d2021-12-24 20:51:48 +0530171int sfe_ipv4_recv(struct net_device *dev, struct sk_buff *skb, struct sfe_l2_info *l2_info, bool tun_outer);
Ratheesh Kannoth89302a72021-10-20 08:10:37 +0530172int sfe_ipv4_create_rule(struct sfe_ipv4_rule_create_msg *msg);
173void sfe_ipv4_destroy_rule(struct sfe_ipv4_rule_destroy_msg *msg);
Xiaoping Fan6a1672f2016-08-17 19:58:12 -0700174void sfe_ipv4_destroy_all_rules_for_dev(struct net_device *dev);
175void sfe_ipv4_register_sync_rule_callback(sfe_sync_rule_callback_t callback);
Ratheesh Kannoth89302a72021-10-20 08:10:37 +0530176void sfe_ipv4_update_rule(struct sfe_ipv4_rule_create_msg *msg);
Nitin Shettye6ed5b52021-12-27 14:50:11 +0530177bool sfe_dev_has_hw_csum(struct net_device *dev);
Xiaoping Fan978b3772015-05-27 14:15:18 -0700178
Ken Zhu7a43d882022-01-04 10:51:44 -0800179bool sfe_ipv4_sync_invoke(uint16_t index);
180void sfe_ipv4_register_many_sync_callback(sfe_ipv4_many_sync_callback_t cb);
181void sfe_ipv4_stats_convert(struct sfe_ipv4_conn_sync *sync_msg, struct sfe_connection_sync *sis);
Xiaoping Fan978b3772015-05-27 14:15:18 -0700182#ifdef SFE_SUPPORT_IPV6
183/*
184 * IPv6 APIs used by connection manager
185 */
Suruchi Suman23a279d2021-11-16 15:13:09 +0530186int sfe_ipv6_recv(struct net_device *dev, struct sk_buff *skb, struct sfe_l2_info *l2_info, bool tun_outer);
Ratheesh Kannoth89302a72021-10-20 08:10:37 +0530187int sfe_ipv6_create_rule(struct sfe_ipv6_rule_create_msg *msg);
188void sfe_ipv6_destroy_rule(struct sfe_ipv6_rule_destroy_msg *msg);
Xiaoping Fan6a1672f2016-08-17 19:58:12 -0700189void sfe_ipv6_destroy_all_rules_for_dev(struct net_device *dev);
190void sfe_ipv6_register_sync_rule_callback(sfe_sync_rule_callback_t callback);
Ratheesh Kannoth89302a72021-10-20 08:10:37 +0530191void sfe_ipv6_update_rule(struct sfe_ipv6_rule_create_msg *msg);
Ken Zhu7a43d882022-01-04 10:51:44 -0800192bool sfe_ipv6_sync_invoke(uint16_t index);
193void sfe_ipv6_register_many_sync_callback(sfe_ipv6_many_sync_callback_t cb);
194void sfe_ipv6_stats_convert(struct sfe_ipv6_conn_sync *sync_msg, struct sfe_connection_sync *sis);
Xiaoping Fan978b3772015-05-27 14:15:18 -0700195#else
Suruchi Suman23a279d2021-11-16 15:13:09 +0530196static inline int sfe_ipv6_recv(struct net_device *dev, struct sk_buff *skb, struct sfe_l2_info *l2_info, bool tun_outer)
Xiaoping Fan978b3772015-05-27 14:15:18 -0700197{
198 return 0;
199}
200
Ratheesh Kannoth89302a72021-10-20 08:10:37 +0530201static inline int sfe_ipv6_create_rule(struct sfe_ipv6_rule_create_msg *msg)
Xiaoping Fan978b3772015-05-27 14:15:18 -0700202{
Xiaoping Fan6a1672f2016-08-17 19:58:12 -0700203 return 0;
Xiaoping Fan978b3772015-05-27 14:15:18 -0700204}
205
Suruchi Suman23a279d2021-11-16 15:13:09 +0530206static inline void sfe_ipv6_destroy_rule(struct sfe_ipv6_rule_destroy_msg *msg)
Xiaoping Fan978b3772015-05-27 14:15:18 -0700207{
208 return;
209}
210
211static inline void sfe_ipv6_destroy_all_rules_for_dev(struct net_device *dev)
212{
213 return;
214}
215
216static inline void sfe_ipv6_register_sync_rule_callback(sfe_sync_rule_callback_t callback)
217{
218 return;
219}
220
Ratheesh Kannoth89302a72021-10-20 08:10:37 +0530221static inline void sfe_ipv6_update_rule(struct sfe_ipv6_rule_create_msg *msg)
Xiaoping Fan978b3772015-05-27 14:15:18 -0700222{
223 return;
224}
225
Ken Zhu7a43d882022-01-04 10:51:44 -0800226static inline bool sfe_ipv6_sync_invoke(uint16_t index)
227{
228 return false;
229}
230
231static inline void sfe_ipv6_register_many_sync_callback(sfe_ipv6_many_sync_callback_t cb)
232{
233 return;
234}
235
236static inline void sfe_ipv6_stats_convert(struct sfe_ipv6_conn_sync *sync_msg, struct sfe_connection_sync *sis)
237{
238 return;
239}
Xiaoping Fan978b3772015-05-27 14:15:18 -0700240#endif
Xiaoping Fan9b6bb332016-04-05 19:21:26 -0700241
242/*
243 * sfe_ipv6_addr_equal()
244 * compare ipv6 address
245 *
246 * return: 1, equal; 0, no equal
247 */
248static inline int sfe_ipv6_addr_equal(struct sfe_ipv6_addr *a,
249 struct sfe_ipv6_addr *b)
250{
251 return a->addr[0] == b->addr[0] &&
252 a->addr[1] == b->addr[1] &&
253 a->addr[2] == b->addr[2] &&
254 a->addr[3] == b->addr[3];
255}
256
257/*
258 * sfe_ipv4_addr_equal()
259 * compare ipv4 address
260 *
261 * return: 1, equal; 0, no equal
262 */
Xiaoping Fan6a1672f2016-08-17 19:58:12 -0700263#define sfe_ipv4_addr_equal(a, b) ((u32)(a) == (u32)(b))
Xiaoping Fan9b6bb332016-04-05 19:21:26 -0700264
265/*
266 * sfe_addr_equal()
267 * compare ipv4 or ipv6 address
268 *
269 * return: 1, equal; 0, no equal
270 */
271static inline int sfe_addr_equal(sfe_ip_addr_t *a,
272 sfe_ip_addr_t *b, int is_v4)
273{
274 return is_v4 ? sfe_ipv4_addr_equal(a->ip, b->ip) : sfe_ipv6_addr_equal(a->ip6, b->ip6);
275}
Ratheesh Kannoth24fb1db2021-10-20 07:28:06 +0530276
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +0530277/*
278 * sfe_l2_parse_flag_set()
279 * Set L2 parse flag
280 */
Guduri Prathyusha5f27e232022-01-06 14:39:04 +0530281static inline void sfe_l2_parse_flag_set(struct sfe_l2_info *l2_info, u16 flag)
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +0530282{
283 l2_info->parse_flags |= flag;
284}
285
286/*
287 * sfe_l2_parse_flag_get()
288 * Get L2 parse flag
289 */
Guduri Prathyusha5f27e232022-01-06 14:39:04 +0530290static inline u16 sfe_l2_parse_flag_get(struct sfe_l2_info *l2_info)
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +0530291{
292 return l2_info->parse_flags;
293}
294
295/*
296 * sfe_l2_parse_flag_check()
297 * Check L2 parse flag
298 */
Guduri Prathyusha5f27e232022-01-06 14:39:04 +0530299static inline bool sfe_l2_parse_flag_check(struct sfe_l2_info *l2_info, u16 flag)
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +0530300{
Guduri Prathyusha5f27e232022-01-06 14:39:04 +0530301 return !!(l2_info->parse_flags & flag);
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +0530302}
303
304/*
Nitin Shetty9af87d42022-02-11 16:25:29 +0530305 * sfe_l2_pppoe_session_id_get()
306 * Get PPPPoE session ID from l2_info
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +0530307 */
Nitin Shetty9af87d42022-02-11 16:25:29 +0530308static inline u16 sfe_l2_pppoe_session_id_get(struct sfe_l2_info *l2_info)
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +0530309{
Nitin Shetty9af87d42022-02-11 16:25:29 +0530310 return l2_info->pppoe_session_id;
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +0530311}
312
313/*
Nitin Shetty9af87d42022-02-11 16:25:29 +0530314 * sfe_l2_pppoe_session_id_set()
315 * Set PPPoE session ID to l2_info
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +0530316 */
Nitin Shetty9af87d42022-02-11 16:25:29 +0530317static inline void sfe_l2_pppoe_session_id_set(struct sfe_l2_info *l2_info, u16 session_id)
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +0530318{
Nitin Shetty9af87d42022-02-11 16:25:29 +0530319 l2_info->pppoe_session_id = session_id;
Guduri Prathyusha647fe3e2021-11-22 19:17:51 +0530320}
321
322/*
323 * sfe_l2_protocol_get()
324 * Get L2 protocol
325 */
326static inline u16 sfe_l2_protocol_get(struct sfe_l2_info *l2_info)
327{
328 return l2_info->protocol;
329}
330
331/*
332 * sfe_l2_protocol_set()
333 * Set L2 protocol
334 */
335static inline void sfe_l2_protocol_set(struct sfe_l2_info *l2_info, u16 proto)
336{
337 l2_info->protocol = proto;
338}
339
Ratheesh Kannoth24fb1db2021-10-20 07:28:06 +0530340int sfe_init_if(void);
341void sfe_exit_if(void);
Ratheesh Kannoth7a6a4ae2021-10-20 08:24:05 +0530342
343#endif /* __SFE_H */