Commit c3efe750 authored by Matan Barak's avatar Matan Barak Committed by Doug Ledford

IB/core: Use hop-limit from IP stack for RoCE

Previously, IPV6_DEFAULT_HOPLIMIT was used as the hop limit value for
RoCE. Fixing that by taking ip4_dst_hoplimit and ip6_dst_hoplimit as
hop limit values.
Signed-off-by: default avatarMatan Barak <matanb@mellanox.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent f7f4b23e
...@@ -252,6 +252,8 @@ static int addr4_resolve(struct sockaddr_in *src_in, ...@@ -252,6 +252,8 @@ static int addr4_resolve(struct sockaddr_in *src_in,
if (rt->rt_uses_gateway) if (rt->rt_uses_gateway)
addr->network = RDMA_NETWORK_IPV4; addr->network = RDMA_NETWORK_IPV4;
addr->hoplimit = ip4_dst_hoplimit(&rt->dst);
*prt = rt; *prt = rt;
return 0; return 0;
out: out:
...@@ -295,6 +297,8 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, ...@@ -295,6 +297,8 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
if (rt->rt6i_flags & RTF_GATEWAY) if (rt->rt6i_flags & RTF_GATEWAY)
addr->network = RDMA_NETWORK_IPV6; addr->network = RDMA_NETWORK_IPV6;
addr->hoplimit = ip6_dst_hoplimit(dst);
*pdst = dst; *pdst = dst;
return 0; return 0;
put: put:
...@@ -543,7 +547,8 @@ static void resolve_cb(int status, struct sockaddr *src_addr, ...@@ -543,7 +547,8 @@ static void resolve_cb(int status, struct sockaddr *src_addr,
int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid, int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
const union ib_gid *dgid, const union ib_gid *dgid,
u8 *dmac, u16 *vlan_id, int *if_index) u8 *dmac, u16 *vlan_id, int *if_index,
int *hoplimit)
{ {
int ret = 0; int ret = 0;
struct rdma_dev_addr dev_addr; struct rdma_dev_addr dev_addr;
...@@ -582,6 +587,8 @@ int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid, ...@@ -582,6 +587,8 @@ int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
*if_index = dev_addr.bound_dev_if; *if_index = dev_addr.bound_dev_if;
if (vlan_id) if (vlan_id)
*vlan_id = rdma_vlan_dev_vlan_id(dev); *vlan_id = rdma_vlan_dev_vlan_id(dev);
if (hoplimit)
*hoplimit = dev_addr.hoplimit;
dev_put(dev); dev_put(dev);
return ret; return ret;
} }
......
...@@ -1641,6 +1641,7 @@ static int cm_req_handler(struct cm_work *work) ...@@ -1641,6 +1641,7 @@ static int cm_req_handler(struct cm_work *work)
cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]); cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
memcpy(work->path[0].dmac, cm_id_priv->av.ah_attr.dmac, ETH_ALEN); memcpy(work->path[0].dmac, cm_id_priv->av.ah_attr.dmac, ETH_ALEN);
work->path[0].hop_limit = cm_id_priv->av.ah_attr.grh.hop_limit;
ret = ib_get_cached_gid(work->port->cm_dev->ib_device, ret = ib_get_cached_gid(work->port->cm_dev->ib_device,
work->port->port_num, work->port->port_num,
cm_id_priv->av.ah_attr.grh.sgid_index, cm_id_priv->av.ah_attr.grh.sgid_index,
......
...@@ -2424,7 +2424,6 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) ...@@ -2424,7 +2424,6 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
{ {
struct rdma_route *route = &id_priv->id.route; struct rdma_route *route = &id_priv->id.route;
struct rdma_addr *addr = &route->addr; struct rdma_addr *addr = &route->addr;
enum ib_gid_type network_gid_type;
struct cma_work *work; struct cma_work *work;
int ret; int ret;
struct net_device *ndev = NULL; struct net_device *ndev = NULL;
...@@ -2478,14 +2477,13 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) ...@@ -2478,14 +2477,13 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
&route->path_rec->dgid); &route->path_rec->dgid);
/* Use the hint from IP Stack to select GID Type */ /* Use the hint from IP Stack to select GID Type */
network_gid_type = ib_network_to_gid_type(addr->dev_addr.network); if (route->path_rec->gid_type < ib_network_to_gid_type(addr->dev_addr.network))
if (addr->dev_addr.network != RDMA_NETWORK_IB) { route->path_rec->gid_type = ib_network_to_gid_type(addr->dev_addr.network);
route->path_rec->gid_type = network_gid_type; if (((struct sockaddr *)&id_priv->id.route.addr.dst_addr)->sa_family != AF_IB)
/* TODO: get the hoplimit from the inet/inet6 device */ /* TODO: get the hoplimit from the inet/inet6 device */
route->path_rec->hop_limit = IPV6_DEFAULT_HOPLIMIT; route->path_rec->hop_limit = addr->dev_addr.hoplimit;
} else { else
route->path_rec->hop_limit = 1; route->path_rec->hop_limit = 1;
}
route->path_rec->reversible = 1; route->path_rec->reversible = 1;
route->path_rec->pkey = cpu_to_be16(0xffff); route->path_rec->pkey = cpu_to_be16(0xffff);
route->path_rec->mtu_selector = IB_SA_EQ; route->path_rec->mtu_selector = IB_SA_EQ;
......
...@@ -434,6 +434,7 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, ...@@ -434,6 +434,7 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
int ret; int ret;
enum rdma_network_type net_type = RDMA_NETWORK_IB; enum rdma_network_type net_type = RDMA_NETWORK_IB;
enum ib_gid_type gid_type = IB_GID_TYPE_IB; enum ib_gid_type gid_type = IB_GID_TYPE_IB;
int hoplimit = 0xff;
union ib_gid dgid; union ib_gid dgid;
union ib_gid sgid; union ib_gid sgid;
...@@ -471,7 +472,7 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, ...@@ -471,7 +472,7 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
ah_attr->dmac, ah_attr->dmac,
wc->wc_flags & IB_WC_WITH_VLAN ? wc->wc_flags & IB_WC_WITH_VLAN ?
NULL : &vlan_id, NULL : &vlan_id,
&if_index); &if_index, &hoplimit);
if (ret) { if (ret) {
dev_put(idev); dev_put(idev);
return ret; return ret;
...@@ -520,7 +521,7 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, ...@@ -520,7 +521,7 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
ah_attr->grh.sgid_index = (u8) gid_index; ah_attr->grh.sgid_index = (u8) gid_index;
flow_class = be32_to_cpu(grh->version_tclass_flow); flow_class = be32_to_cpu(grh->version_tclass_flow);
ah_attr->grh.flow_label = flow_class & 0xFFFFF; ah_attr->grh.flow_label = flow_class & 0xFFFFF;
ah_attr->grh.hop_limit = 0xFF; ah_attr->grh.hop_limit = hoplimit;
ah_attr->grh.traffic_class = (flow_class >> 20) & 0xFF; ah_attr->grh.traffic_class = (flow_class >> 20) & 0xFF;
} }
return 0; return 0;
...@@ -1138,6 +1139,7 @@ int ib_resolve_eth_dmac(struct ib_qp *qp, ...@@ -1138,6 +1139,7 @@ int ib_resolve_eth_dmac(struct ib_qp *qp,
union ib_gid sgid; union ib_gid sgid;
struct ib_gid_attr sgid_attr; struct ib_gid_attr sgid_attr;
int ifindex; int ifindex;
int hop_limit;
ret = ib_query_gid(qp->device, ret = ib_query_gid(qp->device,
qp_attr->ah_attr.port_num, qp_attr->ah_attr.port_num,
...@@ -1149,21 +1151,17 @@ int ib_resolve_eth_dmac(struct ib_qp *qp, ...@@ -1149,21 +1151,17 @@ int ib_resolve_eth_dmac(struct ib_qp *qp,
ret = -ENXIO; ret = -ENXIO;
goto out; goto out;
} }
if (sgid_attr.gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP)
/* TODO: get the hoplimit from the inet/inet6
* device
*/
qp_attr->ah_attr.grh.hop_limit =
IPV6_DEFAULT_HOPLIMIT;
ifindex = sgid_attr.ndev->ifindex; ifindex = sgid_attr.ndev->ifindex;
ret = rdma_addr_find_l2_eth_by_grh(&sgid, ret = rdma_addr_find_l2_eth_by_grh(&sgid,
&qp_attr->ah_attr.grh.dgid, &qp_attr->ah_attr.grh.dgid,
qp_attr->ah_attr.dmac, qp_attr->ah_attr.dmac,
NULL, &ifindex); NULL, &ifindex, &hop_limit);
dev_put(sgid_attr.ndev); dev_put(sgid_attr.ndev);
qp_attr->ah_attr.grh.hop_limit = hop_limit;
} }
} }
out: out:
......
...@@ -154,7 +154,8 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr) ...@@ -154,7 +154,8 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
(!rdma_link_local_addr((struct in6_addr *)attr->grh.dgid.raw))) { (!rdma_link_local_addr((struct in6_addr *)attr->grh.dgid.raw))) {
status = rdma_addr_find_l2_eth_by_grh(&sgid, &attr->grh.dgid, status = rdma_addr_find_l2_eth_by_grh(&sgid, &attr->grh.dgid,
attr->dmac, &vlan_tag, attr->dmac, &vlan_tag,
&sgid_attr.ndev->ifindex); &sgid_attr.ndev->ifindex,
NULL);
if (status) { if (status) {
pr_err("%s(): Failed to resolve dmac from gid." pr_err("%s(): Failed to resolve dmac from gid."
"status = %d\n", __func__, status); "status = %d\n", __func__, status);
......
...@@ -84,6 +84,7 @@ struct rdma_dev_addr { ...@@ -84,6 +84,7 @@ struct rdma_dev_addr {
enum rdma_transport_type transport; enum rdma_transport_type transport;
struct net *net; struct net *net;
enum rdma_network_type network; enum rdma_network_type network;
int hoplimit;
}; };
/** /**
...@@ -132,7 +133,8 @@ int rdma_addr_size(struct sockaddr *addr); ...@@ -132,7 +133,8 @@ int rdma_addr_size(struct sockaddr *addr);
int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 *smac, u16 *vlan_id); int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 *smac, u16 *vlan_id);
int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid, int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
const union ib_gid *dgid, const union ib_gid *dgid,
u8 *smac, u16 *vlan_id, int *if_index); u8 *smac, u16 *vlan_id, int *if_index,
int *hoplimit);
static inline u16 ib_addr_get_pkey(struct rdma_dev_addr *dev_addr) static inline u16 ib_addr_get_pkey(struct rdma_dev_addr *dev_addr)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment