aboutsummaryrefslogtreecommitdiffstats
path: root/net/llc/llc_sap.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-19 21:55:56 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-19 21:55:56 -0400
commitd0b952a9837f81cd89e756b1b34293fa6e1cb59d (patch)
treefbe488bc5f407afa0e91cefb262d9e9ee69062ac /net/llc/llc_sap.c
parentd90125bfe958ed0451c6b98f831c86aba08b43d5 (diff)
parent47552c4e555eefe381f3d45140b59a2ea4b16486 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (109 commits) [ETHTOOL]: Fix UFO typo [SCTP]: Fix persistent slowdown in sctp when a gap ack consumes rx buffer. [SCTP]: Send only 1 window update SACK per message. [SCTP]: Don't do CRC32C checksum over loopback. [SCTP] Reset rtt_in_progress for the chunk when processing its sack. [SCTP]: Reject sctp packets with broadcast addresses. [SCTP]: Limit association max_retrans setting in setsockopt. [PFKEYV2]: Fix inconsistent typing in struct sadb_x_kmprivate. [IPV6]: Sum real space for RTAs. [IRDA]: Use put_unaligned() in irlmp_do_discovery(). [BRIDGE]: Add support for NETIF_F_HW_CSUM devices [NET]: Add NETIF_F_GEN_CSUM and NETIF_F_ALL_CSUM [TG3]: Convert to non-LLTX [TG3]: Remove unnecessary tx_lock [TCP]: Add tcp_slow_start_after_idle sysctl. [BNX2]: Update version and reldate [BNX2]: Use CPU native page size [BNX2]: Use compressed firmware [BNX2]: Add firmware decompression [BNX2]: Allow WoL settings on new 5708 chips ... Manual fixup for conflict in drivers/net/tulip/winbond-840.c
Diffstat (limited to 'net/llc/llc_sap.c')
-rw-r--r--net/llc/llc_sap.c59
1 files changed, 51 insertions, 8 deletions
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
index 4029ceee9b9..20c4eb5c1ac 100644
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -282,7 +282,7 @@ static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb)
282 * mac, and local sap. Returns pointer for socket found, %NULL otherwise. 282 * mac, and local sap. Returns pointer for socket found, %NULL otherwise.
283 */ 283 */
284static struct sock *llc_lookup_dgram(struct llc_sap *sap, 284static struct sock *llc_lookup_dgram(struct llc_sap *sap,
285 struct llc_addr *laddr) 285 const struct llc_addr *laddr)
286{ 286{
287 struct sock *rc; 287 struct sock *rc;
288 struct hlist_node *node; 288 struct hlist_node *node;
@@ -304,19 +304,62 @@ found:
304 return rc; 304 return rc;
305} 305}
306 306
307/**
308 * llc_sap_mcast - Deliver multicast PDU's to all matching datagram sockets.
309 * @sap: SAP
310 * @laddr: address of local LLC (MAC + SAP)
311 *
312 * Search socket list of the SAP and finds connections with same sap.
313 * Deliver clone to each.
314 */
315static void llc_sap_mcast(struct llc_sap *sap,
316 const struct llc_addr *laddr,
317 struct sk_buff *skb)
318{
319 struct sock *sk;
320 struct hlist_node *node;
321
322 read_lock_bh(&sap->sk_list.lock);
323 sk_for_each(sk, node, &sap->sk_list.list) {
324 struct llc_sock *llc = llc_sk(sk);
325 struct sk_buff *skb1;
326
327 if (sk->sk_type != SOCK_DGRAM)
328 continue;
329
330 if (llc->laddr.lsap != laddr->lsap)
331 continue;
332
333 skb1 = skb_clone(skb, GFP_ATOMIC);
334 if (!skb1)
335 break;
336
337 sock_hold(sk);
338 skb_set_owner_r(skb1, sk);
339 llc_sap_rcv(sap, skb1);
340 sock_put(sk);
341 }
342 read_unlock_bh(&sap->sk_list.lock);
343}
344
345
307void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb) 346void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb)
308{ 347{
309 struct llc_addr laddr; 348 struct llc_addr laddr;
310 struct sock *sk;
311 349
312 llc_pdu_decode_da(skb, laddr.mac); 350 llc_pdu_decode_da(skb, laddr.mac);
313 llc_pdu_decode_dsap(skb, &laddr.lsap); 351 llc_pdu_decode_dsap(skb, &laddr.lsap);
314 352
315 sk = llc_lookup_dgram(sap, &laddr); 353 if (llc_mac_multicast(laddr.mac)) {
316 if (sk) { 354 llc_sap_mcast(sap, &laddr, skb);
317 skb_set_owner_r(skb, sk);
318 llc_sap_rcv(sap, skb);
319 sock_put(sk);
320 } else
321 kfree_skb(skb); 355 kfree_skb(skb);
356 } else {
357 struct sock *sk = llc_lookup_dgram(sap, &laddr);
358 if (sk) {
359 skb_set_owner_r(skb, sk);
360 llc_sap_rcv(sap, skb);
361 sock_put(sk);
362 } else
363 kfree_skb(skb);
364 }
322} 365}