| From 1ef5a17381cc08787b90d1bdc335a105ed8013ed Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?H=C3=A5kon=20Bugge?= <haakon.bugge@oracle.com> |
| Date: Mon, 16 Dec 2019 13:04:36 +0100 |
| Subject: [PATCH] RDMA/netlink: Do not always generate an ACK for some netlink |
| operations |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| commit a242c36951ecd24bc16086940dbe6b522205c461 upstream. |
| |
| In rdma_nl_rcv_skb(), the local variable err is assigned the return value |
| of the supplied callback function, which could be one of |
| ib_nl_handle_resolve_resp(), ib_nl_handle_set_timeout(), or |
| ib_nl_handle_ip_res_resp(). These three functions all return skb->len on |
| success. |
| |
| rdma_nl_rcv_skb() is merely a copy of netlink_rcv_skb(). The callback |
| functions used by the latter have the convention: "Returns 0 on success or |
| a negative error code". |
| |
| In particular, the statement (equal for both functions): |
| |
| if (nlh->nlmsg_flags & NLM_F_ACK || err) |
| |
| implies that rdma_nl_rcv_skb() always will ack a message, independent of |
| the NLM_F_ACK being set in nlmsg_flags or not. |
| |
| The fix could be to change the above statement, but it is better to keep |
| the two *_rcv_skb() functions equal in this respect and instead change the |
| three callback functions in the rdma subsystem to the correct convention. |
| |
| Fixes: 2ca546b92a02 ("IB/sa: Route SA pathrecord query through netlink") |
| Fixes: ae43f8286730 ("IB/core: Add IP to GID netlink offload") |
| Link: https://lore.kernel.org/r/20191216120436.3204814-1-haakon.bugge@oracle.com |
| Suggested-by: Mark Haywood <mark.haywood@oracle.com> |
| Signed-off-by: Håkon Bugge <haakon.bugge@oracle.com> |
| Tested-by: Mark Haywood <mark.haywood@oracle.com> |
| Reviewed-by: Leon Romanovsky <leonro@mellanox.com> |
| Reviewed-by: Jason Gunthorpe <jgg@mellanox.com> |
| Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c |
| index fca5025d5a1a..152b3069588a 100644 |
| --- a/drivers/infiniband/core/addr.c |
| +++ b/drivers/infiniband/core/addr.c |
| @@ -139,7 +139,7 @@ int ib_nl_handle_ip_res_resp(struct sk_buff *skb, |
| if (ib_nl_is_good_ip_resp(nlh)) |
| ib_nl_process_good_ip_rsep(nlh); |
| |
| - return skb->len; |
| + return 0; |
| } |
| |
| static int ib_nl_ip_send_msg(struct rdma_dev_addr *dev_addr, |
| diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c |
| index 7d8071c7e564..440b0e1cc6b2 100644 |
| --- a/drivers/infiniband/core/sa_query.c |
| +++ b/drivers/infiniband/core/sa_query.c |
| @@ -1068,7 +1068,7 @@ int ib_nl_handle_set_timeout(struct sk_buff *skb, |
| } |
| |
| settimeout_out: |
| - return skb->len; |
| + return 0; |
| } |
| |
| static inline int ib_nl_is_good_resolve_resp(const struct nlmsghdr *nlh) |
| @@ -1139,7 +1139,7 @@ int ib_nl_handle_resolve_resp(struct sk_buff *skb, |
| } |
| |
| resp_out: |
| - return skb->len; |
| + return 0; |
| } |
| |
| static void free_sm_ah(struct kref *kref) |
| -- |
| 2.7.4 |
| |