summaryrefslogtreecommitdiff
path: root/net/llc/llc_input.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-20 08:59:45 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-20 08:59:45 -0400
commitd59bf96cdde5b874a57bfd1425faa45da915d0b7 (patch)
tree351a40b72514d620e5bebea2de38c26f23277ffc /net/llc/llc_input.c
parent28df955a2ad484d602314b30183ea8496a9aa34a (diff)
parent25f42b6af09e34c3f92107b36b5aa6edc2fdba2f (diff)
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Diffstat (limited to 'net/llc/llc_input.c')
-rw-r--r--net/llc/llc_input.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c
index d62e0f9b9da3..94d2368ade92 100644
--- a/net/llc/llc_input.c
+++ b/net/llc/llc_input.c
@@ -142,6 +142,8 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
struct llc_sap *sap;
struct llc_pdu_sn *pdu;
int dest;
+ int (*rcv)(struct sk_buff *, struct net_device *,
+ struct packet_type *, struct net_device *);
/*
* When the interface is in promisc. mode, drop all the crap that it
@@ -169,9 +171,11 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
* First the upper layer protocols that don't need the full
* LLC functionality
*/
- if (sap->rcv_func) {
- sap->rcv_func(skb, dev, pt, orig_dev);
- goto out_put;
+ rcv = rcu_dereference(sap->rcv_func);
+ if (rcv) {
+ struct sk_buff *cskb = skb_clone(skb, GFP_ATOMIC);
+ if (cskb)
+ rcv(cskb, dev, pt, orig_dev);
}
dest = llc_pdu_type(skb);
if (unlikely(!dest || !llc_type_handlers[dest - 1]))