vswitch: Eliminate OpenFlow connection to ofproto.
authorBen Pfaff <blp@nicira.com>
Mon, 9 Mar 2009 22:37:16 +0000 (15:37 -0700)
committerBen Pfaff <blp@nicira.com>
Mon, 9 Mar 2009 22:49:38 +0000 (15:49 -0700)
The vswitch interface to the ofproto is now entirely a functional
interface, instead of going partially over an OpenFlow connection that
"loops back" to the ofproto via a socketpair.  So this commit drops
the code that connects and maintains that connection.

vswitchd/bridge.c

index 38e8550f636cb70ee6107f7adca301ed4e3047c0..16382aff7ee18279150e8f8e54851d563b046358 100644 (file)
@@ -57,7 +57,6 @@
 #include "poll-loop.h"
 #include "port-array.h"
 #include "process.h"
-#include "rconn.h"
 #include "secchan/ofproto.h"
 #include "socket-util.h"
 #include "stp.h"
@@ -148,7 +147,6 @@ struct port {
 struct bridge {
     struct list node;           /* Node in global list of bridges. */
     char *name;                 /* User-specified arbitrary name. */
-    struct rconn_packet_counter *txqlen; /* # queued to send on 'rconn'. */
     struct mac_learning *ml;    /* MAC learning table, or null not to learn. */
     int flow_idle_time;         /* Idle time for flows we set up. */
     bool sent_config_request;   /* Successfully sent config request? */
@@ -161,7 +159,6 @@ struct bridge {
 
     /* OpenFlow switch processing. */
     struct ofproto *ofproto;    /* OpenFlow switch. */
-    struct rconn *rconn;        /* Connection to switch. */
 
     /* Kernel datapath information. */
     struct dpif dpif;           /* Kernel datapath. */
@@ -200,13 +197,11 @@ static int if_up(const char *netdev_name);
 static int bridge_run_one(struct bridge *);
 static void bridge_reconfigure_one(struct bridge *);
 static void bridge_get_all_ifaces(const struct bridge *, struct svec *ifaces);
-static bool bridge_is_backlogged(const struct bridge *);
 static void bridge_fetch_dp_ifaces(struct bridge *);
 static void bridge_flush(struct bridge *);
 static void bridge_pick_local_hw_addr(struct bridge *,
                                       struct iface *local_iface);
 
-static void bridge_process_msg(struct bridge *, struct ofpbuf *);
 static void revalidate_flow(struct bridge *, struct ft_flow *);
 
 static void flowstats_run(struct bridge *);
@@ -563,10 +558,6 @@ bridge_wait(void)
             continue;
         }
 
-        rconn_run_wait(br->rconn);
-        if (!bridge_is_backlogged(br)) {
-            rconn_recv_wait(br->rconn);
-        }
         if (br->ml) {
             mac_learning_wait(br->ml);
         }
@@ -628,14 +619,11 @@ bridge_create(const char *name)
     }
 
     br->name = xstrdup(name);
-    br->txqlen = rconn_packet_counter_create();
     br->ml = mac_learning_create();
     br->flow_idle_time = 5;
     br->sent_config_request = false;
     eth_addr_random(br->default_ea);
 
-    br->rconn = rconn_create(30, 1);
-
     port_array_init(&br->ifaces);
 
     br->ft = ft_create();
@@ -649,39 +637,6 @@ bridge_create(const char *name)
     return br;
 }
 
-static void
-connect_ofproto(struct bridge *br)
-{
-    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
-    int sockets[2];
-    int i;
-
-    if (ofproto_is_alive(br->ofproto)) {
-        return;
-    }
-
-    VLOG_INFO_RL(&rl, "%s: connecting to internal OpenFlow switch", br->name);
-    if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sockets)) {
-        VLOG_ERR("%s: failed to create socket pair: %s",
-                 br->name, strerror(errno));
-        /* XXX need to wait before trying again */
-        return;
-    }
-
-    /* Connect the ofproto to one end of the socketpair, and ourselves to the
-     * other end. */
-    for (i = 0; i < 2; i++) {
-        char *name = xasprintf("fd:%d", sockets[i]);
-        set_nonblocking(sockets[i]);
-        if (i) {
-            ofproto_set_controller(br->ofproto, name);
-        } else {
-            rconn_connect(br->rconn, name);
-        }
-        free(name);
-    }
-}
-
 static void
 bridge_destroy(struct bridge *br)
 {
@@ -699,8 +654,6 @@ bridge_destroy(struct bridge *br)
         }
         dpif_close(&br->dpif);
         ofproto_destroy(br->ofproto);
-        rconn_destroy(br->rconn);
-        rconn_packet_counter_destroy(br->txqlen);
         free(br->controller);
         ft_destroy(br->ft);
         mac_learning_destroy(br->ml);
@@ -744,49 +697,17 @@ if_up(const char *netdev_name)
     return retval;
 }
 
-static void
-send_set_config_request(struct bridge *br)
-{
-    struct ofp_switch_config *osc;
-    struct ofpbuf *msg;
-
-    osc = make_openflow(sizeof *osc, OFPT_SET_CONFIG, &msg);
-    osc->flags = htons(OFPC_SEND_FLOW_EXP | OFPC_FRAG_NORMAL);
-    osc->miss_send_len = htons(OFP_DEFAULT_MISS_SEND_LEN);
-    if (!rconn_send_with_limit(br->rconn, msg, br->txqlen, INT_MAX)) {
-        br->sent_config_request = true;
-    }
-}
-
 static int
 bridge_run_one(struct bridge *br)
 {
-    int iteration;
     int error;
 
     if (br->controller) {
         return ofproto_run(br->ofproto);
     }
 
-    rconn_run(br->rconn);
-
-    if (rconn_is_connected(br->rconn)) {
-        if (!br->sent_config_request) {
-            send_set_config_request(br);
-        }
-    }
-
     /* Now do the things that may want to revalidate flows. */
-    for (iteration = 0; iteration < 50 && !bridge_is_backlogged(br);
-         iteration++) {
-        struct ofpbuf *msg = rconn_recv(br->rconn);
-        if (!msg) {
-            break;
-        }
-
-        bridge_process_msg(br, msg);
-        ofpbuf_delete(msg);
-    }
+    error = ofproto_run(br->ofproto);
     hmap_shrink(&br->ft->flows);
     if (br->ml) {
         mac_learning_run(br->ml, &br->revalidate_set);
@@ -795,10 +716,6 @@ bridge_run_one(struct bridge *br)
     bond_run(br);
     brstp_run(br);
 
-    /* Start or restart switch if necessary. */
-    connect_ofproto(br);
-    error = ofproto_run(br->ofproto);
-
     /* Now revalidate any flows that need it. */
     if (br->flush || !tag_set_is_empty(&br->revalidate_set)) {
         struct ft_flow *f, *next;
@@ -1034,12 +951,6 @@ bridge_get_all_ifaces(const struct bridge *br, struct svec *ifaces)
     assert(svec_is_unique(ifaces));
 }
 
-static bool
-bridge_is_backlogged(const struct bridge *br)
-{
-    return br->txqlen->n >= 100;
-}
-
 /* For robustness, in case the administrator moves around datapath ports behind
  * our back, we re-check all the datapath port numbers here. */
 static void
@@ -1103,43 +1014,6 @@ bridge_idle_time(const struct bridge *br)
 \f
 /* Bridge packet processing functions. */
 
-typedef void packet_handler_func(struct bridge *, void *);
-static packet_handler_func process_echo_request;
-
-static void
-bridge_process_msg(struct bridge *br, struct ofpbuf *msg)
-{
-    struct ofp_header *oh = msg->data;
-    switch (oh->type) {
-    case OFPT_ECHO_REQUEST:
-        process_echo_request(br, msg->data);
-        break;
-    default:
-        if (VLOG_IS_DBG_ENABLED()) {
-            static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(30, 300);
-            char *p = ofp_to_string(msg->data, msg->size, 2);
-            VLOG_DBG_RL(&rl, "bridge %s: OpenFlow packet ignored: %s",
-                        br->name, p);
-            free(p);
-        }
-        break;
-    }
-}
-
-static void
-queue_tx(struct bridge *br, struct ofpbuf *msg)
-{
-    int retval;
-    update_openflow_length(msg);
-    retval = rconn_send(br->rconn, msg, br->txqlen);
-    if (retval) {
-        ofpbuf_delete(msg);
-        /* No point in logging: rconn_send() only fails due to disconnection,
-         * and disconnecting from the switch will cause all kinds of log
-         * messages anyhow.  */
-    }
-}
-
 static struct bond_entry *
 lookup_bond_entry(const struct port *port, const uint8_t mac[ETH_ADDR_LEN])
 {
@@ -1844,13 +1718,6 @@ revalidate_flow(struct bridge *br, struct ft_flow *f)
     process_flow(br, &f->flow, NULL);
 }
 
-static void
-process_echo_request(struct bridge *br, void *rq_)
-{
-    struct ofp_header *rq = rq_;
-    queue_tx(br, make_echo_reply(rq));
-}
-
 /* Careful: 'opp' is in host byte order and opp->port_no is an OFP port
  * number. */
 static void
@@ -2225,8 +2092,7 @@ request_flow_stats(struct bridge *br)
 static void
 flowstats_run(struct bridge *br)
 {
-    if (rconn_is_connected(br->rconn)
-        && time_now() >= br->next_stats_request) {
+    if (time_now() >= br->next_stats_request) {
         request_flow_stats(br);
         br->next_stats_request = time_now() + 10;
     }
@@ -2235,9 +2101,7 @@ flowstats_run(struct bridge *br)
 static void
 flowstats_wait(struct bridge *br)
 {
-    if (rconn_is_connected(br->rconn)) {
-        poll_timer_wait((br->next_stats_request - time_now()) * 1000);
-    }
+    poll_timer_wait((br->next_stats_request - time_now()) * 1000);
 }
 \f
 /* Port functions. */