Signed-off-by: Isaku Yamahata <yamah...@valinux.co.jp> --- v2 - changed for ofp_instruction --- lib/ofp-actions.c | 85 +++++++++++++++++++++++++++++++++++++++++++++------- lib/ofp-util.c | 26 ++++++++++++++++ 2 files changed, 99 insertions(+), 12 deletions(-)
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index 0122594..3e00366 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -1140,6 +1140,7 @@ ofpact_to_nxast(const struct ofpact *a, struct ofpbuf *out) break; case OFPACT_RESUBMIT: + assert(a->compat != -1); ofpact_resubmit_to_nxast(ofpact_get_RESUBMIT(a), out); break; @@ -1378,8 +1379,22 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out) break; case OFPACT_INSTRUCTION: - NOT_REACHED(); /* TODO:XXX */ + NOT_REACHED(); + break; + + case OFPACT_RESUBMIT: { + struct ofpact_resubmit *resubmit = ofpact_get_RESUBMIT(a); + struct ofp11_instruction_goto_table *oigt; + if (a->compat != -1) { /* TODO:XXX use symbolic constant */ + ofpact_to_nxast(a, out); + break; + } + oigt = instruction_put_OFPIT11_GOTO_TABLE(out); + oigt->table_id = resubmit->table_id; + memset(oigt->pad, 0, sizeof oigt->pad); break; + } + case OFPACT_CONTROLLER: case OFPACT_OUTPUT_REG: @@ -1391,7 +1406,6 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out) case OFPACT_SET_QUEUE: case OFPACT_POP_QUEUE: case OFPACT_FIN_TIMEOUT: - case OFPACT_RESUBMIT: case OFPACT_LEARN: case OFPACT_MULTIPATH: case OFPACT_AUTOPATH: @@ -1416,18 +1430,10 @@ ofpacts_put_openflow11_actions(const struct ofpact ofpacts[], } } -void -ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[], - size_t ofpacts_len, - struct ofpbuf *openflow) +static void +ofpacts_update_instruction_actions(struct ofpbuf *openflow, size_t ofs) { struct ofp11_instruction_actions *oia; - size_t ofs; - - /* Put an OFPIT11_APPLY_ACTIONS instruction and fill it in. */ - ofs = openflow->size; - instruction_put_OFPIT11_APPLY_ACTIONS(openflow); - ofpacts_put_openflow11_actions(ofpacts, ofpacts_len, openflow); /* Update the instruction's length (or, if it's empty, delete it). */ oia = ofpbuf_at_assert(openflow, ofs, sizeof *oia); @@ -1437,6 +1443,61 @@ ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[], openflow->size = ofs; } } + +void +ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[], + size_t ofpacts_len, + struct ofpbuf *openflow) +{ + size_t ofs; + const struct ofpact *a; + + if (ofpacts[0].type != OFPACT_INSTRUCTION) { + /* Put an OFPIT11_APPLY_ACTIONS instruction and fill it in. */ + ofs = openflow->size; + instruction_put_OFPIT11_APPLY_ACTIONS(openflow); + ofpacts_put_openflow11_actions(ofpacts, ofpacts_len, openflow); + ofpacts_update_instruction_actions(openflow, ofs); + return; + } + + ofs = 0; + OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) { + if (a->type == OFPACT_INSTRUCTION) { + const struct ofpact_instruction *oi; + + if (ofs > 0) { + ofpacts_update_instruction_actions(openflow, ofs); + ofs = 0; + } + + oi = ofpact_get_INSTRUCTION(a); + switch (oi->type) { + case OVSINST_OFPIT11_APPLY_ACTIONS: + ofs = openflow->size; + instruction_put_OFPIT11_APPLY_ACTIONS(openflow); + continue; + case OVSINST_OFPIT11_CLEAR_ACTIONS: + instruction_put_OFPIT11_CLEAR_ACTIONS(openflow); + continue; + case OVSINST_OFPIT11_WRITE_ACTIONS: + ofs = openflow->size; + instruction_put_OFPIT11_WRITE_ACTIONS(openflow); + continue; + case OVSINST_OFPIT11_WRITE_METADATA: + NOT_REACHED(); /* TODO:XXX */ + break; + case OVSINST_OFPIT11_GOTO_TABLE: + /* nothing */ + continue; + } + } + ofpact_to_openflow11(a, openflow); + } + if (ofs > 0) { + ofpacts_update_instruction_actions(openflow, ofs); + } +} /* Returns true if 'action' outputs to 'port', false otherwise. */ static bool diff --git a/lib/ofp-util.c b/lib/ofp-util.c index faa0687..cfa2a53 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -1788,6 +1788,32 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm, : fm->command); switch (protocol) { +#if 0 + case OFPUTIL_P_OF11: { + struct ofp11_flow_mod *ofm11; + msg = ofpbuf_new(sizeof *ofm11 + NXM_TYPICAL_LEN + fm->ofpacts_len); + ofm11 = put_openflow(sizeof *ofm11, ofp_version, OFPT11_FLOW_MOD, msg); + ofm11->cookie = fm->new_cookie; + ofm11->cookie_mask = fm->cookie_mask; + ofm11->table_id = fm->table_id; + ofm11->command = fm->command; + ofm11->idle_timeout = htons(fm->idle_timeout); + ofm11->hard_timeout = htons(fm->hard_timeout); + ofm11->priority = htons(fm->cr.priority); + ofm11->buffer_id = htonl(fm->buffer_id); + ofm11->out_port = ofputil_port_to_ofp11(fm->out_port); + ofm11->out_group = htonl(OFPG11_ANY); + ofm11->flags = htons(fm->flags); + memset(ofm11->pad, 0, sizeof ofm11->pad); + /* TODO:XXX ofm11::match */ + if (fm->ofpacts) { + ofpacts_put_openflow11_instructions(fm->ofpacts, fm->ofpacts_len, + msg); + } + break; + } +#endif + case OFPUTIL_P_OF10: case OFPUTIL_P_OF10_TID: msg = ofpbuf_new(sizeof *ofm + fm->ofpacts_len); -- 1.7.1.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev