[dpdk-dev,v3,09/10] vmxnet3: add check for jumbo segment
Commit Message
From: Stephen Hemminger <shemming@brocade.com>
It is possible that some rogue application might pass a segment
larger than 16K to the vmxnet3 transmit routine. In which case
just drop it and increment counter.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_pmd_vmxnet3/vmxnet3_ring.h | 1 +
lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 18 ++++++++++++++++++
2 files changed, 19 insertions(+)
Comments
On 3/5/15, 4:10 PM, "Stephen Hemminger" <stephen@networkplumber.org> wrote:
>From: Stephen Hemminger <shemming@brocade.com>
>
>It is possible that some rogue application might pass a segment
>larger than 16K to the vmxnet3 transmit routine. In which case
>just drop it and increment counter.
>
>Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
One minor comment below. Otherwise looks good to me.
Acked-by: Yong Wang <yongwang@vmware.com>
>---
> lib/librte_pmd_vmxnet3/vmxnet3_ring.h | 1 +
> lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 18 ++++++++++++++++++
> 2 files changed, 19 insertions(+)
>
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
>b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
>index 55ceadf..5cdcb23 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
>@@ -126,6 +126,7 @@ struct vmxnet3_txq_stats {
> * different reasons
> */
> uint64_t drop_too_many_segs;
>+ uint64_t drop_too_big;
> uint64_t drop_tso;
> uint64_t tx_ring_full;
> };
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>index 3bd13ef..f6c3452 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>@@ -327,6 +327,17 @@ vmxnet3_tq_tx_complete(vmxnet3_tx_queue_t *txq)
> PMD_TX_LOG(DEBUG, "Processed %d tx comps & command descs.", completed);
> }
>
>+static inline int
>+vmxnet3_seg_too_big(const struct rte_mbuf *m)
>+{
>+ do {
>+ if (m->data_len > VMXNET3_MAX_TX_BUF_SIZE)
>+ return 1;
>+ } while ((m = m->next) != NULL);
nit: extra space after "while”.
>+
>+ return 0;
>+}
>+
> uint16_t
> vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
> uint16_t nb_pkts)
>@@ -353,6 +364,13 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf
>**tx_pkts,
> /* Is this packet execessively fragmented, then drop */
> if (unlikely(txm->nb_segs > VMXNET3_MAX_TXD_PER_PKT)) {
> ++txq->stats.drop_too_many_segs;
>+ goto drop;
>+ }
>+
>+ /* Check for case of monster segment */
>+ if (unlikely(vmxnet3_seg_too_big(txm))) {
>+ ++txq->stats.drop_too_big;
>+ drop:
> ++txq->stats.drop_total;
> rte_pktmbuf_free(txm);
> ++nb_tx;
>--
>2.1.4
>
@@ -126,6 +126,7 @@ struct vmxnet3_txq_stats {
* different reasons
*/
uint64_t drop_too_many_segs;
+ uint64_t drop_too_big;
uint64_t drop_tso;
uint64_t tx_ring_full;
};
@@ -327,6 +327,17 @@ vmxnet3_tq_tx_complete(vmxnet3_tx_queue_t *txq)
PMD_TX_LOG(DEBUG, "Processed %d tx comps & command descs.", completed);
}
+static inline int
+vmxnet3_seg_too_big(const struct rte_mbuf *m)
+{
+ do {
+ if (m->data_len > VMXNET3_MAX_TX_BUF_SIZE)
+ return 1;
+ } while ((m = m->next) != NULL);
+
+ return 0;
+}
+
uint16_t
vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts)
@@ -353,6 +364,13 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
/* Is this packet execessively fragmented, then drop */
if (unlikely(txm->nb_segs > VMXNET3_MAX_TXD_PER_PKT)) {
++txq->stats.drop_too_many_segs;
+ goto drop;
+ }
+
+ /* Check for case of monster segment */
+ if (unlikely(vmxnet3_seg_too_big(txm))) {
+ ++txq->stats.drop_too_big;
+ drop:
++txq->stats.drop_total;
rte_pktmbuf_free(txm);
++nb_tx;