raw.c revision ae641949df01b85117845bec45328eab6d6fada1
19ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin/* 29ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * Raw IEEE 802.15.4 sockets 39ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * 49ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * Copyright 2007, 2008 Siemens AG 59ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * 69ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * This program is free software; you can redistribute it and/or modify 79ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * it under the terms of the GNU General Public License version 2 89ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * as published by the Free Software Foundation. 99ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * 109ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * This program is distributed in the hope that it will be useful, 119ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * but WITHOUT ANY WARRANTY; without even the implied warranty of 129ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 139ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * GNU General Public License for more details. 149ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * 159ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * You should have received a copy of the GNU General Public License along 169ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * with this program; if not, write to the Free Software Foundation, Inc., 179ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 189ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * 199ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * Written by: 209ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * Sergey Lapin <slapin@ossfans.org> 219ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 229ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin */ 239ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 249ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin#include <linux/net.h> 259ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin#include <linux/module.h> 269ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin#include <linux/if_arp.h> 279ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin#include <linux/list.h> 285a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 299ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin#include <net/sock.h> 30f0166e5e3cdab66d5a31f796ce18e21fd3ce99dcDmitry Eremin-Solenikov#include <net/af_ieee802154.h> 319ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 329ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin#include "af802154.h" 339ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 349ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic HLIST_HEAD(raw_head); 359ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic DEFINE_RWLOCK(raw_lock); 369ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 379ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic void raw_hash(struct sock *sk) 389ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 399ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin write_lock_bh(&raw_lock); 409ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sk_add_node(sk, &raw_head); 419ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); 429ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin write_unlock_bh(&raw_lock); 439ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 449ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 459ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic void raw_unhash(struct sock *sk) 469ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 479ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin write_lock_bh(&raw_lock); 489ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (sk_del_node_init(sk)) 499ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); 509ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin write_unlock_bh(&raw_lock); 519ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 529ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 539ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic void raw_close(struct sock *sk, long timeout) 549ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 559ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sk_common_release(sk); 569ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 579ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 589ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic int raw_bind(struct sock *sk, struct sockaddr *uaddr, int len) 599ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 609ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr; 619ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin int err = 0; 629ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin struct net_device *dev = NULL; 639ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 649ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (len < sizeof(*addr)) 659ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return -EINVAL; 669ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 679ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (addr->family != AF_IEEE802154) 689ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return -EINVAL; 699ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 709ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin lock_sock(sk); 719ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 729ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin dev = ieee802154_get_dev(sock_net(sk), &addr->addr); 739ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (!dev) { 749ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = -ENODEV; 759ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto out; 769ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 779ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 78929122cdd5d4c344e59f9b55f870a8fcf7aa0d27Dmitry Eremin-Solenikov if (dev->type != ARPHRD_IEEE802154) { 799ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = -ENODEV; 809ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto out_put; 819ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 829ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 839ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sk->sk_bound_dev_if = dev->ifindex; 849ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sk_dst_reset(sk); 859ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 869ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinout_put: 879ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin dev_put(dev); 889ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinout: 899ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin release_sock(sk); 909ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 919ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return err; 929ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 939ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 949ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic int raw_connect(struct sock *sk, struct sockaddr *uaddr, 959ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin int addr_len) 969ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 979ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return -ENOTSUPP; 989ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 999ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1009ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic int raw_disconnect(struct sock *sk, int flags) 1019ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 1029ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return 0; 1039ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 1049ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1059ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, 1069ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin size_t size) 1079ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 1089ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin struct net_device *dev; 1099ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin unsigned mtu; 1109ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin struct sk_buff *skb; 111ae641949df01b85117845bec45328eab6d6fada1Herbert Xu int hlen, tlen; 1129ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin int err; 1139ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1149ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (msg->msg_flags & MSG_OOB) { 1159ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags); 1169ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return -EOPNOTSUPP; 1179ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 1189ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1199ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin lock_sock(sk); 1209ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (!sk->sk_bound_dev_if) 1219ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); 1229ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin else 1239ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if); 1249ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin release_sock(sk); 1259ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1269ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (!dev) { 1279ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin pr_debug("no dev\n"); 1289ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = -ENXIO; 1299ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto out; 1309ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 1319ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1329ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin mtu = dev->mtu; 1339ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin pr_debug("name = %s, mtu = %u\n", dev->name, mtu); 1349ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1359ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (size > mtu) { 136e5241c448f94feee40b2a285c8bf55d066420073David S. Miller pr_debug("size = %Zu, mtu = %u\n", size, mtu); 1379ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = -EINVAL; 1389ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto out_dev; 1399ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 1409ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 141ae641949df01b85117845bec45328eab6d6fada1Herbert Xu hlen = LL_RESERVED_SPACE(dev); 142ae641949df01b85117845bec45328eab6d6fada1Herbert Xu tlen = dev->needed_tailroom; 143ae641949df01b85117845bec45328eab6d6fada1Herbert Xu skb = sock_alloc_send_skb(sk, hlen + tlen + size, 1449ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin msg->msg_flags & MSG_DONTWAIT, &err); 1459ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (!skb) 1469ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto out_dev; 1479ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 148ae641949df01b85117845bec45328eab6d6fada1Herbert Xu skb_reserve(skb, hlen); 1499ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1509ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin skb_reset_mac_header(skb); 1519ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin skb_reset_network_header(skb); 1529ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1539ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); 1549ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (err < 0) 1559ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto out_skb; 1569ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1579ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin skb->dev = dev; 1589ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin skb->sk = sk; 1599ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin skb->protocol = htons(ETH_P_IEEE802154); 1609ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1619ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin dev_put(dev); 1629ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1639ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = dev_queue_xmit(skb); 1649ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (err > 0) 1659ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = net_xmit_errno(err); 1669ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1679ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return err ?: size; 1689ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1699ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinout_skb: 1709ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin kfree_skb(skb); 1719ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinout_dev: 1729ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin dev_put(dev); 1739ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinout: 1749ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return err; 1759ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 1769ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1779ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, 1789ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin size_t len, int noblock, int flags, int *addr_len) 1799ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 1809ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin size_t copied = 0; 1819ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin int err = -EOPNOTSUPP; 1829ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin struct sk_buff *skb; 1839ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1849ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin skb = skb_recv_datagram(sk, flags, noblock, &err); 1859ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (!skb) 1869ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto out; 1879ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1889ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin copied = skb->len; 1899ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (len < copied) { 1909ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin msg->msg_flags |= MSG_TRUNC; 1919ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin copied = len; 1929ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 1939ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1949ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); 1959ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (err) 1969ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto done; 1979ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1983b885787ea4112eaa80945999ea0901bf742707fNeil Horman sock_recv_ts_and_drops(msg, sk, skb); 1999ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2009ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (flags & MSG_TRUNC) 2019ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin copied = skb->len; 2029ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapindone: 2039ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin skb_free_datagram(sk, skb); 2049ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinout: 2059ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (err) 2069ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return err; 2079ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return copied; 2089ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 2099ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2109ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic int raw_rcv_skb(struct sock *sk, struct sk_buff *skb) 2119ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 2129ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (sock_queue_rcv_skb(sk, skb) < 0) { 2139ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin kfree_skb(skb); 2149ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return NET_RX_DROP; 2159ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 2169ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2179ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return NET_RX_SUCCESS; 2189ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 2199ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2209ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2219ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinvoid ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb) 2229ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 2239ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin struct sock *sk; 2249ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin struct hlist_node *node; 2259ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2269ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin read_lock(&raw_lock); 2279ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sk_for_each(sk, node, &raw_head) { 2289ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin bh_lock_sock(sk); 2299ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (!sk->sk_bound_dev_if || 2309ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sk->sk_bound_dev_if == dev->ifindex) { 2319ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2329ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin struct sk_buff *clone; 2339ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2349ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin clone = skb_clone(skb, GFP_ATOMIC); 2359ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (clone) 2369ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin raw_rcv_skb(sk, clone); 2379ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 2389ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin bh_unlock_sock(sk); 2399ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 2409ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin read_unlock(&raw_lock); 2419ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 2429ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 243a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikovstatic int raw_getsockopt(struct sock *sk, int level, int optname, 244a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov char __user *optval, int __user *optlen) 245a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov{ 246a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov return -EOPNOTSUPP; 247a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov} 248a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov 249a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikovstatic int raw_setsockopt(struct sock *sk, int level, int optname, 250b7058842c940ad2c08dd829b21e5c92ebe3b8758David S. Miller char __user *optval, unsigned int optlen) 251a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov{ 252a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov return -EOPNOTSUPP; 253a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov} 254a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov 2559ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstruct proto ieee802154_raw_prot = { 2569ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .name = "IEEE-802.15.4-RAW", 2579ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .owner = THIS_MODULE, 2589ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .obj_size = sizeof(struct sock), 2599ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .close = raw_close, 2609ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .bind = raw_bind, 2619ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .sendmsg = raw_sendmsg, 2629ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .recvmsg = raw_recvmsg, 2639ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .hash = raw_hash, 2649ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .unhash = raw_unhash, 2659ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .connect = raw_connect, 2669ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .disconnect = raw_disconnect, 267a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov .getsockopt = raw_getsockopt, 268a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov .setsockopt = raw_setsockopt, 2699ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin}; 2709ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 271