aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorDavid Miller <davem@davemloft.net>2015-04-05 22:19:04 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-07 15:25:55 -0400
commit7026b1ddb6b8d4e6ee33dc2bd06c0ca8746fa7ab (patch)
tree3e11ed0f186ea6066a3f7efecb88d85bc732ee51 /include/linux
parent1c984f8a5df085bcf35364a8a870bd4db4da4ed3 (diff)
netfilter: Pass socket pointer down through okfn().
On the output paths in particular, we have to sometimes deal with two socket contexts. First, and usually skb->sk, is the local socket that generated the frame. And second, is potentially the socket used to control a tunneling socket, such as one the encapsulates using UDP. We do not want to disassociate skb->sk when encapsulating in order to fix this, because that would break socket memory accounting. The most extreme case where this can cause huge problems is an AF_PACKET socket transmitting over a vxlan device. We hit code paths doing checks that assume they are dealing with an ipv4 socket, but are actually operating upon the AF_PACKET one. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/netdevice.h14
-rw-r--r--include/linux/netfilter.h62
-rw-r--r--include/linux/netfilter_bridge.h2
3 files changed, 46 insertions, 32 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 41bf58a2b936..45823db2efb0 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2165,8 +2165,12 @@ int dev_open(struct net_device *dev);
2165int dev_close(struct net_device *dev); 2165int dev_close(struct net_device *dev);
2166int dev_close_many(struct list_head *head, bool unlink); 2166int dev_close_many(struct list_head *head, bool unlink);
2167void dev_disable_lro(struct net_device *dev); 2167void dev_disable_lro(struct net_device *dev);
2168int dev_loopback_xmit(struct sk_buff *newskb); 2168int dev_loopback_xmit(struct sock *sk, struct sk_buff *newskb);
2169int dev_queue_xmit(struct sk_buff *skb); 2169int dev_queue_xmit_sk(struct sock *sk, struct sk_buff *skb);
2170static inline int dev_queue_xmit(struct sk_buff *skb)
2171{
2172 return dev_queue_xmit_sk(skb->sk, skb);
2173}
2170int dev_queue_xmit_accel(struct sk_buff *skb, void *accel_priv); 2174int dev_queue_xmit_accel(struct sk_buff *skb, void *accel_priv);
2171int register_netdevice(struct net_device *dev); 2175int register_netdevice(struct net_device *dev);
2172void unregister_netdevice_queue(struct net_device *dev, struct list_head *head); 2176void unregister_netdevice_queue(struct net_device *dev, struct list_head *head);
@@ -2927,7 +2931,11 @@ static inline void dev_consume_skb_any(struct sk_buff *skb)
2927 2931
2928int netif_rx(struct sk_buff *skb); 2932int netif_rx(struct sk_buff *skb);
2929int netif_rx_ni(struct sk_buff *skb); 2933int netif_rx_ni(struct sk_buff *skb);
2930int netif_receive_skb(struct sk_buff *skb); 2934int netif_receive_skb_sk(struct sock *sk, struct sk_buff *skb);
2935static inline int netif_receive_skb(struct sk_buff *skb)
2936{
2937 return netif_receive_skb_sk(skb->sk, skb);
2938}
2931gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb); 2939gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb);
2932void napi_gro_flush(struct napi_struct *napi, bool flush_old); 2940void napi_gro_flush(struct napi_struct *napi, bool flush_old);
2933struct sk_buff *napi_get_frags(struct napi_struct *napi); 2941struct sk_buff *napi_get_frags(struct napi_struct *napi);
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index f8f58fab2402..63560d0a8dfe 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -54,7 +54,7 @@ struct nf_hook_state {
54 struct net_device *in; 54 struct net_device *in;
55 struct net_device *out; 55 struct net_device *out;
56 struct sock *sk; 56 struct sock *sk;
57 int (*okfn)(struct sk_buff *); 57 int (*okfn)(struct sock *, struct sk_buff *);
58}; 58};
59 59
60static inline void nf_hook_state_init(struct nf_hook_state *p, 60static inline void nf_hook_state_init(struct nf_hook_state *p,
@@ -63,7 +63,7 @@ static inline void nf_hook_state_init(struct nf_hook_state *p,
63 struct net_device *indev, 63 struct net_device *indev,
64 struct net_device *outdev, 64 struct net_device *outdev,
65 struct sock *sk, 65 struct sock *sk,
66 int (*okfn)(struct sk_buff *)) 66 int (*okfn)(struct sock *, struct sk_buff *))
67{ 67{
68 p->hook = hook; 68 p->hook = hook;
69 p->thresh = thresh; 69 p->thresh = thresh;
@@ -156,26 +156,29 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state);
156 * value indicates the packet has been consumed by the hook. 156 * value indicates the packet has been consumed by the hook.
157 */ 157 */
158static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook, 158static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
159 struct sock *sk,
159 struct sk_buff *skb, 160 struct sk_buff *skb,
160 struct net_device *indev, 161 struct net_device *indev,
161 struct net_device *outdev, 162 struct net_device *outdev,
162 int (*okfn)(struct sk_buff *), int thresh) 163 int (*okfn)(struct sock *, struct sk_buff *),
164 int thresh)
163{ 165{
164 if (nf_hooks_active(pf, hook)) { 166 if (nf_hooks_active(pf, hook)) {
165 struct nf_hook_state state; 167 struct nf_hook_state state;
166 168
167 nf_hook_state_init(&state, hook, thresh, pf, 169 nf_hook_state_init(&state, hook, thresh, pf,
168 indev, outdev, NULL, okfn); 170 indev, outdev, sk, okfn);
169 return nf_hook_slow(skb, &state); 171 return nf_hook_slow(skb, &state);
170 } 172 }
171 return 1; 173 return 1;
172} 174}
173 175
174static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb, 176static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sock *sk,
175 struct net_device *indev, struct net_device *outdev, 177 struct sk_buff *skb, struct net_device *indev,
176 int (*okfn)(struct sk_buff *)) 178 struct net_device *outdev,
179 int (*okfn)(struct sock *, struct sk_buff *))
177{ 180{
178 return nf_hook_thresh(pf, hook, skb, indev, outdev, okfn, INT_MIN); 181 return nf_hook_thresh(pf, hook, sk, skb, indev, outdev, okfn, INT_MIN);
179} 182}
180 183
181/* Activate hook; either okfn or kfree_skb called, unless a hook 184/* Activate hook; either okfn or kfree_skb called, unless a hook
@@ -196,35 +199,36 @@ static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
196*/ 199*/
197 200
198static inline int 201static inline int
199NF_HOOK_THRESH(uint8_t pf, unsigned int hook, struct sk_buff *skb, 202NF_HOOK_THRESH(uint8_t pf, unsigned int hook, struct sock *sk,
200 struct net_device *in, struct net_device *out, 203 struct sk_buff *skb, struct net_device *in,
201 int (*okfn)(struct sk_buff *), int thresh) 204 struct net_device *out,
205 int (*okfn)(struct sock *, struct sk_buff *), int thresh)
202{ 206{
203 int ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, thresh); 207 int ret = nf_hook_thresh(pf, hook, sk, skb, in, out, okfn, thresh);
204 if (ret == 1) 208 if (ret == 1)
205 ret = okfn(skb); 209 ret = okfn(sk, skb);
206 return ret; 210 return ret;
207} 211}
208 212
209static inline int 213static inline int
210NF_HOOK_COND(uint8_t pf, unsigned int hook, struct sk_buff *skb, 214NF_HOOK_COND(uint8_t pf, unsigned int hook, struct sock *sk,
211 struct net_device *in, struct net_device *out, 215 struct sk_buff *skb, struct net_device *in, struct net_device *out,
212 int (*okfn)(struct sk_buff *), bool cond) 216 int (*okfn)(struct sock *, struct sk_buff *), bool cond)
213{ 217{
214 int ret; 218 int ret;
215 219
216 if (!cond || 220 if (!cond ||
217 ((ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, INT_MIN)) == 1)) 221 ((ret = nf_hook_thresh(pf, hook, sk, skb, in, out, okfn, INT_MIN)) == 1))
218 ret = okfn(skb); 222 ret = okfn(sk, skb);
219 return ret; 223 return ret;
220} 224}
221 225
222static inline int 226static inline int
223NF_HOOK(uint8_t pf, unsigned int hook, struct sk_buff *skb, 227NF_HOOK(uint8_t pf, unsigned int hook, struct sock *sk, struct sk_buff *skb,
224 struct net_device *in, struct net_device *out, 228 struct net_device *in, struct net_device *out,
225 int (*okfn)(struct sk_buff *)) 229 int (*okfn)(struct sock *, struct sk_buff *))
226{ 230{
227 return NF_HOOK_THRESH(pf, hook, skb, in, out, okfn, INT_MIN); 231 return NF_HOOK_THRESH(pf, hook, sk, skb, in, out, okfn, INT_MIN);
228} 232}
229 233
230/* Call setsockopt() */ 234/* Call setsockopt() */
@@ -324,19 +328,21 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
324} 328}
325 329
326#else /* !CONFIG_NETFILTER */ 330#else /* !CONFIG_NETFILTER */
327#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) 331#define NF_HOOK(pf, hook, sk, skb, indev, outdev, okfn) (okfn)(sk, skb)
328#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb) 332#define NF_HOOK_COND(pf, hook, sk, skb, indev, outdev, okfn, cond) (okfn)(sk, skb)
329static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook, 333static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
334 struct sock *sk,
330 struct sk_buff *skb, 335 struct sk_buff *skb,
331 struct net_device *indev, 336 struct net_device *indev,
332 struct net_device *outdev, 337 struct net_device *outdev,
333 int (*okfn)(struct sk_buff *), int thresh) 338 int (*okfn)(struct sock *sk, struct sk_buff *), int thresh)
334{ 339{
335 return okfn(skb); 340 return okfn(sk, skb);
336} 341}
337static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb, 342static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sock *sk,
338 struct net_device *indev, struct net_device *outdev, 343 struct sk_buff *skb, struct net_device *indev,
339 int (*okfn)(struct sk_buff *)) 344 struct net_device *outdev,
345 int (*okfn)(struct sock *, struct sk_buff *))
340{ 346{
341 return 1; 347 return 1;
342} 348}
diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h
index 2734977199ca..5fc0a0fe244b 100644
--- a/include/linux/netfilter_bridge.h
+++ b/include/linux/netfilter_bridge.h
@@ -30,7 +30,7 @@ static inline unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb)
30 return 0; 30 return 0;
31} 31}
32 32
33int br_handle_frame_finish(struct sk_buff *skb); 33int br_handle_frame_finish(struct sock *sk, struct sk_buff *skb);
34 34
35static inline void br_drop_fake_rtable(struct sk_buff *skb) 35static inline void br_drop_fake_rtable(struct sk_buff *skb)
36{ 36{