2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-02 07:15:17 +00:00

ofp-util: Make ofputil_cls_rule_to_match() help with flow cookies too.

This fixes OpenFlow 1.0 flow stats reporting of flows added via NXM.

I noticed this problem while implementing 64-bit tunnel IDs, hence the
positioning.  The following commit adds a test.

Acked-by: Jesse Gross <jesse@nicira.com>
This commit is contained in:
Ben Pfaff
2010-12-09 14:19:51 -08:00
parent cb833cf6c3
commit ff9d38264c
4 changed files with 37 additions and 25 deletions

View File

@@ -200,16 +200,21 @@ ofputil_cls_rule_from_match(const struct ofp_match *match,
cls_rule_zero_wildcarded_fields(rule); cls_rule_zero_wildcarded_fields(rule);
} }
/* Extract 'flow' with 'wildcards' into the OpenFlow match structure /* Convert 'rule' into the OpenFlow match structure 'match'. 'flow_format'
* 'match'. * must either NXFF_OPENFLOW10 or NXFF_TUN_ID_FROM_COOKIE.
* *
* 'flow_format' must either NXFF_OPENFLOW10 or NXFF_TUN_ID_FROM_COOKIE. In * The NXFF_TUN_ID_FROM_COOKIE flow format requires modifying the flow cookie.
* the latter case only, 'match''s NXFW_TUN_ID bit will be filled in; otherwise * This function can help with that, if 'cookie_out' is nonnull. For
* it is always set to 0. */ * NXFF_OPENFLOW10, or if the tunnel ID is wildcarded, 'cookie_in' will be
* copied directly to '*cookie_out'. For NXFF_TUN_ID_FROM_COOKIE when tunnel
* ID is matched, 'cookie_in' will be modified appropriately before setting
* '*cookie_out'.
*/
void void
ofputil_cls_rule_to_match(const struct cls_rule *rule, ofputil_cls_rule_to_match(const struct cls_rule *rule,
enum nx_flow_format flow_format, enum nx_flow_format flow_format,
struct ofp_match *match) struct ofp_match *match,
ovs_be64 cookie_in, ovs_be64 *cookie_out)
{ {
const struct flow_wildcards *wc = &rule->wc; const struct flow_wildcards *wc = &rule->wc;
unsigned int ofpfw; unsigned int ofpfw;
@@ -221,8 +226,19 @@ ofputil_cls_rule_to_match(const struct cls_rule *rule,
if (wc->wildcards & FWW_NW_TOS) { if (wc->wildcards & FWW_NW_TOS) {
ofpfw |= OFPFW_NW_TOS; ofpfw |= OFPFW_NW_TOS;
} }
if (flow_format == NXFF_TUN_ID_FROM_COOKIE && wc->wildcards & FWW_TUN_ID) {
/* Tunnel ID. */
if (flow_format == NXFF_TUN_ID_FROM_COOKIE) {
if (wc->wildcards & FWW_TUN_ID) {
ofpfw |= NXFW_TUN_ID; ofpfw |= NXFW_TUN_ID;
} else {
uint32_t cookie_lo = ntohll(cookie_in);
uint32_t cookie_hi = ntohl(rule->flow.tun_id);
cookie_in = htonll(cookie_lo | ((uint64_t) cookie_hi << 32));
}
}
if (cookie_out) {
*cookie_out = cookie_in;
} }
/* Translate VLANs. */ /* Translate VLANs. */
@@ -979,15 +995,8 @@ ofputil_encode_flow_mod(const struct flow_mod *fm,
msg = ofpbuf_new(sizeof *ofm + actions_len); msg = ofpbuf_new(sizeof *ofm + actions_len);
ofm = put_openflow(sizeof *ofm, OFPT_FLOW_MOD, msg); ofm = put_openflow(sizeof *ofm, OFPT_FLOW_MOD, msg);
ofputil_cls_rule_to_match(&fm->cr, flow_format, &ofm->match); ofputil_cls_rule_to_match(&fm->cr, flow_format, &ofm->match,
if (flow_format != NXFF_TUN_ID_FROM_COOKIE fm->cookie, &ofm->cookie);
|| fm->cr.wc.wildcards & FWW_TUN_ID) {
ofm->cookie = fm->cookie;
} else {
uint32_t cookie_lo = ntohll(fm->cookie);
uint32_t cookie_hi = ntohl(fm->cr.flow.tun_id);
ofm->cookie = htonll(cookie_lo | ((uint64_t) cookie_hi << 32));
}
ofm->command = htons(fm->command); ofm->command = htons(fm->command);
ofm->idle_timeout = htons(fm->idle_timeout); ofm->idle_timeout = htons(fm->idle_timeout);
ofm->hard_timeout = htons(fm->hard_timeout); ofm->hard_timeout = htons(fm->hard_timeout);
@@ -1124,7 +1133,8 @@ ofputil_encode_flow_stats_request(const struct flow_stats_request *fsr,
type = fsr->aggregate ? OFPST_AGGREGATE : OFPST_FLOW; type = fsr->aggregate ? OFPST_AGGREGATE : OFPST_FLOW;
ofsr = ofputil_make_stats_request(sizeof *ofsr, type, &msg); ofsr = ofputil_make_stats_request(sizeof *ofsr, type, &msg);
ofputil_cls_rule_to_match(&fsr->match, flow_format, &ofsr->match); ofputil_cls_rule_to_match(&fsr->match, flow_format, &ofsr->match,
0, NULL);
ofsr->table_id = fsr->table_id; ofsr->table_id = fsr->table_id;
ofsr->out_port = htons(fsr->out_port); ofsr->out_port = htons(fsr->out_port);
} else if (flow_format == NXFF_NXM) { } else if (flow_format == NXFF_NXM) {
@@ -1427,7 +1437,7 @@ make_flow_mod(uint16_t command, const struct cls_rule *rule,
ofm->header.length = htons(size); ofm->header.length = htons(size);
ofm->cookie = 0; ofm->cookie = 0;
ofm->priority = htons(MIN(rule->priority, UINT16_MAX)); ofm->priority = htons(MIN(rule->priority, UINT16_MAX));
ofputil_cls_rule_to_match(rule, NXFF_OPENFLOW10, &ofm->match); ofputil_cls_rule_to_match(rule, NXFF_OPENFLOW10, &ofm->match, 0, NULL);
ofm->command = htons(command); ofm->command = htons(command);
return out; return out;
} }

View File

@@ -105,7 +105,8 @@ void ofputil_cls_rule_from_match(const struct ofp_match *,
unsigned int priority, enum nx_flow_format, unsigned int priority, enum nx_flow_format,
ovs_be64 cookie, struct cls_rule *); ovs_be64 cookie, struct cls_rule *);
void ofputil_cls_rule_to_match(const struct cls_rule *, enum nx_flow_format, void ofputil_cls_rule_to_match(const struct cls_rule *, enum nx_flow_format,
struct ofp_match *); struct ofp_match *,
ovs_be64 cookie_in, ovs_be64 *cookie_out);
void normalize_match(struct ofp_match *); void normalize_match(struct ofp_match *);
char *ofp_match_to_literal_string(const struct ofp_match *match); char *ofp_match_to_literal_string(const struct ofp_match *match);

View File

@@ -3451,9 +3451,9 @@ put_ofp_flow_stats(struct ofconn *ofconn, struct rule *rule,
ofs->length = htons(len); ofs->length = htons(len);
ofs->table_id = 0; ofs->table_id = 0;
ofs->pad = 0; ofs->pad = 0;
ofputil_cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofs->match); ofputil_cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofs->match,
rule->flow_cookie, &ofs->cookie);
calc_flow_duration(rule->created, &ofs->duration_sec, &ofs->duration_nsec); calc_flow_duration(rule->created, &ofs->duration_sec, &ofs->duration_nsec);
ofs->cookie = rule->flow_cookie;
ofs->priority = htons(rule->cr.priority); ofs->priority = htons(rule->cr.priority);
ofs->idle_timeout = htons(rule->idle_timeout); ofs->idle_timeout = htons(rule->idle_timeout);
ofs->hard_timeout = htons(rule->hard_timeout); ofs->hard_timeout = htons(rule->hard_timeout);
@@ -4669,8 +4669,8 @@ compose_ofp_flow_removed(struct ofconn *ofconn, const struct rule *rule,
struct ofpbuf *buf; struct ofpbuf *buf;
ofr = make_openflow(sizeof *ofr, OFPT_FLOW_REMOVED, &buf); ofr = make_openflow(sizeof *ofr, OFPT_FLOW_REMOVED, &buf);
ofputil_cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofr->match); ofputil_cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofr->match,
ofr->cookie = rule->flow_cookie; rule->flow_cookie, &ofr->cookie);
ofr->priority = htons(rule->cr.priority); ofr->priority = htons(rule->cr.priority);
ofr->reason = reason; ofr->reason = reason;
calc_flow_duration(rule->created, &ofr->duration_sec, &ofr->duration_nsec); calc_flow_duration(rule->created, &ofr->duration_sec, &ofr->duration_nsec);

View File

@@ -70,7 +70,8 @@ main(int argc OVS_UNUSED, char *argv[])
flow_extract(packet, 0, 1, &flow); flow_extract(packet, 0, 1, &flow);
cls_rule_init_exact(&flow, 0, &rule); cls_rule_init_exact(&flow, 0, &rule);
ofputil_cls_rule_to_match(&rule, NXFF_OPENFLOW10, &extracted_match); ofputil_cls_rule_to_match(&rule, NXFF_OPENFLOW10, &extracted_match,
0, NULL);
if (memcmp(&expected_match, &extracted_match, sizeof expected_match)) { if (memcmp(&expected_match, &extracted_match, sizeof expected_match)) {
char *exp_s = ofp_match_to_string(&expected_match, 2); char *exp_s = ofp_match_to_string(&expected_match, 2);