Skip to content

Commit

Permalink
Merge pull request #5 from timofei-durakov/swap_field
Browse files Browse the repository at this point in the history
Swap Field Experimenter
  • Loading branch information
timofei-durakov authored Jun 10, 2021
2 parents a644b53 + a1c19ae commit 9ecd7aa
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 3 deletions.
3 changes: 2 additions & 1 deletion build-aux/extract-ofp-actions
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ version_reverse_map = dict((v, k) for (k, v) in version_map.items())
# Map from vendor name to the length of the action header.
vendor_map = {"OF": (0x00000000, 4),
"ONF": (0x4f4e4600, 10),
"NX": (0x00002320, 10)}
"NX": (0x00002320, 10),
"OPK": (0x0000AA02, 10)}

# Basic types used in action arguments.
types = {}
Expand Down
1 change: 1 addition & 0 deletions include/openflow/openflow-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ enum ofp_version {
#define NX_VENDOR_ID 0x00002320 /* Nicira. */
#define ONF_VENDOR_ID 0x4f4e4600 /* Open Networking Foundation. */
#define INTEL_VENDOR_ID 0x0000AA01 /* Intel */
#define OPK_VENDOR_ID 0x0000AA02 /* Open Kilda */

#define OFP_MAX_TABLE_NAME_LEN 32
#define OFP_MAX_PORT_NAME_LEN 16
Expand Down
9 changes: 9 additions & 0 deletions include/openvswitch/ofp-actions.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ struct vl_mff_map;
OFPACT(SET_L4_SRC_PORT, ofpact_l4_port, ofpact, "mod_tp_src") \
OFPACT(SET_L4_DST_PORT, ofpact_l4_port, ofpact, "mod_tp_dst") \
OFPACT(REG_MOVE, ofpact_reg_move, ofpact, "move") \
OFPACT(SWAP_FIELD, ofpact_swap_field, ofpact, "swap") \
OFPACT(STACK_PUSH, ofpact_stack, ofpact, "push") \
OFPACT(STACK_POP, ofpact_stack, ofpact, "pop") \
OFPACT(DEC_TTL, ofpact_cnt_ids, cnt_ids, "dec_ttl") \
Expand Down Expand Up @@ -527,6 +528,14 @@ struct ofpact_reg_move {
);
};

struct ofpact_swap_field {
OFPACT_PADDED_MEMBERS(
struct ofpact ofpact;
struct mf_subfield src;
struct mf_subfield dst;
);
};

/* OFPACT_STACK_PUSH, OFPACT_STACK_POP.
*
* Used for NXAST_STACK_PUSH and NXAST_STACK_POP. */
Expand Down
49 changes: 49 additions & 0 deletions lib/nx-match.c
Original file line number Diff line number Diff line change
Expand Up @@ -1810,6 +1810,33 @@ nxm_parse_reg_move(struct ofpact_reg_move *move, const char *s)
}
return NULL;
}

char * OVS_WARN_UNUSED_RESULT
nxm_parse_swap_field(struct ofpact_swap_field *swap, const char *s)
{
const char *full_s = s;
char *error;

error = mf_parse_subfield__(&swap->src, &s);
if (error) {
return error;
}
if (strncmp(s, "->", 2)) {
return xasprintf("%s: missing `->' following source", full_s);
}
s += 2;
error = mf_parse_subfield(&swap->dst, s);
if (error) {
return error;
}

if (swap->src.n_bits != swap->dst.n_bits) {
return xasprintf("%s: source field is %d bits wide but destination is "
"%d bits wide", full_s,
swap->src.n_bits, swap->dst.n_bits);
}
return NULL;
}

/* nxm_format_reg_move(). */

Expand All @@ -1822,6 +1849,15 @@ nxm_format_reg_move(const struct ofpact_reg_move *move, struct ds *s)
mf_format_subfield(&move->dst, s);
}

void
nxm_format_swap_field(const struct ofpact_swap_field *swap, struct ds *s)
{
ds_put_format(s, "%sswap:%s", colors.special, colors.end);
mf_format_subfield(&swap->src, s);
ds_put_format(s, "%s->%s", colors.special, colors.end);
mf_format_subfield(&swap->dst, s);
}


enum ofperr
nxm_reg_move_check(const struct ofpact_reg_move *move,
Expand All @@ -1839,6 +1875,19 @@ nxm_reg_move_check(const struct ofpact_reg_move *move,

/* nxm_execute_reg_move(). */

enum ofperr nxm_swap_field_check(const struct ofpact_swap_field *swap,
const struct match *match)
{
enum ofperr error;

error = mf_check_src(&swap->src, match);
if (error) {
return error;
}

return mf_check_dst(&swap->dst, match);
}

void
nxm_reg_load(const struct mf_subfield *dst, uint64_t src_data,
struct flow *flow, struct flow_wildcards *wc)
Expand Down
9 changes: 9 additions & 0 deletions lib/nx-match.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
struct ds;
struct match;
struct ofpact_reg_move;
struct ofpact_swap_field;
struct ofpact_reg_load;
struct ofpact_stack;
struct ofpbuf;
Expand Down Expand Up @@ -118,11 +119,19 @@ void nx_format_field_name(enum mf_field_id, enum ofp_version, struct ds *);
char *nxm_parse_reg_move(struct ofpact_reg_move *, const char *)
OVS_WARN_UNUSED_RESULT;

char *nxm_parse_swap_field(struct ofpact_swap_field *, const char *)
OVS_WARN_UNUSED_RESULT;

void nxm_format_reg_move(const struct ofpact_reg_move *, struct ds *);

void nxm_format_swap_field(const struct ofpact_swap_field *, struct ds *);

enum ofperr nxm_reg_move_check(const struct ofpact_reg_move *,
const struct match *);

enum ofperr nxm_swap_field_check(const struct ofpact_swap_field *,
const struct match *);

void nxm_reg_load(const struct mf_subfield *, uint64_t src_data,
struct flow *, struct flow_wildcards *);

Expand Down
128 changes: 126 additions & 2 deletions lib/ofp-actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,12 @@ enum ofp_raw_action_type {
/* OF1.5+(29): uint32_t. */
OFPAT_RAW15_METER,

/* ## ------------------------- ## */
/* ## Open Kilda extension actions. ## */
/* ## ------------------------- ## */
/* OPK1.3-1.4(3201): struct opk_action_swap_field, ... VLMFF */
OPK_RAW13_SWAP_FIELD,

/* ## ------------------------- ## */
/* ## Nicira extension actions. ## */
/* ## ------------------------- ## */
Expand Down Expand Up @@ -470,6 +476,7 @@ ofpact_next_flattened(const struct ofpact *ofpact)
case OFPACT_SET_L4_SRC_PORT:
case OFPACT_SET_L4_DST_PORT:
case OFPACT_REG_MOVE:
case OFPACT_SWAP_FIELD:
case OFPACT_STACK_PUSH:
case OFPACT_STACK_POP:
case OFPACT_DEC_TTL:
Expand Down Expand Up @@ -2458,6 +2465,26 @@ struct onf_action_copy_field {
* The "pad3" member is the beginning of the above. */
uint8_t pad3[4]; /* Not used. */
};

/* Action structure for OpenFlow 1.3 extension copy-field action.. */
struct opk_action_swap_field {
ovs_be16 type; /* OFPAT_EXPERIMENTER. */
ovs_be16 len; /* Length is padded to 64 bits. */
ovs_be32 experimenter; /* OPK_VENDOR_ID. */
ovs_be16 exp_type; /* 3201. */
uint8_t pad[2]; /* Not used. */
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. */
uint8_t pad2[2]; /* Not used. */
/* Followed by:
* - OXM header for source field.
* - OXM header for destination field.
* - Padding with 0-bytes (either 0 or 4 of them) to a multiple of 8 bytes.
* The "pad3" member is the beginning of the above. */
uint8_t pad3[4]; /* Not used. */
};

OFP_ASSERT(sizeof(struct onf_action_copy_field) == 24);

/* Action structure for NXAST_REG_MOVE.
Expand Down Expand Up @@ -2607,6 +2634,42 @@ decode_copy_field__(ovs_be16 src_offset, ovs_be16 dst_offset, ovs_be16 n_bits,
return nxm_reg_move_check(move, NULL);
}

static enum ofperr
decode_swap_field__(ovs_be16 src_offset, ovs_be16 dst_offset, ovs_be16 n_bits,
const void *action, ovs_be16 action_len, size_t oxm_offset,
const struct vl_mff_map *vl_mff_map,
uint64_t *tlv_bitmap, struct ofpbuf *ofpacts)
{
struct ofpact_swap_field *swap = ofpact_put_SWAP_FIELD(ofpacts);
enum ofperr error;

swap->ofpact.raw = ONFACT_RAW13_COPY_FIELD;
swap->src.ofs = ntohs(src_offset);
swap->src.n_bits = ntohs(n_bits);
swap->dst.ofs = ntohs(dst_offset);
swap->dst.n_bits = ntohs(n_bits);

struct ofpbuf b = ofpbuf_const_initializer(action, ntohs(action_len));
ofpbuf_pull(&b, oxm_offset);

error = mf_vl_mff_nx_pull_header(&b, vl_mff_map, &swap->src.field, NULL,
tlv_bitmap);
if (error) {
return error;
}
error = mf_vl_mff_nx_pull_header(&b, vl_mff_map, &swap->dst.field, NULL,
tlv_bitmap);
if (error) {
return error;
}

if (!is_all_zeros(b.data, b.size)) {
return OFPERR_NXBRC_MUST_BE_ZERO;
}

return nxm_swap_field_check(swap, NULL);
}

static enum ofperr
decode_OFPAT_RAW15_COPY_FIELD(const struct ofp15_action_copy_field *oacf,
enum ofp_version ofp_version OVS_UNUSED,
Expand All @@ -2619,6 +2682,18 @@ decode_OFPAT_RAW15_COPY_FIELD(const struct ofp15_action_copy_field *oacf,
tlv_bitmap, ofpacts);
}

static enum ofperr
decode_OPK_RAW13_SWAP_FIELD(const struct opk_action_swap_field *oasf,
enum ofp_version ofp_version OVS_UNUSED,
const struct vl_mff_map *vl_mff_map,
uint64_t *tlv_bitmap, struct ofpbuf *ofpacts)
{
return decode_swap_field__(oasf->src_offset, oasf->dst_offset,
oasf->n_bits, oasf, oasf->len,
OBJECT_OFFSETOF(oasf, pad3), vl_mff_map,
tlv_bitmap, ofpacts);
}

static enum ofperr
decode_ONFACT_RAW13_COPY_FIELD(const struct onf_action_copy_field *oacf,
enum ofp_version ofp_version OVS_UNUSED,
Expand Down Expand Up @@ -2707,6 +2782,24 @@ encode_REG_MOVE(const struct ofpact_reg_move *move,
pad_ofpat(out, start_ofs);
}

static void
encode_SWAP_FIELD(const struct ofpact_swap_field *swap,
enum ofp_version ofp_version, struct ofpbuf *out)
{
size_t start_ofs = out->size;

struct opk_action_swap_field *swap_action = put_OPK13_SWAP_FIELD(out);
swap_action->n_bits = htons(swap->dst.n_bits);
swap_action->src_offset = htons(swap->src.ofs);
swap_action->dst_offset = htons(swap->dst.ofs);
out->size = out->size - sizeof swap_action->pad3;
nx_put_mff_header(out, swap->src.field, ofp_version, false);
nx_put_mff_header(out, swap->dst.field, ofp_version, false);

pad_ofpat(out, start_ofs);
}


static char * OVS_WARN_UNUSED_RESULT
parse_REG_MOVE(const char *arg, const struct ofpact_parse_params *pp)
{
Expand All @@ -2727,6 +2820,28 @@ check_REG_MOVE(const struct ofpact_reg_move *a,
{
return nxm_reg_move_check(a, cp->match);
}

static char * OVS_WARN_UNUSED_RESULT
parse_SWAP_FIELD(const char *arg, const struct ofpact_parse_params *pp)
{
struct ofpact_swap_field *swap = ofpact_put_SWAP_FIELD(pp->ofpacts);
return nxm_parse_swap_field(swap, arg);
}


static void
format_SWAP_FIELD(const struct ofpact_swap_field *a,
const struct ofpact_format_params *fp)
{
nxm_format_swap_field(a, fp->s);
}

static enum ofperr
check_SWAP_FIELD(const struct ofpact_swap_field *a,
const struct ofpact_check_params *cp)
{
return nxm_swap_field_check(a, cp->match);
}

/* Action structure for OFPAT12_SET_FIELD. */
struct ofp12_action_set_field {
Expand Down Expand Up @@ -7940,6 +8055,7 @@ action_set_classify(const struct ofpact *a)

case OFPACT_SET_FIELD:
case OFPACT_REG_MOVE:
case OFPACT_SWAP_FIELD:
case OFPACT_SET_ETH_DST:
case OFPACT_SET_ETH_SRC:
case OFPACT_SET_IP_DSCP:
Expand Down Expand Up @@ -8157,6 +8273,7 @@ ovs_instruction_type_from_ofpact_type(enum ofpact_type type,
case OFPACT_SET_L4_SRC_PORT:
case OFPACT_SET_L4_DST_PORT:
case OFPACT_REG_MOVE:
case OFPACT_SWAP_FIELD:
case OFPACT_SET_FIELD:
case OFPACT_STACK_PUSH:
case OFPACT_STACK_POP:
Expand Down Expand Up @@ -8648,6 +8765,10 @@ ofpact_get_mf_dst(const struct ofpact *ofpact)

orm = CONTAINER_OF(ofpact, struct ofpact_reg_move, ofpact);
return orm->dst.field;
} else if (ofpact->type == OFPACT_SWAP_FIELD) {
const struct ofpact_swap_field *orm;
orm = CONTAINER_OF(ofpact, struct ofpact_swap_field, ofpact);
return orm->dst.field;
}

return NULL;
Expand Down Expand Up @@ -9062,6 +9183,7 @@ ofpact_outputs_to_port(const struct ofpact *ofpact, ofp_port_t port)
case OFPACT_SET_L4_SRC_PORT:
case OFPACT_SET_L4_DST_PORT:
case OFPACT_REG_MOVE:
case OFPACT_SWAP_FIELD:
case OFPACT_SET_FIELD:
case OFPACT_STACK_PUSH:
case OFPACT_STACK_POP:
Expand Down Expand Up @@ -9598,7 +9720,8 @@ ofpact_decode_raw(enum ofp_version ofp_version,
if (oah->type == htons(OFPAT_VENDOR)) {
/* Get vendor. */
hdrs.vendor = ntohl(oah->vendor);
if (hdrs.vendor == NX_VENDOR_ID || hdrs.vendor == ONF_VENDOR_ID) {
if (hdrs.vendor == NX_VENDOR_ID || hdrs.vendor == ONF_VENDOR_ID
|| hdrs.vendor == OPK_VENDOR_ID) {
/* Get extension subtype. */
const struct ext_action_header *nah;

Expand Down Expand Up @@ -9725,7 +9848,8 @@ ofpact_put_raw(struct ofpbuf *buf, enum ofp_version ofp_version,
break;

case NX_VENDOR_ID:
case ONF_VENDOR_ID: {
case ONF_VENDOR_ID:
case OPK_VENDOR_ID: {
struct ext_action_header *nah = (struct ext_action_header *) oah;
nah->subtype = htons(hdrs->type);
break;
Expand Down
Loading

0 comments on commit 9ecd7aa

Please sign in to comment.