Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Browse files Browse the repository at this point in the history
Pablo Neira Ayuso says:

====================
Netfilter updates for net-next

The following patchset contains Netfilter updates for your net-next
tree, they are:

1) Remove obsolete nf_log tracing from nf_tables, from Florian Westphal.

2) Add support for map lookups to numgen, random and hash expressions,
   from Laura Garcia.

3) Allow to register nat hooks for iptables and nftables at the same
   time. Patchset from Florian Westpha.

4) Timeout support for rbtree sets.

5) ip6_rpfilter works needs interface for link-local addresses, from
   Vincent Bernat.

6) Add nf_ct_hook and nf_nat_hook structures and use them.

7) Do not drop packets on packets raceing to insert conntrack entries
   into hashes, this is particularly a problem in nfqueue setups.

8) Address fallout from xt_osf separation to nf_osf, patches
   from Florian Westphal and Fernando Mancera.

9) Remove reference to struct nft_af_info, which doesn't exist anymore.
   From Taehee Yoo.

This batch comes with is a conflict between 25fd386 ("netfilter:
core: add missing __rcu annotation") in your tree and 2c205dd
("netfilter: add struct nf_nat_hook and use it") coming in this batch.
This conflict can be solved by leaving the __rcu tag on
__netfilter_net_init() - added by 25fd386 - and remove all code
related to nf_nat_decode_session_hook - which is gone after
2c205dd, as described by:

diff --cc net/netfilter/core.c
index e0ae4aae96f5,206fb2c4c319..168af54db975
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@@ -611,7 -580,13 +611,8 @@@ const struct nf_conntrack_zone nf_ct_zo
  EXPORT_SYMBOL_GPL(nf_ct_zone_dflt);
  #endif /* CONFIG_NF_CONNTRACK */

- static void __net_init __netfilter_net_init(struct nf_hook_entries **e, int max)
 -#ifdef CONFIG_NF_NAT_NEEDED
 -void (*nf_nat_decode_session_hook)(struct sk_buff *, struct flowi *);
 -EXPORT_SYMBOL(nf_nat_decode_session_hook);
 -#endif
 -
+ static void __net_init
+ __netfilter_net_init(struct nf_hook_entries __rcu **e, int max)
  {
  	int h;

I can also merge your net-next tree into nf-next, solve the conflict and
resend the pull request if you prefer so.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed May 23, 2018
2 parents 7c08c41 + 0c6bca7 commit fb83eb9
Show file tree
Hide file tree
Showing 30 changed files with 1,033 additions and 571 deletions.
34 changes: 27 additions & 7 deletions include/linux/netfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ struct nf_hook_ops {
struct net_device *dev;
void *priv;
u_int8_t pf;
bool nat_hook;
unsigned int hooknum;
/* Hooks are ordered in ascending priority. */
int priority;
Expand Down Expand Up @@ -321,18 +320,33 @@ int nf_route(struct net *net, struct dst_entry **dst, struct flowi *fl,
int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry);

#include <net/flow.h>
extern void (*nf_nat_decode_session_hook)(struct sk_buff *, struct flowi *);

struct nf_conn;
enum nf_nat_manip_type;
struct nlattr;
enum ip_conntrack_dir;

struct nf_nat_hook {
int (*parse_nat_setup)(struct nf_conn *ct, enum nf_nat_manip_type manip,
const struct nlattr *attr);
void (*decode_session)(struct sk_buff *skb, struct flowi *fl);
unsigned int (*manip_pkt)(struct sk_buff *skb, struct nf_conn *ct,
enum nf_nat_manip_type mtype,
enum ip_conntrack_dir dir);
};

extern struct nf_nat_hook __rcu *nf_nat_hook;

static inline void
nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
{
#ifdef CONFIG_NF_NAT_NEEDED
void (*decodefn)(struct sk_buff *, struct flowi *);
struct nf_nat_hook *nat_hook;

rcu_read_lock();
decodefn = rcu_dereference(nf_nat_decode_session_hook);
if (decodefn)
decodefn(skb, fl);
nat_hook = rcu_dereference(nf_nat_hook);
if (nat_hook->decode_session)
nat_hook->decode_session(skb, fl);
rcu_read_unlock();
#endif
}
Expand Down Expand Up @@ -374,13 +388,19 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)

extern void (*ip_ct_attach)(struct sk_buff *, const struct sk_buff *) __rcu;
void nf_ct_attach(struct sk_buff *, const struct sk_buff *);
extern void (*nf_ct_destroy)(struct nf_conntrack *) __rcu;
#else
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
#endif

struct nf_conn;
enum ip_conntrack_info;

struct nf_ct_hook {
int (*update)(struct net *net, struct sk_buff *skb);
void (*destroy)(struct nf_conntrack *);
};
extern struct nf_ct_hook __rcu *nf_ct_hook;

struct nlattr;

struct nfnl_ct_hook {
Expand Down
6 changes: 6 additions & 0 deletions include/linux/netfilter/nf_osf.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ enum osf_fmatch_states {
FMATCH_OPT_WRONG,
};

struct nf_osf_finger {
struct rcu_head rcu_head;
struct list_head finger_entry;
struct nf_osf_user_finger finger;
};

bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
int hooknum, struct net_device *in, struct net_device *out,
const struct nf_osf_info *info, struct net *net,
Expand Down
4 changes: 4 additions & 0 deletions include/net/netfilter/nf_nat.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,8 @@ static inline bool nf_nat_oif_changed(unsigned int hooknum,
#endif
}

int nf_nat_register_fn(struct net *net, const struct nf_hook_ops *ops,
const struct nf_hook_ops *nat_ops, unsigned int ops_count);
void nf_nat_unregister_fn(struct net *net, const struct nf_hook_ops *ops,
unsigned int ops_count);
#endif
11 changes: 4 additions & 7 deletions include/net/netfilter/nf_nat_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
unsigned int nf_nat_packet(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
unsigned int hooknum, struct sk_buff *skb);

unsigned int
nf_nat_inet_fn(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state);

int nf_xfrm_me_harder(struct net *net, struct sk_buff *skb, unsigned int family);

static inline int nf_nat_initialized(struct nf_conn *ct,
Expand All @@ -22,11 +26,4 @@ static inline int nf_nat_initialized(struct nf_conn *ct,
return ct->status & IPS_DST_NAT_DONE;
}

struct nlattr;

extern int
(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
enum nf_nat_manip_type manip,
const struct nlattr *attr);

#endif /* _NF_NAT_CORE_H */
52 changes: 4 additions & 48 deletions include/net/netfilter/nf_nat_l3proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,58 +44,14 @@ int nf_nat_icmp_reply_translation(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned int hooknum);

unsigned int nf_nat_ipv4_in(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state,
unsigned int (*do_chain)(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state));

unsigned int nf_nat_ipv4_out(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state,
unsigned int (*do_chain)(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state));

unsigned int nf_nat_ipv4_local_fn(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state,
unsigned int (*do_chain)(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state));

unsigned int nf_nat_ipv4_fn(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state,
unsigned int (*do_chain)(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state));

int nf_nat_icmpv6_reply_translation(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned int hooknum, unsigned int hdrlen);

unsigned int nf_nat_ipv6_in(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state,
unsigned int (*do_chain)(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state));

unsigned int nf_nat_ipv6_out(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state,
unsigned int (*do_chain)(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state));

unsigned int nf_nat_ipv6_local_fn(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state,
unsigned int (*do_chain)(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state));
int nf_nat_l3proto_ipv4_register_fn(struct net *net, const struct nf_hook_ops *ops);
void nf_nat_l3proto_ipv4_unregister_fn(struct net *net, const struct nf_hook_ops *ops);

unsigned int nf_nat_ipv6_fn(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state,
unsigned int (*do_chain)(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state));
int nf_nat_l3proto_ipv6_register_fn(struct net *net, const struct nf_hook_ops *ops);
void nf_nat_l3proto_ipv6_unregister_fn(struct net *net, const struct nf_hook_ops *ops);

#endif /* _NF_NAT_L3PROTO_H */
8 changes: 4 additions & 4 deletions include/net/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -885,8 +885,8 @@ enum nft_chain_types {
* @owner: module owner
* @hook_mask: mask of valid hooks
* @hooks: array of hook functions
* @init: chain initialization function
* @free: chain release function
* @ops_register: base chain register function
* @ops_unregister: base chain unregister function
*/
struct nft_chain_type {
const char *name;
Expand All @@ -895,8 +895,8 @@ struct nft_chain_type {
struct module *owner;
unsigned int hook_mask;
nf_hookfn *hooks[NF_MAX_HOOKS];
int (*init)(struct nft_ctx *ctx);
void (*free)(struct nft_ctx *ctx);
int (*ops_register)(struct net *net, const struct nf_hook_ops *ops);
void (*ops_unregister)(struct net *net, const struct nf_hook_ops *ops);
};

int nft_chain_validate_dependency(const struct nft_chain *chain,
Expand Down
2 changes: 0 additions & 2 deletions include/net/netns/nftables.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

#include <linux/list.h>

struct nft_af_info;

struct netns_nftables {
struct list_head tables;
struct list_head commit_list;
Expand Down
8 changes: 2 additions & 6 deletions include/uapi/linux/netfilter/nf_osf.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef _NF_OSF_H
#define _NF_OSF_H

#include <linux/types.h>

#define MAXGENRELEN 32

#define NF_OSF_GENRE (1 << 0)
Expand Down Expand Up @@ -57,12 +59,6 @@ struct nf_osf_user_finger {
struct nf_osf_opt opt[MAX_IPOPTLEN];
};

struct nf_osf_finger {
struct rcu_head rcu_head;
struct list_head finger_entry;
struct nf_osf_user_finger finger;
};

struct nf_osf_nlmsg {
struct nf_osf_user_finger f;
struct iphdr ip;
Expand Down
4 changes: 4 additions & 0 deletions include/uapi/linux/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,8 @@ enum nft_hash_types {
* @NFTA_HASH_SEED: seed value (NLA_U32)
* @NFTA_HASH_OFFSET: add this offset value to hash result (NLA_U32)
* @NFTA_HASH_TYPE: hash operation (NLA_U32: nft_hash_types)
* @NFTA_HASH_SET_NAME: name of the map to lookup (NLA_STRING)
* @NFTA_HASH_SET_ID: id of the map (NLA_U32)
*/
enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
Expand All @@ -866,6 +868,8 @@ enum nft_hash_attributes {
NFTA_HASH_SEED,
NFTA_HASH_OFFSET,
NFTA_HASH_TYPE,
NFTA_HASH_SET_NAME,
NFTA_HASH_SET_ID,
__NFTA_HASH_MAX,
};
#define NFTA_HASH_MAX (__NFTA_HASH_MAX - 1)
Expand Down
5 changes: 4 additions & 1 deletion net/ipv4/netfilter/ip_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -1783,6 +1783,8 @@ int ipt_register_table(struct net *net, const struct xt_table *table,

/* set res now, will see skbs right after nf_register_net_hooks */
WRITE_ONCE(*res, new_table);
if (!ops)
return 0;

ret = nf_register_net_hooks(net, ops, hweight32(table->valid_hooks));
if (ret != 0) {
Expand All @@ -1800,7 +1802,8 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
void ipt_unregister_table(struct net *net, struct xt_table *table,
const struct nf_hook_ops *ops)
{
nf_unregister_net_hooks(net, ops, hweight32(table->valid_hooks));
if (ops)
nf_unregister_net_hooks(net, ops, hweight32(table->valid_hooks));
__ipt_unregister_table(net, table);
}

Expand Down
85 changes: 43 additions & 42 deletions net/ipv4/netfilter/iptable_nat.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,69 +38,58 @@ static unsigned int iptable_nat_do_chain(void *priv,
return ipt_do_table(skb, state, state->net->ipv4.nat_table);
}

static unsigned int iptable_nat_ipv4_fn(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
return nf_nat_ipv4_fn(priv, skb, state, iptable_nat_do_chain);
}

static unsigned int iptable_nat_ipv4_in(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
return nf_nat_ipv4_in(priv, skb, state, iptable_nat_do_chain);
}

static unsigned int iptable_nat_ipv4_out(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
return nf_nat_ipv4_out(priv, skb, state, iptable_nat_do_chain);
}

static unsigned int iptable_nat_ipv4_local_fn(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
return nf_nat_ipv4_local_fn(priv, skb, state, iptable_nat_do_chain);
}

static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
/* Before packet filtering, change destination */
{
.hook = iptable_nat_ipv4_in,
.hook = iptable_nat_do_chain,
.pf = NFPROTO_IPV4,
.nat_hook = true,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_NAT_DST,
},
/* After packet filtering, change source */
{
.hook = iptable_nat_ipv4_out,
.hook = iptable_nat_do_chain,
.pf = NFPROTO_IPV4,
.nat_hook = true,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_NAT_SRC,
},
/* Before packet filtering, change destination */
{
.hook = iptable_nat_ipv4_local_fn,
.hook = iptable_nat_do_chain,
.pf = NFPROTO_IPV4,
.nat_hook = true,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_NAT_DST,
},
/* After packet filtering, change source */
{
.hook = iptable_nat_ipv4_fn,
.hook = iptable_nat_do_chain,
.pf = NFPROTO_IPV4,
.nat_hook = true,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_NAT_SRC,
},
};

static int ipt_nat_register_lookups(struct net *net)
{
int i, ret;

for (i = 0; i < ARRAY_SIZE(nf_nat_ipv4_ops); i++) {
ret = nf_nat_l3proto_ipv4_register_fn(net, &nf_nat_ipv4_ops[i]);
if (ret) {
while (i)
nf_nat_l3proto_ipv4_unregister_fn(net, &nf_nat_ipv4_ops[--i]);

return ret;
}
}

return 0;
}

static void ipt_nat_unregister_lookups(struct net *net)
{
int i;

for (i = 0; i < ARRAY_SIZE(nf_nat_ipv4_ops); i++)
nf_nat_l3proto_ipv4_unregister_fn(net, &nf_nat_ipv4_ops[i]);
}

static int __net_init iptable_nat_table_init(struct net *net)
{
struct ipt_replace *repl;
Expand All @@ -113,7 +102,18 @@ static int __net_init iptable_nat_table_init(struct net *net)
if (repl == NULL)
return -ENOMEM;
ret = ipt_register_table(net, &nf_nat_ipv4_table, repl,
nf_nat_ipv4_ops, &net->ipv4.nat_table);
NULL, &net->ipv4.nat_table);
if (ret < 0) {
kfree(repl);
return ret;
}

ret = ipt_nat_register_lookups(net);
if (ret < 0) {
ipt_unregister_table(net, net->ipv4.nat_table, NULL);
net->ipv4.nat_table = NULL;
}

kfree(repl);
return ret;
}
Expand All @@ -122,7 +122,8 @@ static void __net_exit iptable_nat_net_exit(struct net *net)
{
if (!net->ipv4.nat_table)
return;
ipt_unregister_table(net, net->ipv4.nat_table, nf_nat_ipv4_ops);
ipt_nat_unregister_lookups(net);
ipt_unregister_table(net, net->ipv4.nat_table, NULL);
net->ipv4.nat_table = NULL;
}

Expand Down
Loading

0 comments on commit fb83eb9

Please sign in to comment.