25
25
26
26
#include <linux/kernel.h>
27
27
#include <linux/net.h>
28
+ #include <linux/poll.h>
28
29
#include <net/sock.h>
29
30
#include <net/tcp_states.h>
30
31
31
32
#include <linux/phonet.h>
32
33
#include <net/phonet/phonet.h>
34
+ #include <net/phonet/pep.h>
33
35
#include <net/phonet/pn_dev.h>
34
36
35
37
static int pn_socket_release (struct socket * sock )
@@ -166,6 +168,24 @@ static int pn_socket_autobind(struct socket *sock)
166
168
return 0 ; /* socket was already bound */
167
169
}
168
170
171
+ static int pn_socket_accept (struct socket * sock , struct socket * newsock ,
172
+ int flags )
173
+ {
174
+ struct sock * sk = sock -> sk ;
175
+ struct sock * newsk ;
176
+ int err ;
177
+
178
+ newsk = sk -> sk_prot -> accept (sk , flags , & err );
179
+ if (!newsk )
180
+ return err ;
181
+
182
+ lock_sock (newsk );
183
+ sock_graft (newsk , newsock );
184
+ newsock -> state = SS_CONNECTED ;
185
+ release_sock (newsk );
186
+ return 0 ;
187
+ }
188
+
169
189
static int pn_socket_getname (struct socket * sock , struct sockaddr * addr ,
170
190
int * sockaddr_len , int peer )
171
191
{
@@ -182,6 +202,33 @@ static int pn_socket_getname(struct socket *sock, struct sockaddr *addr,
182
202
return 0 ;
183
203
}
184
204
205
+ static unsigned int pn_socket_poll (struct file * file , struct socket * sock ,
206
+ poll_table * wait )
207
+ {
208
+ struct sock * sk = sock -> sk ;
209
+ struct pep_sock * pn = pep_sk (sk );
210
+ unsigned int mask = 0 ;
211
+
212
+ poll_wait (file , & sock -> wait , wait );
213
+
214
+ switch (sk -> sk_state ) {
215
+ case TCP_LISTEN :
216
+ return hlist_empty (& pn -> ackq ) ? 0 : POLLIN ;
217
+ case TCP_CLOSE :
218
+ return POLLERR ;
219
+ }
220
+
221
+ if (!skb_queue_empty (& sk -> sk_receive_queue ))
222
+ mask |= POLLIN | POLLRDNORM ;
223
+ else if (sk -> sk_state == TCP_CLOSE_WAIT )
224
+ return POLLHUP ;
225
+
226
+ if (sk -> sk_state == TCP_ESTABLISHED && pn -> tx_credits )
227
+ mask |= POLLOUT | POLLWRNORM | POLLWRBAND ;
228
+
229
+ return mask ;
230
+ }
231
+
185
232
static int pn_socket_ioctl (struct socket * sock , unsigned int cmd ,
186
233
unsigned long arg )
187
234
{
@@ -220,6 +267,30 @@ static int pn_socket_ioctl(struct socket *sock, unsigned int cmd,
220
267
return sk -> sk_prot -> ioctl (sk , cmd , arg );
221
268
}
222
269
270
+ static int pn_socket_listen (struct socket * sock , int backlog )
271
+ {
272
+ struct sock * sk = sock -> sk ;
273
+ int err = 0 ;
274
+
275
+ if (sock -> state != SS_UNCONNECTED )
276
+ return - EINVAL ;
277
+ if (pn_socket_autobind (sock ))
278
+ return - ENOBUFS ;
279
+
280
+ lock_sock (sk );
281
+ if (sk -> sk_state != TCP_CLOSE ) {
282
+ err = - EINVAL ;
283
+ goto out ;
284
+ }
285
+
286
+ sk -> sk_state = TCP_LISTEN ;
287
+ sk -> sk_ack_backlog = 0 ;
288
+ sk -> sk_max_ack_backlog = backlog ;
289
+ out :
290
+ release_sock (sk );
291
+ return err ;
292
+ }
293
+
223
294
static int pn_socket_sendmsg (struct kiocb * iocb , struct socket * sock ,
224
295
struct msghdr * m , size_t total_len )
225
296
{
@@ -256,6 +327,32 @@ const struct proto_ops phonet_dgram_ops = {
256
327
.sendpage = sock_no_sendpage ,
257
328
};
258
329
330
+ const struct proto_ops phonet_stream_ops = {
331
+ .family = AF_PHONET ,
332
+ .owner = THIS_MODULE ,
333
+ .release = pn_socket_release ,
334
+ .bind = pn_socket_bind ,
335
+ .connect = sock_no_connect ,
336
+ .socketpair = sock_no_socketpair ,
337
+ .accept = pn_socket_accept ,
338
+ .getname = pn_socket_getname ,
339
+ .poll = pn_socket_poll ,
340
+ .ioctl = pn_socket_ioctl ,
341
+ .listen = pn_socket_listen ,
342
+ .shutdown = sock_no_shutdown ,
343
+ .setsockopt = sock_no_setsockopt ,
344
+ .getsockopt = sock_no_getsockopt ,
345
+ #ifdef CONFIG_COMPAT
346
+ .compat_setsockopt = sock_no_setsockopt ,
347
+ .compat_getsockopt = compat_sock_no_getsockopt ,
348
+ #endif
349
+ .sendmsg = pn_socket_sendmsg ,
350
+ .recvmsg = sock_common_recvmsg ,
351
+ .mmap = sock_no_mmap ,
352
+ .sendpage = sock_no_sendpage ,
353
+ };
354
+ EXPORT_SYMBOL (phonet_stream_ops );
355
+
259
356
static DEFINE_MUTEX (port_mutex );
260
357
261
358
/* allocate port for a socket */
0 commit comments