Some simple comments below, otherwise: Acked-by: Jarno Rajahalme <jrajaha...@nicira.com>
> On Mar 2, 2015, at 10:51 AM, Pravin B Shelar <pshe...@nicira.com> wrote: > (snip) > diff --git a/lib/bfd.c b/lib/bfd.c > index 3db1d57..62ace8f 100644 > --- a/lib/bfd.c > +++ b/lib/bfd.c > @@ -35,6 +35,7 @@ > #include "ofpbuf.h" > #include "ovs-thread.h" > #include "openvswitch/types.h" > +#include "dp-packet.h” It would be nice to place this alphabetically… This repeats a lot below. > #include "packets.h" > #include "poll-loop.h" > #include "random.h" > @@ -585,7 +586,7 @@ bfd_should_send_packet(const struct bfd *bfd) > OVS_EXCLUDED(mutex) > } > > (snip) > diff --git a/lib/cfm.c b/lib/cfm.c > index 23c1c6f..6d0458d 100644 > --- a/lib/cfm.c > +++ b/lib/cfm.c > @@ -28,7 +28,7 @@ > #include "hash.h" > #include "hmap.h" > #include "netdev.h" > -#include "ofpbuf.h" > +#include "dp-packet.h” Same. > #include "packets.h" > #include "poll-loop.h" > #include “random.h" > (snip) > diff --git a/lib/dp-packet.c b/lib/dp-packet.c > index d77f8e4..b90f678 100644 > --- a/lib/dp-packet.c > +++ b/lib/dp-packet.c > @@ -1,5 +1,5 @@ > /* > - * Copyright (c) 2014 Nicira, Inc. > + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. > * > * Licensed under the Apache License, Version 2.0 (the "License"); > * you may not use this file except in compliance with the License. > @@ -15,57 +15,555 @@ > */ > > #include <config.h> > +#include <stdlib.h> > +#include <string.h> > +#include "dynamic-string.h" > +#include "netdev-dpdk.h" > #include "dp-packet.h" > +#include "util.h" > > -#include "ofpbuf.h" > +static void > +dp_packet_init__(struct dp_packet *b, size_t allocated, enum > dp_packet_source source) > +{ > + b->allocated = allocated; > + b->source = source; > + b->frame = NULL; > + b->l2_pad_size = 0; > + b->l2_5_ofs = b->l3_ofs = b->l4_ofs = UINT16_MAX; > + b->md = PKT_METADATA_INITIALIZER(0); > + list_poison(&b->list_node); > +} > + > +static void > +dp_packet_use__(struct dp_packet *b, void *base, size_t allocated, > + enum dp_packet_source source) > +{ > + dp_packet_set_base(b, base); > + dp_packet_set_data(b, base); > + dp_packet_set_size(b, 0); > + > + dp_packet_init__(b, allocated, source); > +} > + > +/* Initializes 'b' as an empty dp_packet that contains the 'allocated' bytes > of > + * memory starting at 'base'. 'base' should be the first byte of a region > + * obtained from malloc(). It will be freed (with free()) if 'b' is resized > or > + * freed. */ > +void > +dp_packet_use(struct dp_packet *b, void *base, size_t allocated) > +{ > + dp_packet_use__(b, base, allocated, DPBUF_MALLOC); > +} > + > +/* Initializes 'b' as an empty dp_packet that contains the 'allocated' bytes > of > + * memory starting at 'base'. 'base' should point to a buffer on the stack. > + * (Nothing actually relies on 'base' being allocated on the stack. It could > + * be static or malloc()'d memory. But stack space is the most common use > + * case.) > + * > + * 'base' should be appropriately aligned. Using an array of uint32_t or > + * uint64_t for the buffer is a reasonable way to ensure appropriate > alignment > + * for 32- or 64-bit data. > + * > + * An dp_packet operation that requires reallocating data will assert-fail > if this > + * function was used to initialize it. Thus, one need not call > dp_packet_uninit() > + * on an dp_packet initialized by this function (though doing so is > harmless), > + * because it is guaranteed that 'b' does not own any heap-allocated memory. > */ > +void > +dp_packet_use_stack(struct dp_packet *b, void *base, size_t allocated) > +{ > + dp_packet_use__(b, base, allocated, DPBUF_STACK); > +} There seems to be only one use of this. IMO it could be replaced with dp_packet_use_stub(), especially since the buffer there is not from the stack… > + > +/* Initializes 'b' as an empty dp_packet that contains the 'allocated' bytes > of > + * memory starting at 'base'. 'base' should point to a buffer on the stack. > + * (Nothing actually relies on 'base' being allocated on the stack. It could > + * be static or malloc()'d memory. But stack space is the most common use > + * case.) > + * > + * 'base' should be appropriately aligned. Using an array of uint32_t or > + * uint64_t for the buffer is a reasonable way to ensure appropriate > alignment > + * for 32- or 64-bit data. > + * > + * An dp_packet operation that requires reallocating data will copy the > provided > + * buffer into a malloc()'d buffer. Thus, it is wise to call > dp_packet_uninit() > + * on an dp_packet initialized by this function, so that if it expanded into > the > + * heap, that memory is freed. */ > +void > +dp_packet_use_stub(struct dp_packet *b, void *base, size_t allocated) > +{ > + dp_packet_use__(b, base, allocated, DPBUF_STUB); > +} > > +/* Initializes 'b' as an dp_packet whose data starts at 'data' and continues > for > + * 'size' bytes. This is appropriate for an dp_packet that will be used to > + * inspect existing data, without moving it around or reallocating it, and > + * generally without modifying it at all. > + * > + * An dp_packet operation that requires reallocating data will assert-fail > if this > + * function was used to initialize it. */ > +void > +dp_packet_use_const(struct dp_packet *b, const void *data, size_t size) > +{ > + dp_packet_use__(b, CONST_CAST(void *, data), size, DPBUF_STACK); > + dp_packet_set_size(b, size); > +} > + > +/* Initializes 'b' as an empty dp_packet that contains the 'allocated' bytes > of > + * memory starting at 'base'. DPDK allocated dp_packet and *data is > allocated > + * from one continous memory region, so in memory data start right after > + * dp_packet. Therefore there is special method to free this type of > + * buffer. dp_packet base, data and size are initialized by dpdk rcv() so no > + * need to initialize those fields. */ > +void > +dp_packet_init_dpdk(struct dp_packet *b, size_t allocated) > +{ > + dp_packet_init__(b, allocated, DPBUF_DPDK); > +} > + > +/* Initializes 'b' as an empty dp_packet with an initial capacity of 'size' > + * bytes. */ > +void > +dp_packet_init(struct dp_packet *b, size_t size) > +{ > + dp_packet_use(b, size ? xmalloc(size) : NULL, size); > +} > + > +/* Frees memory that 'b' points to. */ > +void > +dp_packet_uninit(struct dp_packet *b) > +{ > + if (b) { > + if (b->source == DPBUF_MALLOC) { > + free(dp_packet_base(b)); > + } else if (b->source == DPBUF_DPDK) { > +#ifdef DPDK_NETDEV > + /* If this dp_packet was allocated by DPDK it must have been > + * created as a dp_packet */ > + free_dpdk_buf((struct dp_packet*) b); > +#else > + ovs_assert(b->source != DPBUF_DPDK); > +#endif > + } > + } > +} > + > +/* Frees memory that 'b' points to and allocates a new dp_packet */ > +void > +dp_packet_reinit(struct dp_packet *b, size_t size) > +{ > + dp_packet_uninit(b); > + dp_packet_init(b, size); > +} This has no users, could it be removed? Otherwise, if this will be used in the fast path, this seems like an obvious candidate for optimization. > + > +/* Creates and returns a new dp_packet with an initial capacity of 'size' > + * bytes. */ > +struct dp_packet * > +dp_packet_new(size_t size) > +{ > + struct dp_packet *b = xmalloc(sizeof *b); > + dp_packet_init(b, size); > + return b; > +} > + > +/* Creates and returns a new dp_packet with an initial capacity of 'size + > + * headroom' bytes, reserving the first 'headroom' bytes as headroom. */ > struct dp_packet * > dp_packet_new_with_headroom(size_t size, size_t headroom) > { > - struct dp_packet *p = xmalloc(sizeof *p); > - struct ofpbuf *b = &p->ofpbuf; > + struct dp_packet *b = dp_packet_new(size + headroom); > + dp_packet_reserve(b, headroom); > + return b; > +} > > - ofpbuf_init(b, size + headroom); > - ofpbuf_reserve(b, headroom); > - p->md = PKT_METADATA_INITIALIZER(0); > +/* Creates and returns a new dp_packet that initially contains a copy of the > + * 'dp_packet_size(buffer)' bytes of data starting at 'buffer->data' with no > headroom or > + * tailroom. */ > +struct dp_packet * > +dp_packet_clone(const struct dp_packet *buffer) > +{ > + return dp_packet_clone_with_headroom(buffer, 0); > +} > > - return p; > +/* Creates and returns a new dp_packet whose data are copied from 'buffer'. > The > + * returned dp_packet will additionally have 'headroom' bytes of headroom. */ > +struct dp_packet * > +dp_packet_clone_with_headroom(const struct dp_packet *buffer, size_t > headroom) > +{ > + struct dp_packet *new_buffer; > + > + new_buffer = dp_packet_clone_data_with_headroom(dp_packet_data(buffer), > + dp_packet_size(buffer), > + headroom); > + if (buffer->frame) { > + uintptr_t data_delta > + = (char *)dp_packet_data(new_buffer) - (char > *)dp_packet_data(buffer); > + > + new_buffer->frame = (char *) buffer->frame + data_delta; > + } > + new_buffer->l2_pad_size = buffer->l2_pad_size; > + new_buffer->l2_5_ofs = buffer->l2_5_ofs; > + new_buffer->l3_ofs = buffer->l3_ofs; > + new_buffer->l4_ofs = buffer->l4_ofs; > + new_buffer->md = buffer->md; > + > + return new_buffer; > +} > + > +/* Creates and returns a new dp_packet that initially contains a copy of the > + * 'size' bytes of data starting at 'data' with no headroom or tailroom. */ > +struct dp_packet * > +dp_packet_clone_data(const void *data, size_t size) > +{ > + return dp_packet_clone_data_with_headroom(data, size, 0); > } > > +/* Creates and returns a new dp_packet that initially contains 'headroom' > bytes of > + * headroom followed by a copy of the 'size' bytes of data starting at > + * 'data'. */ > struct dp_packet * > -dp_packet_clone_from_ofpbuf(const struct ofpbuf *b) > +dp_packet_clone_data_with_headroom(const void *data, size_t size, size_t > headroom) > { > - struct dp_packet *p = xmalloc(sizeof *p); > - size_t headroom = ofpbuf_headroom(b); > + struct dp_packet *b = dp_packet_new_with_headroom(size, headroom); > + dp_packet_put(b, data, size); > + return b; > +} > > - ofpbuf_init(&p->ofpbuf, ofpbuf_size(b) + headroom); > - p->md = PKT_METADATA_INITIALIZER(0); > - ofpbuf_reserve(&p->ofpbuf, headroom); > +static void > +dp_packet_copy__(struct dp_packet *b, uint8_t *new_base, > + size_t new_headroom, size_t new_tailroom) > +{ > + const uint8_t *old_base = dp_packet_base(b); > + size_t old_headroom = dp_packet_headroom(b); > + size_t old_tailroom = dp_packet_tailroom(b); > + size_t copy_headroom = MIN(old_headroom, new_headroom); > + size_t copy_tailroom = MIN(old_tailroom, new_tailroom); > > - ofpbuf_put(&p->ofpbuf, ofpbuf_data(b), ofpbuf_size(b)); > + memcpy(&new_base[new_headroom - copy_headroom], > + &old_base[old_headroom - copy_headroom], > + copy_headroom + dp_packet_size(b) + copy_tailroom); > +} > > - if (b->frame) { > - uintptr_t data_delta > - = (char *)ofpbuf_data(&p->ofpbuf) - (char *)ofpbuf_data(b); > +/* Reallocates 'b' so that it has exactly 'new_headroom' and 'new_tailroom' > + * bytes of headroom and tailroom, respectively. */ > +static void > +dp_packet_resize__(struct dp_packet *b, size_t new_headroom, size_t > new_tailroom) > +{ > + void *new_base, *new_data; > + size_t new_allocated; > + > + new_allocated = new_headroom + dp_packet_size(b) + new_tailroom; > + > + switch (b->source) { > + case DPBUF_DPDK: > + OVS_NOT_REACHED(); > + > + case DPBUF_MALLOC: > + if (new_headroom == dp_packet_headroom(b)) { > + new_base = xrealloc(dp_packet_base(b), new_allocated); > + } else { > + new_base = xmalloc(new_allocated); > + dp_packet_copy__(b, new_base, new_headroom, new_tailroom); > + free(dp_packet_base(b)); > + } > + break; > > - p->ofpbuf.frame = (char *) b->frame + data_delta; > + case DPBUF_STACK: > + OVS_NOT_REACHED(); > + > + case DPBUF_STUB: > + b->source = DPBUF_MALLOC; > + new_base = xmalloc(new_allocated); > + dp_packet_copy__(b, new_base, new_headroom, new_tailroom); > + break; > + > + default: > + OVS_NOT_REACHED(); > } > - p->ofpbuf.l2_5_ofs = b->l2_5_ofs; > - p->ofpbuf.l3_ofs = b->l3_ofs; > - p->ofpbuf.l4_ofs = b->l4_ofs; > > + b->allocated = new_allocated; > + dp_packet_set_base(b, new_base); > + > + new_data = (char *) new_base + new_headroom; > + if (dp_packet_data(b) != new_data) { > + if (b->frame) { > + uintptr_t data_delta = (char *) new_data - (char *) > dp_packet_data(b); > + > + b->frame = (char *) b->frame + data_delta; > + } > + dp_packet_set_data(b, new_data); > + } > +} > + > +/* Ensures that 'b' has room for at least 'size' bytes at its tail end, > + * reallocating and copying its data if necessary. Its headroom, if any, is > + * preserved. */ > +void > +dp_packet_prealloc_tailroom(struct dp_packet *b, size_t size) > +{ > + if (size > dp_packet_tailroom(b)) { > + dp_packet_resize__(b, dp_packet_headroom(b), MAX(size, 64)); > + } > +} > + > +/* Ensures that 'b' has room for at least 'size' bytes at its head, > + * reallocating and copying its data if necessary. Its tailroom, if any, is > + * preserved. */ > +void > +dp_packet_prealloc_headroom(struct dp_packet *b, size_t size) > +{ > + if (size > dp_packet_headroom(b)) { > + dp_packet_resize__(b, MAX(size, 64), dp_packet_tailroom(b)); > + } > +} > + > +/* Trims the size of 'b' to fit its actual content, reducing its headroom and > + * tailroom to 0, if any. > + * > + * Buffers not obtained from malloc() are not resized, since that wouldn't > save > + * any memory. */ > +void > +dp_packet_trim(struct dp_packet *b) > +{ > + ovs_assert(b->source != DPBUF_DPDK); > + > + if (b->source == DPBUF_MALLOC > + && (dp_packet_headroom(b) || dp_packet_tailroom(b))) { > + dp_packet_resize__(b, 0, 0); > + } > +} > + This has no users. > +/* If 'b' is shorter than 'length' bytes, pads its tail out with zeros to > that > + * length. */ > +void > +dp_packet_padto(struct dp_packet *b, size_t length) > +{ > + if (dp_packet_size(b) < length) { > + dp_packet_put_zeros(b, length - dp_packet_size(b)); > + } > +} > + This has no users. > +/* Shifts all of the data within the allocated space in 'b' by 'delta' bytes. > + * For example, a 'delta' of 1 would cause each byte of data to move one byte > + * forward (from address 'p' to 'p+1'), and a 'delta' of -1 would cause each > + * byte to move one byte backward (from 'p' to 'p-1'). */ > +void > +dp_packet_shift(struct dp_packet *b, int delta) > +{ > + ovs_assert(delta > 0 ? delta <= dp_packet_tailroom(b) > + : delta < 0 ? -delta <= dp_packet_headroom(b) > + : true); > + > + if (delta != 0) { > + char *dst = (char *) dp_packet_data(b) + delta; > + memmove(dst, dp_packet_data(b), dp_packet_size(b)); > + dp_packet_set_data(b, dst); > + } > +} > + > +/* Appends 'size' bytes of data to the tail end of 'b', reallocating and > + * copying its data if necessary. Returns a pointer to the first byte of the > + * new data, which is left uninitialized. */ > +void * > +dp_packet_put_uninit(struct dp_packet *b, size_t size) > +{ > + void *p; > + dp_packet_prealloc_tailroom(b, size); > + p = dp_packet_tail(b); > + dp_packet_set_size(b, dp_packet_size(b) + size); > return p; > } > > -struct dp_packet * > -dp_packet_clone(struct dp_packet *p) > +/* Appends 'size' zeroed bytes to the tail end of 'b'. Data in 'b' is > + * reallocated and copied if necessary. Returns a pointer to the first byte > of > + * the data's location in the dp_packet. */ > +void * > +dp_packet_put_zeros(struct dp_packet *b, size_t size) > +{ > + void *dst = dp_packet_put_uninit(b, size); > + memset(dst, 0, size); > + return dst; > +} > + > +/* Appends the 'size' bytes of data in 'p' to the tail end of 'b'. Data in > 'b' > + * is reallocated and copied if necessary. Returns a pointer to the first > + * byte of the data's location in the dp_packet. */ > +void * > +dp_packet_put(struct dp_packet *b, const void *p, size_t size) > +{ > + void *dst = dp_packet_put_uninit(b, size); > + memcpy(dst, p, size); > + return dst; > +} > + > +/* Parses as many pairs of hex digits as possible (possibly separated by > + * spaces) from the beginning of 's', appending bytes for their values to > 'b'. > + * Returns the first character of 's' that is not the first of a pair of hex > + * digits. If 'n' is nonnull, stores the number of bytes added to 'b' in > + * '*n'. */ > +char * > +dp_packet_put_hex(struct dp_packet *b, const char *s, size_t *n) > +{ > + size_t initial_size = dp_packet_size(b); > + for (;;) { > + uint8_t byte; > + bool ok; > + > + s += strspn(s, " \t\r\n"); > + byte = hexits_value(s, 2, &ok); > + if (!ok) { > + if (n) { > + *n = dp_packet_size(b) - initial_size; > + } > + return CONST_CAST(char *, s); > + } > + > + dp_packet_put(b, &byte, 1); > + s += 2; > + } > +} > + > +/* Reserves 'size' bytes of headroom so that they can be later allocated with > + * dp_packet_push_uninit() without reallocating the dp_packet. */ > +void > +dp_packet_reserve(struct dp_packet *b, size_t size) > +{ > + ovs_assert(!dp_packet_size(b)); > + dp_packet_prealloc_tailroom(b, size); > + dp_packet_set_data(b, (char*)dp_packet_data(b) + size); > +} > + > +/* Reserves 'headroom' bytes at the head and 'tailroom' at the end so that > + * they can be later allocated with dp_packet_push_uninit() or > + * dp_packet_put_uninit() without reallocating the dp_packet. */ > +void > +dp_packet_reserve_with_tailroom(struct dp_packet *b, size_t headroom, > + size_t tailroom) > +{ > + ovs_assert(!dp_packet_size(b)); > + dp_packet_prealloc_tailroom(b, headroom + tailroom); > + dp_packet_set_data(b, (char*)dp_packet_data(b) + headroom); > +} > + > +/* Prefixes 'size' bytes to the head end of 'b', reallocating and copying its > + * data if necessary. Returns a pointer to the first byte of the data's > + * location in the dp_packet. The new data is left uninitialized. */ > +void * > +dp_packet_push_uninit(struct dp_packet *b, size_t size) > +{ > + dp_packet_prealloc_headroom(b, size); > + dp_packet_set_data(b, (char*)dp_packet_data(b) - size); > + dp_packet_set_size(b, dp_packet_size(b) + size); > + return dp_packet_data(b); > +} > + > +/* Prefixes 'size' zeroed bytes to the head end of 'b', reallocating and > + * copying its data if necessary. Returns a pointer to the first byte of the > + * data's location in the dp_packet. */ > +void * > +dp_packet_push_zeros(struct dp_packet *b, size_t size) > +{ > + void *dst = dp_packet_push_uninit(b, size); > + memset(dst, 0, size); > + return dst; > +} > + > +/* Copies the 'size' bytes starting at 'p' to the head end of 'b', > reallocating > + * and copying its data if necessary. Returns a pointer to the first byte of > + * the data's location in the dp_packet. */ > +void * > +dp_packet_push(struct dp_packet *b, const void *p, size_t size) > +{ > + void *dst = dp_packet_push_uninit(b, size); > + memcpy(dst, p, size); > + return dst; > +} > + > +/* Returns the data in 'b' as a block of malloc()'d memory and frees the > buffer > + * within 'b'. (If 'b' itself was dynamically allocated, e.g. with > + * dp_packet_new(), then it should still be freed with, e.g., > dp_packet_delete().) */ > +void * > +dp_packet_steal_data(struct dp_packet *b) > +{ > + void *p; > + ovs_assert(b->source != DPBUF_DPDK); > + > + if (b->source == DPBUF_MALLOC && dp_packet_data(b) == dp_packet_base(b)) > { > + p = dp_packet_data(b); > + } else { > + p = xmemdup(dp_packet_data(b), dp_packet_size(b)); > + if (b->source == DPBUF_MALLOC) { > + free(dp_packet_base(b)); > + } > + } > + dp_packet_set_base(b, NULL); > + dp_packet_set_data(b, NULL); > + return p; > +} > + > +/* Returns a string that describes some of 'b''s metadata plus a hex dump of > up > + * to 'maxbytes' from the start of the buffer. */ > +char * > +dp_packet_to_string(const struct dp_packet *b, size_t maxbytes) > +{ > + struct ds s; > + > + ds_init(&s); > + ds_put_format(&s, "size=%"PRIu32", allocated=%"PRIu32", > head=%"PRIuSIZE", tail=%"PRIuSIZE"\n", > + dp_packet_size(b), b->allocated, > + dp_packet_headroom(b), dp_packet_tailroom(b)); > + ds_put_hex_dump(&s, dp_packet_data(b), MIN(dp_packet_size(b), maxbytes), > 0, false); > + return ds_cstr(&s); > +} > + > +/* Removes each of the "struct dp_packet"s on 'list' from the list and frees > + * them. */ > +void > +dp_packet_list_delete(struct ovs_list *list) > +{ > + struct dp_packet *b, *next; > + > + LIST_FOR_EACH_SAFE (b, next, list_node, list) { > + list_remove(&b->list_node); > + dp_packet_delete(b); > + } > +} > + > +static inline void > +dp_packet_adjust_layer_offset(uint16_t *offset, int increment) > { > - struct dp_packet *newp; > + if (*offset != UINT16_MAX) { > + *offset += increment; > + } > +} > > - newp = dp_packet_clone_from_ofpbuf(&p->ofpbuf); > - memcpy(&newp->md, &p->md, sizeof p->md); > +/* Adjust the size of the l2_5 portion of the dp_packet, updating the l2 > + * pointer and the layer offsets. The caller is responsible for > + * modifying the contents. */ > +void * > +dp_packet_resize_l2_5(struct dp_packet *b, int increment) > +{ > + if (increment >= 0) { > + dp_packet_push_uninit(b, increment); > + } else { > + dp_packet_pull(b, -increment); > + } > + > + b->frame = dp_packet_data(b); > + /* Adjust layer offsets after l2_5. */ > + dp_packet_adjust_layer_offset(&b->l3_ofs, increment); > + dp_packet_adjust_layer_offset(&b->l4_ofs, increment); > > - dp_packet_set_dp_hash(newp, dp_packet_get_dp_hash(p)); > + return b->frame; > +} > > - return newp; > +/* Adjust the size of the l2 portion of the dp_packet, updating the l2 > + * pointer and the layer offsets. The caller is responsible for > + * modifying the contents. */ > +void * > +dp_packet_resize_l2(struct dp_packet *b, int increment) > +{ > + dp_packet_resize_l2_5(b, increment); > + dp_packet_adjust_layer_offset(&b->l2_5_ofs, increment); > + return b->frame; > } > diff --git a/lib/dp-packet.h b/lib/dp-packet.h > index 74abdec..e23660d 100644 > --- a/lib/dp-packet.h > +++ b/lib/dp-packet.h > @@ -1,5 +1,5 @@ > /* > - * Copyright (c) 2014 Nicira, Inc. > + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. > * > * Licensed under the Apache License, Version 2.0 (the "License"); > * you may not use this file except in compliance with the License. > @@ -14,43 +14,451 @@ > * limitations under the License. > */ > > -#ifndef PACKET_DPIF_H > -#define PACKET_DPIF_H 1 > +#ifndef DPBUF_H > +#define DPBUF_H 1 > > -#include "ofpbuf.h" > +#include <stddef.h> > +#include <stdint.h> > +#include "list.h" > +#include "packets.h" > +#include "util.h" > +#include "netdev-dpdk.h" > > #ifdef __cplusplus > extern "C" { > #endif > > -/* A packet received from a netdev and passed to a dpif. */ > +enum OVS_PACKED_ENUM dp_packet_source { > + DPBUF_MALLOC, /* Obtained via malloc(). */ > + DPBUF_STACK, /* Un-movable stack space or static buffer. */ > + DPBUF_STUB, /* Starts on stack, may expand into heap. */ > + DPBUF_DPDK, /* buffer data is from DPDK allocated memory. > + ref to build_dp_packet() in netdev-dpdk. > */ > +}; > > +/* Buffer for holding arbitrary data. An dp_packet is automatically > reallocated > + * as necessary if it grows too large for the available memory. > + * > + * 'frame' and offset conventions: > + * > + * Network frames (aka "packets"): 'frame' MUST be set to the start of the > + * packet, layer offsets MAY be set as appropriate for the packet. > + * Additionally, we assume in many places that the 'frame' and 'data' are > + * the same for packets. > + * > + * OpenFlow messages: 'frame' points to the start of the OpenFlow > + * header, while 'l3_ofs' is the length of the OpenFlow header. > + * When parsing, the 'data' will move past these, as data is being > + * pulled from the OpenFlow message. > + * > + * Actions: When encoding OVS action lists, the 'frame' is used > + * as a pointer to the beginning of the current action (see ofpact_put()). > + * > + * rconn: Reuses 'frame' as a private pointer while queuing. > + */ > struct dp_packet { > - struct ofpbuf ofpbuf; /* Packet data. */ > -#ifndef DPDK_NETDEV > +#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. */ > uint32_t dp_hash; /* Packet hash. */ > #endif > + uint32_t allocated; /* Number of bytes allocated. */ > + > + void *frame; /* Packet frame start, or NULL. */ > + enum dp_packet_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. */ > struct pkt_metadata md; > + struct ovs_list list_node; /* Private list element for use by owner. */ > }; > > -struct dp_packet *dp_packet_new_with_headroom(size_t size, > - size_t headroom); > +static inline void * dp_packet_data(const struct dp_packet *); > +static inline void dp_packet_set_data(struct dp_packet *, void *); > +static inline void * dp_packet_base(const struct dp_packet *); > +static inline void dp_packet_set_base(struct dp_packet *, void *); > + > +static inline uint32_t dp_packet_size(const struct dp_packet *); > +static inline void dp_packet_set_size(struct dp_packet *, uint32_t); > + > +void * dp_packet_resize_l2(struct dp_packet *, int increment); > +void * dp_packet_resize_l2_5(struct dp_packet *, int increment); > +static inline void * dp_packet_l2(const struct dp_packet *); > +static inline void dp_packet_set_frame(struct dp_packet *, void *); > +static inline uint8_t dp_packet_l2_pad_size(const struct dp_packet *); > +static inline void dp_packet_set_l2_pad_size(struct dp_packet *, uint8_t); > +static inline void * dp_packet_l2_5(const struct dp_packet *); > +static inline void dp_packet_set_l2_5(struct dp_packet *, void *); > +static inline void * dp_packet_l3(const struct dp_packet *); > +static inline void dp_packet_set_l3(struct dp_packet *, void *); > +static inline void * dp_packet_l4(const struct dp_packet *); > +static inline void dp_packet_set_l4(struct dp_packet *, void *); > +static inline size_t dp_packet_l4_size(const struct dp_packet *); > +static inline const void *dp_packet_get_tcp_payload(const struct dp_packet > *); > +static inline const void *dp_packet_get_udp_payload(const struct dp_packet > *); > +static inline const void *dp_packet_get_sctp_payload(const struct dp_packet > *); > +static inline const void *dp_packet_get_icmp_payload(const struct dp_packet > *); > +static inline const void *dp_packet_get_nd_payload(const struct dp_packet *); > + > +void dp_packet_use(struct dp_packet *, void *, size_t); > +void dp_packet_use_stack(struct dp_packet *, void *, size_t); > +void dp_packet_use_stub(struct dp_packet *, void *, size_t); > +void dp_packet_use_const(struct dp_packet *, const void *, size_t); > + > +void dp_packet_init_dpdk(struct dp_packet *b, size_t allocated); > + > +void dp_packet_init(struct dp_packet *, size_t); > +void dp_packet_uninit(struct dp_packet *); > +static inline void *dp_packet_get_uninit_pointer(struct dp_packet *); > +void dp_packet_reinit(struct dp_packet *, size_t); > + > +struct dp_packet *dp_packet_new(size_t); > +struct dp_packet *dp_packet_new_with_headroom(size_t, size_t headroom); > +struct dp_packet *dp_packet_clone(const struct dp_packet *); > +struct dp_packet *dp_packet_clone_with_headroom(const struct dp_packet *, > + size_t headroom); > +struct dp_packet *dp_packet_clone_data(const void *, size_t); > +struct dp_packet *dp_packet_clone_data_with_headroom(const void *, size_t, > + size_t headroom); > +static inline void dp_packet_delete(struct dp_packet *); > + > +static inline void *dp_packet_at(const struct dp_packet *, size_t offset, > + size_t size); > +static inline void *dp_packet_at_assert(const struct dp_packet *, size_t > offset, > + size_t size); > +static inline void *dp_packet_tail(const struct dp_packet *); > +static inline void *dp_packet_end(const struct dp_packet *); > + > +void *dp_packet_put_uninit(struct dp_packet *, size_t); > +void *dp_packet_put_zeros(struct dp_packet *, size_t); > +void *dp_packet_put(struct dp_packet *, const void *, size_t); > +char *dp_packet_put_hex(struct dp_packet *, const char *s, size_t *n); > +void dp_packet_reserve(struct dp_packet *, size_t); > +void dp_packet_reserve_with_tailroom(struct dp_packet *b, size_t headroom, > + size_t tailroom); > +void *dp_packet_push_uninit(struct dp_packet *b, size_t); > +void *dp_packet_push_zeros(struct dp_packet *, size_t); > +void *dp_packet_push(struct dp_packet *b, const void *, size_t); > + > +static inline size_t dp_packet_headroom(const struct dp_packet *); > +static inline size_t dp_packet_tailroom(const struct dp_packet *); > +void dp_packet_prealloc_headroom(struct dp_packet *, size_t); > +void dp_packet_prealloc_tailroom(struct dp_packet *, size_t); > +void dp_packet_trim(struct dp_packet *); > +void dp_packet_padto(struct dp_packet *, size_t); > +void dp_packet_shift(struct dp_packet *, int); > > -struct dp_packet *dp_packet_clone_from_ofpbuf(const struct ofpbuf *b); > +static inline void dp_packet_clear(struct dp_packet *); > +static inline void *dp_packet_pull(struct dp_packet *, size_t); > +static inline void *dp_packet_try_pull(struct dp_packet *, size_t); > > -struct dp_packet *dp_packet_clone(struct dp_packet *p); > +void *dp_packet_steal_data(struct dp_packet *); > > -static inline void dp_packet_delete(struct dp_packet *p) > +char *dp_packet_to_string(const struct dp_packet *, size_t maxbytes); > +static inline struct dp_packet *dp_packet_from_list(const struct ovs_list *); > +void dp_packet_list_delete(struct ovs_list *); > +static inline bool dp_packet_equal(const struct dp_packet *, const struct > dp_packet *); > + > + > +/* Returns a pointer that may be passed to free() to accomplish the same > thing > + * as dp_packet_uninit(b). The return value is a null pointer if > dp_packet_uninit() > + * would not free any memory. */ > +static inline void *dp_packet_get_uninit_pointer(struct dp_packet *b) > +{ > + /* XXX: If 'source' is DPBUF_DPDK memory gets leaked! */ Is this comment still valid? > + return b && b->source == DPBUF_MALLOC ? dp_packet_base(b) : NULL; > +} > + (snip) > diff --git a/lib/flow.c b/lib/flow.c > index 81b36f9..af9883e 100644 > --- a/lib/flow.c > +++ b/lib/flow.c > @@ -32,7 +32,7 @@ > #include "hash.h" > #include "jhash.h" > #include "match.h" > -#include "ofpbuf.h" > +#include "dp-packet.h" > #include "openflow/openflow.h" > #include "packets.h" > #include "odp-util.h" > @@ -403,8 +403,7 @@ invalid: > * otherwise UINT16_MAX. > */ > void > -flow_extract(struct ofpbuf *packet, const struct pkt_metadata *md, > - struct flow *flow) > +flow_extract(struct dp_packet *packet, struct flow *flow) > { > struct { > struct miniflow mf; > @@ -414,18 +413,18 @@ flow_extract(struct ofpbuf *packet, const struct > pkt_metadata *md, > COVERAGE_INC(flow_extract); > > miniflow_initialize(&m.mf, m.buf); > - miniflow_extract(packet, md, &m.mf); > + miniflow_extract(packet, &m.mf); > miniflow_expand(&m.mf, flow); > } > > /* Caller is responsible for initializing 'dst' with enough storage for > * FLOW_U64S * 8 bytes. */ > void > -miniflow_extract(struct ofpbuf *packet, const struct pkt_metadata *md, > - struct miniflow *dst) > +miniflow_extract(struct dp_packet *packet, struct miniflow *dst) > { > - void *data = ofpbuf_data(packet); > - size_t size = ofpbuf_size(packet); > + const struct pkt_metadata *md = &packet->md; Later in the function we test if ‘md’ is non-null. Now it always is, so we should remove those tests. > + void *data = dp_packet_data(packet); > + size_t size = dp_packet_size(packet); > uint64_t *values = miniflow_values(dst); > struct mf_ctx mf = { 0, values, values + FLOW_U64S }; > char *l2; > @@ -452,7 +451,7 @@ miniflow_extract(struct ofpbuf *packet, const struct > pkt_metadata *md, > > /* Initialize packet's layer pointer and offsets. */ > l2 = data; > - ofpbuf_set_frame(packet, data); > + dp_packet_set_frame(packet, data); > > /* Must have full Ethernet header to proceed. */ > if (OVS_UNLIKELY(size < sizeof(struct eth_header))) { > @@ -508,7 +507,7 @@ miniflow_extract(struct ofpbuf *packet, const struct > pkt_metadata *md, > if (OVS_UNLIKELY(size - tot_len > UINT8_MAX)) { > goto out; > } > - ofpbuf_set_l2_pad_size(packet, size - tot_len); > + dp_packet_set_l2_pad_size(packet, size - tot_len); > size = tot_len; /* Never pull padding. */ > > /* Push both source and destination address at once. */ > @@ -544,7 +543,7 @@ miniflow_extract(struct ofpbuf *packet, const struct > pkt_metadata *md, > if (OVS_UNLIKELY(size - plen > UINT8_MAX)) { > goto out; > } > - ofpbuf_set_l2_pad_size(packet, size - plen); > + dp_packet_set_l2_pad_size(packet, size - plen); > size = plen; /* Never pull padding. */ > > miniflow_push_words(mf, ipv6_src, &nh->ip6_src, > @@ -1707,7 +1706,7 @@ flow_set_mpls_lse(struct flow *flow, int idx, ovs_be32 > lse) > } > (snip) > diff --git a/lib/learning-switch.c b/lib/learning-switch.c > index d03e52e..313b3f1 100644 > --- a/lib/learning-switch.c > +++ b/lib/learning-switch.c > @@ -36,6 +36,7 @@ > #include "ofp-print.h" > #include "ofp-util.h" > #include "openflow/openflow.h" > +#include "dp-packet.h” Should move up a bit. > #include "poll-loop.h" > #include "rconn.h" > #include "shash.h" > @@ -604,7 +605,7 @@ process_packet_in(struct lswitch *sw, const struct > ofp_header *oh) > struct ofputil_packet_out po; > enum ofperr error; > > - struct ofpbuf pkt; > + struct dp_packet pkt; > struct flow flow; > > error = ofputil_decode_packet_in(&pi, oh); > @@ -622,8 +623,8 @@ process_packet_in(struct lswitch *sw, const struct > ofp_header *oh) > } > > /* Extract flow data from 'opi' into 'flow'. */ > - ofpbuf_use_const(&pkt, pi.packet, pi.packet_len); > - flow_extract(&pkt, NULL, &flow); > + dp_packet_use_const(&pkt, pi.packet, pi.packet_len); > + flow_extract(&pkt, &flow); > flow.in_port.ofp_port = pi.fmd.in_port; > flow.tunnel.tun_id = pi.fmd.tun_id; > > @@ -648,8 +649,8 @@ process_packet_in(struct lswitch *sw, const struct > ofp_header *oh) > /* Prepare packet_out in case we need one. */ > po.buffer_id = pi.buffer_id; > if (po.buffer_id == UINT32_MAX) { > - po.packet = ofpbuf_data(&pkt); > - po.packet_len = ofpbuf_size(&pkt); > + po.packet = dp_packet_data(&pkt); > + po.packet_len = dp_packet_size(&pkt); > } else { > po.packet = NULL; > po.packet_len = 0; > diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c > index 36a2642..7dfff13 100644 > --- a/lib/netdev-bsd.c > +++ b/lib/netdev-bsd.c > @@ -52,7 +52,7 @@ > #include "dpif-netdev.h" > #include "dynamic-string.h" > #include "fatal-signal.h" > -#include "ofpbuf.h" > +#include “dp_packet.h" Ditto. > #include "openflow/openflow.h" > #include "ovs-thread.h" > #include "packets.h" > @@ -569,20 +569,20 @@ proc_pkt(u_char *args_, const struct pcap_pkthdr *hdr, > const u_char *packet) > * from rxq->pcap. > */ > static int > -netdev_rxq_bsd_recv_pcap(struct netdev_rxq_bsd *rxq, struct ofpbuf *buffer) > +netdev_rxq_bsd_recv_pcap(struct netdev_rxq_bsd *rxq, struct dp_packet > *buffer) > { > struct pcap_arg arg; > int ret; > > /* prepare the pcap argument to store the packet */ > - arg.size = ofpbuf_tailroom(buffer); > - arg.data = ofpbuf_data(buffer); > + arg.size = dp_packet_tailroom(buffer); > + arg.data = dp_packet_data(buffer); > > for (;;) { > ret = pcap_dispatch(rxq->pcap_handle, 1, proc_pkt, (u_char *) &arg); > > if (ret > 0) { > - ofpbuf_set_size(buffer, ofpbuf_size(buffer) + arg.retval); > + dp_packet_set_size(buffer, dp_packet_size(buffer) + arg.retval); > return 0; > } > if (ret == -1) { > @@ -601,14 +601,14 @@ netdev_rxq_bsd_recv_pcap(struct netdev_rxq_bsd *rxq, > struct ofpbuf *buffer) > * 'rxq->fd' is initialized with the tap file descriptor. > */ > static int > -netdev_rxq_bsd_recv_tap(struct netdev_rxq_bsd *rxq, struct ofpbuf *buffer) > +netdev_rxq_bsd_recv_tap(struct netdev_rxq_bsd *rxq, struct dp_packet *buffer) > { > - size_t size = ofpbuf_tailroom(buffer); > + size_t size = dp_packet_tailroom(buffer); > > for (;;) { > - ssize_t retval = read(rxq->fd, ofpbuf_data(buffer), size); > + ssize_t retval = read(rxq->fd, dp_packet_data(buffer), size); > if (retval >= 0) { > - ofpbuf_set_size(buffer, ofpbuf_size(buffer) + retval); > + dp_packet_set_size(buffer, dp_packet_size(buffer) + retval); > return 0; > } else if (errno != EINTR) { > if (errno != EAGAIN) { > @@ -627,7 +627,6 @@ netdev_bsd_rxq_recv(struct netdev_rxq *rxq_, struct > dp_packet **packets, > struct netdev_rxq_bsd *rxq = netdev_rxq_bsd_cast(rxq_); > struct netdev *netdev = rxq->up.netdev; > struct dp_packet *packet; > - struct ofpbuf *buffer; > ssize_t retval; > int mtu; > > @@ -637,16 +636,14 @@ netdev_bsd_rxq_recv(struct netdev_rxq *rxq_, struct > dp_packet **packets, > > packet = dp_packet_new_with_headroom(VLAN_ETH_HEADER_LEN + mtu, > DP_NETDEV_HEADROOM); > - buffer = &packet->ofpbuf; > - > retval = (rxq->pcap_handle > - ? netdev_rxq_bsd_recv_pcap(rxq, buffer) > - : netdev_rxq_bsd_recv_tap(rxq, buffer)); > + ? netdev_rxq_bsd_recv_pcap(rxq, packet) > + : netdev_rxq_bsd_recv_tap(rxq, packet)); > > if (retval) { > dp_packet_delete(packet); > } else { > - dp_packet_pad(buffer); > + dp_packet_pad(packet); > dp_packet_set_dp_hash(packet, 0); > packets[0] = packet; > *c = 1; > @@ -703,8 +700,8 @@ netdev_bsd_send(struct netdev *netdev_, int qid > OVS_UNUSED, > } > > for (i = 0; i < cnt; i++) { > - const void *data = ofpbuf_data(&pkts[i]->ofpbuf); > - size_t size = ofpbuf_size(&pkts[i]->ofpbuf); > + const void *data = dp_packet_data(pkts[i]); > + size_t size = dp_packet_size(pkts[i]); > > while (!error) { > ssize_t retval; > diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c > index 34dd706..2d56054 100644 > --- a/lib/netdev-dpdk.c > +++ b/lib/netdev-dpdk.c > @@ -36,7 +36,6 @@ > #include "netdev-vport.h" > #include "odp-util.h" > #include "ofp-print.h" > -#include "ofpbuf.h" > #include "ovs-numa.h" > #include "ovs-thread.h" > #include "ovs-rcu.h" > @@ -284,7 +283,7 @@ ovs_rte_pktmbuf_init(struct rte_mempool *mp, > > __rte_pktmbuf_init(mp, opaque_arg, _m, i); > > - ofpbuf_init_dpdk((struct ofpbuf *) m, m->buf_len); > + dp_packet_init_dpdk((struct dp_packet *) m, m->buf_len); > } > > static struct dpdk_mp * > @@ -807,7 +806,7 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct > dp_packet ** pkts, > } > > for (i = 0; i < cnt; i++) { > - int size = ofpbuf_size(&pkts[i]->ofpbuf); > + int size = dp_packet_size(pkts[i]); > > if (OVS_UNLIKELY(size > dev->max_packet_len)) { > VLOG_WARN_RL(&rl, "Too big size %d max_packet_len %d", > @@ -825,7 +824,7 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct > dp_packet ** pkts, > } > > /* We have to do a copy for now */ > - memcpy(mbufs[newcnt]->pkt.data, ofpbuf_data(&pkts[i]->ofpbuf), size); > + memcpy(mbufs[newcnt]->pkt.data, dp_packet_data(pkts[i]), size); > > rte_pktmbuf_data_len(mbufs[newcnt]) = size; > rte_pktmbuf_pkt_len(mbufs[newcnt]) = size; > @@ -854,7 +853,7 @@ netdev_dpdk_send__(struct netdev_dpdk *dev, int qid, > int i; > > if (OVS_UNLIKELY(!may_steal || > - pkts[0]->ofpbuf.source != OFPBUF_DPDK)) { > + pkts[0]->source != DPBUF_DPDK)) { > struct netdev *netdev = &dev->up; > > dpdk_do_tx_copy(netdev, qid, pkts, cnt); > @@ -869,7 +868,7 @@ netdev_dpdk_send__(struct netdev_dpdk *dev, int qid, > int dropped = 0; > > for (i = 0; i < cnt; i++) { > - int size = ofpbuf_size(&pkts[i]->ofpbuf); > + int size = dp_packet_size(pkts[i]); > if (OVS_UNLIKELY(size > dev->max_packet_len)) { > if (next_tx_idx != i) { > dpdk_queue_pkts(dev, qid, > diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c > index 5abac31..b7b50c3 100644 > --- a/lib/netdev-dummy.c > +++ b/lib/netdev-dummy.c > @@ -48,7 +48,7 @@ struct reconnect; > > struct dummy_packet_stream { > struct stream *stream; > - struct ofpbuf rxbuf; > + struct dp_packet rxbuf; > struct ovs_list txq; > }; > > @@ -126,7 +126,7 @@ struct netdev_rxq_dummy { > > static unixctl_cb_func netdev_dummy_set_admin_state; > static int netdev_dummy_construct(struct netdev *); > -static void netdev_dummy_queue_packet(struct netdev_dummy *, struct ofpbuf > *); > +static void netdev_dummy_queue_packet(struct netdev_dummy *, struct > dp_packet *); > > static void dummy_packet_stream_close(struct dummy_packet_stream *); > > @@ -155,7 +155,7 @@ dummy_packet_stream_init(struct dummy_packet_stream *s, > struct stream *stream) > { > int rxbuf_size = stream ? 2048 : 0; > s->stream = stream; > - ofpbuf_init(&s->rxbuf, rxbuf_size); > + dp_packet_init(&s->rxbuf, rxbuf_size); > list_init(&s->txq); > } > > @@ -184,10 +184,10 @@ static void > dummy_packet_stream_send(struct dummy_packet_stream *s, const void *buffer, > size_t size) > { > if (list_size(&s->txq) < NETDEV_DUMMY_MAX_QUEUE) { > - struct ofpbuf *b; > + struct dp_packet *b; > > - b = ofpbuf_clone_data_with_headroom(buffer, size, 2); > - put_unaligned_be16(ofpbuf_push_uninit(b, 2), htons(size)); > + b = dp_packet_clone_data_with_headroom(buffer, size, 2); > + put_unaligned_be16(dp_packet_push_uninit(b, 2), htons(size)); > list_push_back(&s->txq, &b->list_node); > } > } > @@ -201,17 +201,17 @@ dummy_packet_stream_run(struct netdev_dummy *dev, > struct dummy_packet_stream *s) > stream_run(s->stream); > > if (!list_is_empty(&s->txq)) { > - struct ofpbuf *txbuf; > + struct dp_packet *txbuf; > int retval; > > - txbuf = ofpbuf_from_list(list_front(&s->txq)); > - retval = stream_send(s->stream, ofpbuf_data(txbuf), > ofpbuf_size(txbuf)); > + txbuf = dp_packet_from_list(list_front(&s->txq)); > + retval = stream_send(s->stream, dp_packet_data(txbuf), > dp_packet_size(txbuf)); > > if (retval > 0) { > - ofpbuf_pull(txbuf, retval); > - if (!ofpbuf_size(txbuf)) { > + dp_packet_pull(txbuf, retval); > + if (!dp_packet_size(txbuf)) { > list_remove(&txbuf->list_node); > - ofpbuf_delete(txbuf); > + dp_packet_delete(txbuf); > } > } else if (retval != -EAGAIN) { > error = -retval; > @@ -219,37 +219,37 @@ dummy_packet_stream_run(struct netdev_dummy *dev, > struct dummy_packet_stream *s) > } > > if (!error) { > - if (ofpbuf_size(&s->rxbuf) < 2) { > - n = 2 - ofpbuf_size(&s->rxbuf); > + if (dp_packet_size(&s->rxbuf) < 2) { > + n = 2 - dp_packet_size(&s->rxbuf); > } else { > uint16_t frame_len; > > - frame_len = ntohs(get_unaligned_be16(ofpbuf_data(&s->rxbuf))); > + frame_len = ntohs(get_unaligned_be16(dp_packet_data(&s->rxbuf))); > if (frame_len < ETH_HEADER_LEN) { > error = EPROTO; > n = 0; > } else { > - n = (2 + frame_len) - ofpbuf_size(&s->rxbuf); > + n = (2 + frame_len) - dp_packet_size(&s->rxbuf); > } > } > } > if (!error) { > int retval; > > - ofpbuf_prealloc_tailroom(&s->rxbuf, n); > - retval = stream_recv(s->stream, ofpbuf_tail(&s->rxbuf), n); > + dp_packet_prealloc_tailroom(&s->rxbuf, n); > + retval = stream_recv(s->stream, dp_packet_tail(&s->rxbuf), n); > > if (retval > 0) { > - ofpbuf_set_size(&s->rxbuf, ofpbuf_size(&s->rxbuf) + retval); > - if (retval == n && ofpbuf_size(&s->rxbuf) > 2) { > - ofpbuf_pull(&s->rxbuf, 2); > + dp_packet_set_size(&s->rxbuf, dp_packet_size(&s->rxbuf) + > retval); > + if (retval == n && dp_packet_size(&s->rxbuf) > 2) { > + dp_packet_pull(&s->rxbuf, 2); > netdev_dummy_queue_packet(dev, > - ofpbuf_clone(&s->rxbuf)); > - ofpbuf_clear(&s->rxbuf); > + dp_packet_clone(&s->rxbuf)); > + dp_packet_clear(&s->rxbuf); > } > } else if (retval != -EAGAIN) { > error = (retval < 0 ? -retval > - : ofpbuf_size(&s->rxbuf) ? EPROTO > + : dp_packet_size(&s->rxbuf) ? EPROTO > : EOF); > } > } > @@ -261,8 +261,8 @@ static void > dummy_packet_stream_close(struct dummy_packet_stream *s) > { > stream_close(s->stream); > - ofpbuf_uninit(&s->rxbuf); > - ofpbuf_list_delete(&s->txq); > + dp_packet_uninit(&s->rxbuf); > + dp_packet_list_delete(&s->txq); > } > > static void > @@ -794,7 +794,7 @@ netdev_dummy_rxq_destruct(struct netdev_rxq *rxq_) > > ovs_mutex_lock(&netdev->mutex); > list_remove(&rx->node); > - ofpbuf_list_delete(&rx->recv_queue); > + dp_packet_list_delete(&rx->recv_queue); > ovs_mutex_unlock(&netdev->mutex); > seq_destroy(rx->seq); > } > @@ -813,11 +813,11 @@ netdev_dummy_rxq_recv(struct netdev_rxq *rxq_, struct > dp_packet **arr, > { > struct netdev_rxq_dummy *rx = netdev_rxq_dummy_cast(rxq_); > struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev); > - struct ofpbuf *packet; > + struct dp_packet *packet; > > ovs_mutex_lock(&netdev->mutex); > if (!list_is_empty(&rx->recv_queue)) { > - packet = ofpbuf_from_list(list_pop_front(&rx->recv_queue)); > + packet = dp_packet_from_list(list_pop_front(&rx->recv_queue)); > rx->recv_queue_len--; > } else { > packet = NULL; > @@ -829,15 +829,14 @@ netdev_dummy_rxq_recv(struct netdev_rxq *rxq_, struct > dp_packet **arr, > } > ovs_mutex_lock(&netdev->mutex); > netdev->stats.rx_packets++; > - netdev->stats.rx_bytes += ofpbuf_size(packet); > + netdev->stats.rx_bytes += dp_packet_size(packet); > ovs_mutex_unlock(&netdev->mutex); > > dp_packet_pad(packet); > + dp_packet_set_dp_hash(packet, 0); > > /* This performs a (sometimes unnecessary) copy */ This comment is no longer needed. > - arr[0] = dp_packet_clone_from_ofpbuf(packet); > - dp_packet_set_dp_hash(arr[0], 0); > - ofpbuf_delete(packet); > + arr[0] = packet; > *c = 1; > return 0; > } > @@ -865,7 +864,7 @@ netdev_dummy_rxq_drain(struct netdev_rxq *rxq_) > struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev); > > ovs_mutex_lock(&netdev->mutex); > - ofpbuf_list_delete(&rx->recv_queue); > + dp_packet_list_delete(&rx->recv_queue); > rx->recv_queue_len = 0; > ovs_mutex_unlock(&netdev->mutex); > > @@ -883,8 +882,8 @@ netdev_dummy_send(struct netdev *netdev, int qid > OVS_UNUSED, > int i; > > for (i = 0; i < cnt; i++) { > - const void *buffer = ofpbuf_data(&pkts[i]->ofpbuf); > - size_t size = ofpbuf_size(&pkts[i]->ofpbuf); > + const void *buffer = dp_packet_data(pkts[i]); > + size_t size = dp_packet_size(pkts[i]); > > if (size < ETH_HEADER_LEN) { > error = EMSGSIZE; > @@ -913,9 +912,9 @@ netdev_dummy_send(struct netdev *netdev, int qid > OVS_UNUSED, > dummy_packet_conn_send(&dev->conn, buffer, size); > > if (dev->tx_pcap) { > - struct ofpbuf packet; > + struct dp_packet packet; > > - ofpbuf_use_const(&packet, buffer, size); > + dp_packet_use_const(&packet, buffer, size); > ovs_pcap_write(dev->tx_pcap, &packet); > fflush(dev->tx_pcap); > } > @@ -1115,11 +1114,11 @@ static const struct netdev_class dummy_class = { > netdev_dummy_rxq_drain, > }; > > -static struct ofpbuf * > +static struct dp_packet * > eth_from_packet_or_flow(const char *s) > { > enum odp_key_fitness fitness; > - struct ofpbuf *packet; > + struct dp_packet *packet; > struct ofpbuf odp_key; > struct flow flow; > int error; > @@ -1142,13 +1141,14 @@ eth_from_packet_or_flow(const char *s) > } > > /* Convert odp_key to flow. */ > - fitness = odp_flow_key_to_flow(ofpbuf_data(&odp_key), > ofpbuf_size(&odp_key), &flow); > + fitness = odp_flow_key_to_flow(ofpbuf_data(&odp_key), > + ofpbuf_size(&odp_key), &flow); Why this change? > if (fitness == ODP_FIT_ERROR) { > ofpbuf_uninit(&odp_key); > return NULL; > } > > - packet = ofpbuf_new(0); > + packet = dp_packet_new(0); > flow_compose(packet, &flow); > > ofpbuf_uninit(&odp_key); > @@ -1156,7 +1156,7 @@ eth_from_packet_or_flow(const char *s) > } > (snip) > diff --git a/lib/pcap-file.c b/lib/pcap-file.c > index 58c60b1..a5935f8 100644 > --- a/lib/pcap-file.c > +++ b/lib/pcap-file.c > @@ -25,7 +25,7 @@ > #include "compiler.h" > #include "flow.h" > #include "hmap.h" > -#include "ofpbuf.h" > +#include "dp-packet.h” Move up. > #include "packets.h" > #include "timeval.h" > #include "unaligned.h" > @@ -133,10 +133,10 @@ ovs_pcap_write_header(FILE *file) > } > (snip) > --- a/ofproto/ofproto-dpif-monitor.c > +++ b/ofproto/ofproto-dpif-monitor.c > @@ -29,6 +29,7 @@ > #include "ofpbuf.h" > #include "ofproto-dpif.h" > #include "ovs-thread.h" > +#include "dp-packet.h” Move up. > #include "poll-loop.h" > #include "seq.h" > #include "timeval.h" > @@ -80,9 +81,9 @@ static struct latch monitor_exit_latch; > static struct ovs_mutex monitor_mutex = OVS_MUTEX_INITIALIZER; > > static void *monitor_main(void *); > -static void monitor_check_send_soon(struct ofpbuf *); > +static void monitor_check_send_soon(struct dp_packet *); > static void monitor_run(void); > -static void monitor_mport_run(struct mport *, struct ofpbuf *); > +static void monitor_mport_run(struct mport *, struct dp_packet *); > (snip) > diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h > index 9a03782..b1b30a3 100644 > --- a/ofproto/ofproto-dpif-xlate.h > +++ b/ofproto/ofproto-dpif-xlate.h > @@ -22,6 +22,7 @@ > #include "ofproto-dpif-mirror.h" > #include "ofproto-dpif.h" > #include "ofproto.h" > +#include "dp-packet.h” Move up. (snip) > diff --git a/tests/test-stp.c b/tests/test-stp.c > index 6250c54..0fca4db 100644 > --- a/tests/test-stp.c > +++ b/tests/test-stp.c > @@ -25,6 +25,7 @@ > #include <stdlib.h> > #include "ofpbuf.h" > #include "ovstest.h" > +#include "dp-packet.h” Move up. > #include "packets.h" > #include "openvswitch/vlog.h" > > @@ -85,7 +86,7 @@ new_test_case(void) > } > (snip) _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev