]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net/smc: Add global configure for handshake limitation by netlink
authorD. Wythe <alibuda@linux.alibaba.com>
Thu, 10 Feb 2022 09:11:38 +0000 (17:11 +0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 11 Feb 2022 11:14:58 +0000 (11:14 +0000)
Although we can control SMC handshake limitation through socket options,
which means that applications who need it must modify their code. It's
quite troublesome for many existing applications. This patch modifies
the global default value of SMC handshake limitation through netlink,
providing a way to put constraint on handshake without modifies any code
for applications.

Suggested-by: Tony Lu <tonylu@linux.alibaba.com>
Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
Reviewed-by: Tony Lu <tonylu@linux.alibaba.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/netns/smc.h
include/uapi/linux/smc.h
net/smc/af_smc.c
net/smc/smc.h
net/smc/smc_netlink.c
net/smc/smc_pnet.c

index ea8a9cf2619ba2d2922009dd716bcf9e4ee68630..47b166684fd80ca5f99c15f4bcea3c829add7e07 100644 (file)
@@ -12,5 +12,7 @@ struct netns_smc {
        /* protect fback_rsn */
        struct mutex                    mutex_fback_rsn;
        struct smc_stats_rsn            *fback_rsn;
+
+       bool                            limit_smc_hs;   /* constraint on handshake */
 };
 #endif
index 343e7450c3a3b85d5af63cbfa7aa74f625a95dd0..693f549f69661814bd5127b5760010cb0f13789e 100644 (file)
@@ -59,6 +59,9 @@ enum {
        SMC_NETLINK_DUMP_SEID,
        SMC_NETLINK_ENABLE_SEID,
        SMC_NETLINK_DISABLE_SEID,
+       SMC_NETLINK_DUMP_HS_LIMITATION,
+       SMC_NETLINK_ENABLE_HS_LIMITATION,
+       SMC_NETLINK_DISABLE_HS_LIMITATION,
 };
 
 /* SMC_GENL_FAMILY top level attributes */
@@ -285,6 +288,14 @@ enum {
        SMC_NLA_SEID_TABLE_MAX = __SMC_NLA_SEID_TABLE_MAX - 1
 };
 
+/* SMC_NETLINK_HS_LIMITATION attributes */
+enum {
+       SMC_NLA_HS_LIMITATION_UNSPEC,
+       SMC_NLA_HS_LIMITATION_ENABLED,  /* u8 */
+       __SMC_NLA_HS_LIMITATION_MAX,
+       SMC_NLA_HS_LIMITATION_MAX = __SMC_NLA_HS_LIMITATION_MAX - 1
+};
+
 /* SMC socket options */
 #define SMC_LIMIT_HS 1 /* constraint on smc handshake */
 
index 97dcdc0a2107026c39b97655637f41e522f16cf7..246c874de629a98ad8d109baac082a6d9bd05dc6 100644 (file)
@@ -66,6 +66,45 @@ struct workqueue_struct      *smc_close_wq;  /* wq for close work */
 static void smc_tcp_listen_work(struct work_struct *);
 static void smc_connect_work(struct work_struct *);
 
+int smc_nl_dump_hs_limitation(struct sk_buff *skb, struct netlink_callback *cb)
+{
+       struct smc_nl_dmp_ctx *cb_ctx = smc_nl_dmp_ctx(cb);
+       void *hdr;
+
+       if (cb_ctx->pos[0])
+               goto out;
+
+       hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
+                         &smc_gen_nl_family, NLM_F_MULTI,
+                         SMC_NETLINK_DUMP_HS_LIMITATION);
+       if (!hdr)
+               return -ENOMEM;
+
+       if (nla_put_u8(skb, SMC_NLA_HS_LIMITATION_ENABLED,
+                      sock_net(skb->sk)->smc.limit_smc_hs))
+               goto err;
+
+       genlmsg_end(skb, hdr);
+       cb_ctx->pos[0] = 1;
+out:
+       return skb->len;
+err:
+       genlmsg_cancel(skb, hdr);
+       return -EMSGSIZE;
+}
+
+int smc_nl_enable_hs_limitation(struct sk_buff *skb, struct genl_info *info)
+{
+       sock_net(skb->sk)->smc.limit_smc_hs = true;
+       return 0;
+}
+
+int smc_nl_disable_hs_limitation(struct sk_buff *skb, struct genl_info *info)
+{
+       sock_net(skb->sk)->smc.limit_smc_hs = false;
+       return 0;
+}
+
 static void smc_set_keepalive(struct sock *sk, int val)
 {
        struct smc_sock *smc = smc_sk(sk);
@@ -3007,6 +3046,9 @@ static int __smc_create(struct net *net, struct socket *sock, int protocol,
        smc->use_fallback = false; /* assume rdma capability first */
        smc->fallback_rsn = 0;
 
+       /* default behavior from limit_smc_hs in every net namespace */
+       smc->limit_smc_hs = net->smc.limit_smc_hs;
+
        rc = 0;
        if (!clcsock) {
                rc = sock_create_kern(net, family, SOCK_STREAM, IPPROTO_TCP,
index 7e2693832a1b926104d0a36606de0a6f0252dfde..a096d8af21a0de93db34156eb29c3c6a3b839bbd 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/socket.h>
 #include <linux/types.h>
 #include <linux/compiler.h> /* __aligned */
+#include <net/genetlink.h>
 #include <net/sock.h>
 
 #include "smc_ib.h"
@@ -336,4 +337,9 @@ void smc_fill_gid_list(struct smc_link_group *lgr,
                       struct smc_gidlist *gidlist,
                       struct smc_ib_device *known_dev, u8 *known_gid);
 
+/* smc handshake limitation interface for netlink  */
+int smc_nl_dump_hs_limitation(struct sk_buff *skb, struct netlink_callback *cb);
+int smc_nl_enable_hs_limitation(struct sk_buff *skb, struct genl_info *info);
+int smc_nl_disable_hs_limitation(struct sk_buff *skb, struct genl_info *info);
+
 #endif /* __SMC_H */
index f13ab0661ed5ee615e5f3dca2b87e7a5edcd11f4..c5a62f6f52ba5fc092072899916c0d30971d6d26 100644 (file)
@@ -111,6 +111,21 @@ static const struct genl_ops smc_gen_nl_ops[] = {
                .flags = GENL_ADMIN_PERM,
                .doit = smc_nl_disable_seid,
        },
+       {
+               .cmd = SMC_NETLINK_DUMP_HS_LIMITATION,
+               /* can be retrieved by unprivileged users */
+               .dumpit = smc_nl_dump_hs_limitation,
+       },
+       {
+               .cmd = SMC_NETLINK_ENABLE_HS_LIMITATION,
+               .flags = GENL_ADMIN_PERM,
+               .doit = smc_nl_enable_hs_limitation,
+       },
+       {
+               .cmd = SMC_NETLINK_DISABLE_HS_LIMITATION,
+               .flags = GENL_ADMIN_PERM,
+               .doit = smc_nl_disable_hs_limitation,
+       },
 };
 
 static const struct nla_policy smc_gen_nl_policy[2] = {
index 0599246c037690b4b01813956e4af74519277bea..ff61b7b95875a8bb0a210aabeaac706f035547c6 100644 (file)
@@ -870,6 +870,9 @@ int smc_pnet_net_init(struct net *net)
 
        smc_pnet_create_pnetids_list(net);
 
+       /* disable handshake limitation by default */
+       net->smc.limit_smc_hs = 0;
+
        return 0;
 }