[ofa-general] [PATCH regenrated] IB/ipoib: enable IGMP for userpsace multicast IB apps

Eli Cohen eli at mellanox.co.il
Mon Oct 15 00:57:40 PDT 2007


The kernel IB stack allows (through the RDMA CM) user space multicast applications
to interoperate with IP based apps optionally running at a different IP subnet.

To support this inter-op for the case where the receiving party resides at
the IB side, there is a need to handle IGMP (reports/queries) else the local
IP router would not forward multicast traffic towards the IB network.

This patch does a lookup on the database used for multicast reference counting and
enhances IPoIB to ignore multicast group which is already handled by user space, all
this under a per device policy flag. That is when the policy flag allows it, IPoIB
will not join and attach its QP to a multicast group which has an entry on the database.

For each IPoIB device, the /sys/class/net/$dev/umcast attribute controls the
policy flag where the default value is being off (zero). The flag can be read
and set/unset through sysfs.

Signed-off-by: Or Gerlitz <ogerlitz at voltaire.com>

---

This is the same patch the Or committed to the ofa git tree but this one
was regenerated to prevent conflicts which were introduced after the fix
to the checksum offload patch I sent (fix was sent just before this
one).


Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
===================================================================
--- ofa_1_3_dev_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2007-10-14 17:46:43.000000000 +0200
+++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2007-10-14 17:57:10.000000000 +0200
@@ -761,6 +761,7 @@ void ipoib_mcast_restart_task(struct wor
 	struct ipoib_mcast *mcast, *tmcast;
 	LIST_HEAD(remove_list);
 	unsigned long flags;
+	struct ib_sa_mcmember_rec rec;
 
 	ipoib_dbg_mcast(priv, "restarting multicast task\n");
 
@@ -794,6 +795,15 @@ void ipoib_mcast_restart_task(struct wor
 		if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
 			struct ipoib_mcast *nmcast;
 
+			/* ignore group which is directly joined by user space */
+			if (test_bit(IPOIB_FLAG_ADMIN_UMCAST_ALLOWED, &priv->flags) &&
+			    !ib_sa_get_mcmember_rec(priv->ca, priv->port, &mgid, &rec))
+			{
+				ipoib_dbg_mcast(priv, "ignoring multicast entry for mgid "
+						IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid));
+				continue;
+			}
+
 			/* Not found or send-only group, let's add a new entry */
 			ipoib_dbg_mcast(priv, "adding multicast entry for mgid "
 					IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid));
Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib.h
===================================================================
--- ofa_1_3_dev_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib.h	2007-10-14 17:55:52.000000000 +0200
+++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib.h	2007-10-14 17:57:10.000000000 +0200
@@ -88,6 +88,7 @@ enum {
 	IPOIB_FLAG_ADMIN_CM 	  = 10,
 	IPOIB_FLAG_HW_CSUM	  = 11,
 	IPOIB_FLAG_RX_CSUM        = 12,
+ 	IPOIB_FLAG_ADMIN_UMCAST_ALLOWED	= 13,
 
 	IPOIB_MAX_BACKOFF_SECONDS = 16,
 
@@ -498,6 +499,7 @@ static inline void ipoib_put_ah(struct i
 
 int ipoib_open(struct net_device *dev);
 int ipoib_add_pkey_attr(struct net_device *dev);
+int ipoib_add_umcast_attr(struct net_device *dev);
 
 void ipoib_send(struct net_device *dev, struct sk_buff *skb,
 		struct ipoib_ah *address, u32 qpn);
Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
===================================================================
--- ofa_1_3_dev_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c	2007-10-14 17:55:50.000000000 +0200
+++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c	2007-10-14 18:05:36.000000000 +0200
@@ -1131,6 +1131,45 @@ int ipoib_add_pkey_attr(struct net_devic
 	return device_create_file(&dev->dev, &dev_attr_pkey);
 }
 
+static ssize_t show_umcast(struct device *dev,
+                           struct device_attribute *attr, char *buf)
+{
+        struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
+
+        if (test_bit(IPOIB_FLAG_ADMIN_UMCAST_ALLOWED, &priv->flags))
+                return sprintf(buf, "1\n");
+        else
+                return sprintf(buf, "0\n");
+}
+
+static ssize_t set_umcast(struct device *dev,
+                          struct device_attribute *attr,
+                          const char *buf, size_t count)
+{
+        struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
+        unsigned long umcast_val = simple_strtoul(buf, NULL, 0);
+
+        if (umcast_val > 0) {
+                set_bit(IPOIB_FLAG_ADMIN_UMCAST_ALLOWED, &priv->flags);
+                ipoib_warn(priv, "ignoring multicast groups joined directly "
+                                "by user space\n");
+                return count;
+        }
+
+        if (!umcast_val) {
+                clear_bit(IPOIB_FLAG_ADMIN_UMCAST_ALLOWED, &priv->flags);
+                return count;
+        }
+
+        return -EINVAL;
+}
+static DEVICE_ATTR(umcast, S_IWUSR | S_IRUGO, show_umcast, set_umcast);
+
+int ipoib_add_umcast_attr(struct net_device *dev)
+{
+        return device_create_file(&dev->dev, &dev_attr_umcast);
+}
+
 static void set_tx_csum(struct net_device *dev, struct ib_device *hca)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -1233,6 +1272,8 @@ static struct net_device *ipoib_add_port
 		goto sysfs_failed;
 	if (ipoib_add_pkey_attr(priv->dev))
 		goto sysfs_failed;
+	if (ipoib_add_umcast_attr(priv->dev))
+		goto sysfs_failed;
 	if (device_create_file(&priv->dev->dev, &dev_attr_create_child))
 		goto sysfs_failed;
 	if (device_create_file(&priv->dev->dev, &dev_attr_delete_child))
Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
===================================================================
--- ofa_1_3_dev_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_vlan.c	2007-10-14 17:46:43.000000000 +0200
+++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_vlan.c	2007-10-14 17:57:10.000000000 +0200
@@ -119,6 +119,8 @@ int ipoib_vlan_add(struct net_device *pd
 		goto sysfs_failed;
 	if (ipoib_add_pkey_attr(priv->dev))
 		goto sysfs_failed;
+	if (ipoib_add_umcast_attr(priv->dev))
+		goto sysfs_failed;
 
 	if (device_create_file(&priv->dev->dev, &dev_attr_parent))
 		goto sysfs_failed;




More information about the general mailing list