Commit c9ffebdd authored by Christoph Hellwig's avatar Christoph Hellwig Committed by David S. Miller

net/bpfilter: split __bpfilter_process_sockopt

Split __bpfilter_process_sockopt into a low-level send request routine and
the actual setsockopt hook to split the init time ping from the actual
setsockopt processing.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e024e008
...@@ -31,48 +31,51 @@ static void __stop_umh(void) ...@@ -31,48 +31,51 @@ static void __stop_umh(void)
shutdown_umh(); shutdown_umh();
} }
static int __bpfilter_process_sockopt(struct sock *sk, int optname, static int bpfilter_send_req(struct mbox_request *req)
char __user *optval,
unsigned int optlen, bool is_set)
{ {
struct mbox_request req;
struct mbox_reply reply; struct mbox_reply reply;
loff_t pos; loff_t pos;
ssize_t n; ssize_t n;
int ret = -EFAULT;
req.is_set = is_set;
req.pid = current->pid;
req.cmd = optname;
req.addr = (uintptr_t)optval;
req.len = optlen;
if (!bpfilter_ops.info.tgid) if (!bpfilter_ops.info.tgid)
goto out; return -EFAULT;
pos = 0; pos = 0;
n = kernel_write(bpfilter_ops.info.pipe_to_umh, &req, sizeof(req), n = kernel_write(bpfilter_ops.info.pipe_to_umh, req, sizeof(*req),
&pos); &pos);
if (n != sizeof(req)) { if (n != sizeof(*req)) {
pr_err("write fail %zd\n", n); pr_err("write fail %zd\n", n);
__stop_umh(); goto stop;
ret = -EFAULT;
goto out;
} }
pos = 0; pos = 0;
n = kernel_read(bpfilter_ops.info.pipe_from_umh, &reply, sizeof(reply), n = kernel_read(bpfilter_ops.info.pipe_from_umh, &reply, sizeof(reply),
&pos); &pos);
if (n != sizeof(reply)) { if (n != sizeof(reply)) {
pr_err("read fail %zd\n", n); pr_err("read fail %zd\n", n);
__stop_umh(); goto stop;
ret = -EFAULT;
goto out;
} }
ret = reply.status; return reply.status;
out: stop:
return ret; __stop_umh();
return -EFAULT;
}
static int bpfilter_process_sockopt(struct sock *sk, int optname,
char __user *optval, unsigned int optlen,
bool is_set)
{
struct mbox_request req = {
.is_set = is_set,
.pid = current->pid,
.cmd = optname,
.addr = (uintptr_t)optval,
.len = optlen,
};
return bpfilter_send_req(&req);
} }
static int start_umh(void) static int start_umh(void)
{ {
struct mbox_request req = { .pid = current->pid };
int err; int err;
/* fork usermode process */ /* fork usermode process */
...@@ -82,7 +85,7 @@ static int start_umh(void) ...@@ -82,7 +85,7 @@ static int start_umh(void)
pr_info("Loaded bpfilter_umh pid %d\n", pid_nr(bpfilter_ops.info.tgid)); pr_info("Loaded bpfilter_umh pid %d\n", pid_nr(bpfilter_ops.info.tgid));
/* health check that usermode process started correctly */ /* health check that usermode process started correctly */
if (__bpfilter_process_sockopt(NULL, 0, NULL, 0, 0) != 0) { if (bpfilter_send_req(&req) != 0) {
shutdown_umh(); shutdown_umh();
return -EFAULT; return -EFAULT;
} }
...@@ -103,7 +106,7 @@ static int __init load_umh(void) ...@@ -103,7 +106,7 @@ static int __init load_umh(void)
mutex_lock(&bpfilter_ops.lock); mutex_lock(&bpfilter_ops.lock);
err = start_umh(); err = start_umh();
if (!err && IS_ENABLED(CONFIG_INET)) { if (!err && IS_ENABLED(CONFIG_INET)) {
bpfilter_ops.sockopt = &__bpfilter_process_sockopt; bpfilter_ops.sockopt = &bpfilter_process_sockopt;
bpfilter_ops.start = &start_umh; bpfilter_ops.start = &start_umh;
} }
mutex_unlock(&bpfilter_ops.lock); mutex_unlock(&bpfilter_ops.lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment