aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core
diff options
context:
space:
mode:
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 }