18
18
19
19
/* socket implementation */
20
20
21
- struct mctp_sock {
22
- struct sock sk ;
23
- };
24
-
25
21
static int mctp_release (struct socket * sock )
26
22
{
27
23
struct sock * sk = sock -> sk ;
@@ -36,18 +32,160 @@ static int mctp_release(struct socket *sock)
36
32
37
33
static int mctp_bind (struct socket * sock , struct sockaddr * addr , int addrlen )
38
34
{
39
- return 0 ;
35
+ struct sock * sk = sock -> sk ;
36
+ struct mctp_sock * msk = container_of (sk , struct mctp_sock , sk );
37
+ struct sockaddr_mctp * smctp ;
38
+ int rc ;
39
+
40
+ if (addrlen < sizeof (* smctp ))
41
+ return - EINVAL ;
42
+
43
+ if (addr -> sa_family != AF_MCTP )
44
+ return - EAFNOSUPPORT ;
45
+
46
+ if (!capable (CAP_NET_BIND_SERVICE ))
47
+ return - EACCES ;
48
+
49
+ /* it's a valid sockaddr for MCTP, cast and do protocol checks */
50
+ smctp = (struct sockaddr_mctp * )addr ;
51
+
52
+ lock_sock (sk );
53
+
54
+ /* TODO: allow rebind */
55
+ if (sk_hashed (sk )) {
56
+ rc = - EADDRINUSE ;
57
+ goto out_release ;
58
+ }
59
+ msk -> bind_net = smctp -> smctp_network ;
60
+ msk -> bind_addr = smctp -> smctp_addr .s_addr ;
61
+ msk -> bind_type = smctp -> smctp_type & 0x7f ; /* ignore the IC bit */
62
+
63
+ rc = sk -> sk_prot -> hash (sk );
64
+
65
+ out_release :
66
+ release_sock (sk );
67
+
68
+ return rc ;
40
69
}
41
70
42
71
static int mctp_sendmsg (struct socket * sock , struct msghdr * msg , size_t len )
43
72
{
44
- return 0 ;
73
+ DECLARE_SOCKADDR (struct sockaddr_mctp * , addr , msg -> msg_name );
74
+ const int hlen = MCTP_HEADER_MAXLEN + sizeof (struct mctp_hdr );
75
+ int rc , addrlen = msg -> msg_namelen ;
76
+ struct sock * sk = sock -> sk ;
77
+ struct mctp_skb_cb * cb ;
78
+ struct mctp_route * rt ;
79
+ struct sk_buff * skb ;
80
+
81
+ if (addr ) {
82
+ if (addrlen < sizeof (struct sockaddr_mctp ))
83
+ return - EINVAL ;
84
+ if (addr -> smctp_family != AF_MCTP )
85
+ return - EINVAL ;
86
+ if (addr -> smctp_tag & ~(MCTP_TAG_MASK | MCTP_TAG_OWNER ))
87
+ return - EINVAL ;
88
+
89
+ } else {
90
+ /* TODO: connect()ed sockets */
91
+ return - EDESTADDRREQ ;
92
+ }
93
+
94
+ if (!capable (CAP_NET_RAW ))
95
+ return - EACCES ;
96
+
97
+ rt = mctp_route_lookup (sock_net (sk ), addr -> smctp_network ,
98
+ addr -> smctp_addr .s_addr );
99
+ if (!rt )
100
+ return - EHOSTUNREACH ;
101
+
102
+ skb = sock_alloc_send_skb (sk , hlen + 1 + len ,
103
+ msg -> msg_flags & MSG_DONTWAIT , & rc );
104
+ if (!skb )
105
+ return rc ;
106
+
107
+ skb_reserve (skb , hlen );
108
+
109
+ /* set type as fist byte in payload */
110
+ * (u8 * )skb_put (skb , 1 ) = addr -> smctp_type ;
111
+
112
+ rc = memcpy_from_msg ((void * )skb_put (skb , len ), msg , len );
113
+ if (rc < 0 ) {
114
+ kfree_skb (skb );
115
+ return rc ;
116
+ }
117
+
118
+ /* set up cb */
119
+ cb = __mctp_cb (skb );
120
+ cb -> net = addr -> smctp_network ;
121
+
122
+ rc = mctp_local_output (sk , rt , skb , addr -> smctp_addr .s_addr ,
123
+ addr -> smctp_tag );
124
+
125
+ return rc ? : len ;
45
126
}
46
127
47
128
static int mctp_recvmsg (struct socket * sock , struct msghdr * msg , size_t len ,
48
129
int flags )
49
130
{
50
- return 0 ;
131
+ DECLARE_SOCKADDR (struct sockaddr_mctp * , addr , msg -> msg_name );
132
+ struct sock * sk = sock -> sk ;
133
+ struct sk_buff * skb ;
134
+ size_t msglen ;
135
+ u8 type ;
136
+ int rc ;
137
+
138
+ if (flags & ~(MSG_DONTWAIT | MSG_TRUNC | MSG_PEEK ))
139
+ return - EOPNOTSUPP ;
140
+
141
+ skb = skb_recv_datagram (sk , flags , flags & MSG_DONTWAIT , & rc );
142
+ if (!skb )
143
+ return rc ;
144
+
145
+ if (!skb -> len ) {
146
+ rc = 0 ;
147
+ goto out_free ;
148
+ }
149
+
150
+ /* extract message type, remove from data */
151
+ type = * ((u8 * )skb -> data );
152
+ msglen = skb -> len - 1 ;
153
+
154
+ if (len < msglen )
155
+ msg -> msg_flags |= MSG_TRUNC ;
156
+ else
157
+ len = msglen ;
158
+
159
+ rc = skb_copy_datagram_msg (skb , 1 , msg , len );
160
+ if (rc < 0 )
161
+ goto out_free ;
162
+
163
+ sock_recv_ts_and_drops (msg , sk , skb );
164
+
165
+ if (addr ) {
166
+ struct mctp_skb_cb * cb = mctp_cb (skb );
167
+ /* TODO: expand mctp_skb_cb for header fields? */
168
+ struct mctp_hdr * hdr = mctp_hdr (skb );
169
+
170
+ hdr = mctp_hdr (skb );
171
+ addr = msg -> msg_name ;
172
+ addr -> smctp_family = AF_MCTP ;
173
+ addr -> smctp_network = cb -> net ;
174
+ addr -> smctp_addr .s_addr = hdr -> src ;
175
+ addr -> smctp_type = type ;
176
+ addr -> smctp_tag = hdr -> flags_seq_tag &
177
+ (MCTP_HDR_TAG_MASK | MCTP_HDR_FLAG_TO );
178
+ msg -> msg_namelen = sizeof (* addr );
179
+ }
180
+
181
+ rc = len ;
182
+
183
+ if (flags & MSG_TRUNC )
184
+ rc = msglen ;
185
+
186
+ out_free :
187
+ skb_free_datagram (sk , skb );
188
+ return rc ;
51
189
}
52
190
53
191
static int mctp_setsockopt (struct socket * sock , int level , int optname ,
@@ -83,16 +221,63 @@ static const struct proto_ops mctp_dgram_ops = {
83
221
.sendpage = sock_no_sendpage ,
84
222
};
85
223
224
+ static int mctp_sk_init (struct sock * sk )
225
+ {
226
+ struct mctp_sock * msk = container_of (sk , struct mctp_sock , sk );
227
+
228
+ INIT_HLIST_HEAD (& msk -> keys );
229
+ return 0 ;
230
+ }
231
+
86
232
static void mctp_sk_close (struct sock * sk , long timeout )
87
233
{
88
234
sk_common_release (sk );
89
235
}
90
236
237
+ static int mctp_sk_hash (struct sock * sk )
238
+ {
239
+ struct net * net = sock_net (sk );
240
+
241
+ mutex_lock (& net -> mctp .bind_lock );
242
+ sk_add_node_rcu (sk , & net -> mctp .binds );
243
+ mutex_unlock (& net -> mctp .bind_lock );
244
+
245
+ return 0 ;
246
+ }
247
+
248
+ static void mctp_sk_unhash (struct sock * sk )
249
+ {
250
+ struct mctp_sock * msk = container_of (sk , struct mctp_sock , sk );
251
+ struct net * net = sock_net (sk );
252
+ struct mctp_sk_key * key ;
253
+ struct hlist_node * tmp ;
254
+ unsigned long flags ;
255
+
256
+ /* remove from any type-based binds */
257
+ mutex_lock (& net -> mctp .bind_lock );
258
+ sk_del_node_init_rcu (sk );
259
+ mutex_unlock (& net -> mctp .bind_lock );
260
+
261
+ /* remove tag allocations */
262
+ spin_lock_irqsave (& net -> mctp .keys_lock , flags );
263
+ hlist_for_each_entry_safe (key , tmp , & msk -> keys , sklist ) {
264
+ hlist_del_rcu (& key -> sklist );
265
+ hlist_del_rcu (& key -> hlist );
266
+ kfree_rcu (key , rcu );
267
+ }
268
+ spin_unlock_irqrestore (& net -> mctp .keys_lock , flags );
269
+
270
+ synchronize_rcu ();
271
+ }
272
+
91
273
static struct proto mctp_proto = {
92
274
.name = "MCTP" ,
93
275
.owner = THIS_MODULE ,
94
276
.obj_size = sizeof (struct mctp_sock ),
277
+ .init = mctp_sk_init ,
95
278
.close = mctp_sk_close ,
279
+ .hash = mctp_sk_hash ,
280
+ .unhash = mctp_sk_unhash ,
96
281
};
97
282
98
283
static int mctp_pf_create (struct net * net , struct socket * sock ,
@@ -147,6 +332,10 @@ static __init int mctp_init(void)
147
332
{
148
333
int rc ;
149
334
335
+ /* ensure our uapi tag definitions match the header format */
336
+ BUILD_BUG_ON (MCTP_TAG_OWNER != MCTP_HDR_FLAG_TO );
337
+ BUILD_BUG_ON (MCTP_TAG_MASK != MCTP_HDR_TAG_MASK );
338
+
150
339
pr_info ("mctp: management component transport protocol core\n" );
151
340
152
341
rc = sock_register (& mctp_pf );
0 commit comments