aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2012-06-14 16:31:39 -0400
committerRoland Dreier <roland@purestorage.com>2012-07-08 21:02:24 -0400
commit68602120e496a31d8e3b36d0bfc7d9d2456fb05c (patch)
tree04eea1c0673ff60d1e9881b1d73785c0ed6f8271 /drivers/infiniband/core
parent406b6a25f85271397739a7e9f5af1df665b8a0d0 (diff)
RDMA/cma: Allow user to restrict listens to bound address family
Provide an option for the user to specify that listens should only accept connections where the incoming address family matches that of the locally bound address. This is used to support the equivalent of IPV6_V6ONLY socket option, which allows an app to only accept connection requests directed to IPv6 addresses. Signed-off-by: Sean Hefty <sean.hefty@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/core')
-rw-r--r--drivers/infiniband/core/cma.c35
-rw-r--r--drivers/infiniband/core/ucma.c7
2 files changed, 38 insertions, 4 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 454e7ea111e6..8734a6af35d7 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -99,6 +99,10 @@ struct rdma_bind_list {
99 unsigned short port; 99 unsigned short port;
100}; 100};
101 101
102enum {
103 CMA_OPTION_AFONLY,
104};
105
102/* 106/*
103 * Device removal can occur at anytime, so we need extra handling to 107 * Device removal can occur at anytime, so we need extra handling to
104 * serialize notifying the user of device removal with other callbacks. 108 * serialize notifying the user of device removal with other callbacks.
@@ -137,6 +141,7 @@ struct rdma_id_private {
137 u32 qkey; 141 u32 qkey;
138 u32 qp_num; 142 u32 qp_num;
139 pid_t owner; 143 pid_t owner;
144 u32 options;
140 u8 srq; 145 u8 srq;
141 u8 tos; 146 u8 tos;
142 u8 reuseaddr; 147 u8 reuseaddr;
@@ -2104,6 +2109,26 @@ int rdma_set_reuseaddr(struct rdma_cm_id *id, int reuse)
2104} 2109}
2105EXPORT_SYMBOL(rdma_set_reuseaddr); 2110EXPORT_SYMBOL(rdma_set_reuseaddr);
2106 2111
2112int rdma_set_afonly(struct rdma_cm_id *id, int afonly)
2113{
2114 struct rdma_id_private *id_priv;
2115 unsigned long flags;
2116 int ret;
2117
2118 id_priv = container_of(id, struct rdma_id_private, id);
2119 spin_lock_irqsave(&id_priv->lock, flags);
2120 if (id_priv->state == RDMA_CM_IDLE || id_priv->state == RDMA_CM_ADDR_BOUND) {
2121 id_priv->options |= (1 << CMA_OPTION_AFONLY);
2122 id_priv->afonly = afonly;
2123 ret = 0;
2124 } else {
2125 ret = -EINVAL;
2126 }
2127 spin_unlock_irqrestore(&id_priv->lock, flags);
2128 return ret;
2129}
2130EXPORT_SYMBOL(rdma_set_afonly);
2131
2107static void cma_bind_port(struct rdma_bind_list *bind_list, 2132static void cma_bind_port(struct rdma_bind_list *bind_list,
2108 struct rdma_id_private *id_priv) 2133 struct rdma_id_private *id_priv)
2109{ 2134{
@@ -2379,12 +2404,14 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
2379 } 2404 }
2380 2405
2381 memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr)); 2406 memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr));
2382 if (addr->sa_family == AF_INET) 2407 if (!(id_priv->options & (1 << CMA_OPTION_AFONLY))) {
2383 id_priv->afonly = 1; 2408 if (addr->sa_family == AF_INET)
2409 id_priv->afonly = 1;
2384#if IS_ENABLED(CONFIG_IPV6) 2410#if IS_ENABLED(CONFIG_IPV6)
2385 else if (addr->sa_family == AF_INET6) 2411 else if (addr->sa_family == AF_INET6)
2386 id_priv->afonly = init_net.ipv6.sysctl.bindv6only; 2412 id_priv->afonly = init_net.ipv6.sysctl.bindv6only;
2387#endif 2413#endif
2414 }
2388 ret = cma_get_port(id_priv); 2415 ret = cma_get_port(id_priv);
2389 if (ret) 2416 if (ret)
2390 goto err2; 2417 goto err2;
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 8002ae642cfe..893cb879462c 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -909,6 +909,13 @@ static int ucma_set_option_id(struct ucma_context *ctx, int optname,
909 } 909 }
910 ret = rdma_set_reuseaddr(ctx->cm_id, *((int *) optval) ? 1 : 0); 910 ret = rdma_set_reuseaddr(ctx->cm_id, *((int *) optval) ? 1 : 0);
911 break; 911 break;
912 case RDMA_OPTION_ID_AFONLY:
913 if (optlen != sizeof(int)) {
914 ret = -EINVAL;
915 break;
916 }
917 ret = rdma_set_afonly(ctx->cm_id, *((int *) optval) ? 1 : 0);
918 break;
912 default: 919 default:
913 ret = -ENOSYS; 920 ret = -ENOSYS;
914 } 921 }