aboutsummaryrefslogtreecommitdiffstats
path: root/net/iucv
diff options
context:
space:
mode:
authorPhilipp Hachtmann <phacht@linux.vnet.ibm.com>2014-05-28 04:22:28 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-30 20:35:23 -0400
commit53a4b4995edc1b9eddf6cee342479f86cbae4337 (patch)
treef070b61d0413ae5ac205edd4399906510adac3a6 /net/iucv
parent078252e0e877b50fcd42d3bd0d112f1f7c8518e8 (diff)
af_iucv: Add automatic (source) iucv_name to bind
If a socket is bound to an address using before calling connect it is usual to leave it to the network system to choose an appropriate outgoing application name respective port address. af_iucv on VM uses a counter and uses simple numbers as unique identifiers. This behaviour was missing when af_iucv is used with HiperSockets. This patch contains a simple approach to harmonize af_iucv's behaviour. Signed-off-by: Philipp Hachtmann <phacht@linux.vnet.ibm.com> Signed-off-by: Frank Blaschka <blaschka@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/iucv')
-rw-r--r--net/iucv/af_iucv.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 8c9d7302c846..60f5c20d510a 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -682,6 +682,18 @@ struct sock *iucv_accept_dequeue(struct sock *parent, struct socket *newsock)
682 return NULL; 682 return NULL;
683} 683}
684 684
685static void __iucv_auto_name(struct iucv_sock *iucv)
686{
687 char name[12];
688
689 sprintf(name, "%08x", atomic_inc_return(&iucv_sk_list.autobind_name));
690 while (__iucv_get_sock_by_name(name)) {
691 sprintf(name, "%08x",
692 atomic_inc_return(&iucv_sk_list.autobind_name));
693 }
694 memcpy(iucv->src_name, name, 8);
695}
696
685/* Bind an unbound socket */ 697/* Bind an unbound socket */
686static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr, 698static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
687 int addr_len) 699 int addr_len)
@@ -724,8 +736,12 @@ static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
724 rcu_read_lock(); 736 rcu_read_lock();
725 for_each_netdev_rcu(&init_net, dev) { 737 for_each_netdev_rcu(&init_net, dev) {
726 if (!memcmp(dev->perm_addr, uid, 8)) { 738 if (!memcmp(dev->perm_addr, uid, 8)) {
727 memcpy(iucv->src_name, sa->siucv_name, 8);
728 memcpy(iucv->src_user_id, sa->siucv_user_id, 8); 739 memcpy(iucv->src_user_id, sa->siucv_user_id, 8);
740 /* Check for unitialized siucv_name */
741 if (strncmp(sa->siucv_name, " ", 8) == 0)
742 __iucv_auto_name(iucv);
743 else
744 memcpy(iucv->src_name, sa->siucv_name, 8);
729 sk->sk_bound_dev_if = dev->ifindex; 745 sk->sk_bound_dev_if = dev->ifindex;
730 iucv->hs_dev = dev; 746 iucv->hs_dev = dev;
731 dev_hold(dev); 747 dev_hold(dev);
@@ -763,7 +779,6 @@ done:
763static int iucv_sock_autobind(struct sock *sk) 779static int iucv_sock_autobind(struct sock *sk)
764{ 780{
765 struct iucv_sock *iucv = iucv_sk(sk); 781 struct iucv_sock *iucv = iucv_sk(sk);
766 char name[12];
767 int err = 0; 782 int err = 0;
768 783
769 if (unlikely(!pr_iucv)) 784 if (unlikely(!pr_iucv))
@@ -772,17 +787,9 @@ static int iucv_sock_autobind(struct sock *sk)
772 memcpy(iucv->src_user_id, iucv_userid, 8); 787 memcpy(iucv->src_user_id, iucv_userid, 8);
773 788
774 write_lock_bh(&iucv_sk_list.lock); 789 write_lock_bh(&iucv_sk_list.lock);
775 790 __iucv_auto_name(iucv);
776 sprintf(name, "%08x", atomic_inc_return(&iucv_sk_list.autobind_name));
777 while (__iucv_get_sock_by_name(name)) {
778 sprintf(name, "%08x",
779 atomic_inc_return(&iucv_sk_list.autobind_name));
780 }
781
782 write_unlock_bh(&iucv_sk_list.lock); 791 write_unlock_bh(&iucv_sk_list.lock);
783 792
784 memcpy(&iucv->src_name, name, 8);
785
786 if (!iucv->msglimit) 793 if (!iucv->msglimit)
787 iucv->msglimit = IUCV_QUEUELEN_DEFAULT; 794 iucv->msglimit = IUCV_QUEUELEN_DEFAULT;
788 795