diff options
| -rw-r--r-- | include/net/netns/x_tables.h | 6 | ||||
| -rw-r--r-- | net/bridge/netfilter/Kconfig | 6 | ||||
| -rw-r--r-- | net/bridge/netfilter/Makefile | 2 | ||||
| -rw-r--r-- | net/bridge/netfilter/nft_reject_bridge.c | 67 | ||||
| -rw-r--r-- | net/ipv4/netfilter/Makefile | 1 | ||||
| -rw-r--r-- | net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 2 | ||||
| -rw-r--r-- | net/netfilter/nf_tables_api.c | 137 | ||||
| -rw-r--r-- | net/netfilter/nfnetlink_acct.c | 12 | ||||
| -rw-r--r-- | net/netfilter/xt_LED.c | 4 | ||||
| -rw-r--r-- | net/netfilter/xt_hashlimit.c | 31 |
10 files changed, 133 insertions, 135 deletions
diff --git a/include/net/netns/x_tables.h b/include/net/netns/x_tables.h index 02fe40f8c8fd..c24060ee411e 100644 --- a/include/net/netns/x_tables.h +++ b/include/net/netns/x_tables.h | |||
| @@ -15,11 +15,5 @@ struct netns_xt { | |||
| 15 | struct ebt_table *frame_filter; | 15 | struct ebt_table *frame_filter; |
| 16 | struct ebt_table *frame_nat; | 16 | struct ebt_table *frame_nat; |
| 17 | #endif | 17 | #endif |
| 18 | #if IS_ENABLED(CONFIG_IP_NF_TARGET_ULOG) | ||
| 19 | bool ulog_warn_deprecated; | ||
| 20 | #endif | ||
| 21 | #if IS_ENABLED(CONFIG_BRIDGE_EBT_ULOG) | ||
| 22 | bool ebt_ulog_warn_deprecated; | ||
| 23 | #endif | ||
| 24 | }; | 18 | }; |
| 25 | #endif | 19 | #endif |
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig index 4ce0b313f72c..9cebf47ac840 100644 --- a/net/bridge/netfilter/Kconfig +++ b/net/bridge/netfilter/Kconfig | |||
| @@ -14,6 +14,12 @@ config NFT_BRIDGE_META | |||
| 14 | help | 14 | help |
| 15 | Add support for bridge dedicated meta key. | 15 | Add support for bridge dedicated meta key. |
| 16 | 16 | ||
| 17 | config NFT_BRIDGE_REJECT | ||
| 18 | tristate "Netfilter nf_tables bridge reject support" | ||
| 19 | depends on NFT_REJECT && NFT_REJECT_IPV4 && NFT_REJECT_IPV6 | ||
| 20 | help | ||
| 21 | Add support to reject packets. | ||
| 22 | |||
| 17 | config NF_LOG_BRIDGE | 23 | config NF_LOG_BRIDGE |
| 18 | tristate "Bridge packet logging" | 24 | tristate "Bridge packet logging" |
| 19 | 25 | ||
diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile index 1f78ea0d90e4..be4d0cea78ce 100644 --- a/net/bridge/netfilter/Makefile +++ b/net/bridge/netfilter/Makefile | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | obj-$(CONFIG_NF_TABLES_BRIDGE) += nf_tables_bridge.o | 5 | obj-$(CONFIG_NF_TABLES_BRIDGE) += nf_tables_bridge.o |
| 6 | obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o | 6 | obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o |
| 7 | obj-$(CONFIG_NFT_BRIDGE_REJECT) += nft_reject_bridge.o | ||
| 7 | 8 | ||
| 8 | # packet logging | 9 | # packet logging |
| 9 | obj-$(CONFIG_NF_LOG_BRIDGE) += nf_log_bridge.o | 10 | obj-$(CONFIG_NF_LOG_BRIDGE) += nf_log_bridge.o |
| @@ -36,5 +37,4 @@ obj-$(CONFIG_BRIDGE_EBT_SNAT) += ebt_snat.o | |||
| 36 | 37 | ||
| 37 | # watchers | 38 | # watchers |
| 38 | obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o | 39 | obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o |
| 39 | obj-$(CONFIG_BRIDGE_EBT_ULOG) += ebt_ulog.o | ||
| 40 | obj-$(CONFIG_BRIDGE_EBT_NFLOG) += ebt_nflog.o | 40 | obj-$(CONFIG_BRIDGE_EBT_NFLOG) += ebt_nflog.o |
diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c new file mode 100644 index 000000000000..ee3ffe93e14e --- /dev/null +++ b/net/bridge/netfilter/nft_reject_bridge.c | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2014 Pablo Neira Ayuso <pablo@netfilter.org> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/kernel.h> | ||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/netlink.h> | ||
| 13 | #include <linux/netfilter.h> | ||
| 14 | #include <linux/netfilter/nf_tables.h> | ||
| 15 | #include <net/netfilter/nf_tables.h> | ||
| 16 | #include <net/netfilter/nft_reject.h> | ||
| 17 | |||
| 18 | static void nft_reject_bridge_eval(const struct nft_expr *expr, | ||
| 19 | struct nft_data data[NFT_REG_MAX + 1], | ||
| 20 | const struct nft_pktinfo *pkt) | ||
| 21 | { | ||
| 22 | switch (eth_hdr(pkt->skb)->h_proto) { | ||
| 23 | case htons(ETH_P_IP): | ||
| 24 | return nft_reject_ipv4_eval(expr, data, pkt); | ||
| 25 | case htons(ETH_P_IPV6): | ||
| 26 | return nft_reject_ipv6_eval(expr, data, pkt); | ||
| 27 | default: | ||
| 28 | /* No explicit way to reject this protocol, drop it. */ | ||
| 29 | data[NFT_REG_VERDICT].verdict = NF_DROP; | ||
| 30 | break; | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | static struct nft_expr_type nft_reject_bridge_type; | ||
| 35 | static const struct nft_expr_ops nft_reject_bridge_ops = { | ||
| 36 | .type = &nft_reject_bridge_type, | ||
| 37 | .size = NFT_EXPR_SIZE(sizeof(struct nft_reject)), | ||
| 38 | .eval = nft_reject_bridge_eval, | ||
| 39 | .init = nft_reject_init, | ||
| 40 | .dump = nft_reject_dump, | ||
| 41 | }; | ||
| 42 | |||
| 43 | static struct nft_expr_type nft_reject_bridge_type __read_mostly = { | ||
| 44 | .family = NFPROTO_BRIDGE, | ||
| 45 | .name = "reject", | ||
| 46 | .ops = &nft_reject_bridge_ops, | ||
| 47 | .policy = nft_reject_policy, | ||
| 48 | .maxattr = NFTA_REJECT_MAX, | ||
| 49 | .owner = THIS_MODULE, | ||
| 50 | }; | ||
| 51 | |||
| 52 | static int __init nft_reject_bridge_module_init(void) | ||
| 53 | { | ||
| 54 | return nft_register_expr(&nft_reject_bridge_type); | ||
| 55 | } | ||
| 56 | |||
| 57 | static void __exit nft_reject_bridge_module_exit(void) | ||
| 58 | { | ||
| 59 | nft_unregister_expr(&nft_reject_bridge_type); | ||
| 60 | } | ||
| 61 | |||
| 62 | module_init(nft_reject_bridge_module_init); | ||
| 63 | module_exit(nft_reject_bridge_module_exit); | ||
| 64 | |||
| 65 | MODULE_LICENSE("GPL"); | ||
| 66 | MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>"); | ||
| 67 | MODULE_ALIAS_NFT_AF_EXPR(AF_BRIDGE, "reject"); | ||
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 245db9df3337..33001621465b 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
| @@ -57,7 +57,6 @@ obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o | |||
| 57 | obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o | 57 | obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o |
| 58 | obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o | 58 | obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o |
| 59 | obj-$(CONFIG_IP_NF_TARGET_SYNPROXY) += ipt_SYNPROXY.o | 59 | obj-$(CONFIG_IP_NF_TARGET_SYNPROXY) += ipt_SYNPROXY.o |
| 60 | obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o | ||
| 61 | 60 | ||
| 62 | # generic ARP tables | 61 | # generic ARP tables |
| 63 | obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o | 62 | obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 4ce44c4bc57b..a054fe083431 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
| @@ -358,7 +358,7 @@ static struct nf_sockopt_ops so_getorigdst = { | |||
| 358 | .pf = PF_INET, | 358 | .pf = PF_INET, |
| 359 | .get_optmin = SO_ORIGINAL_DST, | 359 | .get_optmin = SO_ORIGINAL_DST, |
| 360 | .get_optmax = SO_ORIGINAL_DST+1, | 360 | .get_optmax = SO_ORIGINAL_DST+1, |
| 361 | .get = &getorigdst, | 361 | .get = getorigdst, |
| 362 | .owner = THIS_MODULE, | 362 | .owner = THIS_MODULE, |
| 363 | }; | 363 | }; |
| 364 | 364 | ||
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 8746ff9a8357..93692d692ebc 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
| @@ -2247,80 +2247,7 @@ err: | |||
| 2247 | return err; | 2247 | return err; |
| 2248 | } | 2248 | } |
| 2249 | 2249 | ||
| 2250 | static int nf_tables_dump_sets_table(struct nft_ctx *ctx, struct sk_buff *skb, | 2250 | static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb) |
| 2251 | struct netlink_callback *cb) | ||
| 2252 | { | ||
| 2253 | const struct nft_set *set; | ||
| 2254 | unsigned int idx = 0, s_idx = cb->args[0]; | ||
| 2255 | |||
| 2256 | if (cb->args[1]) | ||
| 2257 | return skb->len; | ||
| 2258 | |||
| 2259 | rcu_read_lock(); | ||
| 2260 | cb->seq = ctx->net->nft.base_seq; | ||
| 2261 | |||
| 2262 | list_for_each_entry_rcu(set, &ctx->table->sets, list) { | ||
| 2263 | if (idx < s_idx) | ||
| 2264 | goto cont; | ||
| 2265 | if (nf_tables_fill_set(skb, ctx, set, NFT_MSG_NEWSET, | ||
| 2266 | NLM_F_MULTI) < 0) { | ||
| 2267 | cb->args[0] = idx; | ||
| 2268 | goto done; | ||
| 2269 | } | ||
| 2270 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | ||
| 2271 | cont: | ||
| 2272 | idx++; | ||
| 2273 | } | ||
| 2274 | cb->args[1] = 1; | ||
| 2275 | done: | ||
| 2276 | rcu_read_unlock(); | ||
| 2277 | return skb->len; | ||
| 2278 | } | ||
| 2279 | |||
| 2280 | static int nf_tables_dump_sets_family(struct nft_ctx *ctx, struct sk_buff *skb, | ||
| 2281 | struct netlink_callback *cb) | ||
| 2282 | { | ||
| 2283 | const struct nft_set *set; | ||
| 2284 | unsigned int idx, s_idx = cb->args[0]; | ||
| 2285 | struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2]; | ||
| 2286 | |||
| 2287 | if (cb->args[1]) | ||
| 2288 | return skb->len; | ||
| 2289 | |||
| 2290 | rcu_read_lock(); | ||
| 2291 | cb->seq = ctx->net->nft.base_seq; | ||
| 2292 | |||
| 2293 | list_for_each_entry_rcu(table, &ctx->afi->tables, list) { | ||
| 2294 | if (cur_table) { | ||
| 2295 | if (cur_table != table) | ||
| 2296 | continue; | ||
| 2297 | |||
| 2298 | cur_table = NULL; | ||
| 2299 | } | ||
| 2300 | ctx->table = table; | ||
| 2301 | idx = 0; | ||
| 2302 | list_for_each_entry_rcu(set, &ctx->table->sets, list) { | ||
| 2303 | if (idx < s_idx) | ||
| 2304 | goto cont; | ||
| 2305 | if (nf_tables_fill_set(skb, ctx, set, NFT_MSG_NEWSET, | ||
| 2306 | NLM_F_MULTI) < 0) { | ||
| 2307 | cb->args[0] = idx; | ||
| 2308 | cb->args[2] = (unsigned long) table; | ||
| 2309 | goto done; | ||
| 2310 | } | ||
| 2311 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | ||
| 2312 | cont: | ||
| 2313 | idx++; | ||
| 2314 | } | ||
| 2315 | } | ||
| 2316 | cb->args[1] = 1; | ||
| 2317 | done: | ||
| 2318 | rcu_read_unlock(); | ||
| 2319 | return skb->len; | ||
| 2320 | } | ||
| 2321 | |||
| 2322 | static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb, | ||
| 2323 | struct netlink_callback *cb) | ||
| 2324 | { | 2251 | { |
| 2325 | const struct nft_set *set; | 2252 | const struct nft_set *set; |
| 2326 | unsigned int idx, s_idx = cb->args[0]; | 2253 | unsigned int idx, s_idx = cb->args[0]; |
| @@ -2328,6 +2255,7 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb, | |||
| 2328 | struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2]; | 2255 | struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2]; |
| 2329 | struct net *net = sock_net(skb->sk); | 2256 | struct net *net = sock_net(skb->sk); |
| 2330 | int cur_family = cb->args[3]; | 2257 | int cur_family = cb->args[3]; |
| 2258 | struct nft_ctx *ctx = cb->data, ctx_set; | ||
| 2331 | 2259 | ||
| 2332 | if (cb->args[1]) | 2260 | if (cb->args[1]) |
| 2333 | return skb->len; | 2261 | return skb->len; |
| @@ -2336,28 +2264,34 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb, | |||
| 2336 | cb->seq = net->nft.base_seq; | 2264 | cb->seq = net->nft.base_seq; |
| 2337 | 2265 | ||
| 2338 | list_for_each_entry_rcu(afi, &net->nft.af_info, list) { | 2266 | list_for_each_entry_rcu(afi, &net->nft.af_info, list) { |
| 2267 | if (ctx->afi && ctx->afi != afi) | ||
| 2268 | continue; | ||
| 2269 | |||
| 2339 | if (cur_family) { | 2270 | if (cur_family) { |
| 2340 | if (afi->family != cur_family) | 2271 | if (afi->family != cur_family) |
| 2341 | continue; | 2272 | continue; |
| 2342 | 2273 | ||
| 2343 | cur_family = 0; | 2274 | cur_family = 0; |
| 2344 | } | 2275 | } |
| 2345 | |||
| 2346 | list_for_each_entry_rcu(table, &afi->tables, list) { | 2276 | list_for_each_entry_rcu(table, &afi->tables, list) { |
| 2277 | if (ctx->table && ctx->table != table) | ||
| 2278 | continue; | ||
| 2279 | |||
| 2347 | if (cur_table) { | 2280 | if (cur_table) { |
| 2348 | if (cur_table != table) | 2281 | if (cur_table != table) |
| 2349 | continue; | 2282 | continue; |
| 2350 | 2283 | ||
| 2351 | cur_table = NULL; | 2284 | cur_table = NULL; |
| 2352 | } | 2285 | } |
| 2353 | |||
| 2354 | ctx->table = table; | ||
| 2355 | ctx->afi = afi; | ||
| 2356 | idx = 0; | 2286 | idx = 0; |
| 2357 | list_for_each_entry_rcu(set, &ctx->table->sets, list) { | 2287 | list_for_each_entry_rcu(set, &table->sets, list) { |
| 2358 | if (idx < s_idx) | 2288 | if (idx < s_idx) |
| 2359 | goto cont; | 2289 | goto cont; |
| 2360 | if (nf_tables_fill_set(skb, ctx, set, | 2290 | |
| 2291 | ctx_set = *ctx; | ||
| 2292 | ctx_set.table = table; | ||
| 2293 | ctx_set.afi = afi; | ||
| 2294 | if (nf_tables_fill_set(skb, &ctx_set, set, | ||
| 2361 | NFT_MSG_NEWSET, | 2295 | NFT_MSG_NEWSET, |
| 2362 | NLM_F_MULTI) < 0) { | 2296 | NLM_F_MULTI) < 0) { |
| 2363 | cb->args[0] = idx; | 2297 | cb->args[0] = idx; |
| @@ -2379,31 +2313,10 @@ done: | |||
| 2379 | return skb->len; | 2313 | return skb->len; |
| 2380 | } | 2314 | } |
| 2381 | 2315 | ||
| 2382 | static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb) | 2316 | static int nf_tables_dump_sets_done(struct netlink_callback *cb) |
| 2383 | { | 2317 | { |
| 2384 | const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); | 2318 | kfree(cb->data); |
| 2385 | struct nlattr *nla[NFTA_SET_MAX + 1]; | 2319 | return 0; |
| 2386 | struct nft_ctx ctx; | ||
| 2387 | int err, ret; | ||
| 2388 | |||
| 2389 | err = nlmsg_parse(cb->nlh, sizeof(*nfmsg), nla, NFTA_SET_MAX, | ||
| 2390 | nft_set_policy); | ||
| 2391 | if (err < 0) | ||
| 2392 | return err; | ||
| 2393 | |||
| 2394 | err = nft_ctx_init_from_setattr(&ctx, cb->skb, cb->nlh, (void *)nla); | ||
| 2395 | if (err < 0) | ||
| 2396 | return err; | ||
| 2397 | |||
| 2398 | if (ctx.table == NULL) { | ||
| 2399 | if (ctx.afi == NULL) | ||
| 2400 | ret = nf_tables_dump_sets_all(&ctx, skb, cb); | ||
| 2401 | else | ||
| 2402 | ret = nf_tables_dump_sets_family(&ctx, skb, cb); | ||
| 2403 | } else | ||
| 2404 | ret = nf_tables_dump_sets_table(&ctx, skb, cb); | ||
| 2405 | |||
| 2406 | return ret; | ||
| 2407 | } | 2320 | } |
| 2408 | 2321 | ||
| 2409 | #define NFT_SET_INACTIVE (1 << 15) /* Internal set flag */ | 2322 | #define NFT_SET_INACTIVE (1 << 15) /* Internal set flag */ |
| @@ -2426,7 +2339,17 @@ static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb, | |||
| 2426 | if (nlh->nlmsg_flags & NLM_F_DUMP) { | 2339 | if (nlh->nlmsg_flags & NLM_F_DUMP) { |
| 2427 | struct netlink_dump_control c = { | 2340 | struct netlink_dump_control c = { |
| 2428 | .dump = nf_tables_dump_sets, | 2341 | .dump = nf_tables_dump_sets, |
| 2342 | .done = nf_tables_dump_sets_done, | ||
| 2429 | }; | 2343 | }; |
| 2344 | struct nft_ctx *ctx_dump; | ||
| 2345 | |||
| 2346 | ctx_dump = kmalloc(sizeof(*ctx_dump), GFP_KERNEL); | ||
| 2347 | if (ctx_dump == NULL) | ||
| 2348 | return -ENOMEM; | ||
| 2349 | |||
| 2350 | *ctx_dump = ctx; | ||
| 2351 | c.data = ctx_dump; | ||
| 2352 | |||
| 2430 | return netlink_dump_start(nlsk, skb, nlh, &c); | 2353 | return netlink_dump_start(nlsk, skb, nlh, &c); |
| 2431 | } | 2354 | } |
| 2432 | 2355 | ||
| @@ -3150,6 +3073,9 @@ static int nf_tables_newsetelem(struct sock *nlsk, struct sk_buff *skb, | |||
| 3150 | struct nft_ctx ctx; | 3073 | struct nft_ctx ctx; |
| 3151 | int rem, err = 0; | 3074 | int rem, err = 0; |
| 3152 | 3075 | ||
| 3076 | if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) | ||
| 3077 | return -EINVAL; | ||
| 3078 | |||
| 3153 | err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla, true); | 3079 | err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla, true); |
| 3154 | if (err < 0) | 3080 | if (err < 0) |
| 3155 | return err; | 3081 | return err; |
| @@ -3233,6 +3159,9 @@ static int nf_tables_delsetelem(struct sock *nlsk, struct sk_buff *skb, | |||
| 3233 | struct nft_ctx ctx; | 3159 | struct nft_ctx ctx; |
| 3234 | int rem, err = 0; | 3160 | int rem, err = 0; |
| 3235 | 3161 | ||
| 3162 | if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) | ||
| 3163 | return -EINVAL; | ||
| 3164 | |||
| 3236 | err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla, false); | 3165 | err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla, false); |
| 3237 | if (err < 0) | 3166 | if (err < 0) |
| 3238 | return err; | 3167 | return err; |
diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c index 2baa125c2e8d..3ea0eacbd970 100644 --- a/net/netfilter/nfnetlink_acct.c +++ b/net/netfilter/nfnetlink_acct.c | |||
| @@ -41,6 +41,7 @@ struct nf_acct { | |||
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | #define NFACCT_F_QUOTA (NFACCT_F_QUOTA_PKTS | NFACCT_F_QUOTA_BYTES) | 43 | #define NFACCT_F_QUOTA (NFACCT_F_QUOTA_PKTS | NFACCT_F_QUOTA_BYTES) |
| 44 | #define NFACCT_OVERQUOTA_BIT 2 /* NFACCT_F_OVERQUOTA */ | ||
| 44 | 45 | ||
| 45 | static int | 46 | static int |
| 46 | nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb, | 47 | nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb, |
| @@ -77,7 +78,8 @@ nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb, | |||
| 77 | smp_mb__before_atomic(); | 78 | smp_mb__before_atomic(); |
| 78 | /* reset overquota flag if quota is enabled. */ | 79 | /* reset overquota flag if quota is enabled. */ |
| 79 | if ((matching->flags & NFACCT_F_QUOTA)) | 80 | if ((matching->flags & NFACCT_F_QUOTA)) |
| 80 | clear_bit(NFACCT_F_OVERQUOTA, &matching->flags); | 81 | clear_bit(NFACCT_OVERQUOTA_BIT, |
| 82 | &matching->flags); | ||
| 81 | return 0; | 83 | return 0; |
| 82 | } | 84 | } |
| 83 | return -EBUSY; | 85 | return -EBUSY; |
| @@ -129,6 +131,7 @@ nfnl_acct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, | |||
| 129 | struct nfgenmsg *nfmsg; | 131 | struct nfgenmsg *nfmsg; |
| 130 | unsigned int flags = portid ? NLM_F_MULTI : 0; | 132 | unsigned int flags = portid ? NLM_F_MULTI : 0; |
| 131 | u64 pkts, bytes; | 133 | u64 pkts, bytes; |
| 134 | u32 old_flags; | ||
| 132 | 135 | ||
| 133 | event |= NFNL_SUBSYS_ACCT << 8; | 136 | event |= NFNL_SUBSYS_ACCT << 8; |
| 134 | nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); | 137 | nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); |
| @@ -143,12 +146,13 @@ nfnl_acct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, | |||
| 143 | if (nla_put_string(skb, NFACCT_NAME, acct->name)) | 146 | if (nla_put_string(skb, NFACCT_NAME, acct->name)) |
| 144 | goto nla_put_failure; | 147 | goto nla_put_failure; |
| 145 | 148 | ||
| 149 | old_flags = acct->flags; | ||
| 146 | if (type == NFNL_MSG_ACCT_GET_CTRZERO) { | 150 | if (type == NFNL_MSG_ACCT_GET_CTRZERO) { |
| 147 | pkts = atomic64_xchg(&acct->pkts, 0); | 151 | pkts = atomic64_xchg(&acct->pkts, 0); |
| 148 | bytes = atomic64_xchg(&acct->bytes, 0); | 152 | bytes = atomic64_xchg(&acct->bytes, 0); |
| 149 | smp_mb__before_atomic(); | 153 | smp_mb__before_atomic(); |
| 150 | if (acct->flags & NFACCT_F_QUOTA) | 154 | if (acct->flags & NFACCT_F_QUOTA) |
| 151 | clear_bit(NFACCT_F_OVERQUOTA, &acct->flags); | 155 | clear_bit(NFACCT_OVERQUOTA_BIT, &acct->flags); |
| 152 | } else { | 156 | } else { |
| 153 | pkts = atomic64_read(&acct->pkts); | 157 | pkts = atomic64_read(&acct->pkts); |
| 154 | bytes = atomic64_read(&acct->bytes); | 158 | bytes = atomic64_read(&acct->bytes); |
| @@ -160,7 +164,7 @@ nfnl_acct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, | |||
| 160 | if (acct->flags & NFACCT_F_QUOTA) { | 164 | if (acct->flags & NFACCT_F_QUOTA) { |
| 161 | u64 *quota = (u64 *)acct->data; | 165 | u64 *quota = (u64 *)acct->data; |
| 162 | 166 | ||
| 163 | if (nla_put_be32(skb, NFACCT_FLAGS, htonl(acct->flags)) || | 167 | if (nla_put_be32(skb, NFACCT_FLAGS, htonl(old_flags)) || |
| 164 | nla_put_be64(skb, NFACCT_QUOTA, cpu_to_be64(*quota))) | 168 | nla_put_be64(skb, NFACCT_QUOTA, cpu_to_be64(*quota))) |
| 165 | goto nla_put_failure; | 169 | goto nla_put_failure; |
| 166 | } | 170 | } |
| @@ -412,7 +416,7 @@ int nfnl_acct_overquota(const struct sk_buff *skb, struct nf_acct *nfacct) | |||
| 412 | ret = now > *quota; | 416 | ret = now > *quota; |
| 413 | 417 | ||
| 414 | if (now >= *quota && | 418 | if (now >= *quota && |
| 415 | !test_and_set_bit(NFACCT_F_OVERQUOTA, &nfacct->flags)) { | 419 | !test_and_set_bit(NFACCT_OVERQUOTA_BIT, &nfacct->flags)) { |
| 416 | nfnl_overquota_report(nfacct); | 420 | nfnl_overquota_report(nfacct); |
| 417 | } | 421 | } |
| 418 | 422 | ||
diff --git a/net/netfilter/xt_LED.c b/net/netfilter/xt_LED.c index 993de2ba89d3..f14bcf23dc9f 100644 --- a/net/netfilter/xt_LED.c +++ b/net/netfilter/xt_LED.c | |||
| @@ -133,9 +133,7 @@ static int led_tg_check(const struct xt_tgchk_param *par) | |||
| 133 | 133 | ||
| 134 | err = led_trigger_register(&ledinternal->netfilter_led_trigger); | 134 | err = led_trigger_register(&ledinternal->netfilter_led_trigger); |
| 135 | if (err) { | 135 | if (err) { |
| 136 | pr_warning("led_trigger_register() failed\n"); | 136 | pr_err("Trigger name is already in use.\n"); |
| 137 | if (err == -EEXIST) | ||
| 138 | pr_warning("Trigger name is already in use.\n"); | ||
| 139 | goto exit_alloc; | 137 | goto exit_alloc; |
| 140 | } | 138 | } |
| 141 | 139 | ||
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index a3910fc2122b..47dc6836830a 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c | |||
| @@ -104,7 +104,7 @@ struct xt_hashlimit_htable { | |||
| 104 | spinlock_t lock; /* lock for list_head */ | 104 | spinlock_t lock; /* lock for list_head */ |
| 105 | u_int32_t rnd; /* random seed for hash */ | 105 | u_int32_t rnd; /* random seed for hash */ |
| 106 | unsigned int count; /* number entries in table */ | 106 | unsigned int count; /* number entries in table */ |
| 107 | struct timer_list timer; /* timer for gc */ | 107 | struct delayed_work gc_work; |
| 108 | 108 | ||
| 109 | /* seq_file stuff */ | 109 | /* seq_file stuff */ |
| 110 | struct proc_dir_entry *pde; | 110 | struct proc_dir_entry *pde; |
| @@ -213,7 +213,7 @@ dsthash_free(struct xt_hashlimit_htable *ht, struct dsthash_ent *ent) | |||
| 213 | call_rcu_bh(&ent->rcu, dsthash_free_rcu); | 213 | call_rcu_bh(&ent->rcu, dsthash_free_rcu); |
| 214 | ht->count--; | 214 | ht->count--; |
| 215 | } | 215 | } |
| 216 | static void htable_gc(unsigned long htlong); | 216 | static void htable_gc(struct work_struct *work); |
| 217 | 217 | ||
| 218 | static int htable_create(struct net *net, struct xt_hashlimit_mtinfo1 *minfo, | 218 | static int htable_create(struct net *net, struct xt_hashlimit_mtinfo1 *minfo, |
| 219 | u_int8_t family) | 219 | u_int8_t family) |
| @@ -273,9 +273,9 @@ static int htable_create(struct net *net, struct xt_hashlimit_mtinfo1 *minfo, | |||
| 273 | } | 273 | } |
| 274 | hinfo->net = net; | 274 | hinfo->net = net; |
| 275 | 275 | ||
| 276 | setup_timer(&hinfo->timer, htable_gc, (unsigned long)hinfo); | 276 | INIT_DEFERRABLE_WORK(&hinfo->gc_work, htable_gc); |
| 277 | hinfo->timer.expires = jiffies + msecs_to_jiffies(hinfo->cfg.gc_interval); | 277 | queue_delayed_work(system_power_efficient_wq, &hinfo->gc_work, |
| 278 | add_timer(&hinfo->timer); | 278 | msecs_to_jiffies(hinfo->cfg.gc_interval)); |
| 279 | 279 | ||
| 280 | hlist_add_head(&hinfo->node, &hashlimit_net->htables); | 280 | hlist_add_head(&hinfo->node, &hashlimit_net->htables); |
| 281 | 281 | ||
| @@ -300,29 +300,30 @@ static void htable_selective_cleanup(struct xt_hashlimit_htable *ht, | |||
| 300 | { | 300 | { |
| 301 | unsigned int i; | 301 | unsigned int i; |
| 302 | 302 | ||
| 303 | /* lock hash table and iterate over it */ | ||
| 304 | spin_lock_bh(&ht->lock); | ||
| 305 | for (i = 0; i < ht->cfg.size; i++) { | 303 | for (i = 0; i < ht->cfg.size; i++) { |
| 306 | struct dsthash_ent *dh; | 304 | struct dsthash_ent *dh; |
| 307 | struct hlist_node *n; | 305 | struct hlist_node *n; |
| 306 | |||
| 307 | spin_lock_bh(&ht->lock); | ||
| 308 | hlist_for_each_entry_safe(dh, n, &ht->hash[i], node) { | 308 | hlist_for_each_entry_safe(dh, n, &ht->hash[i], node) { |
| 309 | if ((*select)(ht, dh)) | 309 | if ((*select)(ht, dh)) |
| 310 | dsthash_free(ht, dh); | 310 | dsthash_free(ht, dh); |
| 311 | } | 311 | } |
| 312 | spin_unlock_bh(&ht->lock); | ||
| 313 | cond_resched(); | ||
| 312 | } | 314 | } |
| 313 | spin_unlock_bh(&ht->lock); | ||
| 314 | } | 315 | } |
| 315 | 316 | ||
| 316 | /* hash table garbage collector, run by timer */ | 317 | static void htable_gc(struct work_struct *work) |
| 317 | static void htable_gc(unsigned long htlong) | ||
| 318 | { | 318 | { |
| 319 | struct xt_hashlimit_htable *ht = (struct xt_hashlimit_htable *)htlong; | 319 | struct xt_hashlimit_htable *ht; |
| 320 | |||
| 321 | ht = container_of(work, struct xt_hashlimit_htable, gc_work.work); | ||
| 320 | 322 | ||
| 321 | htable_selective_cleanup(ht, select_gc); | 323 | htable_selective_cleanup(ht, select_gc); |
| 322 | 324 | ||
| 323 | /* re-add the timer accordingly */ | 325 | queue_delayed_work(system_power_efficient_wq, |
| 324 | ht->timer.expires = jiffies + msecs_to_jiffies(ht->cfg.gc_interval); | 326 | &ht->gc_work, msecs_to_jiffies(ht->cfg.gc_interval)); |
| 325 | add_timer(&ht->timer); | ||
| 326 | } | 327 | } |
| 327 | 328 | ||
| 328 | static void htable_remove_proc_entry(struct xt_hashlimit_htable *hinfo) | 329 | static void htable_remove_proc_entry(struct xt_hashlimit_htable *hinfo) |
| @@ -341,7 +342,7 @@ static void htable_remove_proc_entry(struct xt_hashlimit_htable *hinfo) | |||
| 341 | 342 | ||
| 342 | static void htable_destroy(struct xt_hashlimit_htable *hinfo) | 343 | static void htable_destroy(struct xt_hashlimit_htable *hinfo) |
| 343 | { | 344 | { |
| 344 | del_timer_sync(&hinfo->timer); | 345 | cancel_delayed_work_sync(&hinfo->gc_work); |
| 345 | htable_remove_proc_entry(hinfo); | 346 | htable_remove_proc_entry(hinfo); |
| 346 | htable_selective_cleanup(hinfo, select_all); | 347 | htable_selective_cleanup(hinfo, select_all); |
| 347 | kfree(hinfo->name); | 348 | kfree(hinfo->name); |
