netfilter: nf_tables: build-in filter chain type
Subsystems (4)
Pablo Neira Ayuso
maintainerPATCH 40/47 netfilter: nf_tables: build-in filter chain type
One module per supported filter chain family type takes too much memory for very little code - too much modularization - place all chain filter definitions in one single file.
--- include/net/netfilter/nf_tables.h | 3 + net/bridge/netfilter/Kconfig | 2 +- net/bridge/netfilter/Makefile | 1 - net/bridge/netfilter/nf_tables_bridge.c | 81 ------- net/ipv4/netfilter/Kconfig | 4 +- net/ipv4/netfilter/Makefile | 2 - net/ipv4/netfilter/nf_tables_arp.c | 60 ----- net/ipv4/netfilter/nf_tables_ipv4.c | 69 ------ net/ipv6/netfilter/Kconfig | 2 +- net/ipv6/netfilter/Makefile | 1 - net/ipv6/netfilter/nf_tables_ipv6.c | 67 ------ net/netfilter/Kconfig | 4 +- net/netfilter/Makefile | 9 +- net/netfilter/nf_tables_api.c | 3 + net/netfilter/nf_tables_inet.c | 77 ------ net/netfilter/nf_tables_netdev.c | 140 ----------- net/netfilter/nft_chain_filter.c | 398 ++++++++++++++++++++++++++++++++ 17 files changed, 414 insertions(+), 509 deletions(-) delete mode 100644 net/bridge/netfilter/nf_tables_bridge.c delete mode 100644 net/ipv4/netfilter/nf_tables_arp.c delete mode 100644 net/ipv4/netfilter/nf_tables_ipv4.c delete mode 100644 net/ipv6/netfilter/nf_tables_ipv6.c delete mode 100644 net/netfilter/nf_tables_inet.c delete mode 100644 net/netfilter/nf_tables_netdev.c create mode 100644 net/netfilter/nft_chain_filter.c
include/net/netfilter/nf_tables.h +3 -0
@@ -1345,4 +1345,7 @@ struct nft_trans_flowtable {#define nft_trans_flowtable (trans) \ (((struct nft_trans_flowtable *)trans->data)->flowtable) +int __init nft_chain_filter_init (void ); +void __exit nft_chain_filter_fini(void); +#endif /* _NET_NF_TABLES_H */
net/bridge/netfilter/Kconfig +1 -1
@@ -5,7 +5,7 @@ menuconfig NF_TABLES_BRIDGE depends on BRIDGE && NETFILTER && NF_TABLES select NETFILTER_FAMILY_BRIDGE - tristate "Ethernet Bridge nf_tables support" + bool "Ethernet Bridge nf_tables support" if NF_TABLES_BRIDGE
net/bridge/netfilter/Makefile +0 -1
@@ -3,7 +3,6 @@ # Makefile for the netfilter modules for Link Layer filtering on a bridge. # -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
net/bridge/netfilter/nf_tables_bridge.c deleted +0 -81
81 lines not on this page · raw message
net/ipv4/netfilter/Kconfig +2 -2
@@ -34,7 +34,7 @@ config NF_SOCKET_IPV4 if NF_TABLES config NF_TABLES_IPV4 - tristate "IPv4 nf_tables support" + bool "IPv4 nf_tables support" help This option enables the IPv4 support for nf_tables.
@@ -71,7 +71,7 @@ config NFT_FIB_IPV4 endif # NF_TABLES_IPV4 config NF_TABLES_ARP - tristate "ARP nf_tables support" + bool "ARP nf_tables support" select NETFILTER_FAMILY_ARP help This option enables the ARP support for nf_tables.
net/ipv4/netfilter/Makefile +0 -2
@@ -39,7 +39,6 @@ obj-$(CONFIG_NF_NAT_MASQUERADE_IPV4) += nf_nat_masquerade_ipv4.o # NAT protocols (nf_nat) obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o -obj-$(CONFIG_NF_TABLES_IPV4) += nf_tables_ipv4.o obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV4) += nft_chain_route_ipv4.o obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o
@@ -47,7 +46,6 @@ obj-$(CONFIG_NFT_FIB_IPV4) += nft_fib_ipv4.o obj-$(CONFIG_NFT_MASQ_IPV4) += nft_masq_ipv4.o obj-$(CONFIG_NFT_REDIR_IPV4) += nft_redir_ipv4.o obj-$(CONFIG_NFT_DUP_IPV4) += nft_dup_ipv4.o -obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o # flow table support obj-$(CONFIG_NF_FLOW_TABLE_IPV4) += nf_flow_table_ipv4.o
net/ipv4/netfilter/nf_tables_arp.c deleted +0 -60
60 lines not on this page · raw message
net/ipv4/netfilter/nf_tables_ipv4.c deleted +0 -69
69 lines not on this page · raw message
net/ipv6/netfilter/Kconfig +1 -1
@@ -34,7 +34,7 @@ config NF_SOCKET_IPV6 if NF_TABLES config NF_TABLES_IPV6 - tristate "IPv6 nf_tables support" + bool "IPv6 nf_tables support" help This option enables the IPv6 support for nf_tables.
net/ipv6/netfilter/Makefile +0 -1
@@ -36,7 +36,6 @@ obj-$(CONFIG_NF_REJECT_IPV6) += nf_reject_ipv6.o obj-$(CONFIG_NF_DUP_IPV6) += nf_dup_ipv6.o # nf_tables -obj-$(CONFIG_NF_TABLES_IPV6) += nf_tables_ipv6.o obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o
net/ipv6/netfilter/nf_tables_ipv6.c deleted +0 -67
67 lines not on this page · raw message
net/netfilter/Kconfig +2 -2
@@ -465,12 +465,12 @@ config NF_TABLES_INET depends on IPV6 select NF_TABLES_IPV4 select NF_TABLES_IPV6 - tristate "Netfilter nf_tables mixed IPv4/IPv6 tables support" + bool "Netfilter nf_tables mixed IPv4/IPv6 tables support" help This option enables support for a mixed IPv4/IPv6 "inet" table. config NF_TABLES_NETDEV - tristate "Netfilter nf_tables netdev tables support" + bool "Netfilter nf_tables netdev tables support" help This option enables support for the "netdev" table.
net/netfilter/Makefile +4 -5
@@ -73,13 +73,12 @@ obj-$(CONFIG_NETFILTER_CONNCOUNT) += nf_conncount.o obj-$(CONFIG_NF_DUP_NETDEV) += nf_dup_netdev.o # nf_tables -nf_tables-objs := nf_tables_core.o nf_tables_api.o nf_tables_trace.o \ - nft_immediate.o nft_cmp.o nft_range.o nft_bitwise.o \ - nft_byteorder.o nft_payload.o nft_lookup.o nft_dynset.o +nf_tables-objs := nf_tables_core.o nf_tables_api.o nft_chain_filter.o \ + nf_tables_trace.o nft_immediate.o nft_cmp.o nft_range.o \ + nft_bitwise.o nft_byteorder.o nft_payload.o nft_lookup.o \ + nft_dynset.o obj-$(CONFIG_NF_TABLES) += nf_tables.o -obj-$(CONFIG_NF_TABLES_INET) += nf_tables_inet.o -obj-$(CONFIG_NF_TABLES_NETDEV) += nf_tables_netdev.o obj-$(CONFIG_NFT_COMPAT) += nft_compat.o obj-$(CONFIG_NFT_EXTHDR) += nft_exthdr.o obj-$(CONFIG_NFT_META) += nft_meta.o
net/netfilter/nf_tables_api.c +3 -0
@@ -6584,6 +6584,8 @@ static int __init nf_tables_module_init(void) {int err; +nft_chain_filter_init (); + info =kmalloc (sizeof (struct nft_expr_info ) *NFT_RULE_MAXEXPRS ,GFP_KERNEL );if (info ==NULL ) {
@@ -6618,6 +6620,7 @@ static void __exit nf_tables_module_exit(void)rcu_barrier ();nf_tables_core_module_exit ();kfree (info); +nft_chain_filter_fini (); }module_init (nf_tables_module_init);
net/netfilter/nf_tables_inet.c deleted +0 -77
77 lines not on this page · raw message
net/netfilter/nf_tables_netdev.c deleted +0 -140
140 lines not on this page · raw message
net/netfilter/nft_chain_filter.c new file +398 -0
398 lines not on this page · raw message
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 41/47 netfilter: nf_tables: enable conntrack if NAT chain is registered
Register conntrack hooks if the user adds NAT chains. Users get confused with the existing behaviour since they will see no packets hitting this chain until they add the first rule that refers to conntrack.
This patch adds new ->init() and ->free() indirections to chain types that can be used by NAT chains to invoke the conntrack dependency.
--- include/net/netfilter/nf_tables.h | 4 ++++ net/ipv4/netfilter/nft_chain_nat_ipv4.c | 12 ++++++++++++ net/ipv6/netfilter/nft_chain_nat_ipv6.c | 12 ++++++++++++ net/netfilter/nf_tables_api.c | 24 +++++++++++++++++------- 4 files changed, 45 insertions(+), 7 deletions(-)
include/net/netfilter/nf_tables.h +4 -0
@@ -884,6 +884,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 */ struct nft_chain_type {const char *name;
@@ -892,6 +894,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 nft_chain_validate_dependency(const struct nft_chain *chain,
net/ipv4/netfilter/nft_chain_nat_ipv4.c +12 -0
@@ -67,6 +67,16 @@ static unsigned int nft_nat_ipv4_local_fn(void *priv,return nf_nat_ipv4_local_fn (priv, skb, state, nft_nat_do_chain); } +static int nft_nat_ipv4_init (struct nft_ctx *ctx) +{ +return nf_ct_netns_get (ctx->net, ctx->family); +} + +static void nft_nat_ipv4_free (struct nft_ctx *ctx) +{ +nf_ct_netns_put (ctx->net, ctx->family); +} +static const struct nft_chain_type nft_chain_nat_ipv4 = { .name ="nat" , .type =NFT_CHAIN_T_NAT ,
@@ -82,6 +92,8 @@ static const struct nft_chain_type nft_chain_nat_ipv4 = { [NF_INET_LOCAL_OUT] = nft_nat_ipv4_local_fn, [NF_INET_LOCAL_IN] = nft_nat_ipv4_fn, }, + .init = nft_nat_ipv4_init, + .free = nft_nat_ipv4_free, };static int __init nft_chain_nat_init (void )
net/ipv6/netfilter/nft_chain_nat_ipv6.c +12 -0
@@ -65,6 +65,16 @@ static unsigned int nft_nat_ipv6_local_fn(void *priv,return nf_nat_ipv6_local_fn (priv, skb, state, nft_nat_do_chain); } +static int nft_nat_ipv6_init (struct nft_ctx *ctx) +{ +return nf_ct_netns_get (ctx->net, ctx->family); +} + +static void nft_nat_ipv6_free (struct nft_ctx *ctx) +{ +nf_ct_netns_put (ctx->net, ctx->family); +} +static const struct nft_chain_type nft_chain_nat_ipv6 = { .name ="nat" , .type =NFT_CHAIN_T_NAT ,
@@ -80,6 +90,8 @@ static const struct nft_chain_type nft_chain_nat_ipv6 = { [NF_INET_LOCAL_OUT] = nft_nat_ipv6_local_fn, [NF_INET_LOCAL_IN] = nft_nat_ipv6_fn, }, + .init = nft_nat_ipv6_init, + .free = nft_nat_ipv6_free, };static int __init nft_chain_nat_ipv6_init (void )
net/netfilter/nf_tables_api.c +17 -7
@@ -1211,13 +1211,17 @@ static void nft_chain_stats_replace(struct nft_base_chain *chain,rcu_assign_pointer (chain->stats, newstats); } -static void nf_tables_chain_destroy (struct nft_chain *chain) +static void nf_tables_chain_destroy (struct nft_ctx *ctx) { +struct nft_chain *chain = ctx->chain; +BUG_ON (chain->use >0 );if (nft_is_base_chain (chain)) {struct nft_base_chain *basechain =nft_base_chain (chain); +if (basechain->type->free) + basechain->type->free (ctx);module_put (basechain->type->owner);free_percpu (basechain->stats);if (basechain->stats)
@@ -1354,6 +1358,9 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, } basechain->type = hook.type; +if (basechain->type->init) + basechain->type->init (ctx); + chain = &basechain->chain; ops = &basechain->ops;
@@ -1374,6 +1381,8 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,if (chain ==NULL )return -ENOMEM ; } + ctx->chain = chain; +INIT_LIST_HEAD (&chain->rules); chain->handle =nf_tables_alloc_handle (table); chain->table = table;
@@ -1387,7 +1396,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,if (err <0 ) goto err1; - ctx->chain = chain; err =nft_trans_chain_add (ctx,NFT_MSG_NEWCHAIN );if (err <0 ) goto err2;
@@ -1399,7 +1407,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, err2:nf_tables_unregister_hook (net, table, chain); err1: -nf_tables_chain_destroy (chain); +nf_tables_chain_destroy (ctx);return err; }
@@ -5678,7 +5686,7 @@ static void nf_tables_commit_release(struct nft_trans *trans)nf_tables_table_destroy (&trans->ctx);break ;case NFT_MSG_DELCHAIN : -nf_tables_chain_destroy (trans->ctx.chain); +nf_tables_chain_destroy (&trans->ctx);break ;case NFT_MSG_DELRULE :nf_tables_rule_destroy (&trans->ctx,nft_trans_rule (trans));
@@ -5849,7 +5857,7 @@ static void nf_tables_abort_release(struct nft_trans *trans)nf_tables_table_destroy (&trans->ctx);break ;case NFT_MSG_NEWCHAIN : -nf_tables_chain_destroy (trans->ctx.chain); +nf_tables_chain_destroy (&trans->ctx);break ;case NFT_MSG_NEWRULE :nf_tables_rule_destroy (&trans->ctx,nft_trans_rule (trans));
@@ -6499,7 +6507,7 @@ int __nft_release_basechain(struct nft_ctx *ctx) }list_del (&ctx->chain->list); ctx->table->use--; -nf_tables_chain_destroy (ctx->chain); +nf_tables_chain_destroy (ctx);return 0 ; }
@@ -6515,6 +6523,7 @@ static void __nft_release_tables(struct net *net)struct nft_set *set, *ns;struct nft_ctx ctx = { .net = net, + .family =NFPROTO_NETDEV , };list_for_each_entry_safe (table, nt, &net->nft.tables, list) {
@@ -6551,9 +6560,10 @@ static void __nft_release_tables(struct net *net)nft_obj_destroy (obj); }list_for_each_entry_safe (chain, nc, &table->chains, list) { + ctx.chain = chain;list_del (&chain->list); table->use--; -nf_tables_chain_destroy (chain); +nf_tables_chain_destroy (&ctx); }list_del (&table->list);nf_tables_table_destroy (&ctx);
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 42/47 netfilter: nf_tables: rename to nft_set_lookup_global()
In reply to Pablo Neira AyusoTo prepare shorter introduction of shorter function prefix.
--- include/net/netfilter/nf_tables.h | 10 +++++----- net/netfilter/nf_tables_api.c | 12 ++++++------ net/netfilter/nft_dynset.c | 5 +++-- net/netfilter/nft_lookup.c | 4 ++-- net/netfilter/nft_objref.c | 5 +++-- 5 files changed, 19 insertions(+), 17 deletions(-)
include/net/netfilter/nf_tables.h +5 -5
@@ -434,11 +434,11 @@ static inline struct nft_set *nft_set_container_of(const void *priv)return (void *)priv - offsetof(struct nft_set , data); } -struct nft_set *nft_set_lookup (const struct net *net, -const struct nft_table *table, -const struct nlattr *nla_set_name, -const struct nlattr *nla_set_id, -u8 genmask); +struct nft_set *nft_set_lookup_global (const struct net *net, +const struct nft_table *table, +const struct nlattr *nla_set_name, +const struct nlattr *nla_set_id, +u8 genmask);static inline unsigned long nft_set_gc_interval (const struct nft_set *set) {
net/netfilter/nf_tables_api.c +6 -6
@@ -2633,11 +2633,11 @@ static struct nft_set *nf_tables_set_lookup_byid(const struct net *net,return ERR_PTR (-ENOENT ); } -struct nft_set *nft_set_lookup (const struct net *net, -const struct nft_table *table, -const struct nlattr *nla_set_name, -const struct nlattr *nla_set_id, -u8 genmask) +struct nft_set *nft_set_lookup_global (const struct net *net, +const struct nft_table *table, +const struct nlattr *nla_set_name, +const struct nlattr *nla_set_id, +u8 genmask) {struct nft_set *set;
@@ -2650,7 +2650,7 @@ struct nft_set *nft_set_lookup(const struct net *net, }return set; } -EXPORT_SYMBOL_GPL (nft_set_lookup); +EXPORT_SYMBOL_GPL (nft_set_lookup_global);static int nf_tables_set_alloc_name (struct nft_ctx *ctx,struct nft_set *set,const char *name)
net/netfilter/nft_dynset.c +3 -2
@@ -132,8 +132,9 @@ static int nft_dynset_init(const struct nft_ctx *ctx, priv->invert = true; } - set =nft_set_lookup (ctx->net, ctx->table, tb[NFTA_DYNSET_SET_NAME ], - tb[NFTA_DYNSET_SET_ID ], genmask); + set =nft_set_lookup_global (ctx->net, ctx->table, + tb[NFTA_DYNSET_SET_NAME ], + tb[NFTA_DYNSET_SET_ID ], genmask);if (IS_ERR (set))return PTR_ERR (set);
net/netfilter/nft_lookup.c +2 -2
@@ -71,8 +71,8 @@ static int nft_lookup_init(const struct nft_ctx *ctx, tb[NFTA_LOOKUP_SREG] == NULL)return -EINVAL ; - set =nft_set_lookup (ctx->net, ctx->table, tb[NFTA_LOOKUP_SET ], - tb[NFTA_LOOKUP_SET_ID ], genmask); + set =nft_set_lookup_global (ctx->net, ctx->table, tb[NFTA_LOOKUP_SET ], + tb[NFTA_LOOKUP_SET_ID ], genmask);if (IS_ERR (set))return PTR_ERR (set);
net/netfilter/nft_objref.c +3 -2
@@ -117,8 +117,9 @@ static int nft_objref_map_init(const struct nft_ctx *ctx,struct nft_set *set;int err; - set =nft_set_lookup (ctx->net, ctx->table, tb[NFTA_OBJREF_SET_NAME ], - tb[NFTA_OBJREF_SET_ID ], genmask); + set =nft_set_lookup_global (ctx->net, ctx->table, + tb[NFTA_OBJREF_SET_NAME ], + tb[NFTA_OBJREF_SET_ID ], genmask);if (IS_ERR (set))return PTR_ERR (set);
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 43/47 netfilter: nf_tables: use nft_set_lookup_global from nf_tables_newsetelem()
In reply to Pablo Neira AyusoReplace opencoded implementation of nft_set_lookup_global() by call to this function.
--- net/netfilter/nf_tables_api.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
net/netfilter/nf_tables_api.c +4 -11
@@ -4032,17 +4032,10 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,if (err <0 )return err; - set =nf_tables_set_lookup (ctx.table, nla[NFTA_SET_ELEM_LIST_SET ], - genmask); -if (IS_ERR (set)) { -if (nla[NFTA_SET_ELEM_LIST_SET_ID ]) { - set =nf_tables_set_lookup_byid (net, - nla[NFTA_SET_ELEM_LIST_SET_ID ], - genmask); - } -if (IS_ERR (set)) -return PTR_ERR (set); - } + set =nft_set_lookup_global (net, ctx.table, nla[NFTA_SET_ELEM_LIST_SET ], + nla[NFTA_SET_ELEM_LIST_SET_ID ], genmask); +if (IS_ERR (set)) +return PTR_ERR (set);if (!list_empty (&set->bindings) && set->flags &NFT_SET_CONSTANT )return -EBUSY ;
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 44/47 netfilter: Merge assignment with return
In reply to Pablo Neira AyusoFrom: Arushi Singhal <[email protected]>
Merge assignment with return statement to directly return the value.
--- net/netfilter/nf_conntrack_netlink.c | 5 ++--- net/netfilter/xt_hashlimit.c | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-)
net/netfilter/nf_conntrack_netlink.c +2 -3
@@ -1527,9 +1527,8 @@ ctnetlink_setup_nat(struct nf_conn *ct, const struct nlattr * const cda[])if (ret <0 )return ret; - ret =ctnetlink_parse_nat_setup (ct,NF_NAT_MANIP_SRC , - cda[CTA_NAT_SRC ]); -return ret; +return ctnetlink_parse_nat_setup (ct,NF_NAT_MANIP_SRC , + cda[CTA_NAT_SRC ]);#else if (!cda[CTA_NAT_DST ] && !cda[CTA_NAT_SRC ])return 0 ;
net/netfilter/xt_hashlimit.c +1 -2
@@ -534,8 +534,7 @@ static u64 user2rate_bytes(u32 user)u64 r; r = user ?U32_MAX / user :U32_MAX ; - r = (r -1 ) <<XT_HASHLIMIT_BYTE_SHIFT ; -return r; +return (r -1 ) <<XT_HASHLIMIT_BYTE_SHIFT ; } static void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now,
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 45/47 netfilter: x_tables: Add note about how to free percpu counters
In reply to Pablo Neira AyusoFrom: Ben Hutchings <[email protected]>
Due to the way percpu counters are allocated and freed in blocks, it is not safe to free counters individually. Currently all callers do the right thing, but let's note this restriction.
--- net/netfilter/x_tables.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/netfilter/x_tables.c +3 -1
@@ -1854,7 +1854,9 @@ EXPORT_SYMBOL_GPL(xt_proto_fini);* to fetch the real percpu counter. * * To speed up allocation and improve data locality, a 4kb block is -* allocated. +* allocated. Freeing any counter may free an entire block, so all +* counters allocated using the same state must be freed at the same +* time. * * xt_percpu_counter_alloc_state contains the base address of the * allocated page and the current sub-offset.
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 46/47 Revert "netfilter: x_tables: ensure last rule in base chain matches underflow/policy"
In reply to Pablo Neira AyusoFrom: Florian Westphal <[email protected]>
This reverts commit 0d7df906a0e78079a02108b06d32c3ef2238ad25.
Valdis Kletnieks reported that xtables is broken in linux-next since 0d7df906a0e78 ("netfilter: x_tables: ensure last rule in base chain matches underflow/policy"), as kernel rejects the (well-formed) ruleset:
[ 64.402790] ip6_tables: last base chain position 1136 doesn't match underflow 1344 (hook 1)
mark_source_chains is not the correct place for such a check, as it terminates evaluation of a chain once it sees an unconditional verdict (following rules are known to be unreachable). It seems preferrable to fix libiptc instead, so remove this check again.
--- net/ipv4/netfilter/arp_tables.c | 17 +---------------- net/ipv4/netfilter/ip_tables.c | 17 +---------------- net/ipv6/netfilter/ip6_tables.c | 17 +---------------- 3 files changed, 3 insertions(+), 48 deletions(-)
net/ipv4/netfilter/arp_tables.c +1 -16
@@ -309,13 +309,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo,for (hook =0 ; hook <NF_ARP_NUMHOOKS ; hook++) {unsigned int pos = newinfo->hook_entry[hook];struct arpt_entry *e = entry0 + pos; -unsigned int last_pos, depth;if (!(valid_hooks & (1 << hook)))continue ; - depth =0 ; - last_pos = pos;/* Set initial back pointer. */ e->counters.pcnt = pos;
@@ -346,8 +343,6 @@ static int mark_source_chains(const struct xt_table_info *newinfo, pos = e->counters.pcnt; e->counters.pcnt =0 ; -if (depth) - --depth;/* We're at the start. */ if (pos == oldpos) goto next;
@@ -372,9 +367,6 @@ static int mark_source_chains(const struct xt_table_info *newinfo,if (!xt_find_jump_offset (offsets, newpos, newinfo->number))return 0 ; - -if (entry0 + newpos !=arpt_next_entry (e)) - ++depth; }else {/* ... this is a fallthru */ newpos = pos + e->next_offset;
@@ -385,15 +377,8 @@ static int mark_source_chains(const struct xt_table_info *newinfo, e->counters.pcnt = pos; pos = newpos; } -if (depth ==0 ) - last_pos = pos; - } -next: -if (last_pos != newinfo->underflow[hook]) { -pr_err_ratelimited ("last base chain position %u doesn't match underflow %u (hook %u)\n" , - last_pos, newinfo->underflow[hook], hook); -return 0 ; } +next: ; }return 1 ; }
net/ipv4/netfilter/ip_tables.c +1 -16
@@ -378,13 +378,10 @@ mark_source_chains(const struct xt_table_info *newinfo,for (hook =0 ; hook <NF_INET_NUMHOOKS ; hook++) {unsigned int pos = newinfo->hook_entry[hook];struct ipt_entry *e = entry0 + pos; -unsigned int last_pos, depth;if (!(valid_hooks & (1 << hook)))continue ; - depth =0 ; - last_pos = pos;/* Set initial back pointer. */ e->counters.pcnt = pos;
@@ -413,8 +410,6 @@ mark_source_chains(const struct xt_table_info *newinfo, pos = e->counters.pcnt; e->counters.pcnt =0 ; -if (depth) - --depth;/* We're at the start. */ if (pos == oldpos) goto next;
@@ -439,9 +434,6 @@ mark_source_chains(const struct xt_table_info *newinfo,if (!xt_find_jump_offset (offsets, newpos, newinfo->number))return 0 ; - -if (entry0 + newpos !=ipt_next_entry (e)) - ++depth; }else {/* ... this is a fallthru */ newpos = pos + e->next_offset;
@@ -452,15 +444,8 @@ mark_source_chains(const struct xt_table_info *newinfo, e->counters.pcnt = pos; pos = newpos; } -if (depth ==0 ) - last_pos = pos; - } -next: -if (last_pos != newinfo->underflow[hook]) { -pr_err_ratelimited ("last base chain position %u doesn't match underflow %u (hook %u)\n" , - last_pos, newinfo->underflow[hook], hook); -return 0 ; } +next: ; }return 1 ; }
net/ipv6/netfilter/ip6_tables.c +1 -16
@@ -396,13 +396,10 @@ mark_source_chains(const struct xt_table_info *newinfo,for (hook =0 ; hook <NF_INET_NUMHOOKS ; hook++) {unsigned int pos = newinfo->hook_entry[hook];struct ip6t_entry *e = entry0 + pos; -unsigned int last_pos, depth;if (!(valid_hooks & (1 << hook)))continue ; - depth =0 ; - last_pos = pos;/* Set initial back pointer. */ e->counters.pcnt = pos;
@@ -431,8 +428,6 @@ mark_source_chains(const struct xt_table_info *newinfo, pos = e->counters.pcnt; e->counters.pcnt =0 ; -if (depth) - --depth;/* We're at the start. */ if (pos == oldpos) goto next;
@@ -457,9 +452,6 @@ mark_source_chains(const struct xt_table_info *newinfo,if (!xt_find_jump_offset (offsets, newpos, newinfo->number))return 0 ; - -if (entry0 + newpos !=ip6t_next_entry (e)) - ++depth; }else {/* ... this is a fallthru */ newpos = pos + e->next_offset;
@@ -470,15 +462,8 @@ mark_source_chains(const struct xt_table_info *newinfo, e->counters.pcnt = pos; pos = newpos; } -if (depth ==0 ) - last_pos = pos; - } -next: -if (last_pos != newinfo->underflow[hook]) { -pr_err_ratelimited ("last base chain position %u doesn't match underflow %u (hook %u)\n" , - last_pos, newinfo->underflow[hook], hook); -return 0 ; } +next: ; }return 1 ; }
Signature · 1 line
2.11.0
Pablo Neira Ayuso
maintainerPATCH 47/47 netfilter: ipset: Use is_zero_ether_addr instead of static and memcmp
In reply to Pablo Neira AyusoFrom: Joe Perches <[email protected]>
To make the test a bit clearer and to reduce object size a little.
Miscellanea:
o remove now unnecessary static const array
$ size ip_set_hash_mac.o* text data bss dec hex filename 22822 4619 64 27505 6b71 ip_set_hash_mac.o.allyesconfig.new 22932 4683 64 27679 6c1f ip_set_hash_mac.o.allyesconfig.old 10443 1040 0 11483 2cdb ip_set_hash_mac.o.defconfig.new 10507 1040 0 11547 2d1b ip_set_hash_mac.o.defconfig.old
--- net/netfilter/ipset/ip_set_hash_mac.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
net/netfilter/ipset/ip_set_hash_mac.c +2 -5
@@ -72,9 +72,6 @@ hash_mac4_data_next(struct hash_mac4_elem *next,#define IP_SET_PROTO_UNDEF #include "ip_set_hash_gen.h" -/* Zero valued element is not supported */ -static const unsigned char invalid_ether[ETH_ALEN ] = {0 }; - static int hash_mac4_kadt(struct ip_set *set, const struct sk_buff *skb, const struct xt_action_param *par,
@@ -93,7 +90,7 @@ hash_mac4_kadt(struct ip_set *set, const struct sk_buff *skb,return -EINVAL ;ether_addr_copy (e.ether,eth_hdr (skb)->h_source); -if (memcmp (e.ether, invalid_ether,ETH_ALEN ) ==0 ) +if (is_zero_ether_addr (e.ether))return -EINVAL ;return adtfn (set, &e, &ext, &opt->ext, opt->cmdflags); }
@@ -118,7 +115,7 @@ hash_mac4_uadt(struct ip_set *set, struct nlattr *tb[],if (ret)return ret;ether_addr_copy (e.ether,nla_data (tb[IPSET_ATTR_ETHER ])); -if (memcmp (e.ether, invalid_ether,ETH_ALEN ) ==0 ) +if (is_zero_ether_addr (e.ether))return -IPSET_ERR_HASH_ELEM ;return adtfn (set, &e, &ext, &ext, flags);
Signature · 1 line
2.11.0
Quoted 5 lines · Pablo Neira Ayuso
One module per supported filter chain family type takes too much memory for very little code - too much modularization - place all chain filter definitions in one single file.
Signed-off-by Pablo Neira Ayuso <[email protected]>
Hi Pablo,
I've bisected a link error to this patch:
net/netfilter/nft_reject_inet.o: In function `nft_reject_inet_eval':
nft_reject_inet.c:(.text+0xa7): undefined reference to nf_send_unreach6' nft_reject_inet.c:(.text+0x10c): undefined reference to nf_send_unreach6' nft_reject_inet.c:(.text+0x138): undefined reference to `nf_send_reset6'
Unfortunately I don't immediately see what went wrong, maybe you can spot it.
Arnd
Pablo Neira Ayuso
maintainerQuoted 11 lines · Arnd Bergmann
Quoted 5 lines · Pablo Neira Ayuso
One module per supported filter chain family type takes too much memory for very little code - too much modularization - place all chain filter definitions in one single file.
Signed-off-by Pablo Neira Ayuso <[email protected]>Hi Pablo,
I've bisected a link error to this patch:
Quoted 7 lines
net/netfilter/nft_reject_inet.o: In function `nft_reject_inet_eval':
nft_reject_inet.c:(.text+0xa7): undefined reference tonf_send_unreach6' nft_reject_inet.c:(.text+0x10c): undefined reference tonf_send_unreach6' nft_reject_inet.c:(.text+0x138): undefined reference to `nf_send_reset6'Unfortunately I don't immediately see what went wrong, maybe you can spot it.
Can you pass me your .config file? I will have a look at it. Thanks. Looks like some missing Kconfig stuff.
Quoted 17 lines · Pablo Neira Ayuso
Quoted 16 lines · Arnd Bergmann
Quoted 5 lines · Pablo Neira Ayuso
One module per supported filter chain family type takes too much memory for very little code - too much modularization - place all chain filter definitions in one single file.
Signed-off-by Pablo Neira Ayuso <[email protected]>Hi Pablo,
I've bisected a link error to this patch:
net/netfilter/nft_reject_inet.o: In function `nft_reject_inet_eval':
nft_reject_inet.c:(.text+0xa7): undefined reference tonf_send_unreach6' nft_reject_inet.c:(.text+0x10c): undefined reference tonf_send_unreach6' nft_reject_inet.c:(.text+0x138): undefined reference to `nf_send_reset6'
Quoted 5 lines
Quoted 2 lines
Unfortunately I don't immediately see what went wrong, maybe you can spot it.
Can you pass me your .config file? I will have a look at it. Thanks. Looks like some missing
Kconfigstuff.
Sure, see https://pastebin.com/raw/yF9Y5Mmn
Arnd