Use the IANA-assigned ports for OpenFlow and OVSDB.
[cascardo/ovs.git] / lib / vconn.c
index 8a06485..a59829d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@
 #include "poll-loop.h"
 #include "random.h"
 #include "util.h"
-#include "vlog.h"
+#include "openvswitch/vlog.h"
 #include "socket-util.h"
 
 VLOG_DEFINE_THIS_MODULE(vconn);
@@ -138,10 +138,10 @@ vconn_usage(bool active, bool passive, bool bootstrap OVS_UNUSED)
     if (active) {
         printf("Active OpenFlow connection methods:\n");
         printf("  tcp:IP[:PORT]           "
-               "PORT (default: %d) at remote IP\n", OFP_TCP_PORT);
+               "PORT (default: %d) at remote IP\n", OFP_PORT);
 #ifdef HAVE_OPENSSL
         printf("  ssl:IP[:PORT]           "
-               "SSL PORT (default: %d) at remote IP\n", OFP_TCP_PORT);
+               "SSL PORT (default: %d) at remote IP\n", OFP_PORT);
 #endif
         printf("  unix:FILE               Unix domain socket named FILE\n");
     }
@@ -150,11 +150,11 @@ vconn_usage(bool active, bool passive, bool bootstrap OVS_UNUSED)
         printf("Passive OpenFlow connection methods:\n");
         printf("  ptcp:[PORT][:IP]        "
                "listen to TCP PORT (default: %d) on IP\n",
-               OFP_TCP_PORT);
+               OFP_PORT);
 #ifdef HAVE_OPENSSL
         printf("  pssl:[PORT][:IP]        "
                "listen for SSL on PORT (default: %d) on IP\n",
-               OFP_TCP_PORT);
+               OFP_PORT);
 #endif
         printf("  punix:FILE              "
                "listen on Unix domain socket FILE\n");
@@ -252,7 +252,7 @@ vconn_open(const char *name, uint32_t allowed_versions, uint8_t dscp,
     }
 
     /* Success. */
-    ovs_assert(vconn->state != VCS_CONNECTING || vconn->class->connect);
+    ovs_assert(vconn->state != VCS_CONNECTING || vconn->vclass->connect);
     *vconnp = vconn;
     return 0;
 
@@ -272,8 +272,8 @@ vconn_run(struct vconn *vconn)
         vconn_connect(vconn);
     }
 
-    if (vconn->class->run) {
-        (vconn->class->run)(vconn);
+    if (vconn->vclass->run) {
+        (vconn->vclass->run)(vconn);
     }
 }
 
@@ -288,11 +288,20 @@ vconn_run_wait(struct vconn *vconn)
         vconn_connect_wait(vconn);
     }
 
-    if (vconn->class->run_wait) {
-        (vconn->class->run_wait)(vconn);
+    if (vconn->vclass->run_wait) {
+        (vconn->vclass->run_wait)(vconn);
     }
 }
 
+/* Returns 0 if 'vconn' is healthy (connecting or connected), a positive errno
+ * value if the connection died abnormally (connection failed or aborted), or
+ * EOF if the connection was closed in a normal way. */
+int
+vconn_get_status(const struct vconn *vconn)
+{
+    return vconn->error == EAGAIN ? 0 : vconn->error;
+}
+
 int
 vconn_open_block(const char *name, uint32_t allowed_versions, uint8_t dscp,
                  struct vconn **vconnp)
@@ -322,7 +331,7 @@ vconn_close(struct vconn *vconn)
 {
     if (vconn != NULL) {
         char *name = vconn->name;
-        (vconn->class->close)(vconn);
+        (vconn->vclass->close)(vconn);
         free(name);
     }
 }
@@ -350,39 +359,6 @@ vconn_set_allowed_versions(struct vconn *vconn, uint32_t allowed_versions)
     vconn->allowed_versions = allowed_versions;
 }
 
-/* Returns the IP address of the peer, or 0 if the peer is not connected over
- * an IP-based protocol or if its IP address is not yet known. */
-ovs_be32
-vconn_get_remote_ip(const struct vconn *vconn)
-{
-    return vconn->remote_ip;
-}
-
-/* Returns the transport port of the peer, or 0 if the connection does not
- * contain a port or if the port is not yet known. */
-ovs_be16
-vconn_get_remote_port(const struct vconn *vconn)
-{
-    return vconn->remote_port;
-}
-
-/* Returns the IP address used to connect to the peer, or 0 if the
- * connection is not an IP-based protocol or if its IP address is not
- * yet known. */
-ovs_be32
-vconn_get_local_ip(const struct vconn *vconn)
-{
-    return vconn->local_ip;
-}
-
-/* Returns the transport port used to connect to the peer, or 0 if the
- * connection does not contain a port or if the port is not yet known. */
-ovs_be16
-vconn_get_local_port(const struct vconn *vconn)
-{
-    return vconn->local_port;
-}
-
 /* Returns the OpenFlow version negotiated with the peer, or -1 if version
  * negotiation is not yet complete.
  *
@@ -418,7 +394,7 @@ vconn_set_recv_any_version(struct vconn *vconn)
 static void
 vcs_connecting(struct vconn *vconn)
 {
-    int retval = (vconn->class->connect)(vconn);
+    int retval = (vconn->vclass->connect)(vconn);
     ovs_assert(retval != EINPROGRESS);
     if (!retval) {
         vconn->state = VCS_SEND_HELLO;
@@ -596,7 +572,7 @@ vconn_connect(struct vconn *vconn)
             return vconn->error;
 
         default:
-            NOT_REACHED();
+            OVS_NOT_REACHED();
         }
     } while (vconn->state != last_state);
 
@@ -631,11 +607,25 @@ vconn_recv(struct vconn *vconn, struct ofpbuf **msgp)
                     type != OFPTYPE_ERROR &&
                     type != OFPTYPE_ECHO_REQUEST &&
                     type != OFPTYPE_ECHO_REPLY)) {
+                struct ofpbuf *reply;
+
                 VLOG_ERR_RL(&bad_ofmsg_rl, "%s: received OpenFlow version "
                             "0x%02"PRIx8" != expected %02x",
                             vconn->name, oh->version, vconn->version);
+
+                /* Send a "bad version" reply, if we can. */
+                reply = ofperr_encode_reply(OFPERR_OFPBRC_BAD_VERSION, oh);
+                retval = vconn_send(vconn, reply);
+                if (retval) {
+                    VLOG_INFO_RL(&bad_ofmsg_rl,
+                                 "%s: failed to queue error reply (%s)",
+                                 vconn->name, ovs_strerror(retval));
+                    ofpbuf_delete(reply);
+                }
+
+                /* Suppress the received message, as if it had not arrived. */
+                retval = EAGAIN;
                 ofpbuf_delete(msg);
-                retval = EPROTO;
             }
         }
     }
@@ -647,7 +637,7 @@ vconn_recv(struct vconn *vconn, struct ofpbuf **msgp)
 static int
 do_recv(struct vconn *vconn, struct ofpbuf **msgp)
 {
-    int retval = (vconn->class->recv)(vconn, msgp);
+    int retval = (vconn->vclass->recv)(vconn, msgp);
     if (!retval) {
         COVERAGE_INC(vconn_received);
         if (VLOG_IS_DBG_ENABLED()) {
@@ -689,10 +679,10 @@ do_send(struct vconn *vconn, struct ofpbuf *msg)
     ofpmsg_update_length(msg);
     if (!VLOG_IS_DBG_ENABLED()) {
         COVERAGE_INC(vconn_sent);
-        retval = (vconn->class->send)(vconn, msg);
+        retval = (vconn->vclass->send)(vconn, msg);
     } else {
         char *s = ofp_to_string(msg->data, msg->size, 1);
-        retval = (vconn->class->send)(vconn, msg);
+        retval = (vconn->vclass->send)(vconn, msg);
         if (retval != EAGAIN) {
             VLOG_DBG_RL(&ofmsg_rl, "%s: sent (%s): %s",
                         vconn->name, ovs_strerror(retval), s);
@@ -888,7 +878,7 @@ vconn_transact_noreply(struct vconn *vconn, struct ofpbuf *request,
  * All of the requests on 'requests' are always destroyed, regardless of the
  * return value. */
 int
-vconn_transact_multiple_noreply(struct vconn *vconn, struct list *requests,
+vconn_transact_multiple_noreply(struct vconn *vconn, struct ovs_list *requests,
                                 struct ofpbuf **replyp)
 {
     struct ofpbuf *request, *next;
@@ -935,7 +925,7 @@ vconn_wait(struct vconn *vconn, enum vconn_wait_type wait)
         poll_immediate_wake();
         return;
     }
-    (vconn->class->wait)(vconn, wait);
+    (vconn->vclass->wait)(vconn, wait);
 }
 
 void
@@ -1057,7 +1047,7 @@ pvconn_close(struct pvconn *pvconn)
 {
     if (pvconn != NULL) {
         char *name = pvconn->name;
-        (pvconn->class->close)(pvconn);
+        (pvconn->pvclass->close)(pvconn);
         free(name);
     }
 }
@@ -1075,12 +1065,12 @@ pvconn_close(struct pvconn *pvconn)
 int
 pvconn_accept(struct pvconn *pvconn, struct vconn **new_vconn)
 {
-    int retval = (pvconn->class->accept)(pvconn, new_vconn);
+    int retval = (pvconn->pvclass->accept)(pvconn, new_vconn);
     if (retval) {
         *new_vconn = NULL;
     } else {
         ovs_assert((*new_vconn)->state != VCS_CONNECTING
-                   || (*new_vconn)->class->connect);
+                   || (*new_vconn)->vclass->connect);
     }
     return retval;
 }
@@ -1088,7 +1078,7 @@ pvconn_accept(struct pvconn *pvconn, struct vconn **new_vconn)
 void
 pvconn_wait(struct pvconn *pvconn)
 {
-    (pvconn->class->wait)(pvconn);
+    (pvconn->pvclass->wait)(pvconn);
 }
 
 /* Initializes 'vconn' as a new vconn named 'name', implemented via 'class'.
@@ -1113,7 +1103,7 @@ vconn_init(struct vconn *vconn, const struct vconn_class *class,
            int connect_status, const char *name, uint32_t allowed_versions)
 {
     memset(vconn, 0, sizeof *vconn);
-    vconn->class = class;
+    vconn->vclass = class;
     vconn->state = (connect_status == EAGAIN ? VCS_CONNECTING
                     : !connect_status ? VCS_SEND_HELLO
                     : VCS_DISCONNECTED);
@@ -1123,35 +1113,11 @@ vconn_init(struct vconn *vconn, const struct vconn_class *class,
     ovs_assert(vconn->state != VCS_CONNECTING || class->connect);
 }
 
-void
-vconn_set_remote_ip(struct vconn *vconn, ovs_be32 ip)
-{
-    vconn->remote_ip = ip;
-}
-
-void
-vconn_set_remote_port(struct vconn *vconn, ovs_be16 port)
-{
-    vconn->remote_port = port;
-}
-
-void
-vconn_set_local_ip(struct vconn *vconn, ovs_be32 ip)
-{
-    vconn->local_ip = ip;
-}
-
-void
-vconn_set_local_port(struct vconn *vconn, ovs_be16 port)
-{
-    vconn->local_port = port;
-}
-
 void
 pvconn_init(struct pvconn *pvconn, const struct pvconn_class *class,
             const char *name, uint32_t allowed_versions)
 {
-    pvconn->class = class;
+    pvconn->pvclass = class;
     pvconn->name = xstrdup(name);
     pvconn->allowed_versions = allowed_versions;
 }