diff options
| author | Moni Shoua <monis@mellanox.com> | 2013-12-12 11:03:12 -0500 |
|---|---|---|
| committer | Roland Dreier <roland@purestorage.com> | 2014-01-18 17:12:35 -0500 |
| commit | 7b85627b9f02f9b0fb2ef5f021807f4251135857 (patch) | |
| tree | 46c6c152799067cd4c8a1813a76de58c45c389e9 /include/rdma | |
| parent | dd5f03beb4f76ae65d76d8c22a8815e424fc607c (diff) | |
IB/cma: IBoE (RoCE) IP-based GID addressing
Currently, the IB core and specifically the RDMA-CM assumes that IBoE
(RoCE) gids encode related Ethernet netdevice interface MAC address
and possibly VLAN id.
Change GIDs to be treated as they encode interface IP address.
Since Ethernet layer 2 address parameters are not longer encoded
within gids, we have to extend the Infiniband address structures (e.g.
ib_ah_attr) with layer 2 address parameters, namely mac and vlan.
Signed-off-by: Moni Shoua <monis@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'include/rdma')
| -rw-r--r-- | include/rdma/ib_addr.h | 35 |
1 files changed, 12 insertions, 23 deletions
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index a0715606ebb2..ce55906b54a0 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h | |||
| @@ -38,8 +38,12 @@ | |||
| 38 | #include <linux/in6.h> | 38 | #include <linux/in6.h> |
| 39 | #include <linux/if_arp.h> | 39 | #include <linux/if_arp.h> |
| 40 | #include <linux/netdevice.h> | 40 | #include <linux/netdevice.h> |
| 41 | #include <linux/inetdevice.h> | ||
| 41 | #include <linux/socket.h> | 42 | #include <linux/socket.h> |
| 42 | #include <linux/if_vlan.h> | 43 | #include <linux/if_vlan.h> |
| 44 | #include <net/ipv6.h> | ||
| 45 | #include <net/if_inet6.h> | ||
| 46 | #include <net/ip.h> | ||
| 43 | #include <rdma/ib_verbs.h> | 47 | #include <rdma/ib_verbs.h> |
| 44 | #include <rdma/ib_pack.h> | 48 | #include <rdma/ib_pack.h> |
| 45 | #include <net/ipv6.h> | 49 | #include <net/ipv6.h> |
| @@ -132,20 +136,10 @@ static inline int rdma_addr_gid_offset(struct rdma_dev_addr *dev_addr) | |||
| 132 | return dev_addr->dev_type == ARPHRD_INFINIBAND ? 4 : 0; | 136 | return dev_addr->dev_type == ARPHRD_INFINIBAND ? 4 : 0; |
| 133 | } | 137 | } |
| 134 | 138 | ||
| 135 | static inline void iboe_mac_vlan_to_ll(union ib_gid *gid, u8 *mac, u16 vid) | 139 | static inline u16 rdma_vlan_dev_vlan_id(const struct net_device *dev) |
| 136 | { | 140 | { |
| 137 | memset(gid->raw, 0, 16); | 141 | return dev->priv_flags & IFF_802_1Q_VLAN ? |
| 138 | *((__be32 *) gid->raw) = cpu_to_be32(0xfe800000); | 142 | vlan_dev_vlan_id(dev) : 0xffff; |
| 139 | if (vid < 0x1000) { | ||
| 140 | gid->raw[12] = vid & 0xff; | ||
| 141 | gid->raw[11] = vid >> 8; | ||
| 142 | } else { | ||
| 143 | gid->raw[12] = 0xfe; | ||
| 144 | gid->raw[11] = 0xff; | ||
| 145 | } | ||
| 146 | memcpy(gid->raw + 13, mac + 3, 3); | ||
| 147 | memcpy(gid->raw + 8, mac, 3); | ||
| 148 | gid->raw[8] ^= 2; | ||
| 149 | } | 143 | } |
| 150 | 144 | ||
| 151 | static inline int rdma_ip2gid(struct sockaddr *addr, union ib_gid *gid) | 145 | static inline int rdma_ip2gid(struct sockaddr *addr, union ib_gid *gid) |
| @@ -182,25 +176,20 @@ static inline int rdma_gid2ip(struct sockaddr *out, union ib_gid *gid) | |||
| 182 | return 0; | 176 | return 0; |
| 183 | } | 177 | } |
| 184 | 178 | ||
| 185 | static inline u16 rdma_vlan_dev_vlan_id(const struct net_device *dev) | ||
| 186 | { | ||
| 187 | return dev->priv_flags & IFF_802_1Q_VLAN ? | ||
| 188 | vlan_dev_vlan_id(dev) : 0xffff; | ||
| 189 | } | ||
| 190 | |||
| 191 | static inline void iboe_addr_get_sgid(struct rdma_dev_addr *dev_addr, | 179 | static inline void iboe_addr_get_sgid(struct rdma_dev_addr *dev_addr, |
| 192 | union ib_gid *gid) | 180 | union ib_gid *gid) |
| 193 | { | 181 | { |
| 194 | struct net_device *dev; | 182 | struct net_device *dev; |
| 195 | u16 vid = 0xffff; | 183 | struct in_device *ip4; |
| 196 | 184 | ||
| 197 | dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if); | 185 | dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if); |
| 198 | if (dev) { | 186 | if (dev) { |
| 199 | vid = rdma_vlan_dev_vlan_id(dev); | 187 | ip4 = (struct in_device *)dev->ip_ptr; |
| 188 | if (ip4 && ip4->ifa_list && ip4->ifa_list->ifa_address) | ||
| 189 | ipv6_addr_set_v4mapped(ip4->ifa_list->ifa_address, | ||
| 190 | (struct in6_addr *)gid); | ||
| 200 | dev_put(dev); | 191 | dev_put(dev); |
| 201 | } | 192 | } |
| 202 | |||
| 203 | iboe_mac_vlan_to_ll(gid, dev_addr->src_dev_addr, vid); | ||
| 204 | } | 193 | } |
| 205 | 194 | ||
| 206 | static inline void rdma_addr_get_sgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid) | 195 | static inline void rdma_addr_get_sgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid) |
