- struct ofpbuf *buf;
- int retval;
- int error;
-
- buf = ofpbuf_new(65536);
- retval = read(dpif->fd, ofpbuf_tail(buf), ofpbuf_tailroom(buf));
- if (retval < 0) {
- error = errno;
- if (error != EAGAIN) {
- VLOG_WARN_RL(&error_rl, "dp%u: read failed: %s",
- dpif->minor, strerror(error));
- }
- } else if (retval >= sizeof(struct odp_msg)) {
- struct odp_msg *msg = buf->data;
- if (msg->length <= retval) {
- buf->size += retval;
- if (VLOG_IS_DBG_ENABLED()) {
- void *payload = msg + 1;
- size_t length = buf->size - sizeof *msg;
- char *s = ofp_packet_to_string(payload, length, length);
- VLOG_DBG_RL(&dpmsg_rl, "dp%u: received %s message of length "
- "%zu on port %"PRIu16": %s", dpif->minor,
- (msg->type == _ODPL_MISS_NR ? "miss"
- : msg->type == _ODPL_ACTION_NR ? "action"
- : "<unknown>"),
- msg->length - sizeof(struct odp_msg),
- msg->port, s);
- free(s);
- }
- *bufp = buf;
- COVERAGE_INC(dpif_recv);
- return 0;
- } else {
- VLOG_WARN_RL(&error_rl, "dp%u: discarding message truncated "
- "from %"PRIu32" bytes to %d",
- dpif->minor, msg->length, retval);
- error = ERANGE;
- }
- } else if (!retval) {
- VLOG_WARN_RL(&error_rl, "dp%u: unexpected end of file", dpif->minor);
- error = EPROTO;
- } else {
- VLOG_WARN_RL(&error_rl,
- "dp%u: discarding too-short message (%d bytes)",
- dpif->minor, retval);
- error = ERANGE;