[ovs-dev] [PATCH v2 16/16] ofp-actions: Add support for OpenFlow 1.5 (draft) Copy-Field action.

Ben Pfaff blp at nicira.com
Mon Aug 11 20:10:55 UTC 2014


Applied, thanks!

On Mon, Aug 11, 2014 at 11:46:20AM -0700, Jarno Rajahalme wrote:
> Acked-by: Jarno Rajahalme <jrajahalme at nicira.com>
> 
> On Aug 7, 2014, at 4:14 PM, Ben Pfaff <blp at nicira.com> wrote:
> 
> > ONF-JIRA: EXT-320
> > Signed-off-by: Ben Pfaff <blp at nicira.com>
> > ---
> > NEWS                 |    1 +
> > lib/ofp-actions.c    |   80 ++++++++++++++++++++++++++++++++++++++++++--------
> > tests/ofp-actions.at |   24 +++++++++++++++
> > 3 files changed, 93 insertions(+), 12 deletions(-)
> > 
> > diff --git a/NEWS b/NEWS
> > index 94232b7..15abe45 100644
> > --- a/NEWS
> > +++ b/NEWS
> > @@ -14,6 +14,7 @@ Post-v2.3.0
> >      release.  See ovs-vswitchd(8) for details.
> >    - OpenFlow:
> >      * OpenFlow 1.5 (draft) extended registers are now supported.
> > +     * OpenFlow 1.5 (draft) Copy-Field action is now supported.
> >      * OpenFlow 1.3+ table features requests are now supported (read-only).
> > 
> > 
> > diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
> > index 3799cfd..e2266cd 100644
> > --- a/lib/ofp-actions.c
> > +++ b/lib/ofp-actions.c
> > @@ -206,6 +206,11 @@ enum ofp_raw_action_type {
> >     /* NX1.0+(7): struct nx_action_reg_load. */
> >     NXAST_RAW_REG_LOAD,
> > 
> > +    /* OF1.5+(28): struct ofp15_action_copy_field. */
> > +    OFPAT_RAW15_COPY_FIELD,
> > +    /* NX1.0-1.4(6): struct nx_action_reg_move. */
> > +    NXAST_RAW_REG_MOVE,
> > +
> > /* ## ------------------------- ## */
> > /* ## Nicira extension actions. ## */
> > /* ## ------------------------- ## */
> > @@ -225,9 +230,6 @@ enum ofp_raw_action_type {
> >     /* NX1.0+(5): void. */
> >     NXAST_RAW_POP_QUEUE,
> > 
> > -    /* NX1.0+(6): struct nx_action_reg_move. */
> > -    NXAST_RAW_REG_MOVE,
> > -
> >     /* NX1.0+(8): struct nx_action_note, ... */
> >     NXAST_RAW_NOTE,
> > 
> > @@ -1622,6 +1624,26 @@ format_SET_L4_DST_PORT(const struct ofpact_l4_port *a, struct ds *s)
> >     ds_put_format(s, "mod_tp_dst:%d", a->port);
> > }
> > 
> > +/* Action structure for OFPAT_COPY_FIELD. */
> > +struct ofp15_action_copy_field {
> > +    ovs_be16 type;              /* OFPAT_COPY_FIELD. */
> > +    ovs_be16 len;               /* Length is padded to 64 bits. */
> > +    ovs_be16 n_bits;            /* Number of bits to copy. */
> > +    ovs_be16 src_offset;        /* Starting bit offset in source. */
> > +    ovs_be16 dst_offset;        /* Starting bit offset in destination. */
> > +    ovs_be16 oxm_id_len;        /* Length of oxm_ids. */
> > +
> > +    /* OpenFlow allows for experimenter OXM fields whose expression is longer
> > +     * than a standard 32-bit OXM.  Thus, in the OpenFlow specification, the
> > +     * following is variable-length.  Open vSwitch does not yet support
> > +     * experimenter OXM fields, so until it does we leave these as fixed
> > +     * size. */
> > +    ovs_be32 src;               /* OXM for source field. */
> > +    ovs_be32 dst;               /* OXM for destination field. */
> > +    uint8_t pad[4];             /* Must be zero. */
> > +};
> > +OFP_ASSERT(sizeof(struct ofp15_action_copy_field) == 24);
> > +
> > /* Action structure for NXAST_REG_MOVE.
> >  *
> >  * Copies src[src_ofs:src_ofs+n_bits] to dst[dst_ofs:dst_ofs+n_bits], where
> > @@ -1728,6 +1750,29 @@ struct nx_action_reg_move {
> > OFP_ASSERT(sizeof(struct nx_action_reg_move) == 24);
> > 
> > static enum ofperr
> > +decode_OFPAT_RAW15_COPY_FIELD(const struct ofp15_action_copy_field *oacf,
> > +                              struct ofpbuf *ofpacts)
> > +{
> > +    struct ofpact_reg_move *move;
> > +
> > +    if (oacf->oxm_id_len != htons(8)) {
> > +        /* We only support 4-byte OXM IDs so far. */
> > +        return OFPERR_OFPBAC_BAD_LEN;
> > +    }
> > +
> > +    move = ofpact_put_REG_MOVE(ofpacts);
> > +    move->ofpact.raw = OFPAT_RAW15_COPY_FIELD;
> > +    move->src.field = mf_from_nxm_header(ntohl(oacf->src));
> > +    move->src.ofs = ntohs(oacf->src_offset);
> > +    move->src.n_bits = ntohs(oacf->n_bits);
> > +    move->dst.field = mf_from_nxm_header(ntohl(oacf->dst));
> > +    move->dst.ofs = ntohs(oacf->dst_offset);
> > +    move->dst.n_bits = ntohs(oacf->n_bits);
> > +
> > +    return nxm_reg_move_check(move, NULL);
> > +}
> > +
> > +static enum ofperr
> > decode_NXAST_RAW_REG_MOVE(const struct nx_action_reg_move *narm,
> >                           struct ofpbuf *ofpacts)
> > {
> > @@ -1746,17 +1791,28 @@ decode_NXAST_RAW_REG_MOVE(const struct nx_action_reg_move *narm,
> > 
> > static void
> > encode_REG_MOVE(const struct ofpact_reg_move *move,
> > -                enum ofp_version ofp_version OVS_UNUSED,
> > -                struct ofpbuf *out)
> > +                enum ofp_version ofp_version, struct ofpbuf *out)
> > {
> > -    struct nx_action_reg_move *narm;
> > +    if (ofp_version >= OFP15_VERSION) {
> > +        struct ofp15_action_copy_field *copy;
> > 
> > -    narm = put_NXAST_REG_MOVE(out);
> > -    narm->n_bits = htons(move->dst.n_bits);
> > -    narm->src_ofs = htons(move->src.ofs);
> > -    narm->dst_ofs = htons(move->dst.ofs);
> > -    narm->src = htonl(move->src.field->nxm_header);
> > -    narm->dst = htonl(move->dst.field->nxm_header);
> > +        copy = put_OFPAT15_COPY_FIELD(out);
> > +        copy->n_bits = htons(move->dst.n_bits);
> > +        copy->src_offset = htons(move->src.ofs);
> > +        copy->dst_offset = htons(move->dst.ofs);
> > +        copy->oxm_id_len = htons(8);
> > +        copy->src = htonl(mf_oxm_header(move->src.field->id, ofp_version));
> > +        copy->dst = htonl(mf_oxm_header(move->dst.field->id, ofp_version));
> > +    } else {
> > +        struct nx_action_reg_move *narm;
> > +
> > +        narm = put_NXAST_REG_MOVE(out);
> > +        narm->n_bits = htons(move->dst.n_bits);
> > +        narm->src_ofs = htons(move->src.ofs);
> > +        narm->dst_ofs = htons(move->dst.ofs);
> > +        narm->src = htonl(move->src.field->nxm_header);
> > +        narm->dst = htonl(move->dst.field->nxm_header);
> > +    }
> > }
> > 
> > static char * WARN_UNUSED_RESULT
> > diff --git a/tests/ofp-actions.at b/tests/ofp-actions.at
> > index 9c6f228..569f4ae 100644
> > --- a/tests/ofp-actions.at
> > +++ b/tests/ofp-actions.at
> > @@ -502,6 +502,30 @@ AT_CHECK(
> >   [0], [expout], [experr])
> > AT_CLEANUP
> > 
> > +dnl Our primary goal here is to verify that the copy_field action gets
> > +dnl used instead of the Nicira extension reg_move in OpenFlow 1.5, so
> > +dnl the list of action tests is very short.
> > +AT_SETUP([OpenFlow 1.5 action translation])
> > +AT_KEYWORDS([ofp-actions OF1.5])
> > +AT_DATA([test-data], [dnl
> > +# actions=LOCAL
> > +0000 0010 fffffffe 04d2 000000000000
> > +
> > +# actions=move:NXM_OF_IN_PORT[]->NXM_OF_VLAN_TCI[]
> > +001c 0018 0010 0000 0000 0008 00000002 00000802 00000000
> > +
> > +])
> > +sed '/^[[#&]]/d' < test-data > input.txt
> > +sed -n 's/^# //p; /^$/p' < test-data > expout
> > +sed -n 's/^& //p' < test-data > experr
> > +AT_CAPTURE_FILE([input.txt])
> > +AT_CAPTURE_FILE([expout])
> > +AT_CAPTURE_FILE([experr])
> > +AT_CHECK(
> > +  [ovs-ofctl '-vPATTERN:console:%c|%p|%m' parse-actions OpenFlow15 < input.txt],
> > +  [0], [expout], [experr])
> > +AT_CLEANUP
> > +
> > AT_SETUP([ofp-actions - inconsistent MPLS actions])
> > OVS_VSWITCHD_START
> > dnl OK: Use fin_timeout action on TCP flow
> > -- 
> > 1.7.10.4
> > 
> > _______________________________________________
> > dev mailing list
> > dev at openvswitch.org
> > http://openvswitch.org/mailman/listinfo/dev
> 



More information about the dev mailing list