From: Ben Pfaff Date: Thu, 4 Sep 2008 17:35:50 +0000 (-0700) Subject: Rename struct buffer to struct ofpbuf. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5549180a542fa7aa17a196d55b2f5eb4cbb3159a;p=openvswitch Rename struct buffer to struct ofpbuf. Fixes namespace conflict for partner development. --- diff --git a/controller/controller.c b/controller/controller.c index 2d79afaa..775e905c 100644 --- a/controller/controller.c +++ b/controller/controller.c @@ -40,12 +40,12 @@ #include #include -#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" @@ -209,14 +209,14 @@ static int 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); diff --git a/include/Makefile.am b/include/Makefile.am index 741618a3..a575a374 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,5 +1,4 @@ noinst_HEADERS = \ - buffer.h \ command-line.h \ compiler.h \ csum.h \ @@ -18,6 +17,7 @@ noinst_HEADERS = \ netdev.h \ netlink-protocol.h \ netlink.h \ + ofpbuf.h \ ofp-print.h \ openflow.h \ openflow-netlink.h \ diff --git a/include/buffer.h b/include/buffer.h deleted file mode 100644 index 08680694..00000000 --- a/include/buffer.h +++ /dev/null @@ -1,87 +0,0 @@ -/* 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 - -/* 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 */ diff --git a/include/dhcp.h b/include/dhcp.h index f44c4c65..c513f4e5 100644 --- a/include/dhcp.h +++ b/include/dhcp.h @@ -39,7 +39,7 @@ #include "util.h" struct ds; -struct buffer; +struct ofpbuf; /* Values for 'op' field. */ #define DHCP_BOOTREQUEST 1 /* Message sent by DHCP client. */ @@ -273,7 +273,7 @@ bool dhcp_msg_get_uint16(const struct dhcp_msg *, int code, 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 */ diff --git a/include/dpif.h b/include/dpif.h index 122c64d8..0316e13b 100644 --- a/include/dpif.h +++ b/include/dpif.h @@ -42,7 +42,7 @@ #include #include -struct buffer; +struct ofpbuf; struct ofp_match; /* A datapath interface. Opaque. */ @@ -54,8 +54,8 @@ struct dpif 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); diff --git a/include/flow.h b/include/flow.h index 1364e3a7..0a952f9b 100644 --- a/include/flow.h +++ b/include/flow.h @@ -37,7 +37,7 @@ #include #include "util.h" -struct buffer; +struct ofpbuf; /* Identification data for a flow. All fields are in network byte order. @@ -58,7 +58,7 @@ struct flow { }; 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); diff --git a/include/learning-switch.h b/include/learning-switch.h index 07bb15d7..36f123bf 100644 --- a/include/learning-switch.h +++ b/include/learning-switch.h @@ -36,12 +36,12 @@ #include -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 */ diff --git a/include/netdev.h b/include/netdev.h index 0111e528..8663b33b 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -43,7 +43,7 @@ #include #include -struct buffer; +struct ofpbuf; struct in_addr; struct in6_addr; @@ -61,10 +61,10 @@ enum netdev_pseudo_ethertype { 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 *); diff --git a/include/netlink.h b/include/netlink.h index 54924723..8163a318 100644 --- a/include/netlink.h +++ b/include/netlink.h @@ -47,7 +47,7 @@ #include #include -struct buffer; +struct ofpbuf; struct nl_sock; struct nlattr; @@ -58,43 +58,43 @@ int nl_sock_create(int protocol, int multicast_group, 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 *); /* 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 *); /* Netlink attribute types. */ enum nl_attr_type @@ -135,7 +135,7 @@ struct nl_policy 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); /* Miscellaneous. */ diff --git a/include/ofpbuf.h b/include/ofpbuf.h new file mode 100644 index 00000000..a9cb6185 --- /dev/null +++ b/include/ofpbuf.h @@ -0,0 +1,87 @@ +/* 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 + +/* 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 */ diff --git a/include/queue.h b/include/queue.h index 113d5013..cecc15dd 100644 --- a/include/queue.h +++ b/include/queue.h @@ -37,15 +37,15 @@ /* 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 */ diff --git a/include/rconn.h b/include/rconn.h index df17a5c0..69f9b8de 100644 --- a/include/rconn.h +++ b/include/rconn.h @@ -65,10 +65,10 @@ void rconn_destroy(struct rconn *); 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 *); diff --git a/include/vconn-provider.h b/include/vconn-provider.h index 57778e7b..3a40e234 100644 --- a/include/vconn-provider.h +++ b/include/vconn-provider.h @@ -95,7 +95,7 @@ struct vconn_class { /* 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. @@ -105,7 +105,7 @@ struct vconn_class { * * 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 @@ -121,7 +121,7 @@ struct vconn_class { * * 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); }; diff --git a/include/vconn.h b/include/vconn.h index ec98859d..224fd561 100644 --- a/include/vconn.h +++ b/include/vconn.h @@ -38,7 +38,7 @@ #include #include -struct buffer; +struct ofpbuf; struct flow; struct pollfd; struct ofp_header; @@ -54,13 +54,13 @@ bool vconn_is_passive(const struct vconn *); 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, @@ -74,21 +74,21 @@ void vconn_accept_wait(struct vconn *); 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; diff --git a/lib/Makefile.am b/lib/Makefile.am index 6c02909f..a78597fe 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -3,7 +3,6 @@ include ../Make.vars noinst_LIBRARIES = libopenflow.a libopenflow_a_SOURCES = \ - buffer.c \ command-line.c \ csum.c \ daemon.c \ @@ -18,6 +17,7 @@ libopenflow_a_SOURCES = \ list.c \ mac-learning.c \ netdev.c \ + ofpbuf.c \ ofp-print.c \ poll-loop.c \ queue.c \ diff --git a/lib/buffer.c b/lib/buffer.c deleted file mode 100644 index 47600e6a..00000000 --- a/lib/buffer.c +++ /dev/null @@ -1,275 +0,0 @@ -/* 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 -#include "buffer.h" -#include -#include -#include -#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; -} diff --git a/lib/dhcp-client.c b/lib/dhcp-client.c index a43c01c8..bafa19d0 100644 --- a/lib/dhcp-client.c +++ b/lib/dhcp-client.c @@ -43,12 +43,12 @@ #include #include #include -#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" @@ -876,16 +876,16 @@ timeout(struct dhclient *cli, unsigned int secs) 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; @@ -914,33 +914,33 @@ do_receive_msg(struct dhclient *cli, struct dhcp_msg *msg) 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); @@ -984,9 +984,9 @@ do_send_msg(struct dhclient *cli, const struct dhcp_msg *msg) 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 @@ -1003,7 +1003,7 @@ do_send_msg(struct dhclient *cli, const struct dhcp_msg *msg) VLOG_ERR("cannot send %zu-byte Ethernet frame", b.size); } - buffer_uninit(&b); + ofpbuf_uninit(&b); } static unsigned int diff --git a/lib/dhcp.c b/lib/dhcp.c index 2e9f3dfb..4a273283 100644 --- a/lib/dhcp.c +++ b/lib/dhcp.c @@ -39,8 +39,8 @@ #include #include #include -#include "buffer.h" #include "dynamic-string.h" +#include "ofpbuf.h" #define THIS_MODULE VLM_dhcp #include "vlog.h" @@ -558,7 +558,7 @@ static void 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; @@ -566,20 +566,20 @@ parse_options(struct dhcp_msg *msg, const char *name, void *data, size_t 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", @@ -634,15 +634,15 @@ validate_options(struct dhcp_msg *msg) * 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); @@ -673,7 +673,7 @@ dhcp_parse(struct dhcp_msg *msg, const struct buffer *b_) 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; @@ -734,19 +734,19 @@ error: } 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) { @@ -770,11 +770,11 @@ put_option(struct buffer *b, uint8_t code, void *data, size_t 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; @@ -791,8 +791,8 @@ dhcp_assemble(const struct dhcp_msg *msg, struct buffer *b) 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.) */ @@ -808,7 +808,7 @@ dhcp_assemble(const struct dhcp_msg *msg, struct buffer *b) } /* 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); @@ -816,9 +816,9 @@ dhcp_assemble(const struct dhcp_msg *msg, struct buffer *b) 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); } diff --git a/lib/dpif.c b/lib/dpif.c index 4f993123..b7b29d96 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -41,9 +41,9 @@ #include #include -#include "buffer.h" #include "netlink.h" #include "netlink-protocol.h" +#include "ofpbuf.h" #include "ofp-print.h" #include "openflow-netlink.h" #include "openflow.h" @@ -116,7 +116,7 @@ static const struct nl_policy openflow_policy[] = { /* 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'. * @@ -126,18 +126,18 @@ static const struct nl_policy openflow_policy[] = { * 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 @@ -184,7 +184,7 @@ dpif_recv_openflow(struct dpif *dp, struct buffer **bufferp, return 0; error: - buffer_delete(buffer); + ofpbuf_delete(buffer); return EPROTO; } @@ -200,11 +200,11 @@ error: * 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]; @@ -214,14 +214,14 @@ dpif_send_openflow(struct dpif *dp, struct buffer *buffer, bool wait) /* 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; @@ -288,7 +288,7 @@ static int 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; @@ -296,12 +296,12 @@ lookup_openflow_multicast_group(int dp_idx, int *multicast_group) 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; @@ -309,12 +309,12 @@ lookup_openflow_multicast_group(int dp_idx, int *multicast_group) 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; } @@ -325,10 +325,10 @@ lookup_openflow_multicast_group(int dp_idx, int *multicast_group) 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); @@ -336,8 +336,8 @@ send_mgmt_command(struct dpif *dp, int command, const char *netdev) 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; } diff --git a/lib/flow.c b/lib/flow.c index 795731b5..c0f07a2f 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -36,8 +36,8 @@ #include #include #include -#include "buffer.h" #include "hash.h" +#include "ofpbuf.h" #include "openflow.h" #include "packets.h" @@ -45,54 +45,54 @@ #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; @@ -122,7 +122,7 @@ flow_extract(struct buffer *packet, uint16_t in_port, struct flow *flow) 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; } @@ -132,10 +132,10 @@ flow_extract(struct buffer *packet, uint16_t in_port, struct flow *flow) && !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)); } } diff --git a/lib/learning-switch.c b/lib/learning-switch.c index f056b916..4a46a0f6 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -40,9 +40,9 @@ #include #include -#include "buffer.h" #include "flow.h" #include "mac-learning.h" +#include "ofpbuf.h" #include "ofp-print.h" #include "openflow.h" #include "queue.h" @@ -72,7 +72,7 @@ struct lswitch { * 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 *); @@ -117,7 +117,7 @@ lswitch_destroy(struct lswitch *sw) * '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), @@ -158,13 +158,13 @@ send_features_request(struct lswitch *sw, struct rconn *rconn) { 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; @@ -172,8 +172,8 @@ send_features_request(struct lswitch *sw, struct rconn *rconn) 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; @@ -187,7 +187,7 @@ send_features_request(struct lswitch *sw, struct rconn *rconn) } 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) { @@ -208,7 +208,7 @@ process_packet_in(struct lswitch *sw, struct rconn *rconn, 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'. */ @@ -245,7 +245,7 @@ process_packet_in(struct lswitch *sw, struct rconn *rconn, } 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 { diff --git a/lib/netdev.c b/lib/netdev.c index fc192948..85108680 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -55,9 +55,9 @@ #include #include -#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" @@ -343,11 +343,11 @@ netdev_close(struct netdev *netdev) /* 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); } } @@ -364,15 +364,15 @@ pad_to_minimum_length(struct buffer *buffer) * 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) { @@ -419,7 +419,7 @@ netdev_drain(struct netdev *netdev) * 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; @@ -430,7 +430,7 @@ netdev_send(struct netdev *netdev, const struct buffer *buffer) 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); diff --git a/lib/netlink.c b/lib/netlink.c index 1316547f..e2aa7dbf 100644 --- a/lib/netlink.c +++ b/lib/netlink.c @@ -41,9 +41,9 @@ #include #include #include -#include "buffer.h" -#include "netlink-protocol.h" #include "dynamic-string.h" +#include "netlink-protocol.h" +#include "ofpbuf.h" #include "timeval.h" #include "util.h" @@ -217,7 +217,7 @@ nl_sock_destroy(struct nl_sock *sock) * '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; @@ -261,19 +261,19 @@ nl_sock_sendv(struct nl_sock *sock, const struct iovec iov[], size_t n_iov, /* 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 = { @@ -286,7 +286,7 @@ nl_sock_recv(struct nl_sock *sock, struct buffer **bufp, bool wait) .msg_flags = 0 }; - buf = buffer_new(bufsize); + buf = ofpbuf_new(bufsize); *bufp = NULL; try_again: @@ -294,19 +294,19 @@ 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; @@ -323,7 +323,7 @@ try_again: * 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", @@ -335,7 +335,7 @@ try_again: || 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; @@ -345,7 +345,7 @@ try_again: /* 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 @@ -376,11 +376,11 @@ try_again: */ 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; @@ -409,7 +409,7 @@ recv: 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)) { @@ -437,9 +437,9 @@ nl_sock_fd(const struct nl_sock *sock) * * '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. @@ -447,9 +447,9 @@ nl_msg_nlmsghdr(const struct buffer *msg) * 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 @@ -458,10 +458,10 @@ nl_msg_genlmsghdr(const struct buffer *msg) * * '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)", @@ -481,9 +481,9 @@ nl_msg_nlmsgerr(const struct buffer *msg, int *errorp) /* 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. @@ -503,7 +503,7 @@ nl_msg_reserve(struct buffer *msg, size_t size) * 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; @@ -539,7 +539,7 @@ nl_msg_put_nlmsghdr(struct buffer *msg, struct nl_sock *sock, * 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) { @@ -558,7 +558,7 @@ nl_msg_put_genlmsghdr(struct buffer *msg, struct nl_sock *sock, * 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); } @@ -567,10 +567,10 @@ nl_msg_put(struct buffer *msg, const void *data, size_t 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); } @@ -582,7 +582,7 @@ nl_msg_put_uninit(struct buffer *msg, size_t size) * '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); @@ -597,7 +597,7 @@ nl_msg_put_unspec_uninit(struct buffer *msg, uint16_t type, size_t 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); @@ -607,7 +607,7 @@ nl_msg_put_unspec(struct buffer *msg, uint16_t type, * (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); } @@ -615,7 +615,7 @@ nl_msg_put_flag(struct buffer *msg, uint16_t type) /* 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); } @@ -623,7 +623,7 @@ nl_msg_put_u8(struct buffer *msg, uint16_t type, uint8_t 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); } @@ -631,7 +631,7 @@ nl_msg_put_u16(struct buffer *msg, uint16_t type, uint16_t 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); } @@ -639,7 +639,7 @@ nl_msg_put_u32(struct buffer *msg, uint16_t type, uint32_t 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); } @@ -647,7 +647,7 @@ nl_msg_put_u64(struct buffer *msg, uint16_t type, uint64_t 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); } @@ -656,8 +656,8 @@ nl_msg_put_string(struct buffer *msg, uint16_t type, const char *value) * 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); @@ -763,7 +763,7 @@ static const size_t attr_len_range[][2] = { * 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; @@ -782,12 +782,12 @@ nl_policy_parse(const struct buffer *msg, const struct nl_policy policy[], } } - 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; @@ -862,7 +862,7 @@ static const struct nl_policy family_policy[CTRL_ATTR_MAX + 1] = { 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; @@ -871,12 +871,12 @@ static int do_lookup_genl_family(const char *name) 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; @@ -885,7 +885,7 @@ static int do_lookup_genl_family(const char *name) if (!nl_policy_parse(reply, family_policy, attrs, ARRAY_SIZE(family_policy))) { nl_sock_destroy(sock); - buffer_delete(reply); + ofpbuf_delete(reply); return -EPROTO; } @@ -894,7 +894,7 @@ static int do_lookup_genl_family(const char *name) retval = -EPROTO; } nl_sock_destroy(sock); - buffer_delete(reply); + ofpbuf_delete(reply); return retval; } @@ -1013,15 +1013,15 @@ nlmsghdr_to_string(const struct nlmsghdr *h, struct ds *ds) } 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); @@ -1035,7 +1035,7 @@ nlmsg_to_string(const struct buffer *buffer) 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) { @@ -1056,7 +1056,7 @@ static void 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()) { diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 7cfe0a3d..0bc689ff 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -43,13 +43,13 @@ #include #include -#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 *, @@ -180,7 +180,7 @@ ofp_packet_in(struct ds *string, const void *oh, size_t len, int verbosity) 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; diff --git a/lib/ofpbuf.c b/lib/ofpbuf.c new file mode 100644 index 00000000..50b471af --- /dev/null +++ b/lib/ofpbuf.c @@ -0,0 +1,276 @@ +/* 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 +#include "ofpbuf.h" +#include +#include +#include +#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; +} diff --git a/lib/queue.c b/lib/queue.c index f06c8e9a..33acc7eb 100644 --- a/lib/queue.c +++ b/lib/queue.c @@ -34,7 +34,7 @@ #include #include "queue.h" #include -#include "buffer.h" +#include "ofpbuf.h" static void check_queue(struct queue *q); @@ -51,10 +51,10 @@ queue_init(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); } } @@ -73,7 +73,7 @@ queue_clear(struct queue *q) * 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); @@ -86,7 +86,7 @@ queue_advance_head(struct queue *q, struct buffer *next) /* 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); @@ -102,12 +102,12 @@ queue_push_tail(struct queue *q, struct buffer *b) } /* 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; } @@ -117,7 +117,7 @@ static void check_queue(struct queue *q) { #if 0 - struct buffer *iter; + struct ofpbuf *iter; size_t n; assert(q->n == 0 diff --git a/lib/rconn.c b/lib/rconn.c index 26e2e614..3fce80e6 100644 --- a/lib/rconn.c +++ b/lib/rconn.c @@ -38,9 +38,9 @@ #include #include #include -#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" @@ -421,12 +421,12 @@ rconn_run_wait(struct rconn *rc) /* 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(); @@ -466,7 +466,7 @@ rconn_recv_wait(struct rconn *rc) * 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; @@ -496,13 +496,13 @@ rconn_send(struct rconn *rc, struct buffer *b, int *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; } @@ -645,7 +645,7 @@ static int 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) { @@ -713,12 +713,12 @@ flush_queue(struct rconn *rc) 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(); } diff --git a/lib/vconn-netlink.c b/lib/vconn-netlink.c index 4f609bb3..70f5e3ed 100644 --- a/lib/vconn-netlink.c +++ b/lib/vconn-netlink.c @@ -43,14 +43,14 @@ #include #include #include -#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" @@ -104,19 +104,19 @@ netlink_close(struct vconn *vconn) } 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; } diff --git a/lib/vconn-ssl.c b/lib/vconn-ssl.c index d553834f..48e87cf4 100644 --- a/lib/vconn-ssl.c +++ b/lib/vconn-ssl.c @@ -43,7 +43,7 @@ #include #include #include -#include "buffer.h" +#include "ofpbuf.h" #include "socket-util.h" #include "util.h" #include "openflow.h" @@ -77,8 +77,8 @@ struct ssl_vconn 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() @@ -440,16 +440,16 @@ interpret_ssl_error(const char *function, int ret, int error, } 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; @@ -471,13 +471,13 @@ again: 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) { @@ -518,7 +518,7 @@ again: static void ssl_clear_txbuf(struct ssl_vconn *sslv) { - buffer_delete(sslv->txbuf); + ofpbuf_delete(sslv->txbuf); sslv->txbuf = NULL; sslv->tx_waiter = NULL; } @@ -545,7 +545,7 @@ ssl_do_tx(struct vconn *vconn) } 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; } @@ -576,7 +576,7 @@ ssl_tx_poll_callback(int fd UNUSED, short int revents UNUSED, void *vconn_) } 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); diff --git a/lib/vconn-stream.c b/lib/vconn-stream.c index c419d530..0f7220e2 100644 --- a/lib/vconn-stream.c +++ b/lib/vconn-stream.c @@ -40,13 +40,13 @@ #include #include #include -#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 @@ -57,8 +57,8 @@ struct stream_vconn { struct vconn vconn; int fd; - struct buffer *rxbuf; - struct buffer *txbuf; + struct ofpbuf *rxbuf; + struct ofpbuf *txbuf; struct poll_waiter *tx_waiter; }; @@ -106,15 +106,15 @@ stream_connect(struct vconn *vconn) } 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; @@ -136,9 +136,9 @@ again: 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) { @@ -166,7 +166,7 @@ again: static void stream_clear_txbuf(struct stream_vconn *s) { - buffer_delete(s->txbuf); + ofpbuf_delete(s->txbuf); s->txbuf = NULL; s->tx_waiter = NULL; } @@ -184,7 +184,7 @@ stream_do_tx(int fd UNUSED, short int revents UNUSED, void *vconn_) return; } } else if (n > 0) { - buffer_pull(s->txbuf, n); + ofpbuf_pull(s->txbuf, n); if (!s->txbuf->size) { stream_clear_txbuf(s); return; @@ -194,7 +194,7 @@ stream_do_tx(int fd UNUSED, short int revents UNUSED, void *vconn_) } 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; @@ -205,12 +205,12 @@ stream_send(struct vconn *vconn, struct buffer *buffer) 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; diff --git a/lib/vconn-unix.c b/lib/vconn-unix.c index 356109da..a321b3ce 100644 --- a/lib/vconn-unix.c +++ b/lib/vconn-unix.c @@ -43,13 +43,13 @@ #include #include #include -#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" diff --git a/lib/vconn.c b/lib/vconn.c index 3e06dc34..1a5dc6b0 100644 --- a/lib/vconn.c +++ b/lib/vconn.c @@ -40,9 +40,9 @@ #include #include #include -#include "buffer.h" #include "flow.h" #include "ofp-print.h" +#include "ofpbuf.h" #include "openflow.h" #include "poll-loop.h" #include "random.h" @@ -274,13 +274,13 @@ vconn_accept(struct vconn *vconn, struct vconn **new_vconn) /* 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) { @@ -294,12 +294,12 @@ vconn_recv(struct vconn *vconn, struct buffer **msgp) 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; } @@ -323,7 +323,7 @@ vconn_recv(struct vconn *vconn, struct buffer **msgp) * 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) { @@ -345,7 +345,7 @@ vconn_send(struct vconn *vconn, struct buffer *msg) /* 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) { @@ -357,7 +357,7 @@ vconn_send_block(struct vconn *vconn, struct buffer *msg) /* 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) { @@ -374,8 +374,8 @@ vconn_recv_block(struct vconn *vconn, struct buffer **msgp) * * '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; @@ -383,12 +383,12 @@ vconn_transact(struct vconn *vconn, struct buffer *request, *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) { @@ -402,7 +402,7 @@ vconn_transact(struct vconn *vconn, struct buffer *request, 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); } } @@ -457,7 +457,7 @@ vconn_send_wait(struct vconn *vconn) * 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); } @@ -468,15 +468,15 @@ make_openflow(size_t openflow_len, uint8_t type, struct buffer **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; @@ -488,20 +488,20 @@ make_openflow_xid(size_t openflow_len, uint8_t type, uint32_t xid, /* 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; @@ -524,12 +524,12 @@ make_add_flow(const struct flow *flow, uint32_t buffer_id, 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); @@ -537,14 +537,14 @@ make_add_simple_flow(const struct flow *flow, 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; @@ -554,19 +554,19 @@ make_unbuffered_packet_out(const struct buffer *packet, 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; @@ -581,12 +581,12 @@ make_buffered_packet_out(uint32_t buffer_id, } /* 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); @@ -596,12 +596,12 @@ make_echo_request(void) /* 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; } diff --git a/secchan/secchan.c b/secchan/secchan.c index d45c5ea3..42e99da2 100644 --- a/secchan/secchan.c +++ b/secchan/secchan.c @@ -45,12 +45,11 @@ #include #include -#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" @@ -58,6 +57,7 @@ #include "list.h" #include "mac-learning.h" #include "netdev.h" +#include "ofpbuf.h" #include "openflow.h" #include "packets.h" #include "poll-loop.h" @@ -111,7 +111,7 @@ struct settings { struct half { struct rconn *rconn; - struct buffer *rxbuf; + struct ofpbuf *rxbuf; int n_txq; /* No. of packets queued for tx on 'rconn'. */ }; @@ -430,7 +430,7 @@ relay_run(struct relay *r, const struct hook hooks[], size_t n_hooks) 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; @@ -446,7 +446,7 @@ relay_run(struct relay *r, const struct hook hooks[], size_t n_hooks) if (!retval) { progress = true; } else { - buffer_delete(this->rxbuf); + ofpbuf_delete(this->rxbuf); } this->rxbuf = NULL; } @@ -492,7 +492,7 @@ relay_destroy(struct relay *r) 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); } @@ -509,7 +509,7 @@ struct in_band_data { }; 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); } @@ -576,11 +576,11 @@ in_band_packet_cb(struct relay *r, int half, void *in_band_) { 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; @@ -662,7 +662,7 @@ in_band_packet_cb(struct relay *r, int half, void *in_band_) } 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 { @@ -859,12 +859,12 @@ drop_packet(struct rate_limiter *rl) } /* 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; @@ -913,7 +913,7 @@ rate_limit_packet_cb(struct relay *r, int half, void *rl_) { 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) { @@ -942,7 +942,7 @@ rate_limit_packet_cb(struct relay *r, int half, void *rl_) 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; @@ -974,7 +974,7 @@ rate_limit_periodic_cb(void *rl_) * 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++; } @@ -1044,13 +1044,13 @@ switch_status_packet_cb(struct relay *r, int half, void *ss_) { 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) { diff --git a/switch/datapath.c b/switch/datapath.c index 953a30ba..607347d8 100644 --- a/switch/datapath.c +++ b/switch/datapath.c @@ -38,17 +38,20 @@ #include #include #include -#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 @@ -147,24 +150,24 @@ static void remote_run(struct datapath *, struct remote *); 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 @@ -178,13 +181,13 @@ static void modify_th(struct buffer *buffer, uint16_t eth_proto, #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) @@ -292,7 +295,7 @@ dp_run(struct datapath *dp) 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); @@ -324,7 +327,7 @@ dp_run(struct datapath *dp) 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); @@ -338,7 +341,7 @@ dp_run(struct datapath *dp) 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) { @@ -372,7 +375,7 @@ remote_run(struct datapath *dp, struct remote *r) * 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); @@ -390,7 +393,7 @@ remote_run(struct datapath *dp, struct remote *r) } 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); @@ -517,7 +520,7 @@ dp_destroy(struct datapath *dp) * "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; @@ -531,20 +534,20 @@ output_all(struct datapath *dp, struct buffer *buffer, int in_port, int flood) 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]; @@ -559,14 +562,14 @@ output_packet(struct datapath *dp, struct buffer *buffer, int 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) { @@ -581,7 +584,7 @@ dp_output_port(struct datapath *dp, struct buffer *buffer, 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) { @@ -594,14 +597,14 @@ dp_output_port(struct datapath *dp, struct buffer *buffer, 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; @@ -624,7 +627,7 @@ send_openflow_buffer(struct datapath *dp, struct buffer *buffer, * 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; @@ -637,7 +640,7 @@ dp_output_control(struct datapath *dp, struct buffer *buffer, int in_port, 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); @@ -674,7 +677,7 @@ static void fill_port_desc(struct datapath *dp, struct sw_port *p, 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; @@ -689,7 +692,7 @@ dp_send_features_reply(struct datapath *dp, const struct sender *sender) 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); } @@ -772,7 +775,7 @@ update_port_status(struct sw_port *p) 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; @@ -786,7 +789,7 @@ void 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); @@ -806,7 +809,7 @@ void 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); @@ -817,12 +820,12 @@ dp_send_error_msg(struct datapath *dp, const struct sender *sender, } 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; @@ -854,7 +857,7 @@ fill_flow_stats(struct buffer *buffer, struct sw_flow *flow, * 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; @@ -864,7 +867,7 @@ int run_flow_through_tables(struct datapath *dp, struct buffer *buffer, 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; } @@ -882,7 +885,7 @@ int run_flow_through_tables(struct datapath *dp, struct buffer *buffer, /* '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, @@ -891,7 +894,7 @@ void fwd_port_input(struct datapath *dp, struct buffer *buffer, int in_port) } 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) { @@ -902,7 +905,7 @@ do_output(struct datapath *dp, struct buffer *buffer, int in_port, } 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) { @@ -923,7 +926,7 @@ execute_actions(struct datapath *dp, struct buffer *buffer, 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; } @@ -962,10 +965,10 @@ execute_actions(struct datapath *dp, struct buffer *buffer, 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) { @@ -991,7 +994,7 @@ static void modify_nh(struct buffer *buffer, uint16_t eth_proto, } } -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) { @@ -1014,7 +1017,7 @@ static void modify_th(struct buffer *buffer, uint16_t eth_proto, } 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; @@ -1036,7 +1039,7 @@ modify_vlan(struct buffer *buffer, 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; } @@ -1070,7 +1073,7 @@ static int 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, @@ -1105,7 +1108,7 @@ recv_packet_out(struct datapath *dp, const struct sender *sender UNUSED, { 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]; @@ -1117,8 +1120,8 @@ recv_packet_out(struct datapath *dp, const struct sender *sender UNUSED, 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) { @@ -1193,7 +1196,7 @@ add_flow(struct datapath *dp, const struct ofp_flow_mod *ofm) } 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); @@ -1239,9 +1242,9 @@ recv_flow(struct datapath *dp, const struct sender *sender UNUSED, } 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); @@ -1257,7 +1260,7 @@ struct flow_stats_state { struct ofp_flow_stats_request rq; time_t now; - struct buffer *buffer; + struct ofpbuf *buffer; }; #define MAX_FLOW_STATS_BYTES 4096 @@ -1282,7 +1285,7 @@ static int flow_stats_dump_callback(struct sw_flow *flow, void *private) } 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; @@ -1335,7 +1338,7 @@ static int aggregate_stats_dump_callback(struct sw_flow *flow, void *private) } 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; @@ -1344,7 +1347,7 @@ static int aggregate_stats_dump(struct datapath *dp, void *state, 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); @@ -1377,11 +1380,11 @@ static void aggregate_stats_done(void *state) } 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); @@ -1408,7 +1411,7 @@ static int port_stats_init(struct datapath *dp, const void *body, int body_len, } static int port_stats_dump(struct datapath *dp, void *state, - struct buffer *buffer) + struct ofpbuf *buffer) { struct port_stats_state *s = state; int i; @@ -1419,7 +1422,7 @@ static int port_stats_dump(struct datapath *dp, void *state, 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); @@ -1462,7 +1465,7 @@ struct stats_type { * 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. */ @@ -1520,7 +1523,7 @@ stats_dump(struct datapath *dp, void *cb_) { struct stats_dump_cb *cb = cb_; struct ofp_stats_reply *osr; - struct buffer *buffer; + struct ofpbuf *buffer; int err; if (cb->done) { @@ -1539,7 +1542,7 @@ stats_dump(struct datapath *dp, void *cb_) 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); @@ -1699,7 +1702,7 @@ fwd_control_input(struct datapath *dp, const struct sender *sender, #define OVERWRITE_SECS 1 struct packet_buffer { - struct buffer *buffer; + struct ofpbuf *buffer; uint32_t cookie; time_t timeout; }; @@ -1707,7 +1710,7 @@ struct packet_buffer { 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; @@ -1720,23 +1723,23 @@ uint32_t save_buffer(struct buffer *buffer) 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]; @@ -1757,7 +1760,7 @@ static void discard_buffer(uint32_t id) p = &buffers[id & PKT_BUFFER_MASK]; if (p->cookie == id >> PKT_BUFFER_BITS) { - buffer_delete(p->buffer); + ofpbuf_delete(p->buffer); p->buffer = NULL; } } diff --git a/switch/datapath.h b/switch/datapath.h index 6914782f..260d10d3 100644 --- a/switch/datapath.h +++ b/switch/datapath.h @@ -36,11 +36,7 @@ #ifndef DATAPATH_H #define DATAPATH_H 1 -#include -#include "openflow.h" -#include "switch-flow.h" -#include "buffer.h" -#include "list.h" +#include struct datapath; struct rconn; diff --git a/switch/switch-flow.c b/switch/switch-flow.c index 9c9538d0..babcd6c3 100644 --- a/switch/switch-flow.c +++ b/switch/switch-flow.c @@ -37,7 +37,7 @@ #include #include #include -#include "buffer.h" +#include "ofpbuf.h" #include "openflow.h" #include "packets.h" #include "timeval.h" @@ -236,7 +236,7 @@ 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) { flow->used = time_now(); flow->packet_count++; diff --git a/switch/switch-flow.h b/switch/switch-flow.h index 0f6c7216..1320c097 100644 --- a/switch/switch-flow.h +++ b/switch/switch-flow.h @@ -82,6 +82,6 @@ void flow_fill_match(struct ofp_match* to, const struct sw_flow_key* from); 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 */ diff --git a/switch/table-hash.c b/switch/table-hash.c index 0076537e..175b840b 100644 --- a/switch/table-hash.c +++ b/switch/table-hash.c @@ -37,8 +37,9 @@ #include #include #include "crc32.h" -#include "flow.h" #include "datapath.h" +#include "flow.h" +#include "switch-flow.h" struct sw_table_hash { struct sw_table swt; diff --git a/utilities/dpctl.c b/utilities/dpctl.c index 62c93c67..82312bcd 100644 --- a/utilities/dpctl.c +++ b/utilities/dpctl.c @@ -50,11 +50,11 @@ #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" @@ -329,10 +329,10 @@ static void do_monitor(int argc UNUSED, char *argv[]) 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 */ @@ -340,7 +340,7 @@ static void do_monitor(int argc UNUSED, char *argv[]) /* 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) @@ -351,17 +351,17 @@ alloc_stats_request(size_t body_len, uint16_t type, struct buffer **bufferp) } 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); @@ -373,13 +373,13 @@ dump_transaction(const char *vconn_name, struct buffer *request) 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; @@ -389,7 +389,7 @@ dump_stats_transaction(const char *vconn_name, struct buffer *request) 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; @@ -398,13 +398,13 @@ dump_stats_transaction(const char *vconn_name, struct buffer *request) 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); } @@ -412,7 +412,7 @@ dump_stats_transaction(const char *vconn_name, struct buffer *request) 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); } @@ -427,10 +427,10 @@ do_show(int argc UNUSED, char *argv[]) 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); } @@ -752,7 +752,7 @@ str_to_flow(char *string, struct ofp_match *match, 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, @@ -765,7 +765,7 @@ static void do_dump_flows(int argc, char *argv[]) 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, @@ -778,7 +778,7 @@ static void do_dump_aggregate(int argc, char *argv[]) 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; @@ -798,7 +798,7 @@ static void do_add_flow(int argc, char *argv[]) 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); @@ -819,7 +819,7 @@ static void do_add_flows(int argc, char *argv[]) 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; @@ -850,7 +850,7 @@ static void do_add_flows(int argc, char *argv[]) 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); @@ -865,7 +865,7 @@ static void do_del_flows(int argc, char *argv[]) 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; @@ -896,9 +896,9 @@ do_dump_ports(int argc, char *argv[]) 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]); @@ -906,14 +906,14 @@ do_probe(int argc, char *argv[]) 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; @@ -984,7 +984,7 @@ do_mod_port(int argc, char *argv[]) send_openflow_buffer(vconn, request); - buffer_delete(reply); + ofpbuf_delete(reply); vconn_close(vconn); } @@ -1004,7 +1004,7 @@ do_ping(int argc, char *argv[]) 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, @@ -1012,7 +1012,7 @@ do_ping(int argc, char *argv[]) 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; @@ -1029,8 +1029,8 @@ do_ping(int argc, char *argv[]) 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); } @@ -1060,13 +1060,13 @@ do_benchmark(int argc, char *argv[]) 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);