X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;ds=sidebyside;f=net%2Fllc%2Fllc_input.c;h=db82aff6e40f54802fa79592a76a1d08712b923b;hb=99b0278f95fc9d55adf65133dc678167a88b632a;hp=d62e0f9b9da3edca21a8292bc321764aa1866187;hpb=edc4ff7c08e9885c40e60c4fb39fa42cc91a0602;p=powerpc.git diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c index d62e0f9b9d..db82aff6e4 100644 --- a/net/llc/llc_input.c +++ b/net/llc/llc_input.c @@ -115,8 +115,8 @@ static inline int llc_fixup_skb(struct sk_buff *skb) skb->h.raw += llc_len; skb_pull(skb, llc_len); if (skb->protocol == htons(ETH_P_802_2)) { - u16 pdulen = eth_hdr(skb)->h_proto, - data_size = ntohs(pdulen) - llc_len; + __be16 pdulen = eth_hdr(skb)->h_proto; + u16 data_size = ntohs(pdulen) - llc_len; if (unlikely(pskb_trim_rcsum(skb, data_size))) return 0; @@ -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]))