mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-23 13:09:04 -04:00
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>
This commit is contained in:
parent
1c984f8a5d
commit
7026b1ddb6
39 changed files with 277 additions and 218 deletions
|
|
@ -2165,8 +2165,12 @@ int dev_open(struct net_device *dev);
|
|||
int dev_close(struct net_device *dev);
|
||||
int dev_close_many(struct list_head *head, bool unlink);
|
||||
void dev_disable_lro(struct net_device *dev);
|
||||
int dev_loopback_xmit(struct sk_buff *newskb);
|
||||
int dev_queue_xmit(struct sk_buff *skb);
|
||||
int dev_loopback_xmit(struct sock *sk, struct sk_buff *newskb);
|
||||
int dev_queue_xmit_sk(struct sock *sk, struct sk_buff *skb);
|
||||
static inline int dev_queue_xmit(struct sk_buff *skb)
|
||||
{
|
||||
return dev_queue_xmit_sk(skb->sk, skb);
|
||||
}
|
||||
int dev_queue_xmit_accel(struct sk_buff *skb, void *accel_priv);
|
||||
int register_netdevice(struct net_device *dev);
|
||||
void 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)
|
|||
|
||||
int netif_rx(struct sk_buff *skb);
|
||||
int netif_rx_ni(struct sk_buff *skb);
|
||||
int netif_receive_skb(struct sk_buff *skb);
|
||||
int netif_receive_skb_sk(struct sock *sk, struct sk_buff *skb);
|
||||
static inline int netif_receive_skb(struct sk_buff *skb)
|
||||
{
|
||||
return netif_receive_skb_sk(skb->sk, skb);
|
||||
}
|
||||
gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb);
|
||||
void napi_gro_flush(struct napi_struct *napi, bool flush_old);
|
||||
struct sk_buff *napi_get_frags(struct napi_struct *napi);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ struct nf_hook_state {
|
|||
struct net_device *in;
|
||||
struct net_device *out;
|
||||
struct sock *sk;
|
||||
int (*okfn)(struct sk_buff *);
|
||||
int (*okfn)(struct sock *, struct sk_buff *);
|
||||
};
|
||||
|
||||
static 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,
|
|||
struct net_device *indev,
|
||||
struct net_device *outdev,
|
||||
struct sock *sk,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
int (*okfn)(struct sock *, struct sk_buff *))
|
||||
{
|
||||
p->hook = hook;
|
||||
p->thresh = thresh;
|
||||
|
|
@ -156,26 +156,29 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state);
|
|||
* value indicates the packet has been consumed by the hook.
|
||||
*/
|
||||
static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
|
||||
struct sock *sk,
|
||||
struct sk_buff *skb,
|
||||
struct net_device *indev,
|
||||
struct net_device *outdev,
|
||||
int (*okfn)(struct sk_buff *), int thresh)
|
||||
int (*okfn)(struct sock *, struct sk_buff *),
|
||||
int thresh)
|
||||
{
|
||||
if (nf_hooks_active(pf, hook)) {
|
||||
struct nf_hook_state state;
|
||||
|
||||
nf_hook_state_init(&state, hook, thresh, pf,
|
||||
indev, outdev, NULL, okfn);
|
||||
indev, outdev, sk, okfn);
|
||||
return nf_hook_slow(skb, &state);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
|
||||
struct net_device *indev, struct net_device *outdev,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sock *sk,
|
||||
struct sk_buff *skb, struct net_device *indev,
|
||||
struct net_device *outdev,
|
||||
int (*okfn)(struct sock *, struct sk_buff *))
|
||||
{
|
||||
return nf_hook_thresh(pf, hook, skb, indev, outdev, okfn, INT_MIN);
|
||||
return nf_hook_thresh(pf, hook, sk, skb, indev, outdev, okfn, INT_MIN);
|
||||
}
|
||||
|
||||
/* 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,
|
|||
*/
|
||||
|
||||
static inline int
|
||||
NF_HOOK_THRESH(uint8_t pf, unsigned int hook, struct sk_buff *skb,
|
||||
struct net_device *in, struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *), int thresh)
|
||||
NF_HOOK_THRESH(uint8_t pf, unsigned int hook, struct sock *sk,
|
||||
struct sk_buff *skb, struct net_device *in,
|
||||
struct net_device *out,
|
||||
int (*okfn)(struct sock *, struct sk_buff *), int thresh)
|
||||
{
|
||||
int ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, thresh);
|
||||
int ret = nf_hook_thresh(pf, hook, sk, skb, in, out, okfn, thresh);
|
||||
if (ret == 1)
|
||||
ret = okfn(skb);
|
||||
ret = okfn(sk, skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int
|
||||
NF_HOOK_COND(uint8_t pf, unsigned int hook, struct sk_buff *skb,
|
||||
struct net_device *in, struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *), bool cond)
|
||||
NF_HOOK_COND(uint8_t pf, unsigned int hook, struct sock *sk,
|
||||
struct sk_buff *skb, struct net_device *in, struct net_device *out,
|
||||
int (*okfn)(struct sock *, struct sk_buff *), bool cond)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!cond ||
|
||||
((ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, INT_MIN)) == 1))
|
||||
ret = okfn(skb);
|
||||
((ret = nf_hook_thresh(pf, hook, sk, skb, in, out, okfn, INT_MIN)) == 1))
|
||||
ret = okfn(sk, skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int
|
||||
NF_HOOK(uint8_t pf, unsigned int hook, struct sk_buff *skb,
|
||||
NF_HOOK(uint8_t pf, unsigned int hook, struct sock *sk, struct sk_buff *skb,
|
||||
struct net_device *in, struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
int (*okfn)(struct sock *, struct sk_buff *))
|
||||
{
|
||||
return NF_HOOK_THRESH(pf, hook, skb, in, out, okfn, INT_MIN);
|
||||
return NF_HOOK_THRESH(pf, hook, sk, skb, in, out, okfn, INT_MIN);
|
||||
}
|
||||
|
||||
/* Call setsockopt() */
|
||||
|
|
@ -324,19 +328,21 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
|
|||
}
|
||||
|
||||
#else /* !CONFIG_NETFILTER */
|
||||
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
|
||||
#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
|
||||
#define NF_HOOK(pf, hook, sk, skb, indev, outdev, okfn) (okfn)(sk, skb)
|
||||
#define NF_HOOK_COND(pf, hook, sk, skb, indev, outdev, okfn, cond) (okfn)(sk, skb)
|
||||
static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
|
||||
struct sock *sk,
|
||||
struct sk_buff *skb,
|
||||
struct net_device *indev,
|
||||
struct net_device *outdev,
|
||||
int (*okfn)(struct sk_buff *), int thresh)
|
||||
int (*okfn)(struct sock *sk, struct sk_buff *), int thresh)
|
||||
{
|
||||
return okfn(skb);
|
||||
return okfn(sk, skb);
|
||||
}
|
||||
static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
|
||||
struct net_device *indev, struct net_device *outdev,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sock *sk,
|
||||
struct sk_buff *skb, struct net_device *indev,
|
||||
struct net_device *outdev,
|
||||
int (*okfn)(struct sock *, struct sk_buff *))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ static inline unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int br_handle_frame_finish(struct sk_buff *skb);
|
||||
int br_handle_frame_finish(struct sock *sk, struct sk_buff *skb);
|
||||
|
||||
static inline void br_drop_fake_rtable(struct sk_buff *skb)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue