xref: /OK3568_Linux_fs/kernel/net/nfc/rawsock.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2011 Instituto Nokia de Tecnologia
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Authors:
6*4882a593Smuzhiyun  *    Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
7*4882a593Smuzhiyun  *    Lauro Ramos Venancio <lauro.venancio@openbossa.org>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <net/tcp_states.h>
13*4882a593Smuzhiyun #include <linux/nfc.h>
14*4882a593Smuzhiyun #include <linux/export.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #include "nfc.h"
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun static struct nfc_sock_list raw_sk_list = {
19*4882a593Smuzhiyun 	.lock = __RW_LOCK_UNLOCKED(raw_sk_list.lock)
20*4882a593Smuzhiyun };
21*4882a593Smuzhiyun 
nfc_sock_link(struct nfc_sock_list * l,struct sock * sk)22*4882a593Smuzhiyun static void nfc_sock_link(struct nfc_sock_list *l, struct sock *sk)
23*4882a593Smuzhiyun {
24*4882a593Smuzhiyun 	write_lock(&l->lock);
25*4882a593Smuzhiyun 	sk_add_node(sk, &l->head);
26*4882a593Smuzhiyun 	write_unlock(&l->lock);
27*4882a593Smuzhiyun }
28*4882a593Smuzhiyun 
nfc_sock_unlink(struct nfc_sock_list * l,struct sock * sk)29*4882a593Smuzhiyun static void nfc_sock_unlink(struct nfc_sock_list *l, struct sock *sk)
30*4882a593Smuzhiyun {
31*4882a593Smuzhiyun 	write_lock(&l->lock);
32*4882a593Smuzhiyun 	sk_del_node_init(sk);
33*4882a593Smuzhiyun 	write_unlock(&l->lock);
34*4882a593Smuzhiyun }
35*4882a593Smuzhiyun 
rawsock_write_queue_purge(struct sock * sk)36*4882a593Smuzhiyun static void rawsock_write_queue_purge(struct sock *sk)
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun 	pr_debug("sk=%p\n", sk);
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 	spin_lock_bh(&sk->sk_write_queue.lock);
41*4882a593Smuzhiyun 	__skb_queue_purge(&sk->sk_write_queue);
42*4882a593Smuzhiyun 	nfc_rawsock(sk)->tx_work_scheduled = false;
43*4882a593Smuzhiyun 	spin_unlock_bh(&sk->sk_write_queue.lock);
44*4882a593Smuzhiyun }
45*4882a593Smuzhiyun 
rawsock_report_error(struct sock * sk,int err)46*4882a593Smuzhiyun static void rawsock_report_error(struct sock *sk, int err)
47*4882a593Smuzhiyun {
48*4882a593Smuzhiyun 	pr_debug("sk=%p err=%d\n", sk, err);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	sk->sk_shutdown = SHUTDOWN_MASK;
51*4882a593Smuzhiyun 	sk->sk_err = -err;
52*4882a593Smuzhiyun 	sk->sk_error_report(sk);
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	rawsock_write_queue_purge(sk);
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun 
rawsock_release(struct socket * sock)57*4882a593Smuzhiyun static int rawsock_release(struct socket *sock)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun 	struct sock *sk = sock->sk;
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	pr_debug("sock=%p sk=%p\n", sock, sk);
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 	if (!sk)
64*4882a593Smuzhiyun 		return 0;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	if (sock->type == SOCK_RAW)
67*4882a593Smuzhiyun 		nfc_sock_unlink(&raw_sk_list, sk);
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	sock_orphan(sk);
70*4882a593Smuzhiyun 	sock_put(sk);
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	return 0;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun 
rawsock_connect(struct socket * sock,struct sockaddr * _addr,int len,int flags)75*4882a593Smuzhiyun static int rawsock_connect(struct socket *sock, struct sockaddr *_addr,
76*4882a593Smuzhiyun 			   int len, int flags)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun 	struct sock *sk = sock->sk;
79*4882a593Smuzhiyun 	struct sockaddr_nfc *addr = (struct sockaddr_nfc *)_addr;
80*4882a593Smuzhiyun 	struct nfc_dev *dev;
81*4882a593Smuzhiyun 	int rc = 0;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	pr_debug("sock=%p sk=%p flags=%d\n", sock, sk, flags);
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	if (!addr || len < sizeof(struct sockaddr_nfc) ||
86*4882a593Smuzhiyun 	    addr->sa_family != AF_NFC)
87*4882a593Smuzhiyun 		return -EINVAL;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	pr_debug("addr dev_idx=%u target_idx=%u protocol=%u\n",
90*4882a593Smuzhiyun 		 addr->dev_idx, addr->target_idx, addr->nfc_protocol);
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	lock_sock(sk);
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	if (sock->state == SS_CONNECTED) {
95*4882a593Smuzhiyun 		rc = -EISCONN;
96*4882a593Smuzhiyun 		goto error;
97*4882a593Smuzhiyun 	}
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	dev = nfc_get_device(addr->dev_idx);
100*4882a593Smuzhiyun 	if (!dev) {
101*4882a593Smuzhiyun 		rc = -ENODEV;
102*4882a593Smuzhiyun 		goto error;
103*4882a593Smuzhiyun 	}
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	if (addr->target_idx > dev->target_next_idx - 1 ||
106*4882a593Smuzhiyun 	    addr->target_idx < dev->target_next_idx - dev->n_targets) {
107*4882a593Smuzhiyun 		rc = -EINVAL;
108*4882a593Smuzhiyun 		goto put_dev;
109*4882a593Smuzhiyun 	}
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	rc = nfc_activate_target(dev, addr->target_idx, addr->nfc_protocol);
112*4882a593Smuzhiyun 	if (rc)
113*4882a593Smuzhiyun 		goto put_dev;
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 	nfc_rawsock(sk)->dev = dev;
116*4882a593Smuzhiyun 	nfc_rawsock(sk)->target_idx = addr->target_idx;
117*4882a593Smuzhiyun 	sock->state = SS_CONNECTED;
118*4882a593Smuzhiyun 	sk->sk_state = TCP_ESTABLISHED;
119*4882a593Smuzhiyun 	sk->sk_state_change(sk);
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	release_sock(sk);
122*4882a593Smuzhiyun 	return 0;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun put_dev:
125*4882a593Smuzhiyun 	nfc_put_device(dev);
126*4882a593Smuzhiyun error:
127*4882a593Smuzhiyun 	release_sock(sk);
128*4882a593Smuzhiyun 	return rc;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun 
rawsock_add_header(struct sk_buff * skb)131*4882a593Smuzhiyun static int rawsock_add_header(struct sk_buff *skb)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun 	*(u8 *)skb_push(skb, NFC_HEADER_SIZE) = 0;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	return 0;
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun 
rawsock_data_exchange_complete(void * context,struct sk_buff * skb,int err)138*4882a593Smuzhiyun static void rawsock_data_exchange_complete(void *context, struct sk_buff *skb,
139*4882a593Smuzhiyun 					   int err)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	struct sock *sk = (struct sock *) context;
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	BUG_ON(in_irq());
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	pr_debug("sk=%p err=%d\n", sk, err);
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	if (err)
148*4882a593Smuzhiyun 		goto error;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	err = rawsock_add_header(skb);
151*4882a593Smuzhiyun 	if (err)
152*4882a593Smuzhiyun 		goto error_skb;
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	err = sock_queue_rcv_skb(sk, skb);
155*4882a593Smuzhiyun 	if (err)
156*4882a593Smuzhiyun 		goto error_skb;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	spin_lock_bh(&sk->sk_write_queue.lock);
159*4882a593Smuzhiyun 	if (!skb_queue_empty(&sk->sk_write_queue))
160*4882a593Smuzhiyun 		schedule_work(&nfc_rawsock(sk)->tx_work);
161*4882a593Smuzhiyun 	else
162*4882a593Smuzhiyun 		nfc_rawsock(sk)->tx_work_scheduled = false;
163*4882a593Smuzhiyun 	spin_unlock_bh(&sk->sk_write_queue.lock);
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	sock_put(sk);
166*4882a593Smuzhiyun 	return;
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun error_skb:
169*4882a593Smuzhiyun 	kfree_skb(skb);
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun error:
172*4882a593Smuzhiyun 	rawsock_report_error(sk, err);
173*4882a593Smuzhiyun 	sock_put(sk);
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun 
rawsock_tx_work(struct work_struct * work)176*4882a593Smuzhiyun static void rawsock_tx_work(struct work_struct *work)
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun 	struct sock *sk = to_rawsock_sk(work);
179*4882a593Smuzhiyun 	struct nfc_dev *dev = nfc_rawsock(sk)->dev;
180*4882a593Smuzhiyun 	u32 target_idx = nfc_rawsock(sk)->target_idx;
181*4882a593Smuzhiyun 	struct sk_buff *skb;
182*4882a593Smuzhiyun 	int rc;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	pr_debug("sk=%p target_idx=%u\n", sk, target_idx);
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	if (sk->sk_shutdown & SEND_SHUTDOWN) {
187*4882a593Smuzhiyun 		rawsock_write_queue_purge(sk);
188*4882a593Smuzhiyun 		return;
189*4882a593Smuzhiyun 	}
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	skb = skb_dequeue(&sk->sk_write_queue);
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	sock_hold(sk);
194*4882a593Smuzhiyun 	rc = nfc_data_exchange(dev, target_idx, skb,
195*4882a593Smuzhiyun 			       rawsock_data_exchange_complete, sk);
196*4882a593Smuzhiyun 	if (rc) {
197*4882a593Smuzhiyun 		rawsock_report_error(sk, rc);
198*4882a593Smuzhiyun 		sock_put(sk);
199*4882a593Smuzhiyun 	}
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun 
rawsock_sendmsg(struct socket * sock,struct msghdr * msg,size_t len)202*4882a593Smuzhiyun static int rawsock_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 	struct sock *sk = sock->sk;
205*4882a593Smuzhiyun 	struct nfc_dev *dev = nfc_rawsock(sk)->dev;
206*4882a593Smuzhiyun 	struct sk_buff *skb;
207*4882a593Smuzhiyun 	int rc;
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	pr_debug("sock=%p sk=%p len=%zu\n", sock, sk, len);
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	if (msg->msg_namelen)
212*4882a593Smuzhiyun 		return -EOPNOTSUPP;
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	if (sock->state != SS_CONNECTED)
215*4882a593Smuzhiyun 		return -ENOTCONN;
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	skb = nfc_alloc_send_skb(dev, sk, msg->msg_flags, len, &rc);
218*4882a593Smuzhiyun 	if (skb == NULL)
219*4882a593Smuzhiyun 		return rc;
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun 	rc = memcpy_from_msg(skb_put(skb, len), msg, len);
222*4882a593Smuzhiyun 	if (rc < 0) {
223*4882a593Smuzhiyun 		kfree_skb(skb);
224*4882a593Smuzhiyun 		return rc;
225*4882a593Smuzhiyun 	}
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	spin_lock_bh(&sk->sk_write_queue.lock);
228*4882a593Smuzhiyun 	__skb_queue_tail(&sk->sk_write_queue, skb);
229*4882a593Smuzhiyun 	if (!nfc_rawsock(sk)->tx_work_scheduled) {
230*4882a593Smuzhiyun 		schedule_work(&nfc_rawsock(sk)->tx_work);
231*4882a593Smuzhiyun 		nfc_rawsock(sk)->tx_work_scheduled = true;
232*4882a593Smuzhiyun 	}
233*4882a593Smuzhiyun 	spin_unlock_bh(&sk->sk_write_queue.lock);
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	return len;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun 
rawsock_recvmsg(struct socket * sock,struct msghdr * msg,size_t len,int flags)238*4882a593Smuzhiyun static int rawsock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
239*4882a593Smuzhiyun 			   int flags)
240*4882a593Smuzhiyun {
241*4882a593Smuzhiyun 	int noblock = flags & MSG_DONTWAIT;
242*4882a593Smuzhiyun 	struct sock *sk = sock->sk;
243*4882a593Smuzhiyun 	struct sk_buff *skb;
244*4882a593Smuzhiyun 	int copied;
245*4882a593Smuzhiyun 	int rc;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	pr_debug("sock=%p sk=%p len=%zu flags=%d\n", sock, sk, len, flags);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 	skb = skb_recv_datagram(sk, flags, noblock, &rc);
250*4882a593Smuzhiyun 	if (!skb)
251*4882a593Smuzhiyun 		return rc;
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	copied = skb->len;
254*4882a593Smuzhiyun 	if (len < copied) {
255*4882a593Smuzhiyun 		msg->msg_flags |= MSG_TRUNC;
256*4882a593Smuzhiyun 		copied = len;
257*4882a593Smuzhiyun 	}
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	rc = skb_copy_datagram_msg(skb, 0, msg, copied);
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	skb_free_datagram(sk, skb);
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	return rc ? : copied;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun static const struct proto_ops rawsock_ops = {
267*4882a593Smuzhiyun 	.family         = PF_NFC,
268*4882a593Smuzhiyun 	.owner          = THIS_MODULE,
269*4882a593Smuzhiyun 	.release        = rawsock_release,
270*4882a593Smuzhiyun 	.bind           = sock_no_bind,
271*4882a593Smuzhiyun 	.connect        = rawsock_connect,
272*4882a593Smuzhiyun 	.socketpair     = sock_no_socketpair,
273*4882a593Smuzhiyun 	.accept         = sock_no_accept,
274*4882a593Smuzhiyun 	.getname        = sock_no_getname,
275*4882a593Smuzhiyun 	.poll           = datagram_poll,
276*4882a593Smuzhiyun 	.ioctl          = sock_no_ioctl,
277*4882a593Smuzhiyun 	.listen         = sock_no_listen,
278*4882a593Smuzhiyun 	.shutdown       = sock_no_shutdown,
279*4882a593Smuzhiyun 	.sendmsg        = rawsock_sendmsg,
280*4882a593Smuzhiyun 	.recvmsg        = rawsock_recvmsg,
281*4882a593Smuzhiyun 	.mmap           = sock_no_mmap,
282*4882a593Smuzhiyun };
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun static const struct proto_ops rawsock_raw_ops = {
285*4882a593Smuzhiyun 	.family         = PF_NFC,
286*4882a593Smuzhiyun 	.owner          = THIS_MODULE,
287*4882a593Smuzhiyun 	.release        = rawsock_release,
288*4882a593Smuzhiyun 	.bind           = sock_no_bind,
289*4882a593Smuzhiyun 	.connect        = sock_no_connect,
290*4882a593Smuzhiyun 	.socketpair     = sock_no_socketpair,
291*4882a593Smuzhiyun 	.accept         = sock_no_accept,
292*4882a593Smuzhiyun 	.getname        = sock_no_getname,
293*4882a593Smuzhiyun 	.poll           = datagram_poll,
294*4882a593Smuzhiyun 	.ioctl          = sock_no_ioctl,
295*4882a593Smuzhiyun 	.listen         = sock_no_listen,
296*4882a593Smuzhiyun 	.shutdown       = sock_no_shutdown,
297*4882a593Smuzhiyun 	.sendmsg        = sock_no_sendmsg,
298*4882a593Smuzhiyun 	.recvmsg        = rawsock_recvmsg,
299*4882a593Smuzhiyun 	.mmap           = sock_no_mmap,
300*4882a593Smuzhiyun };
301*4882a593Smuzhiyun 
rawsock_destruct(struct sock * sk)302*4882a593Smuzhiyun static void rawsock_destruct(struct sock *sk)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun 	pr_debug("sk=%p\n", sk);
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	if (sk->sk_state == TCP_ESTABLISHED) {
307*4882a593Smuzhiyun 		nfc_deactivate_target(nfc_rawsock(sk)->dev,
308*4882a593Smuzhiyun 				      nfc_rawsock(sk)->target_idx,
309*4882a593Smuzhiyun 				      NFC_TARGET_MODE_IDLE);
310*4882a593Smuzhiyun 		nfc_put_device(nfc_rawsock(sk)->dev);
311*4882a593Smuzhiyun 	}
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	skb_queue_purge(&sk->sk_receive_queue);
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	if (!sock_flag(sk, SOCK_DEAD)) {
316*4882a593Smuzhiyun 		pr_err("Freeing alive NFC raw socket %p\n", sk);
317*4882a593Smuzhiyun 		return;
318*4882a593Smuzhiyun 	}
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun 
rawsock_create(struct net * net,struct socket * sock,const struct nfc_protocol * nfc_proto,int kern)321*4882a593Smuzhiyun static int rawsock_create(struct net *net, struct socket *sock,
322*4882a593Smuzhiyun 			  const struct nfc_protocol *nfc_proto, int kern)
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun 	struct sock *sk;
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 	pr_debug("sock=%p\n", sock);
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 	if ((sock->type != SOCK_SEQPACKET) && (sock->type != SOCK_RAW))
329*4882a593Smuzhiyun 		return -ESOCKTNOSUPPORT;
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	if (sock->type == SOCK_RAW) {
332*4882a593Smuzhiyun 		if (!ns_capable(net->user_ns, CAP_NET_RAW))
333*4882a593Smuzhiyun 			return -EPERM;
334*4882a593Smuzhiyun 		sock->ops = &rawsock_raw_ops;
335*4882a593Smuzhiyun 	} else {
336*4882a593Smuzhiyun 		sock->ops = &rawsock_ops;
337*4882a593Smuzhiyun 	}
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	sk = sk_alloc(net, PF_NFC, GFP_ATOMIC, nfc_proto->proto, kern);
340*4882a593Smuzhiyun 	if (!sk)
341*4882a593Smuzhiyun 		return -ENOMEM;
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	sock_init_data(sock, sk);
344*4882a593Smuzhiyun 	sk->sk_protocol = nfc_proto->id;
345*4882a593Smuzhiyun 	sk->sk_destruct = rawsock_destruct;
346*4882a593Smuzhiyun 	sock->state = SS_UNCONNECTED;
347*4882a593Smuzhiyun 	if (sock->type == SOCK_RAW)
348*4882a593Smuzhiyun 		nfc_sock_link(&raw_sk_list, sk);
349*4882a593Smuzhiyun 	else {
350*4882a593Smuzhiyun 		INIT_WORK(&nfc_rawsock(sk)->tx_work, rawsock_tx_work);
351*4882a593Smuzhiyun 		nfc_rawsock(sk)->tx_work_scheduled = false;
352*4882a593Smuzhiyun 	}
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 	return 0;
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun 
nfc_send_to_raw_sock(struct nfc_dev * dev,struct sk_buff * skb,u8 payload_type,u8 direction)357*4882a593Smuzhiyun void nfc_send_to_raw_sock(struct nfc_dev *dev, struct sk_buff *skb,
358*4882a593Smuzhiyun 			  u8 payload_type, u8 direction)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun 	struct sk_buff *skb_copy = NULL, *nskb;
361*4882a593Smuzhiyun 	struct sock *sk;
362*4882a593Smuzhiyun 	u8 *data;
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	read_lock(&raw_sk_list.lock);
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun 	sk_for_each(sk, &raw_sk_list.head) {
367*4882a593Smuzhiyun 		if (!skb_copy) {
368*4882a593Smuzhiyun 			skb_copy = __pskb_copy_fclone(skb, NFC_RAW_HEADER_SIZE,
369*4882a593Smuzhiyun 						      GFP_ATOMIC, true);
370*4882a593Smuzhiyun 			if (!skb_copy)
371*4882a593Smuzhiyun 				continue;
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 			data = skb_push(skb_copy, NFC_RAW_HEADER_SIZE);
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 			data[0] = dev ? dev->idx : 0xFF;
376*4882a593Smuzhiyun 			data[1] = direction & 0x01;
377*4882a593Smuzhiyun 			data[1] |= (payload_type << 1);
378*4882a593Smuzhiyun 		}
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 		nskb = skb_clone(skb_copy, GFP_ATOMIC);
381*4882a593Smuzhiyun 		if (!nskb)
382*4882a593Smuzhiyun 			continue;
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 		if (sock_queue_rcv_skb(sk, nskb))
385*4882a593Smuzhiyun 			kfree_skb(nskb);
386*4882a593Smuzhiyun 	}
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	read_unlock(&raw_sk_list.lock);
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 	kfree_skb(skb_copy);
391*4882a593Smuzhiyun }
392*4882a593Smuzhiyun EXPORT_SYMBOL(nfc_send_to_raw_sock);
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun static struct proto rawsock_proto = {
395*4882a593Smuzhiyun 	.name     = "NFC_RAW",
396*4882a593Smuzhiyun 	.owner    = THIS_MODULE,
397*4882a593Smuzhiyun 	.obj_size = sizeof(struct nfc_rawsock),
398*4882a593Smuzhiyun };
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun static const struct nfc_protocol rawsock_nfc_proto = {
401*4882a593Smuzhiyun 	.id	  = NFC_SOCKPROTO_RAW,
402*4882a593Smuzhiyun 	.proto    = &rawsock_proto,
403*4882a593Smuzhiyun 	.owner    = THIS_MODULE,
404*4882a593Smuzhiyun 	.create   = rawsock_create
405*4882a593Smuzhiyun };
406*4882a593Smuzhiyun 
rawsock_init(void)407*4882a593Smuzhiyun int __init rawsock_init(void)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun 	int rc;
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 	rc = nfc_proto_register(&rawsock_nfc_proto);
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	return rc;
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun 
rawsock_exit(void)416*4882a593Smuzhiyun void rawsock_exit(void)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun 	nfc_proto_unregister(&rawsock_nfc_proto);
419*4882a593Smuzhiyun }
420