(pvconn->class->wait)(pvconn);
}
-/* Allocates and returns the first byte of a buffer 'openflow_len' bytes long,
- * containing an OpenFlow header with the given 'type' and a random transaction
- * id. Stores the new buffer in '*bufferp'. The caller must free the buffer
- * when it is no longer needed. */
+/* XXX we should really use consecutive xids to avoid probabilistic
+ * failures. */
+static inline uint32_t
+alloc_xid(void)
+{
+ return random_uint32();
+}
+
+/* Allocates and stores in '*bufferp' a new ofpbuf with a size of
+ * 'openflow_len', starting with an OpenFlow header with the given 'type' and
+ * an arbitrary transaction id. Allocated bytes beyond the header, if any, are
+ * zeroed.
+ *
+ * The caller is responsible for freeing '*bufferp' when it is no longer
+ * needed.
+ *
+ * The OpenFlow header length is initially set to 'openflow_len'; if the
+ * message is later extended, the length should be updated with
+ * update_openflow_length() before sending.
+ *
+ * Returns the header. */
void *
-make_openflow(size_t openflow_len, uint8_t type, struct ofpbuf **bufferp)
+make_openflow(size_t openflow_len, uint8_t type, struct ofpbuf **bufferp)
{
- return make_openflow_xid(openflow_len, type, random_uint32(), bufferp);
+ *bufferp = ofpbuf_new(openflow_len);
+ return put_openflow_xid(openflow_len, type, alloc_xid(), *bufferp);
}
-/* Allocates and returns the first byte of a buffer 'openflow_len' bytes long,
- * containing an OpenFlow header with the given 'type' and transaction id
- * 'xid'. Stores the new buffer in '*bufferp'. The caller must free the
- * buffer when it is no longer needed. */
+/* Allocates and stores in '*bufferp' a new ofpbuf with a size of
+ * 'openflow_len', starting with an OpenFlow header with the given 'type' and
+ * transaction id 'xid'. Allocated bytes beyond the header, if any, are
+ * zeroed.
+ *
+ * The caller is responsible for freeing '*bufferp' when it is no longer
+ * needed.
+ *
+ * The OpenFlow header length is initially set to 'openflow_len'; if the
+ * message is later extended, the length should be updated with
+ * update_openflow_length() before sending.
+ *
+ * Returns the header. */
void *
make_openflow_xid(size_t openflow_len, uint8_t type, uint32_t xid,
struct ofpbuf **bufferp)
{
- struct ofpbuf *buffer;
+ *bufferp = ofpbuf_new(openflow_len);
+ return put_openflow_xid(openflow_len, type, xid, *bufferp);
+}
+
+/* Appends 'openflow_len' bytes to 'buffer', starting with an OpenFlow header
+ * with the given 'type' and an arbitrary transaction id. Allocated bytes
+ * beyond the header, if any, are zeroed.
+ *
+ * The OpenFlow header length is initially set to 'openflow_len'; if the
+ * message is later extended, the length should be updated with
+ * update_openflow_length() before sending.
+ *
+ * Returns the header. */
+void *
+put_openflow(size_t openflow_len, uint8_t type, struct ofpbuf *buffer)
+{
+ return put_openflow_xid(openflow_len, type, alloc_xid(), buffer);
+}
+
+/* Appends 'openflow_len' bytes to 'buffer', starting with an OpenFlow header
+ * with the given 'type' and an transaction id 'xid'. Allocated bytes beyond
+ * the header, if any, are zeroed.
+ *
+ * The OpenFlow header length is initially set to 'openflow_len'; if the
+ * message is later extended, the length should be updated with
+ * update_openflow_length() before sending.
+ *
+ * Returns the header. */
+void *
+put_openflow_xid(size_t openflow_len, uint8_t type, uint32_t xid,
+ struct ofpbuf *buffer)
+{
struct ofp_header *oh;
assert(openflow_len >= sizeof *oh);
assert(openflow_len <= UINT16_MAX);
- buffer = *bufferp = ofpbuf_new(openflow_len);
- oh = ofpbuf_put_zeros(buffer, openflow_len);
+
+ oh = ofpbuf_put_uninit(buffer, openflow_len);
oh->version = OFP_VERSION;
oh->type = type;
oh->length = htons(openflow_len);
oh->xid = xid;
+ memset(oh + 1, 0, openflow_len - sizeof *oh);
return oh;
}
struct ofp_flow_mod *ofm;
size_t size = sizeof *ofm + actions_len;
struct ofpbuf *out = ofpbuf_new(size);
- ofm = ofpbuf_put_zeros(out, size);
+ ofm = ofpbuf_put_zeros(out, sizeof *ofm);
ofm->header.version = OFP_VERSION;
ofm->header.type = OFPT_FLOW_MOD;
ofm->header.length = htons(size);
uint16_t idle_timeout)
{
struct ofp_action_output *oao;
- struct ofpbuf *buffer = make_add_flow(flow, buffer_id, idle_timeout,
- sizeof *oao);
- struct ofp_flow_mod *ofm = buffer->data;
- oao = (struct ofp_action_output *)&ofm->actions[0];
+ struct ofpbuf *buffer = make_add_flow(flow, buffer_id, idle_timeout,
+ sizeof oao);
+ oao = ofpbuf_put_zeros(buffer, sizeof *oao);
oao->type = htons(OFPAT_OUTPUT);
oao->len = htons(sizeof *oao);
oao->port = htons(out_port);