Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Jon Maloy and committed by
Jakub Kicinski
60c102ee fff4c746

+30 -36
+30 -36
net/tipc/socket.c
··· 1 1 /* 2 2 * net/tipc/socket.c: TIPC socket API 3 3 * 4 - * Copyright (c) 2001-2007, 2012-2017, Ericsson AB 4 + * Copyright (c) 2001-2007, 2012-2019, Ericsson AB 5 5 * Copyright (c) 2004-2008, 2010-2013, Wind River Systems 6 + * Copyright (c) 2020, Red Hat Inc 6 7 * All rights reserved. 7 8 * 8 9 * Redistribution and use in source and binary forms, with or without ··· 645 644 } 646 645 647 646 /** 648 - * tipc_bind - associate or disassocate TIPC name(s) with a socket 647 + * __tipc_bind - associate or disassocate TIPC name(s) with a socket 649 648 * @sock: socket structure 650 - * @uaddr: socket address describing name(s) and desired operation 651 - * @uaddr_len: size of socket address data structure 649 + * @skaddr: socket address describing name(s) and desired operation 650 + * @alen: size of socket address data structure 652 651 * 653 652 * Name and name sequence binding is indicated using a positive scope value; 654 653 * a negative scope value unbinds the specified name. Specifying no name ··· 659 658 * NOTE: This routine doesn't need to take the socket lock since it doesn't 660 659 * access any non-constant socket information. 661 660 */ 662 - 663 - int tipc_sk_bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) 661 + static int __tipc_bind(struct socket *sock, struct sockaddr *skaddr, int alen) 664 662 { 665 - struct sock *sk = sock->sk; 666 - struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; 667 - struct tipc_sock *tsk = tipc_sk(sk); 668 - int res = -EINVAL; 663 + struct sockaddr_tipc *addr = (struct sockaddr_tipc *)skaddr; 664 + struct tipc_sock *tsk = tipc_sk(sock->sk); 669 665 670 - lock_sock(sk); 671 - if (unlikely(!uaddr_len)) { 672 - res = tipc_sk_withdraw(tsk, 0, NULL); 673 - goto exit; 674 - } 675 - if (tsk->group) { 676 - res = -EACCES; 677 - goto exit; 678 - } 679 - if (uaddr_len < sizeof(struct sockaddr_tipc)) { 680 - res = -EINVAL; 681 - goto exit; 682 - } 683 - if (addr->family != AF_TIPC) { 684 - res = -EAFNOSUPPORT; 685 - goto exit; 686 - } 666 + if (unlikely(!alen)) 667 + return tipc_sk_withdraw(tsk, 0, NULL); 687 668 688 669 if (addr->addrtype == TIPC_ADDR_NAME) 689 670 addr->addr.nameseq.upper = addr->addr.nameseq.lower; 690 - else if (addr->addrtype != TIPC_ADDR_NAMESEQ) { 691 - res = -EAFNOSUPPORT; 692 - goto exit; 693 - } 694 671 695 - res = (addr->scope >= 0) ? 696 - tipc_sk_publish(tsk, addr->scope, &addr->addr.nameseq) : 697 - tipc_sk_withdraw(tsk, -addr->scope, &addr->addr.nameseq); 698 - exit: 699 - release_sock(sk); 672 + if (tsk->group) 673 + return -EACCES; 674 + 675 + if (addr->scope >= 0) 676 + return tipc_sk_publish(tsk, addr->scope, &addr->addr.nameseq); 677 + else 678 + return tipc_sk_withdraw(tsk, -addr->scope, &addr->addr.nameseq); 679 + } 680 + 681 + int tipc_sk_bind(struct socket *sock, struct sockaddr *skaddr, int alen) 682 + { 683 + int res; 684 + 685 + lock_sock(sock->sk); 686 + res = __tipc_bind(sock, skaddr, alen); 687 + release_sock(sock->sk); 700 688 return res; 701 689 } 702 690 ··· 696 706 if (alen) { 697 707 if (alen < sizeof(struct sockaddr_tipc)) 698 708 return -EINVAL; 709 + if (addr->family != AF_TIPC) 710 + return -EAFNOSUPPORT; 711 + if (addr->addrtype > TIPC_SERVICE_ADDR) 712 + return -EAFNOSUPPORT; 699 713 if (addr->addr.nameseq.type < TIPC_RESERVED_TYPES) { 700 714 pr_warn_once("Can't bind to reserved service type %u\n", 701 715 addr->addr.nameseq.type);