@@ -639,6 +639,58 @@ static void cma_bind_sgid_attr(struct rdma_id_private *id_priv,
639
639
id_priv -> id .route .addr .dev_addr .sgid_attr = sgid_attr ;
640
640
}
641
641
642
+ /**
643
+ * cma_acquire_dev_by_src_ip - Acquire cma device, port, gid attribute
644
+ * based on source ip address.
645
+ * @id_priv: cm_id which should be bound to cma device
646
+ *
647
+ * cma_acquire_dev_by_src_ip() binds cm id to cma device, port and GID attribute
648
+ * based on source IP address. It returns 0 on success or error code otherwise.
649
+ * It is applicable to active and passive side cm_id.
650
+ */
651
+ static int cma_acquire_dev_by_src_ip (struct rdma_id_private * id_priv )
652
+ {
653
+ struct rdma_dev_addr * dev_addr = & id_priv -> id .route .addr .dev_addr ;
654
+ const struct ib_gid_attr * sgid_attr ;
655
+ union ib_gid gid , iboe_gid , * gidp ;
656
+ struct cma_device * cma_dev ;
657
+ enum ib_gid_type gid_type ;
658
+ int ret = - ENODEV ;
659
+ u8 port ;
660
+
661
+ if (dev_addr -> dev_type != ARPHRD_INFINIBAND &&
662
+ id_priv -> id .ps == RDMA_PS_IPOIB )
663
+ return - EINVAL ;
664
+
665
+ rdma_ip2gid ((struct sockaddr * )& id_priv -> id .route .addr .src_addr ,
666
+ & iboe_gid );
667
+
668
+ memcpy (& gid , dev_addr -> src_dev_addr +
669
+ rdma_addr_gid_offset (dev_addr ), sizeof (gid ));
670
+
671
+ mutex_lock (& lock );
672
+ list_for_each_entry (cma_dev , & dev_list , list ) {
673
+ for (port = rdma_start_port (cma_dev -> device );
674
+ port <= rdma_end_port (cma_dev -> device ); port ++ ) {
675
+ gidp = rdma_protocol_roce (cma_dev -> device , port ) ?
676
+ & iboe_gid : & gid ;
677
+ gid_type = cma_dev -> default_gid_type [port - 1 ];
678
+ sgid_attr = cma_validate_port (cma_dev -> device , port ,
679
+ gid_type , gidp , id_priv );
680
+ if (!IS_ERR (sgid_attr )) {
681
+ id_priv -> id .port_num = port ;
682
+ cma_bind_sgid_attr (id_priv , sgid_attr );
683
+ cma_attach_to_dev (id_priv , cma_dev );
684
+ ret = 0 ;
685
+ goto out ;
686
+ }
687
+ }
688
+ }
689
+ out :
690
+ mutex_unlock (& lock );
691
+ return ret ;
692
+ }
693
+
642
694
static int cma_acquire_dev (struct rdma_id_private * id_priv ,
643
695
const struct rdma_id_private * listen_id_priv )
644
696
{
@@ -661,26 +713,22 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv,
661
713
memcpy (& gid , dev_addr -> src_dev_addr +
662
714
rdma_addr_gid_offset (dev_addr ), sizeof gid );
663
715
664
- if (listen_id_priv ) {
665
- cma_dev = listen_id_priv -> cma_dev ;
666
- port = listen_id_priv -> id .port_num ;
667
- gidp = rdma_protocol_roce (cma_dev -> device , port ) ?
668
- & iboe_gid : & gid ;
669
- gid_type = listen_id_priv -> gid_type ;
670
- sgid_attr = cma_validate_port (cma_dev -> device , port ,
671
- gid_type , gidp , id_priv );
672
- if (!IS_ERR (sgid_attr )) {
673
- id_priv -> id .port_num = port ;
674
- cma_bind_sgid_attr (id_priv , sgid_attr );
675
- ret = 0 ;
676
- goto out ;
677
- }
716
+ cma_dev = listen_id_priv -> cma_dev ;
717
+ port = listen_id_priv -> id .port_num ;
718
+ gidp = rdma_protocol_roce (cma_dev -> device , port ) ? & iboe_gid : & gid ;
719
+ gid_type = listen_id_priv -> gid_type ;
720
+ sgid_attr = cma_validate_port (cma_dev -> device , port ,
721
+ gid_type , gidp , id_priv );
722
+ if (!IS_ERR (sgid_attr )) {
723
+ id_priv -> id .port_num = port ;
724
+ cma_bind_sgid_attr (id_priv , sgid_attr );
725
+ ret = 0 ;
726
+ goto out ;
678
727
}
679
728
680
729
list_for_each_entry (cma_dev , & dev_list , list ) {
681
730
for (port = 1 ; port <= cma_dev -> device -> phys_port_cnt ; ++ port ) {
682
- if (listen_id_priv &&
683
- listen_id_priv -> cma_dev == cma_dev &&
731
+ if (listen_id_priv -> cma_dev == cma_dev &&
684
732
listen_id_priv -> id .port_num == port )
685
733
continue ;
686
734
@@ -2878,7 +2926,7 @@ static void addr_handler(int status, struct sockaddr *src_addr,
2878
2926
2879
2927
memcpy (cma_src_addr (id_priv ), src_addr , rdma_addr_size (src_addr ));
2880
2928
if (!status && !id_priv -> cma_dev ) {
2881
- status = cma_acquire_dev (id_priv , NULL );
2929
+ status = cma_acquire_dev_by_src_ip (id_priv );
2882
2930
if (status )
2883
2931
pr_debug_ratelimited ("RDMA CM: ADDR_ERROR: failed to acquire device. status %d\n" ,
2884
2932
status );
@@ -3427,7 +3475,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
3427
3475
if (ret )
3428
3476
goto err1 ;
3429
3477
3430
- ret = cma_acquire_dev (id_priv , NULL );
3478
+ ret = cma_acquire_dev_by_src_ip (id_priv );
3431
3479
if (ret )
3432
3480
goto err1 ;
3433
3481
}
0 commit comments