From ad67e568887f56d3b70a8225c3a476d94f70c20b Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 23 Sep 2010 14:12:09 -0700 Subject: [PATCH] learning-switch: Introduce struct for configuration. This should make extensions easier. --- lib/learning-switch.c | 39 +++++++++----------------------------- lib/learning-switch.h | 32 +++++++++++++++++++++++++++---- utilities/ovs-controller.c | 13 +++++++++---- 3 files changed, 46 insertions(+), 38 deletions(-) diff --git a/lib/learning-switch.c b/lib/learning-switch.c index 36594ac6..90749c01 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -69,35 +69,23 @@ static packet_handler_func process_switch_features; static packet_handler_func process_packet_in; static packet_handler_func process_echo_request; -/* Creates and returns a new learning switch. - * - * If 'learn_macs' is true, the new switch will learn the ports on which MAC - * addresses appear. Otherwise, the new switch will flood all packets. - * - * If 'max_idle' is nonnegative, the new switch will set up flows that expire - * after the given number of seconds (or never expire, if 'max_idle' is - * OFP_FLOW_PERMANENT). Otherwise, the new switch will process every packet. - * - * The caller may provide an ofpbuf 'default_flows' that consists of a chain of - * one or more OpenFlow messages to send to the switch at time of connection. - * Presumably these will be OFPT_FLOW_MOD requests to set up the flow table. +/* Creates and returns a new learning switch whose configuration is given by + * 'cfg'. * * 'rconn' is used to send out an OpenFlow features request. */ struct lswitch * -lswitch_create(struct rconn *rconn, bool learn_macs, - bool exact_flows, int max_idle, bool action_normal, - const struct ofpbuf *default_flows) +lswitch_create(struct rconn *rconn, const struct lswitch_config *cfg) { const struct ofpbuf *b; struct lswitch *sw; sw = xzalloc(sizeof *sw); - sw->max_idle = max_idle; + sw->max_idle = cfg->max_idle; sw->datapath_id = 0; sw->last_features_request = time_now() - 1; - sw->ml = learn_macs ? mac_learning_create() : NULL; - sw->action_normal = action_normal; - if (exact_flows) { + sw->ml = cfg->mode == LSW_LEARN ? mac_learning_create() : NULL; + sw->action_normal = cfg->mode == LSW_NORMAL; + if (cfg->exact_flows) { /* Exact match. */ sw->wildcards = 0; } else { @@ -107,11 +95,11 @@ lswitch_create(struct rconn *rconn, bool learn_macs, sw->wildcards = (OFPFW_DL_TYPE | OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK | OFPFW_NW_PROTO | OFPFW_TP_SRC | OFPFW_TP_DST); } - sw->queue = UINT32_MAX; + sw->queue = cfg->queue_id; sw->queued = rconn_packet_counter_create(); send_features_request(sw, rconn); - for (b = default_flows; b; b = b->next) { + for (b = cfg->default_flows; b; b = b->next) { queue_tx(sw, rconn, ofpbuf_clone(b)); } @@ -129,15 +117,6 @@ lswitch_destroy(struct lswitch *sw) } } -/* Sets 'queue' as the OpenFlow queue used by packets and flows set up by 'sw'. - * Specify UINT32_MAX to avoid specifying a particular queue, which is also the - * default if this function is never called for 'sw'. */ -void -lswitch_set_queue(struct lswitch *sw, uint32_t queue) -{ - sw->queue = queue; -} - /* Takes care of necessary 'sw' activity, except for receiving packets (which * the caller must do). */ void diff --git a/lib/learning-switch.h b/lib/learning-switch.h index edb31549..2ce49e61 100644 --- a/lib/learning-switch.h +++ b/lib/learning-switch.h @@ -24,10 +24,34 @@ struct ofpbuf; struct rconn; -struct lswitch *lswitch_create(struct rconn *, bool learn_macs, - bool exact_flows, int max_idle, - bool action_normal, - const struct ofpbuf *default_flows); +enum lswitch_mode { + LSW_NORMAL, /* Always use OFPP_NORMAL. */ + LSW_FLOOD, /* Always use OFPP_FLOOD. */ + LSW_LEARN /* Learn MACs at controller. */ +}; + +struct lswitch_config { + enum lswitch_mode mode; + + /* Set up only exact-match flows? */ + bool exact_flows; + + /* <0: Process every packet at the controller. + * >=0: Expire flows after they are unused for 'max_idle' seconds. + * OFP_FLOW_PERMANENT: Set up permanent flows. */ + int max_idle; + + /* Optionally, a chain of one or more OpenFlow messages to send to the + * switch at time of connection. Presumably these will be OFPT_FLOW_MOD + * requests to set up the flow table. */ + const struct ofpbuf *default_flows; + + /* The OpenFlow queue used by packets and flows set up by 'sw'. Use + * UINT32_MAX to avoid specifying a particular queue. */ + uint32_t queue_id; +}; + +struct lswitch *lswitch_create(struct rconn *, const struct lswitch_config *); void lswitch_set_queue(struct lswitch *sw, uint32_t queue); void lswitch_run(struct lswitch *); void lswitch_wait(struct lswitch *); diff --git a/utilities/ovs-controller.c b/utilities/ovs-controller.c index b1b4f0a8..9892abe4 100644 --- a/utilities/ovs-controller.c +++ b/utilities/ovs-controller.c @@ -215,13 +215,18 @@ main(int argc, char *argv[]) static void new_switch(struct switch_ *sw, struct vconn *vconn) { + struct lswitch_config cfg; + sw->rconn = rconn_create(60, 0); rconn_connect_unreliably(sw->rconn, vconn, NULL); - sw->lswitch = lswitch_create(sw->rconn, learn_macs, exact_flows, - set_up_flows ? max_idle : -1, - action_normal, default_flows.head); - lswitch_set_queue(sw->lswitch, queue_id); + cfg.mode = (action_normal ? LSW_NORMAL + : learn_macs ? LSW_LEARN + : LSW_FLOOD); + cfg.max_idle = set_up_flows ? max_idle : -1; + cfg.default_flows = default_flows.head; + cfg.queue_id = queue_id; + sw->lswitch = lswitch_create(sw->rconn, &cfg); } static int -- 2.30.2