An ipoib subnet on an IB fabric that spans multiple IB subnets can't use
link-local scope in multicast GIDs.  This patch takes the scope from the
link level broadcast address of the ipoib device when mapping to an IB
multicast address.

Signed-off-by: Rolf Manderscheid <[EMAIL PROTECTED]>

---

diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 9ffb998..2fd1b30 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -2560,7 +2560,7 @@ static void cma_set_mgid(struct rdma_id_private *id_priv,
                /* IPv6 address is an SA assigned MGID. */
                memcpy(mgid, &sin6->sin6_addr, sizeof *mgid);
        } else {
-               ip_ib_mc_map(sin->sin_addr.s_addr, mc_map);
+               ip_ib_mc_map(sin->sin_addr.s_addr, dev_addr->broadcast, mc_map);
                if (id_priv->id.ps == RDMA_PS_UDP)
                        mc_map[7] = 0x01;       /* Use RDMA CM signature */
                mc_map[8] = ib_addr_get_pkey(dev_addr) >> 8;
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 3ec7d07..b636221 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -268,14 +268,17 @@ static inline void ipv6_arcnet_mc_map(const struct 
in6_addr *addr, char *buf)
        buf[0] = 0x00;
 }
 
-static inline void ipv6_ib_mc_map(struct in6_addr *addr, char *buf)
+static inline void ipv6_ib_mc_map(const struct in6_addr *addr,
+                                 const unsigned char *broadcast, char *buf)
 {
+       unsigned char scope = broadcast[5] & 0xF;
+
        buf[0]  = 0;            /* Reserved */
        buf[1]  = 0xff;         /* Multicast QPN */
        buf[2]  = 0xff;
        buf[3]  = 0xff;
        buf[4]  = 0xff;
-       buf[5]  = 0x12;         /* link local scope */
+       buf[5]  = 0x10 | scope; /* scope from broadcast address */
        buf[6]  = 0x60;         /* IPv6 signature */
        buf[7]  = 0x1b;
        buf[8]  = 0;            /* P_Key */
diff --git a/include/net/ip.h b/include/net/ip.h
index abf2820..fbb4dd0 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -266,16 +266,18 @@ static inline void ip_eth_mc_map(__be32 naddr, char *buf)
  *     Leave P_Key as 0 to be filled in by driver.
  */
 
-static inline void ip_ib_mc_map(__be32 naddr, char *buf)
+static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, 
char *buf)
 {
        __u32 addr;
+       unsigned char scope = broadcast[5] & 0xF;
+
        buf[0]  = 0;            /* Reserved */
        buf[1]  = 0xff;         /* Multicast QPN */
        buf[2]  = 0xff;
        buf[3]  = 0xff;
        addr    = ntohl(naddr);
        buf[4]  = 0xff;
-       buf[5]  = 0x12;         /* link local scope */
+       buf[5]  = 0x10 | scope; /* scope from broadcast address */
        buf[6]  = 0x40;         /* IPv4 signature */
        buf[7]  = 0x1b;
        buf[8]  = 0;            /* P_Key */
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 9ab9d53..feb643c 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -214,7 +214,7 @@ int arp_mc_map(__be32 addr, u8 *haddr, struct net_device 
*dev, int dir)
                ip_tr_mc_map(addr, haddr);
                return 0;
        case ARPHRD_INFINIBAND:
-               ip_ib_mc_map(addr, haddr);
+               ip_ib_mc_map(addr, dev->broadcast, haddr);
                return 0;
        default:
                if (dir) {
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 0358e60..8275625 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -308,7 +308,7 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct 
net_device *dev, int d
                ipv6_arcnet_mc_map(addr, buf);
                return 0;
        case ARPHRD_INFINIBAND:
-               ipv6_ib_mc_map(addr, buf);
+               ipv6_ib_mc_map(addr, dev->broadcast, buf);
                return 0;
        default:
                if (dir) {
_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to