[ovs-dev] [PATCH 5/5] ofp-actions: encode OF12 output/set-field actions

Simon Horman horms at verge.net.au
Thu Aug 30 01:40:27 UTC 2012


From: Isaku Yamahata <yamahata at valinux.co.jp>

Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
Signed-off-by: Simon Horman <horms at verge.net.au>

---

v3 [Simon Horman]
* Manual Rebase
  - Add ofpacts_put_openflow12_instructions() and
    ofpacts_put_openflow11_actions(), this seems to be in keeping
    with the intention of the previous version of this patch.

v2 [Isaku Yamahata]
* Initial post
---
 lib/ofp-actions.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 lib/ofp-actions.h |   7 ++-
 lib/ofp-util.c    |   4 +-
 3 files changed, 141 insertions(+), 13 deletions(-)

diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index e86c8ea..ec9f4f6 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -1460,7 +1460,7 @@ ofpact_output_to_openflow11(const struct ofpact_output *output,
 }
 
 static void
-ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
+ofpact_to_openflow11_common(const struct ofpact *a, struct ofpbuf *out)
 {
     switch (a->type) {
     case OFPACT_OUTPUT:
@@ -1470,6 +1470,47 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
         /* XXX */
         break;
 
+    /* TODO: more actions OFPAT_COPY_TTL_OUT ... OFPAT_DEC_NW_TTL */
+
+    case OFPACT_CONTROLLER:
+    case OFPACT_OUTPUT_REG:
+    case OFPACT_BUNDLE:
+    case OFPACT_SET_VLAN_VID:
+    case OFPACT_SET_VLAN_PCP:
+    case OFPACT_STRIP_VLAN:
+    case OFPACT_SET_ETH_SRC:
+    case OFPACT_SET_ETH_DST:
+    case OFPACT_SET_IPV4_SRC:
+    case OFPACT_SET_IPV4_DST:
+    case OFPACT_SET_IPV4_DSCP:
+    case OFPACT_SET_L4_SRC_PORT:
+    case OFPACT_SET_L4_DST_PORT:
+    case OFPACT_REG_MOVE:
+    case OFPACT_REG_LOAD:
+    case OFPACT_DEC_TTL:
+    case OFPACT_SET_TUNNEL:
+    case OFPACT_SET_QUEUE:
+    case OFPACT_POP_QUEUE:
+    case OFPACT_FIN_TIMEOUT:
+    case OFPACT_RESUBMIT:
+    case OFPACT_LEARN:
+    case OFPACT_MULTIPATH:
+    case OFPACT_AUTOPATH:
+    case OFPACT_NOTE:
+    case OFPACT_EXIT:
+    default:
+        NOT_REACHED();
+    }
+}
+
+static void
+ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
+{
+    switch (a->type) {
+    case OFPACT_OUTPUT:
+    case OFPACT_ENQUEUE:
+        return ofpact_to_openflow11_common(a, out);
+
     case OFPACT_SET_VLAN_VID:
         ofputil_put_OFPAT11_SET_VLAN_VID(out)->vlan_vid
             = htons(ofpact_get_SET_VLAN_VID(a)->vlan_vid);
@@ -1540,27 +1581,90 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
     }
 }
 
+static void
+ofpact_to_openflow12(const struct ofpact *a, struct ofpbuf *out)
+{
+    switch (a->type) {
+    case OFPACT_SET_VLAN_VID:
+    case OFPACT_SET_VLAN_PCP:
+    case OFPACT_STRIP_VLAN:
+    case OFPACT_SET_ETH_SRC:
+    case OFPACT_SET_ETH_DST:
+    case OFPACT_SET_IPV4_SRC:
+    case OFPACT_SET_IPV4_DST:
+    case OFPACT_SET_IPV4_DSCP:
+    case OFPACT_SET_L4_SRC_PORT:
+    case OFPACT_SET_L4_DST_PORT:
+        NOT_REACHED();
+
+    case OFPACT_OUTPUT:
+    case OFPACT_ENQUEUE:
+        return ofpact_to_openflow11_common(a, out);
+
+    case OFPACT_CONTROLLER:
+    case OFPACT_OUTPUT_REG:
+    case OFPACT_BUNDLE:
+    case OFPACT_REG_MOVE:
+    case OFPACT_REG_LOAD:
+    case OFPACT_DEC_TTL:
+    case OFPACT_SET_TUNNEL:
+    case OFPACT_SET_QUEUE:
+    case OFPACT_POP_QUEUE:
+    case OFPACT_FIN_TIMEOUT:
+    case OFPACT_RESUBMIT:
+    case OFPACT_LEARN:
+    case OFPACT_MULTIPATH:
+    case OFPACT_AUTOPATH:
+    case OFPACT_NOTE:
+    case OFPACT_EXIT:
+        ofpact_to_nxast(a, out);
+        break;
+    }
+}
+
+typedef void (*ofpact_to_openflow_t)(const struct ofpact *a,
+                                     struct ofpbuf *out);
+
 /* Converts the ofpacts in 'ofpacts' (terminated by OFPACT_END) into OpenFlow
  * 1.1 actions in 'openflow', appending the actions to any existing data in
  * 'openflow'. */
-size_t
-ofpacts_put_openflow11_actions(const struct ofpact ofpacts[],
-                               size_t ofpacts_len, struct ofpbuf *openflow)
+static size_t
+ofpacts_put_openflow11_actions__(const struct ofpact ofpacts[],
+                                 size_t ofpacts_len, struct ofpbuf *openflow,
+                                 ofpact_to_openflow_t ofpact_to_openflow)
+
 {
     const struct ofpact *a;
     size_t start_size = openflow->size;
 
     OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
-        ofpact_to_openflow11(a, openflow);
+        ofpact_to_openflow(a, openflow);
     }
 
     return openflow->size - start_size;
 }
 
-void
-ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[],
-                                    size_t ofpacts_len,
-                                    struct ofpbuf *openflow)
+size_t
+ofpacts_put_openflow11_actions(const struct ofpact ofpacts[],
+                               size_t ofpacts_len, struct ofpbuf *openflow)
+{
+    return ofpacts_put_openflow11_actions__(ofpacts, ofpacts_len, openflow,
+                                            ofpact_to_openflow11);
+}
+
+size_t
+ofpacts_put_openflow12_actions(const struct ofpact ofpacts[],
+                               size_t ofpacts_len, struct ofpbuf *openflow)
+{
+    return ofpacts_put_openflow11_actions__(ofpacts, ofpacts_len, openflow,
+                                            ofpact_to_openflow12);
+}
+
+static void
+ofpacts_put_openflow11_instructions__(const struct ofpact ofpacts[],
+                                      size_t ofpacts_len,
+                                      struct ofpbuf *openflow,
+                                      ofpact_to_openflow_t ofpact_to_openflow)
 {
     struct ofp11_instruction_actions *oia;
     size_t ofs;
@@ -1568,7 +1672,8 @@ ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[],
     /* 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_put_openflow11_actions__(ofpacts, ofpacts_len, openflow,
+                                     ofpact_to_openflow);
 
     /* Update the instruction's length (or, if it's empty, delete it). */
     oia = ofpbuf_at_assert(openflow, ofs, sizeof *oia);
@@ -1578,6 +1683,24 @@ 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)
+{
+    ofpacts_put_openflow11_instructions__(ofpacts, ofpacts_len, openflow,
+                                          ofpact_to_openflow11);
+}
+
+void
+ofpacts_put_openflow12_instructions(const struct ofpact ofpacts[],
+                                    size_t ofpacts_len,
+                                    struct ofpbuf *openflow)
+{
+    ofpacts_put_openflow11_instructions__(ofpacts, ofpacts_len, openflow,
+                                          ofpact_to_openflow12);
+}
 
 /* Returns true if 'action' outputs to 'port', false otherwise. */
 static bool
diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h
index 238bc9a..706c7b2 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -410,11 +410,16 @@ enum ofperr ofpacts_check(const struct ofpact[], size_t ofpacts_len,
 /* Converting ofpacts to OpenFlow. */
 void ofpacts_put_openflow10(const struct ofpact[], size_t ofpacts_len,
                             struct ofpbuf *openflow);
+void ofpacts_put_openflow11_instructions(const struct ofpact[],
+                                         size_t ofpacts_len,
+                                         struct ofpbuf *openflow);
 size_t ofpacts_put_openflow11_actions(const struct ofpact[], size_t ofpacts_len,
                                       struct ofpbuf *openflow);
-void ofpacts_put_openflow11_instructions(const struct ofpact[],
+void ofpacts_put_openflow12_instructions(const struct ofpact[],
                                          size_t ofpacts_len,
                                          struct ofpbuf *openflow);
+size_t ofpacts_put_openflow12_actions(const struct ofpact[], size_t ofpacts_len,
+                                      struct ofpbuf *openflow);
 
 /* Working with ofpacts. */
 bool ofpacts_output_to_port(const struct ofpact[], size_t ofpacts_len,
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 0b1e494..a037ae2 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -1310,7 +1310,7 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm,
         ofm->out_group = htonl(OFPG11_ANY);
         ofm->flags = htons(fm->flags);
         oxm_put_match(msg, &fm->cr);
-        ofpacts_put_openflow11_instructions(fm->ofpacts, fm->ofpacts_len, msg);
+        ofpacts_put_openflow12_instructions(fm->ofpacts, fm->ofpacts_len, msg);
         break;
     }
 
@@ -1783,7 +1783,7 @@ ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs,
 
         ofpbuf_put_uninit(reply, sizeof *ofs);
         oxm_put_match(reply, &fs->rule);
-        ofpacts_put_openflow11_instructions(fs->ofpacts, fs->ofpacts_len,
+        ofpacts_put_openflow12_instructions(fs->ofpacts, fs->ofpacts_len,
                                             reply);
 
         ofs = ofpbuf_at_assert(reply, start_ofs, sizeof *ofs);
-- 
1.7.10.2.484.gcd07cc5




More information about the dev mailing list