Signed-off-by: Isaku Yamahata <[email protected]>
---
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
[email protected]
http://openvswitch.org/mailman/listinfo/dev