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/IPVS updates for net-next

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

1) Remove useless debug message when deleting IPVS service, from
   Yannick Brosseau.

2) Get rid of compilation warning when CONFIG_PROC_FS is unset in
   several spots of the IPVS code, from Arnd Bergmann.

3) Add prandom_u32 support to nft_meta, from Florian Westphal.

4) Remove unused variable in xt_osf, from Sudip Mukherjee.

5) Don't calculate IP checksum twice from netfilter ipv4 defrag hook
   since fixing af_packet defragmentation issues, from Joe Stringer.

6) On-demand hook registration for iptables from netns. Instead of
   registering the hooks for every available netns whenever we need
   one of the support tables, we register this on the specific netns
   that needs it, patchset from Florian Westphal.

7) Add missing port range selection to nf_tables masquerading support.

BTW, just for the record, there is a typo in the description of
5f6c253 ("netfilter: bridge: register hooks only when bridge
interface is added") that refers to the cluster match as deprecated, but
it is actually the CLUSTERIP target (which registers hooks
inconditionally) the one that is scheduled for removal.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 8, 2016
2 parents d24ad3f + 8a6bf5d commit 4c38cd6
Show file tree
Hide file tree
Showing 32 changed files with 626 additions and 353 deletions.
29 changes: 11 additions & 18 deletions include/linux/netfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,22 +141,6 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg);

#ifdef HAVE_JUMP_LABEL
extern struct static_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS];

static inline bool nf_hook_list_active(struct list_head *hook_list,
u_int8_t pf, unsigned int hook)
{
if (__builtin_constant_p(pf) &&
__builtin_constant_p(hook))
return static_key_false(&nf_hooks_needed[pf][hook]);

return !list_empty(hook_list);
}
#else
static inline bool nf_hook_list_active(struct list_head *hook_list,
u_int8_t pf, unsigned int hook)
{
return !list_empty(hook_list);
}
#endif

