From 23dbe7912dad6be71bb9e69cb819d05e2442d362 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 25 May 2006 15:09:37 -0700 Subject: [LLC]: use rcu_dereference on receive handler The receive hander pointer might be modified during network changes of protocol. So use rcu_dereference (only matters on alpha). Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/llc/llc_input.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'net/llc/llc_input.c') diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c index d62e0f9b9da3..cb9f7f058f75 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,8 +171,9 @@ 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); + rcv = rcu_dereference(sap->rcv_func); + if (rcv) { + rcv(skb, dev, pt, orig_dev); goto out_put; } dest = llc_pdu_type(skb); -- cgit v1.2.3 From 8f182b494f87799d6ae20a1401825c516da46081 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 25 May 2006 15:10:02 -0700 Subject: [LLC]: allow applications to get copy of kernel datagrams It is legal for an application to bind to a SAP that is also being used by the kernel. This happens if the bridge module binds to the STP SAP, and the user wants to have a daemon for STP as well. It is possible to have kernel doing STP on one bridge, but let application do RSTP on another bridge. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/llc/llc_input.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'net/llc/llc_input.c') diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c index cb9f7f058f75..32cf8ac8ea80 100644 --- a/net/llc/llc_input.c +++ b/net/llc/llc_input.c @@ -173,8 +173,10 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, */ 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); rcv(skb, dev, pt, orig_dev); - goto out_put; } dest = llc_pdu_type(skb); if (unlikely(!dest || !llc_type_handlers[dest - 1])) -- cgit v1.2.3 From 2f45c340e09242641d4f11498c3be48b35abb926 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 2 Jun 2006 16:29:20 -0700 Subject: [LLC]: Fix double receive of SKB. Oops fix from Stephen: remove duplicate rcv() calls. Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- net/llc/llc_input.c | 1 - 1 file changed, 1 deletion(-) (limited to 'net/llc/llc_input.c') diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c index 32cf8ac8ea80..94d2368ade92 100644 --- a/net/llc/llc_input.c +++ b/net/llc/llc_input.c @@ -176,7 +176,6 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, struct sk_buff *cskb = skb_clone(skb, GFP_ATOMIC); if (cskb) rcv(cskb, dev, pt, orig_dev); - rcv(skb, dev, pt, orig_dev); } dest = llc_pdu_type(skb); if (unlikely(!dest || !llc_type_handlers[dest - 1])) -- cgit v1.2.3