X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fllc%2Fllc_input.c;h=db82aff6e40f54802fa79592a76a1d08712b923b;hb=refs%2Fheads%2Fvserver;hp=8f3addf0724c01658c8c46b96677f701c52197f8;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c index 8f3addf07..db82aff6e 100644 --- a/net/llc/llc_input.c +++ b/net/llc/llc_input.c @@ -115,10 +115,11 @@ 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; - skb_trim(skb, data_size); + if (unlikely(pskb_trim_rcsum(skb, data_size))) + return 0; } return 1; } @@ -141,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 @@ -168,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]))