2016-02-18 3:52 GMT+01:00 Jason Wang <jasow...@redhat.com>:
>
>
> On 02/05/2016 06:30 PM, Vincenzo Maffione wrote:
>> Previous implementation of has_ufo, has_vnet_hdr, has_vnet_hdr_len, etc.
>> did not really probe for virtio-net header support for the netmap
>> interface attached to the backend. These callbacks were correct for
>> VALE ports, but incorrect for hardware NICs, pipes, monitors, etc.
>>
>> This patch fixes the implementation to work properly with all kinds
>> of netmap ports.
>>
>> Signed-off-by: Vincenzo Maffione <v.maffi...@gmail.com>
>> ---
>>  net/netmap.c | 70 
>> ++++++++++++++++++++++++++++++++++++++----------------------
>>  1 file changed, 44 insertions(+), 26 deletions(-)
>>
>> diff --git a/net/netmap.c b/net/netmap.c
>> index 9710321..f2dcaeb 100644
>> --- a/net/netmap.c
>> +++ b/net/netmap.c
>> @@ -323,20 +323,55 @@ static void netmap_cleanup(NetClientState *nc)
>>  }
>>
>>  /* Offloading manipulation support callbacks. */
>> -static bool netmap_has_ufo(NetClientState *nc)
>> +static int netmap_do_set_vnet_hdr_len(NetmapState *s, int len, bool 
>> err_report)
>
> Passing something like err_report usually means it was the
> responsibility of caller to report. So let's remove the err_report and
> let caller to decide based on the return value.
>

Ok, I'll try to fix this with the next patch.

>>  {
>> -    return true;
>> +    struct nmreq req;
>> +    int err;
>> +
>> +    /* Issue a NETMAP_BDG_VNET_HDR command to change the virtio-net header
>> +     * length for the netmap adapter associated to 's->ifname'.
>> +     */
>> +    memset(&req, 0, sizeof(req));
>> +    pstrcpy(req.nr_name, sizeof(req.nr_name), s->ifname);
>> +    req.nr_version = NETMAP_API;
>> +    req.nr_cmd = NETMAP_BDG_VNET_HDR;
>> +    req.nr_arg1 = len;
>> +    err = ioctl(s->nmd->fd, NIOCREGIF, &req);
>> +    if (err) {
>> +        if (err_report) {
>> +            error_report("Unable to execute NETMAP_BDG_VNET_HDR on %s: %s",
>> +                         s->ifname, strerror(errno));
>> +        }
>> +        return -1;
>> +    }
>> +
>> +    /* Keep track of the current length. */
>> +    s->vnet_hdr_len = len;
>> +
>> +    return 0;
>>  }
>>
>> -static bool netmap_has_vnet_hdr(NetClientState *nc)
>> +static bool netmap_has_vnet_hdr_len(NetClientState *nc, int len)
>>  {
>> +    NetmapState *s = DO_UPCAST(NetmapState, nc, nc);
>> +    int prev_len = s->vnet_hdr_len;
>> +
>> +    /* Check that we can set the new length. */
>> +    if (netmap_do_set_vnet_hdr_len(s, len, false)) {
>> +        return false;
>> +    }
>> +
>> +    /* Restore the previous length. */
>> +    netmap_do_set_vnet_hdr_len(s, prev_len, true);
>> +
>>      return true;
>>  }
>>
>> -static bool netmap_has_vnet_hdr_len(NetClientState *nc, int len)
>> +/* A netmap interface that supports virtio-net headers always
>> + * supports UFO, so we use this callback also for the has_ufo hook. */
>> +static bool netmap_has_vnet_hdr(NetClientState *nc)
>>  {
>> -    return len == 0 || len == sizeof(struct virtio_net_hdr) ||
>> -                len == sizeof(struct virtio_net_hdr_mrg_rxbuf);
>> +    return netmap_has_vnet_hdr_len(nc, sizeof(struct virtio_net_hdr));
>>  }
>>
>>  static void netmap_using_vnet_hdr(NetClientState *nc, bool enable)
>> @@ -346,25 +381,8 @@ static void netmap_using_vnet_hdr(NetClientState *nc, 
>> bool enable)
>>  static void netmap_set_vnet_hdr_len(NetClientState *nc, int len)
>>  {
>>      NetmapState *s = DO_UPCAST(NetmapState, nc, nc);
>> -    int err;
>> -    struct nmreq req;
>>
>> -    /* Issue a NETMAP_BDG_VNET_HDR command to change the virtio-net header
>> -     * length for the netmap adapter associated to 's->ifname'.
>> -     */
>> -    memset(&req, 0, sizeof(req));
>> -    pstrcpy(req.nr_name, sizeof(req.nr_name), s->ifname);
>> -    req.nr_version = NETMAP_API;
>> -    req.nr_cmd = NETMAP_BDG_VNET_HDR;
>> -    req.nr_arg1 = len;
>> -    err = ioctl(s->nmd->fd, NIOCREGIF, &req);
>> -    if (err) {
>> -        error_report("Unable to execute NETMAP_BDG_VNET_HDR on %s: %s",
>> -                     s->ifname, strerror(errno));
>> -    } else {
>> -        /* Keep track of the current length. */
>> -        s->vnet_hdr_len = len;
>> -    }
>> +    netmap_do_set_vnet_hdr_len(s, len, true);
>>  }
>>
>>  static void netmap_set_offload(NetClientState *nc, int csum, int tso4, int 
>> tso6,
>> @@ -376,7 +394,7 @@ static void netmap_set_offload(NetClientState *nc, int 
>> csum, int tso4, int tso6,
>>       * enables the offloadings.
>>       */
>>      if (!s->vnet_hdr_len) {
>> -        netmap_set_vnet_hdr_len(nc, sizeof(struct virtio_net_hdr));
>> +        netmap_do_set_vnet_hdr_len(s, sizeof(struct virtio_net_hdr), true);
>>      }
>>  }
>>
>> @@ -388,7 +406,7 @@ static NetClientInfo net_netmap_info = {
>>      .receive_iov = netmap_receive_iov,
>>      .poll = netmap_poll,
>>      .cleanup = netmap_cleanup,
>> -    .has_ufo = netmap_has_ufo,
>> +    .has_ufo = netmap_has_vnet_hdr,
>
> This look suspicious, I'm not sure this is correct for netmap. May need
> a comment to explain. Usually vnet hdr does not imply ufo.
>
>>      .has_vnet_hdr = netmap_has_vnet_hdr,
>>      .has_vnet_hdr_len = netmap_has_vnet_hdr_len,
>>      .using_vnet_hdr = netmap_using_vnet_hdr,
>

Yes, I know it sounds weird in general, but a netmap port using
virtio-net headers always provides TCPv4, TCPv6, UDP and ECN
offloadings (done in software inside netmap).

This patch already provides a little comment about UFO support on the
netmap_has_vnet_hdr() function. Do you want me to move it here, or is
the comment not understandable enough?

Thanks for your review,
  Vincenzo

Reply via email to