IPoIB: improve IPv4/IPv6 to IB mcast mapping functions
Subsystems (4)
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
RFC PATCH 1/1 IPoIB: improve IPv4/IPv6 to IB mcast mapping functions
Any objection to merging the following for 2.6.25?
[Rolf -- I think it makes more sense to delete the overwriting of the P_Key in ipoib_multicast.c in this patch rather than later in the series; do you agree?]
Thanks,
Roland
From: Rolf Manderscheid <[email protected]>
An IPoIB subnet on an IB fabric that spans multiple IB subnets can't use link-local scope in multicast GIDs. The existing routines that map IP/IPv6 multicast addresses into IB link-level addresses hard-code the scope to link-local, and they also leave the partition key field uninitialised. This patch adds a parameter (the link-level broadcast address) to the mapping routines, allowing them to initialise both the scope and the P_Key appropriately, and fixes up the call sites.
The next step will be to add a way to configure the scope for an IPoIB interface.
--- drivers/infiniband/core/cma.c | 4 +--- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 4 ---- include/net/if_inet6.h | 11 +++++++---- include/net/ip.h | 10 ++++++---- net/ipv4/arp.c | 2 +- net/ipv6/ndisc.c | 2 +- 6 files changed, 16 insertions(+), 17 deletions(-)
drivers/infiniband/core/cma.c +1 -3
@@ -2610,11 +2610,9 @@ 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 ; - mc_map[9 ] = (unsigned char )ib_addr_get_pkey (dev_addr); *mgid = *(union ib_gid *) (mc_map +4 ); } }
drivers/infiniband/ulp/ipoib/ipoib_multicast.c +0 -4
@@ -788,10 +788,6 @@ 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 ; - mcast =__ipoib_mcast_find (dev, &mgid);if (!mcast ||test_bit (IPOIB_MCAST_FLAG_SENDONLY , &mcast->flags)) {struct ipoib_mcast *nmcast;
include/net/if_inet6.h +7 -4
@@ -269,18 +269,21 @@ 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 */ - buf[9 ] =0 ; + buf[8 ] = broadcast[8 ];/* P_Key */ + buf[9 ] = broadcast[9 ];memcpy (buf +10 , addr->s6_addr +6 ,10 ); }#endif
include/net/ip.h +6 -4
@@ -266,20 +266,22 @@ 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 */ - buf[9 ] =0 ; + buf[8 ] = broadcast[8 ];/* P_Key */ + buf[9 ] = broadcast[9 ]; buf[10 ] =0 ; buf[11 ] =0 ; buf[12 ] =0 ;
net/ipv4/arp.c +1 -1
@@ -211,7 +211,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) {
net/ipv6/ndisc.c +1 -1
@@ -337,7 +337,7 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dipv6_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) {
Signature · 1 line
1.5.4.rc2
Quoted 6 lines · Roland Dreier
Any objection to merging the following for 2.6.25?
[Rolf -- I think it makes more sense to delete the overwriting of the
P_Keyinipoib_multicast.cin this patch rather than later in the series; do you agree?]
Yes, the first patch is the logical place for it. The only reason I put it in the second patch was to keep the first patch as small and simple as possible.
Rolf
David Miller
maintainerFrom: Roland Dreier <[email protected]>
Date: Fri, 04 Jan 2008 14:05:29 -0800
Quoted 1 line
Any objection to merging the following for 2.6.25?
The ipv4/ipv6 bits look fine to me.