[dpdk-dev] [PATCH 2/4] net/mlx5: fix Netlink communication routine

Slava Ovsiienko viacheslavo at mellanox.com
Mon Nov 12 21:01:40 CET 2018


While receiving the Netlink reply messages we should stop at DONE
or ACK message. The existing implementation stops at DONE message
or if no multiple message flag set ( NLM_F_MULTI). It prevents
the single query requests from working, these requests send the
single reply message without multi-message flag followed by
ACK message. This patch fixes receiving part of Netlink
communication routine.

Fixes: 6e74990b3463 ("net/mlx5: update E-Switch VXLAN netlink routines")

Signed-off-by: Viacheslav Ovsiienko <viacheslavo at mellanox.com>
---
 drivers/net/mlx5/mlx5_flow_tcf.c | 58 +++++++++++++++++++++++++---------------
 1 file changed, 37 insertions(+), 21 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c
index 5a38940..4d154b6 100644
--- a/drivers/net/mlx5/mlx5_flow_tcf.c
+++ b/drivers/net/mlx5/mlx5_flow_tcf.c
@@ -3732,44 +3732,60 @@ struct pedit_parser {
 {
 	unsigned int portid = mnl_socket_get_portid(tcf->nl);
 	uint32_t seq = tcf->seq++;
-	int err, ret;
+	int ret, err = 0;
 
 	assert(tcf->nl);
 	assert(tcf->buf);
-	if (!seq)
+	if (!seq) {
 		/* seq 0 is reserved for kernel event-driven notifications. */
 		seq = tcf->seq++;
+	}
 	nlh->nlmsg_seq = seq;
 	nlh->nlmsg_flags |= NLM_F_ACK;
 	ret = mnl_socket_sendto(tcf->nl, nlh, nlh->nlmsg_len);
-	err = (ret <= 0) ? errno : 0;
+	if (ret <= 0) {
+		/* Message send error occurres. */
+		rte_errno = errno;
+		return -rte_errno;
+	}
 	nlh = (struct nlmsghdr *)(tcf->buf);
 	/*
 	 * The following loop postpones non-fatal errors until multipart
 	 * messages are complete.
 	 */
-	if (ret > 0)
-		while (true) {
-			ret = mnl_socket_recvfrom(tcf->nl, tcf->buf,
-						  tcf->buf_size);
+	while (true) {
+		ret = mnl_socket_recvfrom(tcf->nl, tcf->buf, tcf->buf_size);
+		if (ret < 0) {
+			err = errno;
+			/*
+			 * In case of overflow Will receive till
+			 * end of multipart message. We may lost part
+			 * of reply messages but mark and return an error.
+			 */
+			if (err != ENOSPC ||
+			    !(nlh->nlmsg_flags & NLM_F_MULTI) ||
+			    nlh->nlmsg_type == NLMSG_DONE)
+				break;
+		} else {
+			ret = mnl_cb_run(nlh, ret, seq, portid, cb, arg);
+			if (!ret) {
+				/*
+				 * libmnl returns 0 if DONE or
+				 * success ACK message found.
+				 */
+				break;
+			}
 			if (ret < 0) {
+				/*
+				 * ACK message with error found
+				 * or some error occurred.
+				 */
 				err = errno;
-				if (err != ENOSPC)
-					break;
-			}
-			if (!err) {
-				ret = mnl_cb_run(nlh, ret, seq, portid,
-						 cb, arg);
-				if (ret < 0) {
-					err = errno;
-					break;
-				}
-			}
-			/* Will receive till end of multipart message */
-			if (!(nlh->nlmsg_flags & NLM_F_MULTI) ||
-			      nlh->nlmsg_type == NLMSG_DONE)
 				break;
+			}
+			/* We should continue receiving. */
 		}
+	}
 	if (!err)
 		return 0;
 	rte_errno = err;
-- 
1.8.3.1



More information about the dev mailing list