From daa68e9f291f94fb40a58843ddbe8a9cc8c99ec4 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 10 Nov 2010 14:51:49 -0800 Subject: [PATCH] ofp-util: Make make_flow_mod() take cls_rule instead of struct flow. This reduces code duplication, by eliminating a function that translates from "struct flow" to "struct ofp_match" in favor of the existing function ofputil_cls_rule_to_match(). It also allows the caller to specify the desired priority (as part of the cls_rule). --- lib/learning-switch.c | 21 ++++++++++++--------- lib/ofp-util.c | 33 +++++++++++---------------------- lib/ofp-util.h | 8 ++++---- 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/lib/learning-switch.c b/lib/learning-switch.c index 63edc0fb8..ef715dbab 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -24,6 +24,7 @@ #include #include "byte-order.h" +#include "classifier.h" #include "flow.h" #include "hmap.h" #include "mac-learning.h" @@ -57,7 +58,7 @@ struct lswitch { unsigned long long int datapath_id; time_t last_features_request; struct mac_learning *ml; /* NULL to act as hub instead of switch. */ - uint32_t wildcards; /* Wildcards to apply to flows. */ + struct flow_wildcards wc; /* Wildcards to apply to flows. */ bool action_normal; /* Use OFPP_NORMAL? */ /* Queue distribution. */ @@ -97,15 +98,16 @@ lswitch_create(struct rconn *rconn, const struct lswitch_config *cfg) sw->last_features_request = time_now() - 1; 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 { + + flow_wildcards_init_exact(&sw->wc); + if (!cfg->exact_flows) { /* We cannot wildcard all fields. * We need in_port to detect moves. * We need both SA and DA to do learning. */ - sw->wildcards = (OFPFW_DL_TYPE | OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK - | OFPFW_NW_PROTO | OFPFW_TP_SRC | OFPFW_TP_DST); + sw->wc.wildcards = (FWW_DL_TYPE | FWW_NW_PROTO + | FWW_TP_SRC | FWW_TP_DST); + sw->wc.nw_src_mask = htonl(0); + sw->wc.nw_dst_mask = htonl(0); } sw->default_queue = cfg->default_queue; @@ -423,14 +425,15 @@ process_packet_in(struct lswitch *sw, struct rconn *rconn, void *opi_) if (sw->max_idle >= 0 && (!sw->ml || out_port != OFPP_FLOOD)) { struct ofpbuf *buffer; struct ofp_flow_mod *ofm; + struct cls_rule rule; /* The output port is known, or we always flood everything, so add a * new flow. */ - buffer = make_add_flow(&flow, ntohl(opi->buffer_id), + cls_rule_init(&flow, &sw->wc, 0, &rule); + buffer = make_add_flow(&rule, ntohl(opi->buffer_id), sw->max_idle, actions_len); ofpbuf_put(buffer, actions, actions_len); ofm = buffer->data; - ofm->match.wildcards = htonl(sw->wildcards); queue_tx(sw, rconn, buffer); /* If the switch didn't buffer the packet, we need to send a copy. */ diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 82797d4d5..208eabb5c 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -328,7 +328,8 @@ update_openflow_length(struct ofpbuf *buffer) } struct ofpbuf * -make_flow_mod(uint16_t command, const struct flow *flow, size_t actions_len) +make_flow_mod(uint16_t command, const struct cls_rule *rule, + size_t actions_len) { struct ofp_flow_mod *ofm; size_t size = sizeof *ofm + actions_len; @@ -338,29 +339,17 @@ make_flow_mod(uint16_t command, const struct flow *flow, size_t actions_len) ofm->header.type = OFPT_FLOW_MOD; ofm->header.length = htons(size); ofm->cookie = 0; - ofm->match.wildcards = htonl(0); - ofm->match.in_port = htons(flow->in_port == ODPP_LOCAL ? OFPP_LOCAL - : flow->in_port); - memcpy(ofm->match.dl_src, flow->dl_src, sizeof ofm->match.dl_src); - memcpy(ofm->match.dl_dst, flow->dl_dst, sizeof ofm->match.dl_dst); - ofm->match.dl_vlan = flow->dl_vlan; - ofm->match.dl_vlan_pcp = flow->dl_vlan_pcp; - ofm->match.dl_type = flow->dl_type; - ofm->match.nw_src = flow->nw_src; - ofm->match.nw_dst = flow->nw_dst; - ofm->match.nw_proto = flow->nw_proto; - ofm->match.nw_tos = flow->nw_tos; - ofm->match.tp_src = flow->tp_src; - ofm->match.tp_dst = flow->tp_dst; + ofm->priority = htons(MIN(rule->priority, UINT16_MAX)); + ofputil_cls_rule_to_match(rule, NXFF_OPENFLOW10, &ofm->match); ofm->command = htons(command); return out; } struct ofpbuf * -make_add_flow(const struct flow *flow, uint32_t buffer_id, +make_add_flow(const struct cls_rule *rule, uint32_t buffer_id, uint16_t idle_timeout, size_t actions_len) { - struct ofpbuf *out = make_flow_mod(OFPFC_ADD, flow, actions_len); + struct ofpbuf *out = make_flow_mod(OFPFC_ADD, rule, actions_len); struct ofp_flow_mod *ofm = out->data; ofm->idle_timeout = htons(idle_timeout); ofm->hard_timeout = htons(OFP_FLOW_PERMANENT); @@ -369,16 +358,16 @@ make_add_flow(const struct flow *flow, uint32_t buffer_id, } struct ofpbuf * -make_del_flow(const struct flow *flow) +make_del_flow(const struct cls_rule *rule) { - struct ofpbuf *out = make_flow_mod(OFPFC_DELETE_STRICT, flow, 0); + struct ofpbuf *out = make_flow_mod(OFPFC_DELETE_STRICT, rule, 0); struct ofp_flow_mod *ofm = out->data; ofm->out_port = htons(OFPP_NONE); return out; } struct ofpbuf * -make_add_simple_flow(const struct flow *flow, +make_add_simple_flow(const struct cls_rule *rule, uint32_t buffer_id, uint16_t out_port, uint16_t idle_timeout) { @@ -386,14 +375,14 @@ make_add_simple_flow(const struct flow *flow, struct ofp_action_output *oao; struct ofpbuf *buffer; - buffer = make_add_flow(flow, buffer_id, idle_timeout, sizeof *oao); + buffer = make_add_flow(rule, buffer_id, idle_timeout, sizeof *oao); oao = ofpbuf_put_zeros(buffer, sizeof *oao); oao->type = htons(OFPAT_OUTPUT); oao->len = htons(sizeof *oao); oao->port = htons(out_port); return buffer; } else { - return make_add_flow(flow, buffer_id, idle_timeout, 0); + return make_add_flow(rule, buffer_id, idle_timeout, 0); } } diff --git a/lib/ofp-util.h b/lib/ofp-util.h index 02a84decb..fdca005fb 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -56,12 +56,12 @@ void *put_openflow(size_t openflow_len, uint8_t type, struct ofpbuf *); void *put_openflow_xid(size_t openflow_len, uint8_t type, ovs_be32 xid, struct ofpbuf *); void update_openflow_length(struct ofpbuf *); -struct ofpbuf *make_flow_mod(uint16_t command, const struct flow *, +struct ofpbuf *make_flow_mod(uint16_t command, const struct cls_rule *, size_t actions_len); -struct ofpbuf *make_add_flow(const struct flow *, uint32_t buffer_id, +struct ofpbuf *make_add_flow(const struct cls_rule *, uint32_t buffer_id, uint16_t max_idle, size_t actions_len); -struct ofpbuf *make_del_flow(const struct flow *); -struct ofpbuf *make_add_simple_flow(const struct flow *, +struct ofpbuf *make_del_flow(const struct cls_rule *); +struct ofpbuf *make_add_simple_flow(const struct cls_rule *, uint32_t buffer_id, uint16_t out_port, uint16_t max_idle); struct ofpbuf *make_packet_in(uint32_t buffer_id, uint16_t in_port, -- 2.43.0