2 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016 Nicira, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #ifndef OPENVSWITCH_OFPBUF_H
18 #define OPENVSWITCH_OFPBUF_H 1
24 #include "openvswitch/dynamic-string.h"
25 #include "openvswitch/list.h"
26 #include "openvswitch/util.h"
32 enum OVS_PACKED_ENUM ofpbuf_source
{
33 OFPBUF_MALLOC
, /* Obtained via malloc(). */
34 OFPBUF_STACK
, /* Un-movable stack space or static buffer. */
35 OFPBUF_STUB
, /* Starts on stack, may expand into heap. */
38 /* Buffer for holding arbitrary data. An ofpbuf is automatically reallocated
39 * as necessary if it grows too large for the available memory.
41 * 'header' and 'msg' conventions:
43 * OpenFlow messages: 'header' points to the start of the OpenFlow
44 * header, while 'msg' is the OpenFlow msg body.
45 * When parsing, the 'data' will move past these, as data is being
46 * pulled from the OpenFlow message.
48 * Caution: buffer manipulation of 'struct ofpbuf' must always update
49 * the 'header' and 'msg' pointers.
52 * Actions: When encoding OVS action lists, the 'header' is used
53 * as a pointer to the beginning of the current action (see ofpact_put()).
55 * rconn: Reuses 'header' as a private pointer while queuing.
58 void *base
; /* First byte of allocated space. */
59 void *data
; /* First byte actually in use. */
60 uint32_t size
; /* Number of bytes in use. */
61 uint32_t allocated
; /* Number of bytes allocated. */
63 void *header
; /* OpenFlow header. */
64 void *msg
; /* message's body */
65 struct ovs_list list_node
; /* Private list element for use by owner. */
66 enum ofpbuf_source source
; /* Source of memory allocated as 'base'. */
69 /* An initializer for a struct ofpbuf that will be initially empty and uses the
70 * space in STUB (which should be an array) as a stub. This is the initializer
71 * form of ofpbuf_use_stub().
75 * uint64_t stub[1024 / 8]; // 1 kB stub properly aligned for 64-bit data.
76 * struct ofpbuf ofpbuf = OFPBUF_STUB_INITIALIZER(stub);
78 #define OFPBUF_STUB_INITIALIZER(STUB) { \
82 .allocated = sizeof (STUB), \
85 .list_node = OVS_LIST_POISON, \
86 .source = OFPBUF_STUB, \
89 /* An initializer for a struct ofpbuf whose data starts at DATA and continues
90 * for SIZE bytes. This is appropriate for an ofpbuf that will be used to
91 * inspect existing data, without moving it around or reallocating it, and
92 * generally without modifying it at all. This is the initializer form of
95 static inline struct ofpbuf
96 ofpbuf_const_initializer(const void *data
, size_t size
)
98 return (struct ofpbuf
) {
99 .base
= CONST_CAST(void *, data
),
100 .data
= CONST_CAST(void *, data
),
105 .list_node
= OVS_LIST_POISON
,
106 .source
= OFPBUF_STACK
,
110 void ofpbuf_use_ds(struct ofpbuf
*, const struct ds
*);
111 void ofpbuf_use_stack(struct ofpbuf
*, void *, size_t);
112 void ofpbuf_use_stub(struct ofpbuf
*, void *, size_t);
113 void ofpbuf_use_const(struct ofpbuf
*, const void *, size_t);
115 void ofpbuf_init(struct ofpbuf
*, size_t);
116 void ofpbuf_uninit(struct ofpbuf
*);
117 void ofpbuf_reinit(struct ofpbuf
*, size_t);
119 struct ofpbuf
*ofpbuf_new(size_t);
120 struct ofpbuf
*ofpbuf_new_with_headroom(size_t, size_t headroom
);
121 struct ofpbuf
*ofpbuf_clone(const struct ofpbuf
*);
122 struct ofpbuf
*ofpbuf_clone_with_headroom(const struct ofpbuf
*,
124 struct ofpbuf
*ofpbuf_clone_data(const void *, size_t);
125 struct ofpbuf
*ofpbuf_clone_data_with_headroom(const void *, size_t,
127 static inline void ofpbuf_delete(struct ofpbuf
*);
129 static inline void *ofpbuf_at(const struct ofpbuf
*, size_t offset
,
131 static inline void *ofpbuf_at_assert(const struct ofpbuf
*, size_t offset
,
133 static inline void *ofpbuf_tail(const struct ofpbuf
*);
134 static inline void *ofpbuf_end(const struct ofpbuf
*);
136 void *ofpbuf_put_uninit(struct ofpbuf
*, size_t);
137 void *ofpbuf_put_zeros(struct ofpbuf
*, size_t);
138 void *ofpbuf_put(struct ofpbuf
*, const void *, size_t);
139 char *ofpbuf_put_hex(struct ofpbuf
*, const char *s
, size_t *n
);
140 void ofpbuf_reserve(struct ofpbuf
*, size_t);
141 void *ofpbuf_push_uninit(struct ofpbuf
*b
, size_t);
142 void *ofpbuf_push_zeros(struct ofpbuf
*, size_t);
143 void *ofpbuf_push(struct ofpbuf
*b
, const void *, size_t);
145 static inline size_t ofpbuf_headroom(const struct ofpbuf
*);
146 static inline size_t ofpbuf_tailroom(const struct ofpbuf
*);
147 static inline size_t ofpbuf_msgsize(const struct ofpbuf
*);
148 void ofpbuf_prealloc_headroom(struct ofpbuf
*, size_t);
149 void ofpbuf_prealloc_tailroom(struct ofpbuf
*, size_t);
150 void ofpbuf_trim(struct ofpbuf
*);
151 void ofpbuf_padto(struct ofpbuf
*, size_t);
152 void ofpbuf_shift(struct ofpbuf
*, int);
154 static inline void ofpbuf_clear(struct ofpbuf
*);
155 static inline void *ofpbuf_pull(struct ofpbuf
*, size_t);
156 static inline void *ofpbuf_try_pull(struct ofpbuf
*, size_t);
158 void *ofpbuf_steal_data(struct ofpbuf
*);
160 char *ofpbuf_to_string(const struct ofpbuf
*, size_t maxbytes
);
161 static inline struct ofpbuf
*ofpbuf_from_list(const struct ovs_list
*);
162 void ofpbuf_list_delete(struct ovs_list
*);
163 static inline bool ofpbuf_equal(const struct ofpbuf
*, const struct ofpbuf
*);
166 /* Frees memory that 'b' points to, as well as 'b' itself. */
167 static inline void ofpbuf_delete(struct ofpbuf
*b
)
175 /* If 'b' contains at least 'offset + size' bytes of data, returns a pointer to
176 * byte 'offset'. Otherwise, returns a null pointer. */
177 static inline void *ofpbuf_at(const struct ofpbuf
*b
, size_t offset
,
180 return offset
+ size
<= b
->size
? (char *) b
->data
+ offset
: NULL
;
183 /* Returns a pointer to byte 'offset' in 'b', which must contain at least
184 * 'offset + size' bytes of data. */
185 static inline void *ofpbuf_at_assert(const struct ofpbuf
*b
, size_t offset
,
188 ovs_assert(offset
+ size
<= b
->size
);
189 return ((char *) b
->data
) + offset
;
192 /* Returns a pointer to byte following the last byte of data in use in 'b'. */
193 static inline void *ofpbuf_tail(const struct ofpbuf
*b
)
195 return (char *) b
->data
+ b
->size
;
198 /* Returns a pointer to byte following the last byte allocated for use (but
199 * not necessarily in use) in 'b'. */
200 static inline void *ofpbuf_end(const struct ofpbuf
*b
)
202 return (char *) b
->base
+ b
->allocated
;
205 /* Returns the number of bytes of headroom in 'b', that is, the number of bytes
206 * of unused space in ofpbuf 'b' before the data that is in use. (Most
207 * commonly, the data in a ofpbuf is at its beginning, and thus the ofpbuf's
209 static inline size_t ofpbuf_headroom(const struct ofpbuf
*b
)
211 return (char*)b
->data
- (char*)b
->base
;
214 /* Returns the number of bytes that may be appended to the tail end of ofpbuf
215 * 'b' before the ofpbuf must be reallocated. */
216 static inline size_t ofpbuf_tailroom(const struct ofpbuf
*b
)
218 return (char*)ofpbuf_end(b
) - (char*)ofpbuf_tail(b
);
221 /* Returns the number of bytes from 'b->header' to 'b->msg', that is, the
222 * length of 'b''s header. */
224 ofpbuf_headersize(const struct ofpbuf
*b
)
226 return (char *)b
->msg
- (char *)b
->header
;
229 /* Returns the number of bytes from 'b->msg' to 'b->data + b->size', that is,
230 * the length of the used space in 'b' starting from 'msg'. */
232 ofpbuf_msgsize(const struct ofpbuf
*b
)
234 return (char *)ofpbuf_tail(b
) - (char *)b
->msg
;
237 /* Clears any data from 'b'. */
238 static inline void ofpbuf_clear(struct ofpbuf
*b
)
244 /* Removes 'size' bytes from the head end of 'b', which must contain at least
245 * 'size' bytes of data. Returns the first byte of data removed. */
246 static inline void *ofpbuf_pull(struct ofpbuf
*b
, size_t size
)
248 void *data
= b
->data
;
249 b
->data
= (char*)b
->data
+ size
;
250 b
->size
= b
->size
- size
;
254 /* If 'b' has at least 'size' bytes of data, removes that many bytes from the
255 * head end of 'b' and returns the first byte removed. Otherwise, returns a
256 * null pointer without modifying 'b'. */
257 static inline void *ofpbuf_try_pull(struct ofpbuf
*b
, size_t size
)
259 return b
->size
>= size
? ofpbuf_pull(b
, size
) : NULL
;
262 static inline struct ofpbuf
*ofpbuf_from_list(const struct ovs_list
*list
)
264 return CONTAINER_OF(list
, struct ofpbuf
, list_node
);
267 static inline bool ofpbuf_equal(const struct ofpbuf
*a
, const struct ofpbuf
*b
)
269 return a
->size
== b
->size
&&
270 memcmp(a
->data
, b
->data
, a
->size
) == 0;
277 #endif /* ofpbuf.h */