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> 31e6278d92005e9d6e374f269b4ce39c908a68ad5dPhoebe Buckheister#include <net/ieee802154_netdev.h> 329ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 339ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin#include "af802154.h" 349ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 359ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic HLIST_HEAD(raw_head); 369ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic DEFINE_RWLOCK(raw_lock); 379ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 389ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic void raw_hash(struct sock *sk) 399ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 409ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin write_lock_bh(&raw_lock); 419ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sk_add_node(sk, &raw_head); 429ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); 439ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin write_unlock_bh(&raw_lock); 449ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 459ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 469ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic void raw_unhash(struct sock *sk) 479ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 489ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin write_lock_bh(&raw_lock); 499ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (sk_del_node_init(sk)) 509ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); 519ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin write_unlock_bh(&raw_lock); 529ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 539ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 549ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic void raw_close(struct sock *sk, long timeout) 559ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 569ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sk_common_release(sk); 579ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 589ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 59e6278d92005e9d6e374f269b4ce39c908a68ad5dPhoebe Buckheisterstatic int raw_bind(struct sock *sk, struct sockaddr *_uaddr, int len) 609ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 61e6278d92005e9d6e374f269b4ce39c908a68ad5dPhoebe Buckheister struct ieee802154_addr addr; 62e6278d92005e9d6e374f269b4ce39c908a68ad5dPhoebe Buckheister struct sockaddr_ieee802154 *uaddr = (struct sockaddr_ieee802154 *)_uaddr; 639ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin int err = 0; 649ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin struct net_device *dev = NULL; 659ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 66e6278d92005e9d6e374f269b4ce39c908a68ad5dPhoebe Buckheister if (len < sizeof(*uaddr)) 679ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return -EINVAL; 689ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 69e6278d92005e9d6e374f269b4ce39c908a68ad5dPhoebe Buckheister uaddr = (struct sockaddr_ieee802154 *)_uaddr; 70e6278d92005e9d6e374f269b4ce39c908a68ad5dPhoebe Buckheister if (uaddr->family != AF_IEEE802154) 719ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return -EINVAL; 729ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 739ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin lock_sock(sk); 749ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 75e6278d92005e9d6e374f269b4ce39c908a68ad5dPhoebe Buckheister ieee802154_addr_from_sa(&addr, &uaddr->addr); 76e6278d92005e9d6e374f269b4ce39c908a68ad5dPhoebe Buckheister dev = ieee802154_get_dev(sock_net(sk), &addr); 779ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (!dev) { 789ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = -ENODEV; 799ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto out; 809ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 819ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 82929122cdd5d4c344e59f9b55f870a8fcf7aa0d27Dmitry Eremin-Solenikov if (dev->type != ARPHRD_IEEE802154) { 839ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = -ENODEV; 849ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto out_put; 859ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 869ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 879ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sk->sk_bound_dev_if = dev->ifindex; 889ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sk_dst_reset(sk); 899ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 909ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinout_put: 919ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin dev_put(dev); 929ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinout: 939ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin release_sock(sk); 949ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 959ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return err; 969ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 979ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 989ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic int raw_connect(struct sock *sk, struct sockaddr *uaddr, 994710d806fcb825156e0a7b3a81104915c5e90f5dVarka Bhadram int addr_len) 1009ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 1019ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return -ENOTSUPP; 1029ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 1039ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1049ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic int raw_disconnect(struct sock *sk, int flags) 1059ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 1069ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return 0; 1079ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 1089ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1094710d806fcb825156e0a7b3a81104915c5e90f5dVarka Bhadramstatic int raw_sendmsg(struct kiocb *iocb, struct sock *sk, 1104710d806fcb825156e0a7b3a81104915c5e90f5dVarka Bhadram struct msghdr *msg, size_t size) 1119ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 1129ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin struct net_device *dev; 11395c961747284a6b83a5e2d81240e214b0fa3464dEric Dumazet unsigned int mtu; 1149ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin struct sk_buff *skb; 115ae641949df01b85117845bec45328eab6d6fada1Herbert Xu int hlen, tlen; 1169ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin int err; 1179ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1189ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (msg->msg_flags & MSG_OOB) { 1199ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags); 1209ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return -EOPNOTSUPP; 1219ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 1229ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1239ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin lock_sock(sk); 1249ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (!sk->sk_bound_dev_if) 1259ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); 1269ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin else 1279ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if); 1289ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin release_sock(sk); 1299ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1309ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (!dev) { 1319ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin pr_debug("no dev\n"); 1329ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = -ENXIO; 1339ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto out; 1349ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 1359ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1369ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin mtu = dev->mtu; 1379ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin pr_debug("name = %s, mtu = %u\n", dev->name, mtu); 1389ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1399ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (size > mtu) { 140e5241c448f94feee40b2a285c8bf55d066420073David S. Miller pr_debug("size = %Zu, mtu = %u\n", size, mtu); 1419ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = -EINVAL; 1429ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto out_dev; 1439ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 1449ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 145ae641949df01b85117845bec45328eab6d6fada1Herbert Xu hlen = LL_RESERVED_SPACE(dev); 146ae641949df01b85117845bec45328eab6d6fada1Herbert Xu tlen = dev->needed_tailroom; 147ae641949df01b85117845bec45328eab6d6fada1Herbert Xu skb = sock_alloc_send_skb(sk, hlen + tlen + size, 1484710d806fcb825156e0a7b3a81104915c5e90f5dVarka Bhadram msg->msg_flags & MSG_DONTWAIT, &err); 1499ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (!skb) 1509ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto out_dev; 1519ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 152ae641949df01b85117845bec45328eab6d6fada1Herbert Xu skb_reserve(skb, hlen); 1539ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1549ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin skb_reset_mac_header(skb); 1559ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin skb_reset_network_header(skb); 1569ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1579ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); 1589ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (err < 0) 1599ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto out_skb; 1609ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1619ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin skb->dev = dev; 1629ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin skb->sk = sk; 1639ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin skb->protocol = htons(ETH_P_IEEE802154); 1649ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1659ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin dev_put(dev); 1669ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1679ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = dev_queue_xmit(skb); 1689ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (err > 0) 1699ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = net_xmit_errno(err); 1709ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1719ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return err ?: size; 1729ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1739ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinout_skb: 1749ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin kfree_skb(skb); 1759ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinout_dev: 1769ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin dev_put(dev); 1779ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinout: 1789ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return err; 1799ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 1809ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1819ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, 1829ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin size_t len, int noblock, int flags, int *addr_len) 1839ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 1849ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin size_t copied = 0; 1859ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin int err = -EOPNOTSUPP; 1869ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin struct sk_buff *skb; 1879ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1889ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin skb = skb_recv_datagram(sk, flags, noblock, &err); 1899ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (!skb) 1909ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto out; 1919ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1929ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin copied = skb->len; 1939ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (len < copied) { 1949ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin msg->msg_flags |= MSG_TRUNC; 1959ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin copied = len; 1969ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 1979ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 1989ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); 1999ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (err) 2009ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin goto done; 2019ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2023b885787ea4112eaa80945999ea0901bf742707fNeil Horman sock_recv_ts_and_drops(msg, sk, skb); 2039ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2049ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (flags & MSG_TRUNC) 2059ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin copied = skb->len; 2069ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapindone: 2079ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin skb_free_datagram(sk, skb); 2089ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinout: 2099ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (err) 2109ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return err; 2119ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return copied; 2129ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 2139ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2149ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstatic int raw_rcv_skb(struct sock *sk, struct sk_buff *skb) 2159ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 2168cfad496c4257441710735ccef622f3829870164Phoebe Buckheister skb = skb_share_check(skb, GFP_ATOMIC); 2178cfad496c4257441710735ccef622f3829870164Phoebe Buckheister if (!skb) 2188cfad496c4257441710735ccef622f3829870164Phoebe Buckheister return NET_RX_DROP; 2198cfad496c4257441710735ccef622f3829870164Phoebe Buckheister 2209ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (sock_queue_rcv_skb(sk, skb) < 0) { 2219ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin kfree_skb(skb); 2229ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return NET_RX_DROP; 2239ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 2249ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2259ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin return NET_RX_SUCCESS; 2269ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 2279ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2289ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2299ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinvoid ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb) 2309ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin{ 2319ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin struct sock *sk; 2329ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2339ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin read_lock(&raw_lock); 234b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin sk_for_each(sk, &raw_head) { 2359ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin bh_lock_sock(sk); 2369ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (!sk->sk_bound_dev_if || 2379ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin sk->sk_bound_dev_if == dev->ifindex) { 2389ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin struct sk_buff *clone; 2399ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 2409ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin clone = skb_clone(skb, GFP_ATOMIC); 2419ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin if (clone) 2429ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin raw_rcv_skb(sk, clone); 2439ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 2449ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin bh_unlock_sock(sk); 2459ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin } 2469ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin read_unlock(&raw_lock); 2479ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin} 2489ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin 249a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikovstatic int raw_getsockopt(struct sock *sk, int level, int optname, 2504710d806fcb825156e0a7b3a81104915c5e90f5dVarka Bhadram char __user *optval, int __user *optlen) 251a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov{ 252a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov return -EOPNOTSUPP; 253a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov} 254a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov 255a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikovstatic int raw_setsockopt(struct sock *sk, int level, int optname, 2564710d806fcb825156e0a7b3a81104915c5e90f5dVarka Bhadram char __user *optval, unsigned int optlen) 257a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov{ 258a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov return -EOPNOTSUPP; 259a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov} 260a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov 2619ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapinstruct proto ieee802154_raw_prot = { 2629ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .name = "IEEE-802.15.4-RAW", 2639ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .owner = THIS_MODULE, 2649ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .obj_size = sizeof(struct sock), 2659ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .close = raw_close, 2669ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .bind = raw_bind, 2679ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .sendmsg = raw_sendmsg, 2689ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .recvmsg = raw_recvmsg, 2699ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .hash = raw_hash, 2709ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .unhash = raw_unhash, 2719ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .connect = raw_connect, 2729ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin .disconnect = raw_disconnect, 273a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov .getsockopt = raw_getsockopt, 274a9dfac3353b03432e3d46a0dde6795588c46256dDmitry Eremin-Solenikov .setsockopt = raw_setsockopt, 2759ec7671603573ede31207eb5b0b3e1aa211b2854Sergey Lapin}; 276