Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
scsi
scsi_netlink.c
Go to the documentation of this file.
1
/*
2
* scsi_netlink.c - SCSI Transport Netlink Interface
3
*
4
* Copyright (C) 2006 James Smart, Emulex Corporation
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 as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
*
20
*/
21
#include <linux/time.h>
22
#include <
linux/jiffies.h
>
23
#include <
linux/security.h
>
24
#include <
linux/delay.h
>
25
#include <linux/slab.h>
26
#include <linux/export.h>
27
#include <
net/sock.h
>
28
#include <
net/netlink.h
>
29
30
#include <
scsi/scsi_netlink.h
>
31
#include "
scsi_priv.h
"
32
33
struct
sock
*
scsi_nl_sock
=
NULL
;
34
EXPORT_SYMBOL_GPL
(scsi_nl_sock);
35
45
static
void
46
scsi_nl_rcv_msg(
struct
sk_buff
*
skb
)
47
{
48
struct
nlmsghdr
*nlh;
49
struct
scsi_nl_hdr
*
hdr
;
50
u32
rlen;
51
int
err
, tport;
52
53
while
(skb->
len
>=
NLMSG_SPACE
(0)) {
54
err = 0;
55
56
nlh = nlmsg_hdr(skb);
57
if
((nlh->
nlmsg_len
< (
sizeof
(*nlh) +
sizeof
(*hdr))) ||
58
(skb->
len
< nlh->
nlmsg_len
)) {
59
printk
(
KERN_WARNING
"%s: discarding partial skb\n"
,
60
__func__);
61
return
;
62
}
63
64
rlen =
NLMSG_ALIGN
(nlh->
nlmsg_len
);
65
if
(rlen > skb->
len
)
66
rlen = skb->
len
;
67
68
if
(nlh->
nlmsg_type
!=
SCSI_TRANSPORT_MSG
) {
69
err = -
EBADMSG
;
70
goto
next_msg;
71
}
72
73
hdr =
NLMSG_DATA
(nlh);
74
if
((hdr->
version
!=
SCSI_NL_VERSION
) ||
75
(hdr->
magic
!=
SCSI_NL_MAGIC
)) {
76
err = -
EPROTOTYPE
;
77
goto
next_msg;
78
}
79
80
if
(!
capable
(
CAP_SYS_ADMIN
)) {
81
err = -
EPERM
;
82
goto
next_msg;
83
}
84
85
if
(nlh->
nlmsg_len
< (
sizeof
(*nlh) + hdr->
msglen
)) {
86
printk
(
KERN_WARNING
"%s: discarding partial message\n"
,
87
__func__);
88
goto
next_msg;
89
}
90
91
/*
92
* Deliver message to the appropriate transport
93
*/
94
tport = hdr->
transport
;
95
if
(tport ==
SCSI_NL_TRANSPORT
) {
96
switch
(hdr->
msgtype
) {
97
case
SCSI_NL_SHOST_VENDOR
:
98
/* Locate the driver that corresponds to the message */
99
err = -
ESRCH
;
100
break
;
101
default
:
102
err = -
EBADR
;
103
break
;
104
}
105
if
(err)
106
printk
(
KERN_WARNING
"%s: Msgtype %d failed - err %d\n"
,
107
__func__, hdr->
msgtype
, err);
108
}
109
else
110
err = -
ENOENT
;
111
112
next_msg:
113
if
((err) || (nlh->
nlmsg_flags
&
NLM_F_ACK
))
114
netlink_ack
(skb, nlh, err);
115
116
skb_pull
(skb, rlen);
117
}
118
}
119
125
void
126
scsi_netlink_init
(
void
)
127
{
128
struct
netlink_kernel_cfg
cfg = {
129
.
input
= scsi_nl_rcv_msg,
130
.groups =
SCSI_NL_GRP_CNT
,
131
};
132
133
scsi_nl_sock = netlink_kernel_create(&
init_net
,
NETLINK_SCSITRANSPORT
,
134
&cfg);
135
if
(!scsi_nl_sock) {
136
printk
(
KERN_ERR
"%s: register of receive handler failed\n"
,
137
__func__);
138
return
;
139
}
140
141
return
;
142
}
143
144
149
void
150
scsi_netlink_exit
(
void
)
151
{
152
if
(scsi_nl_sock) {
153
netlink_kernel_release
(scsi_nl_sock);
154
}
155
156
return
;
157
}
158
Generated on Thu Jan 10 2013 14:24:21 for Linux Kernel by
1.8.2