From 1c6141898a7b82484370ec9c61e3acdaf22eaa91 Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Thu, 20 Nov 2014 12:28:39 +0100
Subject: [PATCH] br_netfilter: cleanup nf_bridge_alloc() and
nf_bridge_unshare()
Set skb->nf_bridge out of nf_bridge_alloc() and rework clone logic
in nf_bridge_unshare(). This comes in preparation of Gao feng's
patches.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/bridge/br_netfilter.c | 39 +++++++++++++++++++++++----------------
1 file changed, 23 insertions(+), 16 deletions(-)
@@ -129,27 +129,32 @@ static inline struct net_device *bridge_parent(const struct net_device *dev)
static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
{
- skb->nf_bridge = kzalloc(sizeof(struct nf_bridge_info), GFP_ATOMIC);
- if (likely(skb->nf_bridge))
- atomic_set(&(skb->nf_bridge->use), 1);
+ struct nf_bridge_info *nf_bridge;
+
+ nf_bridge = kzalloc(sizeof(struct nf_bridge_info), GFP_ATOMIC);
+ if (nf_bridge == NULL)
+ return NULL;
- return skb->nf_bridge;
+ atomic_set(&nf_bridge->use, 1);
+ return nf_bridge;
}
static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb)
{
- struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+ struct nf_bridge_info *nf_bridge;
- if (atomic_read(&nf_bridge->use) > 1) {
- struct nf_bridge_info *tmp = nf_bridge_alloc(skb);
+ if (atomic_read(&skb->nf_bridge->use) == 1)
+ return skb->nf_bridge;
+
+ nf_bridge = nf_bridge_alloc(skb);
+ if (nf_bridge == NULL)
+ return NULL;
+
+ memcpy(nf_bridge, skb->nf_bridge, sizeof(struct nf_bridge_info));
+ atomic_set(&nf_bridge->use, 1);
+ nf_bridge_put(skb->nf_bridge);
+ skb->nf_bridge = nf_bridge;
- if (tmp) {
- memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info));
- atomic_set(&tmp->use, 1);
- }
- nf_bridge_put(nf_bridge);
- nf_bridge = tmp;
- }
return nf_bridge;
}
@@ -556,7 +561,8 @@ static unsigned int br_nf_pre_routing_ipv6(const struct nf_hook_ops *ops,
return NF_DROP;
nf_bridge_put(skb->nf_bridge);
- if (!nf_bridge_alloc(skb))
+ skb->nf_bridge = nf_bridge_alloc(skb);
+ if (skb->nf_bridge == NULL)
return NF_DROP;
if (!setup_pre_routing(skb))
return NF_DROP;
@@ -612,7 +618,8 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
return NF_DROP;
nf_bridge_put(skb->nf_bridge);
- if (!nf_bridge_alloc(skb))
+ skb->nf_bridge = nf_bridge_alloc(skb);
+ if (skb->nf_bridge == NULL)
return NF_DROP;
if (!setup_pre_routing(skb))
return NF_DROP;
--
1.7.10.4