Commit 5888b93b authored by David S. Miller's avatar David S. Miller

Merge branch 'nf-hook-compress'

netfilter: Compress hook function signatures.

Currently netfilter hooks have a function signature that is huge and
has many arguments.  This propagates from the hook entry points down
into the individual hook implementations themselves.

This means that if, for example, we want to change the type of one of
these arguments then we have to touch hundreds of locations.

The main initial motivation behind this is that we'd like to change
the signature of "okfn" so that a socket pointer can be passed in (and
reference counted properly) for the sake of using the proper socket
context in the case of tunnels whilst not releasing the top level user
socket from skb->sk (and thus releasing it's socket memory quota
usage) in order to accomodate this.

This also makes it clear who actually uses 'okfn', nf_queue().  It is
absolutely critical to make this obvious because any user of 'okfn'
down in these hook chains have the be strictly audited for
escapability.  Specifically, escapability of references to objects
outside of the packet processing path.  And that's exactly what
nf_queue() does via it's packet reinjection framework.

In fact this points out a bug in Jiri's original attempt to push the
socket pointer down through netfilter's okfn.  It didn't grab and drop
a reference to the socket in net/netfilter/nf_queue.c as needed.

Furthermore, so many code paths are simplified, and should in fact be
more efficient because we aren't passing in arguments that often are
simply not used by the netfilter hook at all.

Further simplifications are probably possible, but this series takes
care of the main cases.

Unfortunately I couldn't convert ebt_do_table() because ebtables is
complete and utter crap and uses ebt_do_table() outside of the hook
call chains.  But that should not be news to anyone.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Acked-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parents b81b7be6 b85c3dc9
...@@ -44,11 +44,19 @@ int netfilter_init(void); ...@@ -44,11 +44,19 @@ int netfilter_init(void);
struct sk_buff; struct sk_buff;
struct nf_hook_ops; struct nf_hook_ops;
struct nf_hook_state {
unsigned int hook;
int thresh;
u_int8_t pf;
struct net_device *in;
struct net_device *out;
int (*okfn)(struct sk_buff *);
};
typedef unsigned int nf_hookfn(const struct nf_hook_ops *ops, typedef unsigned int nf_hookfn(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state);
const struct net_device *out,
int (*okfn)(struct sk_buff *));
struct nf_hook_ops { struct nf_hook_ops {
struct list_head list; struct list_head list;
...@@ -118,9 +126,7 @@ static inline bool nf_hooks_active(u_int8_t pf, unsigned int hook) ...@@ -118,9 +126,7 @@ static inline bool nf_hooks_active(u_int8_t pf, unsigned int hook)
} }
#endif #endif
int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb, int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state);
struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct sk_buff *), int thresh);
/** /**
* nf_hook_thresh - call a netfilter hook * nf_hook_thresh - call a netfilter hook
...@@ -135,8 +141,18 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook, ...@@ -135,8 +141,18 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
struct net_device *outdev, struct net_device *outdev,
int (*okfn)(struct sk_buff *), int thresh) int (*okfn)(struct sk_buff *), int thresh)
{ {
if (nf_hooks_active(pf, hook)) if (nf_hooks_active(pf, hook)) {
return nf_hook_slow(pf, hook, skb, indev, outdev, okfn, thresh); struct nf_hook_state state = {
.hook = hook,
.thresh = thresh,
.pf = pf,
.in = indev,
.out = outdev,
.okfn = okfn
};
return nf_hook_slow(skb, &state);
}
return 1; return 1;
} }
......
...@@ -54,8 +54,7 @@ extern struct xt_table *arpt_register_table(struct net *net, ...@@ -54,8 +54,7 @@ extern struct xt_table *arpt_register_table(struct net *net,
extern void arpt_unregister_table(struct xt_table *table); extern void arpt_unregister_table(struct xt_table *table);
extern unsigned int arpt_do_table(struct sk_buff *skb, extern unsigned int arpt_do_table(struct sk_buff *skb,
unsigned int hook, unsigned int hook,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct xt_table *table); struct xt_table *table);
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
......
...@@ -65,8 +65,7 @@ struct ipt_error { ...@@ -65,8 +65,7 @@ struct ipt_error {
extern void *ipt_alloc_initial_table(const struct xt_table *); extern void *ipt_alloc_initial_table(const struct xt_table *);
extern unsigned int ipt_do_table(struct sk_buff *skb, extern unsigned int ipt_do_table(struct sk_buff *skb,
unsigned int hook, unsigned int hook,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct xt_table *table); struct xt_table *table);
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
......
...@@ -31,8 +31,7 @@ extern struct xt_table *ip6t_register_table(struct net *net, ...@@ -31,8 +31,7 @@ extern struct xt_table *ip6t_register_table(struct net *net,
extern void ip6t_unregister_table(struct net *net, struct xt_table *table); extern void ip6t_unregister_table(struct net *net, struct xt_table *table);
extern unsigned int ip6t_do_table(struct sk_buff *skb, extern unsigned int ip6t_do_table(struct sk_buff *skb,
unsigned int hook, unsigned int hook,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct xt_table *table); struct xt_table *table);
/* Check for an extension */ /* Check for an extension */
......
...@@ -44,40 +44,32 @@ int nf_nat_icmp_reply_translation(struct sk_buff *skb, struct nf_conn *ct, ...@@ -44,40 +44,32 @@ int nf_nat_icmp_reply_translation(struct sk_buff *skb, struct nf_conn *ct,
unsigned int hooknum); unsigned int hooknum);
unsigned int nf_nat_ipv4_in(const struct nf_hook_ops *ops, struct sk_buff *skb, unsigned int nf_nat_ipv4_in(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)); struct nf_conn *ct));
unsigned int nf_nat_ipv4_out(const struct nf_hook_ops *ops, struct sk_buff *skb, unsigned int nf_nat_ipv4_out(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)); struct nf_conn *ct));
unsigned int nf_nat_ipv4_local_fn(const struct nf_hook_ops *ops, unsigned int nf_nat_ipv4_local_fn(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)); struct nf_conn *ct));
unsigned int nf_nat_ipv4_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, unsigned int nf_nat_ipv4_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)); struct nf_conn *ct));
int nf_nat_icmpv6_reply_translation(struct sk_buff *skb, struct nf_conn *ct, int nf_nat_icmpv6_reply_translation(struct sk_buff *skb, struct nf_conn *ct,
...@@ -85,40 +77,32 @@ int nf_nat_icmpv6_reply_translation(struct sk_buff *skb, struct nf_conn *ct, ...@@ -85,40 +77,32 @@ int nf_nat_icmpv6_reply_translation(struct sk_buff *skb, struct nf_conn *ct,
unsigned int hooknum, unsigned int hdrlen); unsigned int hooknum, unsigned int hdrlen);
unsigned int nf_nat_ipv6_in(const struct nf_hook_ops *ops, struct sk_buff *skb, unsigned int nf_nat_ipv6_in(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)); struct nf_conn *ct));
unsigned int nf_nat_ipv6_out(const struct nf_hook_ops *ops, struct sk_buff *skb, unsigned int nf_nat_ipv6_out(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)); struct nf_conn *ct));
unsigned int nf_nat_ipv6_local_fn(const struct nf_hook_ops *ops, unsigned int nf_nat_ipv6_local_fn(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)); struct nf_conn *ct));
unsigned int nf_nat_ipv6_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, unsigned int nf_nat_ipv6_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)); struct nf_conn *ct));
#endif /* _NF_NAT_L3PROTO_H */ #endif /* _NF_NAT_L3PROTO_H */
...@@ -12,12 +12,8 @@ struct nf_queue_entry { ...@@ -12,12 +12,8 @@ struct nf_queue_entry {
unsigned int id; unsigned int id;
struct nf_hook_ops *elem; struct nf_hook_ops *elem;
u_int8_t pf; struct nf_hook_state state;
u16 size; /* sizeof(entry) + saved route keys */ u16 size; /* sizeof(entry) + saved route keys */
unsigned int hook;
struct net_device *indev;
struct net_device *outdev;
int (*okfn)(struct sk_buff *);
/* extra space to store route keys */ /* extra space to store route keys */
}; };
......
...@@ -26,12 +26,11 @@ struct nft_pktinfo { ...@@ -26,12 +26,11 @@ struct nft_pktinfo {
static inline void nft_set_pktinfo(struct nft_pktinfo *pkt, static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
const struct nf_hook_ops *ops, const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out)
{ {
pkt->skb = skb; pkt->skb = skb;
pkt->in = pkt->xt.in = in; pkt->in = pkt->xt.in = state->in;
pkt->out = pkt->xt.out = out; pkt->out = pkt->xt.out = state->out;
pkt->ops = ops; pkt->ops = ops;
pkt->xt.hooknum = ops->hooknum; pkt->xt.hooknum = ops->hooknum;
pkt->xt.family = ops->pf; pkt->xt.family = ops->pf;
......
...@@ -8,12 +8,11 @@ static inline void ...@@ -8,12 +8,11 @@ static inline void
nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt, nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
const struct nf_hook_ops *ops, const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out)
{ {
struct iphdr *ip; struct iphdr *ip;
nft_set_pktinfo(pkt, ops, skb, in, out); nft_set_pktinfo(pkt, ops, skb, state);
ip = ip_hdr(pkt->skb); ip = ip_hdr(pkt->skb);
pkt->tprot = ip->protocol; pkt->tprot = ip->protocol;
......
...@@ -8,13 +8,12 @@ static inline int ...@@ -8,13 +8,12 @@ static inline int
nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt, nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
const struct nf_hook_ops *ops, const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out)
{ {
int protohdr, thoff = 0; int protohdr, thoff = 0;
unsigned short frag_off; unsigned short frag_off;
nft_set_pktinfo(pkt, ops, skb, in, out); nft_set_pktinfo(pkt, ops, skb, state);
protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, NULL); protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, NULL);
/* If malformed, drop it */ /* If malformed, drop it */
......
...@@ -562,9 +562,7 @@ static int check_hbh_len(struct sk_buff *skb) ...@@ -562,9 +562,7 @@ static int check_hbh_len(struct sk_buff *skb)
* to ip6tables, which doesn't support NAT, so things are fairly simple. */ * to ip6tables, which doesn't support NAT, so things are fairly simple. */
static unsigned int br_nf_pre_routing_ipv6(const struct nf_hook_ops *ops, static unsigned int br_nf_pre_routing_ipv6(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
const struct ipv6hdr *hdr; const struct ipv6hdr *hdr;
u32 pkt_len; u32 pkt_len;
...@@ -612,9 +610,7 @@ static unsigned int br_nf_pre_routing_ipv6(const struct nf_hook_ops *ops, ...@@ -612,9 +610,7 @@ static unsigned int br_nf_pre_routing_ipv6(const struct nf_hook_ops *ops,
* address to be able to detect DNAT afterwards. */ * address to be able to detect DNAT afterwards. */
static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops, static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct net_bridge_port *p; struct net_bridge_port *p;
struct net_bridge *br; struct net_bridge *br;
...@@ -623,7 +619,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops, ...@@ -623,7 +619,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
if (unlikely(!pskb_may_pull(skb, len))) if (unlikely(!pskb_may_pull(skb, len)))
return NF_DROP; return NF_DROP;
p = br_port_get_rcu(in); p = br_port_get_rcu(state->in);
if (p == NULL) if (p == NULL)
return NF_DROP; return NF_DROP;
br = p->br; br = p->br;
...@@ -633,7 +629,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops, ...@@ -633,7 +629,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
return NF_ACCEPT; return NF_ACCEPT;
nf_bridge_pull_encap_header_rcsum(skb); nf_bridge_pull_encap_header_rcsum(skb);
return br_nf_pre_routing_ipv6(ops, skb, in, out, okfn); return br_nf_pre_routing_ipv6(ops, skb, state);
} }
if (!brnf_call_iptables && !br->nf_call_iptables) if (!brnf_call_iptables && !br->nf_call_iptables)
...@@ -671,9 +667,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops, ...@@ -671,9 +667,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
* prevent this from happening. */ * prevent this from happening. */
static unsigned int br_nf_local_in(const struct nf_hook_ops *ops, static unsigned int br_nf_local_in(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
br_drop_fake_rtable(skb); br_drop_fake_rtable(skb);
return NF_ACCEPT; return NF_ACCEPT;
...@@ -710,9 +704,7 @@ static int br_nf_forward_finish(struct sk_buff *skb) ...@@ -710,9 +704,7 @@ static int br_nf_forward_finish(struct sk_buff *skb)
* bridge ports. */ * bridge ports. */
static unsigned int br_nf_forward_ip(const struct nf_hook_ops *ops, static unsigned int br_nf_forward_ip(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct nf_bridge_info *nf_bridge; struct nf_bridge_info *nf_bridge;
struct net_device *parent; struct net_device *parent;
...@@ -726,7 +718,7 @@ static unsigned int br_nf_forward_ip(const struct nf_hook_ops *ops, ...@@ -726,7 +718,7 @@ static unsigned int br_nf_forward_ip(const struct nf_hook_ops *ops,
if (!nf_bridge_unshare(skb)) if (!nf_bridge_unshare(skb))
return NF_DROP; return NF_DROP;
parent = bridge_parent(out); parent = bridge_parent(state->out);
if (!parent) if (!parent)
return NF_DROP; return NF_DROP;
...@@ -754,23 +746,21 @@ static unsigned int br_nf_forward_ip(const struct nf_hook_ops *ops, ...@@ -754,23 +746,21 @@ static unsigned int br_nf_forward_ip(const struct nf_hook_ops *ops,
else else
skb->protocol = htons(ETH_P_IPV6); skb->protocol = htons(ETH_P_IPV6);
NF_HOOK(pf, NF_INET_FORWARD, skb, brnf_get_logical_dev(skb, in), parent, NF_HOOK(pf, NF_INET_FORWARD, skb, brnf_get_logical_dev(skb, state->in),
br_nf_forward_finish); parent, br_nf_forward_finish);
return NF_STOLEN; return NF_STOLEN;
} }
static unsigned int br_nf_forward_arp(const struct nf_hook_ops *ops, static unsigned int br_nf_forward_arp(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct net_bridge_port *p; struct net_bridge_port *p;
struct net_bridge *br; struct net_bridge *br;
struct net_device **d = (struct net_device **)(skb->cb); struct net_device **d = (struct net_device **)(skb->cb);
p = br_port_get_rcu(out); p = br_port_get_rcu(state->out);
if (p == NULL) if (p == NULL)
return NF_ACCEPT; return NF_ACCEPT;
br = p->br; br = p->br;
...@@ -789,9 +779,9 @@ static unsigned int br_nf_forward_arp(const struct nf_hook_ops *ops, ...@@ -789,9 +779,9 @@ static unsigned int br_nf_forward_arp(const struct nf_hook_ops *ops,
nf_bridge_push_encap_header(skb); nf_bridge_push_encap_header(skb);
return NF_ACCEPT; return NF_ACCEPT;
} }
*d = (struct net_device *)in; *d = state->in;
NF_HOOK(NFPROTO_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in, NF_HOOK(NFPROTO_ARP, NF_ARP_FORWARD, skb, state->in,
(struct net_device *)out, br_nf_forward_finish); state->out, br_nf_forward_finish);
return NF_STOLEN; return NF_STOLEN;
} }
...@@ -859,9 +849,7 @@ static int br_nf_dev_queue_xmit(struct sk_buff *skb) ...@@ -859,9 +849,7 @@ static int br_nf_dev_queue_xmit(struct sk_buff *skb)
/* PF_BRIDGE/POST_ROUTING ********************************************/ /* PF_BRIDGE/POST_ROUTING ********************************************/
static unsigned int br_nf_post_routing(const struct nf_hook_ops *ops, static unsigned int br_nf_post_routing(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct nf_bridge_info *nf_bridge = skb->nf_bridge; struct nf_bridge_info *nf_bridge = skb->nf_bridge;
struct net_device *realoutdev = bridge_parent(skb->dev); struct net_device *realoutdev = bridge_parent(skb->dev);
...@@ -910,9 +898,7 @@ static unsigned int br_nf_post_routing(const struct nf_hook_ops *ops, ...@@ -910,9 +898,7 @@ static unsigned int br_nf_post_routing(const struct nf_hook_ops *ops,
* for the second time. */ * for the second time. */
static unsigned int ip_sabotage_in(const struct nf_hook_ops *ops, static unsigned int ip_sabotage_in(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
if (skb->nf_bridge && if (skb->nf_bridge &&
!(skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)) { !(skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)) {
......
...@@ -58,20 +58,18 @@ static const struct ebt_table frame_filter = { ...@@ -58,20 +58,18 @@ static const struct ebt_table frame_filter = {
static unsigned int static unsigned int
ebt_in_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, ebt_in_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
return ebt_do_table(ops->hooknum, skb, in, out, return ebt_do_table(ops->hooknum, skb, state->in, state->out,
dev_net(in)->xt.frame_filter); dev_net(state->in)->xt.frame_filter);
} }
static unsigned int static unsigned int
ebt_out_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, ebt_out_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
return ebt_do_table(ops->hooknum, skb, in, out, return ebt_do_table(ops->hooknum, skb, state->in, state->out,
dev_net(out)->xt.frame_filter); dev_net(state->out)->xt.frame_filter);
} }
static struct nf_hook_ops ebt_ops_filter[] __read_mostly = { static struct nf_hook_ops ebt_ops_filter[] __read_mostly = {
......
...@@ -58,20 +58,18 @@ static struct ebt_table frame_nat = { ...@@ -58,20 +58,18 @@ static struct ebt_table frame_nat = {
static unsigned int static unsigned int
ebt_nat_in(const struct nf_hook_ops *ops, struct sk_buff *skb, ebt_nat_in(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
return ebt_do_table(ops->hooknum, skb, in, out, return ebt_do_table(ops->hooknum, skb, state->in, state->out,
dev_net(in)->xt.frame_nat); dev_net(state->in)->xt.frame_nat);
} }
static unsigned int static unsigned int
ebt_nat_out(const struct nf_hook_ops *ops, struct sk_buff *skb, ebt_nat_out(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
return ebt_do_table(ops->hooknum, skb, in, out, return ebt_do_table(ops->hooknum, skb, state->in, state->out,
dev_net(out)->xt.frame_nat); dev_net(state->out)->xt.frame_nat);
} }
static struct nf_hook_ops ebt_ops_nat[] __read_mostly = { static struct nf_hook_ops ebt_ops_nat[] __read_mostly = {
......
...@@ -67,47 +67,43 @@ EXPORT_SYMBOL_GPL(nft_bridge_ip6hdr_validate); ...@@ -67,47 +67,43 @@ EXPORT_SYMBOL_GPL(nft_bridge_ip6hdr_validate);
static inline void nft_bridge_set_pktinfo_ipv4(struct nft_pktinfo *pkt, static inline void nft_bridge_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
const struct nf_hook_ops *ops, const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out)
{ {
if (nft_bridge_iphdr_validate(skb)) if (nft_bridge_iphdr_validate(skb))
nft_set_pktinfo_ipv4(pkt, ops, skb, in, out); nft_set_pktinfo_ipv4(pkt, ops, skb, state);
else else
nft_set_pktinfo(pkt, ops, skb, in, out); nft_set_pktinfo(pkt, ops, skb, state);
} }
static inline void nft_bridge_set_pktinfo_ipv6(struct nft_pktinfo *pkt, static inline void nft_bridge_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
const struct nf_hook_ops *ops, const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out)
{ {
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
if (nft_bridge_ip6hdr_validate(skb) && if (nft_bridge_ip6hdr_validate(skb) &&
nft_set_pktinfo_ipv6(pkt, ops, skb, in, out) == 0) nft_set_pktinfo_ipv6(pkt, ops, skb, state) == 0)
return; return;
#endif #endif
nft_set_pktinfo(pkt, ops, skb, in, out); nft_set_pktinfo(pkt, ops, skb, state);
} }
static unsigned int static unsigned int
nft_do_chain_bridge(const struct nf_hook_ops *ops, nft_do_chain_bridge(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct nft_pktinfo pkt; struct nft_pktinfo pkt;
switch (eth_hdr(skb)->h_proto) { switch (eth_hdr(skb)->h_proto) {
case htons(ETH_P_IP): case htons(ETH_P_IP):
nft_bridge_set_pktinfo_ipv4(&pkt, ops, skb, in, out); nft_bridge_set_pktinfo_ipv4(&pkt, ops, skb, state);
break; break;
case htons(ETH_P_IPV6): case htons(ETH_P_IPV6):
nft_bridge_set_pktinfo_ipv6(&pkt, ops, skb, in, out); nft_bridge_set_pktinfo_ipv6(&pkt, ops, skb, state);
break; break;
default: default:
nft_set_pktinfo(&pkt, ops, skb, in, out); nft_set_pktinfo(&pkt, ops, skb, state);
break; break;
} }
......
...@@ -89,9 +89,7 @@ static void dnrmg_send_peer(struct sk_buff *skb) ...@@ -89,9 +89,7 @@ static void dnrmg_send_peer(struct sk_buff *skb)
static unsigned int dnrmg_hook(const struct nf_hook_ops *ops, static unsigned int dnrmg_hook(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
dnrmg_send_peer(skb); dnrmg_send_peer(skb);
return NF_ACCEPT; return NF_ACCEPT;
......
...@@ -94,7 +94,7 @@ static void nf_ip_saveroute(const struct sk_buff *skb, ...@@ -94,7 +94,7 @@ static void nf_ip_saveroute(const struct sk_buff *skb,
{ {
struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry); struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry);
if (entry->hook == NF_INET_LOCAL_OUT) { if (entry->state.hook == NF_INET_LOCAL_OUT) {
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
rt_info->tos = iph->tos; rt_info->tos = iph->tos;
...@@ -109,7 +109,7 @@ static int nf_ip_reroute(struct sk_buff *skb, ...@@ -109,7 +109,7 @@ static int nf_ip_reroute(struct sk_buff *skb,
{ {
const struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry); const struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry);
if (entry->hook == NF_INET_LOCAL_OUT) { if (entry->state.hook == NF_INET_LOCAL_OUT) {
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
if (!(iph->tos == rt_info->tos && if (!(iph->tos == rt_info->tos &&
......
...@@ -248,8 +248,7 @@ struct arpt_entry *arpt_next_entry(const struct arpt_entry *entry) ...@@ -248,8 +248,7 @@ struct arpt_entry *arpt_next_entry(const struct arpt_entry *entry)
unsigned int arpt_do_table(struct sk_buff *skb, unsigned int arpt_do_table(struct sk_buff *skb,
unsigned int hook, unsigned int hook,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct xt_table *table) struct xt_table *table)
{ {
static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
...@@ -265,8 +264,8 @@ unsigned int arpt_do_table(struct sk_buff *skb, ...@@ -265,8 +264,8 @@ unsigned int arpt_do_table(struct sk_buff *skb,
if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
return NF_DROP; return NF_DROP;
indev = in ? in->name : nulldevname; indev = state->in ? state->in->name : nulldevname;
outdev = out ? out->name : nulldevname; outdev = state->out ? state->out->name : nulldevname;
local_bh_disable(); local_bh_disable();
addend = xt_write_recseq_begin(); addend = xt_write_recseq_begin();
...@@ -281,8 +280,8 @@ unsigned int arpt_do_table(struct sk_buff *skb, ...@@ -281,8 +280,8 @@ unsigned int arpt_do_table(struct sk_buff *skb,
e = get_entry(table_base, private->hook_entry[hook]); e = get_entry(table_base, private->hook_entry[hook]);
back = get_entry(table_base, private->underflow[hook]); back = get_entry(table_base, private->underflow[hook]);
acpar.in = in; acpar.in = state->in;
acpar.out = out; acpar.out = state->out;
acpar.hooknum = hook; acpar.hooknum = hook;
acpar.family = NFPROTO_ARP; acpar.family = NFPROTO_ARP;
acpar.hotdrop = false; acpar.hotdrop = false;
......
...@@ -28,12 +28,11 @@ static const struct xt_table packet_filter = { ...@@ -28,12 +28,11 @@ static const struct xt_table packet_filter = {
/* The work comes in here from netfilter.c */ /* The work comes in here from netfilter.c */
static unsigned int static unsigned int
arptable_filter_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, arptable_filter_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
const struct net *net = dev_net((in != NULL) ? in : out); const struct net *net = dev_net(state->in ? state->in : state->out);
return arpt_do_table(skb, ops->hooknum, in, out, return arpt_do_table(skb, ops->hooknum, state,
net->ipv4.arptable_filter); net->ipv4.arptable_filter);
} }
......
...@@ -288,8 +288,7 @@ struct ipt_entry *ipt_next_entry(const struct ipt_entry *entry) ...@@ -288,8 +288,7 @@ struct ipt_entry *ipt_next_entry(const struct ipt_entry *entry)
unsigned int unsigned int
ipt_do_table(struct sk_buff *skb, ipt_do_table(struct sk_buff *skb,
unsigned int hook, unsigned int hook,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct xt_table *table) struct xt_table *table)
{ {
static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
...@@ -306,8 +305,8 @@ ipt_do_table(struct sk_buff *skb, ...@@ -306,8 +305,8 @@ ipt_do_table(struct sk_buff *skb,
/* Initialization */ /* Initialization */
ip = ip_hdr(skb); ip = ip_hdr(skb);
indev = in ? in->name : nulldevname; indev = state->in ? state->in->name : nulldevname;
outdev = out ? out->name : nulldevname; outdev = state->out ? state->out->name : nulldevname;
/* We handle fragments by dealing with the first fragment as /* We handle fragments by dealing with the first fragment as
* if it was a normal packet. All other fragments are treated * if it was a normal packet. All other fragments are treated
* normally, except that they will NEVER match rules that ask * normally, except that they will NEVER match rules that ask
...@@ -317,8 +316,8 @@ ipt_do_table(struct sk_buff *skb, ...@@ -317,8 +316,8 @@ ipt_do_table(struct sk_buff *skb,
acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
acpar.thoff = ip_hdrlen(skb); acpar.thoff = ip_hdrlen(skb);
acpar.hotdrop = false; acpar.hotdrop = false;
acpar.in = in; acpar.in = state->in;
acpar.out = out; acpar.out = state->out;
acpar.family = NFPROTO_IPV4; acpar.family = NFPROTO_IPV4;
acpar.hooknum = hook; acpar.hooknum = hook;
...@@ -370,7 +369,7 @@ ipt_do_table(struct sk_buff *skb, ...@@ -370,7 +369,7 @@ ipt_do_table(struct sk_buff *skb,
#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE)
/* The packet is traced: log it */ /* The packet is traced: log it */
if (unlikely(skb->nf_trace)) if (unlikely(skb->nf_trace))
trace_packet(skb, hook, in, out, trace_packet(skb, hook, state->in, state->out,
table->name, private, e); table->name, private, e);
#endif #endif
/* Standard target? */ /* Standard target? */
......
...@@ -504,14 +504,12 @@ static void arp_print(struct arp_payload *payload) ...@@ -504,14 +504,12 @@ static void arp_print(struct arp_payload *payload)
static unsigned int static unsigned int
arp_mangle(const struct nf_hook_ops *ops, arp_mangle(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct arphdr *arp = arp_hdr(skb); struct arphdr *arp = arp_hdr(skb);
struct arp_payload *payload; struct arp_payload *payload;
struct clusterip_config *c; struct clusterip_config *c;
struct net *net = dev_net(in ? in : out); struct net *net = dev_net(state->in ? state->in : state->out);
/* we don't care about non-ethernet and non-ipv4 ARP */ /* we don't care about non-ethernet and non-ipv4 ARP */
if (arp->ar_hrd != htons(ARPHRD_ETHER) || if (arp->ar_hrd != htons(ARPHRD_ETHER) ||
...@@ -536,10 +534,10 @@ arp_mangle(const struct nf_hook_ops *ops, ...@@ -536,10 +534,10 @@ arp_mangle(const struct nf_hook_ops *ops,
* addresses on different interfacs. However, in the CLUSTERIP case * addresses on different interfacs. However, in the CLUSTERIP case
* this wouldn't work, since we didn't subscribe the mcast group on * this wouldn't work, since we didn't subscribe the mcast group on
* other interfaces */ * other interfaces */
if (c->dev != out) { if (c->dev != state->out) {
pr_debug("not mangling arp reply on different " pr_debug("not mangling arp reply on different "
"interface: cip'%s'-skb'%s'\n", "interface: cip'%s'-skb'%s'\n",
c->dev->name, out->name); c->dev->name, state->out->name);
clusterip_config_put(c); clusterip_config_put(c);
return NF_ACCEPT; return NF_ACCEPT;
} }
......
...@@ -300,11 +300,9 @@ synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) ...@@ -300,11 +300,9 @@ synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par)
static unsigned int ipv4_synproxy_hook(const struct nf_hook_ops *ops, static unsigned int ipv4_synproxy_hook(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *nhs)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct synproxy_net *snet = synproxy_pernet(dev_net(in ? : out)); struct synproxy_net *snet = synproxy_pernet(dev_net(nhs->in ? : nhs->out));
enum ip_conntrack_info ctinfo; enum ip_conntrack_info ctinfo;
struct nf_conn *ct; struct nf_conn *ct;
struct nf_conn_synproxy *synproxy; struct nf_conn_synproxy *synproxy;
......
...@@ -34,8 +34,7 @@ static const struct xt_table packet_filter = { ...@@ -34,8 +34,7 @@ static const struct xt_table packet_filter = {
static unsigned int static unsigned int
iptable_filter_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, iptable_filter_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
const struct net *net; const struct net *net;
...@@ -45,9 +44,8 @@ iptable_filter_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -45,9 +44,8 @@ iptable_filter_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
/* root is playing with raw sockets. */ /* root is playing with raw sockets. */
return NF_ACCEPT; return NF_ACCEPT;
net = dev_net((in != NULL) ? in : out); net = dev_net(state->in ? state->in : state->out);
return ipt_do_table(skb, ops->hooknum, in, out, return ipt_do_table(skb, ops->hooknum, state, net->ipv4.iptable_filter);
net->ipv4.iptable_filter);
} }
static struct nf_hook_ops *filter_ops __read_mostly; static struct nf_hook_ops *filter_ops __read_mostly;
......
...@@ -37,8 +37,9 @@ static const struct xt_table packet_mangler = { ...@@ -37,8 +37,9 @@ static const struct xt_table packet_mangler = {
}; };
static unsigned int static unsigned int
ipt_mangle_out(struct sk_buff *skb, const struct net_device *out) ipt_mangle_out(struct sk_buff *skb, const struct nf_hook_state *state)
{ {
struct net_device *out = state->out;
unsigned int ret; unsigned int ret;
const struct iphdr *iph; const struct iphdr *iph;
u_int8_t tos; u_int8_t tos;
...@@ -58,7 +59,7 @@ ipt_mangle_out(struct sk_buff *skb, const struct net_device *out) ...@@ -58,7 +59,7 @@ ipt_mangle_out(struct sk_buff *skb, const struct net_device *out)
daddr = iph->daddr; daddr = iph->daddr;
tos = iph->tos; tos = iph->tos;
ret = ipt_do_table(skb, NF_INET_LOCAL_OUT, NULL, out, ret = ipt_do_table(skb, NF_INET_LOCAL_OUT, state,
dev_net(out)->ipv4.iptable_mangle); dev_net(out)->ipv4.iptable_mangle);
/* Reroute for ANY change. */ /* Reroute for ANY change. */
if (ret != NF_DROP && ret != NF_STOLEN) { if (ret != NF_DROP && ret != NF_STOLEN) {
...@@ -81,18 +82,16 @@ ipt_mangle_out(struct sk_buff *skb, const struct net_device *out) ...@@ -81,18 +82,16 @@ ipt_mangle_out(struct sk_buff *skb, const struct net_device *out)
static unsigned int static unsigned int
iptable_mangle_hook(const struct nf_hook_ops *ops, iptable_mangle_hook(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
if (ops->hooknum == NF_INET_LOCAL_OUT) if (ops->hooknum == NF_INET_LOCAL_OUT)
return ipt_mangle_out(skb, out); return ipt_mangle_out(skb, state);
if (ops->hooknum == NF_INET_POST_ROUTING) if (ops->hooknum == NF_INET_POST_ROUTING)
return ipt_do_table(skb, ops->hooknum, in, out, return ipt_do_table(skb, ops->hooknum, state,
dev_net(out)->ipv4.iptable_mangle); dev_net(state->out)->ipv4.iptable_mangle);
/* PREROUTING/INPUT/FORWARD: */ /* PREROUTING/INPUT/FORWARD: */
return ipt_do_table(skb, ops->hooknum, in, out, return ipt_do_table(skb, ops->hooknum, state,
dev_net(in)->ipv4.iptable_mangle); dev_net(state->in)->ipv4.iptable_mangle);
} }
static struct nf_hook_ops *mangle_ops __read_mostly; static struct nf_hook_ops *mangle_ops __read_mostly;
......
...@@ -30,49 +30,40 @@ static const struct xt_table nf_nat_ipv4_table = { ...@@ -30,49 +30,40 @@ static const struct xt_table nf_nat_ipv4_table = {
static unsigned int iptable_nat_do_chain(const struct nf_hook_ops *ops, static unsigned int iptable_nat_do_chain(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct) struct nf_conn *ct)
{ {
struct net *net = nf_ct_net(ct); struct net *net = nf_ct_net(ct);
return ipt_do_table(skb, ops->hooknum, in, out, net->ipv4.nat_table); return ipt_do_table(skb, ops->hooknum, state, net->ipv4.nat_table);
} }
static unsigned int iptable_nat_ipv4_fn(const struct nf_hook_ops *ops, static unsigned int iptable_nat_ipv4_fn(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv4_fn(ops, skb, in, out, iptable_nat_do_chain); return nf_nat_ipv4_fn(ops, skb, state, iptable_nat_do_chain);
} }
static unsigned int iptable_nat_ipv4_in(const struct nf_hook_ops *ops, static unsigned int iptable_nat_ipv4_in(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv4_in(ops, skb, in, out, iptable_nat_do_chain); return nf_nat_ipv4_in(ops, skb, state, iptable_nat_do_chain);
} }
static unsigned int iptable_nat_ipv4_out(const struct nf_hook_ops *ops, static unsigned int iptable_nat_ipv4_out(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv4_out(ops, skb, in, out, iptable_nat_do_chain); return nf_nat_ipv4_out(ops, skb, state, iptable_nat_do_chain);
} }
static unsigned int iptable_nat_ipv4_local_fn(const struct nf_hook_ops *ops, static unsigned int iptable_nat_ipv4_local_fn(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv4_local_fn(ops, skb, in, out, iptable_nat_do_chain); return nf_nat_ipv4_local_fn(ops, skb, state, iptable_nat_do_chain);
} }
static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = { static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = {
......
...@@ -21,8 +21,7 @@ static const struct xt_table packet_raw = { ...@@ -21,8 +21,7 @@ static const struct xt_table packet_raw = {
/* The work comes in here from netfilter.c. */ /* The work comes in here from netfilter.c. */
static unsigned int static unsigned int
iptable_raw_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, iptable_raw_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
const struct net *net; const struct net *net;
...@@ -32,8 +31,8 @@ iptable_raw_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -32,8 +31,8 @@ iptable_raw_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
/* root is playing with raw sockets. */ /* root is playing with raw sockets. */
return NF_ACCEPT; return NF_ACCEPT;
net = dev_net((in != NULL) ? in : out); net = dev_net(state->in ? state->in : state->out);
return ipt_do_table(skb, ops->hooknum, in, out, net->ipv4.iptable_raw); return ipt_do_table(skb, ops->hooknum, state, net->ipv4.iptable_raw);
} }
static struct nf_hook_ops *rawtable_ops __read_mostly; static struct nf_hook_ops *rawtable_ops __read_mostly;
......
...@@ -38,9 +38,7 @@ static const struct xt_table security_table = { ...@@ -38,9 +38,7 @@ static const struct xt_table security_table = {
static unsigned int static unsigned int
iptable_security_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, iptable_security_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
const struct net *net; const struct net *net;
...@@ -50,8 +48,8 @@ iptable_security_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -50,8 +48,8 @@ iptable_security_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
/* Somebody is playing with raw sockets. */ /* Somebody is playing with raw sockets. */
return NF_ACCEPT; return NF_ACCEPT;
net = dev_net((in != NULL) ? in : out); net = dev_net(state->in ? state->in : state->out);
return ipt_do_table(skb, ops->hooknum, in, out, return ipt_do_table(skb, ops->hooknum, state,
net->ipv4.iptable_security); net->ipv4.iptable_security);
} }
......
...@@ -94,9 +94,7 @@ static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, ...@@ -94,9 +94,7 @@ static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
static unsigned int ipv4_helper(const struct nf_hook_ops *ops, static unsigned int ipv4_helper(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct nf_conn *ct; struct nf_conn *ct;
enum ip_conntrack_info ctinfo; enum ip_conntrack_info ctinfo;
...@@ -123,9 +121,7 @@ static unsigned int ipv4_helper(const struct nf_hook_ops *ops, ...@@ -123,9 +121,7 @@ static unsigned int ipv4_helper(const struct nf_hook_ops *ops,
static unsigned int ipv4_confirm(const struct nf_hook_ops *ops, static unsigned int ipv4_confirm(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct nf_conn *ct; struct nf_conn *ct;
enum ip_conntrack_info ctinfo; enum ip_conntrack_info ctinfo;
...@@ -149,24 +145,20 @@ static unsigned int ipv4_confirm(const struct nf_hook_ops *ops, ...@@ -149,24 +145,20 @@ static unsigned int ipv4_confirm(const struct nf_hook_ops *ops,
static unsigned int ipv4_conntrack_in(const struct nf_hook_ops *ops, static unsigned int ipv4_conntrack_in(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_conntrack_in(dev_net(in), PF_INET, ops->hooknum, skb); return nf_conntrack_in(dev_net(state->in), PF_INET, ops->hooknum, skb);
} }
static unsigned int ipv4_conntrack_local(const struct nf_hook_ops *ops, static unsigned int ipv4_conntrack_local(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
/* root is playing with raw sockets. */ /* root is playing with raw sockets. */
if (skb->len < sizeof(struct iphdr) || if (skb->len < sizeof(struct iphdr) ||
ip_hdrlen(skb) < sizeof(struct iphdr)) ip_hdrlen(skb) < sizeof(struct iphdr))
return NF_ACCEPT; return NF_ACCEPT;
return nf_conntrack_in(dev_net(out), PF_INET, ops->hooknum, skb); return nf_conntrack_in(dev_net(state->out), PF_INET, ops->hooknum, skb);
} }
/* Connection tracking may drop packets, but never alters them, so /* Connection tracking may drop packets, but never alters them, so
......
...@@ -63,9 +63,7 @@ static enum ip_defrag_users nf_ct_defrag_user(unsigned int hooknum, ...@@ -63,9 +63,7 @@ static enum ip_defrag_users nf_ct_defrag_user(unsigned int hooknum,
static unsigned int ipv4_conntrack_defrag(const struct nf_hook_ops *ops, static unsigned int ipv4_conntrack_defrag(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct sock *sk = skb->sk; struct sock *sk = skb->sk;
struct inet_sock *inet = inet_sk(skb->sk); struct inet_sock *inet = inet_sk(skb->sk);
......
...@@ -256,11 +256,10 @@ EXPORT_SYMBOL_GPL(nf_nat_icmp_reply_translation); ...@@ -256,11 +256,10 @@ EXPORT_SYMBOL_GPL(nf_nat_icmp_reply_translation);
unsigned int unsigned int
nf_nat_ipv4_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, nf_nat_ipv4_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)) struct nf_conn *ct))
{ {
struct nf_conn *ct; struct nf_conn *ct;
...@@ -309,7 +308,7 @@ nf_nat_ipv4_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -309,7 +308,7 @@ nf_nat_ipv4_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
if (!nf_nat_initialized(ct, maniptype)) { if (!nf_nat_initialized(ct, maniptype)) {
unsigned int ret; unsigned int ret;
ret = do_chain(ops, skb, in, out, ct); ret = do_chain(ops, skb, state, ct);
if (ret != NF_ACCEPT) if (ret != NF_ACCEPT)
return ret; return ret;
...@@ -323,7 +322,8 @@ nf_nat_ipv4_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -323,7 +322,8 @@ nf_nat_ipv4_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
pr_debug("Already setup manip %s for ct %p\n", pr_debug("Already setup manip %s for ct %p\n",
maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST", maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST",
ct); ct);
if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, out)) if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat,
state->out))
goto oif_changed; goto oif_changed;
} }
break; break;
...@@ -332,7 +332,7 @@ nf_nat_ipv4_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -332,7 +332,7 @@ nf_nat_ipv4_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
/* ESTABLISHED */ /* ESTABLISHED */
NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
ctinfo == IP_CT_ESTABLISHED_REPLY); ctinfo == IP_CT_ESTABLISHED_REPLY);
if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, out)) if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, state->out))
goto oif_changed; goto oif_changed;
} }
...@@ -346,17 +346,16 @@ EXPORT_SYMBOL_GPL(nf_nat_ipv4_fn); ...@@ -346,17 +346,16 @@ EXPORT_SYMBOL_GPL(nf_nat_ipv4_fn);
unsigned int unsigned int
nf_nat_ipv4_in(const struct nf_hook_ops *ops, struct sk_buff *skb, nf_nat_ipv4_in(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)) struct nf_conn *ct))
{ {
unsigned int ret; unsigned int ret;
__be32 daddr = ip_hdr(skb)->daddr; __be32 daddr = ip_hdr(skb)->daddr;
ret = nf_nat_ipv4_fn(ops, skb, in, out, do_chain); ret = nf_nat_ipv4_fn(ops, skb, state, do_chain);
if (ret != NF_DROP && ret != NF_STOLEN && if (ret != NF_DROP && ret != NF_STOLEN &&
daddr != ip_hdr(skb)->daddr) daddr != ip_hdr(skb)->daddr)
skb_dst_drop(skb); skb_dst_drop(skb);
...@@ -367,11 +366,10 @@ EXPORT_SYMBOL_GPL(nf_nat_ipv4_in); ...@@ -367,11 +366,10 @@ EXPORT_SYMBOL_GPL(nf_nat_ipv4_in);
unsigned int unsigned int
nf_nat_ipv4_out(const struct nf_hook_ops *ops, struct sk_buff *skb, nf_nat_ipv4_out(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)) struct nf_conn *ct))
{ {
#ifdef CONFIG_XFRM #ifdef CONFIG_XFRM
...@@ -386,7 +384,7 @@ nf_nat_ipv4_out(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -386,7 +384,7 @@ nf_nat_ipv4_out(const struct nf_hook_ops *ops, struct sk_buff *skb,
ip_hdrlen(skb) < sizeof(struct iphdr)) ip_hdrlen(skb) < sizeof(struct iphdr))
return NF_ACCEPT; return NF_ACCEPT;
ret = nf_nat_ipv4_fn(ops, skb, in, out, do_chain); ret = nf_nat_ipv4_fn(ops, skb, state, do_chain);
#ifdef CONFIG_XFRM #ifdef CONFIG_XFRM
if (ret != NF_DROP && ret != NF_STOLEN && if (ret != NF_DROP && ret != NF_STOLEN &&
!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && !(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
...@@ -410,11 +408,10 @@ EXPORT_SYMBOL_GPL(nf_nat_ipv4_out); ...@@ -410,11 +408,10 @@ EXPORT_SYMBOL_GPL(nf_nat_ipv4_out);
unsigned int unsigned int
nf_nat_ipv4_local_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, nf_nat_ipv4_local_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)) struct nf_conn *ct))
{ {
const struct nf_conn *ct; const struct nf_conn *ct;
...@@ -427,7 +424,7 @@ nf_nat_ipv4_local_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -427,7 +424,7 @@ nf_nat_ipv4_local_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
ip_hdrlen(skb) < sizeof(struct iphdr)) ip_hdrlen(skb) < sizeof(struct iphdr))
return NF_ACCEPT; return NF_ACCEPT;
ret = nf_nat_ipv4_fn(ops, skb, in, out, do_chain); ret = nf_nat_ipv4_fn(ops, skb, state, do_chain);
if (ret != NF_DROP && ret != NF_STOLEN && if (ret != NF_DROP && ret != NF_STOLEN &&
(ct = nf_ct_get(skb, &ctinfo)) != NULL) { (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
......
...@@ -17,13 +17,11 @@ ...@@ -17,13 +17,11 @@
static unsigned int static unsigned int
nft_do_chain_arp(const struct nf_hook_ops *ops, nft_do_chain_arp(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct nft_pktinfo pkt; struct nft_pktinfo pkt;
nft_set_pktinfo(&pkt, ops, skb, in, out); nft_set_pktinfo(&pkt, ops, skb, state);
return nft_do_chain(&pkt, ops); return nft_do_chain(&pkt, ops);
} }
......
...@@ -20,22 +20,18 @@ ...@@ -20,22 +20,18 @@
static unsigned int nft_do_chain_ipv4(const struct nf_hook_ops *ops, static unsigned int nft_do_chain_ipv4(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct nft_pktinfo pkt; struct nft_pktinfo pkt;
nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out); nft_set_pktinfo_ipv4(&pkt, ops, skb, state);
return nft_do_chain(&pkt, ops); return nft_do_chain(&pkt, ops);
} }
static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops, static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
if (unlikely(skb->len < sizeof(struct iphdr) || if (unlikely(skb->len < sizeof(struct iphdr) ||
ip_hdr(skb)->ihl < sizeof(struct iphdr) / 4)) { ip_hdr(skb)->ihl < sizeof(struct iphdr) / 4)) {
...@@ -45,7 +41,7 @@ static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops, ...@@ -45,7 +41,7 @@ static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops,
return NF_ACCEPT; return NF_ACCEPT;
} }
return nft_do_chain_ipv4(ops, skb, in, out, okfn); return nft_do_chain_ipv4(ops, skb, state);
} }
struct nft_af_info nft_af_ipv4 __read_mostly = { struct nft_af_info nft_af_ipv4 __read_mostly = {
......
...@@ -28,51 +28,42 @@ ...@@ -28,51 +28,42 @@
static unsigned int nft_nat_do_chain(const struct nf_hook_ops *ops, static unsigned int nft_nat_do_chain(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct) struct nf_conn *ct)
{ {
struct nft_pktinfo pkt; struct nft_pktinfo pkt;
nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out); nft_set_pktinfo_ipv4(&pkt, ops, skb, state);
return nft_do_chain(&pkt, ops); return nft_do_chain(&pkt, ops);
} }
static unsigned int nft_nat_ipv4_fn(const struct nf_hook_ops *ops, static unsigned int nft_nat_ipv4_fn(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv4_fn(ops, skb, in, out, nft_nat_do_chain); return nf_nat_ipv4_fn(ops, skb, state, nft_nat_do_chain);
} }
static unsigned int nft_nat_ipv4_in(const struct nf_hook_ops *ops, static unsigned int nft_nat_ipv4_in(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv4_in(ops, skb, in, out, nft_nat_do_chain); return nf_nat_ipv4_in(ops, skb, state, nft_nat_do_chain);
} }
static unsigned int nft_nat_ipv4_out(const struct nf_hook_ops *ops, static unsigned int nft_nat_ipv4_out(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv4_out(ops, skb, in, out, nft_nat_do_chain); return nf_nat_ipv4_out(ops, skb, state, nft_nat_do_chain);
} }
static unsigned int nft_nat_ipv4_local_fn(const struct nf_hook_ops *ops, static unsigned int nft_nat_ipv4_local_fn(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv4_local_fn(ops, skb, in, out, nft_nat_do_chain); return nf_nat_ipv4_local_fn(ops, skb, state, nft_nat_do_chain);
} }
static const struct nf_chain_type nft_chain_nat_ipv4 = { static const struct nf_chain_type nft_chain_nat_ipv4 = {
......
...@@ -23,9 +23,7 @@ ...@@ -23,9 +23,7 @@
static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops, static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
unsigned int ret; unsigned int ret;
struct nft_pktinfo pkt; struct nft_pktinfo pkt;
...@@ -39,7 +37,7 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops, ...@@ -39,7 +37,7 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
ip_hdrlen(skb) < sizeof(struct iphdr)) ip_hdrlen(skb) < sizeof(struct iphdr))
return NF_ACCEPT; return NF_ACCEPT;
nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out); nft_set_pktinfo_ipv4(&pkt, ops, skb, state);
mark = skb->mark; mark = skb->mark;
iph = ip_hdr(skb); iph = ip_hdr(skb);
......
...@@ -84,7 +84,7 @@ static void nf_ip6_saveroute(const struct sk_buff *skb, ...@@ -84,7 +84,7 @@ static void nf_ip6_saveroute(const struct sk_buff *skb,
{ {
struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry); struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry);
if (entry->hook == NF_INET_LOCAL_OUT) { if (entry->state.hook == NF_INET_LOCAL_OUT) {
const struct ipv6hdr *iph = ipv6_hdr(skb); const struct ipv6hdr *iph = ipv6_hdr(skb);
rt_info->daddr = iph->daddr; rt_info->daddr = iph->daddr;
...@@ -98,7 +98,7 @@ static int nf_ip6_reroute(struct sk_buff *skb, ...@@ -98,7 +98,7 @@ static int nf_ip6_reroute(struct sk_buff *skb,
{ {
struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry); struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry);
if (entry->hook == NF_INET_LOCAL_OUT) { if (entry->state.hook == NF_INET_LOCAL_OUT) {
const struct ipv6hdr *iph = ipv6_hdr(skb); const struct ipv6hdr *iph = ipv6_hdr(skb);
if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) || if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) ||
!ipv6_addr_equal(&iph->saddr, &rt_info->saddr) || !ipv6_addr_equal(&iph->saddr, &rt_info->saddr) ||
......
...@@ -317,8 +317,7 @@ ip6t_next_entry(const struct ip6t_entry *entry) ...@@ -317,8 +317,7 @@ ip6t_next_entry(const struct ip6t_entry *entry)
unsigned int unsigned int
ip6t_do_table(struct sk_buff *skb, ip6t_do_table(struct sk_buff *skb,
unsigned int hook, unsigned int hook,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct xt_table *table) struct xt_table *table)
{ {
static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
...@@ -333,8 +332,8 @@ ip6t_do_table(struct sk_buff *skb, ...@@ -333,8 +332,8 @@ ip6t_do_table(struct sk_buff *skb,
unsigned int addend; unsigned int addend;
/* Initialization */ /* Initialization */
indev = in ? in->name : nulldevname; indev = state->in ? state->in->name : nulldevname;
outdev = out ? out->name : nulldevname; outdev = state->out ? state->out->name : nulldevname;
/* We handle fragments by dealing with the first fragment as /* We handle fragments by dealing with the first fragment as
* if it was a normal packet. All other fragments are treated * if it was a normal packet. All other fragments are treated
* normally, except that they will NEVER match rules that ask * normally, except that they will NEVER match rules that ask
...@@ -342,8 +341,8 @@ ip6t_do_table(struct sk_buff *skb, ...@@ -342,8 +341,8 @@ ip6t_do_table(struct sk_buff *skb,
* rule is also a fragment-specific rule, non-fragments won't * rule is also a fragment-specific rule, non-fragments won't
* match it. */ * match it. */
acpar.hotdrop = false; acpar.hotdrop = false;
acpar.in = in; acpar.in = state->in;
acpar.out = out; acpar.out = state->out;
acpar.family = NFPROTO_IPV6; acpar.family = NFPROTO_IPV6;
acpar.hooknum = hook; acpar.hooknum = hook;
...@@ -393,7 +392,7 @@ ip6t_do_table(struct sk_buff *skb, ...@@ -393,7 +392,7 @@ ip6t_do_table(struct sk_buff *skb,
#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE)
/* The packet is traced: log it */ /* The packet is traced: log it */
if (unlikely(skb->nf_trace)) if (unlikely(skb->nf_trace))
trace_packet(skb, hook, in, out, trace_packet(skb, hook, state->in, state->out,
table->name, private, e); table->name, private, e);
#endif #endif
/* Standard target? */ /* Standard target? */
......
...@@ -315,11 +315,9 @@ synproxy_tg6(struct sk_buff *skb, const struct xt_action_param *par) ...@@ -315,11 +315,9 @@ synproxy_tg6(struct sk_buff *skb, const struct xt_action_param *par)
static unsigned int ipv6_synproxy_hook(const struct nf_hook_ops *ops, static unsigned int ipv6_synproxy_hook(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *nhs)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct synproxy_net *snet = synproxy_pernet(dev_net(in ? : out)); struct synproxy_net *snet = synproxy_pernet(dev_net(nhs->in ? : nhs->out));
enum ip_conntrack_info ctinfo; enum ip_conntrack_info ctinfo;
struct nf_conn *ct; struct nf_conn *ct;
struct nf_conn_synproxy *synproxy; struct nf_conn_synproxy *synproxy;
......
...@@ -33,13 +33,11 @@ static const struct xt_table packet_filter = { ...@@ -33,13 +33,11 @@ static const struct xt_table packet_filter = {
/* The work comes in here from netfilter.c. */ /* The work comes in here from netfilter.c. */
static unsigned int static unsigned int
ip6table_filter_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, ip6table_filter_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
const struct net *net = dev_net((in != NULL) ? in : out); const struct net *net = dev_net(state->in ? state->in : state->out);
return ip6t_do_table(skb, ops->hooknum, in, out, return ip6t_do_table(skb, ops->hooknum, state, net->ipv6.ip6table_filter);
net->ipv6.ip6table_filter);
} }
static struct nf_hook_ops *filter_ops __read_mostly; static struct nf_hook_ops *filter_ops __read_mostly;
......
...@@ -32,7 +32,7 @@ static const struct xt_table packet_mangler = { ...@@ -32,7 +32,7 @@ static const struct xt_table packet_mangler = {
}; };
static unsigned int static unsigned int
ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out) ip6t_mangle_out(struct sk_buff *skb, const struct nf_hook_state *state)
{ {
unsigned int ret; unsigned int ret;
struct in6_addr saddr, daddr; struct in6_addr saddr, daddr;
...@@ -57,8 +57,8 @@ ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out) ...@@ -57,8 +57,8 @@ ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out)
/* flowlabel and prio (includes version, which shouldn't change either */ /* flowlabel and prio (includes version, which shouldn't change either */
flowlabel = *((u_int32_t *)ipv6_hdr(skb)); flowlabel = *((u_int32_t *)ipv6_hdr(skb));
ret = ip6t_do_table(skb, NF_INET_LOCAL_OUT, NULL, out, ret = ip6t_do_table(skb, NF_INET_LOCAL_OUT, state,
dev_net(out)->ipv6.ip6table_mangle); dev_net(state->out)->ipv6.ip6table_mangle);
if (ret != NF_DROP && ret != NF_STOLEN && if (ret != NF_DROP && ret != NF_STOLEN &&
(!ipv6_addr_equal(&ipv6_hdr(skb)->saddr, &saddr) || (!ipv6_addr_equal(&ipv6_hdr(skb)->saddr, &saddr) ||
...@@ -77,17 +77,16 @@ ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out) ...@@ -77,17 +77,16 @@ ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out)
/* The work comes in here from netfilter.c. */ /* The work comes in here from netfilter.c. */
static unsigned int static unsigned int
ip6table_mangle_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, ip6table_mangle_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
if (ops->hooknum == NF_INET_LOCAL_OUT) if (ops->hooknum == NF_INET_LOCAL_OUT)
return ip6t_mangle_out(skb, out); return ip6t_mangle_out(skb, state);
if (ops->hooknum == NF_INET_POST_ROUTING) if (ops->hooknum == NF_INET_POST_ROUTING)
return ip6t_do_table(skb, ops->hooknum, in, out, return ip6t_do_table(skb, ops->hooknum, state,
dev_net(out)->ipv6.ip6table_mangle); dev_net(state->out)->ipv6.ip6table_mangle);
/* INPUT/FORWARD */ /* INPUT/FORWARD */
return ip6t_do_table(skb, ops->hooknum, in, out, return ip6t_do_table(skb, ops->hooknum, state,
dev_net(in)->ipv6.ip6table_mangle); dev_net(state->in)->ipv6.ip6table_mangle);
} }
static struct nf_hook_ops *mangle_ops __read_mostly; static struct nf_hook_ops *mangle_ops __read_mostly;
......
...@@ -32,49 +32,40 @@ static const struct xt_table nf_nat_ipv6_table = { ...@@ -32,49 +32,40 @@ static const struct xt_table nf_nat_ipv6_table = {
static unsigned int ip6table_nat_do_chain(const struct nf_hook_ops *ops, static unsigned int ip6table_nat_do_chain(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct) struct nf_conn *ct)
{ {
struct net *net = nf_ct_net(ct); struct net *net = nf_ct_net(ct);
return ip6t_do_table(skb, ops->hooknum, in, out, net->ipv6.ip6table_nat); return ip6t_do_table(skb, ops->hooknum, state, net->ipv6.ip6table_nat);
} }
static unsigned int ip6table_nat_fn(const struct nf_hook_ops *ops, static unsigned int ip6table_nat_fn(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv6_fn(ops, skb, in, out, ip6table_nat_do_chain); return nf_nat_ipv6_fn(ops, skb, state, ip6table_nat_do_chain);
} }
static unsigned int ip6table_nat_in(const struct nf_hook_ops *ops, static unsigned int ip6table_nat_in(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv6_in(ops, skb, in, out, ip6table_nat_do_chain); return nf_nat_ipv6_in(ops, skb, state, ip6table_nat_do_chain);
} }
static unsigned int ip6table_nat_out(const struct nf_hook_ops *ops, static unsigned int ip6table_nat_out(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv6_out(ops, skb, in, out, ip6table_nat_do_chain); return nf_nat_ipv6_out(ops, skb, state, ip6table_nat_do_chain);
} }
static unsigned int ip6table_nat_local_fn(const struct nf_hook_ops *ops, static unsigned int ip6table_nat_local_fn(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv6_local_fn(ops, skb, in, out, ip6table_nat_do_chain); return nf_nat_ipv6_local_fn(ops, skb, state, ip6table_nat_do_chain);
} }
static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = { static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
......
...@@ -20,13 +20,11 @@ static const struct xt_table packet_raw = { ...@@ -20,13 +20,11 @@ static const struct xt_table packet_raw = {
/* The work comes in here from netfilter.c. */ /* The work comes in here from netfilter.c. */
static unsigned int static unsigned int
ip6table_raw_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, ip6table_raw_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
const struct net *net = dev_net((in != NULL) ? in : out); const struct net *net = dev_net(state->in ? state->in : state->out);
return ip6t_do_table(skb, ops->hooknum, in, out, return ip6t_do_table(skb, ops->hooknum, state, net->ipv6.ip6table_raw);
net->ipv6.ip6table_raw);
} }
static struct nf_hook_ops *rawtable_ops __read_mostly; static struct nf_hook_ops *rawtable_ops __read_mostly;
......
...@@ -37,13 +37,11 @@ static const struct xt_table security_table = { ...@@ -37,13 +37,11 @@ static const struct xt_table security_table = {
static unsigned int static unsigned int
ip6table_security_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, ip6table_security_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
const struct net *net = dev_net((in != NULL) ? in : out); const struct net *net = dev_net(state->in ? state->in : state->out);
return ip6t_do_table(skb, ops->hooknum, in, out, return ip6t_do_table(skb, ops->hooknum, state,
net->ipv6.ip6table_security); net->ipv6.ip6table_security);
} }
......
...@@ -97,9 +97,7 @@ static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, ...@@ -97,9 +97,7 @@ static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
static unsigned int ipv6_helper(const struct nf_hook_ops *ops, static unsigned int ipv6_helper(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct nf_conn *ct; struct nf_conn *ct;
const struct nf_conn_help *help; const struct nf_conn_help *help;
...@@ -135,9 +133,7 @@ static unsigned int ipv6_helper(const struct nf_hook_ops *ops, ...@@ -135,9 +133,7 @@ static unsigned int ipv6_helper(const struct nf_hook_ops *ops,
static unsigned int ipv6_confirm(const struct nf_hook_ops *ops, static unsigned int ipv6_confirm(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct nf_conn *ct; struct nf_conn *ct;
enum ip_conntrack_info ctinfo; enum ip_conntrack_info ctinfo;
...@@ -171,25 +167,21 @@ static unsigned int ipv6_confirm(const struct nf_hook_ops *ops, ...@@ -171,25 +167,21 @@ static unsigned int ipv6_confirm(const struct nf_hook_ops *ops,
static unsigned int ipv6_conntrack_in(const struct nf_hook_ops *ops, static unsigned int ipv6_conntrack_in(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_conntrack_in(dev_net(in), PF_INET6, ops->hooknum, skb); return nf_conntrack_in(dev_net(state->in), PF_INET6, ops->hooknum, skb);
} }
static unsigned int ipv6_conntrack_local(const struct nf_hook_ops *ops, static unsigned int ipv6_conntrack_local(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
/* root is playing with raw sockets. */ /* root is playing with raw sockets. */
if (skb->len < sizeof(struct ipv6hdr)) { if (skb->len < sizeof(struct ipv6hdr)) {
net_notice_ratelimited("ipv6_conntrack_local: packet too short\n"); net_notice_ratelimited("ipv6_conntrack_local: packet too short\n");
return NF_ACCEPT; return NF_ACCEPT;
} }
return nf_conntrack_in(dev_net(out), PF_INET6, ops->hooknum, skb); return nf_conntrack_in(dev_net(state->out), PF_INET6, ops->hooknum, skb);
} }
static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
......
...@@ -54,9 +54,7 @@ static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, ...@@ -54,9 +54,7 @@ static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
static unsigned int ipv6_defrag(const struct nf_hook_ops *ops, static unsigned int ipv6_defrag(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct sk_buff *reasm; struct sk_buff *reasm;
...@@ -78,8 +76,8 @@ static unsigned int ipv6_defrag(const struct nf_hook_ops *ops, ...@@ -78,8 +76,8 @@ static unsigned int ipv6_defrag(const struct nf_hook_ops *ops,
nf_ct_frag6_consume_orig(reasm); nf_ct_frag6_consume_orig(reasm);
NF_HOOK_THRESH(NFPROTO_IPV6, ops->hooknum, reasm, NF_HOOK_THRESH(NFPROTO_IPV6, ops->hooknum, reasm,
(struct net_device *) in, (struct net_device *) out, state->in, state->out,
okfn, NF_IP6_PRI_CONNTRACK_DEFRAG + 1); state->okfn, NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
return NF_STOLEN; return NF_STOLEN;
} }
......
...@@ -263,11 +263,10 @@ EXPORT_SYMBOL_GPL(nf_nat_icmpv6_reply_translation); ...@@ -263,11 +263,10 @@ EXPORT_SYMBOL_GPL(nf_nat_icmpv6_reply_translation);
unsigned int unsigned int
nf_nat_ipv6_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, nf_nat_ipv6_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)) struct nf_conn *ct))
{ {
struct nf_conn *ct; struct nf_conn *ct;
...@@ -318,7 +317,7 @@ nf_nat_ipv6_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -318,7 +317,7 @@ nf_nat_ipv6_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
if (!nf_nat_initialized(ct, maniptype)) { if (!nf_nat_initialized(ct, maniptype)) {
unsigned int ret; unsigned int ret;
ret = do_chain(ops, skb, in, out, ct); ret = do_chain(ops, skb, state, ct);
if (ret != NF_ACCEPT) if (ret != NF_ACCEPT)
return ret; return ret;
...@@ -332,7 +331,7 @@ nf_nat_ipv6_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -332,7 +331,7 @@ nf_nat_ipv6_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
pr_debug("Already setup manip %s for ct %p\n", pr_debug("Already setup manip %s for ct %p\n",
maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST", maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST",
ct); ct);
if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, out)) if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, state->out))
goto oif_changed; goto oif_changed;
} }
break; break;
...@@ -341,7 +340,7 @@ nf_nat_ipv6_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -341,7 +340,7 @@ nf_nat_ipv6_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
/* ESTABLISHED */ /* ESTABLISHED */
NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
ctinfo == IP_CT_ESTABLISHED_REPLY); ctinfo == IP_CT_ESTABLISHED_REPLY);
if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, out)) if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, state->out))
goto oif_changed; goto oif_changed;
} }
...@@ -355,17 +354,16 @@ EXPORT_SYMBOL_GPL(nf_nat_ipv6_fn); ...@@ -355,17 +354,16 @@ EXPORT_SYMBOL_GPL(nf_nat_ipv6_fn);
unsigned int unsigned int
nf_nat_ipv6_in(const struct nf_hook_ops *ops, struct sk_buff *skb, nf_nat_ipv6_in(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)) struct nf_conn *ct))
{ {
unsigned int ret; unsigned int ret;
struct in6_addr daddr = ipv6_hdr(skb)->daddr; struct in6_addr daddr = ipv6_hdr(skb)->daddr;
ret = nf_nat_ipv6_fn(ops, skb, in, out, do_chain); ret = nf_nat_ipv6_fn(ops, skb, state, do_chain);
if (ret != NF_DROP && ret != NF_STOLEN && if (ret != NF_DROP && ret != NF_STOLEN &&
ipv6_addr_cmp(&daddr, &ipv6_hdr(skb)->daddr)) ipv6_addr_cmp(&daddr, &ipv6_hdr(skb)->daddr))
skb_dst_drop(skb); skb_dst_drop(skb);
...@@ -376,11 +374,10 @@ EXPORT_SYMBOL_GPL(nf_nat_ipv6_in); ...@@ -376,11 +374,10 @@ EXPORT_SYMBOL_GPL(nf_nat_ipv6_in);
unsigned int unsigned int
nf_nat_ipv6_out(const struct nf_hook_ops *ops, struct sk_buff *skb, nf_nat_ipv6_out(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)) struct nf_conn *ct))
{ {
#ifdef CONFIG_XFRM #ifdef CONFIG_XFRM
...@@ -394,7 +391,7 @@ nf_nat_ipv6_out(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -394,7 +391,7 @@ nf_nat_ipv6_out(const struct nf_hook_ops *ops, struct sk_buff *skb,
if (skb->len < sizeof(struct ipv6hdr)) if (skb->len < sizeof(struct ipv6hdr))
return NF_ACCEPT; return NF_ACCEPT;
ret = nf_nat_ipv6_fn(ops, skb, in, out, do_chain); ret = nf_nat_ipv6_fn(ops, skb, state, do_chain);
#ifdef CONFIG_XFRM #ifdef CONFIG_XFRM
if (ret != NF_DROP && ret != NF_STOLEN && if (ret != NF_DROP && ret != NF_STOLEN &&
!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && !(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
...@@ -418,11 +415,10 @@ EXPORT_SYMBOL_GPL(nf_nat_ipv6_out); ...@@ -418,11 +415,10 @@ EXPORT_SYMBOL_GPL(nf_nat_ipv6_out);
unsigned int unsigned int
nf_nat_ipv6_local_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, nf_nat_ipv6_local_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state,
unsigned int (*do_chain)(const struct nf_hook_ops *ops, unsigned int (*do_chain)(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct)) struct nf_conn *ct))
{ {
const struct nf_conn *ct; const struct nf_conn *ct;
...@@ -434,7 +430,7 @@ nf_nat_ipv6_local_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -434,7 +430,7 @@ nf_nat_ipv6_local_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
if (skb->len < sizeof(struct ipv6hdr)) if (skb->len < sizeof(struct ipv6hdr))
return NF_ACCEPT; return NF_ACCEPT;
ret = nf_nat_ipv6_fn(ops, skb, in, out, do_chain); ret = nf_nat_ipv6_fn(ops, skb, state, do_chain);
if (ret != NF_DROP && ret != NF_STOLEN && if (ret != NF_DROP && ret != NF_STOLEN &&
(ct = nf_ct_get(skb, &ctinfo)) != NULL) { (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
......
...@@ -18,14 +18,12 @@ ...@@ -18,14 +18,12 @@
static unsigned int nft_do_chain_ipv6(const struct nf_hook_ops *ops, static unsigned int nft_do_chain_ipv6(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct nft_pktinfo pkt; struct nft_pktinfo pkt;
/* malformed packet, drop it */ /* malformed packet, drop it */
if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0) if (nft_set_pktinfo_ipv6(&pkt, ops, skb, state) < 0)
return NF_DROP; return NF_DROP;
return nft_do_chain(&pkt, ops); return nft_do_chain(&pkt, ops);
...@@ -33,9 +31,7 @@ static unsigned int nft_do_chain_ipv6(const struct nf_hook_ops *ops, ...@@ -33,9 +31,7 @@ static unsigned int nft_do_chain_ipv6(const struct nf_hook_ops *ops,
static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops, static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
if (unlikely(skb->len < sizeof(struct ipv6hdr))) { if (unlikely(skb->len < sizeof(struct ipv6hdr))) {
if (net_ratelimit()) if (net_ratelimit())
...@@ -44,7 +40,7 @@ static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops, ...@@ -44,7 +40,7 @@ static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops,
return NF_ACCEPT; return NF_ACCEPT;
} }
return nft_do_chain_ipv6(ops, skb, in, out, okfn); return nft_do_chain_ipv6(ops, skb, state);
} }
struct nft_af_info nft_af_ipv6 __read_mostly = { struct nft_af_info nft_af_ipv6 __read_mostly = {
......
...@@ -26,51 +26,42 @@ ...@@ -26,51 +26,42 @@
static unsigned int nft_nat_do_chain(const struct nf_hook_ops *ops, static unsigned int nft_nat_do_chain(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state,
const struct net_device *out,
struct nf_conn *ct) struct nf_conn *ct)
{ {
struct nft_pktinfo pkt; struct nft_pktinfo pkt;
nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out); nft_set_pktinfo_ipv6(&pkt, ops, skb, state);
return nft_do_chain(&pkt, ops); return nft_do_chain(&pkt, ops);
} }
static unsigned int nft_nat_ipv6_fn(const struct nf_hook_ops *ops, static unsigned int nft_nat_ipv6_fn(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv6_fn(ops, skb, in, out, nft_nat_do_chain); return nf_nat_ipv6_fn(ops, skb, state, nft_nat_do_chain);
} }
static unsigned int nft_nat_ipv6_in(const struct nf_hook_ops *ops, static unsigned int nft_nat_ipv6_in(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv6_in(ops, skb, in, out, nft_nat_do_chain); return nf_nat_ipv6_in(ops, skb, state, nft_nat_do_chain);
} }
static unsigned int nft_nat_ipv6_out(const struct nf_hook_ops *ops, static unsigned int nft_nat_ipv6_out(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv6_out(ops, skb, in, out, nft_nat_do_chain); return nf_nat_ipv6_out(ops, skb, state, nft_nat_do_chain);
} }
static unsigned int nft_nat_ipv6_local_fn(const struct nf_hook_ops *ops, static unsigned int nft_nat_ipv6_local_fn(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return nf_nat_ipv6_local_fn(ops, skb, in, out, nft_nat_do_chain); return nf_nat_ipv6_local_fn(ops, skb, state, nft_nat_do_chain);
} }
static const struct nf_chain_type nft_chain_nat_ipv6 = { static const struct nf_chain_type nft_chain_nat_ipv6 = {
......
...@@ -24,9 +24,7 @@ ...@@ -24,9 +24,7 @@
static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops, static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
unsigned int ret; unsigned int ret;
struct nft_pktinfo pkt; struct nft_pktinfo pkt;
...@@ -35,7 +33,7 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops, ...@@ -35,7 +33,7 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
u32 mark, flowlabel; u32 mark, flowlabel;
/* malformed packet, drop it */ /* malformed packet, drop it */
if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0) if (nft_set_pktinfo_ipv6(&pkt, ops, skb, state) < 0)
return NF_DROP; return NF_DROP;
/* save source/dest address, mark, hoplimit, flowlabel, priority */ /* save source/dest address, mark, hoplimit, flowlabel, priority */
......
...@@ -120,12 +120,8 @@ EXPORT_SYMBOL(nf_unregister_hooks); ...@@ -120,12 +120,8 @@ EXPORT_SYMBOL(nf_unregister_hooks);
unsigned int nf_iterate(struct list_head *head, unsigned int nf_iterate(struct list_head *head,
struct sk_buff *skb, struct sk_buff *skb,
unsigned int hook, struct nf_hook_state *state,
const struct net_device *indev, struct nf_hook_ops **elemp)
const struct net_device *outdev,
struct nf_hook_ops **elemp,
int (*okfn)(struct sk_buff *),
int hook_thresh)
{ {
unsigned int verdict; unsigned int verdict;
...@@ -134,19 +130,19 @@ unsigned int nf_iterate(struct list_head *head, ...@@ -134,19 +130,19 @@ unsigned int nf_iterate(struct list_head *head,
* function because of risk of continuing from deleted element. * function because of risk of continuing from deleted element.
*/ */
list_for_each_entry_continue_rcu((*elemp), head, list) { list_for_each_entry_continue_rcu((*elemp), head, list) {
if (hook_thresh > (*elemp)->priority) if (state->thresh > (*elemp)->priority)
continue; continue;
/* Optimization: we don't need to hold module /* Optimization: we don't need to hold module
reference here, since function can't sleep. --RR */ reference here, since function can't sleep. --RR */
repeat: repeat:
verdict = (*elemp)->hook(*elemp, skb, indev, outdev, okfn); verdict = (*elemp)->hook(*elemp, skb, state);
if (verdict != NF_ACCEPT) { if (verdict != NF_ACCEPT) {
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
if (unlikely((verdict & NF_VERDICT_MASK) if (unlikely((verdict & NF_VERDICT_MASK)
> NF_MAX_VERDICT)) { > NF_MAX_VERDICT)) {
NFDEBUG("Evil return from %p(%u).\n", NFDEBUG("Evil return from %p(%u).\n",
(*elemp)->hook, hook); (*elemp)->hook, state->hook);
continue; continue;
} }
#endif #endif
...@@ -161,11 +157,7 @@ unsigned int nf_iterate(struct list_head *head, ...@@ -161,11 +157,7 @@ unsigned int nf_iterate(struct list_head *head,
/* Returns 1 if okfn() needs to be executed by the caller, /* Returns 1 if okfn() needs to be executed by the caller,
* -EPERM for NF_DROP, 0 otherwise. */ * -EPERM for NF_DROP, 0 otherwise. */
int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb, int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state)
struct net_device *indev,
struct net_device *outdev,
int (*okfn)(struct sk_buff *),
int hook_thresh)
{ {
struct nf_hook_ops *elem; struct nf_hook_ops *elem;
unsigned int verdict; unsigned int verdict;
...@@ -174,10 +166,11 @@ int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb, ...@@ -174,10 +166,11 @@ int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
/* We may already have this, but read-locks nest anyway */ /* We may already have this, but read-locks nest anyway */
rcu_read_lock(); rcu_read_lock();
elem = list_entry_rcu(&nf_hooks[pf][hook], struct nf_hook_ops, list); elem = list_entry_rcu(&nf_hooks[state->pf][state->hook],
struct nf_hook_ops, list);
next_hook: next_hook:
verdict = nf_iterate(&nf_hooks[pf][hook], skb, hook, indev, verdict = nf_iterate(&nf_hooks[state->pf][state->hook], skb, state,
outdev, &elem, okfn, hook_thresh); &elem);
if (verdict == NF_ACCEPT || verdict == NF_STOP) { if (verdict == NF_ACCEPT || verdict == NF_STOP) {
ret = 1; ret = 1;
} else if ((verdict & NF_VERDICT_MASK) == NF_DROP) { } else if ((verdict & NF_VERDICT_MASK) == NF_DROP) {
...@@ -186,8 +179,8 @@ int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb, ...@@ -186,8 +179,8 @@ int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
if (ret == 0) if (ret == 0)
ret = -EPERM; ret = -EPERM;
} else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) { } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
int err = nf_queue(skb, elem, pf, hook, indev, outdev, okfn, int err = nf_queue(skb, elem, state,
verdict >> NF_VERDICT_QBITS); verdict >> NF_VERDICT_QBITS);
if (err < 0) { if (err < 0) {
if (err == -ECANCELED) if (err == -ECANCELED)
goto next_hook; goto next_hook;
......
...@@ -1272,8 +1272,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af) ...@@ -1272,8 +1272,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
*/ */
static unsigned int static unsigned int
ip_vs_reply4(const struct nf_hook_ops *ops, struct sk_buff *skb, ip_vs_reply4(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
return ip_vs_out(ops->hooknum, skb, AF_INET); return ip_vs_out(ops->hooknum, skb, AF_INET);
} }
...@@ -1284,8 +1283,7 @@ ip_vs_reply4(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -1284,8 +1283,7 @@ ip_vs_reply4(const struct nf_hook_ops *ops, struct sk_buff *skb,
*/ */
static unsigned int static unsigned int
ip_vs_local_reply4(const struct nf_hook_ops *ops, struct sk_buff *skb, ip_vs_local_reply4(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
return ip_vs_out(ops->hooknum, skb, AF_INET); return ip_vs_out(ops->hooknum, skb, AF_INET);
} }
...@@ -1299,8 +1297,7 @@ ip_vs_local_reply4(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -1299,8 +1297,7 @@ ip_vs_local_reply4(const struct nf_hook_ops *ops, struct sk_buff *skb,
*/ */
static unsigned int static unsigned int
ip_vs_reply6(const struct nf_hook_ops *ops, struct sk_buff *skb, ip_vs_reply6(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
return ip_vs_out(ops->hooknum, skb, AF_INET6); return ip_vs_out(ops->hooknum, skb, AF_INET6);
} }
...@@ -1311,8 +1308,7 @@ ip_vs_reply6(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -1311,8 +1308,7 @@ ip_vs_reply6(const struct nf_hook_ops *ops, struct sk_buff *skb,
*/ */
static unsigned int static unsigned int
ip_vs_local_reply6(const struct nf_hook_ops *ops, struct sk_buff *skb, ip_vs_local_reply6(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
return ip_vs_out(ops->hooknum, skb, AF_INET6); return ip_vs_out(ops->hooknum, skb, AF_INET6);
} }
...@@ -1769,9 +1765,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) ...@@ -1769,9 +1765,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
*/ */
static unsigned int static unsigned int
ip_vs_remote_request4(const struct nf_hook_ops *ops, struct sk_buff *skb, ip_vs_remote_request4(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return ip_vs_in(ops->hooknum, skb, AF_INET); return ip_vs_in(ops->hooknum, skb, AF_INET);
} }
...@@ -1782,8 +1776,7 @@ ip_vs_remote_request4(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -1782,8 +1776,7 @@ ip_vs_remote_request4(const struct nf_hook_ops *ops, struct sk_buff *skb,
*/ */
static unsigned int static unsigned int
ip_vs_local_request4(const struct nf_hook_ops *ops, struct sk_buff *skb, ip_vs_local_request4(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
return ip_vs_in(ops->hooknum, skb, AF_INET); return ip_vs_in(ops->hooknum, skb, AF_INET);
} }
...@@ -1796,9 +1789,7 @@ ip_vs_local_request4(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -1796,9 +1789,7 @@ ip_vs_local_request4(const struct nf_hook_ops *ops, struct sk_buff *skb,
*/ */
static unsigned int static unsigned int
ip_vs_remote_request6(const struct nf_hook_ops *ops, struct sk_buff *skb, ip_vs_remote_request6(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return ip_vs_in(ops->hooknum, skb, AF_INET6); return ip_vs_in(ops->hooknum, skb, AF_INET6);
} }
...@@ -1809,8 +1800,7 @@ ip_vs_remote_request6(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -1809,8 +1800,7 @@ ip_vs_remote_request6(const struct nf_hook_ops *ops, struct sk_buff *skb,
*/ */
static unsigned int static unsigned int
ip_vs_local_request6(const struct nf_hook_ops *ops, struct sk_buff *skb, ip_vs_local_request6(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
return ip_vs_in(ops->hooknum, skb, AF_INET6); return ip_vs_in(ops->hooknum, skb, AF_INET6);
} }
...@@ -1829,8 +1819,7 @@ ip_vs_local_request6(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -1829,8 +1819,7 @@ ip_vs_local_request6(const struct nf_hook_ops *ops, struct sk_buff *skb,
*/ */
static unsigned int static unsigned int
ip_vs_forward_icmp(const struct nf_hook_ops *ops, struct sk_buff *skb, ip_vs_forward_icmp(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
int r; int r;
struct net *net; struct net *net;
...@@ -1851,8 +1840,7 @@ ip_vs_forward_icmp(const struct nf_hook_ops *ops, struct sk_buff *skb, ...@@ -1851,8 +1840,7 @@ ip_vs_forward_icmp(const struct nf_hook_ops *ops, struct sk_buff *skb,
#ifdef CONFIG_IP_VS_IPV6 #ifdef CONFIG_IP_VS_IPV6
static unsigned int static unsigned int
ip_vs_forward_icmp_v6(const struct nf_hook_ops *ops, struct sk_buff *skb, ip_vs_forward_icmp_v6(const struct nf_hook_ops *ops, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct nf_hook_state *state)
int (*okfn)(struct sk_buff *))
{ {
int r; int r;
struct net *net; struct net *net;
......
...@@ -14,16 +14,11 @@ ...@@ -14,16 +14,11 @@
/* core.c */ /* core.c */
unsigned int nf_iterate(struct list_head *head, struct sk_buff *skb, unsigned int nf_iterate(struct list_head *head, struct sk_buff *skb,
unsigned int hook, const struct net_device *indev, struct nf_hook_state *state, struct nf_hook_ops **elemp);
const struct net_device *outdev,
struct nf_hook_ops **elemp,
int (*okfn)(struct sk_buff *), int hook_thresh);
/* nf_queue.c */ /* nf_queue.c */
int nf_queue(struct sk_buff *skb, struct nf_hook_ops *elem, u_int8_t pf, int nf_queue(struct sk_buff *skb, struct nf_hook_ops *elem,
unsigned int hook, struct net_device *indev, struct nf_hook_state *state, unsigned int queuenum);
struct net_device *outdev, int (*okfn)(struct sk_buff *),
unsigned int queuenum);
int __init netfilter_queue_init(void); int __init netfilter_queue_init(void);
/* nf_log.c */ /* nf_log.c */
......
...@@ -47,11 +47,13 @@ EXPORT_SYMBOL(nf_unregister_queue_handler); ...@@ -47,11 +47,13 @@ EXPORT_SYMBOL(nf_unregister_queue_handler);
void nf_queue_entry_release_refs(struct nf_queue_entry *entry) void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
{ {
struct nf_hook_state *state = &entry->state;
/* Release those devices we held, or Alexey will kill me. */ /* Release those devices we held, or Alexey will kill me. */
if (entry->indev) if (state->in)
dev_put(entry->indev); dev_put(state->in);
if (entry->outdev) if (state->out)
dev_put(entry->outdev); dev_put(state->out);
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
if (entry->skb->nf_bridge) { if (entry->skb->nf_bridge) {
struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge; struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge;
...@@ -70,13 +72,15 @@ EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs); ...@@ -70,13 +72,15 @@ EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
/* Bump dev refs so they don't vanish while packet is out */ /* Bump dev refs so they don't vanish while packet is out */
bool nf_queue_entry_get_refs(struct nf_queue_entry *entry) bool nf_queue_entry_get_refs(struct nf_queue_entry *entry)
{ {
struct nf_hook_state *state = &entry->state;
if (!try_module_get(entry->elem->owner)) if (!try_module_get(entry->elem->owner))
return false; return false;
if (entry->indev) if (state->in)
dev_hold(entry->indev); dev_hold(state->in);
if (entry->outdev) if (state->out)
dev_hold(entry->outdev); dev_hold(state->out);
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
if (entry->skb->nf_bridge) { if (entry->skb->nf_bridge) {
struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge; struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge;
...@@ -100,12 +104,9 @@ EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs); ...@@ -100,12 +104,9 @@ EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs);
* through nf_reinject(). * through nf_reinject().
*/ */
int nf_queue(struct sk_buff *skb, int nf_queue(struct sk_buff *skb,
struct nf_hook_ops *elem, struct nf_hook_ops *elem,
u_int8_t pf, unsigned int hook, struct nf_hook_state *state,
struct net_device *indev, unsigned int queuenum)
struct net_device *outdev,
int (*okfn)(struct sk_buff *),
unsigned int queuenum)
{ {
int status = -ENOENT; int status = -ENOENT;
struct nf_queue_entry *entry = NULL; struct nf_queue_entry *entry = NULL;
...@@ -121,7 +122,7 @@ int nf_queue(struct sk_buff *skb, ...@@ -121,7 +122,7 @@ int nf_queue(struct sk_buff *skb,
goto err_unlock; goto err_unlock;
} }
afinfo = nf_get_afinfo(pf); afinfo = nf_get_afinfo(state->pf);
if (!afinfo) if (!afinfo)
goto err_unlock; goto err_unlock;
...@@ -134,11 +135,7 @@ int nf_queue(struct sk_buff *skb, ...@@ -134,11 +135,7 @@ int nf_queue(struct sk_buff *skb,
*entry = (struct nf_queue_entry) { *entry = (struct nf_queue_entry) {
.skb = skb, .skb = skb,
.elem = elem, .elem = elem,
.pf = pf, .state = *state,
.hook = hook,
.indev = indev,
.outdev = outdev,
.okfn = okfn,
.size = sizeof(*entry) + afinfo->route_key_size, .size = sizeof(*entry) + afinfo->route_key_size,
}; };
...@@ -184,30 +181,29 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) ...@@ -184,30 +181,29 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
} }
if (verdict == NF_ACCEPT) { if (verdict == NF_ACCEPT) {
afinfo = nf_get_afinfo(entry->pf); afinfo = nf_get_afinfo(entry->state.pf);
if (!afinfo || afinfo->reroute(skb, entry) < 0) if (!afinfo || afinfo->reroute(skb, entry) < 0)
verdict = NF_DROP; verdict = NF_DROP;
} }
entry->state.thresh = INT_MIN;
if (verdict == NF_ACCEPT) { if (verdict == NF_ACCEPT) {
next_hook: next_hook:
verdict = nf_iterate(&nf_hooks[entry->pf][entry->hook], verdict = nf_iterate(&nf_hooks[entry->state.pf][entry->state.hook],
skb, entry->hook, skb, &entry->state, &elem);
entry->indev, entry->outdev, &elem,
entry->okfn, INT_MIN);
} }
switch (verdict & NF_VERDICT_MASK) { switch (verdict & NF_VERDICT_MASK) {
case NF_ACCEPT: case NF_ACCEPT:
case NF_STOP: case NF_STOP:
local_bh_disable(); local_bh_disable();
entry->okfn(skb); entry->state.okfn(skb);
local_bh_enable(); local_bh_enable();
break; break;
case NF_QUEUE: case NF_QUEUE:
err = nf_queue(skb, elem, entry->pf, entry->hook, err = nf_queue(skb, elem, &entry->state,
entry->indev, entry->outdev, entry->okfn, verdict >> NF_VERDICT_QBITS);
verdict >> NF_VERDICT_QBITS);
if (err < 0) { if (err < 0) {
if (err == -ECANCELED) if (err == -ECANCELED)
goto next_hook; goto next_hook;
......
...@@ -314,13 +314,13 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, ...@@ -314,13 +314,13 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
if (entskb->tstamp.tv64) if (entskb->tstamp.tv64)
size += nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp)); size += nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp));
if (entry->hook <= NF_INET_FORWARD || if (entry->state.hook <= NF_INET_FORWARD ||
(entry->hook == NF_INET_POST_ROUTING && entskb->sk == NULL)) (entry->state.hook == NF_INET_POST_ROUTING && entskb->sk == NULL))
csum_verify = !skb_csum_unnecessary(entskb); csum_verify = !skb_csum_unnecessary(entskb);
else else
csum_verify = false; csum_verify = false;
outdev = entry->outdev; outdev = entry->state.out;
switch ((enum nfqnl_config_mode)ACCESS_ONCE(queue->copy_mode)) { switch ((enum nfqnl_config_mode)ACCESS_ONCE(queue->copy_mode)) {
case NFQNL_COPY_META: case NFQNL_COPY_META:
...@@ -368,23 +368,23 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, ...@@ -368,23 +368,23 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
return NULL; return NULL;
} }
nfmsg = nlmsg_data(nlh); nfmsg = nlmsg_data(nlh);
nfmsg->nfgen_family = entry->pf; nfmsg->nfgen_family = entry->state.pf;
nfmsg->version = NFNETLINK_V0; nfmsg->version = NFNETLINK_V0;
nfmsg->res_id = htons(queue->queue_num); nfmsg->res_id = htons(queue->queue_num);
nla = __nla_reserve(skb, NFQA_PACKET_HDR, sizeof(*pmsg)); nla = __nla_reserve(skb, NFQA_PACKET_HDR, sizeof(*pmsg));
pmsg = nla_data(nla); pmsg = nla_data(nla);
pmsg->hw_protocol = entskb->protocol; pmsg->hw_protocol = entskb->protocol;
pmsg->hook = entry->hook; pmsg->hook = entry->state.hook;
*packet_id_ptr = &pmsg->packet_id; *packet_id_ptr = &pmsg->packet_id;
indev = entry->indev; indev = entry->state.in;
if (indev) { if (indev) {
#if !IS_ENABLED(CONFIG_BRIDGE_NETFILTER) #if !IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
if (nla_put_be32(skb, NFQA_IFINDEX_INDEV, htonl(indev->ifindex))) if (nla_put_be32(skb, NFQA_IFINDEX_INDEV, htonl(indev->ifindex)))
goto nla_put_failure; goto nla_put_failure;
#else #else
if (entry->pf == PF_BRIDGE) { if (entry->state.pf == PF_BRIDGE) {
/* Case 1: indev is physical input device, we need to /* Case 1: indev is physical input device, we need to
* look for bridge group (when called from * look for bridge group (when called from
* netfilter_bridge) */ * netfilter_bridge) */
...@@ -414,7 +414,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, ...@@ -414,7 +414,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
if (nla_put_be32(skb, NFQA_IFINDEX_OUTDEV, htonl(outdev->ifindex))) if (nla_put_be32(skb, NFQA_IFINDEX_OUTDEV, htonl(outdev->ifindex)))
goto nla_put_failure; goto nla_put_failure;
#else #else
if (entry->pf == PF_BRIDGE) { if (entry->state.pf == PF_BRIDGE) {
/* Case 1: outdev is physical output device, we need to /* Case 1: outdev is physical output device, we need to
* look for bridge group (when called from * look for bridge group (when called from
* netfilter_bridge) */ * netfilter_bridge) */
...@@ -633,8 +633,8 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) ...@@ -633,8 +633,8 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
struct nfqnl_instance *queue; struct nfqnl_instance *queue;
struct sk_buff *skb, *segs; struct sk_buff *skb, *segs;
int err = -ENOBUFS; int err = -ENOBUFS;
struct net *net = dev_net(entry->indev ? struct net *net = dev_net(entry->state.in ?
entry->indev : entry->outdev); entry->state.in : entry->state.out);
struct nfnl_queue_net *q = nfnl_queue_pernet(net); struct nfnl_queue_net *q = nfnl_queue_pernet(net);
/* rcu_read_lock()ed by nf_hook_slow() */ /* rcu_read_lock()ed by nf_hook_slow() */
...@@ -647,7 +647,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) ...@@ -647,7 +647,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
skb = entry->skb; skb = entry->skb;
switch (entry->pf) { switch (entry->state.pf) {
case NFPROTO_IPV4: case NFPROTO_IPV4:
skb->protocol = htons(ETH_P_IP); skb->protocol = htons(ETH_P_IP);
break; break;
...@@ -757,11 +757,11 @@ nfqnl_set_mode(struct nfqnl_instance *queue, ...@@ -757,11 +757,11 @@ nfqnl_set_mode(struct nfqnl_instance *queue,
static int static int
dev_cmp(struct nf_queue_entry *entry, unsigned long ifindex) dev_cmp(struct nf_queue_entry *entry, unsigned long ifindex)
{ {
if (entry->indev) if (entry->state.in)
if (entry->indev->ifindex == ifindex) if (entry->state.in->ifindex == ifindex)
return 1; return 1;
if (entry->outdev) if (entry->state.out)
if (entry->outdev->ifindex == ifindex) if (entry->state.out->ifindex == ifindex)
return 1; return 1;
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
if (entry->skb->nf_bridge) { if (entry->skb->nf_bridge) {
......
...@@ -4852,21 +4852,17 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, ...@@ -4852,21 +4852,17 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb,
static unsigned int selinux_ipv4_forward(const struct nf_hook_ops *ops, static unsigned int selinux_ipv4_forward(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return selinux_ip_forward(skb, in, PF_INET); return selinux_ip_forward(skb, state->in, PF_INET);
} }
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static unsigned int selinux_ipv6_forward(const struct nf_hook_ops *ops, static unsigned int selinux_ipv6_forward(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return selinux_ip_forward(skb, in, PF_INET6); return selinux_ip_forward(skb, state->in, PF_INET6);
} }
#endif /* IPV6 */ #endif /* IPV6 */
...@@ -4914,9 +4910,7 @@ static unsigned int selinux_ip_output(struct sk_buff *skb, ...@@ -4914,9 +4910,7 @@ static unsigned int selinux_ip_output(struct sk_buff *skb,
static unsigned int selinux_ipv4_output(const struct nf_hook_ops *ops, static unsigned int selinux_ipv4_output(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return selinux_ip_output(skb, PF_INET); return selinux_ip_output(skb, PF_INET);
} }
...@@ -5091,21 +5085,17 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, ...@@ -5091,21 +5085,17 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb,
static unsigned int selinux_ipv4_postroute(const struct nf_hook_ops *ops, static unsigned int selinux_ipv4_postroute(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return selinux_ip_postroute(skb, out, PF_INET); return selinux_ip_postroute(skb, state->out, PF_INET);
} }
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static unsigned int selinux_ipv6_postroute(const struct nf_hook_ops *ops, static unsigned int selinux_ipv6_postroute(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
return selinux_ip_postroute(skb, out, PF_INET6); return selinux_ip_postroute(skb, state->out, PF_INET6);
} }
#endif /* IPV6 */ #endif /* IPV6 */
......
...@@ -23,9 +23,7 @@ ...@@ -23,9 +23,7 @@
static unsigned int smack_ipv6_output(const struct nf_hook_ops *ops, static unsigned int smack_ipv6_output(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct socket_smack *ssp; struct socket_smack *ssp;
struct smack_known *skp; struct smack_known *skp;
...@@ -42,9 +40,7 @@ static unsigned int smack_ipv6_output(const struct nf_hook_ops *ops, ...@@ -42,9 +40,7 @@ static unsigned int smack_ipv6_output(const struct nf_hook_ops *ops,
static unsigned int smack_ipv4_output(const struct nf_hook_ops *ops, static unsigned int smack_ipv4_output(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct nf_hook_state *state)
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{ {
struct socket_smack *ssp; struct socket_smack *ssp;
struct smack_known *skp; struct smack_known *skp;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment