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, they are:

1) Add the reject expression for the nf_tables bridge family, this
   allows us to send explicit reject (TCP RST / ICMP dest unrech) to
   the packets matching a rule.

2) Simplify and consolidate the nf_tables set dumping logic. This uses
   netlink control->data to filter out depending on the request.

3) Perform garbage collection in xt_hashlimit using a workqueue instead
   of a timer, which is problematic when many entries are in place in
   the tables, from Eric Dumazet.

4) Remove leftover code from the removed ulog target support, from
   Paul Bolle.

5) Dump unmodified flags in the netfilter packet accounting when resetting
   counters, so userspace knows that a counter was in overquota situation,
   from Alexey Perevalov.

6) Fix wrong usage of the bitwise functions in nfnetlink_acct, also from
   Alexey.

7) Fix a crash when adding new set element with an empty NFTA_SET_ELEM_LIST
   attribute.

This patchset also includes a couple of cleanups for xt_LED from
Duan Jiong and for nf_conntrack_ipv4 (using coccinelle) from
Himangi Saraogi.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jul 31, 2014
2 parents 388070f + 7d5570c commit a173e55
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 135 deletions.
6 changes: 0 additions & 6 deletions include/net/netns/x_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,5 @@ struct netns_xt {
struct ebt_table *frame_filter;
struct ebt_table *frame_nat;
#endif
#if IS_ENABLED(CONFIG_IP_NF_TARGET_ULOG)
bool ulog_warn_deprecated;
#endif
#if IS_ENABLED(CONFIG_BRIDGE_EBT_ULOG)
bool ebt_ulog_warn_deprecated;
#endif
};
#endif
6 changes: 6 additions & 0 deletions net/bridge/netfilter/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ config NFT_BRIDGE_META
help
Add support for bridge dedicated meta key.

config NFT_BRIDGE_REJECT
tristate "Netfilter nf_tables bridge reject support"
depends on NFT_REJECT && NFT_REJECT_IPV4 && NFT_REJECT_IPV6
help
Add support to reject packets.

config NF_LOG_BRIDGE
tristate "Bridge packet logging"

Expand Down
2 changes: 1 addition & 1 deletion net/bridge/netfilter/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

obj-$(CONFIG_NF_TABLES_BRIDGE) += nf_tables_bridge.o
obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o
obj-$(CONFIG_NFT_BRIDGE_REJECT) += nft_reject_bridge.o

# packet logging
obj-$(CONFIG_NF_LOG_BRIDGE) += nf_log_bridge.o
Expand Down Expand Up @@ -36,5 +37,4 @@ obj-$(CONFIG_BRIDGE_EBT_SNAT) += ebt_snat.o

# watchers
obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o
obj-$(CONFIG_BRIDGE_EBT_ULOG) += ebt_ulog.o
obj-$(CONFIG_BRIDGE_EBT_NFLOG) += ebt_nflog.o
67 changes: 67 additions & 0 deletions net/bridge/netfilter/nft_reject_bridge.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2014 Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/netlink.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h>
#include <net/netfilter/nft_reject.h>

static void nft_reject_bridge_eval(const struct nft_expr *expr,
struct nft_data data[NFT_REG_MAX + 1],
const struct nft_pktinfo *pkt)
{
switch (eth_hdr(pkt->skb)->h_proto) {
case htons(ETH_P_IP):
return nft_reject_ipv4_eval(expr, data, pkt);
case htons(ETH_P_IPV6):
return nft_reject_ipv6_eval(expr, data, pkt);
default:
/* No explicit way to reject this protocol, drop it. */
data[NFT_REG_VERDICT].verdict = NF_DROP;
break;
}
}

static struct nft_expr_type nft_reject_bridge_type;
static const struct nft_expr_ops nft_reject_bridge_ops = {
.type = &nft_reject_bridge_type,
.size = NFT_EXPR_SIZE(sizeof(struct nft_reject)),
.eval = nft_reject_bridge_eval,
.init = nft_reject_init,
.dump = nft_reject_dump,
};

static struct nft_expr_type nft_reject_bridge_type __read_mostly = {
.family = NFPROTO_BRIDGE,
.name = "reject",
.ops = &nft_reject_bridge_ops,
.policy = nft_reject_policy,
.maxattr = NFTA_REJECT_MAX,
.owner = THIS_MODULE,
};

static int __init nft_reject_bridge_module_init(void)
{
return nft_register_expr(&nft_reject_bridge_type);
}

static void __exit nft_reject_bridge_module_exit(void)
{
nft_unregister_expr(&nft_reject_bridge_type);
}

module_init(nft_reject_bridge_module_init);
module_exit(nft_reject_bridge_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
MODULE_ALIAS_NFT_AF_EXPR(AF_BRIDGE, "reject");
1 change: 0 additions & 1 deletion net/ipv4/netfilter/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
obj-$(CONFIG_IP_NF_TARGET_SYNPROXY) += ipt_SYNPROXY.o
obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o

# generic ARP tables
obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ static struct nf_sockopt_ops so_getorigdst = {
.pf = PF_INET,
.get_optmin = SO_ORIGINAL_DST,
.get_optmax = SO_ORIGINAL_DST+1,
.get = &getorigdst,
.get = getorigdst,
.owner = THIS_MODULE,
};

Expand Down
137 changes: 33 additions & 104 deletions net/netfilter/nf_tables_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -2247,87 +2247,15 @@ static int nf_tables_set_notify(const struct nft_ctx *ctx,
return err;
}

static int nf_tables_dump_sets_table(struct nft_ctx *ctx, struct sk_buff *skb,
struct netlink_callback *cb)
{
const struct nft_set *set;
unsigned int idx = 0, s_idx = cb->args[0];

if (cb->args[1])
return skb->len;

rcu_read_lock();
cb->seq = ctx->net->nft.base_seq;

list_for_each_entry_rcu(set, &ctx->table->sets, list) {
if (idx < s_idx)
goto cont;
if (nf_tables_fill_set(skb, ctx, set, NFT_MSG_NEWSET,
NLM_F_MULTI) < 0) {
cb->args[0] = idx;
goto done;
}
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
cont:
idx++;
}
cb->args[1] = 1;
done:
rcu_read_unlock();
return skb->len;
}

static int nf_tables_dump_sets_family(struct nft_ctx *ctx, struct sk_buff *skb,
struct netlink_callback *cb)
{
const struct nft_set *set;
unsigned int idx, s_idx = cb->args[0];
struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2];

if (cb->args[1])
return skb->len;

rcu_read_lock();
cb->seq = ctx->net->nft.base_seq;

list_for_each_entry_rcu(table, &ctx->afi->tables, list) {
if (cur_table) {
if (cur_table != table)
continue;

cur_table = NULL;
}
ctx->table = table;
idx = 0;
list_for_each_entry_rcu(set, &ctx->table->sets, list) {
if (idx < s_idx)
goto cont;
if (nf_tables_fill_set(skb, ctx, set, NFT_MSG_NEWSET,
NLM_F_MULTI) < 0) {
cb->args[0] = idx;
cb->args[2] = (unsigned long) table;
goto done;
}
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
cont:
idx++;
}
}
cb->args[1] = 1;
done:
rcu_read_unlock();
return skb->len;
}

static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb,
struct netlink_callback *cb)
static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
{
const struct nft_set *set;
unsigned int idx, s_idx = cb->args[0];
struct nft_af_info *afi;
struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2];
struct net *net = sock_net(skb->sk);
int cur_family = cb->args[3];
struct nft_ctx *ctx = cb->data, ctx_set;

if (cb->args[1])
return skb->len;
Expand All @@ -2336,28 +2264,34 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb,
cb->seq = net->nft.base_seq;

list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
if (ctx->afi && ctx->afi != afi)
continue;

if (cur_family) {
if (afi->family != cur_family)
continue;

cur_family = 0;
}

