]> git.proxmox.com Git - mirror_ovs.git/blobdiff - lib/dp-packet.h
dpif-netdev: Reorder elements in dp_netdev_port structure.
[mirror_ovs.git] / lib / dp-packet.h
index e4c25936b4372886804d4becfa88a46ad4fc930d..1469864cf726a0d3a01a1e194039589ebefdedd5 100644 (file)
 
 #include <stddef.h>
 #include <stdint.h>
-#include "list.h"
+
+#ifdef DPDK_NETDEV
+#include <rte_config.h>
+#include <rte_mbuf.h>
+#endif
+
+#include "netdev-dpdk.h"
+#include "openvswitch/list.h"
 #include "packets.h"
 #include "util.h"
-#include "netdev-dpdk.h"
 
 #ifdef  __cplusplus
 extern "C" {
@@ -36,6 +42,8 @@ enum OVS_PACKED_ENUM dp_packet_source {
                                 * ref to build_dp_packet() in netdev-dpdk. */
 };
 
+#define DP_PACKET_CONTEXT_SIZE 64
+
 /* Buffer for holding packet data.  A dp_packet is automatically reallocated
  * as necessary if it grows too large for the available memory.
  */
@@ -48,6 +56,7 @@ struct dp_packet {
     uint16_t data_ofs;          /* First byte actually in use. */
     uint32_t size_;             /* Number of bytes in use. */
     uint32_t rss_hash;          /* Packet hash. */
+    bool rss_hash_valid;        /* Is the 'rss_hash' valid? */
 #endif
     enum dp_packet_source source;  /* Source of memory allocated as 'base'. */
     uint8_t l2_pad_size;           /* Detected l2 padding size.
@@ -57,7 +66,11 @@ struct dp_packet {
                                     * or UINT16_MAX. */
     uint16_t l4_ofs;               /* Transport-level header offset,
                                       or UINT16_MAX. */
-    struct pkt_metadata md;
+    uint32_t cutlen;               /* length in bytes to cut from the end. */
+    union {
+        struct pkt_metadata md;
+        uint64_t data[DP_PACKET_CONTEXT_SIZE / 8];
+    };
 };
 
 static inline void *dp_packet_data(const struct dp_packet *);
@@ -139,7 +152,6 @@ static inline void *dp_packet_try_pull(struct dp_packet *, size_t);
 
 void *dp_packet_steal_data(struct dp_packet *);
 
-char *dp_packet_to_string(const struct dp_packet *, size_t maxbytes);
 static inline bool dp_packet_equal(const struct dp_packet *,
                                    const struct dp_packet *);
 
@@ -489,6 +501,34 @@ dp_packet_set_allocated(struct dp_packet *b, uint16_t s)
 }
 #endif
 
+static inline void
+dp_packet_reset_cutlen(struct dp_packet *b)
+{
+    b->cutlen = 0;
+}
+
+static inline uint32_t
+dp_packet_set_cutlen(struct dp_packet *b, uint32_t max_len)
+{
+    if (max_len < ETH_HEADER_LEN) {
+        max_len = ETH_HEADER_LEN;
+    }
+
+    if (max_len >= dp_packet_size(b)) {
+        b->cutlen = 0;
+    } else {
+        b->cutlen = dp_packet_size(b) - max_len;
+    }
+    return b->cutlen;
+}
+
+static inline uint32_t
+dp_packet_get_cutlen(struct dp_packet *b)
+{
+    /* Always in valid range if user uses dp_packet_set_cutlen. */
+    return b->cutlen;
+}
+
 static inline void *
 dp_packet_data(const struct dp_packet *b)
 {
@@ -511,9 +551,11 @@ dp_packet_reset_packet(struct dp_packet *b, int off)
 {
     dp_packet_set_size(b, dp_packet_size(b) - off);
     dp_packet_set_data(b, ((unsigned char *) dp_packet_data(b) + off));
-    b->l2_5_ofs = b->l3_ofs = b->l4_ofs = UINT16_MAX;
+    dp_packet_reset_offsets(b);
 }
 
+/* Returns the RSS hash of the packet 'p'.  Note that the returned value is
+ * correct only if 'dp_packet_rss_valid(p)' returns true */
 static inline uint32_t
 dp_packet_get_rss_hash(struct dp_packet *p)
 {
@@ -529,11 +571,112 @@ dp_packet_set_rss_hash(struct dp_packet *p, uint32_t hash)
 {
 #ifdef DPDK_NETDEV
     p->mbuf.hash.rss = hash;
+    p->mbuf.ol_flags |= PKT_RX_RSS_HASH;
 #else
     p->rss_hash = hash;
+    p->rss_hash_valid = true;
 #endif
 }
 
+static inline bool
+dp_packet_rss_valid(struct dp_packet *p)
+{
+#ifdef DPDK_NETDEV
+    return p->mbuf.ol_flags & PKT_RX_RSS_HASH;
+#else
+    return p->rss_hash_valid;
+#endif
+}
+
+static inline void
+dp_packet_rss_invalidate(struct dp_packet *p)
+{
+#ifdef DPDK_NETDEV
+    p->mbuf.ol_flags &= ~PKT_RX_RSS_HASH;
+#else
+    p->rss_hash_valid = false;
+#endif
+}
+
+enum { NETDEV_MAX_BURST = 32 }; /* Maximum number packets in a batch. */
+
+struct dp_packet_batch {
+    int count;
+    bool trunc; /* true if the batch needs truncate. */
+    struct dp_packet *packets[NETDEV_MAX_BURST];
+};
+
+static inline void dp_packet_batch_init(struct dp_packet_batch *b)
+{
+    b->count = 0;
+    b->trunc = false;
+}
+
+static inline void
+dp_packet_batch_clone(struct dp_packet_batch *dst,
+                      struct dp_packet_batch *src)
+{
+    int i;
+
+    for (i = 0; i < src->count; i++) {
+        dst->packets[i] = dp_packet_clone(src->packets[i]);
+    }
+    dst->count = src->count;
+    dst->trunc = src->trunc;
+}
+
+static inline void
+packet_batch_init_packet(struct dp_packet_batch *b, struct dp_packet *p)
+{
+    b->count = 1;
+    b->trunc = false;
+    b->packets[0] = p;
+}
+
+static inline void
+dp_packet_delete_batch(struct dp_packet_batch *batch, bool may_steal)
+{
+    if (may_steal) {
+        int i;
+
+        for (i = 0; i < batch->count; i++) {
+            dp_packet_delete(batch->packets[i]);
+        }
+    }
+}
+
+static inline void
+dp_packet_batch_apply_cutlen(struct dp_packet_batch *pktb)
+{
+    int i;
+
+    if (!pktb->trunc)
+        return;
+
+    for (i = 0; i < pktb->count; i++) {
+        uint32_t cutlen = dp_packet_get_cutlen(pktb->packets[i]);
+
+        dp_packet_set_size(pktb->packets[i],
+                    dp_packet_size(pktb->packets[i]) - cutlen);
+        dp_packet_reset_cutlen(pktb->packets[i]);
+    }
+    pktb->trunc = false;
+}
+
+static inline void
+dp_packet_batch_reset_cutlen(struct dp_packet_batch *pktb)
+{
+    int i;
+
+    if (!pktb->trunc)
+        return;
+
+    pktb->trunc = false;
+    for (i = 0; i < pktb->count; i++) {
+        dp_packet_reset_cutlen(pktb->packets[i]);
+    }
+}
+
 #ifdef  __cplusplus
 }
 #endif