All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony@codemonkey.ws>
To: Benjamin Poirier <benjamin.poirier@polymtl.ca>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v2 1/2] rtl8139: add vlan tag insertion
Date: Tue, 16 Nov 2010 14:06:13 -0600	[thread overview]
Message-ID: <4CE2E435.9000207@codemonkey.ws> (raw)
In-Reply-To: <1289267181-20613-1-git-send-email-benjamin.poirier@polymtl.ca>

On 11/08/2010 07:46 PM, Benjamin Poirier wrote:
> Add support to the emulated hardware to add vlan tags in packets going
> from the guest to the network.
>
> Signed-off-by: Benjamin Poirier<benjamin.poirier@polymtl.ca>
> Cc: Igor V. Kovalenko<igor.v.kovalenko@gmail.com>
> ---
> Changes since v1:
> * moved the debug print statement inside the if block and reworded
>    accordingly. (as suggested by Igor)
>
>   hw/rtl8139.c |   45 ++++++++++++++++++++++++++++++++++-----------
>   1 files changed, 34 insertions(+), 11 deletions(-)
>
> diff --git a/hw/rtl8139.c b/hw/rtl8139.c
> index d92981d..b599945 100644
> --- a/hw/rtl8139.c
> +++ b/hw/rtl8139.c
> @@ -47,6 +47,8 @@
>    *                                  Darwin)
>    */
>
> +#include<net/ethernet.h>
> +
>   #include "hw.h"
>   #include "pci.h"
>   #include "qemu-timer.h"
> @@ -58,6 +60,10 @@
>
>   #define PCI_FREQUENCY 33000000L
>
> +/* bytes in VLAN tag */
> +#define VLAN_TCI_LEN 2
> +#define VLAN_HDR_LEN (ETHER_TYPE_LEN + VLAN_TCI_LEN)
> +
>   /* debug RTL8139 card C+ mode only */
>   //#define DEBUG_RTL8139CP 1
>
> @@ -1913,7 +1919,6 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
>
>       cpu_physical_memory_read(cplus_tx_ring_desc,    (uint8_t *)&val, 4);
>       txdw0 = le32_to_cpu(val);
> -    /* TODO: implement VLAN tagging support, VLAN tag data is read to txdw1 */
>       cpu_physical_memory_read(cplus_tx_ring_desc+4,  (uint8_t *)&val, 4);
>       txdw1 = le32_to_cpu(val);
>       cpu_physical_memory_read(cplus_tx_ring_desc+8,  (uint8_t *)&val, 4);
> @@ -1925,9 +1930,6 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
>              descriptor,
>              txdw0, txdw1, txbufLO, txbufHI));
>
> -    /* TODO: the following discard cast should clean clang analyzer output */
> -    (void)txdw1;
> -
>   /* w0 ownership flag */
>   #define CP_TX_OWN (1<<31)
>   /* w0 end of ring flag */
> @@ -1951,8 +1953,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
>   /* w0 bits 0...15 : buffer size */
>   #define CP_TX_BUFFER_SIZE (1<<16)
>   #define CP_TX_BUFFER_SIZE_MASK (CP_TX_BUFFER_SIZE - 1)
> -/* w1 tag available flag */
> -#define CP_RX_TAGC (1<<17)
> +/* w1 add tag flag */
> +#define CP_TX_TAGC (1<<17)
>   /* w1 bits 0...15 : VLAN tag */
>   #define CP_TX_VLAN_TAG_MASK ((1<<16) - 1)
>   /* w2 low  32bit of Rx buffer ptr */
> @@ -1978,12 +1980,21 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
>
>       DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : transmitting from descriptor %d\n", descriptor));
>
> +    int vlan_extra_size = 0;
>       if (txdw0&  CP_TX_FS)
>       {
>           DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : descriptor %d is first segment descriptor\n", descriptor));
>
>           /* reset internal buffer offset */
>           s->cplus_txbuffer_offset = 0;
> +
> +        if (txdw1&  CP_TX_TAGC)
> +        {
> +            vlan_extra_size = VLAN_HDR_LEN;
> +
> +            DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : inserting vlan tag with "
> +                    "tci: %u\n", bswap16(txdw1&  CP_TX_VLAN_TAG_MASK)));
> +        }
>       }
>
>       int txsize = txdw0&  CP_TX_BUFFER_SIZE_MASK;
> @@ -1992,14 +2003,15 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
>       /* make sure we have enough space to assemble the packet */
>       if (!s->cplus_txbuffer)
>       {
> -        s->cplus_txbuffer_len = CP_TX_BUFFER_SIZE;
> +        s->cplus_txbuffer_len = CP_TX_BUFFER_SIZE + VLAN_HDR_LEN;
>           s->cplus_txbuffer = qemu_malloc(s->cplus_txbuffer_len);
>           s->cplus_txbuffer_offset = 0;
>
>           DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer allocated space %d\n", s->cplus_txbuffer_len));
>       }
>
> -    while (s->cplus_txbuffer&&  s->cplus_txbuffer_offset + txsize>= s->cplus_txbuffer_len)
> +    while (s->cplus_txbuffer&&  s->cplus_txbuffer_offset + txsize +
> +        vlan_extra_size>= s->cplus_txbuffer_len)
>       {
>           s->cplus_txbuffer_len += CP_TX_BUFFER_SIZE;
>           s->cplus_txbuffer = qemu_realloc(s->cplus_txbuffer, s->cplus_txbuffer_len);
> @@ -2025,6 +2037,20 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
>       DEBUG_PRINT(("RTL8139: +++ C+ mode transmit reading %d bytes from host memory at %016" PRIx64 " to offset %d\n",
>                    txsize, (uint64_t)tx_addr, s->cplus_txbuffer_offset));
>
> +    if (vlan_extra_size&&  txsize>= 2 * ETHER_ADDR_LEN)
> +    {
> +        /* copy addresses */
> +        cpu_physical_memory_read(tx_addr, s->cplus_txbuffer, 2 *
> +            ETHER_ADDR_LEN);
> +        tx_addr += 2 * ETHER_ADDR_LEN;
> +        txsize -= 2 * ETHER_ADDR_LEN;
> +        /* insert vlan tag */
> +        *(uint16_t *)(s->cplus_txbuffer + 2 * ETHER_ADDR_LEN) =
> +            cpu_to_be16(ETHERTYPE_VLAN);
> +        *(uint16_t *)(s->cplus_txbuffer + 2 * ETHER_ADDR_LEN + ETHER_TYPE_LEN)
> +            = cpu_to_le16(txdw1&  CP_TX_VLAN_TAG_MASK);
>    

This looks wrong.  You check for txsize >= 2 * ETHER_ADDR_LEN but then 
you assign at 2 * ETHER_ADDR_LEN.  This is a potential overflow, no?

Regards,

Anthony Liguori

> +        s->cplus_txbuffer_offset += 2 * ETHER_ADDR_LEN + VLAN_HDR_LEN;
> +    }
>       cpu_physical_memory_read(tx_addr, s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize);
>       s->cplus_txbuffer_offset += txsize;
>
> @@ -2053,9 +2079,6 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
>       /* update ring data */
>       val = cpu_to_le32(txdw0);
>       cpu_physical_memory_write(cplus_tx_ring_desc,    (uint8_t *)&val, 4);
> -    /* TODO: implement VLAN tagging support, VLAN tag data is read to txdw1 */
> -//    val = cpu_to_le32(txdw1);
> -//    cpu_physical_memory_write(cplus_tx_ring_desc+4,&val, 4);
>
>       /* Now decide if descriptor being processed is holding the last segment of packet */
>       if (txdw0&  CP_TX_LS)
>    

  reply	other threads:[~2010-11-16 20:06 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <AANLkTi=m+SiRkkQBj95X2CNkprVQgejeY_wwB=nmF_55@mail.gmail.com>
2010-11-09  1:46 ` [Qemu-devel] [PATCH v2 1/2] rtl8139: add vlan tag insertion Benjamin Poirier
2010-11-16 20:06   ` Anthony Liguori [this message]
2010-11-17  2:58     ` Benjamin Poirier
2010-11-09  1:46 ` [Qemu-devel] [PATCH v2 2/2] rtl8139: add vlan tag extraction Benjamin Poirier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4CE2E435.9000207@codemonkey.ws \
    --to=anthony@codemonkey.ws \
    --cc=benjamin.poirier@polymtl.ca \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.