int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state);
Expand All @@ -177,9 +161,18 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
int (*okfn)(struct net *, struct sock *, struct sk_buff *),
int thresh)
{
struct list_head *hook_list = &net->nf.hooks[pf][hook];
struct list_head *hook_list;

#ifdef HAVE_JUMP_LABEL
if (__builtin_constant_p(pf) &&
__builtin_constant_p(hook) &&
!static_key_false(&nf_hooks_needed[pf][hook]))
return 1;
#endif

hook_list = &net->nf.hooks[pf][hook];

if (nf_hook_list_active(hook_list, pf, hook)) {
if (!list_empty(hook_list)) {
struct nf_hook_state state;

nf_hook_state_init(&state, hook_list, hook, thresh,
Expand Down
6 changes: 4 additions & 2 deletions include/linux/netfilter/x_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ struct xt_table {
u_int8_t af; /* address/protocol family */
int priority; /* hook order */

/* called when table is needed in the given netns */
int (*table_init)(struct net *net);

/* A unique name... */
const char name[XT_TABLE_MAXNAMELEN];
};
Expand Down Expand Up @@ -408,8 +411,7 @@ xt_get_per_cpu_counter(struct xt_counters *cnt, unsigned int cpu)
return cnt;
}

struct nf_hook_ops *xt_hook_link(const struct xt_table *, nf_hookfn *);
void xt_hook_unlink(const struct xt_table *, struct nf_hook_ops *);
struct nf_hook_ops *xt_hook_ops_alloc(const struct xt_table *, nf_hookfn *);

#ifdef CONFIG_COMPAT
#include <net/compat.h>
Expand Down
9 changes: 5 additions & 4 deletions include/linux/netfilter_arp/arp_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,11 @@ struct arpt_error {
}

extern void *arpt_alloc_initial_table(const struct xt_table *);
extern struct xt_table *arpt_register_table(struct net *net,
const struct xt_table *table,
const struct arpt_replace *repl);
extern void arpt_unregister_table(struct xt_table *table);
int arpt_register_table(struct net *net, const struct xt_table *table,
const struct arpt_replace *repl,
const struct nf_hook_ops *ops, struct xt_table **res);
void arpt_unregister_table(struct net *net, struct xt_table *table,
const struct nf_hook_ops *ops);
extern unsigned int arpt_do_table(struct sk_buff *skb,
const struct nf_hook_state *state,
struct xt_table *table);
Expand Down
9 changes: 5 additions & 4 deletions include/linux/netfilter_ipv4/ip_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@

extern void ipt_init(void) __init;

extern struct xt_table *ipt_register_table(struct net *net,
const struct xt_table *table,
const struct ipt_replace *repl);
extern void ipt_unregister_table(struct net *net, struct xt_table *table);
int ipt_register_table(struct net *net, const struct xt_table *table,
const struct ipt_replace *repl,
const struct nf_hook_ops *ops, struct xt_table **res);
void ipt_unregister_table(struct net *net, struct xt_table *table,
const struct nf_hook_ops *ops);

/* Standard entry. */
struct ipt_standard {
Expand Down
9 changes: 5 additions & 4 deletions include/linux/netfilter_ipv6/ip6_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@
extern void ip6t_init(void) __init;

extern void *ip6t_alloc_initial_table(const struct xt_table *);
extern struct xt_table *ip6t_register_table(struct net *net,
const struct xt_table *table,
const struct ip6t_replace *repl);
extern void ip6t_unregister_table(struct net *net, struct xt_table *table);
int ip6t_register_table(struct net *net, const struct xt_table *table,
const struct ip6t_replace *repl,
const struct nf_hook_ops *ops, struct xt_table **res);
void ip6t_unregister_table(struct net *net, struct xt_table *table,
const struct nf_hook_ops *ops);
extern unsigned int ip6t_do_table(struct sk_buff *skb,
const struct nf_hook_state *state,
struct xt_table *table);
Expand Down
4 changes: 3 additions & 1 deletion include/net/netfilter/nft_masq.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
#define _NFT_MASQ_H_

struct nft_masq {
u32 flags;
u32 flags;
enum nft_registers sreg_proto_min:8;
enum nft_registers sreg_proto_max:8;
};

extern const struct nla_policy nft_masq_policy[];
Expand Down
6 changes: 6 additions & 0 deletions include/uapi/linux/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,7 @@ enum nft_exthdr_attributes {
* @NFT_META_IIFGROUP: packet input interface group
* @NFT_META_OIFGROUP: packet output interface group
* @NFT_META_CGROUP: socket control group (skb->sk->sk_classid)
* @NFT_META_PRANDOM: a 32bit pseudo-random number
*/
enum nft_meta_keys {
NFT_META_LEN,
Expand All @@ -707,6 +708,7 @@ enum nft_meta_keys {
NFT_META_IIFGROUP,
NFT_META_OIFGROUP,
NFT_META_CGROUP,
NFT_META_PRANDOM,
};

/**
Expand Down Expand Up @@ -949,10 +951,14 @@ enum nft_nat_attributes {
* enum nft_masq_attributes - nf_tables masquerade expression attributes
*
* @NFTA_MASQ_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32)
* @NFTA_MASQ_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
* @NFTA_MASQ_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
*/
enum nft_masq_attributes {
NFTA_MASQ_UNSPEC,
NFTA_MASQ_FLAGS,
NFTA_MASQ_REG_PROTO_MIN,
NFTA_MASQ_REG_PROTO_MAX,
__NFTA_MASQ_MAX
};
#define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1)
Expand Down
1 change: 1 addition & 0 deletions lib/random32.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ void prandom_seed_full_state(struct rnd_state __percpu *pcpu_state)
prandom_warmup(state);
}
}
EXPORT_SYMBOL(prandom_seed_full_state);

/*
* Generate better values after random number generator
Expand Down
68 changes: 65 additions & 3 deletions net/bridge/br_netfilter_hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,20 @@
#include <net/addrconf.h>
#include <net/route.h>
#include <net/netfilter/br_netfilter.h>
#include <net/netns/generic.h>

#include <asm/uaccess.h>
#include "br_private.h"
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
#endif

static int brnf_net_id __read_mostly;

struct brnf_net {
bool enabled;
};

#ifdef CONFIG_SYSCTL
static struct ctl_table_header *brnf_sysctl_header;
static int brnf_call_iptables __read_mostly = 1;
Expand Down Expand Up @@ -938,6 +945,53 @@ static struct nf_hook_ops br_nf_ops[] __read_mostly = {
},
};

static int brnf_device_event(struct notifier_block *unused, unsigned long event,
void *ptr)
{
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
struct brnf_net *brnet;
struct net *net;
int ret;

if (event != NETDEV_REGISTER || !(dev->priv_flags & IFF_EBRIDGE))
return NOTIFY_DONE;

ASSERT_RTNL();

net = dev_net(dev);
brnet = net_generic(net, brnf_net_id);
if (brnet->enabled)
return NOTIFY_OK;

ret = nf_register_net_hooks(net, br_nf_ops, ARRAY_SIZE(br_nf_ops));
if (ret)
return NOTIFY_BAD;

brnet->enabled = true;
return NOTIFY_OK;
}

static void __net_exit brnf_exit_net(struct net *net)
{
struct brnf_net *brnet = net_generic(net, brnf_net_id);

if (!brnet->enabled)
return;

nf_unregister_net_hooks(net, br_nf_ops, ARRAY_SIZE(br_nf_ops));
brnet->enabled = false;
}

static struct pernet_operations brnf_net_ops __read_mostly = {
.exit = brnf_exit_net,
.id = &brnf_net_id,
.size = sizeof(struct brnf_net),
};

static struct notifier_block brnf_notifier __read_mostly = {
.notifier_call = brnf_device_event,
};

#ifdef CONFIG_SYSCTL
static
int brnf_sysctl_call_tables(struct ctl_table *ctl, int write,
Expand Down Expand Up @@ -1003,16 +1057,23 @@ static int __init br_netfilter_init(void)
{
int ret;

ret = nf_register_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
ret = register_pernet_subsys(&brnf_net_ops);
if (ret < 0)
return ret;

ret = register_netdevice_notifier(&brnf_notifier);
if (ret < 0) {
unregister_pernet_subsys(&brnf_net_ops);
return ret;
}

#ifdef CONFIG_SYSCTL
brnf_sysctl_header = register_net_sysctl(&init_net, "net/bridge", brnf_table);
if (brnf_sysctl_header == NULL) {
printk(KERN_WARNING
"br_netfilter: can't register to sysctl.\n");
nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
unregister_netdevice_notifier(&brnf_notifier);
unregister_pernet_subsys(&brnf_net_ops);
return -ENOMEM;
}
#endif
Expand All @@ -1024,7 +1085,8 @@ static int __init br_netfilter_init(void)
static void __exit br_netfilter_fini(void)
{
RCU_INIT_POINTER(nf_br_ops, NULL);
nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
unregister_netdevice_notifier(&brnf_notifier);
unregister_pernet_subsys(&brnf_net_ops);
#ifdef CONFIG_SYSCTL
unregister_net_sysctl_table(brnf_sysctl_header);
#endif
Expand Down
66 changes: 41 additions & 25 deletions net/ipv4/netfilter/arp_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -1780,9 +1780,29 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
return ret;
}

struct xt_table *arpt_register_table(struct net *net,
const struct xt_table *table,
const struct arpt_replace *repl)
static void __arpt_unregister_table(struct xt_table *table)
{
struct xt_table_info *private;
void *loc_cpu_entry;
struct module *table_owner = table->me;
struct arpt_entry *iter;

private = xt_unregister_table(table);

/* Decrease module usage counts and free resources */
loc_cpu_entry = private->entries;
xt_entry_foreach(iter, loc_cpu_entry, private->size)
cleanup_entry(iter);
if (private->number > private->initial_entries)
module_put(table_owner);
xt_free_table_info(private);
}

int arpt_register_table(struct net *net,
const struct xt_table *table,
const struct arpt_replace *repl,
const struct nf_hook_ops *ops,
struct xt_table **res)
{
int ret;
struct xt_table_info *newinfo;
Expand All @@ -1791,10 +1811,8 @@ struct xt_table *arpt_register_table(struct net *net,
struct xt_table *new_table;

newinfo = xt_alloc_table_info(repl->size);
if (!newinfo) {
ret = -ENOMEM;
goto out;
}
if (!newinfo)
return -ENOMEM;

loc_cpu_entry = newinfo->entries;
memcpy(loc_cpu_entry, repl->entries, repl->size);
Expand All @@ -1809,30 +1827,28 @@ struct xt_table *arpt_register_table(struct net *net,
ret = PTR_ERR(new_table);
goto out_free;
}
return new_table;

/* set res now, will see skbs right after nf_register_net_hooks */
WRITE_ONCE(*res, new_table);

ret = nf_register_net_hooks(net, ops, hweight32(table->valid_hooks));
if (ret != 0) {
__arpt_unregister_table(new_table);
*res = NULL;
}

return ret;

out_free:
xt_free_table_info(newinfo);
out:
return ERR_PTR(ret);
return ret;
}

void arpt_unregister_table(struct xt_table *table)
void arpt_unregister_table(struct net *net, struct xt_table *table,
const struct nf_hook_ops *ops)
{
struct xt_table_info *private;
void *loc_cpu_entry;
struct module *table_owner = table->me;
struct arpt_entry *iter;

private = xt_unregister_table(table);

/* Decrease module usage counts and free resources */
loc_cpu_entry = private->entries;
xt_entry_foreach(iter, loc_cpu_entry, private->size)
cleanup_entry(iter);
if (private->number > private->initial_entries)
module_put(table_owner);
xt_free_table_info(private);
nf_unregister_net_hooks(net, ops, hweight32(table->valid_hooks));
__arpt_unregister_table(table);
}

/* The built-in targets: standard (NULL) and error. */
Expand Down
Loading

0 comments on commit 4c38cd6

Please sign in to comment.