blob: 5c6850c8cfb832c1dfa71c88af5e86304a8fada4 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/**
2 *
3 * (C) Copyright 2009-2016 Marvell International Ltd. All Rights Reserved
4 *
5 * MARVELL CONFIDENTIAL
6 * The source code contained or described herein and all documents related to
7 * the source code ("Material") are owned by Marvell International Ltd or its
8 * suppliers or licensors. Title to the Material remains with Marvell
9 * International Ltd or its suppliers and licensors. The Material contains
10 * trade secrets and proprietary and confidential information of Marvell or its
11 * suppliers and licensors. The Material is protected by worldwide copyright
12 * and trade secret laws and treaty provisions. No part of the Material may be
13 * used, copied, reproduced, modified, published, uploaded, posted,
14 * transmitted, distributed, or disclosed in any way without Marvell's prior
15 * express written permission.
16 *
17 * No license under any patent, copyright, trade secret or other intellectual
18 * property right is granted to or conferred upon you by disclosure or delivery
19 * of the Materials, either expressly, by implication, inducement, estoppel or
20 * otherwise. Any license under such intellectual property rights must be
21 * express and approved by Marvell in writing.
22 *
23 */
24
25#ifndef FP_COMMON_H
26#define FP_COMMON_H
27
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/version.h>
31
32#include <linux/netdevice.h>
33#include <linux/etherdevice.h>
34#include <linux/ip.h>
35#include <linux/ipv6.h>
36#include <linux/udp.h>
37#include <linux/tcp.h>
38#include <linux/proc_fs.h>
39
40#include <net/netfilter/nf_conntrack.h>
41#include <net/netfilter/nf_conntrack_core.h>
42#include <net/netfilter/nf_conntrack_helper.h>
43#include <net/netfilter/nf_conntrack_ecache.h>
44#include <net/netfilter/nf_conntrack_l4proto.h>
45#include <linux/netfilter/nfnetlink.h>
46#include <linux/netfilter/nfnetlink_conntrack.h>
47#include <net/netfilter/nf_conntrack_zones.h>
48#include <linux/netfilter_ipv4.h>
49#include <linux/netfilter_ipv6.h>
50#include <linux/notifier.h>
51#include <net/netevent.h>
52#include <net/sock.h>
53#include <net/arp.h>
54#include <net/genetlink.h>
55#include <linux/if_arp.h>
56#include <net/ip_fib.h>
57#include <net/ip6_route.h>
58#include <net/ipv6.h>
59#include <net/ip.h>
60
61#include <asm/cacheflush.h>
62#include <linux/timer.h>
63
64
65#define FP_NO_DEBUG_LVL (0)
66#define FP_FATAL_LVL (1)
67#define FP_ERR_LVL (2)
68#define FP_WARNING_LVL (3)
69#define FP_INFO_LVL (4)
70#define FP_DEBUG_LVL (5)
71
72/* Set fastpath debug level */
73#if !defined(FP_DEBUG_LEVEL)
74#define FP_DEBUG_LEVEL (FP_ERR_LVL)
75#endif
76#define MAX_DEBUG_PRINT_SIZE (1000)
77
78/* runtime debug levels */
79enum {
80 /* Warnings as Errors */
81 DBG_WARN_AS_ERR_BIT = 0,
82 DBG_WARN_AS_ERR = (1 << DBG_WARN_AS_ERR_BIT),
83 /* Entry Debug Info */
84 DBG_INFO_BIT = 1,
85 DBG_INFO = (1 << DBG_INFO_BIT),
86 /* Entry Extra Debug Info (for future use) */
87 DBG_INFO_EXT_BIT = 2,
88 DBG_INFO_EXT = (1 << DBG_INFO_EXT_BIT),
89 /* Entry Trace Logging (may impact performance) */
90 DBG_TRACE_LOG_BIT = 3,
91 DBG_TRACE_LOG = (1 << DBG_TRACE_LOG_BIT),
92
93 DBG_LEVEL_END_BIT = 4,
94 DBG_LEVEL_END = (1 << DBG_LEVEL_END_BIT),
95};
96
97void fpdb_dump_tuple(char *msg, struct nf_conntrack_tuple *t);
98
99#if FP_DEBUG_LEVEL >= FP_ERR_LVL
100#define FP_ERR_DUMP_ENTRY(msg, el) \
101 fpdb_dump_entry(msg, el)
102#define FP_ERR_DUMP_CONTRACK(msg, el) \
103 learner_nc_dump_conntrack_tuple(msg, el)
104#define FP_ERR_DUMP_TUPLE(msg, el) \
105 fpdb_dump_tuple(msg, el)
106#else
107#define FP_ERR_DUMP_ENTRY(msg, el) do {} while (0)
108#define FP_ERR_DUMP_CONTRACK(msg, el) do {} while (0)
109#define FP_ERR_DUMP_TUPLE(msg, el) do {} while (0)
110#endif
111
112#if FP_DEBUG_LEVEL >= FP_DEBUG_LVL
113#define FP_DEBUG_DUMP_ENTRY(msg, el) \
114 fpdb_dump_entry(msg, el)
115#define FP_DEBUG_DUMP_TUPLE(msg, el) \
116 fpdb_dump_tuple(msg, el)
117#define FP_DEBUG_DUMP_CONTRACK(msg, el) \
118 learner_nc_dump_conntrack_tuple(msg, el)
119#else
120#define FP_DEBUG_DUMP_ENTRY(msg, el) do {} while (0)
121#define FP_DEBUG_DUMP_TUPLE(msg, el) do {} while (0)
122#define FP_DEBUG_DUMP_CONTRACK(msg, el) do {} while (0)
123#endif
124
125static const char *const tcp_conntrack_names[] = {
126 "NONE",
127 "SYN_SENT",
128 "SYN_RECV",
129 "ESTABLISHED",
130 "FIN_WAIT",
131 "CLOSE_WAIT",
132 "LAST_ACK",
133 "TIME_WAIT",
134 "CLOSE",
135 "SYN_SENT2",
136};
137
138#define SECS * HZ
139#define MINS * 60 SECS
140#define HOURS * 60 MINS
141#define DAYS * 24 HOURS
142
143#define TCP_DEFAULT_TIMEOUT (5 DAYS)
144#define UDP_DEFAULT_TIMEOUT (5 SECS)
145#define UDP_DEFAULT_TIMEOUT_STREAM (180 SECS)
146
147#define IP_VER_4 4
148#define IP_VER_6 6
149#define IP_VERSION(pkt) (((struct iphdr *)(pkt))->version)
150#define NF_CT_NAT(ct) ((ct)->status & IPS_NAT_DONE_MASK)
151
152#ifdef SKB_P_SUPPORT
153#define FP_IS_SKB_P(skb) ((skb)->shared_info_ptr)
154#else
155#define FP_IS_SKB_P(skb) 0
156#endif
157static inline
158int fp_dump_tuple_ip(char *buf,const struct nf_conntrack_tuple *t, int verbose)
159{
160 int len = 0;
161 if (buf) {
162 if (verbose)
163 len += sprintf(buf, "%s ", t->dst.protonum ==
164 IPPROTO_UDP ? "UDP" : "TCP");
165 len += sprintf(buf + len, "src=%pI4 dst=%pI4 sport=%hu dport=%hu",
166 &t->src.u3.ip, &t->dst.u3.ip,
167 ntohs(t->src.u.all), ntohs(t->dst.u.all));
168 }
169 return len;
170}
171
172static inline
173int fp_dump_tuple_ipv6(char *buf, const struct nf_conntrack_tuple *t, int verbose)
174{
175 int len = 0;
176 if (buf) {
177 if (verbose)
178 len += sprintf(buf, "%s ", t->dst.protonum ==
179 IPPROTO_UDP ? "UDP" : "TCP");
180 len += sprintf(buf + len, "src=%pI6c dst=%pI6c sport=%hu dport=%hu",
181 t->src.u3.all, t->dst.u3.all,
182 ntohs(t->src.u.all), ntohs(t->dst.u.all));
183 }
184 return len;
185}
186
187static inline int __fp_dump_tuple(char *buf, const struct nf_conntrack_tuple *t, int verbose)
188{
189 if (t->src.l3num == AF_INET)
190 return fp_dump_tuple_ip(buf, t, verbose);
191 if (t->src.l3num == AF_INET6)
192 return fp_dump_tuple_ipv6(buf, t, verbose);
193
194 return 0;
195}
196
197static inline int fp_dump_tuple(char *buf, const struct nf_conntrack_tuple *t)
198{
199 return __fp_dump_tuple(buf, t, 1);
200}
201
202static inline void fp_print_tuple(char *msg, const struct nf_conntrack_tuple *t)
203{
204 if (t->src.l3num == AF_INET) {
205 pr_err("%s:%d(%s): %s %pI4:%hu -> %pI4:%hu\n",
206 __func__, __LINE__, msg,
207 t->dst.protonum ==
208 IPPROTO_UDP ? "UDP" : "TCP",
209 &t->src.u3.ip, ntohs(t->src.u.all),
210 &t->dst.u3.ip, ntohs(t->dst.u.all));
211 }
212
213 if (t->src.l3num == AF_INET6) {
214 pr_err("%s:%d(%s): %s %pI6 %hu -> %pI6 %hu\n",
215 __func__, __LINE__, msg,
216 t->dst.protonum ==
217 IPPROTO_UDP ? "UDP" : "TCP",
218 t->src.u3.all, ntohs(t->src.u.all),
219 t->dst.u3.all, ntohs(t->dst.u.all));
220 }
221}
222
223/* For debugging only */
224static inline void fp_dump_pkt_data(void *data, int len)
225{
226 void *start, *end;
227
228 start = data;
229 end = start + len;
230
231 while (start < end) {
232 pr_info("0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
233 (u32)((unsigned long)start - (unsigned long)data),
234 ntohl(readl(start)), ntohl(readl(start + 0x4)),
235 ntohl(readl(start + 0x8)), ntohl(readl(start + 0xc)));
236 start += 0x10;
237 }
238}
239
240void restore_ct(struct nf_conn *ct);
241
242/**------------------------------------------------------------**/
243/** BACKWARD COMPATABILITY **/
244/**------------------------------------------------------------**/
245
246#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
247static inline int __must_check kref_get_unless_zero(struct kref *kref)
248{
249 return atomic_add_unless(&kref->refcount, 1, 0);
250}
251#endif
252
253#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)
254extern struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb);
255static inline struct netdev_queue *
256netdev_pick_tx(struct net_device *dev, struct sk_buff *skb)
257{
258 return dev_pick_tx(dev, skb);
259}
260#endif
261
262#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
263#define netif_xmit_frozen_or_stopped(txq) \
264 (netif_tx_queue_stopped(txq) || netif_tx_queue_frozen(txq))
265#endif
266
267static inline struct dst_entry *rt6i_dst_get(struct rt6_info *rt)
268{
269#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
270 return &rt->u.dst;
271#else
272 return &rt->dst;
273#endif
274}
275
276#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
277static inline void ip6_rt_put(struct rt6_info *rt)
278{
279 dst_release(rt6i_dst_get(rt));
280}
281#endif
282
283static inline int
284rt4_lookup(struct net *n, struct flowi *flp, struct fib_result *res)
285{
286 memset(res, 0, sizeof(*res));
287#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
288 return fib_lookup(n, flp, res);
289#else
290 return fib_lookup(n, &flp->u.ip4, res, 0);
291#endif
292}
293
294static inline void ip4_rt_put(struct fib_result *res)
295{
296#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
297 fib_res_put(res);
298#endif
299}
300
301#endif /* FP_COMMON_H */