list_for_each_entry_rcu(table, &afi->tables, list) {
if (ctx->table && ctx->table != table)
continue;

if (cur_table) {
if (cur_table != table)
continue;

cur_table = NULL;
}

ctx->table = table;
ctx->afi = afi;
idx = 0;
list_for_each_entry_rcu(set, &ctx->table->sets, list) {
list_for_each_entry_rcu(set, &table->sets, list) {
if (idx < s_idx)
goto cont;
if (nf_tables_fill_set(skb, ctx, set,

ctx_set = *ctx;
ctx_set.table = table;
ctx_set.afi = afi;
if (nf_tables_fill_set(skb, &ctx_set, set,
NFT_MSG_NEWSET,
NLM_F_MULTI) < 0) {
cb->args[0] = idx;
Expand All @@ -2379,31 +2313,10 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb,
return skb->len;
}

static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
static int nf_tables_dump_sets_done(struct netlink_callback *cb)
{
const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
struct nlattr *nla[NFTA_SET_MAX + 1];
struct nft_ctx ctx;
int err, ret;

err = nlmsg_parse(cb->nlh, sizeof(*nfmsg), nla, NFTA_SET_MAX,
nft_set_policy);
if (err < 0)
return err;

err = nft_ctx_init_from_setattr(&ctx, cb->skb, cb->nlh, (void *)nla);
if (err < 0)
return err;

if (ctx.table == NULL) {
if (ctx.afi == NULL)
ret = nf_tables_dump_sets_all(&ctx, skb, cb);
else
ret = nf_tables_dump_sets_family(&ctx, skb, cb);
} else
ret = nf_tables_dump_sets_table(&ctx, skb, cb);

return ret;
kfree(cb->data);
return 0;
}

#define NFT_SET_INACTIVE (1 << 15) /* Internal set flag */
Expand All @@ -2426,7 +2339,17 @@ static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb,
if (nlh->nlmsg_flags & NLM_F_DUMP) {
struct netlink_dump_control c = {
.dump = nf_tables_dump_sets,
.done = nf_tables_dump_sets_done,
};
struct nft_ctx *ctx_dump;

ctx_dump = kmalloc(sizeof(*ctx_dump), GFP_KERNEL);
if (ctx_dump == NULL)
return -ENOMEM;

*ctx_dump = ctx;
c.data = ctx_dump;

return netlink_dump_start(nlsk, skb, nlh, &c);
}

Expand Down Expand Up @@ -3150,6 +3073,9 @@ static int nf_tables_newsetelem(struct sock *nlsk, struct sk_buff *skb,
struct nft_ctx ctx;
int rem, err = 0;

if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
return -EINVAL;

err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla, true);
if (err < 0)
return err;
Expand Down Expand Up @@ -3233,6 +3159,9 @@ static int nf_tables_delsetelem(struct sock *nlsk, struct sk_buff *skb,
struct nft_ctx ctx;
int rem, err = 0;

if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
return -EINVAL;

err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla, false);
if (err < 0)
return err;
Expand Down
12 changes: 8 additions & 4 deletions net/netfilter/nfnetlink_acct.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct nf_acct {
};

#define NFACCT_F_QUOTA (NFACCT_F_QUOTA_PKTS | NFACCT_F_QUOTA_BYTES)
#define NFACCT_OVERQUOTA_BIT 2 /* NFACCT_F_OVERQUOTA */

static int
nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb,
Expand Down Expand Up @@ -77,7 +78,8 @@ nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb,
smp_mb__before_atomic();
/* reset overquota flag if quota is enabled. */
if ((matching->flags & NFACCT_F_QUOTA))
clear_bit(NFACCT_F_OVERQUOTA, &matching->flags);
clear_bit(NFACCT_OVERQUOTA_BIT,
&matching->flags);
return 0;
}
return -EBUSY;
Expand Down Expand Up @@ -129,6 +131,7 @@ nfnl_acct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
struct nfgenmsg *nfmsg;
unsigned int flags = portid ? NLM_F_MULTI : 0;
u64 pkts, bytes;
u32 old_flags;

event |= NFNL_SUBSYS_ACCT << 8;
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
Expand All @@ -143,12 +146,13 @@ nfnl_acct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
if (nla_put_string(skb, NFACCT_NAME, acct->name))
goto nla_put_failure;

old_flags = acct->flags;
if (type == NFNL_MSG_ACCT_GET_CTRZERO) {
pkts = atomic64_xchg(&acct->pkts, 0);
bytes = atomic64_xchg(&acct->bytes, 0);
smp_mb__before_atomic();
if (acct->flags & NFACCT_F_QUOTA)
clear_bit(NFACCT_F_OVERQUOTA, &acct->flags);
clear_bit(NFACCT_OVERQUOTA_BIT, &acct->flags);
} else {
pkts = atomic64_read(&acct->pkts);
bytes = atomic64_read(&acct->bytes);
Expand All @@ -160,7 +164,7 @@ nfnl_acct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
if (acct->flags & NFACCT_F_QUOTA) {
u64 *quota = (u64 *)acct->data;

if (nla_put_be32(skb, NFACCT_FLAGS, htonl(acct->flags)) ||
if (nla_put_be32(skb, NFACCT_FLAGS, htonl(old_flags)) ||
nla_put_be64(skb, NFACCT_QUOTA, cpu_to_be64(*quota)))
goto nla_put_failure;
}
Expand Down Expand Up @@ -412,7 +416,7 @@ int nfnl_acct_overquota(const struct sk_buff *skb, struct nf_acct *nfacct)
ret = now > *quota;

if (now >= *quota &&
!test_and_set_bit(NFACCT_F_OVERQUOTA, &nfacct->flags)) {
!test_and_set_bit(NFACCT_OVERQUOTA_BIT, &nfacct->flags)) {
nfnl_overquota_report(nfacct);
}

Expand Down
4 changes: 1 addition & 3 deletions net/netfilter/xt_LED.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,7 @@ static int led_tg_check(const struct xt_tgchk_param *par)

err = led_trigger_register(&ledinternal->netfilter_led_trigger);
if (err) {
pr_warning("led_trigger_register() failed\n");
if (err == -EEXIST)
pr_warning("Trigger name is already in use.\n");
pr_err("Trigger name is already in use.\n");
goto exit_alloc;
}

Expand Down
Loading

0 comments on commit a173e55

Please sign in to comment.