summaryrefslogtreecommitdiff
path: root/drivers/s390/net/qeth_core_sys.c
diff options
context:
space:
mode:
authorEinar Lueck <elelueck@de.ibm.com>2009-11-12 00:11:41 +0000
committerDavid S. Miller <davem@davemloft.net>2009-11-16 02:42:05 -0800
commitd64ecc22d0a4b175d97cb2b1e297a9c5e3bdb26d (patch)
tree7d1b7c417c5ab005bfb3ceba31262929b1a85b86 /drivers/s390/net/qeth_core_sys.c
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/qeth_core_sys.c')
-rw-r--r--drivers/s390/net/qeth_core_sys.c77
1 files changed, 77 insertions, 0 deletions
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,
static DEVICE_ATTR(large_send, 0644, qeth_dev_large_send_show,
qeth_dev_large_send_store);
+#define ATTR_QETH_ISOLATION_NONE ("none")
+#define ATTR_QETH_ISOLATION_FWD ("forward")
+#define ATTR_QETH_ISOLATION_DROP ("drop")
+
+static ssize_t qeth_dev_isolation_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct qeth_card *card = dev_get_drvdata(dev);
+
+ if (!card)
+ return -EINVAL;
+
+ switch (card->options.isolation) {
+ case ISOLATION_MODE_NONE:
+ return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_NONE);
+ case ISOLATION_MODE_FWD:
+ return snprintf(buf, 9, "%s\n", ATTR_QETH_ISOLATION_FWD);
+ case ISOLATION_MODE_DROP:
+ return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_DROP);
+ default:
+ return snprintf(buf, 5, "%s\n", "N/A");
+ }
+}
+
+static ssize_t qeth_dev_isolation_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct qeth_card *card = dev_get_drvdata(dev);
+ enum qeth_ipa_isolation_modes isolation;
+ int rc = 0;
+ char *tmp, *curtoken;
+ curtoken = (char *) buf;
+
+ if (!card) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ /* check for unknown, too, in case we do not yet know who we are */
+ if (card->info.type != QETH_CARD_TYPE_OSAE &&
+ card->info.type != QETH_CARD_TYPE_UNKNOWN) {
+ rc = -EOPNOTSUPP;
+ dev_err(&card->gdev->dev, "Adapter does not "
+ "support QDIO data connection isolation\n");
+ goto out;
+ }
+
+ /* parse input into isolation mode */
+ tmp = strsep(&curtoken, "\n");
+ if (!strcmp(tmp, ATTR_QETH_ISOLATION_NONE)) {
+ isolation = ISOLATION_MODE_NONE;
+ } else if (!strcmp(tmp, ATTR_QETH_ISOLATION_FWD)) {
+ isolation = ISOLATION_MODE_FWD;
+ } else if (!strcmp(tmp, ATTR_QETH_ISOLATION_DROP)) {
+ isolation = ISOLATION_MODE_DROP;
+ } else {
+ rc = -EINVAL;
+ goto out;
+ }
+ rc = count;
+
+ /* defer IP assist if device is offline (until discipline->set_online)*/
+ card->options.isolation = isolation;
+ if (card->state == CARD_STATE_SOFTSETUP ||
+ card->state == CARD_STATE_UP) {
+ int ipa_rc = qeth_set_access_ctrl_online(card);
+ if (ipa_rc != 0)
+ rc = ipa_rc;
+ }
+out:
+ return rc;
+}
+
+static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
+ qeth_dev_isolation_store);
+
static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
{
@@ -583,6 +659,7 @@ static struct attribute *qeth_device_attrs[] = {
&dev_attr_performance_stats.attr,
&dev_attr_layer2.attr,
&dev_attr_large_send.attr,
+ &dev_attr_isolation.attr,
NULL,
};