mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-07 10:29:52 +00:00
netfilter: nft_set_pipapo: prepare pipapo_get helper for on-demand clone
The helper uses priv->clone unconditionally which will fail once we do the clone conditionally on first insert or removal. 'nft get element' from userspace needs to use priv->match since this runs from rcu read side lock section. Prepare for this by passing the match backend data as argument. Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
committed by
Pablo Neira Ayuso
parent
c5444786d0
commit
a238106703
@@ -504,6 +504,7 @@ out:
|
|||||||
* pipapo_get() - Get matching element reference given key data
|
* pipapo_get() - Get matching element reference given key data
|
||||||
* @net: Network namespace
|
* @net: Network namespace
|
||||||
* @set: nftables API set representation
|
* @set: nftables API set representation
|
||||||
|
* @m: storage containing active/existing elements
|
||||||
* @data: Key data to be matched against existing elements
|
* @data: Key data to be matched against existing elements
|
||||||
* @genmask: If set, check that element is active in given genmask
|
* @genmask: If set, check that element is active in given genmask
|
||||||
* @tstamp: timestamp to check for expired elements
|
* @tstamp: timestamp to check for expired elements
|
||||||
@@ -517,17 +518,15 @@ out:
|
|||||||
*/
|
*/
|
||||||
static struct nft_pipapo_elem *pipapo_get(const struct net *net,
|
static struct nft_pipapo_elem *pipapo_get(const struct net *net,
|
||||||
const struct nft_set *set,
|
const struct nft_set *set,
|
||||||
|
const struct nft_pipapo_match *m,
|
||||||
const u8 *data, u8 genmask,
|
const u8 *data, u8 genmask,
|
||||||
u64 tstamp, gfp_t gfp)
|
u64 tstamp, gfp_t gfp)
|
||||||
{
|
{
|
||||||
struct nft_pipapo_elem *ret = ERR_PTR(-ENOENT);
|
struct nft_pipapo_elem *ret = ERR_PTR(-ENOENT);
|
||||||
struct nft_pipapo *priv = nft_set_priv(set);
|
|
||||||
unsigned long *res_map, *fill_map = NULL;
|
unsigned long *res_map, *fill_map = NULL;
|
||||||
const struct nft_pipapo_match *m;
|
|
||||||
const struct nft_pipapo_field *f;
|
const struct nft_pipapo_field *f;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
m = priv->clone;
|
|
||||||
if (m->bsize_max == 0)
|
if (m->bsize_max == 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -612,9 +611,11 @@ static struct nft_elem_priv *
|
|||||||
nft_pipapo_get(const struct net *net, const struct nft_set *set,
|
nft_pipapo_get(const struct net *net, const struct nft_set *set,
|
||||||
const struct nft_set_elem *elem, unsigned int flags)
|
const struct nft_set_elem *elem, unsigned int flags)
|
||||||
{
|
{
|
||||||
|
struct nft_pipapo *priv = nft_set_priv(set);
|
||||||
|
struct nft_pipapo_match *m = rcu_dereference(priv->match);
|
||||||
struct nft_pipapo_elem *e;
|
struct nft_pipapo_elem *e;
|
||||||
|
|
||||||
e = pipapo_get(net, set, (const u8 *)elem->key.val.data,
|
e = pipapo_get(net, set, m, (const u8 *)elem->key.val.data,
|
||||||
nft_genmask_cur(net), get_jiffies_64(),
|
nft_genmask_cur(net), get_jiffies_64(),
|
||||||
GFP_ATOMIC);
|
GFP_ATOMIC);
|
||||||
if (IS_ERR(e))
|
if (IS_ERR(e))
|
||||||
@@ -1288,7 +1289,7 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
|
|||||||
else
|
else
|
||||||
end = start;
|
end = start;
|
||||||
|
|
||||||
dup = pipapo_get(net, set, start, genmask, tstamp, GFP_KERNEL);
|
dup = pipapo_get(net, set, m, start, genmask, tstamp, GFP_KERNEL);
|
||||||
if (!IS_ERR(dup)) {
|
if (!IS_ERR(dup)) {
|
||||||
/* Check if we already have the same exact entry */
|
/* Check if we already have the same exact entry */
|
||||||
const struct nft_data *dup_key, *dup_end;
|
const struct nft_data *dup_key, *dup_end;
|
||||||
@@ -1310,7 +1311,7 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
|
|||||||
|
|
||||||
if (PTR_ERR(dup) == -ENOENT) {
|
if (PTR_ERR(dup) == -ENOENT) {
|
||||||
/* Look for partially overlapping entries */
|
/* Look for partially overlapping entries */
|
||||||
dup = pipapo_get(net, set, end, nft_genmask_next(net), tstamp,
|
dup = pipapo_get(net, set, m, end, nft_genmask_next(net), tstamp,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1862,9 +1863,11 @@ static struct nft_elem_priv *
|
|||||||
nft_pipapo_deactivate(const struct net *net, const struct nft_set *set,
|
nft_pipapo_deactivate(const struct net *net, const struct nft_set *set,
|
||||||
const struct nft_set_elem *elem)
|
const struct nft_set_elem *elem)
|
||||||
{
|
{
|
||||||
|
const struct nft_pipapo *priv = nft_set_priv(set);
|
||||||
|
struct nft_pipapo_match *m = priv->clone;
|
||||||
struct nft_pipapo_elem *e;
|
struct nft_pipapo_elem *e;
|
||||||
|
|
||||||
e = pipapo_get(net, set, (const u8 *)elem->key.val.data,
|
e = pipapo_get(net, set, m, (const u8 *)elem->key.val.data,
|
||||||
nft_genmask_next(net), nft_net_tstamp(net), GFP_KERNEL);
|
nft_genmask_next(net), nft_net_tstamp(net), GFP_KERNEL);
|
||||||
if (IS_ERR(e))
|
if (IS_ERR(e))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
Reference in New Issue
Block a user