diff options
author | Ka-Cheong Poon <ka-cheong.poon@oracle.com> | 2018-07-23 23:51:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-07-24 00:17:44 -0400 |
commit | 1e2b44e78eead7bcadfbf96f70d95773191541c9 (patch) | |
tree | e7944339dd957ae23cfd690cb0ad6962d98c053c /net/rds/ib_cm.c | |
parent | eee2fa6ab3225192d6d894c54a6fb02ac9efdff6 (diff) |
rds: Enable RDS IPv6 support
This patch enables RDS to use IPv6 addresses. For RDS/TCP, the
listener is now an IPv6 endpoint which accepts both IPv4 and IPv6
connection requests. RDS/RDMA/IB uses a private data (struct
rds_ib_connect_private) exchange between endpoints at RDS connection
establishment time to support RDMA. This private data exchange uses a
32 bit integer to represent an IP address. This needs to be changed in
order to support IPv6. A new private data struct
rds6_ib_connect_private is introduced to handle this. To ensure
backward compatibility, an IPv6 capable RDS stack uses another RDMA
listener port (RDS_CM_PORT) to accept IPv6 connection. And it
continues to use the original RDS_PORT for IPv4 RDS connections. When
it needs to communicate with an IPv6 peer, it uses the RDS_CM_PORT to
send the connection set up request.
v5: Fixed syntax problem (David Miller).
v4: Changed port history comments in rds.h (Sowmini Varadhan).
v3: Added support to set up IPv4 connection using mapped address
(David Miller).
Added support to set up connection between link local and non-link
addresses.
Various review comments from Santosh Shilimkar and Sowmini Varadhan.
v2: Fixed bound and peer address scope mismatched issue.
Added back rds_connect() IPv6 changes.
Signed-off-by: Ka-Cheong Poon <ka-cheong.poon@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/rds/ib_cm.c')
-rw-r--r-- | net/rds/ib_cm.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index dd8a867e5a9c..a33b82dc0804 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c | |||
@@ -678,7 +678,7 @@ static u32 rds_ib_protocol_compatible(struct rdma_cm_event *event, bool isv6) | |||
678 | return version; | 678 | return version; |
679 | } | 679 | } |
680 | 680 | ||
681 | /* Given an IPv6 address, find the IB net_device which hosts that address and | 681 | /* Given an IPv6 address, find the net_device which hosts that address and |
682 | * return its index. This is used by the rds_ib_cm_handle_connect() code to | 682 | * return its index. This is used by the rds_ib_cm_handle_connect() code to |
683 | * find the interface index of where an incoming request comes from when | 683 | * find the interface index of where an incoming request comes from when |
684 | * the request is using a link local address. | 684 | * the request is using a link local address. |
@@ -695,8 +695,7 @@ static u32 __rds_find_ifindex(struct net *net, const struct in6_addr *addr) | |||
695 | 695 | ||
696 | rcu_read_lock(); | 696 | rcu_read_lock(); |
697 | for_each_netdev_rcu(net, dev) { | 697 | for_each_netdev_rcu(net, dev) { |
698 | if (dev->type == ARPHRD_INFINIBAND && | 698 | if (ipv6_chk_addr(net, addr, dev, 1)) { |
699 | ipv6_chk_addr(net, addr, dev, 0)) { | ||
700 | idx = dev->ifindex; | 699 | idx = dev->ifindex; |
701 | break; | 700 | break; |
702 | } | 701 | } |
@@ -736,7 +735,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, | |||
736 | dp_cmn = &dp->ricp_v6.dp_cmn; | 735 | dp_cmn = &dp->ricp_v6.dp_cmn; |
737 | saddr6 = &dp->ricp_v6.dp_saddr; | 736 | saddr6 = &dp->ricp_v6.dp_saddr; |
738 | daddr6 = &dp->ricp_v6.dp_daddr; | 737 | daddr6 = &dp->ricp_v6.dp_daddr; |
739 | /* If the local address is link local, need to find the | 738 | /* If either address is link local, need to find the |
740 | * interface index in order to create a proper RDS | 739 | * interface index in order to create a proper RDS |
741 | * connection. | 740 | * connection. |
742 | */ | 741 | */ |
@@ -748,6 +747,14 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, | |||
748 | err = -EOPNOTSUPP; | 747 | err = -EOPNOTSUPP; |
749 | goto out; | 748 | goto out; |
750 | } | 749 | } |
750 | } else if (ipv6_addr_type(saddr6) & IPV6_ADDR_LINKLOCAL) { | ||
751 | /* Use our address to find the correct index. */ | ||
752 | ifindex = __rds_find_ifindex(&init_net, daddr6); | ||
753 | /* No index found... Need to bail out. */ | ||
754 | if (ifindex == 0) { | ||
755 | err = -EOPNOTSUPP; | ||
756 | goto out; | ||
757 | } | ||
751 | } | 758 | } |
752 | } else { | 759 | } else { |
753 | dp_cmn = &dp->ricp_v4.dp_cmn; | 760 | dp_cmn = &dp->ricp_v4.dp_cmn; |
@@ -886,7 +893,10 @@ int rds_ib_conn_path_connect(struct rds_conn_path *cp) | |||
886 | 893 | ||
887 | /* XXX I wonder what affect the port space has */ | 894 | /* XXX I wonder what affect the port space has */ |
888 | /* delegate cm event handler to rdma_transport */ | 895 | /* delegate cm event handler to rdma_transport */ |
889 | handler = rds_rdma_cm_event_handler; | 896 | if (conn->c_isv6) |
897 | handler = rds6_rdma_cm_event_handler; | ||
898 | else | ||
899 | handler = rds_rdma_cm_event_handler; | ||
890 | ic->i_cm_id = rdma_create_id(&init_net, handler, conn, | 900 | ic->i_cm_id = rdma_create_id(&init_net, handler, conn, |
891 | RDMA_PS_TCP, IB_QPT_RC); | 901 | RDMA_PS_TCP, IB_QPT_RC); |
892 | if (IS_ERR(ic->i_cm_id)) { | 902 | if (IS_ERR(ic->i_cm_id)) { |