[ovs-dev] [PATCH v3 06/12] ofp-actions: implement instruction encoder

Isaku Yamahata yamahata at valinux.co.jp
Mon Jul 23 08:08:45 UTC 2012


Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
---
v3
- changed for OFPACT_{CLEAR_ACTIONS, WRITE_ACTIONS, GOTO_TABLE}

v2
- changed for ofp_instruction
---
 lib/ofp-actions.c |   66 +++++++++++++++++++++++++++++++++++++++-------------
 lib/ofp-util.c    |   26 +++++++++++++++++++++
 2 files changed, 75 insertions(+), 17 deletions(-)

diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index d7b99f8..25d600b 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -1370,15 +1370,9 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
         break;
 
     case OFPACT_CLEAR_ACTIONS:
-        NOT_REACHED();  /* TODO:XXX */
-        break;
-
     case OFPACT_WRITE_ACTIONS:
-        NOT_REACHED();  /* TODO:XXX */
-        break;
-
     case OFPACT_GOTO_TABLE:
-        NOT_REACHED();  /* TODO:XXX */
+        NOT_REACHED();
         break;
 
     case OFPACT_CONTROLLER:
@@ -1416,18 +1410,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 +1423,52 @@ 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)
+{
+    bool in_instruction;
+    size_t ofs;
+    const struct ofpact *a;
+
+    in_instruction = false;
+    ofs = 0;
+    OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
+        if (in_instruction && ofpact_is_instruction(a)) {
+            ofpacts_update_instruction_actions(openflow, ofs);
+            in_instruction = false;
+            ofs = 0;
+        }
+
+        if (a->type == OFPACT_CLEAR_ACTIONS) {
+            struct ofp11_instruction_actions *oia;
+            oia = instruction_put_OFPIT11_CLEAR_ACTIONS(openflow);
+            memset(oia->pad, 0, sizeof oia->pad);
+        } else if (a->type == OFPACT_WRITE_ACTIONS) {
+            in_instruction = true;
+            ofs = openflow->size;
+            instruction_put_OFPIT11_WRITE_ACTIONS(openflow);
+        /* TODO:XXX write-metadata */
+        } else if (a->type == OFPACT_GOTO_TABLE) {
+            struct ofp11_instruction_goto_table *oigt;
+            oigt = instruction_put_OFPIT11_GOTO_TABLE(openflow);
+            oigt->table_id = ofpact_get_GOTO_TABLE(a)->table_id;
+            memset(oigt->pad, 0, sizeof oigt->pad);
+        } else {
+            if (!in_instruction) {
+                in_instruction = true;
+                ofs = openflow->size;
+                instruction_put_OFPIT11_APPLY_ACTIONS(openflow);
+            }
+            ofpact_to_openflow11(a, openflow);
+        }
+    }
+    if (in_instruction) {
+        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




More information about the dev mailing list