aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/llc/llc_sap.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
index 39760d013ce2..94790e60d072 100644
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -355,6 +355,24 @@ static inline bool llc_mcast_match(const struct llc_sap *sap,
355 llc->dev == skb->dev; 355 llc->dev == skb->dev;
356} 356}
357 357
358static void llc_do_mcast(struct llc_sap *sap, struct sk_buff *skb,
359 struct sock **stack, int count)
360{
361 struct sk_buff *skb1;
362 int i;
363
364 for (i = 0; i < count; i++) {
365 skb1 = skb_clone(skb, GFP_ATOMIC);
366 if (!skb1) {
367 sock_put(stack[i]);
368 continue;
369 }
370
371 llc_sap_rcv(sap, skb1, stack[i]);
372 sock_put(stack[i]);
373 }
374}
375
358/** 376/**
359 * llc_sap_mcast - Deliver multicast PDU's to all matching datagram sockets. 377 * llc_sap_mcast - Deliver multicast PDU's to all matching datagram sockets.
360 * @sap: SAP 378 * @sap: SAP
@@ -367,25 +385,27 @@ static void llc_sap_mcast(struct llc_sap *sap,
367 const struct llc_addr *laddr, 385 const struct llc_addr *laddr,
368 struct sk_buff *skb) 386 struct sk_buff *skb)
369{ 387{
370 struct sock *sk; 388 int i = 0, count = 256 / sizeof(struct sock *);
389 struct sock *sk, *stack[count];
371 struct hlist_nulls_node *node; 390 struct hlist_nulls_node *node;
372 391
373 spin_lock_bh(&sap->sk_lock); 392 spin_lock_bh(&sap->sk_lock);
374 sk_nulls_for_each_rcu(sk, node, &sap->sk_list) { 393 sk_nulls_for_each_rcu(sk, node, &sap->sk_list) {
375 struct sk_buff *skb1;
376 394
377 if (!llc_mcast_match(sap, laddr, skb, sk)) 395 if (!llc_mcast_match(sap, laddr, skb, sk))
378 continue; 396 continue;
379 397
380 skb1 = skb_clone(skb, GFP_ATOMIC);
381 if (!skb1)
382 break;
383
384 sock_hold(sk); 398 sock_hold(sk);
385 llc_sap_rcv(sap, skb1, sk); 399 if (i < count)
386 sock_put(sk); 400 stack[i++] = sk;
401 else {
402 llc_do_mcast(sap, skb, stack, i);
403 i = 0;
404 }
387 } 405 }
388 spin_unlock_bh(&sap->sk_lock); 406 spin_unlock_bh(&sap->sk_lock);
407
408 llc_do_mcast(sap, skb, stack, i);
389} 409}
390 410
391 411