uint32_t allocated; /* Number of bytes allocated. */
void *frame; /* Packet frame start, or NULL. */
+ enum ofpbuf_source source; /* Source of memory allocated as 'base'. */
+ uint8_t l2_pad_size; /* Detected l2 padding size.
+ * Padding is non-pullable. */
uint16_t l2_5_ofs; /* MPLS label stack offset from 'frame', or
* UINT16_MAX */
uint16_t l3_ofs; /* Network-level header offset from 'frame',
or UINT16_MAX. */
uint16_t l4_ofs; /* Transport-level header offset from 'frame',
or UINT16_MAX. */
- enum ofpbuf_source source; /* Source of memory allocated as 'base'. */
- struct list list_node; /* Private list element for use by owner. */
+ struct ovs_list list_node; /* Private list element for use by owner. */
};
static inline void * ofpbuf_data(const struct ofpbuf *);
void * ofpbuf_resize_l2_5(struct ofpbuf *, int increment);
static inline void * ofpbuf_l2(const struct ofpbuf *);
static inline void ofpbuf_set_frame(struct ofpbuf *, void *);
+static inline uint8_t ofpbuf_l2_pad_size(const struct ofpbuf *);
+static inline void ofpbuf_set_l2_pad_size(struct ofpbuf *, uint8_t);
static inline void * ofpbuf_l2_5(const struct ofpbuf *);
static inline void ofpbuf_set_l2_5(struct ofpbuf *, void *);
static inline void * ofpbuf_l3(const struct ofpbuf *);
void *ofpbuf_steal_data(struct ofpbuf *);
char *ofpbuf_to_string(const struct ofpbuf *, size_t maxbytes);
-static inline struct ofpbuf *ofpbuf_from_list(const struct list *);
-void ofpbuf_list_delete(struct list *);
+static inline struct ofpbuf *ofpbuf_from_list(const struct ovs_list *);
+void ofpbuf_list_delete(struct ovs_list *);
static inline bool ofpbuf_equal(const struct ofpbuf *, const struct ofpbuf *);
\f
{
if (b) {
if (b->source == OFPBUF_DPDK) {
- free_dpdk_buf(b);
+ /* If this ofpbuf was allocated by DPDK it must have been
+ * created as a dpif_packet */
+ free_dpdk_buf((struct dpif_packet*) b);
return;
}
return ((char *) ofpbuf_data(b)) + offset;
}
-/* Returns the byte following the last byte of data in use in 'b'. */
+/* Returns a pointer to byte following the last byte of data in use in 'b'. */
static inline void *ofpbuf_tail(const struct ofpbuf *b)
{
return (char *) ofpbuf_data(b) + ofpbuf_size(b);
}
-/* Returns the byte following the last byte allocated for use (but not
- * necessarily in use) by 'b'. */
+/* Returns a pointer to byte following the last byte allocated for use (but
+ * not necessarily in use) in 'b'. */
static inline void *ofpbuf_end(const struct ofpbuf *b)
{
return (char *) ofpbuf_base(b) + b->allocated;
static inline void *ofpbuf_pull(struct ofpbuf *b, size_t size)
{
void *data = ofpbuf_data(b);
- ovs_assert(ofpbuf_size(b) >= size);
+ ovs_assert(ofpbuf_size(b) - ofpbuf_l2_pad_size(b) >= size);
ofpbuf_set_data(b, (char*)ofpbuf_data(b) + size);
ofpbuf_set_size(b, ofpbuf_size(b) - size);
return data;
* null pointer without modifying 'b'. */
static inline void *ofpbuf_try_pull(struct ofpbuf *b, size_t size)
{
- return ofpbuf_size(b) >= size ? ofpbuf_pull(b, size) : NULL;
+ return ofpbuf_size(b) - ofpbuf_l2_pad_size(b) >= size
+ ? ofpbuf_pull(b, size) : NULL;
}
-static inline struct ofpbuf *ofpbuf_from_list(const struct list *list)
+static inline struct ofpbuf *ofpbuf_from_list(const struct ovs_list *list)
{
return CONTAINER_OF(list, struct ofpbuf, list_node);
}
static inline void ofpbuf_set_frame(struct ofpbuf *b, void *packet)
{
b->frame = packet;
+ b->l2_pad_size = 0;
b->l2_5_ofs = UINT16_MAX;
b->l3_ofs = UINT16_MAX;
b->l4_ofs = UINT16_MAX;
}
+static inline uint8_t ofpbuf_l2_pad_size(const struct ofpbuf *b)
+{
+ return b->l2_pad_size;
+}
+
+static inline void ofpbuf_set_l2_pad_size(struct ofpbuf *b, uint8_t pad_size)
+{
+ ovs_assert(pad_size <= ofpbuf_size(b));
+ b->l2_pad_size = pad_size;
+}
+
static inline void * ofpbuf_l2_5(const struct ofpbuf *b)
{
return b->l2_5_ofs != UINT16_MAX ? (char *)b->frame + b->l2_5_ofs : NULL;
static inline size_t ofpbuf_l4_size(const struct ofpbuf *b)
{
return b->l4_ofs != UINT16_MAX
- ? (const char *)ofpbuf_tail(b) - (const char *)ofpbuf_l4(b) : 0;
+ ? (const char *)ofpbuf_tail(b) - (const char *)ofpbuf_l4(b)
+ - ofpbuf_l2_pad_size(b)
+ : 0;
}
static inline const void *ofpbuf_get_tcp_payload(const struct ofpbuf *b)
}
#ifdef DPDK_NETDEV
+BUILD_ASSERT_DECL(offsetof(struct ofpbuf, mbuf) == 0);
+
static inline void * ofpbuf_data(const struct ofpbuf *b)
{
return b->mbuf.pkt.data;
}
#endif
+static inline void ofpbuf_reset_packet(struct ofpbuf *b, int off)
+{
+ ofpbuf_set_size(b, ofpbuf_size(b) - off);
+ ofpbuf_set_data(b, (void *) ((unsigned char *) b->frame + off));
+ b->frame = NULL;
+ b->l2_5_ofs = b->l3_ofs = b->l4_ofs = UINT16_MAX;
+}
+
#ifdef __cplusplus
}
#endif