protocols: make socket buffers ioctl handler changeable
Allow to set custom per-protocol handlers for the socket buffers ioctls by introducing pr_setsbopt callback with the default value set to the currently-used sbsetopt(). Reviewed by: glebius Differential Revision: https://reviews.freebsd.org/D36746
This commit is contained in:
parent
a42206a7ca
commit
f66968564d
@ -201,6 +201,7 @@ pr_init(struct domain *dom, struct protosw *pr)
|
||||
DEFAULT(pr_sosend, sosend_generic);
|
||||
DEFAULT(pr_soreceive, soreceive_generic);
|
||||
DEFAULT(pr_sopoll, sopoll_generic);
|
||||
DEFAULT(pr_setsbopt, sbsetopt);
|
||||
|
||||
#define NOTSUPP(foo) if (pr->foo == NULL) pr->foo = foo ## _notsupp
|
||||
NOTSUPP(pr_accept);
|
||||
|
@ -651,18 +651,30 @@ sbreserve_locked(struct socket *so, sb_which which, u_long cc,
|
||||
}
|
||||
|
||||
int
|
||||
sbsetopt(struct socket *so, int cmd, u_long cc)
|
||||
sbsetopt(struct socket *so, struct sockopt *sopt)
|
||||
{
|
||||
struct sockbuf *sb;
|
||||
sb_which wh;
|
||||
short *flags;
|
||||
u_int *hiwat, *lowat;
|
||||
int error;
|
||||
u_int cc, *hiwat, *lowat;
|
||||
int error, optval;
|
||||
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* Values < 1 make no sense for any of these options,
|
||||
* so disallow them.
|
||||
*/
|
||||
if (optval < 1)
|
||||
return (EINVAL);
|
||||
cc = optval;
|
||||
|
||||
sb = NULL;
|
||||
SOCK_LOCK(so);
|
||||
if (SOLISTENING(so)) {
|
||||
switch (cmd) {
|
||||
switch (sopt->sopt_name) {
|
||||
case SO_SNDLOWAT:
|
||||
case SO_SNDBUF:
|
||||
lowat = &so->sol_sbsnd_lowat;
|
||||
@ -677,7 +689,7 @@ sbsetopt(struct socket *so, int cmd, u_long cc)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (cmd) {
|
||||
switch (sopt->sopt_name) {
|
||||
case SO_SNDLOWAT:
|
||||
case SO_SNDBUF:
|
||||
sb = &so->so_snd;
|
||||
@ -696,7 +708,7 @@ sbsetopt(struct socket *so, int cmd, u_long cc)
|
||||
}
|
||||
|
||||
error = 0;
|
||||
switch (cmd) {
|
||||
switch (sopt->sopt_name) {
|
||||
case SO_SNDBUF:
|
||||
case SO_RCVBUF:
|
||||
if (SOLISTENING(so)) {
|
||||
|
@ -3109,21 +3109,9 @@ sosetopt(struct socket *so, struct sockopt *sopt)
|
||||
case SO_RCVBUF:
|
||||
case SO_SNDLOWAT:
|
||||
case SO_RCVLOWAT:
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
error = so->so_proto->pr_setsbopt(so, sopt);
|
||||
if (error)
|
||||
goto bad;
|
||||
|
||||
/*
|
||||
* Values < 1 make no sense for any of these options,
|
||||
* so disallow them.
|
||||
*/
|
||||
if (optval < 1) {
|
||||
error = EINVAL;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
error = sbsetopt(so, sopt->sopt_name, optval);
|
||||
break;
|
||||
|
||||
case SO_SNDTIMEO:
|
||||
|
@ -62,6 +62,7 @@ struct uio;
|
||||
|
||||
/* USE THESE FOR YOUR PROTOTYPES ! */
|
||||
typedef int pr_ctloutput_t(struct socket *, struct sockopt *);
|
||||
typedef int pr_setsbopt_t(struct socket *, struct sockopt *);
|
||||
typedef void pr_abort_t(struct socket *);
|
||||
typedef int pr_accept_t(struct socket *, struct sockaddr **);
|
||||
typedef int pr_attach_t(struct socket *, int, struct thread *);
|
||||
@ -143,6 +144,7 @@ struct protosw {
|
||||
pr_sense_t *pr_sense; /* stat(2) */
|
||||
pr_flush_t *pr_flush; /* XXXGL: merge with pr_shutdown_t! */
|
||||
pr_sosetlabel_t *pr_sosetlabel; /* MAC, XXXGL: remove */
|
||||
pr_setsbopt_t *pr_setsbopt; /* Socket buffer ioctls */
|
||||
};
|
||||
/*#endif*/
|
||||
|
||||
|
@ -71,6 +71,7 @@ struct ktls_session;
|
||||
struct mbuf;
|
||||
struct sockaddr;
|
||||
struct socket;
|
||||
struct sockopt;
|
||||
struct thread;
|
||||
struct selinfo;
|
||||
|
||||
@ -227,7 +228,7 @@ void sbflush(struct sockbuf *sb);
|
||||
void sbflush_locked(struct sockbuf *sb);
|
||||
void sbrelease(struct socket *, sb_which);
|
||||
void sbrelease_locked(struct socket *, sb_which);
|
||||
int sbsetopt(struct socket *so, int cmd, u_long cc);
|
||||
int sbsetopt(struct socket *so, struct sockopt *);
|
||||
bool sbreserve_locked(struct socket *so, sb_which which, u_long cc,
|
||||
struct thread *td);
|
||||
void sbsndptr_adv(struct sockbuf *sb, struct mbuf *mb, u_int len);
|
||||
|
Loading…
Reference in New Issue
Block a user