From: Valentine Fatiev <valentinef@nvidia.com>
Subject: [PATCH] BACKPORT: drivers/infiniband/core/nldev.c

Change-Id: I5d14fb3c5bee691bb4420d70af35a342a1e67346
---
 drivers/infiniband/core/nldev.c | 153 +++++++++++++++++++++++++-------
 1 file changed, 120 insertions(+), 33 deletions(-)

--- a/drivers/infiniband/core/nldev.c
+++ b/drivers/infiniband/core/nldev.c
@@ -75,9 +75,9 @@ static const struct nla_policy nldev_pol
 	[RDMA_NLDEV_ATTR_DRIVER_PRINT_TYPE]	= { .type = NLA_U8 },
 	[RDMA_NLDEV_ATTR_DRIVER_STRING]		= { .type = NLA_NUL_STRING,
 					.len = RDMA_NLDEV_ATTR_EMPTY_STRING },
-	[RDMA_NLDEV_ATTR_DRIVER_S32]		= { .type = NLA_S32 },
-	[RDMA_NLDEV_ATTR_DRIVER_S64]		= { .type = NLA_S64 },
-	[RDMA_NLDEV_ATTR_DRIVER_U32]		= { .type = NLA_U32 },
+       [RDMA_NLDEV_ATTR_DRIVER_S32]		= { .type = NLA_S32 },
+       [RDMA_NLDEV_ATTR_DRIVER_S64]		= { .type = NLA_S64 },
+       [RDMA_NLDEV_ATTR_DRIVER_U32]		= { .type = NLA_U32 },
 	[RDMA_NLDEV_ATTR_DRIVER_U64]		= { .type = NLA_U64 },
 	[RDMA_NLDEV_ATTR_FW_VERSION]		= { .type = NLA_NUL_STRING,
 					.len = RDMA_NLDEV_ATTR_EMPTY_STRING },
@@ -396,9 +396,12 @@ static int fill_res_info_entry(struct sk
 			       const char *name, u64 curr)
 {
 	struct nlattr *entry_attr;
-
+#ifdef HAVE_NLA_NEST_START_NOFLAG
 	entry_attr = nla_nest_start_noflag(msg,
 					   RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY);
+#else
+	entry_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY);
+#endif
 	if (!entry_attr)
 		return -EMSGSIZE;
 
@@ -434,7 +437,11 @@ static int fill_res_info(struct sk_buff
 	if (fill_nldev_handle(msg, device))
 		return -EMSGSIZE;
 
+#ifdef HAVE_NLA_NEST_START_NOFLAG
 	table_attr = nla_nest_start_noflag(msg, RDMA_NLDEV_ATTR_RES_SUMMARY);
+#else
+	table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_SUMMARY);
+#endif
 	if (!table_attr)
 		return -EMSGSIZE;
 
