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

Reply via email to