Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/ieee802154/netlink.c
15109 views
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 <[email protected]>
21
* Dmitry Eremin-Solenikov <[email protected]>
22
* Maxim Osipov <[email protected]>
23
*/
24
25
#include <linux/kernel.h>
26
#include <linux/gfp.h>
27
#include <net/genetlink.h>
28
#include <linux/nl802154.h>
29
30
#include "ieee802154.h"
31
32
static unsigned int ieee802154_seq_num;
33
static DEFINE_SPINLOCK(ieee802154_seq_lock);
34
35
struct genl_family nl802154_family = {
36
.id = GENL_ID_GENERATE,
37
.hdrsize = 0,
38
.name = IEEE802154_NL_NAME,
39
.version = 1,
40
.maxattr = IEEE802154_ATTR_MAX,
41
};
42
43
/* Requests to userspace */
44
struct sk_buff *ieee802154_nl_create(int flags, u8 req)
45
{
46
void *hdr;
47
struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
48
unsigned long f;
49
50
if (!msg)
51
return NULL;
52
53
spin_lock_irqsave(&ieee802154_seq_lock, f);
54
hdr = genlmsg_put(msg, 0, ieee802154_seq_num++,
55
&nl802154_family, flags, req);
56
spin_unlock_irqrestore(&ieee802154_seq_lock, f);
57
if (!hdr) {
58
nlmsg_free(msg);
59
return NULL;
60
}
61
62
return msg;
63
}
64
65
int ieee802154_nl_mcast(struct sk_buff *msg, unsigned int group)
66
{
67
/* XXX: nlh is right at the start of msg */
68
void *hdr = genlmsg_data(NLMSG_DATA(msg->data));
69
70
if (genlmsg_end(msg, hdr) < 0)
71
goto out;
72
73
return genlmsg_multicast(msg, 0, group, GFP_ATOMIC);
74
out:
75
nlmsg_free(msg);
76
return -ENOBUFS;
77
}
78
79
struct sk_buff *ieee802154_nl_new_reply(struct genl_info *info,
80
int flags, u8 req)
81
{
82
void *hdr;
83
struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
84
85
if (!msg)
86
return NULL;
87
88
hdr = genlmsg_put_reply(msg, info,
89
&nl802154_family, flags, req);
90
if (!hdr) {
91
nlmsg_free(msg);
92
return NULL;
93
}
94
95
return msg;
96
}
97
98
int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info)
99
{
100
/* XXX: nlh is right at the start of msg */
101
void *hdr = genlmsg_data(NLMSG_DATA(msg->data));
102
103
if (genlmsg_end(msg, hdr) < 0)
104
goto out;
105
106
return genlmsg_reply(msg, info);
107
out:
108
nlmsg_free(msg);
109
return -ENOBUFS;
110
}
111
112
int __init ieee802154_nl_init(void)
113
{
114
int rc;
115
116
rc = genl_register_family(&nl802154_family);
117
if (rc)
118
goto fail;
119
120
rc = nl802154_mac_register();
121
if (rc)
122
goto fail;
123
124
rc = nl802154_phy_register();
125
if (rc)
126
goto fail;
127
128
return 0;
129
130
fail:
131
genl_unregister_family(&nl802154_family);
132
return rc;
133
}
134
135
void __exit ieee802154_nl_exit(void)
136
{
137
genl_unregister_family(&nl802154_family);
138
}
139
140
141