diff options
Diffstat (limited to 'net/llc')
-rw-r--r-- | net/llc/llc_input.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c index f99687439139..058f1e9a9128 100644 --- a/net/llc/llc_input.c +++ b/net/llc/llc_input.c | |||
@@ -181,25 +181,26 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, | |||
181 | * LLC functionality | 181 | * LLC functionality |
182 | */ | 182 | */ |
183 | rcv = rcu_dereference(sap->rcv_func); | 183 | rcv = rcu_dereference(sap->rcv_func); |
184 | if (rcv) { | ||
185 | struct sk_buff *cskb = skb_clone(skb, GFP_ATOMIC); | ||
186 | if (cskb) | ||
187 | rcv(cskb, dev, pt, orig_dev); | ||
188 | } | ||
189 | dest = llc_pdu_type(skb); | 184 | dest = llc_pdu_type(skb); |
190 | if (unlikely(!dest || !llc_type_handlers[dest - 1])) | 185 | if (unlikely(!dest || !llc_type_handlers[dest - 1])) { |
191 | goto drop_put; | 186 | if (rcv) |
192 | llc_type_handlers[dest - 1](sap, skb); | 187 | rcv(skb, dev, pt, orig_dev); |
193 | out_put: | 188 | else |
189 | kfree_skb(skb); | ||
190 | } else { | ||
191 | if (rcv) { | ||
192 | struct sk_buff *cskb = skb_clone(skb, GFP_ATOMIC); | ||
193 | if (cskb) | ||
194 | rcv(cskb, dev, pt, orig_dev); | ||
195 | } | ||
196 | llc_type_handlers[dest - 1](sap, skb); | ||
197 | } | ||
194 | llc_sap_put(sap); | 198 | llc_sap_put(sap); |
195 | out: | 199 | out: |
196 | return 0; | 200 | return 0; |
197 | drop: | 201 | drop: |
198 | kfree_skb(skb); | 202 | kfree_skb(skb); |
199 | goto out; | 203 | goto out; |
200 | drop_put: | ||
201 | kfree_skb(skb); | ||
202 | goto out_put; | ||
203 | handle_station: | 204 | handle_station: |
204 | if (!llc_station_handler) | 205 | if (!llc_station_handler) |
205 | goto drop; | 206 | goto drop; |