Commit 00cbc3dc authored by David S. Miller's avatar David S. Miller

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf

Pablo Neira Ayuso says:

====================
Netfilter fixes for net

The following patchset contains three Netfilter fixes for your net tree,
they are:

* Fix missing generation sequence initialization which results in a splat
  if lockdep is enabled, it was introduced in the recent works to improve
  nf_conntrack scalability, from Andrey Vagin.

* Don't flush the GRE keymap list in nf_conntrack when the pptp helper is
  disabled otherwise this crashes due to a double release, from Andrey
  Vagin.

* Fix nf_tables cmp fast in big endian, from Patrick McHardy.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1e785f48 b855d416
...@@ -87,7 +87,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, ...@@ -87,7 +87,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
/* delete keymap entries */ /* delete keymap entries */
void nf_ct_gre_keymap_destroy(struct nf_conn *ct); void nf_ct_gre_keymap_destroy(struct nf_conn *ct);
void nf_ct_gre_keymap_flush(struct net *net);
void nf_nat_need_gre(void); void nf_nat_need_gre(void);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -13,6 +13,16 @@ struct nft_cmp_fast_expr { ...@@ -13,6 +13,16 @@ struct nft_cmp_fast_expr {
u8 len; u8 len;
}; };
/* Calculate the mask for the nft_cmp_fast expression. On big endian the
* mask needs to include the *upper* bytes when interpreting that data as
* something smaller than the full u32, therefore a cpu_to_le32 is done.
*/
static inline u32 nft_cmp_fast_mask(unsigned int len)
{
return cpu_to_le32(~0U >> (FIELD_SIZEOF(struct nft_cmp_fast_expr,
data) * BITS_PER_BYTE - len));
}
extern const struct nft_expr_ops nft_cmp_fast_ops; extern const struct nft_expr_ops nft_cmp_fast_ops;
int nft_cmp_module_init(void); int nft_cmp_module_init(void);
......
...@@ -1795,6 +1795,7 @@ int nf_conntrack_init_net(struct net *net) ...@@ -1795,6 +1795,7 @@ int nf_conntrack_init_net(struct net *net)
int cpu; int cpu;
atomic_set(&net->ct.count, 0); atomic_set(&net->ct.count, 0);
seqcount_init(&net->ct.generation);
net->ct.pcpu_lists = alloc_percpu(struct ct_pcpu); net->ct.pcpu_lists = alloc_percpu(struct ct_pcpu);
if (!net->ct.pcpu_lists) if (!net->ct.pcpu_lists)
......
...@@ -605,32 +605,14 @@ static struct nf_conntrack_helper pptp __read_mostly = { ...@@ -605,32 +605,14 @@ static struct nf_conntrack_helper pptp __read_mostly = {
.expect_policy = &pptp_exp_policy, .expect_policy = &pptp_exp_policy,
}; };
static void nf_conntrack_pptp_net_exit(struct net *net)
{
nf_ct_gre_keymap_flush(net);
}
static struct pernet_operations nf_conntrack_pptp_net_ops = {
.exit = nf_conntrack_pptp_net_exit,
};
static int __init nf_conntrack_pptp_init(void) static int __init nf_conntrack_pptp_init(void)
{ {
int rv; return nf_conntrack_helper_register(&pptp);
rv = nf_conntrack_helper_register(&pptp);
if (rv < 0)
return rv;
rv = register_pernet_subsys(&nf_conntrack_pptp_net_ops);
if (rv < 0)
nf_conntrack_helper_unregister(&pptp);
return rv;
} }
static void __exit nf_conntrack_pptp_fini(void) static void __exit nf_conntrack_pptp_fini(void)
{ {
nf_conntrack_helper_unregister(&pptp); nf_conntrack_helper_unregister(&pptp);
unregister_pernet_subsys(&nf_conntrack_pptp_net_ops);
} }
module_init(nf_conntrack_pptp_init); module_init(nf_conntrack_pptp_init);
......
...@@ -66,7 +66,7 @@ static inline struct netns_proto_gre *gre_pernet(struct net *net) ...@@ -66,7 +66,7 @@ static inline struct netns_proto_gre *gre_pernet(struct net *net)
return net_generic(net, proto_gre_net_id); return net_generic(net, proto_gre_net_id);
} }
void nf_ct_gre_keymap_flush(struct net *net) static void nf_ct_gre_keymap_flush(struct net *net)
{ {
struct netns_proto_gre *net_gre = gre_pernet(net); struct netns_proto_gre *net_gre = gre_pernet(net);
struct nf_ct_gre_keymap *km, *tmp; struct nf_ct_gre_keymap *km, *tmp;
...@@ -78,7 +78,6 @@ void nf_ct_gre_keymap_flush(struct net *net) ...@@ -78,7 +78,6 @@ void nf_ct_gre_keymap_flush(struct net *net)
} }
write_unlock_bh(&net_gre->keymap_lock); write_unlock_bh(&net_gre->keymap_lock);
} }
EXPORT_SYMBOL(nf_ct_gre_keymap_flush);
static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km, static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km,
const struct nf_conntrack_tuple *t) const struct nf_conntrack_tuple *t)
......
...@@ -25,9 +25,8 @@ static void nft_cmp_fast_eval(const struct nft_expr *expr, ...@@ -25,9 +25,8 @@ static void nft_cmp_fast_eval(const struct nft_expr *expr,
struct nft_data data[NFT_REG_MAX + 1]) struct nft_data data[NFT_REG_MAX + 1])
{ {
const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr); const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr);
u32 mask; u32 mask = nft_cmp_fast_mask(priv->len);
mask = ~0U >> (sizeof(priv->data) * BITS_PER_BYTE - priv->len);
if ((data[priv->sreg].data[0] & mask) == priv->data) if ((data[priv->sreg].data[0] & mask) == priv->data)
return; return;
data[NFT_REG_VERDICT].verdict = NFT_BREAK; data[NFT_REG_VERDICT].verdict = NFT_BREAK;
......
...@@ -128,7 +128,7 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx, ...@@ -128,7 +128,7 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx,
BUG_ON(err < 0); BUG_ON(err < 0);
desc.len *= BITS_PER_BYTE; desc.len *= BITS_PER_BYTE;
mask = ~0U >> (sizeof(priv->data) * BITS_PER_BYTE - desc.len); mask = nft_cmp_fast_mask(desc.len);
priv->data = data.data[0] & mask; priv->data = data.data[0] & mask;
priv->len = desc.len; priv->len = desc.len;
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment