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

Reply via email to