aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-01-06 17:37:45 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-06 17:37:45 -0500
commit56a4342dfe3145cd66f766adccb28fd9b571606d (patch)
treed1593764488ff8cbb0b83cb9ae35fd968bf81760 /net/tipc/socket.c
parent805c1f4aedaba1bc8d839e7c27b128083dd5c2f0 (diff)
parentfe0d692bbc645786bce1a98439e548ae619269f5 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c net/ipv6/ip6_tunnel.c net/ipv6/ip6_vti.c ipv6 tunnel statistic bug fixes conflicting with consolidation into generic sw per-cpu net stats. qlogic conflict between queue counting bug fix and the addition of multiple MAC address support. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c46
1 files changed, 31 insertions, 15 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 5efdeef06f9d..c8341d1f995e 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -351,7 +351,7 @@ static int release(struct socket *sock)
351 * Delete TIPC port; this ensures no more messages are queued 351 * Delete TIPC port; this ensures no more messages are queued
352 * (also disconnects an active connection & sends a 'FIN-' to peer) 352 * (also disconnects an active connection & sends a 'FIN-' to peer)
353 */ 353 */
354 res = tipc_deleteport(tport->ref); 354 res = tipc_deleteport(tport);
355 355
356 /* Discard any remaining (connection-based) messages in receive queue */ 356 /* Discard any remaining (connection-based) messages in receive queue */
357 __skb_queue_purge(&sk->sk_receive_queue); 357 __skb_queue_purge(&sk->sk_receive_queue);
@@ -383,30 +383,46 @@ static int release(struct socket *sock)
383 */ 383 */
384static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) 384static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
385{ 385{
386 struct sock *sk = sock->sk;
386 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; 387 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
387 u32 portref = tipc_sk_port(sock->sk)->ref; 388 struct tipc_port *tport = tipc_sk_port(sock->sk);
389 int res = -EINVAL;
388 390
389 if (unlikely(!uaddr_len)) 391 lock_sock(sk);
390 return tipc_withdraw(portref, 0, NULL); 392 if (unlikely(!uaddr_len)) {
393 res = tipc_withdraw(tport, 0, NULL);
394 goto exit;
395 }
391 396
392 if (uaddr_len < sizeof(struct sockaddr_tipc)) 397 if (uaddr_len < sizeof(struct sockaddr_tipc)) {
393 return -EINVAL; 398 res = -EINVAL;
394 if (addr->family != AF_TIPC) 399 goto exit;
395 return -EAFNOSUPPORT; 400 }
401 if (addr->family != AF_TIPC) {
402 res = -EAFNOSUPPORT;
403 goto exit;
404 }
396 405
397 if (addr->addrtype == TIPC_ADDR_NAME) 406 if (addr->addrtype == TIPC_ADDR_NAME)
398 addr->addr.nameseq.upper = addr->addr.nameseq.lower; 407 addr->addr.nameseq.upper = addr->addr.nameseq.lower;
399 else if (addr->addrtype != TIPC_ADDR_NAMESEQ) 408 else if (addr->addrtype != TIPC_ADDR_NAMESEQ) {
400 return -EAFNOSUPPORT; 409 res = -EAFNOSUPPORT;
410 goto exit;
411 }
401 412
402 if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) && 413 if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) &&
403 (addr->addr.nameseq.type != TIPC_TOP_SRV) && 414 (addr->addr.nameseq.type != TIPC_TOP_SRV) &&
404 (addr->addr.nameseq.type != TIPC_CFG_SRV)) 415 (addr->addr.nameseq.type != TIPC_CFG_SRV)) {
405 return -EACCES; 416 res = -EACCES;
417 goto exit;
418 }
406 419
407 return (addr->scope > 0) ? 420 res = (addr->scope > 0) ?
408 tipc_publish(portref, addr->scope, &addr->addr.nameseq) : 421 tipc_publish(tport, addr->scope, &addr->addr.nameseq) :
409 tipc_withdraw(portref, -addr->scope, &addr->addr.nameseq); 422 tipc_withdraw(tport, -addr->scope, &addr->addr.nameseq);
423exit:
424 release_sock(sk);
425 return res;
410} 426}
411 427
412/** 428/**