Skip to content

Commit 4e9ea3a

Browse files
SantoshShilimkarSomasundaram Krishnasamy
authored andcommitted
RDS: IB: enforce IP anti-spoofing based on ACLs
Connection is established only after the IP requesting the connection is legitimate and part of the ACL group. Invalid connection request(s) are rejected and destroyed. Ajay moved destroy connection when ACL check fails while initiating connection to avoid unnecessary packet transfer on wire. Orabug: 23222944 Orabug: 27300453 Signed-off-by: Bang Ngyen <[email protected]> Signed-off-by: Ajaykumar Hotchandani <[email protected]> Signed-off-by: Yuval Shaia <[email protected]> Signed-off-by: Santosh Shilimkar <[email protected]> Orabug: 27364391 (cherry picked from commit 25e58c2) cherry-pick-repo=linux-uek.git Merge-Monkey-Notes: Need to make this new feature optional right away, in order to be able to meet the requirement that each and every commit compiles: net/rds: Make ACL optional (configurable via CONFIG_RDS_ACL) With the transition to RoCE, and not having a working version of Oracle's ACL to go on top of a RoCE netdev (it was coded straight into IPoIB), we simply make ACL optional for RDS. Merge-Monkey: Gerd Rausch <[email protected]> Signed-off-by: Gerd Rausch <[email protected]> Signed-off-by: Somasundaram Krishnasamy <[email protected]>
1 parent 1cad9c0 commit 4e9ea3a

File tree

2 files changed

+101
-2
lines changed

2 files changed

+101
-2
lines changed

net/rds/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ config RDS_TCP
1919
Allow RDS to use TCP as a transport.
2020
This transport does not support RDMA operations.
2121

22+
config RDS_ACL
23+
bool "RDS support for ACL"
24+
depends on RDS
25+
default n
26+
2227
config RDS_DEBUG
2328
bool "RDS debugging messages"
2429
depends on RDS

net/rds/ib_cm.c

Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@
3434
#include <linux/in.h>
3535
#include <linux/vmalloc.h>
3636
#include <linux/version.h>
37+
#include <linux/kconfig.h>
3738
#include <asm-generic/sizes.h>
3839
#include <rdma/rdma_cm_ib.h>
3940
#include <rdma/ib_cache.h>
41+
#include <rdma/ib_cm.h>
4042

4143
#include "rds.h"
4244
#include "ib.h"
@@ -193,6 +195,58 @@ static inline void rds_ib_init_ic_frag(struct rds_ib_connection *ic)
193195
ic->i_frag_sz = ib_init_frag_size;
194196
}
195197

198+
#ifdef CONFIG_RDS_ACL
199+
200+
/*
201+
* 0 - all good
202+
* 1 - acl is not enabled
203+
* -1 - acl match failed
204+
*/
205+
static int rds_ib_match_acl(struct rdma_cm_id *cm_id, __be32 saddr)
206+
{
207+
struct ib_cm_acl *acl = 0;
208+
struct ib_cm_acl_elem *acl_elem = 0;
209+
__be64 fguid = cm_id->route.path_rec->dgid.global.interface_id;
210+
__be64 fsubnet = cm_id->route.path_rec->dgid.global.subnet_prefix;
211+
struct ib_cm_dpp dpp;
212+
u32 addr;
213+
214+
ib_cm_dpp_init(&dpp, cm_id->device, cm_id->port_num,
215+
ntohs(cm_id->route.path_rec->pkey));
216+
acl = ib_cm_dpp_acl_lookup(&dpp);
217+
if (!acl)
218+
goto out;
219+
220+
if (!acl->enabled)
221+
return 0;
222+
223+
acl_elem = ib_cm_acl_lookup(acl, be64_to_cpu(fsubnet),
224+
be64_to_cpu(fguid));
225+
if (!acl_elem) {
226+
pr_err_ratelimited("RDS/IB: GUID ib_cm_acl_lookup() failed\n");
227+
goto out;
228+
}
229+
230+
addr = be32_to_cpu(saddr);
231+
if (!addr)
232+
goto out;
233+
234+
acl_elem = ib_cm_acl_lookup_uuid_ip(acl, acl_elem->uuid, addr);
235+
if (!acl_elem) {
236+
pr_err_ratelimited("RDS/IB: IP %pI4 ib_cm_acl_lookup_uuid_ip() failed\n",
237+
&saddr);
238+
goto out;
239+
}
240+
241+
return 1;
242+
out:
243+
pr_err_ratelimited("RDS/IB: %s failed due to ACLs. Check ACLs\n",
244+
__func__);
245+
return -1;
246+
}
247+
248+
#endif /* CONFIG_RDS_ACL */
249+
196250
/*
197251
* Connection established.
198252
* We get here for both outgoing and incoming connection.
@@ -232,13 +286,14 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
232286
}
233287
}
234288

235-
printk(KERN_NOTICE "RDS/IB: %s conn %p i_cm_id %p, frag %dKB, connected <%pI4,%pI4,%d> version %u.%u%s\n",
289+
printk(KERN_NOTICE "RDS/IB: %s conn %p i_cm_id %p, frag %dKB, connected <%pI4,%pI4,%d> version %u.%u%s%s\n",
236290
ic->i_active_side ? "Active " : "Passive",
237291
conn, ic->i_cm_id, ic->i_frag_sz / SZ_1K,
238292
&conn->c_laddr, &conn->c_faddr, conn->c_tos,
239293
RDS_PROTOCOL_MAJOR(conn->c_version),
240294
RDS_PROTOCOL_MINOR(conn->c_version),
241-
ic->i_flowctl ? ", flow control" : "");
295+
ic->i_flowctl ? ", flow control" : "",
296+
conn->c_acl_en ? ", ACL Enabled" : "");
242297

243298
/* The connection might have been dropped under us*/
244299
if (!ic->i_cm_id) {
@@ -830,6 +885,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
830885
struct rdma_conn_param conn_param;
831886
u32 version;
832887
int err = 1, destroy = 1;
888+
int acl_ret = 0;
833889

834890
/* Check whether the remote protocol version matches ours. */
835891
version = rds_ib_protocol_compatible(event);
@@ -845,6 +901,21 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
845901
(unsigned long long)be64_to_cpu(fguid),
846902
dp->dp_tos);
847903

904+
#ifdef CONFIG_RDS_ACL
905+
906+
acl_ret = rds_ib_match_acl(cm_id, dp->dp_saddr);
907+
if (acl_ret < 0) {
908+
rdma_reject(cm_id, &acl_ret, sizeof(int));
909+
rdsdebug("RDS: IB: rds_ib_match_acl failed\n");
910+
goto out;
911+
}
912+
913+
#else /* !CONFIG_RDS_ACL */
914+
915+
acl_ret = 0;
916+
917+
#endif /* !CONFIG_RDS_ACL */
918+
848919
/* RDS/IB is not currently netns aware, thus init_net */
849920
conn = rds_conn_create(&init_net, dp->dp_daddr, dp->dp_saddr,
850921
&rds_ib_transport, dp->dp_tos, GFP_KERNEL);
@@ -858,6 +929,9 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
858929
rds_ib_set_protocol(conn, version);
859930
rds_ib_set_frag_size(conn, be16_to_cpu(dp->dp_frag_sz));
860931

932+
conn->c_acl_en = acl_ret;
933+
conn->c_acl_init = 1;
934+
861935
if (dp->dp_tos && !conn->c_base_conn) {
862936
conn->c_base_conn = rds_conn_create(&init_net,
863937
dp->dp_daddr, dp->dp_saddr,
@@ -1027,6 +1101,26 @@ int rds_ib_cm_initiate_connect(struct rdma_cm_id *cm_id)
10271101
struct rds_ib_connect_private dp;
10281102
int ret;
10291103

1104+
#ifdef CONFIG_RDS_ACL
1105+
1106+
ret = rds_ib_match_acl(ic->i_cm_id, conn->c_faddr);
1107+
if (ret < 0) {
1108+
pr_err("RDS: IB: active conn=%p, <%pI4,%pI4,%d> destroyed due ACL violation\n",
1109+
conn, &conn->c_laddr, &conn->c_faddr,
1110+
conn->c_tos);
1111+
rds_ib_conn_destroy_init(conn);
1112+
return 0;
1113+
}
1114+
1115+
#else /* !CONFIG_RDS_ACL */
1116+
1117+
ret = 0;
1118+
1119+
#endif /* !CONFIG_RDS_ACL */
1120+
1121+
conn->c_acl_en = ret;
1122+
conn->c_acl_init = 1;
1123+
10301124
rds_ib_set_protocol(conn, RDS_PROTOCOL_4_1);
10311125
ic->i_flowctl = rds_ib_sysctl_flow_control; /* advertise flow control */
10321126
/* Use ic->i_flowctl as the first post credit to enable

0 commit comments

Comments
 (0)