if (passive) {
printf("Passive OpenFlow connection methods:\n");
- printf(" ptcp:[PORT] "
- "listen to TCP PORT (default: %d)\n",
+ printf(" ptcp:[PORT][:IP] "
+ "listen to TCP PORT (default: %d) on IP\n",
OFP_TCP_PORT);
#ifdef HAVE_OPENSSL
- printf(" pssl:[PORT] "
- "listen for SSL on PORT (default: %d)\n",
+ printf(" pssl:[PORT][:IP] "
+ "listen for SSL on PORT (default: %d) on IP\n",
OFP_SSL_PORT);
#endif
printf(" punix:FILE "
if (retval != EAGAIN) {
vconn->state = VCS_DISCONNECTED;
- vconn->error = retval;
+ vconn->error = retval == EOF ? ECONNRESET : retval;
}
}
static int
do_recv(struct vconn *vconn, struct ofpbuf **msgp)
{
- int retval;
-
-again:
- retval = (vconn->class->recv)(vconn, msgp);
+ int retval = (vconn->class->recv)(vconn, msgp);
if (!retval) {
struct ofp_header *oh;
&& oh->type != OFPT_VENDOR)
{
if (vconn->version < 0) {
- if (oh->type == OFPT_PACKET_IN
- || oh->type == OFPT_FLOW_EXPIRED
- || oh->type == OFPT_PORT_STATUS) {
- /* The kernel datapath is stateless and doesn't really
- * support version negotiation, so it can end up sending
- * these asynchronous message before version negotiation
- * is complete. Just ignore them.
- *
- * (After we move OFPT_PORT_STATUS messages from the kernel
- * into secchan, we won't get those here, since secchan
- * does proper version negotiation.) */
- ofpbuf_delete(*msgp);
- goto again;
- }
VLOG_ERR_RL(&bad_ofmsg_rl,
"%s: received OpenFlow message type %"PRIu8" "
"before version negotiation complete",
break;
default:
- VLOG_WARN_RL(&bad_ofmsg_rl, "unknown action type %"PRIu16, a->type);
+ VLOG_WARN_RL(&bad_ofmsg_rl, "unknown action type %"PRIu16,
+ ntohs(a->type));
return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_TYPE);
}
if (wc & OFPFW_DL_TYPE) {
m->dl_type = 0;
- /* Can't sensibly m on network or transport headers if the
+ /* Can't sensibly match on network or transport headers if the
* data link type is unknown. */
wc |= OFPFW_NW | OFPFW_TP;
m->nw_src = m->nw_dst = m->nw_proto = 0;
if (wc & OFPFW_NW_PROTO) {
m->nw_proto = 0;
- /* Can't sensibly m on transport headers if the network
+ /* Can't sensibly match on transport headers if the network
* protocol is unknown. */
wc |= OFPFW_TP;
m->tp_src = m->tp_dst = 0;
}
} else {
/* Transport layer fields will always be extracted as zeros, so we
- * can do an exact-m on those values. */
+ * can do an exact-match on those values. */
wc &= ~OFPFW_TP;
m->tp_src = m->tp_dst = 0;
}
}
} else {
/* Network and transport layer fields will always be extracted as
- * zeros, so we can do an exact-m on those values. */
+ * zeros, so we can do an exact-match on those values. */
wc &= ~(OFPFW_NW | OFPFW_TP);
m->nw_proto = m->nw_src = m->nw_dst = 0;
m->tp_src = m->tp_dst = 0;
m->wildcards = htonl(wc);
}
+/* Initializes 'vconn' as a new vconn named 'name', implemented via 'class'.
+ * The initial connection status, supplied as 'connect_status', is interpreted
+ * as follows:
+ *
+ * - 0: 'vconn' is connected. Its 'send' and 'recv' functions may be
+ * called in the normal fashion.
+ *
+ * - EAGAIN: 'vconn' is trying to complete a connection. Its 'connect'
+ * function should be called to complete the connection.
+ *
+ * - Other positive errno values indicate that the connection failed with
+ * the specified error.
+ *
+ * After calling this function, vconn_close() must be used to destroy 'vconn',
+ * otherwise resources will be leaked.
+ *
+ * The caller retains ownership of 'name'. */
void
vconn_init(struct vconn *vconn, struct vconn_class *class, int connect_status,
- const char *name, bool reconnectable)
+ const char *name)
{
vconn->class = class;
vconn->state = (connect_status == EAGAIN ? VCS_CONNECTING
vconn->local_ip = 0;
vconn->local_port = 0;
vconn->name = xstrdup(name);
- vconn->reconnectable = reconnectable;
}
void