Fixes namespace conflict for partner development.
#include <stdlib.h>
#include <string.h>
-#include "buffer.h"
#include "command-line.h"
#include "compiler.h"
#include "daemon.h"
#include "fault.h"
#include "learning-switch.h"
+#include "ofpbuf.h"
#include "openflow.h"
#include "poll-loop.h"
#include "rconn.h"
do_switching(struct switch_ *sw)
{
unsigned int packets_sent;
- struct buffer *msg;
+ struct ofpbuf *msg;
packets_sent = rconn_packets_sent(sw->rconn);
msg = rconn_recv(sw->rconn);
if (msg) {
lswitch_process_packet(sw->lswitch, sw->rconn, msg);
- buffer_delete(msg);
+ ofpbuf_delete(msg);
}
rconn_run(sw->rconn);
noinst_HEADERS = \
- buffer.h \
command-line.h \
compiler.h \
csum.h \
netdev.h \
netlink-protocol.h \
netlink.h \
+ ofpbuf.h \
ofp-print.h \
openflow.h \
openflow-netlink.h \
+++ /dev/null
-/* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
- * Junior University
- *
- * We are making the OpenFlow specification and associated documentation
- * (Software) available for public use and benefit with the expectation
- * that others will use, modify and enhance the Software and contribute
- * those enhancements back to the community. However, since we would
- * like to make the Software available for broadest use, with as few
- * restrictions as possible permission is hereby granted, free of
- * charge, to any person obtaining a copy of this Software to deal in
- * the Software under the copyrights without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The name and trademarks of copyright holder(s) may NOT be used in
- * advertising or publicity pertaining to the Software or any
- * derivatives without specific, written prior permission.
- */
-
-#ifndef BUFFER_H
-#define BUFFER_H 1
-
-#include <stddef.h>
-
-/* Buffer for holding arbitrary data. A buffer is automatically reallocated as
- * necessary if it grows too large for the available memory. */
-struct buffer {
- void *base; /* First byte of area malloc()'d area. */
- size_t allocated; /* Number of bytes allocated. */
-
- void *data; /* First byte actually in use. */
- size_t size; /* Number of bytes in use. */
-
- void *l2; /* Link-level header. */
- void *l3; /* Network-level header. */
- void *l4; /* Transport-level header. */
- void *l7; /* Application data. */
-
- struct buffer *next; /* Next in a list of buffers. */
- void *private; /* Private pointer for use by owner. */
-};
-
-void buffer_use(struct buffer *, void *, size_t);
-
-void buffer_init(struct buffer *, size_t);
-void buffer_uninit(struct buffer *);
-void buffer_reinit(struct buffer *, size_t);
-
-struct buffer *buffer_new(size_t);
-struct buffer *buffer_clone(const struct buffer *);
-void buffer_delete(struct buffer *);
-
-void *buffer_at(const struct buffer *, size_t offset, size_t size);
-void *buffer_at_assert(const struct buffer *, size_t offset, size_t size);
-void *buffer_tail(const struct buffer *);
-void *buffer_end(const struct buffer *);
-
-void *buffer_put_uninit(struct buffer *, size_t);
-void *buffer_put(struct buffer *, const void *, size_t);
-void buffer_reserve(struct buffer *, size_t);
-void *buffer_push_uninit(struct buffer *b, size_t);
-void *buffer_push(struct buffer *b, const void *, size_t);
-
-size_t buffer_headroom(struct buffer *);
-size_t buffer_tailroom(struct buffer *);
-void buffer_prealloc_headroom(struct buffer *, size_t);
-void buffer_prealloc_tailroom(struct buffer *, size_t);
-
-void buffer_clear(struct buffer *);
-void *buffer_pull(struct buffer *, size_t);
-void *buffer_try_pull(struct buffer *, size_t);
-
-#endif /* buffer.h */
#include "util.h"
struct ds;
-struct buffer;
+struct ofpbuf;
/* Values for 'op' field. */
#define DHCP_BOOTREQUEST 1 /* Message sent by DHCP client. */
size_t offset, uint16_t *);
const char *dhcp_msg_to_string(const struct dhcp_msg *, bool multiline,
struct ds *);
-int dhcp_parse(struct dhcp_msg *, const struct buffer *);
-void dhcp_assemble(const struct dhcp_msg *, struct buffer *);
+int dhcp_parse(struct dhcp_msg *, const struct ofpbuf *);
+void dhcp_assemble(const struct dhcp_msg *, struct ofpbuf *);
#endif /* dhcp.h */
#include <stdbool.h>
#include <stdint.h>
-struct buffer;
+struct ofpbuf;
struct ofp_match;
/* A datapath interface. Opaque. */
int dpif_open(int dp_idx, bool subscribe, struct dpif *);
void dpif_close(struct dpif *);
-int dpif_recv_openflow(struct dpif *, struct buffer **, bool wait);
-int dpif_send_openflow(struct dpif *, struct buffer *, bool wait);
+int dpif_recv_openflow(struct dpif *, struct ofpbuf **, bool wait);
+int dpif_send_openflow(struct dpif *, struct ofpbuf *, bool wait);
int dpif_add_dp(struct dpif *);
int dpif_del_dp(struct dpif *);
int dpif_add_port(struct dpif *, const char *netdev);
#include <stdint.h>
#include "util.h"
-struct buffer;
+struct ofpbuf;
/* Identification data for a flow.
All fields are in network byte order.
};
BUILD_ASSERT_DECL(sizeof (struct flow) == 32);
-int flow_extract(struct buffer *, uint16_t in_port, struct flow *);
+int flow_extract(struct ofpbuf *, uint16_t in_port, struct flow *);
void flow_print(FILE *, const struct flow *);
int flow_compare(const struct flow *, const struct flow *);
unsigned long int flow_hash(const struct flow *, uint32_t basis);
#include <stdbool.h>
-struct buffer;
+struct ofpbuf;
struct rconn;
struct lswitch *lswitch_create(struct rconn *, bool learn_macs, int max_idle);
void lswitch_destroy(struct lswitch *);
void lswitch_process_packet(struct lswitch *, struct rconn *,
- const struct buffer *);
+ const struct ofpbuf *);
#endif /* learning-switch.h */
#include <stdbool.h>
#include <stdint.h>
-struct buffer;
+struct ofpbuf;
struct in_addr;
struct in6_addr;
struct netdev;
int netdev_open(const char *name, int ethertype, struct netdev **);
void netdev_close(struct netdev *);
-int netdev_recv(struct netdev *, struct buffer *);
+int netdev_recv(struct netdev *, struct ofpbuf *);
void netdev_recv_wait(struct netdev *);
void netdev_drain(struct netdev *);
-int netdev_send(struct netdev *, const struct buffer *);
+int netdev_send(struct netdev *, const struct ofpbuf *);
const uint8_t *netdev_get_etheraddr(const struct netdev *);
const char *netdev_get_name(const struct netdev *);
int netdev_get_mtu(const struct netdev *);
#include <sys/uio.h>
#include <stdint.h>
-struct buffer;
+struct ofpbuf;
struct nl_sock;
struct nlattr;
struct nl_sock **);
void nl_sock_destroy(struct nl_sock *);
-int nl_sock_send(struct nl_sock *, const struct buffer *, bool wait);
+int nl_sock_send(struct nl_sock *, const struct ofpbuf *, bool wait);
int nl_sock_sendv(struct nl_sock *sock, const struct iovec iov[], size_t n_iov,
bool wait);
-int nl_sock_recv(struct nl_sock *, struct buffer **, bool wait);
-int nl_sock_transact(struct nl_sock *, const struct buffer *request,
- struct buffer **reply);
+int nl_sock_recv(struct nl_sock *, struct ofpbuf **, bool wait);
+int nl_sock_transact(struct nl_sock *, const struct ofpbuf *request,
+ struct ofpbuf **reply);
int nl_sock_fd(const struct nl_sock *);
\f
/* Netlink messages. */
/* Accessing headers and data. */
-struct nlmsghdr *nl_msg_nlmsghdr(const struct buffer *);
-struct genlmsghdr *nl_msg_genlmsghdr(const struct buffer *);
-bool nl_msg_nlmsgerr(const struct buffer *, int *error);
-void nl_msg_reserve(struct buffer *, size_t);
+struct nlmsghdr *nl_msg_nlmsghdr(const struct ofpbuf *);
+struct genlmsghdr *nl_msg_genlmsghdr(const struct ofpbuf *);
+bool nl_msg_nlmsgerr(const struct ofpbuf *, int *error);
+void nl_msg_reserve(struct ofpbuf *, size_t);
/* Appending headers and raw data. */
-void nl_msg_put_nlmsghdr(struct buffer *, struct nl_sock *,
+void nl_msg_put_nlmsghdr(struct ofpbuf *, struct nl_sock *,
size_t expected_payload,
uint32_t type, uint32_t flags);
-void nl_msg_put_genlmsghdr(struct buffer *, struct nl_sock *,
+void nl_msg_put_genlmsghdr(struct ofpbuf *, struct nl_sock *,
size_t expected_payload, int family, uint32_t flags,
uint8_t cmd, uint8_t version);
-void nl_msg_put(struct buffer *, const void *, size_t);
-void *nl_msg_put_uninit(struct buffer *, size_t);
+void nl_msg_put(struct ofpbuf *, const void *, size_t);
+void *nl_msg_put_uninit(struct ofpbuf *, size_t);
/* Appending attributes. */
-void *nl_msg_put_unspec_uninit(struct buffer *, uint16_t type, size_t);
-void nl_msg_put_unspec(struct buffer *, uint16_t type, const void *, size_t);
-void nl_msg_put_flag(struct buffer *, uint16_t type);
-void nl_msg_put_u8(struct buffer *, uint16_t type, uint8_t value);
-void nl_msg_put_u16(struct buffer *, uint16_t type, uint16_t value);
-void nl_msg_put_u32(struct buffer *, uint16_t type, uint32_t value);
-void nl_msg_put_u64(struct buffer *, uint16_t type, uint64_t value);
-void nl_msg_put_string(struct buffer *, uint16_t type, const char *value);
-void nl_msg_put_nested(struct buffer *, uint16_t type, struct buffer *);
+void *nl_msg_put_unspec_uninit(struct ofpbuf *, uint16_t type, size_t);
+void nl_msg_put_unspec(struct ofpbuf *, uint16_t type, const void *, size_t);
+void nl_msg_put_flag(struct ofpbuf *, uint16_t type);
+void nl_msg_put_u8(struct ofpbuf *, uint16_t type, uint8_t value);
+void nl_msg_put_u16(struct ofpbuf *, uint16_t type, uint16_t value);
+void nl_msg_put_u32(struct ofpbuf *, uint16_t type, uint32_t value);
+void nl_msg_put_u64(struct ofpbuf *, uint16_t type, uint64_t value);
+void nl_msg_put_string(struct ofpbuf *, uint16_t type, const char *value);
+void nl_msg_put_nested(struct ofpbuf *, uint16_t type, struct ofpbuf *);
\f
/* Netlink attribute types. */
enum nl_attr_type
bool optional;
};
-bool nl_policy_parse(const struct buffer *, const struct nl_policy[],
+bool nl_policy_parse(const struct ofpbuf *, const struct nl_policy[],
struct nlattr *[], size_t n_attrs);
\f
/* Miscellaneous. */
--- /dev/null
+/* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
+ * Junior University
+ *
+ * We are making the OpenFlow specification and associated documentation
+ * (Software) available for public use and benefit with the expectation
+ * that others will use, modify and enhance the Software and contribute
+ * those enhancements back to the community. However, since we would
+ * like to make the Software available for broadest use, with as few
+ * restrictions as possible permission is hereby granted, free of
+ * charge, to any person obtaining a copy of this Software to deal in
+ * the Software under the copyrights without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The name and trademarks of copyright holder(s) may NOT be used in
+ * advertising or publicity pertaining to the Software or any
+ * derivatives without specific, written prior permission.
+ */
+
+#ifndef OFPBUF_H
+#define OFPBUF_H 1
+
+#include <stddef.h>
+
+/* Buffer for holding arbitrary data. An ofpbuf is automatically reallocated
+ * as necessary if it grows too large for the available memory. */
+struct ofpbuf {
+ void *base; /* First byte of area malloc()'d area. */
+ size_t allocated; /* Number of bytes allocated. */
+
+ void *data; /* First byte actually in use. */
+ size_t size; /* Number of bytes in use. */
+
+ void *l2; /* Link-level header. */
+ void *l3; /* Network-level header. */
+ void *l4; /* Transport-level header. */
+ void *l7; /* Application data. */
+
+ struct ofpbuf *next; /* Next in a list of ofpbufs. */
+ void *private; /* Private pointer for use by owner. */
+};
+
+void ofpbuf_use(struct ofpbuf *, void *, size_t);
+
+void ofpbuf_init(struct ofpbuf *, size_t);
+void ofpbuf_uninit(struct ofpbuf *);
+void ofpbuf_reinit(struct ofpbuf *, size_t);
+
+struct ofpbuf *ofpbuf_new(size_t);
+struct ofpbuf *ofpbuf_clone(const struct ofpbuf *);
+void ofpbuf_delete(struct ofpbuf *);
+
+void *ofpbuf_at(const struct ofpbuf *, size_t offset, size_t size);
+void *ofpbuf_at_assert(const struct ofpbuf *, size_t offset, size_t size);
+void *ofpbuf_tail(const struct ofpbuf *);
+void *ofpbuf_end(const struct ofpbuf *);
+
+void *ofpbuf_put_uninit(struct ofpbuf *, size_t);
+void *ofpbuf_put(struct ofpbuf *, const void *, size_t);
+void ofpbuf_reserve(struct ofpbuf *, size_t);
+void *ofpbuf_push_uninit(struct ofpbuf *b, size_t);
+void *ofpbuf_push(struct ofpbuf *b, const void *, size_t);
+
+size_t ofpbuf_headroom(struct ofpbuf *);
+size_t ofpbuf_tailroom(struct ofpbuf *);
+void ofpbuf_prealloc_headroom(struct ofpbuf *, size_t);
+void ofpbuf_prealloc_tailroom(struct ofpbuf *, size_t);
+
+void ofpbuf_clear(struct ofpbuf *);
+void *ofpbuf_pull(struct ofpbuf *, size_t);
+void *ofpbuf_try_pull(struct ofpbuf *, size_t);
+
+#endif /* ofpbuf.h */
/* Packet queue. */
struct queue {
int n; /* Number of queued packets. */
- struct buffer *head; /* First queued packet, null if n == 0. */
- struct buffer *tail; /* Last queued packet, null if n == 0. */
+ struct ofpbuf *head; /* First queued packet, null if n == 0. */
+ struct ofpbuf *tail; /* Last queued packet, null if n == 0. */
};
void queue_init(struct queue *);
void queue_destroy(struct queue *);
void queue_clear(struct queue *);
-void queue_advance_head(struct queue *, struct buffer *next);
-void queue_push_tail(struct queue *, struct buffer *);
-struct buffer *queue_pop_head(struct queue *);
+void queue_advance_head(struct queue *, struct ofpbuf *next);
+void queue_push_tail(struct queue *, struct ofpbuf *);
+struct ofpbuf *queue_pop_head(struct queue *);
#endif /* queue.h */
void rconn_run(struct rconn *);
void rconn_run_wait(struct rconn *);
-struct buffer *rconn_recv(struct rconn *);
+struct ofpbuf *rconn_recv(struct rconn *);
void rconn_recv_wait(struct rconn *);
-int rconn_send(struct rconn *, struct buffer *, int *n_queued);
-int rconn_send_with_limit(struct rconn *, struct buffer *,
+int rconn_send(struct rconn *, struct ofpbuf *, int *n_queued);
+int rconn_send_with_limit(struct rconn *, struct ofpbuf *,
int *n_queued, int queue_limit);
unsigned int rconn_packets_sent(const struct rconn *);
unsigned int rconn_packets_received(const struct rconn *);
/* Tries to receive an OpenFlow message from 'vconn', which must be an
* active vconn. If successful, stores the received message into '*msgp'
* and returns 0. The caller is responsible for destroying the message
- * with buffer_delete(). On failure, returns a positive errno value and
+ * with ofpbuf_delete(). On failure, returns a positive errno value and
* stores a null pointer into '*msgp'.
*
* If the connection has been closed in the normal fashion, returns EOF.
*
* Nonnull iff this is an active vconn (one that transfers data and does
* not accept connections). */
- int (*recv)(struct vconn *vconn, struct buffer **msgp);
+ int (*recv)(struct vconn *vconn, struct ofpbuf **msgp);
/* Tries to queue 'msg' for transmission on 'vconn', which must be an
* active vconn. If successful, returns 0, in which case ownership of
*
* Nonnull iff this is an active vconn (one that transfers data and does
* not accept connections). */
- int (*send)(struct vconn *vconn, struct buffer *msg);
+ int (*send)(struct vconn *vconn, struct ofpbuf *msg);
void (*wait)(struct vconn *vconn, enum vconn_wait_type);
};
#include <stddef.h>
#include <stdint.h>
-struct buffer;
+struct ofpbuf;
struct flow;
struct pollfd;
struct ofp_header;
uint32_t vconn_get_ip(const struct vconn *);
int vconn_connect(struct vconn *);
int vconn_accept(struct vconn *, struct vconn **);
-int vconn_recv(struct vconn *, struct buffer **);
-int vconn_send(struct vconn *, struct buffer *);
-int vconn_transact(struct vconn *, struct buffer *, struct buffer **);
+int vconn_recv(struct vconn *, struct ofpbuf **);
+int vconn_send(struct vconn *, struct ofpbuf *);
+int vconn_transact(struct vconn *, struct ofpbuf *, struct ofpbuf **);
int vconn_open_block(const char *name, struct vconn **);
-int vconn_send_block(struct vconn *, struct buffer *);
-int vconn_recv_block(struct vconn *, struct buffer **);
+int vconn_send_block(struct vconn *, struct ofpbuf *);
+int vconn_recv_block(struct vconn *, struct ofpbuf **);
enum vconn_wait_type {
WAIT_CONNECT,
void vconn_recv_wait(struct vconn *);
void vconn_send_wait(struct vconn *);
-void *make_openflow(size_t openflow_len, uint8_t type, struct buffer **);
+void *make_openflow(size_t openflow_len, uint8_t type, struct ofpbuf **);
void *make_openflow_xid(size_t openflow_len, uint8_t type,
- uint32_t xid, struct buffer **);
-void update_openflow_length(struct buffer *);
-struct buffer *make_add_flow(const struct flow *, uint32_t buffer_id,
+ uint32_t xid, struct ofpbuf **);
+void update_openflow_length(struct ofpbuf *);
+struct ofpbuf *make_add_flow(const struct flow *, uint32_t buffer_id,
uint16_t max_idle, size_t n_actions);
-struct buffer *make_add_simple_flow(const struct flow *,
+struct ofpbuf *make_add_simple_flow(const struct flow *,
uint32_t buffer_id, uint16_t out_port,
uint16_t max_idle);
-struct buffer *make_buffered_packet_out(uint32_t buffer_id,
+struct ofpbuf *make_buffered_packet_out(uint32_t buffer_id,
uint16_t in_port, uint16_t out_port);
-struct buffer *make_unbuffered_packet_out(const struct buffer *packet,
+struct ofpbuf *make_unbuffered_packet_out(const struct ofpbuf *packet,
uint16_t in_port, uint16_t out_port);
-struct buffer *make_echo_request(void);
-struct buffer *make_echo_reply(const struct ofp_header *rq);
+struct ofpbuf *make_echo_request(void);
+struct ofpbuf *make_echo_reply(const struct ofp_header *rq);
extern struct vconn_class tcp_vconn_class;
extern struct vconn_class ptcp_vconn_class;
noinst_LIBRARIES = libopenflow.a
libopenflow_a_SOURCES = \
- buffer.c \
command-line.c \
csum.c \
daemon.c \
list.c \
mac-learning.c \
netdev.c \
+ ofpbuf.c \
ofp-print.c \
poll-loop.c \
queue.c \
+++ /dev/null
-/* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
- * Junior University
- *
- * We are making the OpenFlow specification and associated documentation
- * (Software) available for public use and benefit with the expectation
- * that others will use, modify and enhance the Software and contribute
- * those enhancements back to the community. However, since we would
- * like to make the Software available for broadest use, with as few
- * restrictions as possible permission is hereby granted, free of
- * charge, to any person obtaining a copy of this Software to deal in
- * the Software under the copyrights without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The name and trademarks of copyright holder(s) may NOT be used in
- * advertising or publicity pertaining to the Software or any
- * derivatives without specific, written prior permission.
- */
-
-#include <config.h>
-#include "buffer.h"
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include "util.h"
-
-/* Initializes 'b' as an empty buffer that contains the 'allocated' bytes of
- * memory starting at 'base'.
- *
- * 'base' should ordinarily be the first byte of a region obtained from
- * malloc(), but in circumstances where it can be guaranteed that 'b' will
- * never need to be expanded or freed, it can be a pointer into arbitrary
- * memory. */
-void
-buffer_use(struct buffer *b, void *base, size_t allocated)
-{
- b->base = b->data = base;
- b->allocated = allocated;
- b->size = 0;
- b->l2 = b->l3 = b->l4 = b->l7 = NULL;
- b->next = NULL;
- b->private = NULL;
-}
-
-/* Initializes 'b' as a buffer with an initial capacity of 'size' bytes. */
-void
-buffer_init(struct buffer *b, size_t size)
-{
- buffer_use(b, size ? xmalloc(size) : NULL, size);
-}
-
-/* Frees memory that 'b' points to. */
-void
-buffer_uninit(struct buffer *b)
-{
- if (b) {
- free(b->base);
- }
-}
-
-/* Frees memory that 'b' points to and allocates a new buffer */
-void
-buffer_reinit(struct buffer *b, size_t size)
-{
- buffer_uninit(b);
- buffer_init(b, size);
-}
-
-/* Creates and returns a new buffer with an initial capacity of 'size'
- * bytes. */
-struct buffer *
-buffer_new(size_t size)
-{
- struct buffer *b = xmalloc(sizeof *b);
- buffer_init(b, size);
- return b;
-}
-
-struct buffer *
-buffer_clone(const struct buffer *buffer)
-{
- /* FIXME: reference counting. */
- struct buffer *b = buffer_new(buffer->size);
- buffer_put(b, buffer->data, buffer->size);
- return b;
-}
-
-/* Frees memory that 'b' points to, as well as 'b' itself. */
-void
-buffer_delete(struct buffer *b)
-{
- if (b) {
- buffer_uninit(b);
- free(b);
- }
-}
-
-/* Returns the number of bytes of headroom in 'b', that is, the number of bytes
- * of unused space in buffer 'b' before the data that is in use. (Most
- * commonly, the data in a buffer is at its beginning, and thus the buffer's
- * headroom is 0.) */
-size_t
-buffer_headroom(struct buffer *b)
-{
- return b->data - b->base;
-}
-
-/* Returns the number of bytes that may be appended to the tail end of buffer
- * 'b' before the buffer must be reallocated. */
-size_t
-buffer_tailroom(struct buffer *b)
-{
- return buffer_end(b) - buffer_tail(b);
-}
-
-/* Ensures that 'b' has room for at least 'size' bytes at its tail end,
- * reallocating and copying its data if necessary. */
-void
-buffer_prealloc_tailroom(struct buffer *b, size_t size)
-{
- if (size > buffer_tailroom(b)) {
- size_t new_allocated = b->allocated + MAX(size, 64);
- void *new_base = xmalloc(new_allocated);
- uintptr_t base_delta = new_base - b->base;
- memcpy(new_base, b->base, b->allocated);
- free(b->base);
- b->base = new_base;
- b->allocated = new_allocated;
- b->data += base_delta;
- if (b->l2) {
- b->l2 += base_delta;
- }
- if (b->l3) {
- b->l3 += base_delta;
- }
- if (b->l4) {
- b->l4 += base_delta;
- }
- if (b->l7) {
- b->l7 += base_delta;
- }
- }
-}
-
-void
-buffer_prealloc_headroom(struct buffer *b, size_t size)
-{
- assert(size <= buffer_headroom(b));
-}
-
-/* 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 *
-buffer_put_uninit(struct buffer *b, size_t size)
-{
- void *p;
- buffer_prealloc_tailroom(b, size);
- p = buffer_tail(b);
- b->size += size;
- return p;
-}
-
-/* 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 buffer. */
-void *
-buffer_put(struct buffer *b, const void *p, size_t size)
-{
- void *dst = buffer_put_uninit(b, size);
- memcpy(dst, p, size);
- return dst;
-}
-
-/* Reserves 'size' bytes of headroom so that they can be later allocated with
- * buffer_push_uninit() without reallocating the buffer. */
-void
-buffer_reserve(struct buffer *b, size_t size)
-{
- assert(!b->size);
- buffer_prealloc_tailroom(b, size);
- b->data += size;
-}
-
-void *
-buffer_push_uninit(struct buffer *b, size_t size)
-{
- buffer_prealloc_headroom(b, size);
- b->data -= size;
- b->size += size;
- return b->data;
-}
-
-void *
-buffer_push(struct buffer *b, const void *p, size_t size)
-{
- void *dst = buffer_push_uninit(b, size);
- memcpy(dst, p, size);
- return dst;
-}
-
-/* If 'b' contains at least 'offset + size' bytes of data, returns a pointer to
- * byte 'offset'. Otherwise, returns a null pointer. */
-void *
-buffer_at(const struct buffer *b, size_t offset, size_t size)
-{
- return offset + size <= b->size ? (char *) b->data + offset : NULL;
-}
-
-/* Returns a pointer to byte 'offset' in 'b', which must contain at least
- * 'offset + size' bytes of data. */
-void *
-buffer_at_assert(const struct buffer *b, size_t offset, size_t size)
-{
- assert(offset + size <= b->size);
- return ((char *) b->data) + offset;
-}
-
-/* Returns the byte following the last byte of data in use in 'b'. */
-void *
-buffer_tail(const struct buffer *b)
-{
- return (char *) b->data + b->size;
-}
-
-/* Returns the byte following the last byte allocated for use (but not
- * necessarily in use) by 'b'. */
-void *
-buffer_end(const struct buffer *b)
-{
- return (char *) b->base + b->allocated;
-}
-
-/* Clears any data from 'b'. */
-void
-buffer_clear(struct buffer *b)
-{
- b->data = b->base;
- b->size = 0;
-}
-
-/* Removes 'size' bytes from the head end of 'b', which must contain at least
- * 'size' bytes of data. Returns the first byte of data removed. */
-void *
-buffer_pull(struct buffer *b, size_t size)
-{
- void *data = b->data;
- assert(b->size >= size);
- b->data += size;
- b->size -= size;
- return data;
-}
-
-/* If 'b' has at least 'size' bytes of data, removes that many bytes from the
- * head end of 'b' and returns the first byte removed. Otherwise, returns a
- * null pointer without modifying 'b'. */
-void *
-buffer_try_pull(struct buffer *b, size_t size)
-{
- return b->size >= size ? buffer_pull(b, size) : NULL;
-}
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
-#include "buffer.h"
#include "csum.h"
#include "dhcp.h"
#include "dynamic-string.h"
#include "flow.h"
#include "netdev.h"
+#include "ofpbuf.h"
#include "ofp-print.h"
#include "poll-loop.h"
#include "sat-math.h"
static bool
do_receive_msg(struct dhclient *cli, struct dhcp_msg *msg)
{
- struct buffer b;
+ struct ofpbuf b;
- buffer_init(&b, netdev_get_mtu(cli->netdev) + VLAN_ETH_HEADER_LEN);
+ ofpbuf_init(&b, netdev_get_mtu(cli->netdev) + VLAN_ETH_HEADER_LEN);
for (; cli->received < 50; cli->received++) {
const struct ip_header *ip;
const struct dhcp_header *dhcp;
struct flow flow;
int error;
- buffer_clear(&b);
+ ofpbuf_clear(&b);
error = netdev_recv(cli->netdev, &b);
if (error) {
goto drained;
continue;
}
- buffer_pull(&b, b.l7 - b.data);
+ ofpbuf_pull(&b, b.l7 - b.data);
error = dhcp_parse(msg, &b);
if (!error) {
VLOG_DBG_RL(&rl, "received %s",
dhcp_msg_to_string(msg, false, &cli->s));
- buffer_uninit(&b);
+ ofpbuf_uninit(&b);
return true;
}
}
netdev_drain(cli->netdev);
drained:
- buffer_uninit(&b);
+ ofpbuf_uninit(&b);
return false;
}
static void
do_send_msg(struct dhclient *cli, const struct dhcp_msg *msg)
{
- struct buffer b;
+ struct ofpbuf b;
struct eth_header eh;
struct ip_header nh;
struct udp_header th;
uint32_t udp_csum;
int error;
- buffer_init(&b, ETH_TOTAL_MAX);
- buffer_reserve(&b, ETH_HEADER_LEN + IP_HEADER_LEN + UDP_HEADER_LEN);
+ ofpbuf_init(&b, ETH_TOTAL_MAX);
+ ofpbuf_reserve(&b, ETH_HEADER_LEN + IP_HEADER_LEN + UDP_HEADER_LEN);
dhcp_assemble(msg, &b);
udp_csum = csum_continue(udp_csum, &th, sizeof th);
th.udp_csum = csum_finish(csum_continue(udp_csum, b.data, b.size));
- buffer_push(&b, &th, sizeof th);
- buffer_push(&b, &nh, sizeof nh);
- buffer_push(&b, &eh, sizeof eh);
+ ofpbuf_push(&b, &th, sizeof th);
+ ofpbuf_push(&b, &nh, sizeof nh);
+ ofpbuf_push(&b, &eh, sizeof eh);
/* Don't try to send the frame if it's too long for an Ethernet frame. We
* disregard the network device's actual MTU because we don't want the
VLOG_ERR("cannot send %zu-byte Ethernet frame", b.size);
}
- buffer_uninit(&b);
+ ofpbuf_uninit(&b);
}
static unsigned int
#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
-#include "buffer.h"
#include "dynamic-string.h"
+#include "ofpbuf.h"
#define THIS_MODULE VLM_dhcp
#include "vlog.h"
parse_options(struct dhcp_msg *msg, const char *name, void *data, size_t size,
int option_offset)
{
- struct buffer b;
+ struct ofpbuf b;
b.data = data;
b.size = size;
uint8_t *code, *len;
void *payload;
- code = buffer_try_pull(&b, 1);
+ code = ofpbuf_try_pull(&b, 1);
if (!code || *code == DHCP_CODE_END) {
break;
} else if (*code == DHCP_CODE_PAD) {
continue;
}
- len = buffer_try_pull(&b, 1);
+ len = ofpbuf_try_pull(&b, 1);
if (!len) {
VLOG_DBG_RL(&rl, "reached end of %s expecting length byte", name);
break;
}
- payload = buffer_try_pull(&b, *len);
+ payload = ofpbuf_try_pull(&b, *len);
if (!payload) {
VLOG_DBG_RL(&rl, "expected %"PRIu8" bytes of option-%"PRIu8" "
"payload with only %zu bytes of %s left",
* to the parsed message and returns 0. Otherwise, returns a positive errno
* value and '*msg' is indeterminate. */
int
-dhcp_parse(struct dhcp_msg *msg, const struct buffer *b_)
+dhcp_parse(struct dhcp_msg *msg, const struct ofpbuf *b_)
{
- struct buffer b = *b_;
+ struct ofpbuf b = *b_;
struct dhcp_header *dhcp;
uint32_t *cookie;
uint8_t type;
char *vendor_class;
- dhcp = buffer_try_pull(&b, sizeof *dhcp);
+ dhcp = ofpbuf_try_pull(&b, sizeof *dhcp);
if (!dhcp) {
VLOG_DBG_RL(&rl, "buffer too small for DHCP header (%zu bytes)",
b.size);
msg->giaddr = dhcp->giaddr;
memcpy(msg->chaddr, dhcp->chaddr, ETH_ADDR_LEN);
- cookie = buffer_try_pull(&b, sizeof cookie);
+ cookie = ofpbuf_try_pull(&b, sizeof cookie);
if (cookie) {
if (ntohl(*cookie) == DHCP_OPTS_COOKIE) {
uint8_t overload;
}
static void
-put_option_chunk(struct buffer *b, uint8_t code, void *data, size_t n)
+put_option_chunk(struct ofpbuf *b, uint8_t code, void *data, size_t n)
{
uint8_t header[2];
assert(n < 256);
header[0] = code;
header[1] = n;
- buffer_put(b, header, sizeof header);
- buffer_put(b, data, n);
+ ofpbuf_put(b, header, sizeof header);
+ ofpbuf_put(b, data, n);
}
static void
-put_option(struct buffer *b, uint8_t code, void *data, size_t n)
+put_option(struct ofpbuf *b, uint8_t code, void *data, size_t n)
{
if (data) {
if (n) {
/* Appends to 'b' the DHCP message represented by 'msg'. */
void
-dhcp_assemble(const struct dhcp_msg *msg, struct buffer *b)
+dhcp_assemble(const struct dhcp_msg *msg, struct ofpbuf *b)
{
const uint8_t end = DHCP_CODE_END;
uint32_t cookie = htonl(DHCP_OPTS_COOKIE);
- struct buffer vnd_data;
+ struct ofpbuf vnd_data;
struct dhcp_header dhcp;
int i;
dhcp.siaddr = msg->siaddr;
dhcp.giaddr = msg->giaddr;
memcpy(dhcp.chaddr, msg->chaddr, ETH_ADDR_LEN);
- buffer_put(b, &dhcp, sizeof dhcp);
- buffer_put(b, &cookie, sizeof cookie);
+ ofpbuf_put(b, &dhcp, sizeof dhcp);
+ ofpbuf_put(b, &cookie, sizeof cookie);
/* Put DHCP message type first. (The ordering is not required but it
* seems polite.) */
}
/* Assemble vendor specific option and put it. */
- buffer_init(&vnd_data, 0);
+ ofpbuf_init(&vnd_data, 0);
for (i = DHCP_VENDOR_OFS; i < DHCP_N_OPTIONS; i++) {
const struct dhcp_option *option = &msg->options[i];
put_option(&vnd_data, i - DHCP_VENDOR_OFS, option->data, option->n);
if (vnd_data.size) {
put_option(b, DHCP_CODE_VENDOR_SPECIFIC, vnd_data.data, vnd_data.size);
}
- buffer_uninit(&vnd_data);
+ ofpbuf_uninit(&vnd_data);
/* Put end-of-options option. */
- buffer_put(b, &end, sizeof end);
+ ofpbuf_put(b, &end, sizeof end);
}
#include <stdlib.h>
#include <string.h>
-#include "buffer.h"
#include "netlink.h"
#include "netlink-protocol.h"
+#include "ofpbuf.h"
#include "ofp-print.h"
#include "openflow-netlink.h"
#include "openflow.h"
/* Tries to receive an openflow message from the kernel on 'sock'. If
* successful, stores the received message into '*msgp' and returns 0. The
- * caller is responsible for destroying the message with buffer_delete(). On
+ * caller is responsible for destroying the message with ofpbuf_delete(). On
* failure, returns a positive errno value and stores a null pointer into
* '*msgp'.
*
* If 'wait' is true, dpif_recv_openflow waits for a message to be ready;
* otherwise, returns EAGAIN if the 'sock' receive buffer is empty. */
int
-dpif_recv_openflow(struct dpif *dp, struct buffer **bufferp,
+dpif_recv_openflow(struct dpif *dp, struct ofpbuf **bufferp,
bool wait)
{
struct nlattr *attrs[ARRAY_SIZE(openflow_policy)];
- struct buffer *buffer;
+ struct ofpbuf *buffer;
struct ofp_header *oh;
uint16_t ofp_len;
int retval;
buffer = *bufferp = NULL;
do {
- buffer_delete(buffer);
+ ofpbuf_delete(buffer);
retval = nl_sock_recv(dp->sock, &buffer, wait);
} while (retval == ENOBUFS
|| (!retval
return 0;
error:
- buffer_delete(buffer);
+ ofpbuf_delete(buffer);
return EPROTO;
}
* for details).
*/
int
-dpif_send_openflow(struct dpif *dp, struct buffer *buffer, bool wait)
+dpif_send_openflow(struct dpif *dp, struct ofpbuf *buffer, bool wait)
{
struct ofp_header *oh;
unsigned int dump_flag;
- struct buffer hdr;
+ struct ofpbuf hdr;
struct nlattr *nla;
uint32_t fixed_buffer[64 / 4];
struct iovec iov[3];
/* The reply to OFPT_STATS_REQUEST may be multiple segments long, so we
* need to specify NLM_F_DUMP in the request. */
- oh = buffer_at_assert(buffer, 0, sizeof *oh);
+ oh = ofpbuf_at_assert(buffer, 0, sizeof *oh);
dump_flag = oh->type == OFPT_STATS_REQUEST ? NLM_F_DUMP : 0;
- buffer_use(&hdr, fixed_buffer, sizeof fixed_buffer);
+ ofpbuf_use(&hdr, fixed_buffer, sizeof fixed_buffer);
nl_msg_put_genlmsghdr(&hdr, dp->sock, 32, openflow_family,
NLM_F_REQUEST | dump_flag, DP_GENL_C_OPENFLOW, 1);
nl_msg_put_u32(&hdr, DP_GENL_A_DP_IDX, dp->dp_idx);
- nla = buffer_put_uninit(&hdr, sizeof *nla);
+ nla = ofpbuf_put_uninit(&hdr, sizeof *nla);
nla->nla_len = sizeof *nla + buffer->size;
nla->nla_type = DP_GENL_A_OPENFLOW;
pad_bytes = NLA_ALIGN(nla->nla_len) - nla->nla_len;
lookup_openflow_multicast_group(int dp_idx, int *multicast_group)
{
struct nl_sock *sock;
- struct buffer request, *reply;
+ struct ofpbuf request, *reply;
struct nlattr *attrs[ARRAY_SIZE(openflow_multicast_policy)];
int retval;
if (retval) {
return retval;
}
- buffer_init(&request, 0);
+ ofpbuf_init(&request, 0);
nl_msg_put_genlmsghdr(&request, sock, 0, openflow_family, NLM_F_REQUEST,
DP_GENL_C_QUERY_DP, 1);
nl_msg_put_u32(&request, DP_GENL_A_DP_IDX, dp_idx);
retval = nl_sock_transact(sock, &request, &reply);
- buffer_uninit(&request);
+ ofpbuf_uninit(&request);
if (retval) {
nl_sock_destroy(sock);
return retval;
if (!nl_policy_parse(reply, openflow_multicast_policy, attrs,
ARRAY_SIZE(openflow_multicast_policy))) {
nl_sock_destroy(sock);
- buffer_delete(reply);
+ ofpbuf_delete(reply);
return EPROTO;
}
*multicast_group = nl_attr_get_u32(attrs[DP_GENL_A_MC_GROUP]);
nl_sock_destroy(sock);
- buffer_delete(reply);
+ ofpbuf_delete(reply);
return 0;
}
static int
send_mgmt_command(struct dpif *dp, int command, const char *netdev)
{
- struct buffer request, *reply;
+ struct ofpbuf request, *reply;
int retval;
- buffer_init(&request, 0);
+ ofpbuf_init(&request, 0);
nl_msg_put_genlmsghdr(&request, dp->sock, 32, openflow_family,
NLM_F_REQUEST | NLM_F_ACK, command, 1);
nl_msg_put_u32(&request, DP_GENL_A_DP_IDX, dp->dp_idx);
nl_msg_put_string(&request, DP_GENL_A_PORTNAME, netdev);
}
retval = nl_sock_transact(dp->sock, &request, &reply);
- buffer_uninit(&request);
- buffer_delete(reply);
+ ofpbuf_uninit(&request);
+ ofpbuf_delete(reply);
return retval;
}
#include <inttypes.h>
#include <netinet/in.h>
#include <string.h>
-#include "buffer.h"
#include "hash.h"
+#include "ofpbuf.h"
#include "openflow.h"
#include "packets.h"
#define THIS_MODULE VLM_flow
static struct ip_header *
-pull_ip(struct buffer *packet)
+pull_ip(struct ofpbuf *packet)
{
if (packet->size >= IP_HEADER_LEN) {
struct ip_header *ip = packet->data;
int ip_len = IP_IHL(ip->ip_ihl_ver) * 4;
if (ip_len >= IP_HEADER_LEN && packet->size >= ip_len) {
- return buffer_pull(packet, ip_len);
+ return ofpbuf_pull(packet, ip_len);
}
}
return NULL;
}
static struct tcp_header *
-pull_tcp(struct buffer *packet)
+pull_tcp(struct ofpbuf *packet)
{
if (packet->size >= TCP_HEADER_LEN) {
struct tcp_header *tcp = packet->data;
int tcp_len = TCP_OFFSET(tcp->tcp_ctl) * 4;
if (tcp_len >= TCP_HEADER_LEN && packet->size >= tcp_len) {
- return buffer_pull(packet, tcp_len);
+ return ofpbuf_pull(packet, tcp_len);
}
}
return NULL;
}
static struct udp_header *
-pull_udp(struct buffer *packet)
+pull_udp(struct ofpbuf *packet)
{
- return buffer_try_pull(packet, UDP_HEADER_LEN);
+ return ofpbuf_try_pull(packet, UDP_HEADER_LEN);
}
static struct eth_header *
-pull_eth(struct buffer *packet)
+pull_eth(struct ofpbuf *packet)
{
- return buffer_try_pull(packet, ETH_HEADER_LEN);
+ return ofpbuf_try_pull(packet, ETH_HEADER_LEN);
}
static struct vlan_header *
-pull_vlan(struct buffer *packet)
+pull_vlan(struct ofpbuf *packet)
{
- return buffer_try_pull(packet, VLAN_HEADER_LEN);
+ return ofpbuf_try_pull(packet, VLAN_HEADER_LEN);
}
/* Returns 1 if 'packet' is an IP fragment, 0 otherwise. */
int
-flow_extract(struct buffer *packet, uint16_t in_port, struct flow *flow)
+flow_extract(struct ofpbuf *packet, uint16_t in_port, struct flow *flow)
{
- struct buffer b = *packet;
+ struct ofpbuf b = *packet;
struct eth_header *eth;
int retval = 0;
flow->dl_type = eth->eth_type;
} else {
/* This is an 802.2 frame */
- struct llc_snap_header *h = buffer_at(&b, 0, sizeof *h);
+ struct llc_snap_header *h = ofpbuf_at(&b, 0, sizeof *h);
if (h == NULL) {
return 0;
}
&& !memcmp(h->snap.snap_org, SNAP_ORG_ETHERNET,
sizeof h->snap.snap_org)) {
flow->dl_type = h->snap.snap_type;
- buffer_pull(&b, sizeof *h);
+ ofpbuf_pull(&b, sizeof *h);
} else {
flow->dl_type = htons(OFP_DL_TYPE_NOT_ETH_TYPE);
- buffer_pull(&b, sizeof(struct llc_header));
+ ofpbuf_pull(&b, sizeof(struct llc_header));
}
}
#include <stdlib.h>
#include <time.h>
-#include "buffer.h"
#include "flow.h"
#include "mac-learning.h"
+#include "ofpbuf.h"
#include "ofp-print.h"
#include "openflow.h"
#include "queue.h"
* rate limit relatively high. */
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(30, 300);
-static void queue_tx(struct lswitch *, struct rconn *, struct buffer *);
+static void queue_tx(struct lswitch *, struct rconn *, struct ofpbuf *);
static void send_features_request(struct lswitch *, struct rconn *);
static void process_packet_in(struct lswitch *, struct rconn *,
struct ofp_packet_in *);
* 'rconn'. */
void
lswitch_process_packet(struct lswitch *sw, struct rconn *rconn,
- const struct buffer *msg)
+ const struct ofpbuf *msg)
{
static const size_t min_size[UINT8_MAX + 1] = {
[0 ... UINT8_MAX] = sizeof (struct ofp_header),
{
time_t now = time_now();
if (now >= sw->last_features_request + 1) {
- struct buffer *b;
+ struct ofpbuf *b;
struct ofp_header *ofr;
struct ofp_switch_config *osc;
/* Send OFPT_FEATURES_REQUEST. */
- b = buffer_new(0);
- ofr = buffer_put_uninit(b, sizeof *ofr);
+ b = ofpbuf_new(0);
+ ofr = ofpbuf_put_uninit(b, sizeof *ofr);
memset(ofr, 0, sizeof *ofr);
ofr->type = OFPT_FEATURES_REQUEST;
ofr->version = OFP_VERSION;
queue_tx(sw, rconn, b);
/* Send OFPT_SET_CONFIG. */
- b = buffer_new(0);
- osc = buffer_put_uninit(b, sizeof *osc);
+ b = ofpbuf_new(0);
+ osc = ofpbuf_put_uninit(b, sizeof *osc);
memset(osc, 0, sizeof *osc);
osc->header.type = OFPT_SET_CONFIG;
osc->header.version = OFP_VERSION;
}
static void
-queue_tx(struct lswitch *sw, struct rconn *rconn, struct buffer *b)
+queue_tx(struct lswitch *sw, struct rconn *rconn, struct ofpbuf *b)
{
int retval = rconn_send_with_limit(rconn, b, &sw->n_queued, 10);
if (retval && retval != ENOTCONN) {
uint16_t out_port = OFPP_FLOOD;
size_t pkt_ofs, pkt_len;
- struct buffer pkt;
+ struct ofpbuf pkt;
struct flow flow;
/* Extract flow data from 'opi' into 'flow'. */
} else {
/* We don't know that MAC, or we don't set up flows. Send along the
* packet without setting up a flow. */
- struct buffer *b;
+ struct ofpbuf *b;
if (ntohl(opi->buffer_id) == UINT32_MAX) {
b = make_unbuffered_packet_out(&pkt, in_port, out_port);
} else {
#include <string.h>
#include <unistd.h>
-#include "list.h"
#include "fatal-signal.h"
-#include "buffer.h"
+#include "list.h"
+#include "ofpbuf.h"
#include "openflow.h"
#include "packets.h"
#include "poll-loop.h"
/* Pads 'buffer' out with zero-bytes to the minimum valid length of an
* Ethernet packet, if necessary. */
static void
-pad_to_minimum_length(struct buffer *buffer)
+pad_to_minimum_length(struct ofpbuf *buffer)
{
if (buffer->size < ETH_TOTAL_MIN) {
size_t shortage = ETH_TOTAL_MIN - buffer->size;
- memset(buffer_put_uninit(buffer, shortage), 0, shortage);
+ memset(ofpbuf_put_uninit(buffer, shortage), 0, shortage);
}
}
* be returned.
*/
int
-netdev_recv(struct netdev *netdev, struct buffer *buffer)
+netdev_recv(struct netdev *netdev, struct ofpbuf *buffer)
{
ssize_t n_bytes;
assert(buffer->size == 0);
- assert(buffer_tailroom(buffer) >= ETH_TOTAL_MIN);
+ assert(ofpbuf_tailroom(buffer) >= ETH_TOTAL_MIN);
do {
n_bytes = recv(netdev->fd,
- buffer_tail(buffer), buffer_tailroom(buffer),
+ ofpbuf_tail(buffer), ofpbuf_tailroom(buffer),
MSG_DONTWAIT);
} while (n_bytes < 0 && errno == EINTR);
if (n_bytes < 0) {
* The kernel maintains a packet transmission queue, so the caller is not
* expected to do additional queuing of packets. */
int
-netdev_send(struct netdev *netdev, const struct buffer *buffer)
+netdev_send(struct netdev *netdev, const struct ofpbuf *buffer)
{
ssize_t n_bytes;
const struct eth_header *eh;
buffer->size, netdev->name);
return EMSGSIZE;
}
- eh = buffer_at_assert(buffer, 0, sizeof *eh);
+ eh = ofpbuf_at_assert(buffer, 0, sizeof *eh);
do {
n_bytes = sendto(netdev->fd, buffer->data, buffer->size, 0, NULL, 0);
#include <string.h>
#include <time.h>
#include <unistd.h>
-#include "buffer.h"
-#include "netlink-protocol.h"
#include "dynamic-string.h"
+#include "netlink-protocol.h"
+#include "ofpbuf.h"
#include "timeval.h"
#include "util.h"
* 'wait' is true, then the send will wait until buffer space is ready;
* otherwise, returns EAGAIN if the 'sock' send buffer is full. */
int
-nl_sock_send(struct nl_sock *sock, const struct buffer *msg, bool wait)
+nl_sock_send(struct nl_sock *sock, const struct ofpbuf *msg, bool wait)
{
int error;
/* Tries to receive a netlink message from the kernel on 'sock'. If
* successful, stores the received message into '*bufp' and returns 0. The
- * caller is responsible for destroying the message with buffer_delete(). On
+ * caller is responsible for destroying the message with ofpbuf_delete(). On
* failure, returns a positive errno value and stores a null pointer into
* '*bufp'.
*
* If 'wait' is true, nl_sock_recv waits for a message to be ready; otherwise,
* returns EAGAIN if the 'sock' receive buffer is empty. */
int
-nl_sock_recv(struct nl_sock *sock, struct buffer **bufp, bool wait)
+nl_sock_recv(struct nl_sock *sock, struct ofpbuf **bufp, bool wait)
{
uint8_t tmp;
ssize_t bufsize = 2048;
ssize_t nbytes, nbytes2;
- struct buffer *buf;
+ struct ofpbuf *buf;
struct nlmsghdr *nlmsghdr;
struct iovec iov;
struct msghdr msg = {
.msg_flags = 0
};
- buf = buffer_new(bufsize);
+ buf = ofpbuf_new(bufsize);
*bufp = NULL;
try_again:
* yet, so we take a guess at 2048. If we're wrong, we keep trying
* and doubling the buffer size each time.
*/
- nlmsghdr = buffer_put_uninit(buf, bufsize);
+ nlmsghdr = ofpbuf_put_uninit(buf, bufsize);
iov.iov_base = nlmsghdr;
iov.iov_len = bufsize;
do {
nbytes = recvmsg(sock->fd, &msg, (wait ? 0 : MSG_DONTWAIT) | MSG_PEEK);
} while (nbytes < 0 && errno == EINTR);
if (nbytes < 0) {
- buffer_delete(buf);
+ ofpbuf_delete(buf);
return errno;
}
if (msg.msg_flags & MSG_TRUNC) {
bufsize *= 2;
- buffer_reinit(buf, bufsize);
+ ofpbuf_reinit(buf, bufsize);
goto try_again;
}
buf->size = nbytes;
* was dropped. We have to pass this along to the caller in case
* it wants to retry a request. So kill the buffer, which we can
* re-read next time. */
- buffer_delete(buf);
+ ofpbuf_delete(buf);
return ENOBUFS;
} else {
VLOG_ERR_RL(&rl, "failed to remove nlmsg from socket: %s\n",
|| nlmsghdr->nlmsg_len > nbytes) {
VLOG_ERR_RL(&rl, "received invalid nlmsg (%zd bytes < %d)",
bufsize, NLMSG_HDRLEN);
- buffer_delete(buf);
+ ofpbuf_delete(buf);
return EPROTO;
}
*bufp = buf;
/* Sends 'request' to the kernel via 'sock' and waits for a response. If
* successful, stores the reply into '*replyp' and returns 0. The caller is
- * responsible for destroying the reply with buffer_delete(). On failure,
+ * responsible for destroying the reply with ofpbuf_delete(). On failure,
* returns a positive errno value and stores a null pointer into '*replyp'.
*
* Bare Netlink is an unreliable transport protocol. This function layers
*/
int
nl_sock_transact(struct nl_sock *sock,
- const struct buffer *request, struct buffer **replyp)
+ const struct ofpbuf *request, struct ofpbuf **replyp)
{
uint32_t seq = nl_msg_nlmsghdr(request)->nlmsg_seq;
struct nlmsghdr *nlmsghdr;
- struct buffer *reply;
+ struct ofpbuf *reply;
int retval;
*replyp = NULL;
if (seq != nlmsghdr->nlmsg_seq) {
VLOG_DBG_RL(&rl, "ignoring seq %"PRIu32" != expected %"PRIu32,
nl_msg_nlmsghdr(reply)->nlmsg_seq, seq);
- buffer_delete(reply);
+ ofpbuf_delete(reply);
goto recv;
}
if (nl_msg_nlmsgerr(reply, &retval)) {
*
* 'msg' must be at least as large as a nlmsghdr. */
struct nlmsghdr *
-nl_msg_nlmsghdr(const struct buffer *msg)
+nl_msg_nlmsghdr(const struct ofpbuf *msg)
{
- return buffer_at_assert(msg, 0, NLMSG_HDRLEN);
+ return ofpbuf_at_assert(msg, 0, NLMSG_HDRLEN);
}
/* Returns the genlmsghdr just past 'msg''s nlmsghdr.
* Returns a null pointer if 'msg' is not large enough to contain an nlmsghdr
* and a genlmsghdr. */
struct genlmsghdr *
-nl_msg_genlmsghdr(const struct buffer *msg)
+nl_msg_genlmsghdr(const struct ofpbuf *msg)
{
- return buffer_at(msg, NLMSG_HDRLEN, GENL_HDRLEN);
+ return ofpbuf_at(msg, NLMSG_HDRLEN, GENL_HDRLEN);
}
/* If 'buffer' is a NLMSG_ERROR message, stores 0 in '*errorp' if it is an ACK
*
* 'msg' must be at least as large as a nlmsghdr. */
bool
-nl_msg_nlmsgerr(const struct buffer *msg, int *errorp)
+nl_msg_nlmsgerr(const struct ofpbuf *msg, int *errorp)
{
if (nl_msg_nlmsghdr(msg)->nlmsg_type == NLMSG_ERROR) {
- struct nlmsgerr *err = buffer_at(msg, NLMSG_HDRLEN, sizeof *err);
+ struct nlmsgerr *err = ofpbuf_at(msg, NLMSG_HDRLEN, sizeof *err);
int code = EPROTO;
if (!err) {
VLOG_ERR_RL(&rl, "received invalid nlmsgerr (%zd bytes < %zd)",
/* Ensures that 'b' has room for at least 'size' bytes plus netlink padding at
* its tail end, reallocating and copying its data if necessary. */
void
-nl_msg_reserve(struct buffer *msg, size_t size)
+nl_msg_reserve(struct ofpbuf *msg, size_t size)
{
- buffer_prealloc_tailroom(msg, NLMSG_ALIGN(size));
+ ofpbuf_prealloc_tailroom(msg, NLMSG_ALIGN(size));
}
/* Puts a nlmsghdr at the beginning of 'msg', which must be initially empty.
* nl_msg_put_genlmsghdr is more convenient for composing a Generic Netlink
* message. */
void
-nl_msg_put_nlmsghdr(struct buffer *msg, struct nl_sock *sock,
+nl_msg_put_nlmsghdr(struct ofpbuf *msg, struct nl_sock *sock,
size_t expected_payload, uint32_t type, uint32_t flags)
{
struct nlmsghdr *nlmsghdr;
* nl_msg_put_nlmsghdr should be used to compose Netlink messages that are not
* Generic Netlink messages. */
void
-nl_msg_put_genlmsghdr(struct buffer *msg, struct nl_sock *sock,
+nl_msg_put_genlmsghdr(struct ofpbuf *msg, struct nl_sock *sock,
size_t expected_payload, int family, uint32_t flags,
uint8_t cmd, uint8_t version)
{
* the tail end of 'msg'. Data in 'msg' is reallocated and copied if
* necessary. */
void
-nl_msg_put(struct buffer *msg, const void *data, size_t size)
+nl_msg_put(struct ofpbuf *msg, const void *data, size_t size)
{
memcpy(nl_msg_put_uninit(msg, size), data, size);
}
* end of 'msg', reallocating and copying its data if necessary. Returns a
* pointer to the first byte of the new data, which is left uninitialized. */
void *
-nl_msg_put_uninit(struct buffer *msg, size_t size)
+nl_msg_put_uninit(struct ofpbuf *msg, size_t size)
{
size_t pad = NLMSG_ALIGN(size) - size;
- char *p = buffer_put_uninit(msg, size + pad);
+ char *p = ofpbuf_put_uninit(msg, size + pad);
if (pad) {
memset(p + size, 0, pad);
}
* 'msg', reallocating and copying its data if necessary. Returns a pointer to
* the first byte of data in the attribute, which is left uninitialized. */
void *
-nl_msg_put_unspec_uninit(struct buffer *msg, uint16_t type, size_t size)
+nl_msg_put_unspec_uninit(struct ofpbuf *msg, uint16_t type, size_t size)
{
size_t total_size = NLA_HDRLEN + size;
struct nlattr* nla = nl_msg_put_uninit(msg, total_size);
* its data if necessary. Returns a pointer to the first byte of data in the
* attribute, which is left uninitialized. */
void
-nl_msg_put_unspec(struct buffer *msg, uint16_t type,
+nl_msg_put_unspec(struct ofpbuf *msg, uint16_t type,
const void *data, size_t size)
{
memcpy(nl_msg_put_unspec_uninit(msg, type, size), data, size);
* (Some Netlink protocols use the presence or absence of an attribute as a
* Boolean flag.) */
void
-nl_msg_put_flag(struct buffer *msg, uint16_t type)
+nl_msg_put_flag(struct ofpbuf *msg, uint16_t type)
{
nl_msg_put_unspec(msg, type, NULL, 0);
}
/* Appends a Netlink attribute of the given 'type' and the given 8-bit 'value'
* to 'msg'. */
void
-nl_msg_put_u8(struct buffer *msg, uint16_t type, uint8_t value)
+nl_msg_put_u8(struct ofpbuf *msg, uint16_t type, uint8_t value)
{
nl_msg_put_unspec(msg, type, &value, sizeof value);
}
/* Appends a Netlink attribute of the given 'type' and the given 16-bit 'value'
* to 'msg'. */
void
-nl_msg_put_u16(struct buffer *msg, uint16_t type, uint16_t value)
+nl_msg_put_u16(struct ofpbuf *msg, uint16_t type, uint16_t value)
{
nl_msg_put_unspec(msg, type, &value, sizeof value);
}
/* Appends a Netlink attribute of the given 'type' and the given 32-bit 'value'
* to 'msg'. */
void
-nl_msg_put_u32(struct buffer *msg, uint16_t type, uint32_t value)
+nl_msg_put_u32(struct ofpbuf *msg, uint16_t type, uint32_t value)
{
nl_msg_put_unspec(msg, type, &value, sizeof value);
}
/* Appends a Netlink attribute of the given 'type' and the given 64-bit 'value'
* to 'msg'. */
void
-nl_msg_put_u64(struct buffer *msg, uint16_t type, uint64_t value)
+nl_msg_put_u64(struct ofpbuf *msg, uint16_t type, uint64_t value)
{
nl_msg_put_unspec(msg, type, &value, sizeof value);
}
/* Appends a Netlink attribute of the given 'type' and the given
* null-terminated string 'value' to 'msg'. */
void
-nl_msg_put_string(struct buffer *msg, uint16_t type, const char *value)
+nl_msg_put_string(struct ofpbuf *msg, uint16_t type, const char *value)
{
nl_msg_put_unspec(msg, type, value, strlen(value) + 1);
}
* netlink message in 'nested_msg' to 'msg'. The nlmsg_len field in
* 'nested_msg' is finalized to match 'nested_msg->size'. */
void
-nl_msg_put_nested(struct buffer *msg,
- uint16_t type, struct buffer *nested_msg)
+nl_msg_put_nested(struct ofpbuf *msg,
+ uint16_t type, struct ofpbuf *nested_msg)
{
nl_msg_nlmsghdr(nested_msg)->nlmsg_len = nested_msg->size;
nl_msg_put_unspec(msg, type, nested_msg->data, nested_msg->size);
* with nla_type == i is parsed; a pointer to attribute i is stored in
* attrs[i]. Returns true if successful, false on failure. */
bool
-nl_policy_parse(const struct buffer *msg, const struct nl_policy policy[],
+nl_policy_parse(const struct ofpbuf *msg, const struct nl_policy policy[],
struct nlattr *attrs[], size_t n_attrs)
{
void *p, *tail;
}
}
- p = buffer_at(msg, NLMSG_HDRLEN + GENL_HDRLEN, 0);
+ p = ofpbuf_at(msg, NLMSG_HDRLEN + GENL_HDRLEN, 0);
if (p == NULL) {
VLOG_DBG_RL(&rl, "missing headers in nl_policy_parse");
return false;
}
- tail = buffer_tail(msg);
+ tail = ofpbuf_tail(msg);
while (p < tail) {
size_t offset = p - msg->data;
static int do_lookup_genl_family(const char *name)
{
struct nl_sock *sock;
- struct buffer request, *reply;
+ struct ofpbuf request, *reply;
struct nlattr *attrs[ARRAY_SIZE(family_policy)];
int retval;
return -retval;
}
- buffer_init(&request, 0);
+ ofpbuf_init(&request, 0);
nl_msg_put_genlmsghdr(&request, sock, 0, GENL_ID_CTRL, NLM_F_REQUEST,
CTRL_CMD_GETFAMILY, 1);
nl_msg_put_string(&request, CTRL_ATTR_FAMILY_NAME, name);
retval = nl_sock_transact(sock, &request, &reply);
- buffer_uninit(&request);
+ ofpbuf_uninit(&request);
if (retval) {
nl_sock_destroy(sock);
return -retval;
if (!nl_policy_parse(reply, family_policy, attrs,
ARRAY_SIZE(family_policy))) {
nl_sock_destroy(sock);
- buffer_delete(reply);
+ ofpbuf_delete(reply);
return -EPROTO;
}
retval = -EPROTO;
}
nl_sock_destroy(sock);
- buffer_delete(reply);
+ ofpbuf_delete(reply);
return retval;
}
}
static char *
-nlmsg_to_string(const struct buffer *buffer)
+nlmsg_to_string(const struct ofpbuf *buffer)
{
struct ds ds = DS_EMPTY_INITIALIZER;
- const struct nlmsghdr *h = buffer_at(buffer, 0, NLMSG_HDRLEN);
+ const struct nlmsghdr *h = ofpbuf_at(buffer, 0, NLMSG_HDRLEN);
if (h) {
nlmsghdr_to_string(h, &ds);
if (h->nlmsg_type == NLMSG_ERROR) {
const struct nlmsgerr *e;
- e = buffer_at(buffer, NLMSG_HDRLEN,
+ e = ofpbuf_at(buffer, NLMSG_HDRLEN,
NLMSG_ALIGN(sizeof(struct nlmsgerr)));
if (e) {
ds_put_format(&ds, " error(%d", e->error);
ds_put_cstr(&ds, " error(truncated)");
}
} else if (h->nlmsg_type == NLMSG_DONE) {
- int *error = buffer_at(buffer, NLMSG_HDRLEN, sizeof *error);
+ int *error = ofpbuf_at(buffer, NLMSG_HDRLEN, sizeof *error);
if (error) {
ds_put_format(&ds, " done(%d", *error);
if (*error < 0) {
log_nlmsg(const char *function, int error,
const void *message, size_t size)
{
- struct buffer buffer;
+ struct ofpbuf buffer;
char *nlmsg;
if (!VLOG_IS_DBG_ENABLED()) {
#include <stdlib.h>
#include <ctype.h>
-#include "buffer.h"
#include "compiler.h"
#include "dynamic-string.h"
#include "flow.h"
-#include "util.h"
+#include "ofpbuf.h"
#include "openflow.h"
#include "packets.h"
+#include "util.h"
static void ofp_print_port_name(struct ds *string, uint16_t port);
static void ofp_print_match(struct ds *, const struct ofp_match *,
if (verbosity > 0) {
struct flow flow;
- struct buffer packet;
+ struct ofpbuf packet;
struct ofp_match match;
packet.data = (void *) op->data;
packet.size = data_len;
--- /dev/null
+/* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
+ * Junior University
+ *
+ * We are making the OpenFlow specification and associated documentation
+ * (Software) available for public use and benefit with the expectation
+ * that others will use, modify and enhance the Software and contribute
+ * those enhancements back to the community. However, since we would
+ * like to make the Software available for broadest use, with as few
+ * restrictions as possible permission is hereby granted, free of
+ * charge, to any person obtaining a copy of this Software to deal in
+ * the Software under the copyrights without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The name and trademarks of copyright holder(s) may NOT be used in
+ * advertising or publicity pertaining to the Software or any
+ * derivatives without specific, written prior permission.
+ */
+
+#include <config.h>
+#include "ofpbuf.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "util.h"
+
+/* Initializes 'b' as an empty ofpbuf that contains the 'allocated' bytes of
+ * memory starting at 'base'.
+ *
+ * 'base' should ordinarily be the first byte of a region obtained from
+ * malloc(), but in circumstances where it can be guaranteed that 'b' will
+ * never need to be expanded or freed, it can be a pointer into arbitrary
+ * memory. */
+void
+ofpbuf_use(struct ofpbuf *b, void *base, size_t allocated)
+{
+ b->base = b->data = base;
+ b->allocated = allocated;
+ b->size = 0;
+ b->l2 = b->l3 = b->l4 = b->l7 = NULL;
+ b->next = NULL;
+ b->private = NULL;
+}
+
+/* Initializes 'b' as an empty ofpbuf with an initial capacity of 'size'
+ * bytes. */
+void
+ofpbuf_init(struct ofpbuf *b, size_t size)
+{
+ ofpbuf_use(b, size ? xmalloc(size) : NULL, size);
+}
+
+/* Frees memory that 'b' points to. */
+void
+ofpbuf_uninit(struct ofpbuf *b)
+{
+ if (b) {
+ free(b->base);
+ }
+}
+
+/* Frees memory that 'b' points to and allocates a new ofpbuf */
+void
+ofpbuf_reinit(struct ofpbuf *b, size_t size)
+{
+ ofpbuf_uninit(b);
+ ofpbuf_init(b, size);
+}
+
+/* Creates and returns a new ofpbuf with an initial capacity of 'size'
+ * bytes. */
+struct ofpbuf *
+ofpbuf_new(size_t size)
+{
+ struct ofpbuf *b = xmalloc(sizeof *b);
+ ofpbuf_init(b, size);
+ return b;
+}
+
+struct ofpbuf *
+ofpbuf_clone(const struct ofpbuf *buffer)
+{
+ /* FIXME: reference counting. */
+ struct ofpbuf *b = ofpbuf_new(buffer->size);
+ ofpbuf_put(b, buffer->data, buffer->size);
+ return b;
+}
+
+/* Frees memory that 'b' points to, as well as 'b' itself. */
+void
+ofpbuf_delete(struct ofpbuf *b)
+{
+ if (b) {
+ ofpbuf_uninit(b);
+ free(b);
+ }
+}
+
+/* Returns the number of bytes of headroom in 'b', that is, the number of bytes
+ * of unused space in ofpbuf 'b' before the data that is in use. (Most
+ * commonly, the data in a ofpbuf is at its beginning, and thus the ofpbuf's
+ * headroom is 0.) */
+size_t
+ofpbuf_headroom(struct ofpbuf *b)
+{
+ return b->data - b->base;
+}
+
+/* Returns the number of bytes that may be appended to the tail end of ofpbuf
+ * 'b' before the ofpbuf must be reallocated. */
+size_t
+ofpbuf_tailroom(struct ofpbuf *b)
+{
+ return ofpbuf_end(b) - ofpbuf_tail(b);
+}
+
+/* Ensures that 'b' has room for at least 'size' bytes at its tail end,
+ * reallocating and copying its data if necessary. */
+void
+ofpbuf_prealloc_tailroom(struct ofpbuf *b, size_t size)
+{
+ if (size > ofpbuf_tailroom(b)) {
+ size_t new_allocated = b->allocated + MAX(size, 64);
+ void *new_base = xmalloc(new_allocated);
+ uintptr_t base_delta = new_base - b->base;
+ memcpy(new_base, b->base, b->allocated);
+ free(b->base);
+ b->base = new_base;
+ b->allocated = new_allocated;
+ b->data += base_delta;
+ if (b->l2) {
+ b->l2 += base_delta;
+ }
+ if (b->l3) {
+ b->l3 += base_delta;
+ }
+ if (b->l4) {
+ b->l4 += base_delta;
+ }
+ if (b->l7) {
+ b->l7 += base_delta;
+ }
+ }
+}
+
+void
+ofpbuf_prealloc_headroom(struct ofpbuf *b, size_t size)
+{
+ assert(size <= ofpbuf_headroom(b));
+}
+
+/* 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 *
+ofpbuf_put_uninit(struct ofpbuf *b, size_t size)
+{
+ void *p;
+ ofpbuf_prealloc_tailroom(b, size);
+ p = ofpbuf_tail(b);
+ b->size += size;
+ return p;
+}
+
+/* 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 ofpbuf. */
+void *
+ofpbuf_put(struct ofpbuf *b, const void *p, size_t size)
+{
+ void *dst = ofpbuf_put_uninit(b, size);
+ memcpy(dst, p, size);
+ return dst;
+}
+
+/* Reserves 'size' bytes of headroom so that they can be later allocated with
+ * ofpbuf_push_uninit() without reallocating the ofpbuf. */
+void
+ofpbuf_reserve(struct ofpbuf *b, size_t size)
+{
+ assert(!b->size);
+ ofpbuf_prealloc_tailroom(b, size);
+ b->data += size;
+}
+
+void *
+ofpbuf_push_uninit(struct ofpbuf *b, size_t size)
+{
+ ofpbuf_prealloc_headroom(b, size);
+ b->data -= size;
+ b->size += size;
+ return b->data;
+}
+
+void *
+ofpbuf_push(struct ofpbuf *b, const void *p, size_t size)
+{
+ void *dst = ofpbuf_push_uninit(b, size);
+ memcpy(dst, p, size);
+ return dst;
+}
+
+/* If 'b' contains at least 'offset + size' bytes of data, returns a pointer to
+ * byte 'offset'. Otherwise, returns a null pointer. */
+void *
+ofpbuf_at(const struct ofpbuf *b, size_t offset, size_t size)
+{
+ return offset + size <= b->size ? (char *) b->data + offset : NULL;
+}
+
+/* Returns a pointer to byte 'offset' in 'b', which must contain at least
+ * 'offset + size' bytes of data. */
+void *
+ofpbuf_at_assert(const struct ofpbuf *b, size_t offset, size_t size)
+{
+ assert(offset + size <= b->size);
+ return ((char *) b->data) + offset;
+}
+
+/* Returns the byte following the last byte of data in use in 'b'. */
+void *
+ofpbuf_tail(const struct ofpbuf *b)
+{
+ return (char *) b->data + b->size;
+}
+
+/* Returns the byte following the last byte allocated for use (but not
+ * necessarily in use) by 'b'. */
+void *
+ofpbuf_end(const struct ofpbuf *b)
+{
+ return (char *) b->base + b->allocated;
+}
+
+/* Clears any data from 'b'. */
+void
+ofpbuf_clear(struct ofpbuf *b)
+{
+ b->data = b->base;
+ b->size = 0;
+}
+
+/* Removes 'size' bytes from the head end of 'b', which must contain at least
+ * 'size' bytes of data. Returns the first byte of data removed. */
+void *
+ofpbuf_pull(struct ofpbuf *b, size_t size)
+{
+ void *data = b->data;
+ assert(b->size >= size);
+ b->data += size;
+ b->size -= size;
+ return data;
+}
+
+/* If 'b' has at least 'size' bytes of data, removes that many bytes from the
+ * head end of 'b' and returns the first byte removed. Otherwise, returns a
+ * null pointer without modifying 'b'. */
+void *
+ofpbuf_try_pull(struct ofpbuf *b, size_t size)
+{
+ return b->size >= size ? ofpbuf_pull(b, size) : NULL;
+}
#include <config.h>
#include "queue.h"
#include <assert.h>
-#include "buffer.h"
+#include "ofpbuf.h"
static void check_queue(struct queue *q);
void
queue_destroy(struct queue *q)
{
- struct buffer *cur, *next;
+ struct ofpbuf *cur, *next;
for (cur = q->head; cur != NULL; cur = next) {
next = cur->next;
- buffer_delete(cur);
+ ofpbuf_delete(cur);
}
}
* passed to a function for possible consumption (and destruction) and only
* dropped from the queue if that function actually accepts it. */
void
-queue_advance_head(struct queue *q, struct buffer *next)
+queue_advance_head(struct queue *q, struct ofpbuf *next)
{
assert(q->n);
assert(q->head);
/* Appends 'b' to the tail of 'q'. */
void
-queue_push_tail(struct queue *q, struct buffer *b)
+queue_push_tail(struct queue *q, struct ofpbuf *b)
{
check_queue(q);
}
/* Removes the first buffer from 'q', which must not be empty, and returns
- * it. The caller must free the buffer (with buffer_delete()) when it is no
+ * it. The caller must free the buffer (with ofpbuf_delete()) when it is no
* longer needed. */
-struct buffer *
+struct ofpbuf *
queue_pop_head(struct queue *q)
{
- struct buffer *head = q->head;
+ struct ofpbuf *head = q->head;
queue_advance_head(q, head->next);
return head;
}
check_queue(struct queue *q)
{
#if 0
- struct buffer *iter;
+ struct ofpbuf *iter;
size_t n;
assert(q->n == 0
#include <limits.h>
#include <stdlib.h>
#include <string.h>
-#include "buffer.h"
-#include "poll-loop.h"
#include "ofp-print.h"
+#include "ofpbuf.h"
+#include "poll-loop.h"
#include "sat-math.h"
#include "timeval.h"
#include "util.h"
/* Attempts to receive a packet from 'rc'. If successful, returns the packet;
* otherwise, returns a null pointer. The caller is responsible for freeing
- * the packet (with buffer_delete()). */
-struct buffer *
+ * the packet (with ofpbuf_delete()). */
+struct ofpbuf *
rconn_recv(struct rconn *rc)
{
if (rc->state & (S_ACTIVE | S_IDLE)) {
- struct buffer *buffer;
+ struct ofpbuf *buffer;
int error = vconn_recv(rc->vconn, &buffer);
if (!error) {
rc->last_received = time_now();
* takes care of sending if you call rconn_run(), which will have the side
* effect of waking up poll_block(). */
int
-rconn_send(struct rconn *rc, struct buffer *b, int *n_queued)
+rconn_send(struct rconn *rc, struct ofpbuf *b, int *n_queued)
{
if (rconn_is_connected(rc)) {
b->private = n_queued;
* takes care of sending if you call rconn_run(), which will have the side
* effect of waking up poll_block(). */
int
-rconn_send_with_limit(struct rconn *rc, struct buffer *b,
+rconn_send_with_limit(struct rconn *rc, struct ofpbuf *b,
int *n_queued, int queue_limit)
{
int retval;
retval = *n_queued >= queue_limit ? EAGAIN : rconn_send(rc, b, n_queued);
if (retval) {
- buffer_delete(b);
+ ofpbuf_delete(b);
}
return retval;
}
try_send(struct rconn *rc)
{
int retval = 0;
- struct buffer *next = rc->txq.head->next;
+ struct ofpbuf *next = rc->txq.head->next;
int *n_queued = rc->txq.head->private;
retval = vconn_send(rc->vconn, rc->txq.head);
if (retval) {
return;
}
while (rc->txq.n > 0) {
- struct buffer *b = queue_pop_head(&rc->txq);
+ struct ofpbuf *b = queue_pop_head(&rc->txq);
int *n_queued = b->private;
if (n_queued) {
--*n_queued;
}
- buffer_delete(b);
+ ofpbuf_delete(b);
}
poll_immediate_wake();
}
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include "openflow-netlink.h"
-#include "buffer.h"
#include "dpif.h"
#include "netlink.h"
+#include "ofpbuf.h"
+#include "openflow-netlink.h"
+#include "openflow.h"
#include "poll-loop.h"
#include "socket-util.h"
#include "util.h"
-#include "openflow.h"
#include "vconn-provider.h"
#include "vlog.h"
}
static int
-netlink_recv(struct vconn *vconn, struct buffer **bufferp)
+netlink_recv(struct vconn *vconn, struct ofpbuf **bufferp)
{
struct netlink_vconn *netlink = netlink_vconn_cast(vconn);
return dpif_recv_openflow(&netlink->dp, bufferp, false);
}
static int
-netlink_send(struct vconn *vconn, struct buffer *buffer)
+netlink_send(struct vconn *vconn, struct ofpbuf *buffer)
{
struct netlink_vconn *netlink = netlink_vconn_cast(vconn);
int retval = dpif_send_openflow(&netlink->dp, buffer, false);
if (!retval) {
- buffer_delete(buffer);
+ ofpbuf_delete(buffer);
}
return retval;
}
#include <openssl/ssl.h>
#include <poll.h>
#include <unistd.h>
-#include "buffer.h"
+#include "ofpbuf.h"
#include "socket-util.h"
#include "util.h"
#include "openflow.h"
enum session_type type;
int fd;
SSL *ssl;
- struct buffer *rxbuf;
- struct buffer *txbuf;
+ struct ofpbuf *rxbuf;
+ struct ofpbuf *txbuf;
struct poll_waiter *tx_waiter;
/* rx_want and tx_want record the result of the last call to SSL_read()
}
static int
-ssl_recv(struct vconn *vconn, struct buffer **bufferp)
+ssl_recv(struct vconn *vconn, struct ofpbuf **bufferp)
{
struct ssl_vconn *sslv = ssl_vconn_cast(vconn);
- struct buffer *rx;
+ struct ofpbuf *rx;
size_t want_bytes;
int old_state;
ssize_t ret;
if (sslv->rxbuf == NULL) {
- sslv->rxbuf = buffer_new(1564);
+ sslv->rxbuf = ofpbuf_new(1564);
}
rx = sslv->rxbuf;
return 0;
}
}
- buffer_prealloc_tailroom(rx, want_bytes);
+ ofpbuf_prealloc_tailroom(rx, want_bytes);
/* Behavior of zero-byte SSL_read is poorly defined. */
assert(want_bytes > 0);
old_state = SSL_get_state(sslv->ssl);
- ret = SSL_read(sslv->ssl, buffer_tail(rx), want_bytes);
+ ret = SSL_read(sslv->ssl, ofpbuf_tail(rx), want_bytes);
if (old_state != SSL_get_state(sslv->ssl)) {
sslv->tx_want = SSL_NOTHING;
if (sslv->tx_waiter) {
static void
ssl_clear_txbuf(struct ssl_vconn *sslv)
{
- buffer_delete(sslv->txbuf);
+ ofpbuf_delete(sslv->txbuf);
sslv->txbuf = NULL;
sslv->tx_waiter = NULL;
}
}
sslv->tx_want = SSL_NOTHING;
if (ret > 0) {
- buffer_pull(sslv->txbuf, ret);
+ ofpbuf_pull(sslv->txbuf, ret);
if (sslv->txbuf->size == 0) {
return 0;
}
}
static int
-ssl_send(struct vconn *vconn, struct buffer *buffer)
+ssl_send(struct vconn *vconn, struct ofpbuf *buffer)
{
struct ssl_vconn *sslv = ssl_vconn_cast(vconn);
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
-#include "buffer.h"
-#include "util.h"
+#include "ofpbuf.h"
#include "openflow.h"
#include "poll-loop.h"
#include "socket-util.h"
-#include "vconn.h"
+#include "util.h"
#include "vconn-provider.h"
+#include "vconn.h"
#include "vlog.h"
#define THIS_MODULE VLM_vconn_stream
{
struct vconn vconn;
int fd;
- struct buffer *rxbuf;
- struct buffer *txbuf;
+ struct ofpbuf *rxbuf;
+ struct ofpbuf *txbuf;
struct poll_waiter *tx_waiter;
};
}
static int
-stream_recv(struct vconn *vconn, struct buffer **bufferp)
+stream_recv(struct vconn *vconn, struct ofpbuf **bufferp)
{
struct stream_vconn *s = stream_vconn_cast(vconn);
- struct buffer *rx;
+ struct ofpbuf *rx;
size_t want_bytes;
ssize_t retval;
if (s->rxbuf == NULL) {
- s->rxbuf = buffer_new(1564);
+ s->rxbuf = ofpbuf_new(1564);
}
rx = s->rxbuf;
return 0;
}
}
- buffer_prealloc_tailroom(rx, want_bytes);
+ ofpbuf_prealloc_tailroom(rx, want_bytes);
- retval = read(s->fd, buffer_tail(rx), want_bytes);
+ retval = read(s->fd, ofpbuf_tail(rx), want_bytes);
if (retval > 0) {
rx->size += retval;
if (retval == want_bytes) {
static void
stream_clear_txbuf(struct stream_vconn *s)
{
- buffer_delete(s->txbuf);
+ ofpbuf_delete(s->txbuf);
s->txbuf = NULL;
s->tx_waiter = NULL;
}
return;
}
} else if (n > 0) {
- buffer_pull(s->txbuf, n);
+ ofpbuf_pull(s->txbuf, n);
if (!s->txbuf->size) {
stream_clear_txbuf(s);
return;
}
static int
-stream_send(struct vconn *vconn, struct buffer *buffer)
+stream_send(struct vconn *vconn, struct ofpbuf *buffer)
{
struct stream_vconn *s = stream_vconn_cast(vconn);
ssize_t retval;
retval = write(s->fd, buffer->data, buffer->size);
if (retval == buffer->size) {
- buffer_delete(buffer);
+ ofpbuf_delete(buffer);
return 0;
} else if (retval >= 0 || errno == EAGAIN) {
s->txbuf = buffer;
if (retval > 0) {
- buffer_pull(buffer, retval);
+ ofpbuf_pull(buffer, retval);
}
s->tx_waiter = poll_fd_callback(s->fd, POLLOUT, stream_do_tx, vconn);
return 0;
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include "buffer.h"
-#include "socket-util.h"
-#include "util.h"
-#include "openflow.h"
#include "ofp-print.h"
+#include "ofpbuf.h"
+#include "openflow.h"
#include "packets.h"
#include "poll-loop.h"
+#include "socket-util.h"
+#include "util.h"
#include "vconn-provider.h"
#include "vconn-stream.h"
#include <poll.h>
#include <stdlib.h>
#include <string.h>
-#include "buffer.h"
#include "flow.h"
#include "ofp-print.h"
+#include "ofpbuf.h"
#include "openflow.h"
#include "poll-loop.h"
#include "random.h"
/* Tries to receive an OpenFlow message from 'vconn', which must be an active
* vconn. If successful, stores the received message into '*msgp' and returns
* 0. The caller is responsible for destroying the message with
- * buffer_delete(). On failure, returns a positive errno value and stores a
+ * ofpbuf_delete(). On failure, returns a positive errno value and stores a
* null pointer into '*msgp'. On normal connection close, returns EOF.
*
* vconn_recv will not block waiting for a packet to arrive. If no packets
* have been received, it returns EAGAIN immediately. */
int
-vconn_recv(struct vconn *vconn, struct buffer **msgp)
+vconn_recv(struct vconn *vconn, struct ofpbuf **msgp)
{
int retval = vconn_connect(vconn);
if (!retval) {
free(s);
}
- oh = buffer_at_assert(*msgp, 0, sizeof *oh);
+ oh = ofpbuf_at_assert(*msgp, 0, sizeof *oh);
if (oh->version != OFP_VERSION) {
VLOG_ERR_RL(&rl, "%s: received OpenFlow version %02"PRIx8" "
"!= expected %02x",
vconn->name, oh->version, OFP_VERSION);
- buffer_delete(*msgp);
+ ofpbuf_delete(*msgp);
*msgp = NULL;
return EPROTO;
}
* vconn_send will not block. If 'msg' cannot be immediately accepted for
* transmission, it returns EAGAIN immediately. */
int
-vconn_send(struct vconn *vconn, struct buffer *msg)
+vconn_send(struct vconn *vconn, struct ofpbuf *msg)
{
int retval = vconn_connect(vconn);
if (!retval) {
/* Same as vconn_send, except that it waits until 'msg' can be transmitted. */
int
-vconn_send_block(struct vconn *vconn, struct buffer *msg)
+vconn_send_block(struct vconn *vconn, struct ofpbuf *msg)
{
int retval;
while ((retval = vconn_send(vconn, msg)) == EAGAIN) {
/* Same as vconn_recv, except that it waits until a message is received. */
int
-vconn_recv_block(struct vconn *vconn, struct buffer **msgp)
+vconn_recv_block(struct vconn *vconn, struct ofpbuf **msgp)
{
int retval;
while ((retval = vconn_recv(vconn, msgp)) == EAGAIN) {
*
* 'request' is always destroyed, regardless of the return value. */
int
-vconn_transact(struct vconn *vconn, struct buffer *request,
- struct buffer **replyp)
+vconn_transact(struct vconn *vconn, struct ofpbuf *request,
+ struct ofpbuf **replyp)
{
uint32_t send_xid = ((struct ofp_header *) request->data)->xid;
int error;
*replyp = NULL;
error = vconn_send_block(vconn, request);
if (error) {
- buffer_delete(request);
+ ofpbuf_delete(request);
return error;
}
for (;;) {
uint32_t recv_xid;
- struct buffer *reply;
+ struct ofpbuf *reply;
error = vconn_recv_block(vconn, &reply);
if (error) {
VLOG_DBG_RL(&rl, "%s: received reply with xid %08"PRIx32" != expected "
"%08"PRIx32, vconn->name, recv_xid, send_xid);
- buffer_delete(reply);
+ ofpbuf_delete(reply);
}
}
* id. Stores the new buffer in '*bufferp'. The caller must free the buffer
* when it is no longer needed. */
void *
-make_openflow(size_t openflow_len, uint8_t type, struct buffer **bufferp)
+make_openflow(size_t openflow_len, uint8_t type, struct ofpbuf **bufferp)
{
return make_openflow_xid(openflow_len, type, random_uint32(), bufferp);
}
* buffer when it is no longer needed. */
void *
make_openflow_xid(size_t openflow_len, uint8_t type, uint32_t xid,
- struct buffer **bufferp)
+ struct ofpbuf **bufferp)
{
- struct buffer *buffer;
+ struct ofpbuf *buffer;
struct ofp_header *oh;
assert(openflow_len >= sizeof *oh);
assert(openflow_len <= UINT16_MAX);
- buffer = *bufferp = buffer_new(openflow_len);
- oh = buffer_put_uninit(buffer, openflow_len);
+ buffer = *bufferp = ofpbuf_new(openflow_len);
+ oh = ofpbuf_put_uninit(buffer, openflow_len);
memset(oh, 0, openflow_len);
oh->version = OFP_VERSION;
oh->type = type;
/* Updates the 'length' field of the OpenFlow message in 'buffer' to
* 'buffer->size'. */
void
-update_openflow_length(struct buffer *buffer)
+update_openflow_length(struct ofpbuf *buffer)
{
- struct ofp_header *oh = buffer_at_assert(buffer, 0, sizeof *oh);
+ struct ofp_header *oh = ofpbuf_at_assert(buffer, 0, sizeof *oh);
oh->length = htons(buffer->size);
}
-struct buffer *
+struct ofpbuf *
make_add_flow(const struct flow *flow, uint32_t buffer_id,
uint16_t idle_timeout, size_t n_actions)
{
struct ofp_flow_mod *ofm;
size_t size = sizeof *ofm + n_actions * sizeof ofm->actions[0];
- struct buffer *out = buffer_new(size);
- ofm = buffer_put_uninit(out, size);
+ struct ofpbuf *out = ofpbuf_new(size);
+ ofm = ofpbuf_put_uninit(out, size);
memset(ofm, 0, size);
ofm->header.version = OFP_VERSION;
ofm->header.type = OFPT_FLOW_MOD;
return out;
}
-struct buffer *
+struct ofpbuf *
make_add_simple_flow(const struct flow *flow,
uint32_t buffer_id, uint16_t out_port,
uint16_t idle_timeout)
{
- struct buffer *buffer = make_add_flow(flow, buffer_id, idle_timeout, 1);
+ struct ofpbuf *buffer = make_add_flow(flow, buffer_id, idle_timeout, 1);
struct ofp_flow_mod *ofm = buffer->data;
ofm->actions[0].type = htons(OFPAT_OUTPUT);
ofm->actions[0].arg.output.max_len = htons(0);
return buffer;
}
-struct buffer *
-make_unbuffered_packet_out(const struct buffer *packet,
+struct ofpbuf *
+make_unbuffered_packet_out(const struct ofpbuf *packet,
uint16_t in_port, uint16_t out_port)
{
struct ofp_packet_out *opo;
size_t size = sizeof *opo + sizeof opo->actions[0];
- struct buffer *out = buffer_new(size + packet->size);
- opo = buffer_put_uninit(out, size);
+ struct ofpbuf *out = ofpbuf_new(size + packet->size);
+ opo = ofpbuf_put_uninit(out, size);
memset(opo, 0, sizeof *opo);
opo->header.version = OFP_VERSION;
opo->header.type = OFPT_PACKET_OUT;
opo->actions[0].type = htons(OFPAT_OUTPUT);
opo->actions[0].arg.output.max_len = htons(0);
opo->actions[0].arg.output.port = htons(out_port);
- buffer_put(out, packet->data, packet->size);
+ ofpbuf_put(out, packet->data, packet->size);
update_openflow_length(out);
return out;
}
-struct buffer *
+struct ofpbuf *
make_buffered_packet_out(uint32_t buffer_id,
uint16_t in_port, uint16_t out_port)
{
struct ofp_packet_out *opo;
size_t size = sizeof *opo + sizeof opo->actions[0];
- struct buffer *out = buffer_new(size);
- opo = buffer_put_uninit(out, size);
+ struct ofpbuf *out = ofpbuf_new(size);
+ opo = ofpbuf_put_uninit(out, size);
memset(opo, 0, size);
opo->header.version = OFP_VERSION;
opo->header.type = OFPT_PACKET_OUT;
}
/* Creates and returns an OFPT_ECHO_REQUEST message with an empty payload. */
-struct buffer *
+struct ofpbuf *
make_echo_request(void)
{
struct ofp_header *rq;
- struct buffer *out = buffer_new(sizeof *rq);
- rq = buffer_put_uninit(out, sizeof *rq);
+ struct ofpbuf *out = ofpbuf_new(sizeof *rq);
+ rq = ofpbuf_put_uninit(out, sizeof *rq);
rq->version = OFP_VERSION;
rq->type = OFPT_ECHO_REQUEST;
rq->length = htons(sizeof *rq);
/* Creates and returns an OFPT_ECHO_REPLY message matching the
* OFPT_ECHO_REQUEST message in 'rq'. */
-struct buffer *
+struct ofpbuf *
make_echo_reply(const struct ofp_header *rq)
{
size_t size = ntohs(rq->length);
- struct buffer *out = buffer_new(size);
- struct ofp_header *reply = buffer_put(out, rq, size);
+ struct ofpbuf *out = ofpbuf_new(size);
+ struct ofp_header *reply = ofpbuf_put(out, rq, size);
reply->type = OFPT_ECHO_REPLY;
return out;
}
#include <time.h>
#include <unistd.h>
-#include "buffer.h"
#include "command-line.h"
#include "compiler.h"
#include "daemon.h"
-#include "dhcp.h"
#include "dhcp-client.h"
+#include "dhcp.h"
#include "dynamic-string.h"
#include "fault.h"
#include "flow.h"
#include "list.h"
#include "mac-learning.h"
#include "netdev.h"
+#include "ofpbuf.h"
#include "openflow.h"
#include "packets.h"
#include "poll-loop.h"
struct half {
struct rconn *rconn;
- struct buffer *rxbuf;
+ struct ofpbuf *rxbuf;
int n_txq; /* No. of packets queued for tx on 'rconn'. */
};
const struct hook *h;
for (h = hooks; h < &hooks[n_hooks]; h++) {
if (h->packet_cb(r, i, h->aux)) {
- buffer_delete(this->rxbuf);
+ ofpbuf_delete(this->rxbuf);
this->rxbuf = NULL;
progress = true;
break;
if (!retval) {
progress = true;
} else {
- buffer_delete(this->rxbuf);
+ ofpbuf_delete(this->rxbuf);
}
this->rxbuf = NULL;
}
for (i = 0; i < 2; i++) {
struct half *this = &r->halves[i];
rconn_destroy(this->rconn);
- buffer_delete(this->rxbuf);
+ ofpbuf_delete(this->rxbuf);
}
free(r);
}
};
static void
-queue_tx(struct rconn *rc, struct in_band_data *in_band, struct buffer *b)
+queue_tx(struct rconn *rc, struct in_band_data *in_band, struct ofpbuf *b)
{
rconn_send_with_limit(rc, b, &in_band->n_queued, 10);
}
{
struct in_band_data *in_band = in_band_;
struct rconn *rc = r->halves[HALF_LOCAL].rconn;
- struct buffer *msg = r->halves[HALF_LOCAL].rxbuf;
+ struct ofpbuf *msg = r->halves[HALF_LOCAL].rxbuf;
struct ofp_packet_in *opi;
struct ofp_header *oh;
size_t pkt_ofs, pkt_len;
- struct buffer pkt;
+ struct ofpbuf pkt;
struct flow flow;
uint16_t in_port, out_port;
const uint8_t *controller_mac;
} else {
/* We don't know that MAC. Send along the packet without setting up a
* flow. */
- struct buffer *b;
+ struct ofpbuf *b;
if (ntohl(opi->buffer_id) == UINT32_MAX) {
b = make_unbuffered_packet_out(&pkt, in_port, out_port);
} else {
}
/* FIXME: do we want to pop the tail instead? */
- buffer_delete(queue_pop_head(longest));
+ ofpbuf_delete(queue_pop_head(longest));
rl->n_queued--;
}
/* Remove and return the next packet to transmit (in round-robin order). */
-static struct buffer *
+static struct ofpbuf *
dequeue_packet(struct rate_limiter *rl)
{
unsigned int i;
{
struct rate_limiter *rl = rl_;
const struct settings *s = rl->s;
- struct buffer *msg = r->halves[HALF_LOCAL].rxbuf;
+ struct ofpbuf *msg = r->halves[HALF_LOCAL].rxbuf;
struct ofp_header *oh;
if (half == HALF_REMOTE) {
if (rl->n_queued >= s->burst_limit) {
drop_packet(rl);
}
- queue_push_tail(&rl->queues[port], buffer_clone(msg));
+ queue_push_tail(&rl->queues[port], ofpbuf_clone(msg));
rl->n_queued++;
rl->n_limited++;
return true;
* because the TCP connection is responsible for buffering and there is
* no point in trying to transmit faster than the TCP connection can
* handle. */
- struct buffer *b = dequeue_packet(rl);
+ struct ofpbuf *b = dequeue_packet(rl);
if (rconn_send_with_limit(rl->remote_rconn, b, &rl->n_txq, 10)) {
rl->n_tx_dropped++;
}
{
struct switch_status *ss = ss_;
struct rconn *rc = r->halves[HALF_REMOTE].rconn;
- struct buffer *msg = r->halves[HALF_REMOTE].rxbuf;
+ struct ofpbuf *msg = r->halves[HALF_REMOTE].rxbuf;
struct switch_status_category *c;
struct ofp_stats_request *osr;
struct ofp_stats_reply *reply;
struct status_reply sr;
struct ofp_header *oh;
- struct buffer *b;
+ struct ofpbuf *b;
int retval;
if (half == HALF_LOCAL) {
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
-#include "buffer.h"
#include "chain.h"
#include "csum.h"
#include "flow.h"
+#include "list.h"
#include "netdev.h"
+#include "ofpbuf.h"
+#include "openflow.h"
#include "packets.h"
#include "poll-loop.h"
#include "rconn.h"
-#include "vconn.h"
+#include "switch-flow.h"
#include "table.h"
#include "timeval.h"
+#include "vconn.h"
#include "xtoxll.h"
#define THIS_MODULE VLM_datapath
static void remote_wait(struct remote *);
static void remote_destroy(struct remote *);
-void dp_output_port(struct datapath *, struct buffer *,
+void dp_output_port(struct datapath *, struct ofpbuf *,
int in_port, int out_port);
void dp_update_port_flags(struct datapath *dp, const struct ofp_port_mod *opm);
-void dp_output_control(struct datapath *, struct buffer *, int in_port,
+void dp_output_control(struct datapath *, struct ofpbuf *, int in_port,
size_t max_len, int reason);
static void send_flow_expired(struct datapath *, struct sw_flow *,
enum ofp_flow_expired_reason);
static int update_port_status(struct sw_port *p);
static void send_port_status(struct sw_port *p, uint8_t status);
static void del_switch_port(struct sw_port *p);
-static void execute_actions(struct datapath *, struct buffer *,
+static void execute_actions(struct datapath *, struct ofpbuf *,
int in_port, const struct sw_flow_key *,
const struct ofp_action *, int n_actions);
-static void modify_vlan(struct buffer *buffer, const struct sw_flow_key *key,
+static void modify_vlan(struct ofpbuf *buffer, const struct sw_flow_key *key,
const struct ofp_action *a);
-static void modify_nh(struct buffer *buffer, uint16_t eth_proto,
+static void modify_nh(struct ofpbuf *buffer, uint16_t eth_proto,
uint8_t nw_proto, const struct ofp_action *a);
-static void modify_th(struct buffer *buffer, uint16_t eth_proto,
+static void modify_th(struct ofpbuf *buffer, uint16_t eth_proto,
uint8_t nw_proto, const struct ofp_action *a);
/* Buffers are identified to userspace by a 31-bit opaque ID. We divide the ID
#define PKT_COOKIE_BITS (32 - PKT_BUFFER_BITS)
-int run_flow_through_tables(struct datapath *, struct buffer *, int in_port);
-void fwd_port_input(struct datapath *, struct buffer *, int in_port);
+int run_flow_through_tables(struct datapath *, struct ofpbuf *, int in_port);
+void fwd_port_input(struct datapath *, struct ofpbuf *, int in_port);
int fwd_control_input(struct datapath *, const struct sender *,
const void *, size_t);
-uint32_t save_buffer(struct buffer *);
-static struct buffer *retrieve_buffer(uint32_t id);
+uint32_t save_buffer(struct ofpbuf *);
+static struct ofpbuf *retrieve_buffer(uint32_t id);
static void discard_buffer(uint32_t id);
static int port_no(struct datapath *dp, struct sw_port *p)
time_t now = time_now();
struct sw_port *p, *pn;
struct remote *r, *rn;
- struct buffer *buffer = NULL;
+ struct ofpbuf *buffer = NULL;
if (now != dp->last_timeout) {
struct list deleted = LIST_INITIALIZER(&deleted);
const int headroom = 128 + 2;
const int hard_header = VLAN_ETH_HEADER_LEN;
const int mtu = netdev_get_mtu(p->netdev);
- buffer = buffer_new(headroom + hard_header + mtu);
+ buffer = ofpbuf_new(headroom + hard_header + mtu);
buffer->data += headroom;
}
error = netdev_recv(p->netdev, buffer);
netdev_get_name(p->netdev), strerror(error));
}
}
- buffer_delete(buffer);
+ ofpbuf_delete(buffer);
/* Talk to remotes. */
LIST_FOR_EACH_SAFE (r, rn, struct remote, node, &dp->remotes) {
* other processing doesn't starve. */
for (i = 0; i < 50; i++) {
if (!r->cb_dump) {
- struct buffer *buffer;
+ struct ofpbuf *buffer;
struct ofp_header *oh;
buffer = rconn_recv(r->rconn);
} else {
VLOG_WARN_RL(&rl, "received too-short OpenFlow message");
}
- buffer_delete(buffer);
+ ofpbuf_delete(buffer);
} else {
if (r->n_txq < TXQ_LIMIT) {
int error = r->cb_dump(dp, r->cb_aux);
* "flood" argument is set, don't send out ports with flooding disabled.
*/
static int
-output_all(struct datapath *dp, struct buffer *buffer, int in_port, int flood)
+output_all(struct datapath *dp, struct ofpbuf *buffer, int in_port, int flood)
{
struct sw_port *p;
int prev_port;
continue;
}
if (prev_port != -1) {
- dp_output_port(dp, buffer_clone(buffer), in_port, prev_port);
+ dp_output_port(dp, ofpbuf_clone(buffer), in_port, prev_port);
}
prev_port = port_no(dp, p);
}
if (prev_port != -1)
dp_output_port(dp, buffer, in_port, prev_port);
else
- buffer_delete(buffer);
+ ofpbuf_delete(buffer);
return 0;
}
void
-output_packet(struct datapath *dp, struct buffer *buffer, int out_port)
+output_packet(struct datapath *dp, struct ofpbuf *buffer, int out_port)
{
if (out_port >= 0 && out_port < OFPP_MAX) {
struct sw_port *p = &dp->ports[out_port];
}
}
- buffer_delete(buffer);
+ ofpbuf_delete(buffer);
VLOG_DBG_RL(&rl, "can't forward to bad port %d\n", out_port);
}
/* Takes ownership of 'buffer' and transmits it to 'out_port' on 'dp'.
*/
void
-dp_output_port(struct datapath *dp, struct buffer *buffer,
+dp_output_port(struct datapath *dp, struct ofpbuf *buffer,
int in_port, int out_port)
{
output_packet(dp, buffer, in_port);
} else if (out_port == OFPP_TABLE) {
if (run_flow_through_tables(dp, buffer, in_port)) {
- buffer_delete(buffer);
+ ofpbuf_delete(buffer);
}
} else {
if (in_port == out_port) {
static void *
make_openflow_reply(size_t openflow_len, uint8_t type,
- const struct sender *sender, struct buffer **bufferp)
+ const struct sender *sender, struct ofpbuf **bufferp)
{
return make_openflow_xid(openflow_len, type, sender ? sender->xid : 0,
bufferp);
}
static int
-send_openflow_buffer(struct datapath *dp, struct buffer *buffer,
+send_openflow_buffer(struct datapath *dp, struct ofpbuf *buffer,
const struct sender *sender)
{
struct remote *remote = sender ? sender->remote : dp->controller;
* the caller wants to be sent; a value of 0 indicates the entire packet should
* be sent. */
void
-dp_output_control(struct datapath *dp, struct buffer *buffer, int in_port,
+dp_output_control(struct datapath *dp, struct ofpbuf *buffer, int in_port,
size_t max_len, int reason)
{
struct ofp_packet_in *opi;
buffer->size = max_len;
}
- opi = buffer_push_uninit(buffer, offsetof(struct ofp_packet_in, data));
+ opi = ofpbuf_push_uninit(buffer, offsetof(struct ofp_packet_in, data));
opi->header.version = OFP_VERSION;
opi->header.type = OFPT_PACKET_IN;
opi->header.length = htons(buffer->size);
static void
dp_send_features_reply(struct datapath *dp, const struct sender *sender)
{
- struct buffer *buffer;
+ struct ofpbuf *buffer;
struct ofp_switch_features *ofr;
struct sw_port *p;
ofr->capabilities = htonl(OFP_SUPPORTED_CAPABILITIES);
ofr->actions = htonl(OFP_SUPPORTED_ACTIONS);
LIST_FOR_EACH (p, struct sw_port, node, &dp->port_list) {
- struct ofp_phy_port *opp = buffer_put_uninit(buffer, sizeof *opp);
+ struct ofp_phy_port *opp = ofpbuf_put_uninit(buffer, sizeof *opp);
memset(opp, 0, sizeof *opp);
fill_port_desc(dp, p, opp);
}
static void
send_port_status(struct sw_port *p, uint8_t status)
{
- struct buffer *buffer;
+ struct ofpbuf *buffer;
struct ofp_port_status *ops;
ops = make_openflow_xid(sizeof *ops, OFPT_PORT_STATUS, 0, &buffer);
ops->reason = status;
send_flow_expired(struct datapath *dp, struct sw_flow *flow,
enum ofp_flow_expired_reason reason)
{
- struct buffer *buffer;
+ struct ofpbuf *buffer;
struct ofp_flow_expired *ofe;
ofe = make_openflow_xid(sizeof *ofe, OFPT_FLOW_EXPIRED, 0, &buffer);
flow_fill_match(&ofe->match, &flow->key);
dp_send_error_msg(struct datapath *dp, const struct sender *sender,
uint16_t type, uint16_t code, const uint8_t *data, size_t len)
{
- struct buffer *buffer;
+ struct ofpbuf *buffer;
struct ofp_error_msg *oem;
oem = make_openflow_reply(sizeof(*oem)+len, OFPT_ERROR_MSG,
sender, &buffer);
}
static void
-fill_flow_stats(struct buffer *buffer, struct sw_flow *flow,
+fill_flow_stats(struct ofpbuf *buffer, struct sw_flow *flow,
int table_idx, time_t now)
{
struct ofp_flow_stats *ofs;
int length = sizeof *ofs + sizeof *ofs->actions * flow->n_actions;
- ofs = buffer_put_uninit(buffer, length);
+ ofs = ofpbuf_put_uninit(buffer, length);
ofs->length = htons(length);
ofs->table_id = table_idx;
ofs->pad = 0;
* OFPP_MAX. Process it according to 'dp''s flow table. Returns 0 if
* successful, in which case 'buffer' is destroyed, or -ESRCH if there is no
* matching flow, in which case 'buffer' still belongs to the caller. */
-int run_flow_through_tables(struct datapath *dp, struct buffer *buffer,
+int run_flow_through_tables(struct datapath *dp, struct ofpbuf *buffer,
int in_port)
{
struct sw_flow_key key;
if (flow_extract(buffer, in_port, &key.flow)
&& (dp->flags & OFPC_FRAG_MASK) == OFPC_FRAG_DROP) {
/* Drop fragment. */
- buffer_delete(buffer);
+ ofpbuf_delete(buffer);
return 0;
}
/* 'buffer' was received on 'in_port', a physical switch port between 0 and
* OFPP_MAX. Process it according to 'dp''s flow table, sending it up to the
* controller if no flow matches. Takes ownership of 'buffer'. */
-void fwd_port_input(struct datapath *dp, struct buffer *buffer, int in_port)
+void fwd_port_input(struct datapath *dp, struct ofpbuf *buffer, int in_port)
{
if (run_flow_through_tables(dp, buffer, in_port)) {
dp_output_control(dp, buffer, in_port, dp->miss_send_len,
}
static void
-do_output(struct datapath *dp, struct buffer *buffer, int in_port,
+do_output(struct datapath *dp, struct ofpbuf *buffer, int in_port,
size_t max_len, int out_port)
{
if (out_port != OFPP_CONTROLLER) {
}
static void
-execute_actions(struct datapath *dp, struct buffer *buffer,
+execute_actions(struct datapath *dp, struct ofpbuf *buffer,
int in_port, const struct sw_flow_key *key,
const struct ofp_action *actions, int n_actions)
{
struct eth_header *eh = buffer->l2;
if (prev_port != -1) {
- do_output(dp, buffer_clone(buffer), in_port, max_len, prev_port);
+ do_output(dp, ofpbuf_clone(buffer), in_port, max_len, prev_port);
prev_port = -1;
}
if (prev_port != -1)
do_output(dp, buffer, in_port, max_len, prev_port);
else
- buffer_delete(buffer);
+ ofpbuf_delete(buffer);
}
-static void modify_nh(struct buffer *buffer, uint16_t eth_proto,
+static void modify_nh(struct ofpbuf *buffer, uint16_t eth_proto,
uint8_t nw_proto, const struct ofp_action *a)
{
if (eth_proto == ETH_TYPE_IP) {
}
}
-static void modify_th(struct buffer *buffer, uint16_t eth_proto,
+static void modify_th(struct ofpbuf *buffer, uint16_t eth_proto,
uint8_t nw_proto, const struct ofp_action *a)
{
if (eth_proto == ETH_TYPE_IP) {
}
static void
-modify_vlan(struct buffer *buffer,
+modify_vlan(struct ofpbuf *buffer,
const struct sw_flow_key *key, const struct ofp_action *a)
{
uint16_t new_id = a->arg.vlan_id;
tmp.veth_tci = new_id;
tmp.veth_next_type = eh->eth_type;
- veh = buffer_push_uninit(buffer, VLAN_HEADER_LEN);
+ veh = ofpbuf_push_uninit(buffer, VLAN_HEADER_LEN);
memcpy(veh, &tmp, sizeof tmp);
buffer->l2 -= VLAN_HEADER_LEN;
}
recv_get_config_request(struct datapath *dp, const struct sender *sender,
const void *msg)
{
- struct buffer *buffer;
+ struct ofpbuf *buffer;
struct ofp_switch_config *osc;
osc = make_openflow_reply(sizeof *osc, OFPT_GET_CONFIG_REPLY,
{
const struct ofp_packet_out *opo = msg;
struct sw_flow_key key;
- struct buffer *buffer;
+ struct ofpbuf *buffer;
int n_actions = ntohs(opo->n_actions);
int act_len = n_actions * sizeof opo->actions[0];
if (ntohl(opo->buffer_id) == (uint32_t) -1) {
/* FIXME: can we avoid copying data here? */
int data_len = ntohs(opo->header.length) - sizeof *opo - act_len;
- buffer = buffer_new(data_len);
- buffer_put(buffer, &opo->actions[n_actions], data_len);
+ buffer = ofpbuf_new(data_len);
+ ofpbuf_put(buffer, &opo->actions[n_actions], data_len);
} else {
buffer = retrieve_buffer(ntohl(opo->buffer_id));
if (!buffer) {
}
error = 0;
if (ntohl(ofm->buffer_id) != UINT32_MAX) {
- struct buffer *buffer = retrieve_buffer(ntohl(ofm->buffer_id));
+ struct ofpbuf *buffer = retrieve_buffer(ntohl(ofm->buffer_id));
if (buffer) {
struct sw_flow_key key;
uint16_t in_port = ntohs(ofm->match.in_port);
}
static int desc_stats_dump(struct datapath *dp, void *state,
- struct buffer *buffer)
+ struct ofpbuf *buffer)
{
- struct ofp_desc_stats *ods = buffer_put_uninit(buffer, sizeof *ods);
+ struct ofp_desc_stats *ods = ofpbuf_put_uninit(buffer, sizeof *ods);
strncpy(ods->mfr_desc, &mfr_desc, sizeof ods->mfr_desc);
strncpy(ods->hw_desc, &hw_desc, sizeof ods->hw_desc);
struct ofp_flow_stats_request rq;
time_t now;
- struct buffer *buffer;
+ struct ofpbuf *buffer;
};
#define MAX_FLOW_STATS_BYTES 4096
}
static int flow_stats_dump(struct datapath *dp, void *state,
- struct buffer *buffer)
+ struct ofpbuf *buffer)
{
struct flow_stats_state *s = state;
struct sw_flow_key match_key;
}
static int aggregate_stats_dump(struct datapath *dp, void *state,
- struct buffer *buffer)
+ struct ofpbuf *buffer)
{
struct aggregate_stats_state *s = state;
struct ofp_aggregate_stats_request *rq = &s->rq;
struct sw_flow_key match_key;
int table_idx;
- rpy = buffer_put_uninit(buffer, sizeof *rpy);
+ rpy = ofpbuf_put_uninit(buffer, sizeof *rpy);
memset(rpy, 0, sizeof *rpy);
flow_extract_match(&match_key, &rq->match);
}
static int table_stats_dump(struct datapath *dp, void *state,
- struct buffer *buffer)
+ struct ofpbuf *buffer)
{
int i;
for (i = 0; i < dp->chain->n_tables; i++) {
- struct ofp_table_stats *ots = buffer_put_uninit(buffer, sizeof *ots);
+ struct ofp_table_stats *ots = ofpbuf_put_uninit(buffer, sizeof *ots);
struct sw_table_stats stats;
dp->chain->tables[i]->stats(dp->chain->tables[i], &stats);
strncpy(ots->name, stats.name, sizeof ots->name);
}
static int port_stats_dump(struct datapath *dp, void *state,
- struct buffer *buffer)
+ struct ofpbuf *buffer)
{
struct port_stats_state *s = state;
int i;
if (!p->netdev) {
continue;
}
- ops = buffer_put_uninit(buffer, sizeof *ops);
+ ops = ofpbuf_put_uninit(buffer, sizeof *ops);
ops->port_no = htons(port_no(dp, p));
memset(ops->pad, 0, sizeof ops->pad);
ops->rx_packets = htonll(p->rx_packets);
* struct ofp_stats_reply. On success, it should return 1 if it should be
* called again later with another buffer, 0 if it is done, or a negative
* errno value on failure. */
- int (*dump)(struct datapath *dp, void *state, struct buffer *buffer);
+ int (*dump)(struct datapath *dp, void *state, struct ofpbuf *buffer);
/* Cleans any state created by the init or dump functions. May be null
* if no cleanup is required. */
{
struct stats_dump_cb *cb = cb_;
struct ofp_stats_reply *osr;
- struct buffer *buffer;
+ struct ofpbuf *buffer;
int err;
if (cb->done) {
cb->done = true;
} else {
/* Buffer might have been reallocated, so find our data again. */
- osr = buffer_at_assert(buffer, 0, sizeof *osr);
+ osr = ofpbuf_at_assert(buffer, 0, sizeof *osr);
osr->flags = ntohs(OFPSF_REPLY_MORE);
}
err2 = send_openflow_buffer(dp, buffer, &cb->sender);
#define OVERWRITE_SECS 1
struct packet_buffer {
- struct buffer *buffer;
+ struct ofpbuf *buffer;
uint32_t cookie;
time_t timeout;
};
static struct packet_buffer buffers[N_PKT_BUFFERS];
static unsigned int buffer_idx;
-uint32_t save_buffer(struct buffer *buffer)
+uint32_t save_buffer(struct ofpbuf *buffer)
{
struct packet_buffer *p;
uint32_t id;
if (time_now() < p->timeout) { /* FIXME */
return -1;
} else {
- buffer_delete(p->buffer);
+ ofpbuf_delete(p->buffer);
}
}
/* Don't use maximum cookie value since the all-bits-1 id is
* special. */
if (++p->cookie >= (1u << PKT_COOKIE_BITS) - 1)
p->cookie = 0;
- p->buffer = buffer_clone(buffer); /* FIXME */
+ p->buffer = ofpbuf_clone(buffer); /* FIXME */
p->timeout = time_now() + OVERWRITE_SECS; /* FIXME */
id = buffer_idx | (p->cookie << PKT_BUFFER_BITS);
return id;
}
-static struct buffer *retrieve_buffer(uint32_t id)
+static struct ofpbuf *retrieve_buffer(uint32_t id)
{
- struct buffer *buffer = NULL;
+ struct ofpbuf *buffer = NULL;
struct packet_buffer *p;
p = &buffers[id & PKT_BUFFER_MASK];
p = &buffers[id & PKT_BUFFER_MASK];
if (p->cookie == id >> PKT_BUFFER_BITS) {
- buffer_delete(p->buffer);
+ ofpbuf_delete(p->buffer);
p->buffer = NULL;
}
}
#ifndef DATAPATH_H
#define DATAPATH_H 1
-#include <time.h>
-#include "openflow.h"
-#include "switch-flow.h"
-#include "buffer.h"
-#include "list.h"
+#include <stdint.h>
struct datapath;
struct rconn;
#include <assert.h>
#include <stdlib.h>
#include <string.h>
-#include "buffer.h"
+#include "ofpbuf.h"
#include "openflow.h"
#include "packets.h"
#include "timeval.h"
}
}
-void flow_used(struct sw_flow *flow, struct buffer *buffer)
+void flow_used(struct sw_flow *flow, struct ofpbuf *buffer)
{
flow->used = time_now();
flow->packet_count++;
void print_flow(const struct sw_flow_key *);
bool flow_timeout(struct sw_flow *flow);
-void flow_used(struct sw_flow *flow, struct buffer *buffer);
+void flow_used(struct sw_flow *flow, struct ofpbuf *buffer);
#endif /* switch-flow.h */
#include <stdlib.h>
#include <string.h>
#include "crc32.h"
-#include "flow.h"
#include "datapath.h"
+#include "flow.h"
+#include "switch-flow.h"
struct sw_table_hash {
struct sw_table swt;
#include "openflow-netlink.h"
#endif
-#include "buffer.h"
#include "command-line.h"
#include "compiler.h"
#include "dpif.h"
#include "ofp-print.h"
+#include "ofpbuf.h"
#include "openflow.h"
#include "packets.h"
#include "random.h"
struct dpif dp;
open_nl_vconn(argv[1], true, &dp);
for (;;) {
- struct buffer *b;
+ struct ofpbuf *b;
run(dpif_recv_openflow(&dp, &b, true), "dpif_recv_openflow");
ofp_print(stderr, b->data, b->size, 2);
- buffer_delete(b);
+ ofpbuf_delete(b);
}
}
#endif /* HAVE_NETLINK */
/* Generic commands. */
static void *
-alloc_stats_request(size_t body_len, uint16_t type, struct buffer **bufferp)
+alloc_stats_request(size_t body_len, uint16_t type, struct ofpbuf **bufferp)
{
struct ofp_stats_request *rq;
rq = make_openflow((offsetof(struct ofp_stats_request, body)
}
static void
-send_openflow_buffer(struct vconn *vconn, struct buffer *buffer)
+send_openflow_buffer(struct vconn *vconn, struct ofpbuf *buffer)
{
update_openflow_length(buffer);
run(vconn_send_block(vconn, buffer), "failed to send packet to switch");
}
static void
-dump_transaction(const char *vconn_name, struct buffer *request)
+dump_transaction(const char *vconn_name, struct ofpbuf *request)
{
struct vconn *vconn;
- struct buffer *reply;
+ struct ofpbuf *reply;
update_openflow_length(request);
run(vconn_open_block(vconn_name, &vconn), "connecting to %s", vconn_name);
static void
dump_trivial_transaction(const char *vconn_name, uint8_t request_type)
{
- struct buffer *request;
+ struct ofpbuf *request;
make_openflow(sizeof(struct ofp_header), request_type, &request);
dump_transaction(vconn_name, request);
}
static void
-dump_stats_transaction(const char *vconn_name, struct buffer *request)
+dump_stats_transaction(const char *vconn_name, struct ofpbuf *request)
{
uint32_t send_xid = ((struct ofp_header *) request->data)->xid;
struct vconn *vconn;
send_openflow_buffer(vconn, request);
while (!done) {
uint32_t recv_xid;
- struct buffer *reply;
+ struct ofpbuf *reply;
run(vconn_recv_block(vconn, &reply), "OpenFlow packet receive failed");
recv_xid = ((struct ofp_header *) reply->data)->xid;
ofp_print(stdout, reply->data, reply->size, 1);
- osr = buffer_at(reply, 0, sizeof *osr);
+ osr = ofpbuf_at(reply, 0, sizeof *osr);
done = !osr || !(ntohs(osr->flags) & OFPSF_REPLY_MORE);
} else {
VLOG_DBG("received reply with xid %08"PRIx32" "
"!= expected %08"PRIx32, recv_xid, send_xid);
}
- buffer_delete(reply);
+ ofpbuf_delete(reply);
}
vconn_close(vconn);
}
static void
dump_trivial_stats_transaction(const char *vconn_name, uint8_t stats_type)
{
- struct buffer *request;
+ struct ofpbuf *request;
alloc_stats_request(0, stats_type, &request);
dump_stats_transaction(vconn_name, request);
}
static void
do_status(int argc, char *argv[])
{
- struct buffer *request;
+ struct ofpbuf *request;
alloc_stats_request(0, OFPST_SWITCH, &request);
if (argc > 2) {
- buffer_put(request, argv[2], strlen(argv[2]));
+ ofpbuf_put(request, argv[2], strlen(argv[2]));
}
dump_stats_transaction(argv[1], request);
}
static void do_dump_flows(int argc, char *argv[])
{
struct ofp_flow_stats_request *req;
- struct buffer *request;
+ struct ofpbuf *request;
req = alloc_stats_request(sizeof *req, OFPST_FLOW, &request);
str_to_flow(argc > 2 ? argv[2] : "", &req->match, NULL, 0,
static void do_dump_aggregate(int argc, char *argv[])
{
struct ofp_aggregate_stats_request *req;
- struct buffer *request;
+ struct ofpbuf *request;
req = alloc_stats_request(sizeof *req, OFPST_AGGREGATE, &request);
str_to_flow(argc > 2 ? argv[2] : "", &req->match, NULL, 0,
static void do_add_flow(int argc, char *argv[])
{
struct vconn *vconn;
- struct buffer *buffer;
+ struct ofpbuf *buffer;
struct ofp_flow_mod *ofm;
uint16_t priority, idle_timeout, hard_timeout;
size_t size;
ofm->priority = htons(priority);
ofm->reserved = htonl(0);
- /* xxx Should we use the buffer library? */
+ /* xxx Should we use the ofpbuf library? */
buffer->size -= (MAX_ADD_ACTS - n_actions) * sizeof ofm->actions[0];
send_openflow_buffer(vconn, buffer);
run(vconn_open_block(argv[1], &vconn), "connecting to %s", argv[1]);
while (fgets(line, sizeof line, file)) {
- struct buffer *buffer;
+ struct ofpbuf *buffer;
struct ofp_flow_mod *ofm;
uint16_t priority, idle_timeout, hard_timeout;
size_t size;
ofm->priority = htons(priority);
ofm->reserved = htonl(0);
- /* xxx Should we use the buffer library? */
+ /* xxx Should we use the ofpbuf library? */
buffer->size -= (MAX_ADD_ACTS - n_actions) * sizeof ofm->actions[0];
send_openflow_buffer(vconn, buffer);
uint16_t priority;
run(vconn_open_block(argv[1], &vconn), "connecting to %s", argv[1]);
- struct buffer *buffer;
+ struct ofpbuf *buffer;
struct ofp_flow_mod *ofm;
size_t size;
static void
do_probe(int argc, char *argv[])
{
- struct buffer *request;
+ struct ofpbuf *request;
struct vconn *vconn;
- struct buffer *reply;
+ struct ofpbuf *reply;
make_openflow(sizeof(struct ofp_header), OFPT_ECHO_REQUEST, &request);
run(vconn_open_block(argv[1], &vconn), "connecting to %s", argv[1]);
if (reply->size != request->size) {
fatal(0, "reply does not match request");
}
- buffer_delete(reply);
+ ofpbuf_delete(reply);
vconn_close(vconn);
}
static void
do_mod_port(int argc, char *argv[])
{
- struct buffer *request, *reply;
+ struct ofpbuf *request, *reply;
struct ofp_switch_features *osf;
struct ofp_port_mod *opm;
struct vconn *vconn;
send_openflow_buffer(vconn, request);
- buffer_delete(reply);
+ ofpbuf_delete(reply);
vconn_close(vconn);
}
run(vconn_open_block(argv[1], &vconn), "connecting to %s", argv[1]);
for (i = 0; i < 10; i++) {
struct timeval start, end;
- struct buffer *request, *reply;
+ struct ofpbuf *request, *reply;
struct ofp_header *rq_hdr, *rpy_hdr;
rq_hdr = make_openflow(sizeof(struct ofp_header) + payload,
random_bytes(rq_hdr + 1, payload);
gettimeofday(&start, NULL);
- run(vconn_transact(vconn, buffer_clone(request), &reply), "transact");
+ run(vconn_transact(vconn, ofpbuf_clone(request), &reply), "transact");
gettimeofday(&end, NULL);
rpy_hdr = reply->data;
reply->size - sizeof *rpy_hdr, argv[1], rpy_hdr->xid,
(1000*(double)(end.tv_sec - start.tv_sec))
+ (.001*(end.tv_usec - start.tv_usec)));
- buffer_delete(request);
- buffer_delete(reply);
+ ofpbuf_delete(request);
+ ofpbuf_delete(reply);
}
vconn_close(vconn);
}
run(vconn_open_block(argv[1], &vconn), "connecting to %s", argv[1]);
gettimeofday(&start, NULL);
for (i = 0; i < count; i++) {
- struct buffer *request, *reply;
+ struct ofpbuf *request, *reply;
struct ofp_header *rq_hdr;
rq_hdr = make_openflow(message_size, OFPT_ECHO_REQUEST, &request);
memset(rq_hdr + 1, 0, payload_size);
run(vconn_transact(vconn, request, &reply), "transact");
- buffer_delete(reply);
+ ofpbuf_delete(reply);
}
gettimeofday(&end, NULL);
vconn_close(vconn);