blob: d2d60c73c935bd3d8ae3c68d5e508ae6c52c5861 [file] [log] [blame]
Xiaoping Fan45f4f2c2015-05-22 16:13:00 -07001/*
2 * sfe_backport.h
3 * Shortcut forwarding engine compatible header file.
4 *
Xiaoping Fane70da412016-02-26 16:47:57 -08005 * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
Xiaoping Fana42c68b2015-08-07 18:00:39 -07006 * Permission to use, copy, modify, and/or distribute this software for
7 * any purpose with or without fee is hereby granted, provided that the
8 * above copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Xiaoping Fan45f4f2c2015-05-22 16:13:00 -070016 */
17
Xiaoping Fan3f1fe512014-11-05 12:14:57 -080018#include <linux/version.h>
19
Xiaoping Fanb31b2ec2016-11-17 17:44:36 -080020#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
21#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
22#include <net/netfilter/nf_conntrack_timeout.h>
23#else
24enum udp_conntrack {
25 UDP_CT_UNREPLIED,
26 UDP_CT_REPLIED,
27 UDP_CT_MAX
28};
29
30static inline unsigned int *
31nf_ct_timeout_lookup(struct net *net, struct nf_conn *ct,
32 struct nf_conntrack_l4proto *l4proto)
33{
34#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
35 struct nf_conn_timeout *timeout_ext;
36 unsigned int *timeouts;
37
38 timeout_ext = nf_ct_timeout_find(ct);
39 if (timeout_ext)
40 timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext);
41 else
42 timeouts = l4proto->get_timeouts(net);
43
44 return timeouts;
45#else
46 return l4proto->get_timeouts(net);
47#endif /*CONFIG_NF_CONNTRACK_TIMEOUT*/
48}
49#endif /*KERNEL_VERSION(3, 7, 0)*/
50#endif /*KERNEL_VERSION(3, 4, 0)*/
51
Xiaoping Fane70da412016-02-26 16:47:57 -080052#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
Xiaoping Fan8da13872016-04-04 18:51:56 -070053#define sfe_define_post_routing_hook(FN_NAME, HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
54static unsigned int FN_NAME(void *priv, \
55 struct sk_buff *SKB, \
56 const struct nf_hook_state *state)
Xiaoping Fane70da412016-02-26 16:47:57 -080057#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
Xiaoping Fan8da13872016-04-04 18:51:56 -070058#define sfe_define_post_routing_hook(FN_NAME, HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
59static unsigned int FN_NAME(const struct nf_hook_ops *OPS, \
60 struct sk_buff *SKB, \
61 const struct net_device *UNUSED, \
62 const struct net_device *OUT, \
63 int (*OKFN)(struct sk_buff *))
Xiaoping Fan3f1fe512014-11-05 12:14:57 -080064#else
Xiaoping Fan8da13872016-04-04 18:51:56 -070065#define sfe_define_post_routing_hook(FN_NAME, HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
66static unsigned int FN_NAME(unsigned int HOOKNUM, \
67 struct sk_buff *SKB, \
68 const struct net_device *UNUSED, \
69 const struct net_device *OUT, \
70 int (*OKFN)(struct sk_buff *))
Xiaoping Fan3f1fe512014-11-05 12:14:57 -080071#endif
72
Xiaoping Fan8da13872016-04-04 18:51:56 -070073#define sfe_cm_ipv4_post_routing_hook(HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
74 sfe_define_post_routing_hook(__sfe_cm_ipv4_post_routing_hook, HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN)
75#define sfe_cm_ipv6_post_routing_hook(HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
76 sfe_define_post_routing_hook(__sfe_cm_ipv6_post_routing_hook, HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN)
77#define fast_classifier_ipv4_post_routing_hook(HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
78 sfe_define_post_routing_hook(__fast_classifier_ipv4_post_routing_hook, HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN)
Xiaoping Fan9b6bb332016-04-05 19:21:26 -070079#define fast_classifier_ipv6_post_routing_hook(HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
80 sfe_define_post_routing_hook(__fast_classifier_ipv6_post_routing_hook, HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN)
Xiaoping Fan8da13872016-04-04 18:51:56 -070081
Xiaoping Fane70da412016-02-26 16:47:57 -080082#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
83#define SFE_IPV4_NF_POST_ROUTING_HOOK(fn) \
84 { \
85 .hook = fn, \
86 .pf = NFPROTO_IPV4, \
87 .hooknum = NF_INET_POST_ROUTING, \
88 .priority = NF_IP_PRI_NAT_SRC + 1, \
89 }
90#else
91#define SFE_IPV4_NF_POST_ROUTING_HOOK(fn) \
92 { \
93 .hook = fn, \
94 .owner = THIS_MODULE, \
95 .pf = NFPROTO_IPV4, \
96 .hooknum = NF_INET_POST_ROUTING, \
97 .priority = NF_IP_PRI_NAT_SRC + 1, \
98 }
99#endif
100
101#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
102#define SFE_IPV6_NF_POST_ROUTING_HOOK(fn) \
103 { \
104 .hook = fn, \
105 .pf = NFPROTO_IPV6, \
106 .hooknum = NF_INET_POST_ROUTING, \
107 .priority = NF_IP_PRI_NAT_SRC + 1, \
108 }
109#else
110#define SFE_IPV6_NF_POST_ROUTING_HOOK(fn) \
111 { \
112 .hook = fn, \
113 .owner = THIS_MODULE, \
114 .pf = NFPROTO_IPV6, \
115 .hooknum = NF_INET_POST_ROUTING, \
116 .priority = NF_IP6_PRI_NAT_SRC + 1, \
117 }
118#endif
119
120#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0))
121#define SFE_NF_CT_DEFAULT_ZONE (&nf_ct_zone_dflt)
122#else
123#define SFE_NF_CT_DEFAULT_ZONE NF_CT_DEFAULT_ZONE
124#endif
125
Xiaoping Fan79ed7292015-03-27 16:47:19 -0700126/*
127 * sfe_dev_get_master
128 * get master of bridge port, and hold it
129 */
130static inline struct net_device *sfe_dev_get_master(struct net_device *dev)
131{
132 struct net_device *master;
Xiaoping Fane70da412016-02-26 16:47:57 -0800133#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
Xiaoping Fan79ed7292015-03-27 16:47:19 -0700134 rcu_read_lock();
135 master = netdev_master_upper_dev_get_rcu(dev);
136 if (master)
137 dev_hold(master);
138
139 rcu_read_unlock();
Xiaoping Fan3f1fe512014-11-05 12:14:57 -0800140#else
Xiaoping Fan79ed7292015-03-27 16:47:19 -0700141 master = dev->master;
142 if (master)
143 dev_hold(master);
Xiaoping Fan3f1fe512014-11-05 12:14:57 -0800144#endif
Xiaoping Fan79ed7292015-03-27 16:47:19 -0700145 return master;
146}
Xiaoping Fan3f1fe512014-11-05 12:14:57 -0800147
Xiaoping Fane70da412016-02-26 16:47:57 -0800148#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
Xiaoping Fan20f04cc2015-03-30 10:14:20 -0700149#define SFE_DEV_EVENT_PTR(PTR) netdev_notifier_info_to_dev(PTR)
150#else
151#define SFE_DEV_EVENT_PTR(PTR) (struct net_device *)(PTR)
152#endif
153
Xiaoping Fane70da412016-02-26 16:47:57 -0800154#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
Xiaoping Fan3f1fe512014-11-05 12:14:57 -0800155#define SFE_NF_CONN_ACCT(NM) struct nf_conn_acct *NM
156#else
157#define SFE_NF_CONN_ACCT(NM) struct nf_conn_counter *NM
158#endif
159
Xiaoping Fane70da412016-02-26 16:47:57 -0800160#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
Xiaoping Fan59176422015-05-22 15:58:10 -0700161#define SFE_ACCT_COUNTER(NM) ((NM)->counter)
Xiaoping Fan3f1fe512014-11-05 12:14:57 -0800162#else
163#define SFE_ACCT_COUNTER(NM) (NM)
164#endif
Xiaoping Fan8da13872016-04-04 18:51:56 -0700165
166#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
167#define sfe_hash_for_each_possible(name, obj, node, member, key) \
168 hash_for_each_possible(name, obj, member, key)
169#else
170#define sfe_hash_for_each_possible(name, obj, node, member, key) \
171 hash_for_each_possible(name, obj, node, member, key)
172#endif
173
174#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
175#define sfe_hash_for_each(name, bkt, node, obj, member) \
176 hash_for_each(name, bkt, obj, member)
177#else
178#define sfe_hash_for_each(name, bkt, node, obj, member) \
179 hash_for_each(name, bkt, node, obj, member)
180#endif
Xiaoping Fan9b7690b2016-10-12 19:04:24 -0700181
182#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
183#define sfe_dst_get_neighbour(dst, daddr) dst_neigh_lookup(dst, addr)
184#else
185static inline struct neighbour *
186sfe_dst_get_neighbour(struct dst_entry *dst, void *daddr)
187{
188 struct neighbour *neigh = dst_get_neighbour_noref(dst);
189
190 if (neigh)
191 neigh_hold(neigh);
192
193 return neigh;
194}
195#endif