Monday, November 12, 2018 10:02 PM, Slava Ovsiienko: > Subject: [PATCH 2/4] 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 <viachesl...@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) {
This while(true) is a bit disturbing (I know it exists also before). Can't we bound it to some limit, e.g. is there any multiply of tcf->buf_size that if we receive more than that it is for sure an error? > + 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