Commit 60c102ee authored by Jon Maloy's avatar Jon Maloy Committed by Jakub Kicinski

tipc: refactor tipc_sk_bind() function

We refactor the tipc_sk_bind() function, so that the lock handling
is handled separately from the logics. We also move some sanity
tests to earlier in the call chain, to the function tipc_bind().
Acked-by: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarJon Maloy <jmaloy@redhat.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent fff4c746
/* /*
* net/tipc/socket.c: TIPC socket API * net/tipc/socket.c: TIPC socket API
* *
* Copyright (c) 2001-2007, 2012-2017, Ericsson AB * Copyright (c) 2001-2007, 2012-2019, Ericsson AB
* Copyright (c) 2004-2008, 2010-2013, Wind River Systems * Copyright (c) 2004-2008, 2010-2013, Wind River Systems
* Copyright (c) 2020, Red Hat Inc
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -644,10 +645,10 @@ static int tipc_release(struct socket *sock) ...@@ -644,10 +645,10 @@ static int tipc_release(struct socket *sock)
} }
/** /**
* tipc_bind - associate or disassocate TIPC name(s) with a socket * __tipc_bind - associate or disassocate TIPC name(s) with a socket
* @sock: socket structure * @sock: socket structure
* @uaddr: socket address describing name(s) and desired operation * @skaddr: socket address describing name(s) and desired operation
* @uaddr_len: size of socket address data structure * @alen: size of socket address data structure
* *
* Name and name sequence binding is indicated using a positive scope value; * Name and name sequence binding is indicated using a positive scope value;
* a negative scope value unbinds the specified name. Specifying no name * a negative scope value unbinds the specified name. Specifying no name
...@@ -658,44 +659,33 @@ static int tipc_release(struct socket *sock) ...@@ -658,44 +659,33 @@ static int tipc_release(struct socket *sock)
* NOTE: This routine doesn't need to take the socket lock since it doesn't * NOTE: This routine doesn't need to take the socket lock since it doesn't
* access any non-constant socket information. * access any non-constant socket information.
*/ */
static int __tipc_bind(struct socket *sock, struct sockaddr *skaddr, int alen)
int tipc_sk_bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
{ {
struct sock *sk = sock->sk; struct sockaddr_tipc *addr = (struct sockaddr_tipc *)skaddr;
struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; struct tipc_sock *tsk = tipc_sk(sock->sk);
struct tipc_sock *tsk = tipc_sk(sk);
int res = -EINVAL;
lock_sock(sk); if (unlikely(!alen))
if (unlikely(!uaddr_len)) { return tipc_sk_withdraw(tsk, 0, NULL);
res = tipc_sk_withdraw(tsk, 0, NULL);
goto exit;
}
if (tsk->group) {
res = -EACCES;
goto exit;
}
if (uaddr_len < sizeof(struct sockaddr_tipc)) {
res = -EINVAL;
goto exit;
}
if (addr->family != AF_TIPC) {
res = -EAFNOSUPPORT;
goto exit;
}
if (addr->addrtype == TIPC_ADDR_NAME) if (addr->addrtype == TIPC_ADDR_NAME)
addr->addr.nameseq.upper = addr->addr.nameseq.lower; addr->addr.nameseq.upper = addr->addr.nameseq.lower;
else if (addr->addrtype != TIPC_ADDR_NAMESEQ) {
res = -EAFNOSUPPORT;
goto exit;
}
res = (addr->scope >= 0) ? if (tsk->group)
tipc_sk_publish(tsk, addr->scope, &addr->addr.nameseq) : return -EACCES;
tipc_sk_withdraw(tsk, -addr->scope, &addr->addr.nameseq);
exit: if (addr->scope >= 0)
release_sock(sk); return tipc_sk_publish(tsk, addr->scope, &addr->addr.nameseq);
else
return tipc_sk_withdraw(tsk, -addr->scope, &addr->addr.nameseq);
}
int tipc_sk_bind(struct socket *sock, struct sockaddr *skaddr, int alen)
{
int res;
lock_sock(sock->sk);
res = __tipc_bind(sock, skaddr, alen);
release_sock(sock->sk);
return res; return res;
} }
...@@ -706,6 +696,10 @@ static int tipc_bind(struct socket *sock, struct sockaddr *skaddr, int alen) ...@@ -706,6 +696,10 @@ static int tipc_bind(struct socket *sock, struct sockaddr *skaddr, int alen)
if (alen) { if (alen) {
if (alen < sizeof(struct sockaddr_tipc)) if (alen < sizeof(struct sockaddr_tipc))
return -EINVAL; return -EINVAL;
if (addr->family != AF_TIPC)
return -EAFNOSUPPORT;
if (addr->addrtype > TIPC_SERVICE_ADDR)
return -EAFNOSUPPORT;
if (addr->addr.nameseq.type < TIPC_RESERVED_TYPES) { if (addr->addr.nameseq.type < TIPC_RESERVED_TYPES) {
pr_warn_once("Can't bind to reserved service type %u\n", pr_warn_once("Can't bind to reserved service type %u\n",
addr->addr.nameseq.type); addr->addr.nameseq.type);
......
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