@@ -1071,7 +1078,11 @@ static int nldev_get_doit(struct sk_buff
 	u32 index;
 	int err;
 
+#ifdef HAVE_NLMSG_PARSE_DEPRECATED
 	err = nlmsg_parse_deprecated(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+#else
+	err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+#endif/*HAVE_NLMSG_PARSE_DEPRECATED*/
 				     nldev_policy, extack);
 	if (err || !tb[RDMA_NLDEV_ATTR_DEV_INDEX])
 		return -EINVAL;
@@ -1120,8 +1131,13 @@ static int nldev_set_doit(struct sk_buff
 	u32 index;
 	int err;
 
+#ifdef HAVE_NLMSG_PARSE_DEPRECATED
 	err = nlmsg_parse_deprecated(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
 				     nldev_policy, extack);
+#else
+	err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+	                                     nldev_policy, extack);
+#endif /*HAVE_NLMSG_PARSE_DEPRECATED*/
 	if (err || !tb[RDMA_NLDEV_ATTR_DEV_INDEX])
 		return -EINVAL;
 
@@ -1133,8 +1149,13 @@ static int nldev_set_doit(struct sk_buff
 	if (tb[RDMA_NLDEV_ATTR_DEV_NAME]) {
 		char name[IB_DEVICE_NAME_MAX] = {};
 
+#ifdef HAVE_NLA_STRSCPY
 		nla_strscpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
 			    IB_DEVICE_NAME_MAX);
+#else
+		nla_strlcpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
+				IB_DEVICE_NAME_MAX);
+#endif
 		if (strlen(name) == 0) {
 			err = -EINVAL;
 			goto done;
@@ -1212,8 +1233,12 @@ static int nldev_port_get_doit(struct sk
 	u32 port;
 	int err;
 
+#ifdef HAVE_NLMSG_PARSE_DEPRECATED
 	err = nlmsg_parse_deprecated(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
-				     nldev_policy, extack);
+#else
+	err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+#endif /*HAVE_NLMSG_PARSE_DEPRECATED*/
+       			     nldev_policy, extack);
 	if (err ||
 	    !tb[RDMA_NLDEV_ATTR_DEV_INDEX] ||
 	    !tb[RDMA_NLDEV_ATTR_PORT_INDEX])
@@ -1251,7 +1276,7 @@ static int nldev_port_get_doit(struct sk
 	nlmsg_end(msg, nlh);
 	ib_device_put(device);
 
-	return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
+       return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
 
 err_free:
 	nlmsg_free(msg);
@@ -1272,7 +1297,11 @@ static int nldev_port_get_dumpit(struct
 	int err;
 	unsigned int p;
 
+#ifdef HAVE_NLMSG_PARSE_DEPRECATED
 	err = nlmsg_parse_deprecated(cb->nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+#else
+	err = nlmsg_parse(cb->nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+#endif
 				     nldev_policy, NULL);
 	if (err || !tb[RDMA_NLDEV_ATTR_DEV_INDEX])
 		return -EINVAL;
@@ -1327,8 +1356,13 @@ static int nldev_res_get_doit(struct sk_
 	u32 index;
 	int ret;
 
+#ifdef HAVE_NLMSG_PARSE_DEPRECATED
 	ret = nlmsg_parse_deprecated(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
-				     nldev_policy, extack);
+#else
+	ret = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+#endif /*HAVE_NLMSG_PARSE_DEPRECATED*/
+       			     nldev_policy, extack);
+
 	if (ret || !tb[RDMA_NLDEV_ATTR_DEV_INDEX])
 		return -EINVAL;
 
@@ -1357,7 +1391,7 @@ static int nldev_res_get_doit(struct sk_
 
 	nlmsg_end(msg, nlh);
 	ib_device_put(device);
-	return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
+       return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
 
 err_free:
 	nlmsg_free(msg);
@@ -1474,7 +1508,11 @@ static int res_get_common_doit(struct sk
 	struct sk_buff *msg;
 	int ret;
 
+#ifdef HAVE_NLMSG_PARSE_DEPRECATED
 	ret = nlmsg_parse_deprecated(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+#else
+	ret = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+#endif
 				     nldev_policy, extack);
 	if (ret || !tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !fe->id || !tb[fe->id])
 		return -EINVAL;
@@ -1511,7 +1549,7 @@ static int res_get_common_doit(struct sk
 		goto err_get;
 	}
 
-	nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
+       nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
 			RDMA_NL_GET_TYPE(RDMA_NL_NLDEV,
 					 RDMA_NL_GET_OP(nlh->nlmsg_type)),
 			0, 0);
@@ -1521,7 +1559,7 @@ static int res_get_common_doit(struct sk
 		goto err_free;
 	}
 
-	has_cap_net_admin = netlink_capable(skb, CAP_NET_ADMIN);
+       has_cap_net_admin = netlink_capable(skb, CAP_NET_ADMIN);
 
 	ret = fill_func(msg, has_cap_net_admin, res, port);
 	if (ret)
@@ -1561,7 +1599,11 @@ static int res_get_common_dumpit(struct
 	u32 index, port = 0;
 	bool filled = false;
 
+#ifdef HAVE_NLMSG_PARSE_DEPRECATED
 	err = nlmsg_parse_deprecated(cb->nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+#else
+	err = nlmsg_parse(cb->nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+#endif
 				     nldev_policy, NULL);
 	/*
 	 * Right now, we are expecting the device index to get res information,
@@ -1600,13 +1642,17 @@ static int res_get_common_dumpit(struct
 		goto err;
 	}
 
+#ifdef HAVE_NLA_NEST_START_NOFLAG
 	table_attr = nla_nest_start_noflag(skb, fe->nldev_attr);
+#else
+	table_attr = nla_nest_start(skb, fe->nldev_attr);
+#endif
 	if (!table_attr) {
 		ret = -EMSGSIZE;
 		goto err;
 	}
 
-	has_cap_net_admin = netlink_capable(cb->skb, CAP_NET_ADMIN);
+       has_cap_net_admin = netlink_capable(cb->skb, CAP_NET_ADMIN);
 
 	rt = &device->res[res_type];
 	xa_lock(&rt->xa);
@@ -1623,7 +1669,11 @@ static int res_get_common_dumpit(struct
 
 		filled = true;
 
+#ifdef HAVE_NLA_NEST_START_NOFLAG
 		entry_attr = nla_nest_start_noflag(skb, fe->entry);
+#else
+		entry_attr = nla_nest_start(skb, fe->entry);
+#endif
 		if (!entry_attr) {
 			ret = -EMSGSIZE;
 			rdma_restrack_put(res);
@@ -1665,7 +1715,6 @@ msg_full:
 
 res_err:
 	nla_nest_cancel(skb, table_attr);
-
 err:
 	nlmsg_cancel(skb, nlh);
 
@@ -1737,8 +1786,9 @@ void rdma_link_unregister(struct rdma_li
 }
 EXPORT_SYMBOL(rdma_link_unregister);
 
-static int nldev_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
-			  struct netlink_ext_ack *extack)
+static int nldev_newlink(struct sk_buff *skb, struct nlmsghdr *nlh
+			  ,struct netlink_ext_ack *extack
+			  )
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
 	char ibdev_name[IB_DEVICE_NAME_MAX];
@@ -1748,20 +1798,35 @@ static int nldev_newlink(struct sk_buff
 	char type[IFNAMSIZ];
 	int err;
 
+#ifdef HAVE_NLMSG_PARSE_DEPRECATED
 	err = nlmsg_parse_deprecated(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+#else
+	err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+#endif
 				     nldev_policy, extack);
 	if (err || !tb[RDMA_NLDEV_ATTR_DEV_NAME] ||
 	    !tb[RDMA_NLDEV_ATTR_LINK_TYPE] || !tb[RDMA_NLDEV_ATTR_NDEV_NAME])
 		return -EINVAL;
 
+#ifdef HAVE_NLA_STRSCPY
 	nla_strscpy(ibdev_name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
 		    sizeof(ibdev_name));
+#else
+ 	nla_strlcpy(ibdev_name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
+ 		    sizeof(ibdev_name));
+#endif
 	if (strchr(ibdev_name, '%') || strlen(ibdev_name) == 0)
 		return -EINVAL;
 
+#ifdef HAVE_NLA_STRSCPY
 	nla_strscpy(type, tb[RDMA_NLDEV_ATTR_LINK_TYPE], sizeof(type));
 	nla_strscpy(ndev_name, tb[RDMA_NLDEV_ATTR_NDEV_NAME],
 		    sizeof(ndev_name));
+#else
+ 	nla_strlcpy(type, tb[RDMA_NLDEV_ATTR_LINK_TYPE], sizeof(type));
+ 	nla_strlcpy(ndev_name, tb[RDMA_NLDEV_ATTR_NDEV_NAME],
+				sizeof(ndev_name));
+#endif
 
 	ndev = dev_get_by_name(sock_net(skb->sk), ndev_name);
 	if (!ndev)
@@ -1784,15 +1849,20 @@ static int nldev_newlink(struct sk_buff
 	return err;
 }
 
-static int nldev_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
-			  struct netlink_ext_ack *extack)
+static int nldev_dellink(struct sk_buff *skb, struct nlmsghdr *nlh
+			  ,struct netlink_ext_ack *extack
+			  )
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
 	struct ib_device *device;
 	u32 index;
 	int err;
 
+#ifdef HAVE_NLMSG_PARSE_DEPRECATED
 	err = nlmsg_parse_deprecated(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+#else
+	err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+#endif
 				     nldev_policy, extack);
 	if (err || !tb[RDMA_NLDEV_ATTR_DEV_INDEX])
 		return -EINVAL;
@@ -1811,8 +1881,9 @@ static int nldev_dellink(struct sk_buff
 	return 0;
 }
 
-static int nldev_get_chardev(struct sk_buff *skb, struct nlmsghdr *nlh,
-			     struct netlink_ext_ack *extack)
+static int nldev_get_chardev(struct sk_buff *skb, struct nlmsghdr *nlh
+			    ,struct netlink_ext_ack *extack
+			    )
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
 	char client_name[RDMA_NLDEV_ATTR_CHARDEV_TYPE_SIZE];
@@ -1827,8 +1898,13 @@ static int nldev_get_chardev(struct sk_b
 	if (err || !tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE])
 		return -EINVAL;
 
+#ifdef HAVE_NLA_STRSCPY
 	nla_strscpy(client_name, tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE],
 		    sizeof(client_name));
+#else
+	nla_strlcpy(client_name, tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE],
+		    sizeof(client_name));
+#endif
 
 	if (tb[RDMA_NLDEV_ATTR_DEV_INDEX]) {
 		index = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
@@ -1899,8 +1975,9 @@ out_put:
 	return err;
 }
 
-static int nldev_sys_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
-			      struct netlink_ext_ack *extack)
+static int nldev_sys_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh
+			  ,struct netlink_ext_ack *extack
+			  )
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
 	struct sk_buff *msg;
@@ -1943,6 +2020,7 @@ static int nldev_sys_get_doit(struct sk_
 		nlmsg_free(msg);
 		return err;
 	}
+#ifdef HAVE_IS_COW_MAPPING
 	/*
 	 * Copy-on-fork is supported.
 	 * See commits:
@@ -1954,6 +2032,7 @@ static int nldev_sys_get_doit(struct sk_
 	 * supported in case of failure.
 	 */
 	nla_put_u8(msg, RDMA_NLDEV_SYS_ATTR_COPY_ON_FORK, 1);
+#endif
 
 	nlmsg_end(msg, nlh);
 	return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
@@ -1986,8 +2065,9 @@ static int nldev_set_sys_set_pqkey_doit(
 	return 0;
 }
 
-static int nldev_set_sys_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
-				  struct netlink_ext_ack *extack)
+static int nldev_set_sys_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh
+			  ,struct netlink_ext_ack *extack
+			  )
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
 	int err;
@@ -2025,7 +2105,8 @@ static int nldev_stat_set_mode_doit(stru
 		if (tb[RDMA_NLDEV_ATTR_STAT_AUTO_MODE_MASK])
 			mask = nla_get_u32(
 				tb[RDMA_NLDEV_ATTR_STAT_AUTO_MODE_MASK]);
-		return rdma_counter_set_auto_mode(device, port, mask, extack);
+		return rdma_counter_set_auto_mode(device, port, mask
+				, extack);
 	}
 
 	if (!tb[RDMA_NLDEV_ATTR_RES_LQPN])
@@ -2101,8 +2182,8 @@ out:
 	return ret;
 }
 
-static int nldev_stat_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
-			       struct netlink_ext_ack *extack)
+static int nldev_stat_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh
+			  ,struct netlink_ext_ack *extack)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
 	struct ib_device *device;
@@ -2149,7 +2230,9 @@ static int nldev_stat_set_doit(struct sk
 	}
 
 	if (tb[RDMA_NLDEV_ATTR_STAT_MODE]) {
-		ret = nldev_stat_set_mode_doit(msg, extack, tb, device, port);
+		ret = nldev_stat_set_mode_doit(msg,
+				extack,
+				tb, device, port);
 		if (ret)
 			goto err_free_msg;
 	}
@@ -2171,8 +2254,8 @@ err_put_device:
 	return ret;
 }
 
-static int nldev_stat_del_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
-			       struct netlink_ext_ack *extack)
+static int nldev_stat_del_doit(struct sk_buff *skb, struct nlmsghdr *nlh
+			  ,struct netlink_ext_ack *extack)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
 	struct ib_device *device;
@@ -2232,7 +2315,7 @@ static int nldev_stat_del_doit(struct sk
 
 	nlmsg_end(msg, nlh);
 	ib_device_put(device);
-	return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
+       return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
 
 err_fill:
 	nlmsg_free(msg);
@@ -2406,8 +2489,8 @@ err:
 	return ret;
 }
 
-static int nldev_stat_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
-			       struct netlink_ext_ack *extack)
+static int nldev_stat_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh
+			  ,struct netlink_ext_ack *extack)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
 	int ret;
@@ -2464,8 +2547,8 @@ static int nldev_stat_get_dumpit(struct
 }
 
 static int nldev_stat_get_counter_status_doit(struct sk_buff *skb,
-					      struct nlmsghdr *nlh,
-					      struct netlink_ext_ack *extack)
+					      struct nlmsghdr *nlh
+					      ,struct netlink_ext_ack *extack)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX], *table, *entry;
 	struct rdma_hw_stats *stats;
@@ -2572,7 +2655,11 @@ static int nldev_newdev(struct sk_buff *
 		!tb[RDMA_NLDEV_ATTR_DEV_NAME] || !tb[RDMA_NLDEV_ATTR_DEV_TYPE])
 		return -EINVAL;
 
+#ifdef HAVE_NLA_STRSCPY
 	nla_strscpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME], sizeof(name));
+#else
+	nla_strlcpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME], sizeof(name));
+#endif
 	type = nla_get_u8(tb[RDMA_NLDEV_ATTR_DEV_TYPE]);
 	parentid = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
 	parent = ib_device_get_by_index(sock_net(skb->sk), parentid);
