From 69d3183d9c6588aa635fed2b6878784e6805dd4d Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 9 Mar 2009 15:37:16 -0700 Subject: [PATCH] vswitch: Eliminate OpenFlow connection to ofproto. 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 | 142 +--------------------------------------------- 1 file changed, 3 insertions(+), 139 deletions(-) diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 38e8550f..16382aff 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -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) /* 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); } /* Port functions. */ -- 2.30.2