diff options
author | Ben Pfaff <blp@ovn.org> | 2016-07-13 16:50:33 -0700 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2016-07-14 09:15:29 -0700 |
commit | 4b684612d9009c20ace820d48ba772fa00975d87 (patch) | |
tree | c84d72ace28075a1fe08cabb7024721ed4f92601 /lib | |
parent | 0f2aaee939fb9d10c6d985687edb20c8847f9143 (diff) | |
download | openvswitch-4b684612d9009c20ace820d48ba772fa00975d87.tar.gz |
ofp-actions: Translate mod_nw_ecn action to OF1.1 properly.
Also, translate OF1.2+ "set_field" on OXM_OF_IP_ECN properly to OF1.1
"mod_nw_ecn".
Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Jarno Rajahalme <jarno@ovn.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ofp-actions.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index 4ac284f9f..232e72895 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -356,6 +356,9 @@ static enum ofperr ofpacts_verify(const struct ofpact[], size_t ofpacts_len, static void ofpact_put_set_field(struct ofpbuf *openflow, enum ofp_version, enum mf_field_id, uint64_t value); +static void put_reg_load(struct ofpbuf *openflow, + const struct mf_subfield *, uint64_t value); + static enum ofperr ofpact_pull_raw(struct ofpbuf *, enum ofp_version, enum ofp_raw_action_type *, uint64_t *arg); static void *ofpact_put_raw(struct ofpbuf *, enum ofp_version, @@ -1913,7 +1916,9 @@ encode_SET_IP_ECN(const struct ofpact_ecn *ip_ecn, { uint8_t ecn = ip_ecn->ecn; if (ofp_version == OFP10_VERSION) { - /* XXX */ + struct mf_subfield dst = { .field = mf_from_id(MFF_IP_ECN), + .ofs = 0, .n_bits = 2 }; + put_reg_load(out, &dst, ecn); } else if (ofp_version == OFP11_VERSION) { put_OFPAT11_SET_NW_ECN(out, ecn); } else { @@ -2604,6 +2609,18 @@ ofpact_put_set_field(struct ofpbuf *openflow, enum ofp_version ofp_version, pad_ofpat(openflow, start_ofs); } +static void +put_reg_load(struct ofpbuf *openflow, + const struct mf_subfield *dst, uint64_t value) +{ + ovs_assert(dst->n_bits <= 64); + + struct nx_action_reg_load *narl = put_NXAST_REG_LOAD(openflow); + narl->ofs_nbits = nxm_encode_ofs_nbits(dst->ofs, dst->n_bits); + narl->dst = htonl(mf_nxm_header(dst->field->id)); + narl->value = htonll(value); +} + static bool next_load_segment(const struct ofpact_set_field *sf, struct mf_subfield *dst, uint64_t *value) @@ -2648,10 +2665,7 @@ set_field_to_nxast(const struct ofpact_set_field *sf, struct ofpbuf *openflow) dst.ofs = dst.n_bits = 0; while (next_load_segment(sf, &dst, &value)) { - struct nx_action_reg_load *narl = put_NXAST_REG_LOAD(openflow); - narl->ofs_nbits = nxm_encode_ofs_nbits(dst.ofs, dst.n_bits); - narl->dst = htonl(mf_nxm_header(dst.field->id)); - narl->value = htonll(value); + put_reg_load(openflow, &dst, value); } } } @@ -2759,6 +2773,10 @@ set_field_to_legacy_openflow(const struct ofpact_set_field *sf, put_OFPAT_SET_NW_TOS(out, ofp_version, sf->value.u8 << 2); break; + case MFF_IP_ECN: + put_OFPAT11_SET_NW_ECN(out, sf->value.u8); + break; + case MFF_TCP_SRC: case MFF_UDP_SRC: put_OFPAT_SET_TP_SRC(out, sf->value.be16); |