From 844dff325b1f6a6f520fce9242c85162275ab7ad Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 22 Nov 2010 10:10:14 -0800 Subject: [PATCH] flow: Remove flow_to/from_match() in favor of cls_rule_to/from_match(). The flow_from_match() and flow_to_match() functions have to deal with most of the state in a cls_rule anyhow, and this will increase in upcoming commits, to the point that we might as well just use a cls_rule anyhow. This commit therefore deletes flow_from_match() and flow_to_match(), integrating their code into cls_rule_from_match() and the new function cls_rule_to_match(), respectively. It also changes each of the functions' callers to use the new cls_rule_*() function. --- lib/classifier.c | 77 ++++++++++++++++++++++++++++++++++++++----- lib/classifier.h | 5 ++- lib/flow.c | 65 ------------------------------------ lib/flow.h | 4 --- lib/ofp-parse.c | 3 +- ofproto/ofproto.c | 9 ++--- tests/test-flows.c | 6 +++- utilities/ovs-ofctl.c | 6 ++-- 8 files changed, 83 insertions(+), 92 deletions(-) diff --git a/lib/classifier.c b/lib/classifier.c index c57c7e56..76a33dd2 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -19,6 +19,7 @@ #include #include #include +#include "byte-order.h" #include "dynamic-string.h" #include "flow.h" #include "hash.h" @@ -85,6 +86,16 @@ cls_rule_init_exact(const struct flow *flow, rule->priority = priority; } +/* Initializes 'rule' as a "catch-all" rule that matches every packet, with + * priority 'priority'. */ +void +cls_rule_init_catchall(struct cls_rule *rule, unsigned int priority) +{ + memset(&rule->flow, 0, sizeof rule->flow); + flow_wildcards_init(&rule->wc, OVSFW_ALL | FWW_ALL); + rule->priority = priority; +} + /* Converts the ofp_match in 'match' (with format 'flow_format', one of NXFF_*) * into a cls_rule in 'rule', with the given 'priority'. 'cookie' is used * when 'flow_format' is NXFF_TUN_ID_FROM_COOKIE. */ @@ -93,19 +104,67 @@ cls_rule_from_match(const struct ofp_match *match, unsigned int priority, int flow_format, uint64_t cookie, struct cls_rule *rule) { - flow_from_match(match, flow_format, cookie, &rule->flow, &rule->wc); - rule->priority = !rule->wc.wildcards ? UINT16_MAX : priority; + uint32_t wildcards = ntohl(match->wildcards) & OVSFW_ALL; + + rule->priority = !wildcards ? UINT16_MAX : priority; + + rule->flow.tun_id = 0; + if (flow_format != NXFF_TUN_ID_FROM_COOKIE) { + wildcards |= NXFW_TUN_ID; + } else { + if (!(wildcards & NXFW_TUN_ID)) { + rule->flow.tun_id = htonl(ntohll(cookie) >> 32); + } + } + if (wildcards & OFPFW_DL_DST) { + /* OpenFlow 1.0 OFPFW_DL_DST covers the whole Ethernet destination, but + * internally to OVS it excludes the multicast bit, which has to be set + * separately with FWW_ETH_MCAST. */ + wildcards |= FWW_ETH_MCAST; + } + flow_wildcards_init(&rule->wc, wildcards); + + rule->flow.nw_src = match->nw_src; + rule->flow.nw_dst = match->nw_dst; + rule->flow.in_port = (match->in_port == htons(OFPP_LOCAL) ? ODPP_LOCAL + : ntohs(match->in_port)); + rule->flow.dl_vlan = match->dl_vlan; + rule->flow.dl_vlan_pcp = match->dl_vlan_pcp; + rule->flow.dl_type = match->dl_type; + rule->flow.tp_src = match->tp_src; + rule->flow.tp_dst = match->tp_dst; + memcpy(rule->flow.dl_src, match->dl_src, ETH_ADDR_LEN); + memcpy(rule->flow.dl_dst, match->dl_dst, ETH_ADDR_LEN); + rule->flow.nw_tos = match->nw_tos; + rule->flow.nw_proto = match->nw_proto; + cls_rule_zero_wildcarded_fields(rule); } -/* Initializes 'rule' as a "catch-all" rule that matches every packet, with - * priority 'priority'. */ +/* Converts 'rule' into an OpenFlow match structure 'match' with the given flow + * format 'flow_format' (one of NXFF_*). */ void -cls_rule_init_catchall(struct cls_rule *rule, unsigned int priority) -{ - memset(&rule->flow, 0, sizeof rule->flow); - flow_wildcards_init(&rule->wc, OVSFW_ALL | FWW_ALL); - rule->priority = priority; +cls_rule_to_match(const struct cls_rule *rule, int flow_format, + struct ofp_match *match) +{ + match->wildcards = htonl(rule->wc.wildcards + & (flow_format == NXFF_TUN_ID_FROM_COOKIE + ? OVSFW_ALL : OFPFW_ALL)); + match->in_port = htons(rule->flow.in_port == ODPP_LOCAL ? OFPP_LOCAL + : rule->flow.in_port); + match->dl_vlan = rule->flow.dl_vlan; + match->dl_vlan_pcp = rule->flow.dl_vlan_pcp; + memcpy(match->dl_src, rule->flow.dl_src, ETH_ADDR_LEN); + memcpy(match->dl_dst, rule->flow.dl_dst, ETH_ADDR_LEN); + match->dl_type = rule->flow.dl_type; + match->nw_src = rule->flow.nw_src; + match->nw_dst = rule->flow.nw_dst; + match->nw_tos = rule->flow.nw_tos; + match->nw_proto = rule->flow.nw_proto; + match->tp_src = rule->flow.tp_src; + match->tp_dst = rule->flow.tp_dst; + memset(match->pad1, '\0', sizeof match->pad1); + memset(match->pad2, '\0', sizeof match->pad2); } /* For each bit or field wildcarded in 'rule', sets the corresponding bit or diff --git a/lib/classifier.h b/lib/classifier.h index ea4d6fc8..d8135e9e 100644 --- a/lib/classifier.h +++ b/lib/classifier.h @@ -70,9 +70,12 @@ void cls_rule_init(const struct flow *, const struct flow_wildcards *, unsigned int priority, struct cls_rule *); void cls_rule_init_exact(const struct flow *, unsigned int priority, struct cls_rule *); +void cls_rule_init_catchall(struct cls_rule *, unsigned int priority); + void cls_rule_from_match(const struct ofp_match *, unsigned int priority, int flow_format, uint64_t cookie, struct cls_rule *); -void cls_rule_init_catchall(struct cls_rule *, unsigned int priority); +void cls_rule_to_match(const struct cls_rule *, int flow_format, + struct ofp_match *); void cls_rule_zero_wildcarded_fields(struct cls_rule *); diff --git a/lib/flow.c b/lib/flow.c index a5995854..7c3ad511 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -250,71 +250,6 @@ flow_extract_stats(const struct flow *flow, struct ofpbuf *packet, stats->n_packets = 1; } -/* Extract 'flow' with 'wildcards' into the OpenFlow match structure - * 'match'. 'flow_format' should be one of NXFF_*. */ -void -flow_to_match(const struct flow *flow, uint32_t wildcards, - int flow_format, struct ofp_match *match) -{ - wildcards &= (flow_format == NXFF_TUN_ID_FROM_COOKIE ? OVSFW_ALL - : OFPFW_ALL); - match->wildcards = htonl(wildcards); - - match->in_port = htons(flow->in_port == ODPP_LOCAL ? OFPP_LOCAL - : flow->in_port); - match->dl_vlan = flow->dl_vlan; - match->dl_vlan_pcp = flow->dl_vlan_pcp; - memcpy(match->dl_src, flow->dl_src, ETH_ADDR_LEN); - memcpy(match->dl_dst, flow->dl_dst, ETH_ADDR_LEN); - match->dl_type = flow->dl_type; - match->nw_src = flow->nw_src; - match->nw_dst = flow->nw_dst; - match->nw_tos = flow->nw_tos; - match->nw_proto = flow->nw_proto; - match->tp_src = flow->tp_src; - match->tp_dst = flow->tp_dst; - memset(match->pad1, '\0', sizeof match->pad1); - memset(match->pad2, '\0', sizeof match->pad2); -} - -void -flow_from_match(const struct ofp_match *match, int flow_format, - ovs_be64 cookie, struct flow *flow, - struct flow_wildcards *wc) -{ - uint32_t wildcards = ntohl(match->wildcards) & OVSFW_ALL; - - flow->tun_id = 0; - if (flow_format != NXFF_TUN_ID_FROM_COOKIE) { - wildcards |= NXFW_TUN_ID; - } else { - if (!(wildcards & NXFW_TUN_ID)) { - flow->tun_id = htonl(ntohll(cookie) >> 32); - } - } - if (wildcards & OFPFW_DL_DST) { - /* OpenFlow 1.0 OFPFW_DL_DST covers the whole Ethernet destination, but - * internally to OVS it excludes the multicast bit, which has to be set - * separately with FWW_ETH_MCAST. */ - wildcards |= FWW_ETH_MCAST; - } - flow_wildcards_init(wc, wildcards); - - flow->nw_src = match->nw_src; - flow->nw_dst = match->nw_dst; - flow->in_port = (match->in_port == htons(OFPP_LOCAL) ? ODPP_LOCAL - : ntohs(match->in_port)); - flow->dl_vlan = match->dl_vlan; - flow->dl_vlan_pcp = match->dl_vlan_pcp; - flow->dl_type = match->dl_type; - flow->tp_src = match->tp_src; - flow->tp_dst = match->tp_dst; - memcpy(flow->dl_src, match->dl_src, ETH_ADDR_LEN); - memcpy(flow->dl_dst, match->dl_dst, ETH_ADDR_LEN); - flow->nw_tos = match->nw_tos; - flow->nw_proto = match->nw_proto; -} - char * flow_to_string(const struct flow *flow) { diff --git a/lib/flow.h b/lib/flow.h index 8292359e..1a704bff 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -64,10 +64,6 @@ int flow_extract(struct ofpbuf *, ovs_be32 tun_id, uint16_t in_port, struct flow *); void flow_extract_stats(const struct flow *flow, struct ofpbuf *packet, struct odp_flow_stats *stats); -void flow_to_match(const struct flow *, uint32_t wildcards, int flow_format, - struct ofp_match *); -void flow_from_match(const struct ofp_match *, int flow_format, - ovs_be64 cookie, struct flow *, struct flow_wildcards *); char *flow_to_string(const struct flow *); void flow_format(struct ds *, const struct flow *); void flow_print(FILE *, const struct flow *); diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index 20440323..d0488ddb 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -608,8 +608,7 @@ parse_ofp_flow_mod_str(char *string, uint16_t command) parse_ofp_str(&pf, buffer, string); ofm = buffer->data; - flow_to_match(&pf.rule.flow, pf.rule.wc.wildcards, NXFF_OPENFLOW10, - &ofm->match); + cls_rule_to_match(&pf.rule, NXFF_OPENFLOW10, &ofm->match); ofm->command = htons(command); ofm->cookie = htonll(pf.cookie); ofm->idle_timeout = htons(pf.idle_timeout); diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index a8fc28b6..bf4a51fc 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -3412,8 +3412,7 @@ put_ofp_flow_stats(struct ofconn *ofconn, struct rule *rule, ofs->length = htons(len); ofs->table_id = 0; ofs->pad = 0; - flow_to_match(&rule->cr.flow, rule->cr.wc.wildcards, - ofconn->flow_format, &ofs->match); + cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofs->match); calc_flow_duration(rule->created, &ofs->duration_sec, &ofs->duration_nsec); ofs->cookie = rule->flow_cookie; ofs->priority = htons(rule->cr.priority); @@ -3544,8 +3543,7 @@ flow_stats_ds(struct ofproto *ofproto, struct rule *rule, struct ds *results) size_t act_len = sizeof *rule->actions * rule->n_actions; query_stats(ofproto, rule, &packet_count, &byte_count); - flow_to_match(&rule->cr.flow, rule->cr.wc.wildcards, - NXFF_OPENFLOW10, &match); + cls_rule_to_match(&rule->cr, NXFF_OPENFLOW10, &match); ds_put_format(results, "duration=%llds, ", (time_msec() - rule->created) / 1000); @@ -4815,8 +4813,7 @@ compose_ofp_flow_removed(struct ofconn *ofconn, const struct rule *rule, struct ofpbuf *buf; ofr = make_openflow(sizeof *ofr, OFPT_FLOW_REMOVED, &buf); - flow_to_match(&rule->cr.flow, rule->cr.wc.wildcards, ofconn->flow_format, - &ofr->match); + cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofr->match); ofr->cookie = rule->flow_cookie; ofr->priority = htons(rule->cr.priority); ofr->reason = reason; diff --git a/tests/test-flows.c b/tests/test-flows.c index a4649b3f..b53d8532 100644 --- a/tests/test-flows.c +++ b/tests/test-flows.c @@ -19,10 +19,12 @@ #include #include #include +#include "classifier.h" #include "openflow/openflow.h" #include "timeval.h" #include "ofpbuf.h" #include "ofp-print.h" +#include "ofp-util.h" #include "pcap.h" #include "util.h" #include "vlog.h" @@ -54,6 +56,7 @@ main(int argc OVS_UNUSED, char *argv[]) while (fread(&expected_match, sizeof expected_match, 1, flows)) { struct ofpbuf *packet; struct ofp_match extracted_match; + struct cls_rule rule; struct flow flow; n++; @@ -66,7 +69,8 @@ main(int argc OVS_UNUSED, char *argv[]) } flow_extract(packet, 0, 1, &flow); - flow_to_match(&flow, 0, false, &extracted_match); + cls_rule_init_exact(&flow, 0, &rule); + cls_rule_to_match(&rule, NXFF_OPENFLOW10, &extracted_match); if (memcmp(&expected_match, &extracted_match, sizeof expected_match)) { char *exp_s = ofp_match_to_string(&expected_match, 2); diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index be68bdcb..3a0056ad 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -443,8 +443,7 @@ do_dump_flows(int argc, char *argv[]) req = alloc_stats_request(sizeof *req, OFPST_FLOW, &request); parse_ofp_str(&pf, NULL, argc > 2 ? argv[2] : ""); - flow_to_match(&pf.rule.flow, pf.rule.wc.wildcards, NXFF_OPENFLOW10, - &req->match); + cls_rule_to_match(&pf.rule, NXFF_OPENFLOW10, &req->match); memset(&req->pad, 0, sizeof req->pad); req->out_port = htons(pf.out_port); @@ -460,8 +459,7 @@ do_dump_aggregate(int argc, char *argv[]) req = alloc_stats_request(sizeof *req, OFPST_AGGREGATE, &request); parse_ofp_str(&pf, NULL, argc > 2 ? argv[2] : ""); - flow_to_match(&pf.rule.flow, pf.rule.wc.wildcards, NXFF_OPENFLOW10, - &req->match); + cls_rule_to_match(&pf.rule, NXFF_OPENFLOW10, &req->match); memset(&req->pad, 0, sizeof req->pad); req->out_port = htons(pf.out_port); -- 2.30.2