diff options
Diffstat (limited to 'net/llc/llc_input.c')
| -rw-r--r-- | net/llc/llc_input.c | 10 |
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, | |||
| 142 | struct llc_sap *sap; | 142 | struct llc_sap *sap; |
| 143 | struct llc_pdu_sn *pdu; | 143 | struct llc_pdu_sn *pdu; |
| 144 | int dest; | 144 | int dest; |
| 145 | int (*rcv)(struct sk_buff *, struct net_device *, | ||
| 146 | struct packet_type *, struct net_device *); | ||
| 145 | 147 | ||
| 146 | /* | 148 | /* |
| 147 | * When the interface is in promisc. mode, drop all the crap that it | 149 | * 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, | |||
| 169 | * First the upper layer protocols that don't need the full | 171 | * First the upper layer protocols that don't need the full |
| 170 | * LLC functionality | 172 | * LLC functionality |
| 171 | */ | 173 | */ |
| 172 | if (sap->rcv_func) { | 174 | rcv = rcu_dereference(sap->rcv_func); |
| 173 | sap->rcv_func(skb, dev, pt, orig_dev); | 175 | if (rcv) { |
| 174 | goto out_put; | 176 | struct sk_buff *cskb = skb_clone(skb, GFP_ATOMIC); |
| 177 | if (cskb) | ||
| 178 | rcv(cskb, dev, pt, orig_dev); | ||
| 175 | } | 179 | } |
| 176 | dest = llc_pdu_type(skb); | 180 | dest = llc_pdu_type(skb); |
| 177 | if (unlikely(!dest || !llc_type_handlers[dest - 1])) | 181 | if (unlikely(!dest || !llc_type_handlers[dest - 1])) |
