aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/net
diff options
context:
space:
mode:
authorEinar Lueck <elelueck@de.ibm.com>2009-11-11 19:11:41 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-16 05:42:05 -0500
commitd64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26d (patch)
tree7d1b7c417c5ab005bfb3ceba31262929b1a85b86 /drivers/s390/net
parentb9f5d52670c27e71f04c466aee77e3a2eeca8080 (diff)
qeth: Exploit Connection Isolation
Isolate data connection to a shared OSA card against other data connections to the same OSA card. Connectivity between isolated data connections sharing the same OSA card is therefore possible only through external network gear (e.g. a router). Signed-off-by: Einar Lueck <elelueck@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')
-rw-r--r--drivers/s390/net/qeth_core.h2
-rw-r--r--drivers/s390/net/qeth_core_main.c151
-rw-r--r--drivers/s390/net/qeth_core_mpc.h45
-rw-r--r--drivers/s390/net/qeth_core_sys.c77
-rw-r--r--drivers/s390/net/qeth_l2_main.c2
-rw-r--r--drivers/s390/net/qeth_l3_main.c2
6 files changed, 267 insertions, 12 deletions
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index e8f72d715eba..4df5eaad6f94 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -648,6 +648,7 @@ struct qeth_card_options {
648 enum qeth_large_send_types large_send; 648 enum qeth_large_send_types large_send;
649 int performance_stats; 649 int performance_stats;
650 int rx_sg_cb; 650 int rx_sg_cb;
651 enum qeth_ipa_isolation_modes isolation;
651}; 652};
652 653
653/* 654/*
@@ -856,6 +857,7 @@ void qeth_core_get_strings(struct net_device *, u32, u8 *);
856void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); 857void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
857void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *text, ...); 858void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *text, ...);
858int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *); 859int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *);
860int qeth_set_access_ctrl_online(struct qeth_card *card);
859 861
860/* exports for OSN */ 862/* exports for OSN */
861int qeth_osn_assist(struct net_device *, void *, int); 863int qeth_osn_assist(struct net_device *, void *, int);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index edee4dc6430c..2c71948c71a1 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -1079,6 +1079,7 @@ static void qeth_set_intial_options(struct qeth_card *card)
1079 card->options.add_hhlen = DEFAULT_ADD_HHLEN; 1079 card->options.add_hhlen = DEFAULT_ADD_HHLEN;
1080 card->options.performance_stats = 0; 1080 card->options.performance_stats = 0;
1081 card->options.rx_sg_cb = QETH_RX_SG_CB; 1081 card->options.rx_sg_cb = QETH_RX_SG_CB;
1082 card->options.isolation = ISOLATION_MODE_NONE;
1082} 1083}
1083 1084
1084static int qeth_do_start_thread(struct qeth_card *card, unsigned long thread) 1085static int qeth_do_start_thread(struct qeth_card *card, unsigned long thread)
@@ -3389,6 +3390,156 @@ int qeth_setadpparms_change_macaddr(struct qeth_card *card)
3389} 3390}
3390EXPORT_SYMBOL_GPL(qeth_setadpparms_change_macaddr); 3391EXPORT_SYMBOL_GPL(qeth_setadpparms_change_macaddr);
3391 3392
3393static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
3394 struct qeth_reply *reply, unsigned long data)
3395{
3396 struct qeth_ipa_cmd *cmd;
3397 struct qeth_set_access_ctrl *access_ctrl_req;
3398 int rc;
3399
3400 QETH_DBF_TEXT(TRACE, 4, "setaccb");
3401
3402 cmd = (struct qeth_ipa_cmd *) data;
3403 access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
3404 QETH_DBF_TEXT_(SETUP, 2, "setaccb");
3405 QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name);
3406 QETH_DBF_TEXT_(SETUP, 2, "rc=%d",
3407 cmd->data.setadapterparms.hdr.return_code);
3408 switch (cmd->data.setadapterparms.hdr.return_code) {
3409 case SET_ACCESS_CTRL_RC_SUCCESS:
3410 case SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED:
3411 case SET_ACCESS_CTRL_RC_ALREADY_ISOLATED:
3412 {
3413 card->options.isolation = access_ctrl_req->subcmd_code;
3414 if (card->options.isolation == ISOLATION_MODE_NONE) {
3415 dev_info(&card->gdev->dev,
3416 "QDIO data connection isolation is deactivated\n");
3417 } else {
3418 dev_info(&card->gdev->dev,
3419 "QDIO data connection isolation is activated\n");
3420 }
3421 QETH_DBF_MESSAGE(3, "OK:SET_ACCESS_CTRL(%s, %d)==%d\n",
3422 card->gdev->dev.kobj.name,
3423 access_ctrl_req->subcmd_code,
3424 cmd->data.setadapterparms.hdr.return_code);
3425 rc = 0;
3426 break;
3427 }
3428 case SET_ACCESS_CTRL_RC_NOT_SUPPORTED:
3429 {
3430 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%s,%d)==%d\n",
3431 card->gdev->dev.kobj.name,
3432 access_ctrl_req->subcmd_code,
3433 cmd->data.setadapterparms.hdr.return_code);
3434 dev_err(&card->gdev->dev, "Adapter does not "
3435 "support QDIO data connection isolation\n");
3436
3437 /* ensure isolation mode is "none" */
3438 card->options.isolation = ISOLATION_MODE_NONE;
3439 rc = -EOPNOTSUPP;
3440 break;
3441 }
3442 case SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER:
3443 {
3444 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d\n",
3445 card->gdev->dev.kobj.name,
3446 access_ctrl_req->subcmd_code,
3447 cmd->data.setadapterparms.hdr.return_code);
3448 dev_err(&card->gdev->dev,
3449 "Adapter is dedicated. "
3450 "QDIO data connection isolation not supported\n");
3451
3452 /* ensure isolation mode is "none" */
3453 card->options.isolation = ISOLATION_MODE_NONE;
3454 rc = -EOPNOTSUPP;
3455 break;
3456 }
3457 case SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF:
3458 {
3459 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d\n",
3460 card->gdev->dev.kobj.name,
3461 access_ctrl_req->subcmd_code,
3462 cmd->data.setadapterparms.hdr.return_code);
3463 dev_err(&card->gdev->dev,
3464 "TSO does not permit QDIO data connection isolation\n");
3465
3466 /* ensure isolation mode is "none" */
3467 card->options.isolation = ISOLATION_MODE_NONE;
3468 rc = -EPERM;
3469 break;
3470 }
3471 default:
3472 {
3473 /* this should never happen */
3474 QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d"
3475 "==UNKNOWN\n",
3476 card->gdev->dev.kobj.name,
3477 access_ctrl_req->subcmd_code,
3478 cmd->data.setadapterparms.hdr.return_code);
3479
3480 /* ensure isolation mode is "none" */
3481 card->options.isolation = ISOLATION_MODE_NONE;
3482 rc = 0;
3483 break;
3484 }
3485 }
3486 qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
3487 return rc;
3488}
3489
3490static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
3491 enum qeth_ipa_isolation_modes isolation)
3492{
3493 int rc;
3494 struct qeth_cmd_buffer *iob;
3495 struct qeth_ipa_cmd *cmd;
3496 struct qeth_set_access_ctrl *access_ctrl_req;
3497
3498 QETH_DBF_TEXT(TRACE, 4, "setacctl");
3499
3500 QETH_DBF_TEXT_(SETUP, 2, "setacctl");
3501 QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name);
3502
3503 iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL,
3504 sizeof(struct qeth_ipacmd_setadpparms_hdr) +
3505 sizeof(struct qeth_set_access_ctrl));
3506 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
3507 access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
3508 access_ctrl_req->subcmd_code = isolation;
3509
3510 rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_set_access_ctrl_cb,
3511 NULL);
3512 QETH_DBF_TEXT_(SETUP, 2, "rc=%d", rc);
3513 return rc;
3514}
3515
3516int qeth_set_access_ctrl_online(struct qeth_card *card)
3517{
3518 int rc = 0;
3519
3520 QETH_DBF_TEXT(TRACE, 4, "setactlo");
3521
3522 if (card->info.type == QETH_CARD_TYPE_OSAE &&
3523 qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) {
3524 rc = qeth_setadpparms_set_access_ctrl(card,
3525 card->options.isolation);
3526 if (rc) {
3527 QETH_DBF_MESSAGE(3,
3528 "IPA(SET_ACCESS_CTRL,%s,%d) sent failed",
3529 card->gdev->dev.kobj.name,
3530 rc);
3531 }
3532 } else if (card->options.isolation != ISOLATION_MODE_NONE) {
3533 card->options.isolation = ISOLATION_MODE_NONE;
3534
3535 dev_err(&card->gdev->dev, "Adapter does not "
3536 "support QDIO data connection isolation\n");
3537 rc = -EOPNOTSUPP;
3538 }
3539 return rc;
3540}
3541EXPORT_SYMBOL_GPL(qeth_set_access_ctrl_online);
3542
3392void qeth_tx_timeout(struct net_device *dev) 3543void qeth_tx_timeout(struct net_device *dev)
3393{ 3544{
3394 struct qeth_card *card; 3545 struct qeth_card *card;
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index eecb2ee62e85..52c03438dbec 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -234,18 +234,19 @@ enum qeth_ipa_setdelip_flags {
234 234
235/* SETADAPTER IPA Command: ****************************************************/ 235/* SETADAPTER IPA Command: ****************************************************/
236enum qeth_ipa_setadp_cmd { 236enum qeth_ipa_setadp_cmd {
237 IPA_SETADP_QUERY_COMMANDS_SUPPORTED = 0x0001, 237 IPA_SETADP_QUERY_COMMANDS_SUPPORTED = 0x00000001L,
238 IPA_SETADP_ALTER_MAC_ADDRESS = 0x0002, 238 IPA_SETADP_ALTER_MAC_ADDRESS = 0x00000002L,
239 IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x0004, 239 IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x00000004L,
240 IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x0008, 240 IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x00000008L,
241 IPA_SETADP_SET_ADDRESSING_MODE = 0x0010, 241 IPA_SETADP_SET_ADDRESSING_MODE = 0x00000010L,
242 IPA_SETADP_SET_CONFIG_PARMS = 0x0020, 242 IPA_SETADP_SET_CONFIG_PARMS = 0x00000020L,
243 IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x0040, 243 IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x00000040L,
244 IPA_SETADP_SET_BROADCAST_MODE = 0x0080, 244 IPA_SETADP_SET_BROADCAST_MODE = 0x00000080L,
245 IPA_SETADP_SEND_OSA_MESSAGE = 0x0100, 245 IPA_SETADP_SEND_OSA_MESSAGE = 0x00000100L,
246 IPA_SETADP_SET_SNMP_CONTROL = 0x0200, 246 IPA_SETADP_SET_SNMP_CONTROL = 0x00000200L,
247 IPA_SETADP_QUERY_CARD_INFO = 0x0400, 247 IPA_SETADP_QUERY_CARD_INFO = 0x00000400L,
248 IPA_SETADP_SET_PROMISC_MODE = 0x0800, 248 IPA_SETADP_SET_PROMISC_MODE = 0x00000800L,
249 IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L,
249}; 250};
250enum qeth_ipa_mac_ops { 251enum qeth_ipa_mac_ops {
251 CHANGE_ADDR_READ_MAC = 0, 252 CHANGE_ADDR_READ_MAC = 0,
@@ -264,6 +265,20 @@ enum qeth_ipa_promisc_modes {
264 SET_PROMISC_MODE_OFF = 0, 265 SET_PROMISC_MODE_OFF = 0,
265 SET_PROMISC_MODE_ON = 1, 266 SET_PROMISC_MODE_ON = 1,
266}; 267};
268enum qeth_ipa_isolation_modes {
269 ISOLATION_MODE_NONE = 0x00000000L,
270 ISOLATION_MODE_FWD = 0x00000001L,
271 ISOLATION_MODE_DROP = 0x00000002L,
272};
273enum qeth_ipa_set_access_mode_rc {
274 SET_ACCESS_CTRL_RC_SUCCESS = 0x0000,
275 SET_ACCESS_CTRL_RC_NOT_SUPPORTED = 0x0004,
276 SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED = 0x0008,
277 SET_ACCESS_CTRL_RC_ALREADY_ISOLATED = 0x0010,
278 SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER = 0x0014,
279 SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF = 0x0018,
280};
281
267 282
268/* (SET)DELIP(M) IPA stuff ***************************************************/ 283/* (SET)DELIP(M) IPA stuff ***************************************************/
269struct qeth_ipacmd_setdelip4 { 284struct qeth_ipacmd_setdelip4 {
@@ -376,6 +391,11 @@ struct qeth_snmp_ureq {
376 struct qeth_snmp_cmd cmd; 391 struct qeth_snmp_cmd cmd;
377} __attribute__((packed)); 392} __attribute__((packed));
378 393
394/* SET_ACCESS_CONTROL: same format for request and reply */
395struct qeth_set_access_ctrl {
396 __u32 subcmd_code;
397} __attribute__((packed));
398
379struct qeth_ipacmd_setadpparms_hdr { 399struct qeth_ipacmd_setadpparms_hdr {
380 __u32 supp_hw_cmds; 400 __u32 supp_hw_cmds;
381 __u32 reserved1; 401 __u32 reserved1;
@@ -394,6 +414,7 @@ struct qeth_ipacmd_setadpparms {
394 struct qeth_query_cmds_supp query_cmds_supp; 414 struct qeth_query_cmds_supp query_cmds_supp;
395 struct qeth_change_addr change_addr; 415 struct qeth_change_addr change_addr;
396 struct qeth_snmp_cmd snmp; 416 struct qeth_snmp_cmd snmp;
417 struct qeth_set_access_ctrl set_access_ctrl;
397 __u32 mode; 418 __u32 mode;
398 } data; 419 } data;
399} __attribute__ ((packed)); 420} __attribute__ ((packed));
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 33505c2a0e3a..f2358a75ed0c 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -463,6 +463,82 @@ static ssize_t qeth_dev_large_send_store(struct device *dev,
463static DEVICE_ATTR(large_send, 0644, qeth_dev_large_send_show, 463static DEVICE_ATTR(large_send, 0644, qeth_dev_large_send_show,
464 qeth_dev_large_send_store); 464 qeth_dev_large_send_store);
465 465
466#define ATTR_QETH_ISOLATION_NONE ("none")
467#define ATTR_QETH_ISOLATION_FWD ("forward")
468#define ATTR_QETH_ISOLATION_DROP ("drop")
469
470static ssize_t qeth_dev_isolation_show(struct device *dev,
471 struct device_attribute *attr, char *buf)
472{
473 struct qeth_card *card = dev_get_drvdata(dev);
474
475 if (!card)
476 return -EINVAL;
477
478 switch (card->options.isolation) {
479 case ISOLATION_MODE_NONE:
480 return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_NONE);
481 case ISOLATION_MODE_FWD:
482 return snprintf(buf, 9, "%s\n", ATTR_QETH_ISOLATION_FWD);
483 case ISOLATION_MODE_DROP:
484 return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_DROP);
485 default:
486 return snprintf(buf, 5, "%s\n", "N/A");
487 }
488}
489
490static ssize_t qeth_dev_isolation_store(struct device *dev,
491 struct device_attribute *attr, const char *buf, size_t count)
492{
493 struct qeth_card *card = dev_get_drvdata(dev);
494 enum qeth_ipa_isolation_modes isolation;
495 int rc = 0;
496 char *tmp, *curtoken;
497 curtoken = (char *) buf;
498
499 if (!card) {
500 rc = -EINVAL;
501 goto out;
502 }
503
504 /* check for unknown, too, in case we do not yet know who we are */
505 if (card->info.type != QETH_CARD_TYPE_OSAE &&
506 card->info.type != QETH_CARD_TYPE_UNKNOWN) {
507 rc = -EOPNOTSUPP;
508 dev_err(&card->gdev->dev, "Adapter does not "
509 "support QDIO data connection isolation\n");
510 goto out;
511 }
512
513 /* parse input into isolation mode */
514 tmp = strsep(&curtoken, "\n");
515 if (!strcmp(tmp, ATTR_QETH_ISOLATION_NONE)) {
516 isolation = ISOLATION_MODE_NONE;
517 } else if (!strcmp(tmp, ATTR_QETH_ISOLATION_FWD)) {
518 isolation = ISOLATION_MODE_FWD;
519 } else if (!strcmp(tmp, ATTR_QETH_ISOLATION_DROP)) {
520 isolation = ISOLATION_MODE_DROP;
521 } else {
522 rc = -EINVAL;
523 goto out;
524 }
525 rc = count;
526
527 /* defer IP assist if device is offline (until discipline->set_online)*/
528 card->options.isolation = isolation;
529 if (card->state == CARD_STATE_SOFTSETUP ||
530 card->state == CARD_STATE_UP) {
531 int ipa_rc = qeth_set_access_ctrl_online(card);
532 if (ipa_rc != 0)
533 rc = ipa_rc;
534 }
535out:
536 return rc;
537}
538
539static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
540 qeth_dev_isolation_store);
541
466static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value) 542static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
467{ 543{
468 544
@@ -583,6 +659,7 @@ static struct attribute *qeth_device_attrs[] = {
583 &dev_attr_performance_stats.attr, 659 &dev_attr_performance_stats.attr,
584 &dev_attr_layer2.attr, 660 &dev_attr_layer2.attr,
585 &dev_attr_large_send.attr, 661 &dev_attr_large_send.attr,
662 &dev_attr_isolation.attr,
586 NULL, 663 NULL,
587}; 664};
588 665
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index b61d5c723c50..a63a3dfcdf63 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -988,6 +988,8 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
988 card->lan_online = 1; 988 card->lan_online = 1;
989 989
990 if (card->info.type != QETH_CARD_TYPE_OSN) { 990 if (card->info.type != QETH_CARD_TYPE_OSN) {
991 /* configure isolation level */
992 qeth_set_access_ctrl_online(card);
991 qeth_set_large_send(card, card->options.large_send); 993 qeth_set_large_send(card, card->options.large_send);
992 qeth_l2_process_vlans(card, 0); 994 qeth_l2_process_vlans(card, 0);
993 } 995 }
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 4ca28c16ca83..dd6766672a00 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1506,6 +1506,8 @@ static int qeth_l3_start_ipa_tso(struct qeth_card *card)
1506static int qeth_l3_start_ipassists(struct qeth_card *card) 1506static int qeth_l3_start_ipassists(struct qeth_card *card)
1507{ 1507{
1508 QETH_DBF_TEXT(TRACE, 3, "strtipas"); 1508 QETH_DBF_TEXT(TRACE, 3, "strtipas");
1509
1510 qeth_set_access_ctrl_online(card); /* go on*/
1509 qeth_l3_start_ipa_arp_processing(card); /* go on*/ 1511 qeth_l3_start_ipa_arp_processing(card); /* go on*/
1510 qeth_l3_start_ipa_ip_fragmentation(card); /* go on*/ 1512 qeth_l3_start_ipa_ip_fragmentation(card); /* go on*/
1511 qeth_l3_start_ipa_source_mac(card); /* go on*/ 1513 qeth_l3_start_ipa_source_mac(card); /* go on*/