[ofa-general] [PATCH RFC] IB/ipoib: enable IGMP for userpsace multicast IB apps
Or Gerlitz
ogerlitz at voltaire.com
Sun Sep 2 05:04:12 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 this multicast traffic.
This patch does a lookup on the database used for multicast reference counting
and enhances IPoIB to ignore mulicast 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/attach its QP to a
multicast group which has an entry on the database. The default value is "disallowed",
where through /sys/class/net/$dev/umcast one can allow/disallow and read it.
Signed-off-by: Or Gerlitz <ogerlitz at voltaire.com>
Index: linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
===================================================================
--- linux-2.6.23-rc5.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 2007-07-09 02:32:17.000000000 +0300
+++ linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 2007-09-02 13:46:29.000000000 +0300
@@ -783,6 +783,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");
@@ -816,6 +817,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_ALLOW_UMCAST, &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: linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib.h
===================================================================
--- linux-2.6.23-rc5.orig/drivers/infiniband/ulp/ipoib/ipoib.h 2007-07-09 02:32:17.000000000 +0300
+++ linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib.h 2007-09-02 13:46:29.000000000 +0300
@@ -86,6 +86,7 @@ enum {
IPOIB_MCAST_STARTED = 8,
IPOIB_FLAG_NETIF_STOPPED = 9,
IPOIB_FLAG_ADMIN_CM = 10,
+ IPOIB_FLAG_ADMIN_ALLOW_UMCAST = 11,
IPOIB_MAX_BACKOFF_SECONDS = 16,
@@ -364,6 +365,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: linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib_main.c
===================================================================
--- linux-2.6.23-rc5.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c 2007-07-09 02:32:17.000000000 +0300
+++ linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib_main.c 2007-09-02 14:01:33.000000000 +0300
@@ -1017,6 +1017,44 @@ static ssize_t show_pkey(struct device *
}
static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
+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_ALLOW_UMCAST, &priv->flags))
+ return sprintf(buf, "allowed\n");
+ else
+ return sprintf(buf, "disallowed\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));
+
+ if (!strcmp(buf, "allowed\n")) {
+ set_bit(IPOIB_FLAG_ADMIN_ALLOW_UMCAST, &priv->flags);
+ ipoib_warn(priv, "ignoring multicast groups joined directly "
+ "by user space\n");
+ return count;
+ }
+
+ if (!strcmp(buf, "disallowed\n")) {
+ clear_bit(IPOIB_FLAG_ADMIN_ALLOW_UMCAST, &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 ssize_t create_child(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -1134,6 +1172,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: linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
===================================================================
--- linux-2.6.23-rc5.orig/drivers/infiniband/ulp/ipoib/ipoib_vlan.c 2007-07-09 02:32:17.000000000 +0300
+++ linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib_vlan.c 2007-09-02 13:46:29.000000000 +0300
@@ -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