Add ioctl(2) handler for kernel part of sctp_peeloff().

This commit is contained in:
rjs 2018-08-01 23:35:32 +00:00
parent f13786ea7f
commit d3646d152b
4 changed files with 88 additions and 6 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: sys_socket.c,v 1.76 2017/11/30 20:25:55 christos Exp $ */
/* $NetBSD: sys_socket.c,v 1.77 2018/08/01 23:35:32 rjs Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sys_socket.c,v 1.76 2017/11/30 20:25:55 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: sys_socket.c,v 1.77 2018/08/01 23:35:32 rjs Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -192,6 +192,12 @@ soo_ioctl(file_t *fp, u_long cmd, void *data)
*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
break;
case SIOCPEELOFF:
solock(so);
error = do_sys_peeloff(so, data);
sounlock(so);
break;
default:
/*
* Interface/routing/protocol specific ioctls:

View File

@ -1,4 +1,4 @@
/* $NetBSD: uipc_syscalls.c,v 1.195 2018/07/31 13:00:13 rjs Exp $ */
/* $NetBSD: uipc_syscalls.c,v 1.196 2018/08/01 23:35:32 rjs Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@ -61,10 +61,11 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.195 2018/07/31 13:00:13 rjs Exp $");
__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.196 2018/08/01 23:35:32 rjs Exp $");
#ifdef _KERNEL_OPT
#include "opt_pipe.h"
#include "opt_sctp.h"
#endif
#define MBUFTYPES
@ -85,6 +86,11 @@ __KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.195 2018/07/31 13:00:13 rjs Exp
#include <sys/atomic.h>
#include <sys/kauth.h>
#ifdef SCTP
#include <netinet/sctp_uio.h>
#include <netinet/sctp_peeloff.h>
#endif
#include <sys/mount.h>
#include <sys/syscallargs.h>
@ -1606,3 +1612,69 @@ sockargs(struct mbuf **mp, const void *bf, size_t buflen, enum uio_seg seg,
return EINVAL;
}
}
int
do_sys_peeloff(struct socket *head, void *data)
{
#ifdef SCTP
/*file_t *lfp = NULL;*/
file_t *nfp = NULL;
int error;
struct socket *so;
int fd;
uint32_t name;
/*short fflag;*/ /* type must match fp->f_flag */
name = *(uint32_t *) data;
error = sctp_can_peel_off(head, name);
if (error) {
printf("peeloff failed\n");
return error;
}
/*
* At this point we know we do have a assoc to pull
* we proceed to get the fd setup. This may block
* but that is ok.
*/
error = fd_allocfile(&nfp, &fd);
if (error) {
/*
* Probably ran out of file descriptors. Put the
* unaccepted connection back onto the queue and
* do another wakeup so some other process might
* have a chance at it.
*/
return error;
}
*(int *) data = fd;
so = sctp_get_peeloff(head, name, &error);
if (so == NULL) {
/*
* Either someone else peeled it off OR
* we can't get a socket.
* close the new descriptor, assuming someone hasn't ripped it
* out from under us.
*/
mutex_enter(&nfp->f_lock);
nfp->f_count++;
mutex_exit(&nfp->f_lock);
fd_abort(curlwp->l_proc, nfp, fd);
return error;
}
so->so_state &= ~SS_NOFDREF;
so->so_state &= ~SS_ISCONNECTING;
so->so_head = NULL;
so->so_cred = kauth_cred_dup(head->so_cred);
nfp->f_socket = so;
nfp->f_flag = FREAD|FWRITE;
nfp->f_ops = &socketops;
nfp->f_type = DTYPE_SOCKET;
fd_affix(curlwp->l_proc, nfp, fd);
return error;
#else
return EOPNOTSUPP;
#endif
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: socketvar.h,v 1.157 2018/07/20 08:26:25 msaitoh Exp $ */
/* $NetBSD: socketvar.h,v 1.158 2018/08/01 23:35:32 rjs Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@ -378,6 +378,7 @@ int do_sys_connect(struct lwp *, int, struct sockaddr *);
int do_sys_accept(struct lwp *, int, struct sockaddr *, register_t *,
const sigset_t *, int, int);
int do_sys_peeloff(struct socket *, void *);
/*
* Inline functions for sockets and socket buffering.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: sockio.h,v 1.34 2018/07/31 16:44:30 khorben Exp $ */
/* $NetBSD: sockio.h,v 1.35 2018/08/01 23:35:32 rjs Exp $ */
/*-
* Copyright (c) 1982, 1986, 1990, 1993, 1994
@ -44,6 +44,9 @@
#define SIOCATMARK _IOR('s', 7, int) /* at oob mark? */
#define SIOCSPGRP _IOW('s', 8, int) /* set process group */
#define SIOCGPGRP _IOR('s', 9, int) /* get process group */
#define SIOCPEELOFF _IOWR('s', 10, int)
/* ('s', 11, ...) is SIOCCONNECTX in sctp_uio.h */
/* ('s', 12, ...) is SIOCCONNECTXDEL in sctp_uio.h */
#define SIOCADDRT _IOW('r', 10, struct ortentry) /* add route */
#define SIOCDELRT _IOW('r', 11, struct ortentry) /* delete route */