[ofa-general] [PATCH 2/4] ipoib: make broadcast scope configurable

Rolf Manderscheid rvm at obsidianresearch.com
Mon Dec 10 12:39:49 PST 2007


Add a broadcast_scope attribute to parent ipoib devices to enable ipoib over routers.
The scope can be changed provided that the link is down.  Some mgids are mapped early
so the scope field in the mgid needs to be fixed up before use now that the scope is
configurable.  The pkey fixups have been removed because the mapping functions now
take care of that.

Signed-off-by: Rolf Manderscheid <rvm at obsidianresearch.com>

---

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index fe63723..7b6627f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -1056,6 +1056,43 @@ int ipoib_add_umcast_attr(struct net_device *dev)
 	return device_create_file(&dev->dev, &dev_attr_umcast);
 }
 
+static ssize_t show_bcast_scope(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
+
+	return sprintf(buf, "0x%x\n", priv->dev->broadcast[5] & 0xF);
+}
+
+static ssize_t set_bcast_scope(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
+	int scope;
+
+	if (priv->dev->flags & IFF_UP)
+		return -EBUSY;
+
+	if (sscanf(buf, "%i", &scope) != 1)
+		return -EINVAL;
+
+	switch (scope) {
+	case 0x2: /* link-local */
+	case 0x5: /* site-local */
+	case 0x8: /* organization-local */
+	case 0xE: /* global */
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	priv->dev->broadcast[5] &= ~0xF;
+	priv->dev->broadcast[5] |= scope;
+	return count;
+}
+static DEVICE_ATTR(broadcast_scope, S_IWUSR | S_IRUGO, show_bcast_scope, set_bcast_scope);
+
 static ssize_t create_child(struct device *dev,
 			    struct device_attribute *attr,
 			    const char *buf, size_t count)
@@ -1179,6 +1216,8 @@ static struct net_device *ipoib_add_port(const char *format,
 		goto sysfs_failed;
 	if (device_create_file(&priv->dev->dev, &dev_attr_delete_child))
 		goto sysfs_failed;
+	if (device_create_file(&priv->dev->dev, &dev_attr_broadcast_scope))
+		goto sysfs_failed;
 
 	return priv->dev;
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 858ada1..00e29b9 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -788,9 +788,11 @@ void ipoib_mcast_restart_task(struct work_struct *work)
 
 		memcpy(mgid.raw, mclist->dmi_addr + 4, sizeof mgid);
 
-		/* Add in the P_Key */
-		mgid.raw[4] = (priv->pkey >> 8) & 0xff;
-		mgid.raw[5] = priv->pkey & 0xff;
+		/* FIXME: ipv6 maps the all-nodes multicast group at device creation,
+		   so the mapping can change if the broadcast_scope is changed.  If
+		   the ipv6 core can delay joining the all-nodes group until after
+		   the link is brought up, then this can go away: */
+		mgid.raw[1] = (mgid.raw[1] & ~0xF) | (priv->dev->broadcast[5] & 0xF);
 
 		mcast = __ipoib_mcast_find(dev, &mgid);
 		if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {



More information about the general mailing list