Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 24d44a39 authored by Steve Wise's avatar Steve Wise Committed by Roland Dreier
Browse files

RDMA/cma: Add IPv6 support for iWARP



Modify the type of local_addr and remote_addr fields in struct
iw_cm_id from struct sockaddr_in to struct sockaddr_storage to hold
IPv6 and IPv4 addresses uniformly.

Change the references of local_addr and remote_addr in cxgb4, cxgb3,
nes and amso drivers to match this.  However to be able to actully run
traffic over IPv6, low-level drivers have to add code to support this.

Signed-off-by: default avatarSteve Wise <swise@opengridcomputing.com>
Reviewed-by: default avatarSean Hefty <sean.hefty@intel.com>

[ Fix unused variable warnings when INFINIBAND_NES_DEBUG not set.
  - Roland ]

Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent c095ba72
Loading
Loading
Loading
Loading
+17 −27
Original line number Diff line number Diff line
@@ -1385,8 +1385,9 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event)
{
	struct rdma_id_private *id_priv = iw_id->context;
	struct rdma_cm_event event;
	struct sockaddr_in *sin;
	int ret = 0;
	struct sockaddr *laddr = (struct sockaddr *)&iw_event->local_addr;
	struct sockaddr *raddr = (struct sockaddr *)&iw_event->remote_addr;

	if (cma_disable_callback(id_priv, RDMA_CM_CONNECT))
		return 0;
@@ -1397,10 +1398,10 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event)
		event.event = RDMA_CM_EVENT_DISCONNECTED;
		break;
	case IW_CM_EVENT_CONNECT_REPLY:
		sin = (struct sockaddr_in *) cma_src_addr(id_priv);
		*sin = iw_event->local_addr;
		sin = (struct sockaddr_in *) cma_dst_addr(id_priv);
		*sin = iw_event->remote_addr;
		memcpy(cma_src_addr(id_priv), laddr,
		       rdma_addr_size(laddr));
		memcpy(cma_dst_addr(id_priv), raddr,
		       rdma_addr_size(raddr));
		switch (iw_event->status) {
		case 0:
			event.event = RDMA_CM_EVENT_ESTABLISHED;
@@ -1450,11 +1451,12 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
{
	struct rdma_cm_id *new_cm_id;
	struct rdma_id_private *listen_id, *conn_id;
	struct sockaddr_in *sin;
	struct net_device *dev = NULL;
	struct rdma_cm_event event;
	int ret;
	struct ib_device_attr attr;
	struct sockaddr *laddr = (struct sockaddr *)&iw_event->local_addr;
	struct sockaddr *raddr = (struct sockaddr *)&iw_event->remote_addr;

	listen_id = cm_id->context;
	if (cma_disable_callback(listen_id, RDMA_CM_LISTEN))
@@ -1472,14 +1474,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
	mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING);
	conn_id->state = RDMA_CM_CONNECT;

	dev = ip_dev_find(&init_net, iw_event->local_addr.sin_addr.s_addr);
	if (!dev) {
		ret = -EADDRNOTAVAIL;
		mutex_unlock(&conn_id->handler_mutex);
		rdma_destroy_id(new_cm_id);
		goto out;
	}
	ret = rdma_copy_addr(&conn_id->id.route.addr.dev_addr, dev, NULL);
	ret = rdma_translate_ip(laddr, &conn_id->id.route.addr.dev_addr);
	if (ret) {
		mutex_unlock(&conn_id->handler_mutex);
		rdma_destroy_id(new_cm_id);
@@ -1497,10 +1492,8 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
	cm_id->context = conn_id;
	cm_id->cm_handler = cma_iw_handler;

	sin = (struct sockaddr_in *) cma_src_addr(conn_id);
	*sin = iw_event->local_addr;
	sin = (struct sockaddr_in *) cma_dst_addr(conn_id);
	*sin = iw_event->remote_addr;
	memcpy(cma_src_addr(conn_id), laddr, rdma_addr_size(laddr));
	memcpy(cma_dst_addr(conn_id), raddr, rdma_addr_size(raddr));

	ret = ib_query_device(conn_id->id.device, &attr);
	if (ret) {
@@ -1576,7 +1569,6 @@ static int cma_ib_listen(struct rdma_id_private *id_priv)
static int cma_iw_listen(struct rdma_id_private *id_priv, int backlog)
{
	int ret;
	struct sockaddr_in *sin;
	struct iw_cm_id	*id;

	id = iw_create_cm_id(id_priv->id.device,
@@ -1587,8 +1579,8 @@ static int cma_iw_listen(struct rdma_id_private *id_priv, int backlog)

	id_priv->cm_id.iw = id;

	sin = (struct sockaddr_in *) cma_src_addr(id_priv);
	id_priv->cm_id.iw->local_addr = *sin;
	memcpy(&id_priv->cm_id.iw->local_addr, cma_src_addr(id_priv),
	       rdma_addr_size(cma_src_addr(id_priv)));

	ret = iw_cm_listen(id_priv->cm_id.iw, backlog);

@@ -2803,7 +2795,6 @@ static int cma_connect_iw(struct rdma_id_private *id_priv,
			  struct rdma_conn_param *conn_param)
{
	struct iw_cm_id *cm_id;
	struct sockaddr_in* sin;
	int ret;
	struct iw_cm_conn_param iw_param;

@@ -2813,11 +2804,10 @@ static int cma_connect_iw(struct rdma_id_private *id_priv,

	id_priv->cm_id.iw = cm_id;

	sin = (struct sockaddr_in *) cma_src_addr(id_priv);
	cm_id->local_addr = *sin;

	sin = (struct sockaddr_in *) cma_dst_addr(id_priv);
	cm_id->remote_addr = *sin;
	memcpy(&cm_id->local_addr, cma_src_addr(id_priv),
	       rdma_addr_size(cma_src_addr(id_priv)));
	memcpy(&cm_id->remote_addr, cma_dst_addr(id_priv),
	       rdma_addr_size(cma_dst_addr(id_priv)));

	ret = cma_modify_qp_rtr(id_priv, conn_param);
	if (ret)
+10 −8
Original line number Diff line number Diff line
@@ -155,6 +155,8 @@ void c2_ae_event(struct c2_dev *c2dev, u32 mq_index)
	enum c2_event_id event_id;
	unsigned long flags;
	int status;
	struct sockaddr_in *laddr = (struct sockaddr_in *)&cm_event.local_addr;
	struct sockaddr_in *raddr = (struct sockaddr_in *)&cm_event.remote_addr;

	/*
	 * retrieve the message
@@ -206,10 +208,10 @@ void c2_ae_event(struct c2_dev *c2dev, u32 mq_index)
		case CCAE_ACTIVE_CONNECT_RESULTS:
			res = &wr->ae.ae_active_connect_results;
			cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
			cm_event.local_addr.sin_addr.s_addr = res->laddr;
			cm_event.remote_addr.sin_addr.s_addr = res->raddr;
			cm_event.local_addr.sin_port = res->lport;
			cm_event.remote_addr.sin_port =	res->rport;
			laddr->sin_addr.s_addr = res->laddr;
			raddr->sin_addr.s_addr = res->raddr;
			laddr->sin_port = res->lport;
			raddr->sin_port = res->rport;
			if (status == 0) {
				cm_event.private_data_len =
					be32_to_cpu(res->private_data_length);
@@ -281,10 +283,10 @@ void c2_ae_event(struct c2_dev *c2dev, u32 mq_index)
		}
		cm_event.event = IW_CM_EVENT_CONNECT_REQUEST;
		cm_event.provider_data = (void*)(unsigned long)req->cr_handle;
		cm_event.local_addr.sin_addr.s_addr = req->laddr;
		cm_event.remote_addr.sin_addr.s_addr = req->raddr;
		cm_event.local_addr.sin_port = req->lport;
		cm_event.remote_addr.sin_port = req->rport;
		laddr->sin_addr.s_addr = req->laddr;
		raddr->sin_addr.s_addr = req->raddr;
		laddr->sin_port = req->lport;
		raddr->sin_port = req->rport;
		cm_event.private_data_len =
			be32_to_cpu(req->private_data_length);
		cm_event.private_data = req->private_data;
+12 −4
Original line number Diff line number Diff line
@@ -46,6 +46,10 @@ int c2_llp_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
	struct c2wr_qp_connect_req *wr;	/* variable size needs a malloc. */
	struct c2_vq_req *vq_req;
	int err;
	struct sockaddr_in *raddr = (struct sockaddr_in *)&cm_id->remote_addr;

	if (cm_id->remote_addr.ss_family != AF_INET)
		return -ENOSYS;

	ibqp = c2_get_qp(cm_id->device, iw_param->qpn);
	if (!ibqp)
@@ -91,8 +95,8 @@ int c2_llp_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
	wr->rnic_handle = c2dev->adapter_handle;
	wr->qp_handle = qp->adapter_handle;

	wr->remote_addr = cm_id->remote_addr.sin_addr.s_addr;
	wr->remote_port = cm_id->remote_addr.sin_port;
	wr->remote_addr = raddr->sin_addr.s_addr;
	wr->remote_port = raddr->sin_port;

	/*
	 * Move any private data from the callers's buf into
@@ -135,6 +139,10 @@ int c2_llp_service_create(struct iw_cm_id *cm_id, int backlog)
	struct c2wr_ep_listen_create_rep *reply;
	struct c2_vq_req *vq_req;
	int err;
	struct sockaddr_in *laddr = (struct sockaddr_in *)&cm_id->local_addr;

	if (cm_id->local_addr.ss_family != AF_INET)
		return -ENOSYS;

	c2dev = to_c2dev(cm_id->device);
	if (c2dev == NULL)
@@ -153,8 +161,8 @@ int c2_llp_service_create(struct iw_cm_id *cm_id, int backlog)
	c2_wr_set_id(&wr, CCWR_EP_LISTEN_CREATE);
	wr.hdr.context = (u64) (unsigned long) vq_req;
	wr.rnic_handle = c2dev->adapter_handle;
	wr.local_addr = cm_id->local_addr.sin_addr.s_addr;
	wr.local_port = cm_id->local_addr.sin_port;
	wr.local_addr = laddr->sin_addr.s_addr;
	wr.local_port = laddr->sin_port;
	wr.backlog = cpu_to_be32(backlog);
	wr.user_context = (u64) (unsigned long) cm_id;

+32 −14
Original line number Diff line number Diff line
@@ -721,8 +721,10 @@ static void connect_reply_upcall(struct iwch_ep *ep, int status)
	memset(&event, 0, sizeof(event));
	event.event = IW_CM_EVENT_CONNECT_REPLY;
	event.status = status;
	event.local_addr = ep->com.local_addr;
	event.remote_addr = ep->com.remote_addr;
	memcpy(&event.local_addr, &ep->com.local_addr,
	       sizeof(ep->com.local_addr));
	memcpy(&event.remote_addr, &ep->com.remote_addr,
	       sizeof(ep->com.remote_addr));

	if ((status == 0) || (status == -ECONNREFUSED)) {
		event.private_data_len = ep->plen;
@@ -747,8 +749,10 @@ static void connect_request_upcall(struct iwch_ep *ep)
	PDBG("%s ep %p tid %d\n", __func__, ep, ep->hwtid);
	memset(&event, 0, sizeof(event));
	event.event = IW_CM_EVENT_CONNECT_REQUEST;
	event.local_addr = ep->com.local_addr;
	event.remote_addr = ep->com.remote_addr;
	memcpy(&event.local_addr, &ep->com.local_addr,
	       sizeof(ep->com.local_addr));
	memcpy(&event.remote_addr, &ep->com.remote_addr,
	       sizeof(ep->com.local_addr));
	event.private_data_len = ep->plen;
	event.private_data = ep->mpa_pkt + sizeof(struct mpa_message);
	event.provider_data = ep;
@@ -1872,8 +1876,9 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
static int is_loopback_dst(struct iw_cm_id *cm_id)
{
	struct net_device *dev;
	struct sockaddr_in *raddr = (struct sockaddr_in *)&cm_id->remote_addr;

	dev = ip_dev_find(&init_net, cm_id->remote_addr.sin_addr.s_addr);
	dev = ip_dev_find(&init_net, raddr->sin_addr.s_addr);
	if (!dev)
		return 0;
	dev_put(dev);
@@ -1886,6 +1891,13 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
	struct iwch_ep *ep;
	struct rtable *rt;
	int err = 0;
	struct sockaddr_in *laddr = (struct sockaddr_in *)&cm_id->local_addr;
	struct sockaddr_in *raddr = (struct sockaddr_in *)&cm_id->remote_addr;

	if (cm_id->remote_addr.ss_family != PF_INET) {
		err = -ENOSYS;
		goto out;
	}

	if (is_loopback_dst(cm_id)) {
		err = -ENOSYS;
@@ -1929,11 +1941,9 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
	}

	/* find a route */
	rt = find_route(h->rdev.t3cdev_p,
			cm_id->local_addr.sin_addr.s_addr,
			cm_id->remote_addr.sin_addr.s_addr,
			cm_id->local_addr.sin_port,
			cm_id->remote_addr.sin_port, IPTOS_LOWDELAY);
	rt = find_route(h->rdev.t3cdev_p, laddr->sin_addr.s_addr,
			raddr->sin_addr.s_addr, laddr->sin_port,
			raddr->sin_port, IPTOS_LOWDELAY);
	if (!rt) {
		printk(KERN_ERR MOD "%s - cannot find route.\n", __func__);
		err = -EHOSTUNREACH;
@@ -1941,7 +1951,7 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
	}
	ep->dst = &rt->dst;
	ep->l2t = t3_l2t_get(ep->com.tdev, ep->dst, NULL,
			     &cm_id->remote_addr.sin_addr.s_addr);
			     &raddr->sin_addr.s_addr);
	if (!ep->l2t) {
		printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
		err = -ENOMEM;
@@ -1950,8 +1960,10 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)

	state_set(&ep->com, CONNECTING);
	ep->tos = IPTOS_LOWDELAY;
	ep->com.local_addr = cm_id->local_addr;
	ep->com.remote_addr = cm_id->remote_addr;
	memcpy(&ep->com.local_addr, &cm_id->local_addr,
	       sizeof(ep->com.local_addr));
	memcpy(&ep->com.remote_addr, &cm_id->remote_addr,
	       sizeof(ep->com.remote_addr));

	/* send connect request to rnic */
	err = send_connect(ep);
@@ -1979,6 +1991,11 @@ int iwch_create_listen(struct iw_cm_id *cm_id, int backlog)

	might_sleep();

	if (cm_id->local_addr.ss_family != PF_INET) {
		err = -ENOSYS;
		goto fail1;
	}

	ep = alloc_ep(sizeof(*ep), GFP_KERNEL);
	if (!ep) {
		printk(KERN_ERR MOD "%s - cannot alloc ep.\n", __func__);
@@ -1990,7 +2007,8 @@ int iwch_create_listen(struct iw_cm_id *cm_id, int backlog)
	cm_id->add_ref(cm_id);
	ep->com.cm_id = cm_id;
	ep->backlog = backlog;
	ep->com.local_addr = cm_id->local_addr;
	memcpy(&ep->com.local_addr, &cm_id->local_addr,
	       sizeof(ep->com.local_addr));

	/*
	 * Allocate a server TID.
+29 −26
Original line number Diff line number Diff line
@@ -952,8 +952,10 @@ static void connect_reply_upcall(struct c4iw_ep *ep, int status)
	memset(&event, 0, sizeof(event));
	event.event = IW_CM_EVENT_CONNECT_REPLY;
	event.status = status;
	event.local_addr = ep->com.local_addr;
	event.remote_addr = ep->com.remote_addr;
	memcpy(&event.local_addr, &ep->com.local_addr,
	       sizeof(ep->com.local_addr));
	memcpy(&event.remote_addr, &ep->com.remote_addr,
	       sizeof(ep->com.remote_addr));

	if ((status == 0) || (status == -ECONNREFUSED)) {
		if (!ep->tried_with_mpa_v1) {
@@ -989,8 +991,10 @@ static void connect_request_upcall(struct c4iw_ep *ep)
	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
	memset(&event, 0, sizeof(event));
	event.event = IW_CM_EVENT_CONNECT_REQUEST;
	event.local_addr = ep->com.local_addr;
	event.remote_addr = ep->com.remote_addr;
	memcpy(&event.local_addr, &ep->com.local_addr,
	       sizeof(ep->com.local_addr));
	memcpy(&event.remote_addr, &ep->com.remote_addr,
	       sizeof(ep->com.remote_addr));
	event.provider_data = ep;
	if (!ep->tried_with_mpa_v1) {
		/* this means MPA_v2 is used */
@@ -1568,6 +1572,10 @@ static int c4iw_reconnect(struct c4iw_ep *ep)
	struct net_device *pdev;
	int step;
	struct neighbour *neigh;
	struct sockaddr_in *laddr = (struct sockaddr_in *)
				    &ep->com.cm_id->local_addr;
	struct sockaddr_in *raddr = (struct sockaddr_in *)
				    &ep->com.cm_id->remote_addr;

	PDBG("%s qp %p cm_id %p\n", __func__, ep->com.qp, ep->com.cm_id);
	init_timer(&ep->timer);
@@ -1585,10 +1593,8 @@ static int c4iw_reconnect(struct c4iw_ep *ep)

	/* find a route */
	rt = find_route(ep->com.dev,
			ep->com.cm_id->local_addr.sin_addr.s_addr,
			ep->com.cm_id->remote_addr.sin_addr.s_addr,
			ep->com.cm_id->local_addr.sin_port,
			ep->com.cm_id->remote_addr.sin_port, 0);
			laddr->sin_addr.s_addr, raddr->sin_addr.s_addr,
			laddr->sin_port, raddr->sin_port, 0);
	if (!rt) {
		pr_err("%s - cannot find route.\n", __func__);
		err = -EHOSTUNREACH;
@@ -1596,8 +1602,7 @@ static int c4iw_reconnect(struct c4iw_ep *ep)
	}
	ep->dst = &rt->dst;

	neigh = dst_neigh_lookup(ep->dst,
			&ep->com.cm_id->remote_addr.sin_addr.s_addr);
	neigh = dst_neigh_lookup(ep->dst, &raddr->sin_addr.s_addr);
	if (!neigh) {
		pr_err("%s - cannot alloc neigh.\n", __func__);
		err = -ENOMEM;
@@ -1607,8 +1612,7 @@ static int c4iw_reconnect(struct c4iw_ep *ep)
	/* get a l2t entry */
	if (neigh->dev->flags & IFF_LOOPBACK) {
		PDBG("%s LOOPBACK\n", __func__);
		pdev = ip_dev_find(&init_net,
				ep->com.cm_id->remote_addr.sin_addr.s_addr);
		pdev = ip_dev_find(&init_net, raddr->sin_addr.s_addr);
		ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t,
				neigh, pdev, 0);
		pi = (struct port_info *)netdev_priv(pdev);
@@ -2518,6 +2522,8 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
	struct c4iw_ep *ep;
	struct rtable *rt;
	int err = 0;
	struct sockaddr_in *laddr = (struct sockaddr_in *)&cm_id->local_addr;
	struct sockaddr_in *raddr = (struct sockaddr_in *)&cm_id->remote_addr;

	if ((conn_param->ord > c4iw_max_read_depth) ||
	    (conn_param->ird > c4iw_max_read_depth)) {
@@ -2562,17 +2568,12 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
	insert_handle(dev, &dev->atid_idr, ep, ep->atid);

	PDBG("%s saddr 0x%x sport 0x%x raddr 0x%x rport 0x%x\n", __func__,
	     ntohl(cm_id->local_addr.sin_addr.s_addr),
	     ntohs(cm_id->local_addr.sin_port),
	     ntohl(cm_id->remote_addr.sin_addr.s_addr),
	     ntohs(cm_id->remote_addr.sin_port));
	     ntohl(laddr->sin_addr.s_addr), ntohs(laddr->sin_port),
	     ntohl(raddr->sin_addr.s_addr), ntohs(raddr->sin_port));

	/* find a route */
	rt = find_route(dev,
			cm_id->local_addr.sin_addr.s_addr,
			cm_id->remote_addr.sin_addr.s_addr,
			cm_id->local_addr.sin_port,
			cm_id->remote_addr.sin_port, 0);
	rt = find_route(dev, laddr->sin_addr.s_addr, raddr->sin_addr.s_addr,
			laddr->sin_port, raddr->sin_port, 0);
	if (!rt) {
		printk(KERN_ERR MOD "%s - cannot find route.\n", __func__);
		err = -EHOSTUNREACH;
@@ -2580,8 +2581,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
	}
	ep->dst = &rt->dst;

	err = import_ep(ep, cm_id->remote_addr.sin_addr.s_addr,
			ep->dst, ep->com.dev, true);
	err = import_ep(ep, raddr->sin_addr.s_addr, ep->dst, ep->com.dev, true);
	if (err) {
		printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
		goto fail4;
@@ -2593,8 +2593,10 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)

	state_set(&ep->com, CONNECTING);
	ep->tos = 0;
	ep->com.local_addr = cm_id->local_addr;
	ep->com.remote_addr = cm_id->remote_addr;
	memcpy(&ep->com.local_addr, &cm_id->local_addr,
	       sizeof(ep->com.local_addr));
	memcpy(&ep->com.remote_addr, &cm_id->remote_addr,
	       sizeof(ep->com.remote_addr));

	/* send connect request to rnic */
	err = send_connect(ep);
@@ -2633,7 +2635,8 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog)
	ep->com.cm_id = cm_id;
	ep->com.dev = dev;
	ep->backlog = backlog;
	ep->com.local_addr = cm_id->local_addr;
	memcpy(&ep->com.local_addr, &cm_id->local_addr,
	       sizeof(ep->com.local_addr));

	/*
	 * Allocate a server TID.
Loading