Message ID | 20241202125203.48821-3-guangguan.wang@linux.alibaba.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | net/smc: Two features for smc-r | expand |
On 02.12.24 13:52, Guangguan Wang wrote: > AF_INET6 is not supported for smc-r v2 client before, event if the %s/event/even/g > ipv6 addr is ipv4 mapped. Thus, when using AF_INET6, smc-r connection > will fallback to tcp, especially for java applications running smc-r. > This patch support ipv4 mapped ipv6 addr client for smc-r v2. Clients > using real global ipv6 addr is still not supported yet. > > Signed-off-by: Guangguan Wang <guangguan.wang@linux.alibaba.com> > Reviewed-by: Wen Gu <guwen@linux.alibaba.com> > Reviewed-by: Dust Li <dust.li@linux.alibaba.com> > Reviewed-by: D. Wythe <alibuda@linux.alibaba.com> > --- > net/smc/af_smc.c | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c > index 9d76e902fd77..5b13dd759766 100644 > --- a/net/smc/af_smc.c > +++ b/net/smc/af_smc.c > @@ -1116,7 +1116,12 @@ static int smc_find_proposal_devices(struct smc_sock *smc, > ini->check_smcrv2 = true; > ini->smcrv2.saddr = smc->clcsock->sk->sk_rcv_saddr; > if (!(ini->smcr_version & SMC_V2) || > +#if IS_ENABLED(CONFIG_IPV6) > + (smc->clcsock->sk->sk_family != AF_INET && > + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || I think here you want to say !(smc->clcsock->sk->sk_family == AF_INET && ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)), right? If it is, the negativ form of the logical operation (a&&b) is (!a)||(!b), i.e. here should be: (smc->clcsock->sk->sk_family != AF_INET)|| (!ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) > +#else > smc->clcsock->sk->sk_family != AF_INET || > +#endif > !smc_clc_ueid_count() || > smc_find_rdma_device(smc, ini)) > ini->smcr_version &= ~SMC_V2;
On 2024/12/5 18:16, Wenjia Zhang wrote: > > > On 02.12.24 13:52, Guangguan Wang wrote: >> AF_INET6 is not supported for smc-r v2 client before, event if the > %s/event/even/g > I will fix it in the next version. >> ipv6 addr is ipv4 mapped. Thus, when using AF_INET6, smc-r connection >> will fallback to tcp, especially for java applications running smc-r. >> This patch support ipv4 mapped ipv6 addr client for smc-r v2. Clients >> using real global ipv6 addr is still not supported yet. >> >> Signed-off-by: Guangguan Wang <guangguan.wang@linux.alibaba.com> >> Reviewed-by: Wen Gu <guwen@linux.alibaba.com> >> Reviewed-by: Dust Li <dust.li@linux.alibaba.com> >> Reviewed-by: D. Wythe <alibuda@linux.alibaba.com> >> --- >> net/smc/af_smc.c | 5 +++++ >> 1 file changed, 5 insertions(+) >> >> diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c >> index 9d76e902fd77..5b13dd759766 100644 >> --- a/net/smc/af_smc.c >> +++ b/net/smc/af_smc.c >> @@ -1116,7 +1116,12 @@ static int smc_find_proposal_devices(struct smc_sock *smc, >> ini->check_smcrv2 = true; >> ini->smcrv2.saddr = smc->clcsock->sk->sk_rcv_saddr; >> if (!(ini->smcr_version & SMC_V2) || >> +#if IS_ENABLED(CONFIG_IPV6) >> + (smc->clcsock->sk->sk_family != AF_INET && >> + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || > I think here you want to say !(smc->clcsock->sk->sk_family == AF_INET && ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)), right? If it is, the negativ form of the logical operation (a&&b) is (!a)||(!b), i.e. here should be: > (smc->clcsock->sk->sk_family != AF_INET)|| (!ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) > (smc->clcsock->sk->sk_family != AF_INET && !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) not equls to !(smc->clcsock->sk->sk_family == AF_INET && ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) Following your logic, here also can be: !(smc->clcsock->sk->sk_family == AF_INET || ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) I think both is acceptable. But in order to keep consistent with the code when IPV6 is not enabled, I prefer (smc->clcsock->sk->sk_family != AF_INET && !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)). >> +#else >> smc->clcsock->sk->sk_family != AF_INET || >> +#endif >> !smc_clc_ueid_count() || >> smc_find_rdma_device(smc, ini)) >> ini->smcr_version &= ~SMC_V2;
On Thu, 5 Dec 2024 11:16:27 +0100 Wenjia Zhang <wenjia@linux.ibm.com> wrote: > > --- a/net/smc/af_smc.c > > +++ b/net/smc/af_smc.c > > @@ -1116,7 +1116,12 @@ static int smc_find_proposal_devices(struct > > smc_sock *smc, ini->check_smcrv2 = true; > > ini->smcrv2.saddr = smc->clcsock->sk->sk_rcv_saddr; > > if (!(ini->smcr_version & SMC_V2) || > > +#if IS_ENABLED(CONFIG_IPV6) > > + (smc->clcsock->sk->sk_family != AF_INET && > > + > > !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || > I think here you want to say !(smc->clcsock->sk->sk_family == AF_INET > && ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)), right? If > it is, the negativ form of the logical operation (a&&b) is (!a)||(!b), > i.e. here should be: > (smc->clcsock->sk->sk_family != AF_INET)|| > (!ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) Wenjia, I think you happen to confuse something here. The condition of this if statement is supposed to evaluate as true iff we don't want to propose SMCRv2 because the situation is such that SMCRv2 is not supported. We have a bunch of conditions we need to meet for SMCRv2 so logically we have (A && B && C && D). Now since the if is about when SMCRv2 is not supported we have a super structure that looks like !A || !B || !C || !D. With this patch, if CONFIG_IPV6 is not enabled, the sub-condition remains the same: if smc->clcsock->sk->sk_family is something else that AF_INET the we do not do SMCRv2! But when we do have CONFIG_IPV6 then we want to do SMCRv2 for AF_INET6 sockets too if the addresses used are actually v4 mapped addresses. Now this is where the cognitive dissonance starts on my end. I think the author assumes sk_family == AF_INET || sk_family == AF_INET6 is a tautology in this context. That may be a reasonable thing to assume. Under that assumption sk_family != AF_INET && !ipv6_addr_v4mapped(addr) (shortened for convenience) becomes equivalent to sk_family == AF_INET6 && !ipv6_addr_v4mapped(addr) which means in words if the socket is an IPv6 sockeet and the addr is not a v4 mapped v6 address then we *can not* do SMCRv2. And the condition when we can is sk_family != AF_INET6 || ipv6_addr_v4mapped(addr) which is equivalen to sk_family == AF_INET || ipv6_addr_v4mapped(addr) under the aforementioned assumption. But if we assume sk_family == AF_INET || sk_family == AF_INET6 then the #else does not make any sense, because I guess with IPv6 not available AF_INET6 is not available ant thus the else is always guaranteed to evaluate to false under the assumption made. Thus I conclude, that I am certainly missing something here. Guangguan, do you care to explain? Regards, Halil
On 2024/12/5 20:58, Halil Pasic wrote: > On Thu, 5 Dec 2024 11:16:27 +0100 > Wenjia Zhang <wenjia@linux.ibm.com> wrote: > >>> --- a/net/smc/af_smc.c >>> +++ b/net/smc/af_smc.c >>> @@ -1116,7 +1116,12 @@ static int smc_find_proposal_devices(struct >>> smc_sock *smc, ini->check_smcrv2 = true; >>> ini->smcrv2.saddr = smc->clcsock->sk->sk_rcv_saddr; >>> if (!(ini->smcr_version & SMC_V2) || >>> +#if IS_ENABLED(CONFIG_IPV6) >>> + (smc->clcsock->sk->sk_family != AF_INET && >>> + >>> !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || >> I think here you want to say !(smc->clcsock->sk->sk_family == AF_INET >> && ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)), right? If >> it is, the negativ form of the logical operation (a&&b) is (!a)||(!b), >> i.e. here should be: >> (smc->clcsock->sk->sk_family != AF_INET)|| >> (!ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) > > Wenjia, I think you happen to confuse something here. The condition > of this if statement is supposed to evaluate as true iff we don't want > to propose SMCRv2 because the situation is such that SMCRv2 is not > supported. > > We have a bunch of conditions we need to meet for SMCRv2 so > logically we have (A && B && C && D). Now since the if is > about when SMCRv2 is not supported we have a super structure > that looks like !A || !B || !C || !D. With this patch, if > CONFIG_IPV6 is not enabled, the sub-condition remains the same: > if smc->clcsock->sk->sk_family is something else that AF_INET > the we do not do SMCRv2! > > But when we do have CONFIG_IPV6 then we want to do SMCRv2 for > AF_INET6 sockets too if the addresses used are actually > v4 mapped addresses. > > Now this is where the cognitive dissonance starts on my end. I > think the author assumes sk_family == AF_INET || sk_family == AF_INET6 > is a tautology in this context. That may be a reasonable thing to > assume. Under that assumption > sk_family != AF_INET && !ipv6_addr_v4mapped(addr) (shortened for > convenience) > becomes equivalent to > sk_family == AF_INET6 && !ipv6_addr_v4mapped(addr) > which means in words if the socket is an IPv6 sockeet and the addr is not > a v4 mapped v6 address then we *can not* do SMCRv2. And the condition > when we can is sk_family != AF_INET6 || ipv6_addr_v4mapped(addr) which > is equivalen to sk_family == AF_INET || ipv6_addr_v4mapped(addr) under > the aforementioned assumption. Hi, Halil Thank you for such a detailed derivation. Yes, here assume that sk_family == AF_INET || sk_family == AF_INET6. Indeed, many codes in SMC have already made this assumption, for example, static int __smc_create(struct net *net, struct socket *sock, int protocol, int kern, struct socket *clcsock) { int family = (protocol == SMCPROTO_SMC6) ? PF_INET6 : PF_INET; ... } And I also believe it is reasonable. Before this patch, for SMCR client, only an IPV4 socket can do SMCRv2. This patch introduce an IPV6 socket with v4 mapped v6 address for SMCRv2. It is equivalen to sk_family == AF_INET || ipv6_addr_v4mapped(addr) as you described. > > But if we assume sk_family == AF_INET || sk_family == AF_INET6 then > the #else does not make any sense, because I guess with IPv6 not > available AF_INET6 is not available ant thus the else is always > guaranteed to evaluate to false under the assumption made. > You are right. The #else here does not make any sense. It's my mistake. The condition is easier to understand and read should be like this: if (!(ini->smcr_version & SMC_V2) || +#if IS_ENABLED(CONFIG_IPV6) + (smc->clcsock->sk->sk_family == AF_INET6 && + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || +#endif !smc_clc_ueid_count() || smc_find_rdma_device(smc, ini)) ini->smcr_version &= ~SMC_V2; Thanks, Guangguan Wang > Thus I conclude, that I am certainly missing something here. Guangguan, > do you care to explain? > > Regards, > Halil >
On 06.12.24 07:06, Guangguan Wang wrote: > > > On 2024/12/5 20:58, Halil Pasic wrote: >> On Thu, 5 Dec 2024 11:16:27 +0100 >> Wenjia Zhang <wenjia@linux.ibm.com> wrote: >> >>>> --- a/net/smc/af_smc.c >>>> +++ b/net/smc/af_smc.c >>>> @@ -1116,7 +1116,12 @@ static int smc_find_proposal_devices(struct >>>> smc_sock *smc, ini->check_smcrv2 = true; >>>> ini->smcrv2.saddr = smc->clcsock->sk->sk_rcv_saddr; >>>> if (!(ini->smcr_version & SMC_V2) || >>>> +#if IS_ENABLED(CONFIG_IPV6) >>>> + (smc->clcsock->sk->sk_family != AF_INET && >>>> + >>>> !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || >>> I think here you want to say !(smc->clcsock->sk->sk_family == AF_INET >>> && ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)), right? If >>> it is, the negativ form of the logical operation (a&&b) is (!a)||(!b), >>> i.e. here should be: >>> (smc->clcsock->sk->sk_family != AF_INET)|| >>> (!ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) >> >> Wenjia, I think you happen to confuse something here. The condition >> of this if statement is supposed to evaluate as true iff we don't want >> to propose SMCRv2 because the situation is such that SMCRv2 is not >> supported. >> >> We have a bunch of conditions we need to meet for SMCRv2 so >> logically we have (A && B && C && D). Now since the if is >> about when SMCRv2 is not supported we have a super structure >> that looks like !A || !B || !C || !D. With this patch, if >> CONFIG_IPV6 is not enabled, the sub-condition remains the same: >> if smc->clcsock->sk->sk_family is something else that AF_INET >> the we do not do SMCRv2! >> >> But when we do have CONFIG_IPV6 then we want to do SMCRv2 for >> AF_INET6 sockets too if the addresses used are actually >> v4 mapped addresses. >> >> Now this is where the cognitive dissonance starts on my end. I >> think the author assumes sk_family == AF_INET || sk_family == AF_INET6 >> is a tautology in this context. That may be a reasonable thing to >> assume. Under that assumption >> sk_family != AF_INET && !ipv6_addr_v4mapped(addr) (shortened for >> convenience) >> becomes equivalent to >> sk_family == AF_INET6 && !ipv6_addr_v4mapped(addr) >> which means in words if the socket is an IPv6 sockeet and the addr is not >> a v4 mapped v6 address then we *can not* do SMCRv2. And the condition >> when we can is sk_family != AF_INET6 || ipv6_addr_v4mapped(addr) which >> is equivalen to sk_family == AF_INET || ipv6_addr_v4mapped(addr) under >> the aforementioned assumption. > > Hi, Halil > > Thank you for such a detailed derivation. > > Yes, here assume that sk_family == AF_INET || sk_family == AF_INET6. Indeed, > many codes in SMC have already made this assumption, for example, > static int __smc_create(struct net *net, struct socket *sock, int protocol, > int kern, struct socket *clcsock) > { > int family = (protocol == SMCPROTO_SMC6) ? PF_INET6 : PF_INET; > ... > } > And I also believe it is reasonable. > > Before this patch, for SMCR client, only an IPV4 socket can do SMCRv2. This patch > introduce an IPV6 socket with v4 mapped v6 address for SMCRv2. It is equivalen > to sk_family == AF_INET || ipv6_addr_v4mapped(addr) as you described. > >> >> But if we assume sk_family == AF_INET || sk_family == AF_INET6 then >> the #else does not make any sense, because I guess with IPv6 not >> available AF_INET6 is not available ant thus the else is always >> guaranteed to evaluate to false under the assumption made. >> > You are right. The #else here does not make any sense. It's my mistake. > > The condition is easier to understand and read should be like this: > if (!(ini->smcr_version & SMC_V2) || > +#if IS_ENABLED(CONFIG_IPV6) > + (smc->clcsock->sk->sk_family == AF_INET6 && > + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || > +#endif > !smc_clc_ueid_count() || > smc_find_rdma_device(smc, ini)) > ini->smcr_version &= ~SMC_V2; > sorry, I still don't agree on this version. You removed the condition " smc->clcsock->sk->sk_family != AF_INET || " completely. What about the socket with neither AF_INET nor AF_INET6 family? Thanks, Wenjia
On 06.12.24 11:51, Wenjia Zhang wrote: > > > On 06.12.24 07:06, Guangguan Wang wrote: >> >> >> On 2024/12/5 20:58, Halil Pasic wrote: >>> On Thu, 5 Dec 2024 11:16:27 +0100 >>> Wenjia Zhang <wenjia@linux.ibm.com> wrote: >>> >>>>> --- a/net/smc/af_smc.c >>>>> +++ b/net/smc/af_smc.c >>>>> @@ -1116,7 +1116,12 @@ static int smc_find_proposal_devices(struct >>>>> smc_sock *smc, ini->check_smcrv2 = true; >>>>> ini->smcrv2.saddr = smc->clcsock->sk->sk_rcv_saddr; >>>>> if (!(ini->smcr_version & SMC_V2) || >>>>> +#if IS_ENABLED(CONFIG_IPV6) >>>>> + (smc->clcsock->sk->sk_family != AF_INET && >>>>> + >>>>> !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || >>>> I think here you want to say !(smc->clcsock->sk->sk_family == AF_INET >>>> && ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)), right? If >>>> it is, the negativ form of the logical operation (a&&b) is (!a)||(!b), >>>> i.e. here should be: >>>> (smc->clcsock->sk->sk_family != AF_INET)|| >>>> (!ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) >>> >>> Wenjia, I think you happen to confuse something here. The condition >>> of this if statement is supposed to evaluate as true iff we don't want >>> to propose SMCRv2 because the situation is such that SMCRv2 is not >>> supported. >>> >>> We have a bunch of conditions we need to meet for SMCRv2 so >>> logically we have (A && B && C && D). Now since the if is >>> about when SMCRv2 is not supported we have a super structure >>> that looks like !A || !B || !C || !D. With this patch, if >>> CONFIG_IPV6 is not enabled, the sub-condition remains the same: >>> if smc->clcsock->sk->sk_family is something else that AF_INET >>> the we do not do SMCRv2! >>> >>> But when we do have CONFIG_IPV6 then we want to do SMCRv2 for >>> AF_INET6 sockets too if the addresses used are actually >>> v4 mapped addresses. >>> >>> Now this is where the cognitive dissonance starts on my end. I >>> think the author assumes sk_family == AF_INET || sk_family == AF_INET6 >>> is a tautology in this context. That may be a reasonable thing to >>> assume. Under that assumption >>> sk_family != AF_INET && !ipv6_addr_v4mapped(addr) (shortened for >>> convenience) >>> becomes equivalent to >>> sk_family == AF_INET6 && !ipv6_addr_v4mapped(addr) >>> which means in words if the socket is an IPv6 sockeet and the addr is >>> not >>> a v4 mapped v6 address then we *can not* do SMCRv2. And the condition >>> when we can is sk_family != AF_INET6 || ipv6_addr_v4mapped(addr) which >>> is equivalen to sk_family == AF_INET || ipv6_addr_v4mapped(addr) under >>> the aforementioned assumption. >> >> Hi, Halil >> >> Thank you for such a detailed derivation. >> >> Yes, here assume that sk_family == AF_INET || sk_family == AF_INET6. >> Indeed, >> many codes in SMC have already made this assumption, for example, >> static int __smc_create(struct net *net, struct socket *sock, int >> protocol, >> int kern, struct socket *clcsock) >> { >> int family = (protocol == SMCPROTO_SMC6) ? PF_INET6 : PF_INET; >> ... >> } >> And I also believe it is reasonable. >> >> Before this patch, for SMCR client, only an IPV4 socket can do SMCRv2. >> This patch >> introduce an IPV6 socket with v4 mapped v6 address for SMCRv2. It is >> equivalen >> to sk_family == AF_INET || ipv6_addr_v4mapped(addr) as you described. >> >>> >>> But if we assume sk_family == AF_INET || sk_family == AF_INET6 then >>> the #else does not make any sense, because I guess with IPv6 not >>> available AF_INET6 is not available ant thus the else is always >>> guaranteed to evaluate to false under the assumption made. >>> >> You are right. The #else here does not make any sense. It's my mistake. >> >> The condition is easier to understand and read should be like this: >> if (!(ini->smcr_version & SMC_V2) || >> +#if IS_ENABLED(CONFIG_IPV6) >> + (smc->clcsock->sk->sk_family == AF_INET6 && >> + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || >> +#endif >> !smc_clc_ueid_count() || >> smc_find_rdma_device(smc, ini)) >> ini->smcr_version &= ~SMC_V2; >> > > sorry, I still don't agree on this version. You removed the condition > " > smc->clcsock->sk->sk_family != AF_INET || > " > completely. What about the socket with neither AF_INET nor AF_INET6 family? > > Thanks, > Wenjia > I think the main problem in the original version was that (sk_family != AF_INET) is not equivalent to (sk_family == AF_INET6). Since you already in the new version above used sk_family == AF_INET6, the else condition could stay as it is. My suggestion: diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 8e3093938cd2..5f205a41fc48 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -1116,7 +1116,12 @@ static int smc_find_proposal_devices(struct smc_sock *smc, ini->check_smcrv2 = true; ini->smcrv2.saddr = smc->clcsock->sk->sk_rcv_saddr; if (!(ini->smcr_version & SMC_V2) || +#if IS_ENABLED(CONFIG_IPV6) + (smc->clcsock->sk->sk_family == AF_INET6 && + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || +#else smc->clcsock->sk->sk_family != AF_INET || +#endif !smc_clc_ueid_count() || smc_find_rdma_device(smc, ini)) ini->smcr_version &= ~SMC_V2; Thanks, Wenjia
On 2024/12/7 03:49, Wenjia Zhang wrote: > > > On 06.12.24 11:51, Wenjia Zhang wrote: >> >> >> On 06.12.24 07:06, Guangguan Wang wrote: >>> >>> >>> On 2024/12/5 20:58, Halil Pasic wrote: >>>> On Thu, 5 Dec 2024 11:16:27 +0100 >>>> Wenjia Zhang <wenjia@linux.ibm.com> wrote: >>>> >>>>>> --- a/net/smc/af_smc.c >>>>>> +++ b/net/smc/af_smc.c >>>>>> @@ -1116,7 +1116,12 @@ static int smc_find_proposal_devices(struct >>>>>> smc_sock *smc, ini->check_smcrv2 = true; >>>>>> ini->smcrv2.saddr = smc->clcsock->sk->sk_rcv_saddr; >>>>>> if (!(ini->smcr_version & SMC_V2) || >>>>>> +#if IS_ENABLED(CONFIG_IPV6) >>>>>> + (smc->clcsock->sk->sk_family != AF_INET && >>>>>> + >>>>>> !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || >>>>> I think here you want to say !(smc->clcsock->sk->sk_family == AF_INET >>>>> && ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)), right? If >>>>> it is, the negativ form of the logical operation (a&&b) is (!a)||(!b), >>>>> i.e. here should be: >>>>> (smc->clcsock->sk->sk_family != AF_INET)|| >>>>> (!ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) >>>> >>>> Wenjia, I think you happen to confuse something here. The condition >>>> of this if statement is supposed to evaluate as true iff we don't want >>>> to propose SMCRv2 because the situation is such that SMCRv2 is not >>>> supported. >>>> >>>> We have a bunch of conditions we need to meet for SMCRv2 so >>>> logically we have (A && B && C && D). Now since the if is >>>> about when SMCRv2 is not supported we have a super structure >>>> that looks like !A || !B || !C || !D. With this patch, if >>>> CONFIG_IPV6 is not enabled, the sub-condition remains the same: >>>> if smc->clcsock->sk->sk_family is something else that AF_INET >>>> the we do not do SMCRv2! >>>> >>>> But when we do have CONFIG_IPV6 then we want to do SMCRv2 for >>>> AF_INET6 sockets too if the addresses used are actually >>>> v4 mapped addresses. >>>> >>>> Now this is where the cognitive dissonance starts on my end. I >>>> think the author assumes sk_family == AF_INET || sk_family == AF_INET6 >>>> is a tautology in this context. That may be a reasonable thing to >>>> assume. Under that assumption >>>> sk_family != AF_INET && !ipv6_addr_v4mapped(addr) (shortened for >>>> convenience) >>>> becomes equivalent to >>>> sk_family == AF_INET6 && !ipv6_addr_v4mapped(addr) >>>> which means in words if the socket is an IPv6 sockeet and the addr is not >>>> a v4 mapped v6 address then we *can not* do SMCRv2. And the condition >>>> when we can is sk_family != AF_INET6 || ipv6_addr_v4mapped(addr) which >>>> is equivalen to sk_family == AF_INET || ipv6_addr_v4mapped(addr) under >>>> the aforementioned assumption. >>> >>> Hi, Halil >>> >>> Thank you for such a detailed derivation. >>> >>> Yes, here assume that sk_family == AF_INET || sk_family == AF_INET6. Indeed, >>> many codes in SMC have already made this assumption, for example, >>> static int __smc_create(struct net *net, struct socket *sock, int protocol, >>> int kern, struct socket *clcsock) >>> { >>> int family = (protocol == SMCPROTO_SMC6) ? PF_INET6 : PF_INET; >>> ... >>> } >>> And I also believe it is reasonable. >>> >>> Before this patch, for SMCR client, only an IPV4 socket can do SMCRv2. This patch >>> introduce an IPV6 socket with v4 mapped v6 address for SMCRv2. It is equivalen >>> to sk_family == AF_INET || ipv6_addr_v4mapped(addr) as you described. >>> >>>> >>>> But if we assume sk_family == AF_INET || sk_family == AF_INET6 then >>>> the #else does not make any sense, because I guess with IPv6 not >>>> available AF_INET6 is not available ant thus the else is always >>>> guaranteed to evaluate to false under the assumption made. >>>> >>> You are right. The #else here does not make any sense. It's my mistake. >>> >>> The condition is easier to understand and read should be like this: >>> if (!(ini->smcr_version & SMC_V2) || >>> +#if IS_ENABLED(CONFIG_IPV6) >>> + (smc->clcsock->sk->sk_family == AF_INET6 && >>> + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || >>> +#endif >>> !smc_clc_ueid_count() || >>> smc_find_rdma_device(smc, ini)) >>> ini->smcr_version &= ~SMC_V2; >>> >> >> sorry, I still don't agree on this version. You removed the condition >> " >> smc->clcsock->sk->sk_family != AF_INET || >> " >> completely. What about the socket with neither AF_INET nor AF_INET6 family? >> >> Thanks, >> Wenjia >> > I think the main problem in the original version was that > (sk_family != AF_INET) is not equivalent to (sk_family == AF_INET6). > Since you already in the new version above used sk_family == AF_INET6, > the else condition could stay as it is. My suggestion: > > diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c > index 8e3093938cd2..5f205a41fc48 100644 > --- a/net/smc/af_smc.c > +++ b/net/smc/af_smc.c > @@ -1116,7 +1116,12 @@ static int smc_find_proposal_devices(struct smc_sock *smc, > ini->check_smcrv2 = true; > ini->smcrv2.saddr = smc->clcsock->sk->sk_rcv_saddr; > if (!(ini->smcr_version & SMC_V2) || > +#if IS_ENABLED(CONFIG_IPV6) > + (smc->clcsock->sk->sk_family == AF_INET6 && > + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || > +#else > smc->clcsock->sk->sk_family != AF_INET || > +#endif > !smc_clc_ueid_count() || > smc_find_rdma_device(smc, ini)) > ini->smcr_version &= ~SMC_V2; > > Thanks, > Wenjia The RFC7609 have confined SMC to socket applications using stream (i.e., TCP) sockets over IPv4 or IPv6. https://datatracker.ietf.org/doc/html/rfc7609#page-26:~:text=It%20is%20confined%20to%20socket%20applications%20using%20stream%0A%20%20%20(i.e.%2C%20TCP)%20sockets%20over%20IPv4%20or%20IPv6 Both in the smc-tools and in smc kernel module, we can see codes that the sk_family is either AF_INET or AF_INET6. The codes here: https://raw.githubusercontent.com/ibm-s390-linux/smc-tools/refs/heads/main/smc-preload.c#:~:text=if%20((domain%20%3D%3D%20AF_INET%20%7C%7C%20domain%20%3D%3D%20AF_INET6)%20%26%26 and https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/net/smc/af_smc.c#:~:text=(sk%2D%3Esk_family%20!%3D%20AF_INET%20%26%26%20sk%2D%3Esk_family%20!%3D%20AF_INET6)) https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/net/smc/af_smc.c#:~:text=int%20family%20%3D%20(protocol%20%3D%3D%20SMCPROTO_SMC6)%20%3F%20PF_INET6%20%3A%20PF_INET%3B https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/net/smc/af_smc.c#:~:text=%2D%3Esin_family%20!%3D-,AF_INET,-%26%26%0A%09%20%20%20%20addr%2D%3E https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/net/smc/af_smc.c#:~:text=%2D%3Esa_family%20!%3D-,AF_INET6,-)%0A%09%09goto%20out_err ... I wonder if SMC-R can support other address famliy rather than AF_INET AF_INET6 in design? And IBM has any plan to support other address family in future? Wenjia, can you help explain this? If the answer is positive, the code should be like this: if (!(ini->smcr_version & SMC_V2) || +#if IS_ENABLED(CONFIG_IPV6) + !(smc->clcsock->sk->sk_family == AF_INET || (smc->clcsock->sk->sk_family == AF_INET6 && + ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr))) || +#else smc->clcsock->sk->sk_family != AF_INET || +#endif !smc_clc_ueid_count() || smc_find_rdma_device(smc, ini)) ini->smcr_version &= ~SMC_V2; Otherwise, the code below is reasonable. if (!(ini->smcr_version & SMC_V2) || +#if IS_ENABLED(CONFIG_IPV6) + (smc->clcsock->sk->sk_family == AF_INET6 && + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || +#endif !smc_clc_ueid_count() || smc_find_rdma_device(smc, ini)) ini->smcr_version &= ~SMC_V2; Thanks, Guangguan Wang
On 09.12.24 07:04, Guangguan Wang wrote: > > > On 2024/12/7 03:49, Wenjia Zhang wrote: >> >> >> On 06.12.24 11:51, Wenjia Zhang wrote: >>> >>> >>> On 06.12.24 07:06, Guangguan Wang wrote: >>>> >>>> >>>> On 2024/12/5 20:58, Halil Pasic wrote: >>>>> On Thu, 5 Dec 2024 11:16:27 +0100 >>>>> Wenjia Zhang <wenjia@linux.ibm.com> wrote: >>>>> >>>>>>> --- a/net/smc/af_smc.c >>>>>>> +++ b/net/smc/af_smc.c >>>>>>> @@ -1116,7 +1116,12 @@ static int smc_find_proposal_devices(struct >>>>>>> smc_sock *smc, ini->check_smcrv2 = true; >>>>>>> ini->smcrv2.saddr = smc->clcsock->sk->sk_rcv_saddr; >>>>>>> if (!(ini->smcr_version & SMC_V2) || >>>>>>> +#if IS_ENABLED(CONFIG_IPV6) >>>>>>> + (smc->clcsock->sk->sk_family != AF_INET && >>>>>>> + >>>>>>> !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || >>>>>> I think here you want to say !(smc->clcsock->sk->sk_family == AF_INET >>>>>> && ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)), right? If >>>>>> it is, the negativ form of the logical operation (a&&b) is (!a)||(!b), >>>>>> i.e. here should be: >>>>>> (smc->clcsock->sk->sk_family != AF_INET)|| >>>>>> (!ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) >>>>> >>>>> Wenjia, I think you happen to confuse something here. The condition >>>>> of this if statement is supposed to evaluate as true iff we don't want >>>>> to propose SMCRv2 because the situation is such that SMCRv2 is not >>>>> supported. >>>>> >>>>> We have a bunch of conditions we need to meet for SMCRv2 so >>>>> logically we have (A && B && C && D). Now since the if is >>>>> about when SMCRv2 is not supported we have a super structure >>>>> that looks like !A || !B || !C || !D. With this patch, if >>>>> CONFIG_IPV6 is not enabled, the sub-condition remains the same: >>>>> if smc->clcsock->sk->sk_family is something else that AF_INET >>>>> the we do not do SMCRv2! >>>>> >>>>> But when we do have CONFIG_IPV6 then we want to do SMCRv2 for >>>>> AF_INET6 sockets too if the addresses used are actually >>>>> v4 mapped addresses. >>>>> >>>>> Now this is where the cognitive dissonance starts on my end. I >>>>> think the author assumes sk_family == AF_INET || sk_family == AF_INET6 >>>>> is a tautology in this context. That may be a reasonable thing to >>>>> assume. Under that assumption >>>>> sk_family != AF_INET && !ipv6_addr_v4mapped(addr) (shortened for >>>>> convenience) >>>>> becomes equivalent to >>>>> sk_family == AF_INET6 && !ipv6_addr_v4mapped(addr) >>>>> which means in words if the socket is an IPv6 sockeet and the addr is not >>>>> a v4 mapped v6 address then we *can not* do SMCRv2. And the condition >>>>> when we can is sk_family != AF_INET6 || ipv6_addr_v4mapped(addr) which >>>>> is equivalen to sk_family == AF_INET || ipv6_addr_v4mapped(addr) under >>>>> the aforementioned assumption. >>>> >>>> Hi, Halil >>>> >>>> Thank you for such a detailed derivation. >>>> >>>> Yes, here assume that sk_family == AF_INET || sk_family == AF_INET6. Indeed, >>>> many codes in SMC have already made this assumption, for example, >>>> static int __smc_create(struct net *net, struct socket *sock, int protocol, >>>> int kern, struct socket *clcsock) >>>> { >>>> int family = (protocol == SMCPROTO_SMC6) ? PF_INET6 : PF_INET; >>>> ... >>>> } >>>> And I also believe it is reasonable. >>>> >>>> Before this patch, for SMCR client, only an IPV4 socket can do SMCRv2. This patch >>>> introduce an IPV6 socket with v4 mapped v6 address for SMCRv2. It is equivalen >>>> to sk_family == AF_INET || ipv6_addr_v4mapped(addr) as you described. >>>> >>>>> >>>>> But if we assume sk_family == AF_INET || sk_family == AF_INET6 then >>>>> the #else does not make any sense, because I guess with IPv6 not >>>>> available AF_INET6 is not available ant thus the else is always >>>>> guaranteed to evaluate to false under the assumption made. >>>>> >>>> You are right. The #else here does not make any sense. It's my mistake. >>>> >>>> The condition is easier to understand and read should be like this: >>>> if (!(ini->smcr_version & SMC_V2) || >>>> +#if IS_ENABLED(CONFIG_IPV6) >>>> + (smc->clcsock->sk->sk_family == AF_INET6 && >>>> + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || >>>> +#endif >>>> !smc_clc_ueid_count() || >>>> smc_find_rdma_device(smc, ini)) >>>> ini->smcr_version &= ~SMC_V2; >>>> >>> >>> sorry, I still don't agree on this version. You removed the condition >>> " >>> smc->clcsock->sk->sk_family != AF_INET || >>> " >>> completely. What about the socket with neither AF_INET nor AF_INET6 family? >>> >>> Thanks, >>> Wenjia >>> >> I think the main problem in the original version was that >> (sk_family != AF_INET) is not equivalent to (sk_family == AF_INET6). >> Since you already in the new version above used sk_family == AF_INET6, >> the else condition could stay as it is. My suggestion: >> >> diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c >> index 8e3093938cd2..5f205a41fc48 100644 >> --- a/net/smc/af_smc.c >> +++ b/net/smc/af_smc.c >> @@ -1116,7 +1116,12 @@ static int smc_find_proposal_devices(struct smc_sock *smc, >> ini->check_smcrv2 = true; >> ini->smcrv2.saddr = smc->clcsock->sk->sk_rcv_saddr; >> if (!(ini->smcr_version & SMC_V2) || >> +#if IS_ENABLED(CONFIG_IPV6) >> + (smc->clcsock->sk->sk_family == AF_INET6 && >> + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || >> +#else >> smc->clcsock->sk->sk_family != AF_INET || >> +#endif >> !smc_clc_ueid_count() || >> smc_find_rdma_device(smc, ini)) >> ini->smcr_version &= ~SMC_V2; >> >> Thanks, >> Wenjia > > The RFC7609 have confined SMC to socket applications using stream (i.e., TCP) sockets over IPv4 or IPv6. > https://datatracker.ietf.org/doc/html/rfc7609#page-26:~:text=It%20is%20confined%20to%20socket%20applications%20using%20stream%0A%20%20%20(i.e.%2C%20TCP)%20sockets%20over%20IPv4%20or%20IPv6 > > Both in the smc-tools and in smc kernel module, we can see codes that the sk_family is either AF_INET or AF_INET6. > The codes here: > https://raw.githubusercontent.com/ibm-s390-linux/smc-tools/refs/heads/main/smc-preload.c#:~:text=if%20((domain%20%3D%3D%20AF_INET%20%7C%7C%20domain%20%3D%3D%20AF_INET6)%20%26%26 > and > https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/net/smc/af_smc.c#:~:text=(sk%2D%3Esk_family%20!%3D%20AF_INET%20%26%26%20sk%2D%3Esk_family%20!%3D%20AF_INET6)) > https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/net/smc/af_smc.c#:~:text=int%20family%20%3D%20(protocol%20%3D%3D%20SMCPROTO_SMC6)%20%3F%20PF_INET6%20%3A%20PF_INET%3B > https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/net/smc/af_smc.c#:~:text=%2D%3Esin_family%20!%3D-,AF_INET,-%26%26%0A%09%20%20%20%20addr%2D%3E > https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/net/smc/af_smc.c#:~:text=%2D%3Esa_family%20!%3D-,AF_INET6,-)%0A%09%09goto%20out_err > ... > > I wonder if SMC-R can support other address famliy rather than AF_INET AF_INET6 in design? > And IBM has any plan to support other address family in future? Wenjia, can you help explain > this? > The answer is no, at least in the near future. As you might be already aware, it depends on the implementation on z/OS. > If the answer is positive, the code should be like this: > if (!(ini->smcr_version & SMC_V2) || > +#if IS_ENABLED(CONFIG_IPV6) > + !(smc->clcsock->sk->sk_family == AF_INET || (smc->clcsock->sk->sk_family == AF_INET6 && > + ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr))) || > +#else > smc->clcsock->sk->sk_family != AF_INET || > +#endif > !smc_clc_ueid_count() || > smc_find_rdma_device(smc, ini)) > ini->smcr_version &= ~SMC_V2; > > Otherwise, the code below is reasonable. > if (!(ini->smcr_version & SMC_V2) || > +#if IS_ENABLED(CONFIG_IPV6) > + (smc->clcsock->sk->sk_family == AF_INET6 && > + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || > +#endif > !smc_clc_ueid_count() || > smc_find_rdma_device(smc, ini)) > ini->smcr_version &= ~SMC_V2; > Ok, I got your point, a socket with an address family other than AF_INET and AF_INET6 is already pre-filtered, so that such extra condition checking for the smc->clcsock->sk->sk_family != AF_INET is not necessary, right? Would you like to send a new version? And feel free to use this in the new version: Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com> Thanks, Wenjia
On Mon, 9 Dec 2024 09:49:23 +0100 Wenjia Zhang <wenjia@linux.ibm.com> wrote: > > Otherwise, the code below is reasonable. > > if (!(ini->smcr_version & SMC_V2) || > > +#if IS_ENABLED(CONFIG_IPV6) > > + (smc->clcsock->sk->sk_family == AF_INET6 && > > + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || > > +#endif > > !smc_clc_ueid_count() || > > smc_find_rdma_device(smc, ini)) > > ini->smcr_version &= ~SMC_V2; > > > Ok, I got your point, a socket with an address family other than AF_INET > and AF_INET6 is already pre-filtered, so that such extra condition > checking for the smc->clcsock->sk->sk_family != AF_INET is not > necessary, right? > > Would you like to send a new version? And feel free to use this in the > new version: > > Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com> I believe we would like to have a v3 here. Also I'm not sure checking on saddr is sufficient, but I didn't do my research on that question yet. Regards, Halil
On 2024/12/9 17:46, Halil Pasic wrote: > On Mon, 9 Dec 2024 09:49:23 +0100 > Wenjia Zhang <wenjia@linux.ibm.com> wrote: > >>> Otherwise, the code below is reasonable. >>> if (!(ini->smcr_version & SMC_V2) || >>> +#if IS_ENABLED(CONFIG_IPV6) >>> + (smc->clcsock->sk->sk_family == AF_INET6 && >>> + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || >>> +#endif >>> !smc_clc_ueid_count() || >>> smc_find_rdma_device(smc, ini)) >>> ini->smcr_version &= ~SMC_V2; >>> >> Ok, I got your point, a socket with an address family other than AF_INET >> and AF_INET6 is already pre-filtered, so that such extra condition >> checking for the smc->clcsock->sk->sk_family != AF_INET is not >> necessary, right? >> >> Would you like to send a new version? And feel free to use this in the >> new version: >> >> Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com> > > I believe we would like to have a v3 here. Also I'm not sure > checking on saddr is sufficient, but I didn't do my research on > that question yet. > > Regards, > Halil Did you mean to research whether the daddr should be checked too? Thanks, Guangguan Wang
On Mon, 9 Dec 2024 20:36:45 +0800 Guangguan Wang <guangguan.wang@linux.alibaba.com> wrote: > > I believe we would like to have a v3 here. Also I'm not sure > > checking on saddr is sufficient, but I didn't do my research on > > that question yet. > > > > Regards, > > Halil > > Did you mean to research whether the daddr should be checked too? Right! Or is it implied that if saddr is a ipv4 mapped ipv6 addr then the daddr must be ipv4 mapped ipv6 addr as well? Regards, Halil
On 2024/12/10 04:44, Halil Pasic wrote: > On Mon, 9 Dec 2024 20:36:45 +0800 > Guangguan Wang <guangguan.wang@linux.alibaba.com> wrote: > >>> I believe we would like to have a v3 here. Also I'm not sure >>> checking on saddr is sufficient, but I didn't do my research on >>> that question yet. >>> >>> Regards, >>> Halil >> >> Did you mean to research whether the daddr should be checked too? > > Right! Or is it implied that if saddr is a ipv4 mapped ipv6 addr > then the daddr must be ipv4 mapped ipv6 addr as well? > > Regards, > Halil I did a test by iperf3: A server with IPV4 addr 11.213.5.33/24 and real IPV6 addr 2012::1/64. A client with IPV4 addr 11.213.5.5/24 and real IPV6 addr 2012::2/64. iperf3 fails to run when server listen on IPV6 addr and client connect to server using IPV4 mapped IPV6 addr. commands show below: server: smc_run iperf3 -s -6 -B 2012::1 client: smc_run iperf3 -t 10 -c 2012::1 -6 -B ::ffff:11.213.5.5 Failure happened due to the connect() function got the errno -EAFNOSUPPORT, I also located the kernel code where the -EAFNOSUPPORT is returned (https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/net/ipv6/ip6_output.c#:~:text=err%20%3D%20%2DEAFNOSUPPORT%3B). The call stack is: ip6_dst_lookup_tail+1 ip6_dst_lookup_flow+55 tcp_v6_connect+743 __inet_stream_connect+181 inet_stream_connect+59 kernel_connect+109 smc_connect+239 __sys_connect+179 __x64_sys_connect+26 do_syscall_64+112 entry_SYSCALL_64_after_hwframe+118 The kernel code mentioned above restricts that when the saddr is ipv4 mapped ipv6 addr, the daddr should be either ipv4 mapped ipv6 addr or ipv6_addr_any(::). As far as I know, the ipv6_addr_any daddr is used to connect to a server listen on ipv6_addr_any(::) by loopback connection. Thus, based on the test and the code, I think it has the restrict that for SMC-Rv2 if saddr is a ipv4 mapped ipv6 addr then the daddr must be ipv4 mapped ipv6 addr as well. Thanks, Guangguan Wang
On Tue, 10 Dec 2024 15:07:04 +0800 Guangguan Wang <guangguan.wang@linux.alibaba.com> wrote: > On 2024/12/10 04:44, Halil Pasic wrote: > > On Mon, 9 Dec 2024 20:36:45 +0800 > > Guangguan Wang <guangguan.wang@linux.alibaba.com> wrote: > > > >>> I believe we would like to have a v3 here. Also I'm not sure > >>> checking on saddr is sufficient, but I didn't do my research on > >>> that question yet. > >>> > >>> Regards, > >>> Halil > >> > >> Did you mean to research whether the daddr should be checked too? > > > > Right! Or is it implied that if saddr is a ipv4 mapped ipv6 addr > > then the daddr must be ipv4 mapped ipv6 addr as well? > > > > Regards, > > Halil > > I did a test by iperf3: > A server with IPV4 addr 11.213.5.33/24 and real IPV6 addr 2012::1/64. > A client with IPV4 addr 11.213.5.5/24 and real IPV6 addr 2012::2/64. > iperf3 fails to run when server listen on IPV6 addr and client connect > to server using IPV4 mapped IPV6 addr. commands show below: > server: smc_run iperf3 -s -6 -B 2012::1 > client: smc_run iperf3 -t 10 -c 2012::1 -6 -B ::ffff:11.213.5.5 > > Failure happened due to the connect() function got the errno -EAFNOSUPPORT, > I also located the kernel code where the -EAFNOSUPPORT is returned > (https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/net/ipv6/ip6_output.c#:~:text=err%20%3D%20%2DEAFNOSUPPORT%3B). Thanks! That is enough for me!
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 9d76e902fd77..5b13dd759766 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -1116,7 +1116,12 @@ static int smc_find_proposal_devices(struct smc_sock *smc, ini->check_smcrv2 = true; ini->smcrv2.saddr = smc->clcsock->sk->sk_rcv_saddr; if (!(ini->smcr_version & SMC_V2) || +#if IS_ENABLED(CONFIG_IPV6) + (smc->clcsock->sk->sk_family != AF_INET && + !ipv6_addr_v4mapped(&smc->clcsock->sk->sk_v6_rcv_saddr)) || +#else smc->clcsock->sk->sk_family != AF_INET || +#endif !smc_clc_ueid_count() || smc_find_rdma_device(smc, ini)) ini->smcr_version &= ~SMC_V2;