netlink.c revision 78fe738d1a631ec34a29d830880e38f5c14c1371
1/* 2 * Netlink inteface for IEEE 802.15.4 stack 3 * 4 * Copyright 2007, 2008 Siemens AG 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 8 * as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Written by: 20 * Sergey Lapin <slapin@ossfans.org> 21 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 22 * Maxim Osipov <maxim.osipov@siemens.com> 23 */ 24 25#include <linux/kernel.h> 26#include <net/genetlink.h> 27#include <linux/nl802154.h> 28 29#include "ieee802154.h" 30 31static unsigned int ieee802154_seq_num; 32static DEFINE_SPINLOCK(ieee802154_seq_lock); 33 34struct genl_family nl802154_family = { 35 .id = GENL_ID_GENERATE, 36 .hdrsize = 0, 37 .name = IEEE802154_NL_NAME, 38 .version = 1, 39 .maxattr = IEEE802154_ATTR_MAX, 40}; 41 42/* Requests to userspace */ 43struct sk_buff *ieee802154_nl_create(int flags, u8 req) 44{ 45 void *hdr; 46 struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); 47 unsigned long f; 48 49 if (!msg) 50 return NULL; 51 52 spin_lock_irqsave(&ieee802154_seq_lock, f); 53 hdr = genlmsg_put(msg, 0, ieee802154_seq_num++, 54 &nl802154_family, flags, req); 55 spin_unlock_irqrestore(&ieee802154_seq_lock, f); 56 if (!hdr) { 57 nlmsg_free(msg); 58 return NULL; 59 } 60 61 return msg; 62} 63 64int ieee802154_nl_mcast(struct sk_buff *msg, unsigned int group) 65{ 66 /* XXX: nlh is right at the start of msg */ 67 void *hdr = genlmsg_data(NLMSG_DATA(msg->data)); 68 69 if (genlmsg_end(msg, hdr) < 0) 70 goto out; 71 72 return genlmsg_multicast(msg, 0, group, GFP_ATOMIC); 73out: 74 nlmsg_free(msg); 75 return -ENOBUFS; 76} 77 78int __init ieee802154_nl_init(void) 79{ 80 int rc; 81 82 rc = genl_register_family(&nl802154_family); 83 if (rc) 84 goto fail; 85 86 rc = nl802154_mac_register(); 87 if (rc) 88 goto fail; 89 90 return 0; 91 92fail: 93 genl_unregister_family(&nl802154_family); 94 return rc; 95} 96 97void __exit ieee802154_nl_exit(void) 98{ 99 genl_unregister_family(&nl802154_family); 100} 101 102