#ifdef DPDK_NETDEV
struct rte_mbuf mbuf; /* DPDK mbuf */
#else
- void *base_; /* First byte of allocated space. */
- void *data_; /* First byte actually in use. */
- uint32_t size_; /* Number of bytes in use. */
+ void *base_; /* First byte of allocated space. */
+ uint16_t data_ofs; /* First byte actually in use. */
+ uint32_t size_; /* Number of bytes in use. */
uint32_t dp_hash; /* Packet hash. */
#endif
uint32_t allocated; /* Number of bytes allocated. */
#ifdef DPDK_NETDEV
BUILD_ASSERT_DECL(offsetof(struct dp_packet, mbuf) == 0);
-static inline void * dp_packet_data(const struct dp_packet *b)
-{
- return b->mbuf.pkt.data;
-}
-
-static inline void dp_packet_set_data(struct dp_packet *b, void *d)
-{
- b->mbuf.pkt.data = d;
-}
-
static inline void * dp_packet_base(const struct dp_packet *b)
{
return b->mbuf.buf_addr;
static inline uint32_t dp_packet_size(const struct dp_packet *b)
{
- return b->mbuf.pkt.pkt_len;
+ return b->mbuf.pkt_len;
}
static inline void dp_packet_set_size(struct dp_packet *b, uint32_t v)
{
- b->mbuf.pkt.data_len = v; /* Current seg length. */
- b->mbuf.pkt.pkt_len = v; /* Total length of all segments linked to
- * this segment. */
+ /* netdev-dpdk does not currently support segmentation; consequently, for
+ * all intents and purposes, 'data_len' (16 bit) and 'pkt_len' (32 bit) may
+ * be used interchangably.
+ *
+ * On the datapath, it is expected that the size of packets
+ * (and thus 'v') will always be <= UINT16_MAX; this means that there is no
+ * loss of accuracy in assigning 'v' to 'data_len'.
+ *
+ * However, control ofpbufs may well be larger than UINT16_MAX (i.e. 'v' >
+ * UINT16_MAX); even though the value is truncated when assigned to
+ * 'data_len', loss of accuracy is avoided in this situation by using
+ * 'pkt_len' to represent the packet size.
+ */
+ b->mbuf.data_len = (uint16_t)v; /* Current seg length. */
+ b->mbuf.pkt_len = v; /* Total length of all segments linked to
+ * this segment. */
+
}
-#else
-static inline void * dp_packet_data(const struct dp_packet *b)
+static inline uint16_t __packet_data(const struct dp_packet *b)
{
- return b->data_;
+ return b->mbuf.data_off;
}
-static inline void dp_packet_set_data(struct dp_packet *b, void *d)
+static inline void __packet_set_data(struct dp_packet *b, uint16_t v)
{
- b->data_ = d;
+ b->mbuf.data_off = v;
}
+#else
static inline void * dp_packet_base(const struct dp_packet *b)
{
return b->base_;
{
b->size_ = v;
}
+
+static inline uint16_t __packet_data(const struct dp_packet *b)
+{
+ return b->data_ofs;
+}
+
+static inline void __packet_set_data(struct dp_packet *b, uint16_t v)
+{
+ b->data_ofs = v;
+}
+
#endif
+static inline void * dp_packet_data(const struct dp_packet *b)
+{
+ return __packet_data(b) != UINT16_MAX ?
+ (char *)dp_packet_base(b) + __packet_data(b) : NULL;
+}
+
+static inline void dp_packet_set_data(struct dp_packet *b, void *data)
+{
+ if (data) {
+ __packet_set_data(b, (char *)data - (char *)dp_packet_base(b));
+ } else {
+ __packet_set_data(b, UINT16_MAX);
+ }
+}
+
static inline void dp_packet_reset_packet(struct dp_packet *b, int off)
{
dp_packet_set_size(b, dp_packet_size(b) - off);
static inline uint32_t dp_packet_get_dp_hash(struct dp_packet *p)
{
#ifdef DPDK_NETDEV
- return p->mbuf.pkt.hash.rss;
+ return p->mbuf.hash.rss;
#else
return p->dp_hash;
#endif
uint32_t hash)
{
#ifdef DPDK_NETDEV
- p->mbuf.pkt.hash.rss = hash;
+ p->mbuf.hash.rss = hash;
#else
p->dp_hash = hash;
#endif
#include "unixctl.h"
#include "openvswitch/vlog.h"
+#include "rte_config.h"
+#include "rte_mbuf.h"
+
VLOG_DEFINE_THIS_MODULE(dpdk);
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
m->buf_len = (uint16_t)buf_len;
/* keep some headroom between start of buffer and data */
- m->pkt.data = (char*) m->buf_addr + RTE_MIN(RTE_PKTMBUF_HEADROOM, m->buf_len);
+ m->data_off = RTE_MIN(RTE_PKTMBUF_HEADROOM, m->buf_len);
/* init some constant fields */
- m->type = RTE_MBUF_PKT;
m->pool = mp;
- m->pkt.nb_segs = 1;
- m->pkt.in_port = 0xff;
+ m->nb_segs = 1;
+ m->port = 0xff;
}
static void
}
/* We have to do a copy for now */
- memcpy(mbufs[newcnt]->pkt.data, dp_packet_data(pkts[i]), size);
+ memcpy(rte_pktmbuf_mtod(mbufs[newcnt], void *), dp_packet_data(pkts[i]), size);
rte_pktmbuf_data_len(mbufs[newcnt]) = size;
rte_pktmbuf_pkt_len(mbufs[newcnt]) = size;
ovs_thread_create("dpdk_watchdog", dpdk_watchdog, NULL);
}
-static int
-dpdk_class_init(void)
-{
- int result;
-
- result = rte_eal_pci_probe();
- if (result) {
- VLOG_ERR("Cannot probe PCI");
- return -result;
- }
-
- VLOG_INFO("Ethernet Device Count: %d", (int)rte_eth_dev_count());
-
- return 0;
-}
-
/* Client Rings */
static int
const struct netdev_class dpdk_class =
NETDEV_DPDK_CLASS(
"dpdk",
- dpdk_class_init,
+ NULL,
netdev_dpdk_construct,
netdev_dpdk_set_multiq,
netdev_dpdk_eth_send);