aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/net/netiucv.c
diff options
context:
space:
mode:
authorUrsula Braun <ursula.braun@de.ibm.com>2011-12-19 17:56:34 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-20 14:05:04 -0500
commit08e3356cc2c0ce8f3359b3d2636c897ac71240ce (patch)
tree086303b5725541ae5d60a492a2248eca0be5b935 /drivers/s390/net/netiucv.c
parentf78ac2bbb1580c2b62ae20d47aaa2ef255f54d38 (diff)
netiucv: allow multiple interfaces to same peer
The NETIUCV device driver allows to connect a Linux guest on z/VM to another z/VM guest based on the z/VM communication facility IUCV. Multiple output paths to different guests are possible, as well as multiple input paths from different guests. With this feature, you can configure multiple point-to-point NETIUCV interfaces between your Linux on System z instance and another z/VM guest. Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com> Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390/net/netiucv.c')
-rw-r--r--drivers/s390/net/netiucv.c217
1 files changed, 135 insertions, 82 deletions
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index b6a6356d09b3..8160591913f9 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -63,6 +63,7 @@
63 63
64#include <asm/io.h> 64#include <asm/io.h>
65#include <asm/uaccess.h> 65#include <asm/uaccess.h>
66#include <asm/ebcdic.h>
66 67
67#include <net/iucv/iucv.h> 68#include <net/iucv/iucv.h>
68#include "fsm.h" 69#include "fsm.h"
@@ -75,7 +76,7 @@ MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");
75 * Debug Facility stuff 76 * Debug Facility stuff
76 */ 77 */
77#define IUCV_DBF_SETUP_NAME "iucv_setup" 78#define IUCV_DBF_SETUP_NAME "iucv_setup"
78#define IUCV_DBF_SETUP_LEN 32 79#define IUCV_DBF_SETUP_LEN 64
79#define IUCV_DBF_SETUP_PAGES 2 80#define IUCV_DBF_SETUP_PAGES 2
80#define IUCV_DBF_SETUP_NR_AREAS 1 81#define IUCV_DBF_SETUP_NR_AREAS 1
81#define IUCV_DBF_SETUP_LEVEL 3 82#define IUCV_DBF_SETUP_LEVEL 3
@@ -226,6 +227,7 @@ struct iucv_connection {
226 struct net_device *netdev; 227 struct net_device *netdev;
227 struct connection_profile prof; 228 struct connection_profile prof;
228 char userid[9]; 229 char userid[9];
230 char userdata[17];
229}; 231};
230 232
231/** 233/**
@@ -263,7 +265,7 @@ struct ll_header {
263}; 265};
264 266
265#define NETIUCV_HDRLEN (sizeof(struct ll_header)) 267#define NETIUCV_HDRLEN (sizeof(struct ll_header))
266#define NETIUCV_BUFSIZE_MAX 32768 268#define NETIUCV_BUFSIZE_MAX 65537
267#define NETIUCV_BUFSIZE_DEFAULT NETIUCV_BUFSIZE_MAX 269#define NETIUCV_BUFSIZE_DEFAULT NETIUCV_BUFSIZE_MAX
268#define NETIUCV_MTU_MAX (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN) 270#define NETIUCV_MTU_MAX (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN)
269#define NETIUCV_MTU_DEFAULT 9216 271#define NETIUCV_MTU_DEFAULT 9216
@@ -288,7 +290,12 @@ static inline int netiucv_test_and_set_busy(struct net_device *dev)
288 return test_and_set_bit(0, &priv->tbusy); 290 return test_and_set_bit(0, &priv->tbusy);
289} 291}
290 292
291static u8 iucvMagic[16] = { 293static u8 iucvMagic_ascii[16] = {
294 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
295 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
296};
297
298static u8 iucvMagic_ebcdic[16] = {
292 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 299 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
293 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 300 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
294}; 301};
@@ -301,18 +308,38 @@ static u8 iucvMagic[16] = {
301 * 308 *
302 * @returns The printable string (static data!!) 309 * @returns The printable string (static data!!)
303 */ 310 */
304static char *netiucv_printname(char *name) 311static char *netiucv_printname(char *name, int len)
305{ 312{
306 static char tmp[9]; 313 static char tmp[17];
307 char *p = tmp; 314 char *p = tmp;
308 memcpy(tmp, name, 8); 315 memcpy(tmp, name, len);
309 tmp[8] = '\0'; 316 tmp[len] = '\0';
310 while (*p && (!isspace(*p))) 317 while (*p && ((p - tmp) < len) && (!isspace(*p)))
311 p++; 318 p++;
312 *p = '\0'; 319 *p = '\0';
313 return tmp; 320 return tmp;
314} 321}
315 322
323static char *netiucv_printuser(struct iucv_connection *conn)
324{
325 static char tmp_uid[9];
326 static char tmp_udat[17];
327 static char buf[100];
328
329 if (memcmp(conn->userdata, iucvMagic_ebcdic, 16)) {
330 tmp_uid[8] = '\0';
331 tmp_udat[16] = '\0';
332 memcpy(tmp_uid, conn->userid, 8);
333 memcpy(tmp_uid, netiucv_printname(tmp_uid, 8), 8);
334 memcpy(tmp_udat, conn->userdata, 16);
335 EBCASC(tmp_udat, 16);
336 memcpy(tmp_udat, netiucv_printname(tmp_udat, 16), 16);
337 sprintf(buf, "%s.%s", tmp_uid, tmp_udat);
338 return buf;
339 } else
340 return netiucv_printname(conn->userid, 8);
341}
342
316/** 343/**
317 * States of the interface statemachine. 344 * States of the interface statemachine.
318 */ 345 */
@@ -563,15 +590,18 @@ static int netiucv_callback_connreq(struct iucv_path *path,
563{ 590{
564 struct iucv_connection *conn = path->private; 591 struct iucv_connection *conn = path->private;
565 struct iucv_event ev; 592 struct iucv_event ev;
593 static char tmp_user[9];
594 static char tmp_udat[17];
566 int rc; 595 int rc;
567 596
568 if (memcmp(iucvMagic, ipuser, 16))
569 /* ipuser must match iucvMagic. */
570 return -EINVAL;
571 rc = -EINVAL; 597 rc = -EINVAL;
598 memcpy(tmp_user, netiucv_printname(ipvmid, 8), 8);
599 memcpy(tmp_udat, ipuser, 16);
600 EBCASC(tmp_udat, 16);
572 read_lock_bh(&iucv_connection_rwlock); 601 read_lock_bh(&iucv_connection_rwlock);
573 list_for_each_entry(conn, &iucv_connection_list, list) { 602 list_for_each_entry(conn, &iucv_connection_list, list) {
574 if (strncmp(ipvmid, conn->userid, 8)) 603 if (strncmp(ipvmid, conn->userid, 8) ||
604 strncmp(ipuser, conn->userdata, 16))
575 continue; 605 continue;
576 /* Found a matching connection for this path. */ 606 /* Found a matching connection for this path. */
577 conn->path = path; 607 conn->path = path;
@@ -580,6 +610,8 @@ static int netiucv_callback_connreq(struct iucv_path *path,
580 fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev); 610 fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev);
581 rc = 0; 611 rc = 0;
582 } 612 }
613 IUCV_DBF_TEXT_(setup, 2, "Connection requested for %s.%s\n",
614 tmp_user, netiucv_printname(tmp_udat, 16));
583 read_unlock_bh(&iucv_connection_rwlock); 615 read_unlock_bh(&iucv_connection_rwlock);
584 return rc; 616 return rc;
585} 617}
@@ -816,7 +848,7 @@ static void conn_action_connaccept(fsm_instance *fi, int event, void *arg)
816 conn->path = path; 848 conn->path = path;
817 path->msglim = NETIUCV_QUEUELEN_DEFAULT; 849 path->msglim = NETIUCV_QUEUELEN_DEFAULT;
818 path->flags = 0; 850 path->flags = 0;
819 rc = iucv_path_accept(path, &netiucv_handler, NULL, conn); 851 rc = iucv_path_accept(path, &netiucv_handler, conn->userdata , conn);
820 if (rc) { 852 if (rc) {
821 IUCV_DBF_TEXT_(setup, 2, "rc %d from iucv_accept", rc); 853 IUCV_DBF_TEXT_(setup, 2, "rc %d from iucv_accept", rc);
822 return; 854 return;
@@ -854,7 +886,7 @@ static void conn_action_conntimsev(fsm_instance *fi, int event, void *arg)
854 886
855 IUCV_DBF_TEXT(trace, 3, __func__); 887 IUCV_DBF_TEXT(trace, 3, __func__);
856 fsm_deltimer(&conn->timer); 888 fsm_deltimer(&conn->timer);
857 iucv_path_sever(conn->path, NULL); 889 iucv_path_sever(conn->path, conn->userdata);
858 fsm_newstate(fi, CONN_STATE_STARTWAIT); 890 fsm_newstate(fi, CONN_STATE_STARTWAIT);
859} 891}
860 892
@@ -867,9 +899,9 @@ static void conn_action_connsever(fsm_instance *fi, int event, void *arg)
867 IUCV_DBF_TEXT(trace, 3, __func__); 899 IUCV_DBF_TEXT(trace, 3, __func__);
868 900
869 fsm_deltimer(&conn->timer); 901 fsm_deltimer(&conn->timer);
870 iucv_path_sever(conn->path, NULL); 902 iucv_path_sever(conn->path, conn->userdata);
871 dev_info(privptr->dev, "The peer interface of the IUCV device" 903 dev_info(privptr->dev, "The peer z/VM guest %s has closed the "
872 " has closed the connection\n"); 904 "connection\n", netiucv_printuser(conn));
873 IUCV_DBF_TEXT(data, 2, 905 IUCV_DBF_TEXT(data, 2,
874 "conn_action_connsever: Remote dropped connection\n"); 906 "conn_action_connsever: Remote dropped connection\n");
875 fsm_newstate(fi, CONN_STATE_STARTWAIT); 907 fsm_newstate(fi, CONN_STATE_STARTWAIT);
@@ -886,8 +918,6 @@ static void conn_action_start(fsm_instance *fi, int event, void *arg)
886 IUCV_DBF_TEXT(trace, 3, __func__); 918 IUCV_DBF_TEXT(trace, 3, __func__);
887 919
888 fsm_newstate(fi, CONN_STATE_STARTWAIT); 920 fsm_newstate(fi, CONN_STATE_STARTWAIT);
889 IUCV_DBF_TEXT_(setup, 2, "%s('%s'): connecting ...\n",
890 netdev->name, conn->userid);
891 921
892 /* 922 /*
893 * We must set the state before calling iucv_connect because the 923 * We must set the state before calling iucv_connect because the
@@ -897,8 +927,11 @@ static void conn_action_start(fsm_instance *fi, int event, void *arg)
897 927
898 fsm_newstate(fi, CONN_STATE_SETUPWAIT); 928 fsm_newstate(fi, CONN_STATE_SETUPWAIT);
899 conn->path = iucv_path_alloc(NETIUCV_QUEUELEN_DEFAULT, 0, GFP_KERNEL); 929 conn->path = iucv_path_alloc(NETIUCV_QUEUELEN_DEFAULT, 0, GFP_KERNEL);
930 IUCV_DBF_TEXT_(setup, 2, "%s: connecting to %s ...\n",
931 netdev->name, netiucv_printuser(conn));
932
900 rc = iucv_path_connect(conn->path, &netiucv_handler, conn->userid, 933 rc = iucv_path_connect(conn->path, &netiucv_handler, conn->userid,
901 NULL, iucvMagic, conn); 934 NULL, conn->userdata, conn);
902 switch (rc) { 935 switch (rc) {
903 case 0: 936 case 0:
904 netdev->tx_queue_len = conn->path->msglim; 937 netdev->tx_queue_len = conn->path->msglim;
@@ -908,13 +941,13 @@ static void conn_action_start(fsm_instance *fi, int event, void *arg)
908 case 11: 941 case 11:
909 dev_warn(privptr->dev, 942 dev_warn(privptr->dev,
910 "The IUCV device failed to connect to z/VM guest %s\n", 943 "The IUCV device failed to connect to z/VM guest %s\n",
911 netiucv_printname(conn->userid)); 944 netiucv_printname(conn->userid, 8));
912 fsm_newstate(fi, CONN_STATE_STARTWAIT); 945 fsm_newstate(fi, CONN_STATE_STARTWAIT);
913 break; 946 break;
914 case 12: 947 case 12:
915 dev_warn(privptr->dev, 948 dev_warn(privptr->dev,
916 "The IUCV device failed to connect to the peer on z/VM" 949 "The IUCV device failed to connect to the peer on z/VM"
917 " guest %s\n", netiucv_printname(conn->userid)); 950 " guest %s\n", netiucv_printname(conn->userid, 8));
918 fsm_newstate(fi, CONN_STATE_STARTWAIT); 951 fsm_newstate(fi, CONN_STATE_STARTWAIT);
919 break; 952 break;
920 case 13: 953 case 13:
@@ -927,7 +960,7 @@ static void conn_action_start(fsm_instance *fi, int event, void *arg)
927 dev_err(privptr->dev, 960 dev_err(privptr->dev,
928 "z/VM guest %s has too many IUCV connections" 961 "z/VM guest %s has too many IUCV connections"
929 " to connect with the IUCV device\n", 962 " to connect with the IUCV device\n",
930 netiucv_printname(conn->userid)); 963 netiucv_printname(conn->userid, 8));
931 fsm_newstate(fi, CONN_STATE_CONNERR); 964 fsm_newstate(fi, CONN_STATE_CONNERR);
932 break; 965 break;
933 case 15: 966 case 15:
@@ -972,7 +1005,7 @@ static void conn_action_stop(fsm_instance *fi, int event, void *arg)
972 netiucv_purge_skb_queue(&conn->collect_queue); 1005 netiucv_purge_skb_queue(&conn->collect_queue);
973 if (conn->path) { 1006 if (conn->path) {
974 IUCV_DBF_TEXT(trace, 5, "calling iucv_path_sever\n"); 1007 IUCV_DBF_TEXT(trace, 5, "calling iucv_path_sever\n");
975 iucv_path_sever(conn->path, iucvMagic); 1008 iucv_path_sever(conn->path, conn->userdata);
976 kfree(conn->path); 1009 kfree(conn->path);
977 conn->path = NULL; 1010 conn->path = NULL;
978 } 1011 }
@@ -1090,7 +1123,8 @@ dev_action_connup(fsm_instance *fi, int event, void *arg)
1090 fsm_newstate(fi, DEV_STATE_RUNNING); 1123 fsm_newstate(fi, DEV_STATE_RUNNING);
1091 dev_info(privptr->dev, 1124 dev_info(privptr->dev,
1092 "The IUCV device has been connected" 1125 "The IUCV device has been connected"
1093 " successfully to %s\n", privptr->conn->userid); 1126 " successfully to %s\n",
1127 netiucv_printuser(privptr->conn));
1094 IUCV_DBF_TEXT(setup, 3, 1128 IUCV_DBF_TEXT(setup, 3,
1095 "connection is up and running\n"); 1129 "connection is up and running\n");
1096 break; 1130 break;
@@ -1452,45 +1486,72 @@ static ssize_t user_show(struct device *dev, struct device_attribute *attr,
1452 struct netiucv_priv *priv = dev_get_drvdata(dev); 1486 struct netiucv_priv *priv = dev_get_drvdata(dev);
1453 1487
1454 IUCV_DBF_TEXT(trace, 5, __func__); 1488 IUCV_DBF_TEXT(trace, 5, __func__);
1455 return sprintf(buf, "%s\n", netiucv_printname(priv->conn->userid)); 1489 return sprintf(buf, "%s\n", netiucv_printuser(priv->conn));
1456} 1490}
1457 1491
1458static ssize_t user_write(struct device *dev, struct device_attribute *attr, 1492static int netiucv_check_user(const char *buf, size_t count, char *username,
1459 const char *buf, size_t count) 1493 char *userdata)
1460{ 1494{
1461 struct netiucv_priv *priv = dev_get_drvdata(dev); 1495 const char *p;
1462 struct net_device *ndev = priv->conn->netdev; 1496 int i;
1463 char *p;
1464 char *tmp;
1465 char username[9];
1466 int i;
1467 struct iucv_connection *cp;
1468 1497
1469 IUCV_DBF_TEXT(trace, 3, __func__); 1498 p = strchr(buf, '.');
1470 if (count > 9) { 1499 if ((p && ((count > 26) ||
1471 IUCV_DBF_TEXT_(setup, 2, 1500 ((p - buf) > 8) ||
1472 "%d is length of username\n", (int) count); 1501 (buf + count - p > 18))) ||
1502 (!p && (count > 9))) {
1503 IUCV_DBF_TEXT(setup, 2, "conn_write: too long\n");
1473 return -EINVAL; 1504 return -EINVAL;
1474 } 1505 }
1475 1506
1476 tmp = strsep((char **) &buf, "\n"); 1507 for (i = 0, p = buf; i < 8 && *p && *p != '.'; i++, p++) {
1477 for (i = 0, p = tmp; i < 8 && *p; i++, p++) { 1508 if (isalnum(*p) || *p == '$') {
1478 if (isalnum(*p) || (*p == '$')) { 1509 username[i] = toupper(*p);
1479 username[i]= toupper(*p);
1480 continue; 1510 continue;
1481 } 1511 }
1482 if (*p == '\n') { 1512 if (*p == '\n')
1483 /* trailing lf, grr */ 1513 /* trailing lf, grr */
1484 break; 1514 break;
1485 }
1486 IUCV_DBF_TEXT_(setup, 2, 1515 IUCV_DBF_TEXT_(setup, 2,
1487 "username: invalid character %c\n", *p); 1516 "conn_write: invalid character %02x\n", *p);
1488 return -EINVAL; 1517 return -EINVAL;
1489 } 1518 }
1490 while (i < 8) 1519 while (i < 8)
1491 username[i++] = ' '; 1520 username[i++] = ' ';
1492 username[8] = '\0'; 1521 username[8] = '\0';
1493 1522
1523 if (*p == '.') {
1524 p++;
1525 for (i = 0; i < 16 && *p; i++, p++) {
1526 if (*p == '\n')
1527 break;
1528 userdata[i] = toupper(*p);
1529 }
1530 while (i > 0 && i < 16)
1531 userdata[i++] = ' ';
1532 } else
1533 memcpy(userdata, iucvMagic_ascii, 16);
1534 userdata[16] = '\0';
1535 ASCEBC(userdata, 16);
1536
1537 return 0;
1538}
1539
1540static ssize_t user_write(struct device *dev, struct device_attribute *attr,
1541 const char *buf, size_t count)
1542{
1543 struct netiucv_priv *priv = dev_get_drvdata(dev);
1544 struct net_device *ndev = priv->conn->netdev;
1545 char username[9];
1546 char userdata[17];
1547 int rc;
1548 struct iucv_connection *cp;
1549
1550 IUCV_DBF_TEXT(trace, 3, __func__);
1551 rc = netiucv_check_user(buf, count, username, userdata);
1552 if (rc)
1553 return rc;
1554
1494 if (memcmp(username, priv->conn->userid, 9) && 1555 if (memcmp(username, priv->conn->userid, 9) &&
1495 (ndev->flags & (IFF_UP | IFF_RUNNING))) { 1556 (ndev->flags & (IFF_UP | IFF_RUNNING))) {
1496 /* username changed while the interface is active. */ 1557 /* username changed while the interface is active. */
@@ -1499,15 +1560,17 @@ static ssize_t user_write(struct device *dev, struct device_attribute *attr,
1499 } 1560 }
1500 read_lock_bh(&iucv_connection_rwlock); 1561 read_lock_bh(&iucv_connection_rwlock);
1501 list_for_each_entry(cp, &iucv_connection_list, list) { 1562 list_for_each_entry(cp, &iucv_connection_list, list) {
1502 if (!strncmp(username, cp->userid, 9) && cp->netdev != ndev) { 1563 if (!strncmp(username, cp->userid, 9) &&
1564 !strncmp(userdata, cp->userdata, 17) && cp->netdev != ndev) {
1503 read_unlock_bh(&iucv_connection_rwlock); 1565 read_unlock_bh(&iucv_connection_rwlock);
1504 IUCV_DBF_TEXT_(setup, 2, "user_write: Connection " 1566 IUCV_DBF_TEXT_(setup, 2, "user_write: Connection to %s "
1505 "to %s already exists\n", username); 1567 "already exists\n", netiucv_printuser(cp));
1506 return -EEXIST; 1568 return -EEXIST;
1507 } 1569 }
1508 } 1570 }
1509 read_unlock_bh(&iucv_connection_rwlock); 1571 read_unlock_bh(&iucv_connection_rwlock);
1510 memcpy(priv->conn->userid, username, 9); 1572 memcpy(priv->conn->userid, username, 9);
1573 memcpy(priv->conn->userdata, userdata, 17);
1511 return count; 1574 return count;
1512} 1575}
1513 1576
@@ -1537,7 +1600,8 @@ static ssize_t buffer_write (struct device *dev, struct device_attribute *attr,
1537 bs1 = simple_strtoul(buf, &e, 0); 1600 bs1 = simple_strtoul(buf, &e, 0);
1538 1601
1539 if (e && (!isspace(*e))) { 1602 if (e && (!isspace(*e))) {
1540 IUCV_DBF_TEXT_(setup, 2, "buffer_write: invalid char %c\n", *e); 1603 IUCV_DBF_TEXT_(setup, 2, "buffer_write: invalid char %02x\n",
1604 *e);
1541 return -EINVAL; 1605 return -EINVAL;
1542 } 1606 }
1543 if (bs1 > NETIUCV_BUFSIZE_MAX) { 1607 if (bs1 > NETIUCV_BUFSIZE_MAX) {
@@ -1864,7 +1928,8 @@ static void netiucv_unregister_device(struct device *dev)
1864 * Add it to the list of netiucv connections; 1928 * Add it to the list of netiucv connections;
1865 */ 1929 */
1866static struct iucv_connection *netiucv_new_connection(struct net_device *dev, 1930static struct iucv_connection *netiucv_new_connection(struct net_device *dev,
1867 char *username) 1931 char *username,
1932 char *userdata)
1868{ 1933{
1869 struct iucv_connection *conn; 1934 struct iucv_connection *conn;
1870 1935
@@ -1893,6 +1958,8 @@ static struct iucv_connection *netiucv_new_connection(struct net_device *dev,
1893 fsm_settimer(conn->fsm, &conn->timer); 1958 fsm_settimer(conn->fsm, &conn->timer);
1894 fsm_newstate(conn->fsm, CONN_STATE_INVALID); 1959 fsm_newstate(conn->fsm, CONN_STATE_INVALID);
1895 1960
1961 if (userdata)
1962 memcpy(conn->userdata, userdata, 17);
1896 if (username) { 1963 if (username) {
1897 memcpy(conn->userid, username, 9); 1964 memcpy(conn->userid, username, 9);
1898 fsm_newstate(conn->fsm, CONN_STATE_STOPPED); 1965 fsm_newstate(conn->fsm, CONN_STATE_STOPPED);
@@ -1919,6 +1986,7 @@ out:
1919 */ 1986 */
1920static void netiucv_remove_connection(struct iucv_connection *conn) 1987static void netiucv_remove_connection(struct iucv_connection *conn)
1921{ 1988{
1989
1922 IUCV_DBF_TEXT(trace, 3, __func__); 1990 IUCV_DBF_TEXT(trace, 3, __func__);
1923 write_lock_bh(&iucv_connection_rwlock); 1991 write_lock_bh(&iucv_connection_rwlock);
1924 list_del_init(&conn->list); 1992 list_del_init(&conn->list);
@@ -1926,7 +1994,7 @@ static void netiucv_remove_connection(struct iucv_connection *conn)
1926 fsm_deltimer(&conn->timer); 1994 fsm_deltimer(&conn->timer);
1927 netiucv_purge_skb_queue(&conn->collect_queue); 1995 netiucv_purge_skb_queue(&conn->collect_queue);
1928 if (conn->path) { 1996 if (conn->path) {
1929 iucv_path_sever(conn->path, iucvMagic); 1997 iucv_path_sever(conn->path, conn->userdata);
1930 kfree(conn->path); 1998 kfree(conn->path);
1931 conn->path = NULL; 1999 conn->path = NULL;
1932 } 2000 }
@@ -1985,7 +2053,7 @@ static void netiucv_setup_netdevice(struct net_device *dev)
1985/** 2053/**
1986 * Allocate and initialize everything of a net device. 2054 * Allocate and initialize everything of a net device.
1987 */ 2055 */
1988static struct net_device *netiucv_init_netdevice(char *username) 2056static struct net_device *netiucv_init_netdevice(char *username, char *userdata)
1989{ 2057{
1990 struct netiucv_priv *privptr; 2058 struct netiucv_priv *privptr;
1991 struct net_device *dev; 2059 struct net_device *dev;
@@ -2004,7 +2072,7 @@ static struct net_device *netiucv_init_netdevice(char *username)
2004 if (!privptr->fsm) 2072 if (!privptr->fsm)
2005 goto out_netdev; 2073 goto out_netdev;
2006 2074
2007 privptr->conn = netiucv_new_connection(dev, username); 2075 privptr->conn = netiucv_new_connection(dev, username, userdata);
2008 if (!privptr->conn) { 2076 if (!privptr->conn) {
2009 IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_new_connection\n"); 2077 IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_new_connection\n");
2010 goto out_fsm; 2078 goto out_fsm;
@@ -2022,47 +2090,31 @@ out_netdev:
2022static ssize_t conn_write(struct device_driver *drv, 2090static ssize_t conn_write(struct device_driver *drv,
2023 const char *buf, size_t count) 2091 const char *buf, size_t count)
2024{ 2092{
2025 const char *p;
2026 char username[9]; 2093 char username[9];
2027 int i, rc; 2094 char userdata[17];
2095 int rc;
2028 struct net_device *dev; 2096 struct net_device *dev;
2029 struct netiucv_priv *priv; 2097 struct netiucv_priv *priv;
2030 struct iucv_connection *cp; 2098 struct iucv_connection *cp;
2031 2099
2032 IUCV_DBF_TEXT(trace, 3, __func__); 2100 IUCV_DBF_TEXT(trace, 3, __func__);
2033 if (count>9) { 2101 rc = netiucv_check_user(buf, count, username, userdata);
2034 IUCV_DBF_TEXT(setup, 2, "conn_write: too long\n"); 2102 if (rc)
2035 return -EINVAL; 2103 return rc;
2036 }
2037
2038 for (i = 0, p = buf; i < 8 && *p; i++, p++) {
2039 if (isalnum(*p) || *p == '$') {
2040 username[i] = toupper(*p);
2041 continue;
2042 }
2043 if (*p == '\n')
2044 /* trailing lf, grr */
2045 break;
2046 IUCV_DBF_TEXT_(setup, 2,
2047 "conn_write: invalid character %c\n", *p);
2048 return -EINVAL;
2049 }
2050 while (i < 8)
2051 username[i++] = ' ';
2052 username[8] = '\0';
2053 2104
2054 read_lock_bh(&iucv_connection_rwlock); 2105 read_lock_bh(&iucv_connection_rwlock);
2055 list_for_each_entry(cp, &iucv_connection_list, list) { 2106 list_for_each_entry(cp, &iucv_connection_list, list) {
2056 if (!strncmp(username, cp->userid, 9)) { 2107 if (!strncmp(username, cp->userid, 9) &&
2108 !strncmp(userdata, cp->userdata, 17)) {
2057 read_unlock_bh(&iucv_connection_rwlock); 2109 read_unlock_bh(&iucv_connection_rwlock);
2058 IUCV_DBF_TEXT_(setup, 2, "conn_write: Connection " 2110 IUCV_DBF_TEXT_(setup, 2, "conn_write: Connection to %s "
2059 "to %s already exists\n", username); 2111 "already exists\n", netiucv_printuser(cp));
2060 return -EEXIST; 2112 return -EEXIST;
2061 } 2113 }
2062 } 2114 }
2063 read_unlock_bh(&iucv_connection_rwlock); 2115 read_unlock_bh(&iucv_connection_rwlock);
2064 2116
2065 dev = netiucv_init_netdevice(username); 2117 dev = netiucv_init_netdevice(username, userdata);
2066 if (!dev) { 2118 if (!dev) {
2067 IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_init_netdevice\n"); 2119 IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_init_netdevice\n");
2068 return -ENODEV; 2120 return -ENODEV;
@@ -2083,8 +2135,9 @@ static ssize_t conn_write(struct device_driver *drv,
2083 if (rc) 2135 if (rc)
2084 goto out_unreg; 2136 goto out_unreg;
2085 2137
2086 dev_info(priv->dev, "The IUCV interface to %s has been" 2138 dev_info(priv->dev, "The IUCV interface to %s has been established "
2087 " established successfully\n", netiucv_printname(username)); 2139 "successfully\n",
2140 netiucv_printuser(priv->conn));
2088 2141
2089 return count; 2142 return count;
2090 2143