summaryrefslogtreecommitdiffstats
path: root/drivers/s390/net/qeth_core_main.c
diff options
context:
space:
mode:
authorEinar Lueck2009-11-12 01:11:41 +0100
committerDavid S. Miller2009-11-16 11:42:05 +0100
commitd64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26d (patch)
tree7d1b7c417c5ab005bfb3ceba31262929b1a85b86 /drivers/s390/net/qeth_core_main.c
parentremove deprecated and not used: print_mac() (diff)
downloadkernel-qcow2-linux-d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26d.tar.gz
kernel-qcow2-linux-d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26d.tar.xz
kernel-qcow2-linux-d64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26d.zip
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/qeth_core_main.c')
-rw-r--r--drivers/s390/net/qeth_core_main.c151
1 files changed, 151 insertions, 0 deletions
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)
card->options.add_hhlen = DEFAULT_ADD_HHLEN;
card->options.performance_stats = 0;
card->options.rx_sg_cb = QETH_RX_SG_CB;
+ card->options.isolation = ISOLATION_MODE_NONE;
}
static 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)
}
EXPORT_SYMBOL_GPL(qeth_setadpparms_change_macaddr);
+static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
+ struct qeth_reply *reply, unsigned long data)
+{
+ struct qeth_ipa_cmd *cmd;
+ struct qeth_set_access_ctrl *access_ctrl_req;
+ int rc;
+
+ QETH_DBF_TEXT(TRACE, 4, "setaccb");
+
+ cmd = (struct qeth_ipa_cmd *) data;
+ access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
+ QETH_DBF_TEXT_(SETUP, 2, "setaccb");
+ QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name);
+ QETH_DBF_TEXT_(SETUP, 2, "rc=%d",
+ cmd->data.setadapterparms.hdr.return_code);
+ switch (cmd->data.setadapterparms.hdr.return_code) {
+ case SET_ACCESS_CTRL_RC_SUCCESS:
+ case SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED:
+ case SET_ACCESS_CTRL_RC_ALREADY_ISOLATED:
+ {
+ card->options.isolation = access_ctrl_req->subcmd_code;
+ if (card->options.isolation == ISOLATION_MODE_NONE) {
+ dev_info(&card->gdev->dev,
+ "QDIO data connection isolation is deactivated\n");
+ } else {
+ dev_info(&card->gdev->dev,
+ "QDIO data connection isolation is activated\n");
+ }
+ QETH_DBF_MESSAGE(3, "OK:SET_ACCESS_CTRL(%s, %d)==%d\n",
+ card->gdev->dev.kobj.name,
+ access_ctrl_req->subcmd_code,
+ cmd->data.setadapterparms.hdr.return_code);
+ rc = 0;
+ break;
+ }
+ case SET_ACCESS_CTRL_RC_NOT_SUPPORTED:
+ {
+ QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%s,%d)==%d\n",
+ card->gdev->dev.kobj.name,
+ access_ctrl_req->subcmd_code,
+ cmd->data.setadapterparms.hdr.return_code);
+ dev_err(&card->gdev->dev, "Adapter does not "
+ "support QDIO data connection isolation\n");
+
+ /* ensure isolation mode is "none" */
+ card->options.isolation = ISOLATION_MODE_NONE;
+ rc = -EOPNOTSUPP;
+ break;
+ }
+ case SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER:
+ {
+ QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d\n",
+ card->gdev->dev.kobj.name,
+ access_ctrl_req->subcmd_code,
+ cmd->data.setadapterparms.hdr.return_code);
+ dev_err(&card->gdev->dev,
+ "Adapter is dedicated. "
+ "QDIO data connection isolation not supported\n");
+
+ /* ensure isolation mode is "none" */
+ card->options.isolation = ISOLATION_MODE_NONE;
+ rc = -EOPNOTSUPP;
+ break;
+ }
+ case SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF:
+ {
+ QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d\n",
+ card->gdev->dev.kobj.name,
+ access_ctrl_req->subcmd_code,
+ cmd->data.setadapterparms.hdr.return_code);
+ dev_err(&card->gdev->dev,
+ "TSO does not permit QDIO data connection isolation\n");
+
+ /* ensure isolation mode is "none" */
+ card->options.isolation = ISOLATION_MODE_NONE;
+ rc = -EPERM;
+ break;
+ }
+ default:
+ {
+ /* this should never happen */
+ QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d"
+ "==UNKNOWN\n",
+ card->gdev->dev.kobj.name,
+ access_ctrl_req->subcmd_code,
+ cmd->data.setadapterparms.hdr.return_code);
+
+ /* ensure isolation mode is "none" */
+ card->options.isolation = ISOLATION_MODE_NONE;
+ rc = 0;
+ break;
+ }
+ }
+ qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
+ return rc;
+}
+
+static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
+ enum qeth_ipa_isolation_modes isolation)
+{
+ int rc;
+ struct qeth_cmd_buffer *iob;
+ struct qeth_ipa_cmd *cmd;
+ struct qeth_set_access_ctrl *access_ctrl_req;
+
+ QETH_DBF_TEXT(TRACE, 4, "setacctl");
+
+ QETH_DBF_TEXT_(SETUP, 2, "setacctl");
+ QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name);
+
+ iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL,
+ sizeof(struct qeth_ipacmd_setadpparms_hdr) +
+ sizeof(struct qeth_set_access_ctrl));
+ cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
+ access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
+ access_ctrl_req->subcmd_code = isolation;
+
+ rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_set_access_ctrl_cb,
+ NULL);
+ QETH_DBF_TEXT_(SETUP, 2, "rc=%d", rc);
+ return rc;
+}
+
+int qeth_set_access_ctrl_online(struct qeth_card *card)
+{
+ int rc = 0;
+
+ QETH_DBF_TEXT(TRACE, 4, "setactlo");
+
+ if (card->info.type == QETH_CARD_TYPE_OSAE &&
+ qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) {
+ rc = qeth_setadpparms_set_access_ctrl(card,
+ card->options.isolation);
+ if (rc) {
+ QETH_DBF_MESSAGE(3,
+ "IPA(SET_ACCESS_CTRL,%s,%d) sent failed",
+ card->gdev->dev.kobj.name,
+ rc);
+ }
+ } else if (card->options.isolation != ISOLATION_MODE_NONE) {
+ card->options.isolation = ISOLATION_MODE_NONE;
+
+ dev_err(&card->gdev->dev, "Adapter does not "
+ "support QDIO data connection isolation\n");
+ rc = -EOPNOTSUPP;
+ }
+ return rc;
+}
+EXPORT_SYMBOL_GPL(qeth_set_access_ctrl_online);
+
void qeth_tx_timeout(struct net_device *dev)
{
struct qeth_card *card;