Skip to content

Commit 082eaa5

Browse files
committed
Merge branches 'nes', 'cxgb4' and 'iwpm' into k.o/for-4.6
4 parents d2ad9cc + a82268b + 3021376 + dafb558 commit 082eaa5

File tree

23 files changed

+442
-753
lines changed

23 files changed

+442
-753
lines changed

drivers/infiniband/core/iwcm.c

Lines changed: 164 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,25 @@
5050

5151
#include <rdma/iw_cm.h>
5252
#include <rdma/ib_addr.h>
53+
#include <rdma/iw_portmap.h>
54+
#include <rdma/rdma_netlink.h>
5355

5456
#include "iwcm.h"
5557

5658
MODULE_AUTHOR("Tom Tucker");
5759
MODULE_DESCRIPTION("iWARP CM");
5860
MODULE_LICENSE("Dual BSD/GPL");
5961

62+
static struct ibnl_client_cbs iwcm_nl_cb_table[] = {
63+
[RDMA_NL_IWPM_REG_PID] = {.dump = iwpm_register_pid_cb},
64+
[RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb},
65+
[RDMA_NL_IWPM_QUERY_MAPPING] = {.dump = iwpm_add_and_query_mapping_cb},
66+
[RDMA_NL_IWPM_REMOTE_INFO] = {.dump = iwpm_remote_info_cb},
67+
[RDMA_NL_IWPM_HANDLE_ERR] = {.dump = iwpm_mapping_error_cb},
68+
[RDMA_NL_IWPM_MAPINFO] = {.dump = iwpm_mapping_info_cb},
69+
[RDMA_NL_IWPM_MAPINFO_NUM] = {.dump = iwpm_ack_mapping_info_cb}
70+
};
71+
6072
static struct workqueue_struct *iwcm_wq;
6173
struct iwcm_work {
6274
struct work_struct work;
@@ -402,6 +414,11 @@ static void destroy_cm_id(struct iw_cm_id *cm_id)
402414
}
403415
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
404416

417+
if (cm_id->mapped) {
418+
iwpm_remove_mapinfo(&cm_id->local_addr, &cm_id->m_local_addr);
419+
iwpm_remove_mapping(&cm_id->local_addr, RDMA_NL_IWCM);
420+
}
421+
405422
(void)iwcm_deref_id(cm_id_priv);
406423
}
407424

@@ -426,6 +443,97 @@ void iw_destroy_cm_id(struct iw_cm_id *cm_id)
426443
}
427444
EXPORT_SYMBOL(iw_destroy_cm_id);
428445

