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

Reply via email to