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 net-next:

1) Use nfnetlink_unicast() instead of netlink_unicast() in nft_compat.

2) Remove call to nf_ct_l4proto_find() in flowtable offload timeout
   fixup.

3) CLUSTERIP registers ARP hook on demand, from Florian.

4) Use clusterip_net to store pernet warning, also from Florian.

5) Remove struct netns_xt, from Florian Westphal.

6) Enable ebtables hooks in initns on demand, from Florian.

7) Allow to filter conntrack netlink dump per status bits,
   from Florian Westphal.

8) Register x_tables hooks in initns on demand, from Florian.

9) Remove queue_handler from per-netns structure, again from Florian.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 11, 2021
2 parents d3432bf + 8702997 commit 6f45933
Show file tree
Hide file tree
Showing 30 changed files with 468 additions and 248 deletions.
6 changes: 3 additions & 3 deletions include/linux/netfilter/x_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,6 @@ 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 @@ -452,6 +449,9 @@ xt_get_per_cpu_counter(struct xt_counters *cnt, unsigned int cpu)

struct nf_hook_ops *xt_hook_ops_alloc(const struct xt_table *, nf_hookfn *);

int xt_register_template(const struct xt_table *t, int(*table_init)(struct net *net));
void xt_unregister_template(const struct xt_table *t);

#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
#include <net/compat.h>

Expand Down
2 changes: 2 additions & 0 deletions include/linux/netfilter_bridge/ebtables.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,6 @@ static inline bool ebt_invalid_target(int target)
return (target < -NUM_STANDARD_TARGETS || target >= 0);
}

int ebt_register_template(const struct ebt_table *t, int(*table_init)(struct net *net));
void ebt_unregister_template(const struct ebt_table *t);
#endif
2 changes: 0 additions & 2 deletions include/net/net_namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include <net/netns/ieee802154_6lowpan.h>
#include <net/netns/sctp.h>
#include <net/netns/netfilter.h>
#include <net/netns/x_tables.h>
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
#include <net/netns/conntrack.h>
#endif
Expand Down Expand Up @@ -133,7 +132,6 @@ struct net {
#endif
#ifdef CONFIG_NETFILTER
struct netns_nf nf;
struct netns_xt xt;
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct netns_ct ct;
#endif
Expand Down
4 changes: 2 additions & 2 deletions include/net/netfilter/nf_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ struct nf_queue_handler {
void (*nf_hook_drop)(struct net *net);
};

void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh);
void nf_unregister_queue_handler(struct net *net);
void nf_register_queue_handler(const struct nf_queue_handler *qh);
void nf_unregister_queue_handler(void);
void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);

void nf_queue_entry_get_refs(struct nf_queue_entry *entry);
Expand Down
1 change: 0 additions & 1 deletion include/net/netns/netfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ struct netns_nf {
#if defined CONFIG_PROC_FS
struct proc_dir_entry *proc_netfilter;
#endif
const struct nf_queue_handler __rcu *queue_handler;
const struct nf_logger __rcu *nf_loggers[NFPROTO_NUMPROTO];
#ifdef CONFIG_SYSCTL
struct ctl_table_header *nf_log_dir_header;
Expand Down
12 changes: 0 additions & 12 deletions include/net/netns/x_tables.h

This file was deleted.

1 change: 1 addition & 0 deletions include/uapi/linux/netfilter/nfnetlink_conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ enum ctattr_type {
CTA_LABELS_MASK,
CTA_SYNPROXY,
CTA_FILTER,
CTA_STATUS_MASK,
__CTA_MAX
};
#define CTA_MAX (__CTA_MAX - 1)
Expand Down
17 changes: 14 additions & 3 deletions net/bridge/netfilter/ebtable_broute.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ static const struct nf_hook_ops ebt_ops_broute = {
.priority = NF_BR_PRI_FIRST,
};

static int __net_init broute_net_init(struct net *net)
static int broute_table_init(struct net *net)
{
return ebt_register_table(net, &broute_table, &ebt_ops_broute);
}
Expand All @@ -114,19 +114,30 @@ static void __net_exit broute_net_exit(struct net *net)
}

static struct pernet_operations broute_net_ops = {
.init = broute_net_init,
.exit = broute_net_exit,
.pre_exit = broute_net_pre_exit,
};

static int __init ebtable_broute_init(void)
{
return register_pernet_subsys(&broute_net_ops);
int ret = ebt_register_template(&broute_table, broute_table_init);

if (ret)
return ret;

ret = register_pernet_subsys(&broute_net_ops);
if (ret) {
ebt_unregister_template(&broute_table);
return ret;
}

return 0;
}

static void __exit ebtable_broute_fini(void)
{
unregister_pernet_subsys(&broute_net_ops);
ebt_unregister_template(&broute_table);
}

module_init(ebtable_broute_init);
Expand Down
17 changes: 14 additions & 3 deletions net/bridge/netfilter/ebtable_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ static const struct nf_hook_ops ebt_ops_filter[] = {
},
};

static int __net_init frame_filter_net_init(struct net *net)
static int frame_filter_table_init(struct net *net)
{
return ebt_register_table(net, &frame_filter, ebt_ops_filter);
}
Expand All @@ -102,19 +102,30 @@ static void __net_exit frame_filter_net_exit(struct net *net)
}

static struct pernet_operations frame_filter_net_ops = {
.init = frame_filter_net_init,
.exit = frame_filter_net_exit,
.pre_exit = frame_filter_net_pre_exit,
};

static int __init ebtable_filter_init(void)
{
return register_pernet_subsys(&frame_filter_net_ops);
int ret = ebt_register_template(&frame_filter, frame_filter_table_init);

if (ret)
return ret;

ret = register_pernet_subsys(&frame_filter_net_ops);
if (ret) {
ebt_unregister_template(&frame_filter);
return ret;
}

return 0;
}

static void __exit ebtable_filter_fini(void)
{
unregister_pernet_subsys(&frame_filter_net_ops);
ebt_unregister_template(&frame_filter);
}

module_init(ebtable_filter_init);
Expand Down
17 changes: 14 additions & 3 deletions net/bridge/netfilter/ebtable_nat.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ static const struct nf_hook_ops ebt_ops_nat[] = {
},
};

static int __net_init frame_nat_net_init(struct net *net)
static int frame_nat_table_init(struct net *net)
{
return ebt_register_table(net, &frame_nat, ebt_ops_nat);
}
Expand All @@ -101,19 +101,30 @@ static void __net_exit frame_nat_net_exit(struct net *net)
}

static struct pernet_operations frame_nat_net_ops = {
.init = frame_nat_net_init,
.exit = frame_nat_net_exit,
.pre_exit = frame_nat_net_pre_exit,
};

static int __init ebtable_nat_init(void)
{
return register_pernet_subsys(&frame_nat_net_ops);
int ret = ebt_register_template(&frame_nat, frame_nat_table_init);

if (ret)
return ret;

ret = register_pernet_subsys(&frame_nat_net_ops);
if (ret) {
ebt_unregister_template(&frame_nat);
return ret;
}

return ret;
}

static void __exit ebtable_nat_fini(void)
{
unregister_pernet_subsys(&frame_nat_net_ops);
ebt_unregister_template(&frame_nat);
}

module_init(ebtable_nat_init);
Expand Down
109 changes: 95 additions & 14 deletions net/bridge/netfilter/ebtables.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,16 @@ struct ebt_pernet {
struct list_head tables;
};

struct ebt_template {
struct list_head list;
char name[EBT_TABLE_MAXNAMELEN];
struct module *owner;
/* called when table is needed in the given netns */
int (*table_init)(struct net *net);
};

static unsigned int ebt_pernet_id __read_mostly;
static LIST_HEAD(template_tables);
static DEFINE_MUTEX(ebt_mutex);

#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
Expand Down Expand Up @@ -309,41 +318,65 @@ unsigned int ebt_do_table(struct sk_buff *skb,

/* If it succeeds, returns element and locks mutex */
static inline void *
find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
find_inlist_lock_noload(struct net *net, const char *name, int *error,
struct mutex *mutex)
{
struct {
struct list_head list;
char name[EBT_FUNCTION_MAXNAMELEN];
} *e;
struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
struct ebt_template *tmpl;
struct ebt_table *table;

mutex_lock(mutex);
list_for_each_entry(e, head, list) {
if (strcmp(e->name, name) == 0)
return e;
list_for_each_entry(table, &ebt_net->tables, list) {
if (strcmp(table->name, name) == 0)
return table;
}

list_for_each_entry(tmpl, &template_tables, list) {
if (strcmp(name, tmpl->name) == 0) {
struct module *owner = tmpl->owner;

if (!try_module_get(owner))
goto out;

mutex_unlock(mutex);

*error = tmpl->table_init(net);
if (*error) {
module_put(owner);
return NULL;
}

mutex_lock(mutex);
module_put(owner);
break;
}
}

list_for_each_entry(table, &ebt_net->tables, list) {
if (strcmp(table->name, name) == 0)
return table;
}

out:
*error = -ENOENT;
mutex_unlock(mutex);
return NULL;
}

static void *
find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
find_inlist_lock(struct net *net, const char *name, const char *prefix,
int *error, struct mutex *mutex)
{
return try_then_request_module(
find_inlist_lock_noload(head, name, error, mutex),
find_inlist_lock_noload(net, name, error, mutex),
"%s%s", prefix, name);
}

static inline struct ebt_table *
find_table_lock(struct net *net, const char *name, int *error,
struct mutex *mutex)
{
struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);

return find_inlist_lock(&ebt_net->tables, name,
"ebtable_", error, mutex);
return find_inlist_lock(net, name, "ebtable_", error, mutex);
}

static inline void ebt_free_table_info(struct ebt_table_info *info)
Expand Down Expand Up @@ -1258,6 +1291,54 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table,
return ret;
}

int ebt_register_template(const struct ebt_table *t, int (*table_init)(struct net *net))
{
struct ebt_template *tmpl;

mutex_lock(&ebt_mutex);
list_for_each_entry(tmpl, &template_tables, list) {
if (WARN_ON_ONCE(strcmp(t->name, tmpl->name) == 0)) {
mutex_unlock(&ebt_mutex);
return -EEXIST;
}
}

tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
if (!tmpl) {
mutex_unlock(&ebt_mutex);
return -ENOMEM;
}

tmpl->table_init = table_init;
strscpy(tmpl->name, t->name, sizeof(tmpl->name));
tmpl->owner = t->me;
list_add(&tmpl->list, &template_tables);

mutex_unlock(&ebt_mutex);
return 0;
}
EXPORT_SYMBOL(ebt_register_template);

void ebt_unregister_template(const struct ebt_table *t)
{
struct ebt_template *tmpl;

mutex_lock(&ebt_mutex);
list_for_each_entry(tmpl, &template_tables, list) {
if (strcmp(t->name, tmpl->name))
continue;

list_del(&tmpl->list);
mutex_unlock(&ebt_mutex);
kfree(tmpl);
return;
}

mutex_unlock(&ebt_mutex);
WARN_ON_ONCE(1);
}
EXPORT_SYMBOL(ebt_unregister_template);

static struct ebt_table *__ebt_find_table(struct net *net, const char *name)
{
struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
Expand Down
Loading

0 comments on commit 6f45933

Please sign in to comment.