446+
/**
447+
* iw_cm_check_wildcard - If IP address is 0 then use original
448+
* @pm_addr: sockaddr containing the ip to check for wildcard
449+
* @cm_addr: sockaddr containing the actual IP address
450+
* @cm_outaddr: sockaddr to set IP addr which leaving port
451+
*
452+
* Checks the pm_addr for wildcard and then sets cm_outaddr's
453+
* IP to the actual (cm_addr).
454+
*/
455+
static void iw_cm_check_wildcard(struct sockaddr_storage *pm_addr,
456+
struct sockaddr_storage *cm_addr,
457+
struct sockaddr_storage *cm_outaddr)
458+
{
459+
if (pm_addr->ss_family == AF_INET) {
460+
struct sockaddr_in *pm4_addr = (struct sockaddr_in *)pm_addr;
461+
462+
if (pm4_addr->sin_addr.s_addr == INADDR_ANY) {
463+
struct sockaddr_in *cm4_addr =
464+
(struct sockaddr_in *)cm_addr;
465+
struct sockaddr_in *cm4_outaddr =
466+
(struct sockaddr_in *)cm_outaddr;
467+
468+
cm4_outaddr->sin_addr = cm4_addr->sin_addr;
469+
}
470+
} else {
471+
struct sockaddr_in6 *pm6_addr = (struct sockaddr_in6 *)pm_addr;
472+
473+
if (ipv6_addr_type(&pm6_addr->sin6_addr) == IPV6_ADDR_ANY) {
474+
struct sockaddr_in6 *cm6_addr =
475+
(struct sockaddr_in6 *)cm_addr;
476+
struct sockaddr_in6 *cm6_outaddr =
477+
(struct sockaddr_in6 *)cm_outaddr;
478+
479+
cm6_outaddr->sin6_addr = cm6_addr->sin6_addr;
480+
}
481+
}
482+
}
483+
484+
/**
485+
* iw_cm_map - Use portmapper to map the ports
486+
* @cm_id: connection manager pointer
487+
* @active: Indicates the active side when true
488+
* returns nonzero for error only if iwpm_create_mapinfo() fails
489+
*
490+
* Tries to add a mapping for a port using the Portmapper. If
491+
* successful in mapping the IP/Port it will check the remote
492+
* mapped IP address for a wildcard IP address and replace the
493+
* zero IP address with the remote_addr.
494+
*/
495+
static int iw_cm_map(struct iw_cm_id *cm_id, bool active)
496+
{
497+
struct iwpm_dev_data pm_reg_msg;
498+
struct iwpm_sa_data pm_msg;
499+
int status;
500+
501+
cm_id->m_local_addr = cm_id->local_addr;
502+
cm_id->m_remote_addr = cm_id->remote_addr;
503+
504+
memcpy(pm_reg_msg.dev_name, cm_id->device->name,
505+
sizeof(pm_reg_msg.dev_name));
506+
memcpy(pm_reg_msg.if_name, cm_id->device->iwcm->ifname,
507+
sizeof(pm_reg_msg.if_name));
508+
509+
if (iwpm_register_pid(&pm_reg_msg, RDMA_NL_IWCM) ||
510+
!iwpm_valid_pid())
511+
return 0;
512+
513+
cm_id->mapped = true;
514+
pm_msg.loc_addr = cm_id->local_addr;
515+
pm_msg.rem_addr = cm_id->remote_addr;
516+
if (active)
517+
status = iwpm_add_and_query_mapping(&pm_msg,
518+
RDMA_NL_IWCM);
519+
else
520+
status = iwpm_add_mapping(&pm_msg, RDMA_NL_IWCM);
521+
522+
if (!status) {
523+
cm_id->m_local_addr = pm_msg.mapped_loc_addr;
524+
if (active) {
525+
cm_id->m_remote_addr = pm_msg.mapped_rem_addr;
526+
iw_cm_check_wildcard(&pm_msg.mapped_rem_addr,
527+
&cm_id->remote_addr,
528+
&cm_id->m_remote_addr);
529+
}
530+
}
531+
532+
return iwpm_create_mapinfo(&cm_id->local_addr,
533+
&cm_id->m_local_addr,
534+
RDMA_NL_IWCM);
535+
}
536+
429537
/*
430538
* CM_ID <-- LISTEN
431539
*
@@ -452,7 +560,9 @@ int iw_cm_listen(struct iw_cm_id *cm_id, int backlog)
452560
case IW_CM_STATE_IDLE:
453561
cm_id_priv->state = IW_CM_STATE_LISTEN;
454562
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
455-
ret = cm_id->device->iwcm->create_listen(cm_id, backlog);
563+
ret = iw_cm_map(cm_id, false);
564+
if (!ret)
565+
ret = cm_id->device->iwcm->create_listen(cm_id, backlog);
456566
if (ret)
457567
cm_id_priv->state = IW_CM_STATE_IDLE;
458568
spin_lock_irqsave(&cm_id_priv->lock, flags);
@@ -582,39 +692,37 @@ int iw_cm_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
582692
spin_lock_irqsave(&cm_id_priv->lock, flags);
583693

584694
if (cm_id_priv->state != IW_CM_STATE_IDLE) {
585-
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
586-
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
587-
wake_up_all(&cm_id_priv->connect_wait);
588-
return -EINVAL;
695+
ret = -EINVAL;
696+
goto err;
589697
}
590698

591699
/* Get the ib_qp given the QPN */
592700
qp = cm_id->device->iwcm->get_qp(cm_id->device, iw_param->qpn);
593701
if (!qp) {
594-
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
595-
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
596-
wake_up_all(&cm_id_priv->connect_wait);
597-
return -EINVAL;
702+
ret = -EINVAL;
703+
goto err;
598704
}
599705
cm_id->device->iwcm->add_ref(qp);
600706
cm_id_priv->qp = qp;
601707
cm_id_priv->state = IW_CM_STATE_CONN_SENT;
602708
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
603709

604-
ret = cm_id->device->iwcm->connect(cm_id, iw_param);
605-
if (ret) {
606-
spin_lock_irqsave(&cm_id_priv->lock, flags);
607-
if (cm_id_priv->qp) {
608-
cm_id->device->iwcm->rem_ref(qp);
609-
cm_id_priv->qp = NULL;
610-
}
611-
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
612-
BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_SENT);
613-
cm_id_priv->state = IW_CM_STATE_IDLE;
614-
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
615-
wake_up_all(&cm_id_priv->connect_wait);
616-
}
710+
ret = iw_cm_map(cm_id, true);
711+
if (!ret)
712+
ret = cm_id->device->iwcm->connect(cm_id, iw_param);
713+
if (!ret)
714+
return 0; /* success */
617715

716+
spin_lock_irqsave(&cm_id_priv->lock, flags);
717+
if (cm_id_priv->qp) {
718+
cm_id->device->iwcm->rem_ref(qp);
719+
cm_id_priv->qp = NULL;
720+
}
721+
cm_id_priv->state = IW_CM_STATE_IDLE;
722+
err:
723+
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
724+
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
725+
wake_up_all(&cm_id_priv->connect_wait);
618726
return ret;
619727
}
620728
EXPORT_SYMBOL(iw_cm_connect);
@@ -656,8 +764,23 @@ static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv,
656764
goto out;
657765

658766
cm_id->provider_data = iw_event->provider_data;
659-
cm_id->local_addr = iw_event->local_addr;
660-
cm_id->remote_addr = iw_event->remote_addr;
767+
cm_id->m_local_addr = iw_event->local_addr;
768+
cm_id->m_remote_addr = iw_event->remote_addr;
769+
cm_id->local_addr = listen_id_priv->id.local_addr;
770+
771+
ret = iwpm_get_remote_info(&listen_id_priv->id.m_local_addr,
772+
&iw_event->remote_addr,
773+
&cm_id->remote_addr,
774+
RDMA_NL_IWCM);
775+
if (ret) {
776+
cm_id->remote_addr = iw_event->remote_addr;
777+
} else {
778+
iw_cm_check_wildcard(&listen_id_priv->id.m_local_addr,
779+
&iw_event->local_addr,
780+
&cm_id->local_addr);
781+
iw_event->local_addr = cm_id->local_addr;
782+
iw_event->remote_addr = cm_id->remote_addr;
783+
}
661784

662785
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
663786
cm_id_priv->state = IW_CM_STATE_CONN_RECV;
@@ -753,8 +876,10 @@ static int cm_conn_rep_handler(struct iwcm_id_private *cm_id_priv,
753876
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
754877
BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_SENT);
755878
if (iw_event->status == 0) {
756-
cm_id_priv->id.local_addr = iw_event->local_addr;
757-
cm_id_priv->id.remote_addr = iw_event->remote_addr;
879+
cm_id_priv->id.m_local_addr = iw_event->local_addr;
880+
cm_id_priv->id.m_remote_addr = iw_event->remote_addr;
881+
iw_event->local_addr = cm_id_priv->id.local_addr;
882+
iw_event->remote_addr = cm_id_priv->id.remote_addr;
758883
cm_id_priv->state = IW_CM_STATE_ESTABLISHED;
759884
} else {
760885
/* REJECTED or RESET */
@@ -1044,6 +1169,17 @@ EXPORT_SYMBOL(iw_cm_init_qp_attr);
10441169

10451170
static int __init iw_cm_init(void)
10461171
{
1172+
int ret;
1173+
1174+
ret = iwpm_init(RDMA_NL_IWCM);
1175+
if (ret)
1176+
pr_err("iw_cm: couldn't init iwpm\n");
1177+
1178+
ret = ibnl_add_client(RDMA_NL_IWCM, RDMA_NL_IWPM_NUM_OPS,
1179+
iwcm_nl_cb_table);
1180+
if (ret)
1181+
pr_err("iw_cm: couldn't register netlink callbacks\n");
1182+
10471183
iwcm_wq = create_singlethread_workqueue("iw_cm_wq");
10481184
if (!iwcm_wq)
10491185
return -ENOMEM;
@@ -1063,6 +1199,8 @@ static void __exit iw_cm_cleanup(void)
10631199
{
10641200
unregister_net_sysctl_table(iwcm_ctl_table_hdr);
10651201
destroy_workqueue(iwcm_wq);
1202+
ibnl_remove_client(RDMA_NL_IWCM);
1203+
iwpm_exit(RDMA_NL_IWCM);
10661204
}
10671205

10681206
module_init(iw_cm_init);

drivers/infiniband/core/iwpm_msg.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client)
8888
ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq, IWPM_NLA_REG_PID_SEQ);
8989
if (ret)
9090
goto pid_query_error;
91-
ret = ibnl_put_attr(skb, nlh, IWPM_IFNAME_SIZE,
92-
pm_msg->if_name, IWPM_NLA_REG_IF_NAME);
91+
ret = ibnl_put_attr(skb, nlh, IFNAMSIZ,
92+
pm_msg->if_name, IWPM_NLA_REG_IF_NAME);
9393
if (ret)
9494
goto pid_query_error;
9595
ret = ibnl_put_attr(skb, nlh, IWPM_DEVNAME_SIZE,
@@ -394,7 +394,7 @@ int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb)
394394
/* always for found nlmsg_request */
395395
kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
396396
barrier();
397-
wake_up(&nlmsg_request->waitq);
397+
up(&nlmsg_request->sem);
398398
return 0;
399399
}
400400
EXPORT_SYMBOL(iwpm_register_pid_cb);
@@ -463,7 +463,7 @@ int iwpm_add_mapping_cb(struct sk_buff *skb, struct netlink_callback *cb)
463463
/* always for found request */
464464
kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
465465
barrier();
466-
wake_up(&nlmsg_request->waitq);
466+
up(&nlmsg_request->sem);
467467
return 0;
468468
}
469469
EXPORT_SYMBOL(iwpm_add_mapping_cb);
@@ -555,7 +555,7 @@ int iwpm_add_and_query_mapping_cb(struct sk_buff *skb,
555555
/* always for found request */
556556
kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
557557
barrier();
558-
wake_up(&nlmsg_request->waitq);
558+
up(&nlmsg_request->sem);
559559
return 0;
560560
}
561561
EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb);
@@ -749,7 +749,7 @@ int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb)
749749
/* always for found request */
750750
kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
751751
barrier();
752-
wake_up(&nlmsg_request->waitq);
752+
up(&nlmsg_request->sem);
753753
return 0;
754754
}
755755
EXPORT_SYMBOL(iwpm_mapping_error_cb);

drivers/infiniband/core/iwpm_util.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,9 @@ void iwpm_add_remote_info(struct iwpm_remote_info *rem_info)
254254
}
255255

256256
int iwpm_get_remote_info(struct sockaddr_storage *mapped_loc_addr,
257-
struct sockaddr_storage *mapped_rem_addr,
258-
struct sockaddr_storage *remote_addr,
259-
u8 nl_client)
257+
struct sockaddr_storage *mapped_rem_addr,
258+
struct sockaddr_storage *remote_addr,
259+
u8 nl_client)
260260
{
261261
struct hlist_node *tmp_hlist_node;
262262
struct hlist_head *hash_bucket_head;
@@ -322,6 +322,8 @@ struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq,
322322
nlmsg_request->nl_client = nl_client;
323323
nlmsg_request->request_done = 0;
324324
nlmsg_request->err_code = 0;
325+
sema_init(&nlmsg_request->sem, 1);
326+
down(&nlmsg_request->sem);
325327
return nlmsg_request;
326328
}
327329

@@ -364,11 +366,9 @@ struct iwpm_nlmsg_request *iwpm_find_nlmsg_request(__u32 echo_seq)
364366
int iwpm_wait_complete_req(struct iwpm_nlmsg_request *nlmsg_request)
365367
{
366368
int ret;
367-
init_waitqueue_head(&nlmsg_request->waitq);
368369

369-
ret = wait_event_timeout(nlmsg_request->waitq,
370-
(nlmsg_request->request_done != 0), IWPM_NL_TIMEOUT);
371-
if (!ret) {
370+
ret = down_timeout(&nlmsg_request->sem, IWPM_NL_TIMEOUT);
371+
if (ret) {
372372
ret = -EINVAL;
373373
pr_info("%s: Timeout %d sec for netlink request (seq = %u)\n",
374374
__func__, (IWPM_NL_TIMEOUT/HZ), nlmsg_request->nlmsg_seq);

drivers/infiniband/core/iwpm_util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ struct iwpm_nlmsg_request {
6969
u8 nl_client;
7070
u8 request_done;
7171
u16 err_code;
72-
wait_queue_head_t waitq;
72+
struct semaphore sem;
7373
struct kref kref;
7474
};
7575

0 commit comments

Comments
 (0)