@@ -3541,121 +3541,6 @@ static int cma_resolve_ib_addr(struct rdma_id_private *id_priv)
35413541 return ret ;
35423542}
35433543
3544- static int cma_bind_addr (struct rdma_cm_id * id , struct sockaddr * src_addr ,
3545- const struct sockaddr * dst_addr )
3546- {
3547- struct sockaddr_storage zero_sock = {};
3548-
3549- if (src_addr && src_addr -> sa_family )
3550- return rdma_bind_addr (id , src_addr );
3551-
3552- /*
3553- * When the src_addr is not specified, automatically supply an any addr
3554- */
3555- zero_sock .ss_family = dst_addr -> sa_family ;
3556- if (IS_ENABLED (CONFIG_IPV6 ) && dst_addr -> sa_family == AF_INET6 ) {
3557- struct sockaddr_in6 * src_addr6 =
3558- (struct sockaddr_in6 * )& zero_sock ;
3559- struct sockaddr_in6 * dst_addr6 =
3560- (struct sockaddr_in6 * )dst_addr ;
3561-
3562- src_addr6 -> sin6_scope_id = dst_addr6 -> sin6_scope_id ;
3563- if (ipv6_addr_type (& dst_addr6 -> sin6_addr ) & IPV6_ADDR_LINKLOCAL )
3564- id -> route .addr .dev_addr .bound_dev_if =
3565- dst_addr6 -> sin6_scope_id ;
3566- } else if (dst_addr -> sa_family == AF_IB ) {
3567- ((struct sockaddr_ib * )& zero_sock )-> sib_pkey =
3568- ((struct sockaddr_ib * )dst_addr )-> sib_pkey ;
3569- }
3570- return rdma_bind_addr (id , (struct sockaddr * )& zero_sock );
3571- }
3572-
3573- /*
3574- * If required, resolve the source address for bind and leave the id_priv in
3575- * state RDMA_CM_ADDR_BOUND. This oddly uses the state to determine the prior
3576- * calls made by ULP, a previously bound ID will not be re-bound and src_addr is
3577- * ignored.
3578- */
3579- static int resolve_prepare_src (struct rdma_id_private * id_priv ,
3580- struct sockaddr * src_addr ,
3581- const struct sockaddr * dst_addr )
3582- {
3583- int ret ;
3584-
3585- memcpy (cma_dst_addr (id_priv ), dst_addr , rdma_addr_size (dst_addr ));
3586- if (!cma_comp_exch (id_priv , RDMA_CM_ADDR_BOUND , RDMA_CM_ADDR_QUERY )) {
3587- /* For a well behaved ULP state will be RDMA_CM_IDLE */
3588- ret = cma_bind_addr (& id_priv -> id , src_addr , dst_addr );
3589- if (ret )
3590- goto err_dst ;
3591- if (WARN_ON (!cma_comp_exch (id_priv , RDMA_CM_ADDR_BOUND ,
3592- RDMA_CM_ADDR_QUERY ))) {
3593- ret = - EINVAL ;
3594- goto err_dst ;
3595- }
3596- }
3597-
3598- if (cma_family (id_priv ) != dst_addr -> sa_family ) {
3599- ret = - EINVAL ;
3600- goto err_state ;
3601- }
3602- return 0 ;
3603-
3604- err_state :
3605- cma_comp_exch (id_priv , RDMA_CM_ADDR_QUERY , RDMA_CM_ADDR_BOUND );
3606- err_dst :
3607- memset (cma_dst_addr (id_priv ), 0 , rdma_addr_size (dst_addr ));
3608- return ret ;
3609- }
3610-
3611- int rdma_resolve_addr (struct rdma_cm_id * id , struct sockaddr * src_addr ,
3612- const struct sockaddr * dst_addr , unsigned long timeout_ms )
3613- {
3614- struct rdma_id_private * id_priv =
3615- container_of (id , struct rdma_id_private , id );
3616- int ret ;
3617-
3618- ret = resolve_prepare_src (id_priv , src_addr , dst_addr );
3619- if (ret )
3620- return ret ;
3621-
3622- if (cma_any_addr (dst_addr )) {
3623- ret = cma_resolve_loopback (id_priv );
3624- } else {
3625- if (dst_addr -> sa_family == AF_IB ) {
3626- ret = cma_resolve_ib_addr (id_priv );
3627- } else {
3628- /*
3629- * The FSM can return back to RDMA_CM_ADDR_BOUND after
3630- * rdma_resolve_ip() is called, eg through the error
3631- * path in addr_handler(). If this happens the existing
3632- * request must be canceled before issuing a new one.
3633- * Since canceling a request is a bit slow and this
3634- * oddball path is rare, keep track once a request has
3635- * been issued. The track turns out to be a permanent
3636- * state since this is the only cancel as it is
3637- * immediately before rdma_resolve_ip().
3638- */
3639- if (id_priv -> used_resolve_ip )
3640- rdma_addr_cancel (& id -> route .addr .dev_addr );
3641- else
3642- id_priv -> used_resolve_ip = 1 ;
3643- ret = rdma_resolve_ip (cma_src_addr (id_priv ), dst_addr ,
3644- & id -> route .addr .dev_addr ,
3645- timeout_ms , addr_handler ,
3646- false, id_priv );
3647- }
3648- }
3649- if (ret )
3650- goto err ;
3651-
3652- return 0 ;
3653- err :
3654- cma_comp_exch (id_priv , RDMA_CM_ADDR_QUERY , RDMA_CM_ADDR_BOUND );
3655- return ret ;
3656- }
3657- EXPORT_SYMBOL (rdma_resolve_addr );
3658-
36593544int rdma_set_reuseaddr (struct rdma_cm_id * id , int reuse )
36603545{
36613546 struct rdma_id_private * id_priv ;
@@ -4058,27 +3943,26 @@ int rdma_listen(struct rdma_cm_id *id, int backlog)
40583943}
40593944EXPORT_SYMBOL (rdma_listen );
40603945
4061- int rdma_bind_addr (struct rdma_cm_id * id , struct sockaddr * addr )
3946+ static int rdma_bind_addr_dst (struct rdma_id_private * id_priv ,
3947+ struct sockaddr * addr , const struct sockaddr * daddr )
40623948{
4063- struct rdma_id_private * id_priv ;
3949+ struct sockaddr * id_daddr ;
40643950 int ret ;
4065- struct sockaddr * daddr ;
40663951
40673952 if (addr -> sa_family != AF_INET && addr -> sa_family != AF_INET6 &&
40683953 addr -> sa_family != AF_IB )
40693954 return - EAFNOSUPPORT ;
40703955
4071- id_priv = container_of (id , struct rdma_id_private , id );
40723956 if (!cma_comp_exch (id_priv , RDMA_CM_IDLE , RDMA_CM_ADDR_BOUND ))
40733957 return - EINVAL ;
40743958
4075- ret = cma_check_linklocal (& id -> route .addr .dev_addr , addr );
3959+ ret = cma_check_linklocal (& id_priv -> id . route .addr .dev_addr , addr );
40763960 if (ret )
40773961 goto err1 ;
40783962
40793963 memcpy (cma_src_addr (id_priv ), addr , rdma_addr_size (addr ));
40803964 if (!cma_any_addr (addr )) {
4081- ret = cma_translate_addr (addr , & id -> route .addr .dev_addr );
3965+ ret = cma_translate_addr (addr , & id_priv -> id . route .addr .dev_addr );
40823966 if (ret )
40833967 goto err1 ;
40843968
@@ -4098,8 +3982,10 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
40983982 }
40993983#endif
41003984 }
4101- daddr = cma_dst_addr (id_priv );
4102- daddr -> sa_family = addr -> sa_family ;
3985+ id_daddr = cma_dst_addr (id_priv );
3986+ if (daddr != id_daddr )
3987+ memcpy (id_daddr , daddr , rdma_addr_size (addr ));
3988+ id_daddr -> sa_family = addr -> sa_family ;
41033989
41043990 ret = cma_get_port (id_priv );
41053991 if (ret )
@@ -4115,6 +4001,127 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
41154001 cma_comp_exch (id_priv , RDMA_CM_ADDR_BOUND , RDMA_CM_IDLE );
41164002 return ret ;
41174003}
4004+
4005+ static int cma_bind_addr (struct rdma_cm_id * id , struct sockaddr * src_addr ,
4006+ const struct sockaddr * dst_addr )
4007+ {
4008+ struct rdma_id_private * id_priv =
4009+ container_of (id , struct rdma_id_private , id );
4010+ struct sockaddr_storage zero_sock = {};
4011+
4012+ if (src_addr && src_addr -> sa_family )
4013+ return rdma_bind_addr_dst (id_priv , src_addr , dst_addr );
4014+
4015+ /*
4016+ * When the src_addr is not specified, automatically supply an any addr
4017+ */
4018+ zero_sock .ss_family = dst_addr -> sa_family ;
4019+ if (IS_ENABLED (CONFIG_IPV6 ) && dst_addr -> sa_family == AF_INET6 ) {
4020+ struct sockaddr_in6 * src_addr6 =
4021+ (struct sockaddr_in6 * )& zero_sock ;
4022+ struct sockaddr_in6 * dst_addr6 =
4023+ (struct sockaddr_in6 * )dst_addr ;
4024+
4025+ src_addr6 -> sin6_scope_id = dst_addr6 -> sin6_scope_id ;
4026+ if (ipv6_addr_type (& dst_addr6 -> sin6_addr ) & IPV6_ADDR_LINKLOCAL )
4027+ id -> route .addr .dev_addr .bound_dev_if =
4028+ dst_addr6 -> sin6_scope_id ;
4029+ } else if (dst_addr -> sa_family == AF_IB ) {
4030+ ((struct sockaddr_ib * )& zero_sock )-> sib_pkey =
4031+ ((struct sockaddr_ib * )dst_addr )-> sib_pkey ;
4032+ }
4033+ return rdma_bind_addr_dst (id_priv , (struct sockaddr * )& zero_sock , dst_addr );
4034+ }
4035+
4036+ /*
4037+ * If required, resolve the source address for bind and leave the id_priv in
4038+ * state RDMA_CM_ADDR_BOUND. This oddly uses the state to determine the prior
4039+ * calls made by ULP, a previously bound ID will not be re-bound and src_addr is
4040+ * ignored.
4041+ */
4042+ static int resolve_prepare_src (struct rdma_id_private * id_priv ,
4043+ struct sockaddr * src_addr ,
4044+ const struct sockaddr * dst_addr )
4045+ {
4046+ int ret ;
4047+
4048+ if (!cma_comp_exch (id_priv , RDMA_CM_ADDR_BOUND , RDMA_CM_ADDR_QUERY )) {
4049+ /* For a well behaved ULP state will be RDMA_CM_IDLE */
4050+ ret = cma_bind_addr (& id_priv -> id , src_addr , dst_addr );
4051+ if (ret )
4052+ return ret ;
4053+ if (WARN_ON (!cma_comp_exch (id_priv , RDMA_CM_ADDR_BOUND ,
4054+ RDMA_CM_ADDR_QUERY )))
4055+ return - EINVAL ;
4056+
4057+ }
4058+
4059+ if (cma_family (id_priv ) != dst_addr -> sa_family ) {
4060+ ret = - EINVAL ;
4061+ goto err_state ;
4062+ }
4063+ return 0 ;
4064+
4065+ err_state :
4066+ cma_comp_exch (id_priv , RDMA_CM_ADDR_QUERY , RDMA_CM_ADDR_BOUND );
4067+ return ret ;
4068+ }
4069+
4070+ int rdma_resolve_addr (struct rdma_cm_id * id , struct sockaddr * src_addr ,
4071+ const struct sockaddr * dst_addr , unsigned long timeout_ms )
4072+ {
4073+ struct rdma_id_private * id_priv =
4074+ container_of (id , struct rdma_id_private , id );
4075+ int ret ;
4076+
4077+ ret = resolve_prepare_src (id_priv , src_addr , dst_addr );
4078+ if (ret )
4079+ return ret ;
4080+
4081+ if (cma_any_addr (dst_addr )) {
4082+ ret = cma_resolve_loopback (id_priv );
4083+ } else {
4084+ if (dst_addr -> sa_family == AF_IB ) {
4085+ ret = cma_resolve_ib_addr (id_priv );
4086+ } else {
4087+ /*
4088+ * The FSM can return back to RDMA_CM_ADDR_BOUND after
4089+ * rdma_resolve_ip() is called, eg through the error
4090+ * path in addr_handler(). If this happens the existing
4091+ * request must be canceled before issuing a new one.
4092+ * Since canceling a request is a bit slow and this
4093+ * oddball path is rare, keep track once a request has
4094+ * been issued. The track turns out to be a permanent
4095+ * state since this is the only cancel as it is
4096+ * immediately before rdma_resolve_ip().
4097+ */
4098+ if (id_priv -> used_resolve_ip )
4099+ rdma_addr_cancel (& id -> route .addr .dev_addr );
4100+ else
4101+ id_priv -> used_resolve_ip = 1 ;
4102+ ret = rdma_resolve_ip (cma_src_addr (id_priv ), dst_addr ,
4103+ & id -> route .addr .dev_addr ,
4104+ timeout_ms , addr_handler ,
4105+ false, id_priv );
4106+ }
4107+ }
4108+ if (ret )
4109+ goto err ;
4110+
4111+ return 0 ;
4112+ err :
4113+ cma_comp_exch (id_priv , RDMA_CM_ADDR_QUERY , RDMA_CM_ADDR_BOUND );
4114+ return ret ;
4115+ }
4116+ EXPORT_SYMBOL (rdma_resolve_addr );
4117+
4118+ int rdma_bind_addr (struct rdma_cm_id * id , struct sockaddr * addr )
4119+ {
4120+ struct rdma_id_private * id_priv =
4121+ container_of (id , struct rdma_id_private , id );
4122+
4123+ return rdma_bind_addr_dst (id_priv , addr , cma_dst_addr (id_priv ));
4124+ }
41184125EXPORT_SYMBOL (rdma_bind_addr );
41194126
41204127static int cma_format_hdr (void * hdr , struct rdma_id_private * id_priv )
0 commit comments