@@ -3493,121 +3493,6 @@ static int cma_resolve_ib_addr(struct rdma_id_private *id_priv)
34933493 return ret ;
34943494}
34953495
3496- static int cma_bind_addr (struct rdma_cm_id * id , struct sockaddr * src_addr ,
3497- const struct sockaddr * dst_addr )
3498- {
3499- struct sockaddr_storage zero_sock = {};
3500-
3501- if (src_addr && src_addr -> sa_family )
3502- return rdma_bind_addr (id , src_addr );
3503-
3504- /*
3505- * When the src_addr is not specified, automatically supply an any addr
3506- */
3507- zero_sock .ss_family = dst_addr -> sa_family ;
3508- if (IS_ENABLED (CONFIG_IPV6 ) && dst_addr -> sa_family == AF_INET6 ) {
3509- struct sockaddr_in6 * src_addr6 =
3510- (struct sockaddr_in6 * )& zero_sock ;
3511- struct sockaddr_in6 * dst_addr6 =
3512- (struct sockaddr_in6 * )dst_addr ;
3513-
3514- src_addr6 -> sin6_scope_id = dst_addr6 -> sin6_scope_id ;
3515- if (ipv6_addr_type (& dst_addr6 -> sin6_addr ) & IPV6_ADDR_LINKLOCAL )
3516- id -> route .addr .dev_addr .bound_dev_if =
3517- dst_addr6 -> sin6_scope_id ;
3518- } else if (dst_addr -> sa_family == AF_IB ) {
3519- ((struct sockaddr_ib * )& zero_sock )-> sib_pkey =
3520- ((struct sockaddr_ib * )dst_addr )-> sib_pkey ;
3521- }
3522- return rdma_bind_addr (id , (struct sockaddr * )& zero_sock );
3523- }
3524-
3525- /*
3526- * If required, resolve the source address for bind and leave the id_priv in
3527- * state RDMA_CM_ADDR_BOUND. This oddly uses the state to determine the prior
3528- * calls made by ULP, a previously bound ID will not be re-bound and src_addr is
3529- * ignored.
3530- */
3531- static int resolve_prepare_src (struct rdma_id_private * id_priv ,
3532- struct sockaddr * src_addr ,
3533- const struct sockaddr * dst_addr )
3534- {
3535- int ret ;
3536-
3537- memcpy (cma_dst_addr (id_priv ), dst_addr , rdma_addr_size (dst_addr ));
3538- if (!cma_comp_exch (id_priv , RDMA_CM_ADDR_BOUND , RDMA_CM_ADDR_QUERY )) {
3539- /* For a well behaved ULP state will be RDMA_CM_IDLE */
3540- ret = cma_bind_addr (& id_priv -> id , src_addr , dst_addr );
3541- if (ret )
3542- goto err_dst ;
3543- if (WARN_ON (!cma_comp_exch (id_priv , RDMA_CM_ADDR_BOUND ,
3544- RDMA_CM_ADDR_QUERY ))) {
3545- ret = - EINVAL ;
3546- goto err_dst ;
3547- }
3548- }
3549-
3550- if (cma_family (id_priv ) != dst_addr -> sa_family ) {
3551- ret = - EINVAL ;
3552- goto err_state ;
3553- }
3554- return 0 ;
3555-
3556- err_state :
3557- cma_comp_exch (id_priv , RDMA_CM_ADDR_QUERY , RDMA_CM_ADDR_BOUND );
3558- err_dst :
3559- memset (cma_dst_addr (id_priv ), 0 , rdma_addr_size (dst_addr ));
3560- return ret ;
3561- }
3562-
3563- int rdma_resolve_addr (struct rdma_cm_id * id , struct sockaddr * src_addr ,
3564- const struct sockaddr * dst_addr , unsigned long timeout_ms )
3565- {
3566- struct rdma_id_private * id_priv =
3567- container_of (id , struct rdma_id_private , id );
3568- int ret ;
3569-
3570- ret = resolve_prepare_src (id_priv , src_addr , dst_addr );
3571- if (ret )
3572- return ret ;
3573-
3574- if (cma_any_addr (dst_addr )) {
3575- ret = cma_resolve_loopback (id_priv );
3576- } else {
3577- if (dst_addr -> sa_family == AF_IB ) {
3578- ret = cma_resolve_ib_addr (id_priv );
3579- } else {
3580- /*
3581- * The FSM can return back to RDMA_CM_ADDR_BOUND after
3582- * rdma_resolve_ip() is called, eg through the error
3583- * path in addr_handler(). If this happens the existing
3584- * request must be canceled before issuing a new one.
3585- * Since canceling a request is a bit slow and this
3586- * oddball path is rare, keep track once a request has
3587- * been issued. The track turns out to be a permanent
3588- * state since this is the only cancel as it is
3589- * immediately before rdma_resolve_ip().
3590- */
3591- if (id_priv -> used_resolve_ip )
3592- rdma_addr_cancel (& id -> route .addr .dev_addr );
3593- else
3594- id_priv -> used_resolve_ip = 1 ;
3595- ret = rdma_resolve_ip (cma_src_addr (id_priv ), dst_addr ,
3596- & id -> route .addr .dev_addr ,
3597- timeout_ms , addr_handler ,
3598- false, id_priv );
3599- }
3600- }
3601- if (ret )
3602- goto err ;
3603-
3604- return 0 ;
3605- err :
3606- cma_comp_exch (id_priv , RDMA_CM_ADDR_QUERY , RDMA_CM_ADDR_BOUND );
3607- return ret ;
3608- }
3609- EXPORT_SYMBOL (rdma_resolve_addr );
3610-
36113496int rdma_set_reuseaddr (struct rdma_cm_id * id , int reuse )
36123497{
36133498 struct rdma_id_private * id_priv ;
@@ -4010,27 +3895,26 @@ int rdma_listen(struct rdma_cm_id *id, int backlog)
40103895}
40113896EXPORT_SYMBOL (rdma_listen );
40123897
4013- int rdma_bind_addr (struct rdma_cm_id * id , struct sockaddr * addr )
3898+ static int rdma_bind_addr_dst (struct rdma_id_private * id_priv ,
3899+ struct sockaddr * addr , const struct sockaddr * daddr )
40143900{
4015- struct rdma_id_private * id_priv ;
3901+ struct sockaddr * id_daddr ;
40163902 int ret ;
4017- struct sockaddr * daddr ;
40183903
40193904 if (addr -> sa_family != AF_INET && addr -> sa_family != AF_INET6 &&
40203905 addr -> sa_family != AF_IB )
40213906 return - EAFNOSUPPORT ;
40223907
4023- id_priv = container_of (id , struct rdma_id_private , id );
40243908 if (!cma_comp_exch (id_priv , RDMA_CM_IDLE , RDMA_CM_ADDR_BOUND ))
40253909 return - EINVAL ;
40263910
4027- ret = cma_check_linklocal (& id -> route .addr .dev_addr , addr );
3911+ ret = cma_check_linklocal (& id_priv -> id . route .addr .dev_addr , addr );
40283912 if (ret )
40293913 goto err1 ;
40303914
40313915 memcpy (cma_src_addr (id_priv ), addr , rdma_addr_size (addr ));
40323916 if (!cma_any_addr (addr )) {
4033- ret = cma_translate_addr (addr , & id -> route .addr .dev_addr );
3917+ ret = cma_translate_addr (addr , & id_priv -> id . route .addr .dev_addr );
40343918 if (ret )
40353919 goto err1 ;
40363920
@@ -4050,8 +3934,10 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
40503934 }
40513935#endif
40523936 }
4053- daddr = cma_dst_addr (id_priv );
4054- daddr -> sa_family = addr -> sa_family ;
3937+ id_daddr = cma_dst_addr (id_priv );
3938+ if (daddr != id_daddr )
3939+ memcpy (id_daddr , daddr , rdma_addr_size (addr ));
3940+ id_daddr -> sa_family = addr -> sa_family ;
40553941
40563942 ret = cma_get_port (id_priv );
40573943 if (ret )
@@ -4067,6 +3953,127 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
40673953 cma_comp_exch (id_priv , RDMA_CM_ADDR_BOUND , RDMA_CM_IDLE );
40683954 return ret ;
40693955}
3956+
3957+ static int cma_bind_addr (struct rdma_cm_id * id , struct sockaddr * src_addr ,
3958+ const struct sockaddr * dst_addr )
3959+ {
3960+ struct rdma_id_private * id_priv =
3961+ container_of (id , struct rdma_id_private , id );
3962+ struct sockaddr_storage zero_sock = {};
3963+
3964+ if (src_addr && src_addr -> sa_family )
3965+ return rdma_bind_addr_dst (id_priv , src_addr , dst_addr );
3966+
3967+ /*
3968+ * When the src_addr is not specified, automatically supply an any addr
3969+ */
3970+ zero_sock .ss_family = dst_addr -> sa_family ;
3971+ if (IS_ENABLED (CONFIG_IPV6 ) && dst_addr -> sa_family == AF_INET6 ) {
3972+ struct sockaddr_in6 * src_addr6 =
3973+ (struct sockaddr_in6 * )& zero_sock ;
3974+ struct sockaddr_in6 * dst_addr6 =
3975+ (struct sockaddr_in6 * )dst_addr ;
3976+
3977+ src_addr6 -> sin6_scope_id = dst_addr6 -> sin6_scope_id ;
3978+ if (ipv6_addr_type (& dst_addr6 -> sin6_addr ) & IPV6_ADDR_LINKLOCAL )
3979+ id -> route .addr .dev_addr .bound_dev_if =
3980+ dst_addr6 -> sin6_scope_id ;
3981+ } else if (dst_addr -> sa_family == AF_IB ) {
3982+ ((struct sockaddr_ib * )& zero_sock )-> sib_pkey =
3983+ ((struct sockaddr_ib * )dst_addr )-> sib_pkey ;
3984+ }
3985+ return rdma_bind_addr_dst (id_priv , (struct sockaddr * )& zero_sock , dst_addr );
3986+ }
3987+
3988+ /*
3989+ * If required, resolve the source address for bind and leave the id_priv in
3990+ * state RDMA_CM_ADDR_BOUND. This oddly uses the state to determine the prior
3991+ * calls made by ULP, a previously bound ID will not be re-bound and src_addr is
3992+ * ignored.
3993+ */
3994+ static int resolve_prepare_src (struct rdma_id_private * id_priv ,
3995+ struct sockaddr * src_addr ,
3996+ const struct sockaddr * dst_addr )
3997+ {
3998+ int ret ;
3999+
4000+ if (!cma_comp_exch (id_priv , RDMA_CM_ADDR_BOUND , RDMA_CM_ADDR_QUERY )) {
4001+ /* For a well behaved ULP state will be RDMA_CM_IDLE */
4002+ ret = cma_bind_addr (& id_priv -> id , src_addr , dst_addr );
4003+ if (ret )
4004+ return ret ;
4005+ if (WARN_ON (!cma_comp_exch (id_priv , RDMA_CM_ADDR_BOUND ,
4006+ RDMA_CM_ADDR_QUERY )))
4007+ return - EINVAL ;
4008+
4009+ }
4010+
4011+ if (cma_family (id_priv ) != dst_addr -> sa_family ) {
4012+ ret = - EINVAL ;
4013+ goto err_state ;
4014+ }
4015+ return 0 ;
4016+
4017+ err_state :
4018+ cma_comp_exch (id_priv , RDMA_CM_ADDR_QUERY , RDMA_CM_ADDR_BOUND );
4019+ return ret ;
4020+ }
4021+
4022+ int rdma_resolve_addr (struct rdma_cm_id * id , struct sockaddr * src_addr ,
4023+ const struct sockaddr * dst_addr , unsigned long timeout_ms )
4024+ {
4025+ struct rdma_id_private * id_priv =
4026+ container_of (id , struct rdma_id_private , id );
4027+ int ret ;
4028+
4029+ ret = resolve_prepare_src (id_priv , src_addr , dst_addr );
4030+ if (ret )
4031+ return ret ;
4032+
4033+ if (cma_any_addr (dst_addr )) {
4034+ ret = cma_resolve_loopback (id_priv );
4035+ } else {
4036+ if (dst_addr -> sa_family == AF_IB ) {
4037+ ret = cma_resolve_ib_addr (id_priv );
4038+ } else {
4039+ /*
4040+ * The FSM can return back to RDMA_CM_ADDR_BOUND after
4041+ * rdma_resolve_ip() is called, eg through the error
4042+ * path in addr_handler(). If this happens the existing
4043+ * request must be canceled before issuing a new one.
4044+ * Since canceling a request is a bit slow and this
4045+ * oddball path is rare, keep track once a request has
4046+ * been issued. The track turns out to be a permanent
4047+ * state since this is the only cancel as it is
4048+ * immediately before rdma_resolve_ip().
4049+ */
4050+ if (id_priv -> used_resolve_ip )
4051+ rdma_addr_cancel (& id -> route .addr .dev_addr );
4052+ else
4053+ id_priv -> used_resolve_ip = 1 ;
4054+ ret = rdma_resolve_ip (cma_src_addr (id_priv ), dst_addr ,
4055+ & id -> route .addr .dev_addr ,
4056+ timeout_ms , addr_handler ,
4057+ false, id_priv );
4058+ }
4059+ }
4060+ if (ret )
4061+ goto err ;
4062+
4063+ return 0 ;
4064+ err :
4065+ cma_comp_exch (id_priv , RDMA_CM_ADDR_QUERY , RDMA_CM_ADDR_BOUND );
4066+ return ret ;
4067+ }
4068+ EXPORT_SYMBOL (rdma_resolve_addr );
4069+
4070+ int rdma_bind_addr (struct rdma_cm_id * id , struct sockaddr * addr )
4071+ {
4072+ struct rdma_id_private * id_priv =
4073+ container_of (id , struct rdma_id_private , id );
4074+
4075+ return rdma_bind_addr_dst (id_priv , addr , cma_dst_addr (id_priv ));
4076+ }
40704077EXPORT_SYMBOL (rdma_bind_addr );
40714078
40724079static int cma_format_hdr (void * hdr , struct rdma_id_private * id_priv )
0 commit comments