Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/smc: fix smc clc failed issue when netdevice not in init_net

If the netdevice is within a container and communicates externally
through network technologies such as VxLAN, we won't be able to find
routing information in the init_net namespace. To address this issue,
we need to add a struct net parameter to the smc_ib_find_route function.
This allow us to locate the routing information within the corresponding
net namespace, ensuring the correct completion of the SMC CLC interaction.

Fixes: e5c4744cfb59 ("net/smc: add SMC-Rv2 connection establishment")
Signed-off-by: Albert Huang <huangjie.albert@bytedance.com>
Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com>
Link: https://lore.kernel.org/r/20231011074851.95280-1-huangjie.albert@bytedance.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Albert Huang and committed by
Jakub Kicinski
c68681ae 419ce133

+7 -5
+2 -1
net/smc/af_smc.c
··· 1201 1201 (struct smc_clc_msg_accept_confirm_v2 *)aclc; 1202 1202 struct smc_clc_first_contact_ext *fce = 1203 1203 smc_get_clc_first_contact_ext(clc_v2, false); 1204 + struct net *net = sock_net(&smc->sk); 1204 1205 int rc; 1205 1206 1206 1207 if (!ini->first_contact_peer || aclc->hdr.version == SMC_V1) ··· 1211 1210 memcpy(ini->smcrv2.nexthop_mac, &aclc->r0.lcl.mac, ETH_ALEN); 1212 1211 ini->smcrv2.uses_gateway = false; 1213 1212 } else { 1214 - if (smc_ib_find_route(smc->clcsock->sk->sk_rcv_saddr, 1213 + if (smc_ib_find_route(net, smc->clcsock->sk->sk_rcv_saddr, 1215 1214 smc_ib_gid_to_ipv4(aclc->r0.lcl.gid), 1216 1215 ini->smcrv2.nexthop_mac, 1217 1216 &ini->smcrv2.uses_gateway))
+4 -3
net/smc/smc_ib.c
··· 193 193 return smcibdev->pattr[ibport - 1].state == IB_PORT_ACTIVE; 194 194 } 195 195 196 - int smc_ib_find_route(__be32 saddr, __be32 daddr, 196 + int smc_ib_find_route(struct net *net, __be32 saddr, __be32 daddr, 197 197 u8 nexthop_mac[], u8 *uses_gateway) 198 198 { 199 199 struct neighbour *neigh = NULL; ··· 205 205 206 206 if (daddr == cpu_to_be32(INADDR_NONE)) 207 207 goto out; 208 - rt = ip_route_output_flow(&init_net, &fl4, NULL); 208 + rt = ip_route_output_flow(net, &fl4, NULL); 209 209 if (IS_ERR(rt)) 210 210 goto out; 211 211 if (rt->rt_uses_gateway && rt->rt_gw_family != AF_INET) ··· 235 235 if (smcrv2 && attr->gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP && 236 236 smc_ib_gid_to_ipv4((u8 *)&attr->gid) != cpu_to_be32(INADDR_NONE)) { 237 237 struct in_device *in_dev = __in_dev_get_rcu(ndev); 238 + struct net *net = dev_net(ndev); 238 239 const struct in_ifaddr *ifa; 239 240 bool subnet_match = false; 240 241 ··· 249 248 } 250 249 if (!subnet_match) 251 250 goto out; 252 - if (smcrv2->daddr && smc_ib_find_route(smcrv2->saddr, 251 + if (smcrv2->daddr && smc_ib_find_route(net, smcrv2->saddr, 253 252 smcrv2->daddr, 254 253 smcrv2->nexthop_mac, 255 254 &smcrv2->uses_gateway))
+1 -1
net/smc/smc_ib.h
··· 112 112 int smc_ib_determine_gid(struct smc_ib_device *smcibdev, u8 ibport, 113 113 unsigned short vlan_id, u8 gid[], u8 *sgid_index, 114 114 struct smc_init_info_smcrv2 *smcrv2); 115 - int smc_ib_find_route(__be32 saddr, __be32 daddr, 115 + int smc_ib_find_route(struct net *net, __be32 saddr, __be32 daddr, 116 116 u8 nexthop_mac[], u8 *uses_gateway); 117 117 bool smc_ib_is_valid_local_systemid(void); 118 118 int smcr_nl_get_device(struct sk_buff *skb, struct netlink_callback *cb);