From: Viacheslav Ovsiienko Date: Mon, 12 Nov 2018 20:01:40 +0000 (+0000) Subject: net/mlx5: fix Netlink communication routine X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=84cacbe34b6bb3071af0313694b119f3872cbb8b;p=dpdk.git net/mlx5: fix Netlink communication routine 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 Acked-by: Shahaf Shuler --- diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c index 5a38940ae5..4d154b65ff 100644 --- a/drivers/net/mlx5/mlx5_flow_tcf.c +++ b/drivers/net/mlx5/mlx5_flow_tcf.c @@ -3732,44 +3732,60 @@ flow_tcf_nl_ack(struct mlx5_flow_tcf_context *tcf, { 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;