+static int
+vconn_stream_recv(struct vconn *vconn, struct ofpbuf **bufferp)
+{
+ struct vconn_stream *s = vconn_stream_cast(vconn);
+ const struct ofp_header *oh;
+ int rx_len;
+
+ /* Allocate new receive buffer if we don't have one. */
+ if (s->rxbuf == NULL) {
+ s->rxbuf = ofpbuf_new(1564);
+ }
+
+ /* Read ofp_header. */
+ if (s->rxbuf->size < sizeof(struct ofp_header)) {
+ int retval = vconn_stream_recv__(s, sizeof(struct ofp_header));
+ if (retval) {
+ return retval;
+ }
+ }
+
+ /* Read payload. */
+ oh = s->rxbuf->data;
+ rx_len = ntohs(oh->length);
+ if (rx_len < sizeof(struct ofp_header)) {
+ VLOG_ERR_RL(&rl, "received too-short ofp_header (%d bytes)", rx_len);
+ return EPROTO;
+ } else if (s->rxbuf->size < rx_len) {
+ int retval = vconn_stream_recv__(s, rx_len);
+ if (retval) {
+ return retval;
+ }
+ }
+
+ s->n_packets++;
+ *bufferp = s->rxbuf;
+ s->rxbuf = NULL;
+ return 0;
+}
+