Signed-off-by: Isaku Yamahata <yamah...@valinux.co.jp>
---
v2
newly created
---
 lib/ofp-actions.c |  116 +++++++++++++++++++++++++++++++++++++++++++++++++----
 lib/ofp-actions.h |    2 +
 lib/ofp-util.c    |    4 +-
 3 files changed, 112 insertions(+), 10 deletions(-)

diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 63cc2b6..7b9ef49 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -1317,12 +1317,9 @@ 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_END:
-        NOT_REACHED();
-
     case OFPACT_OUTPUT:
         return ofpact_output_to_openflow11(ofpact_get_OUTPUT(a), out);
 
@@ -1330,6 +1327,51 @@ 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_END:
+    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_END:
+        NOT_REACHED();
+
+    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);
@@ -1400,12 +1442,56 @@ 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_END:
+    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;
+    }
+}
+
 /* 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'. */
-void
-ofpacts_to_openflow11(const struct ofpact ofpacts[], struct ofpbuf *openflow,
-                      enum ofp11_instruction_type type)
+static void
+__ofpacts_to_openflow11(const struct ofpact ofpacts[], struct ofpbuf *openflow,
+                        enum ofp11_instruction_type type,
+                        void (*ofpact_to_openflow)(const struct ofpact *a,
+                                                   struct ofpbuf *out))
 {
     const struct ofpact *a;
 
@@ -1422,7 +1508,7 @@ ofpacts_to_openflow11(const struct ofpact ofpacts[], 
struct ofpbuf *openflow,
 
         ofpbuf_put_uninit(openflow, sizeof *oia);
         OFPACT_FOR_EACH (a, ofpacts) {
-            ofpact_to_openflow11(a, openflow);
+            ofpact_to_openflow(a, openflow);
         }
         oia = (struct ofp11_instruction_actions *)((char *)openflow->data +
                                                    start_len);
@@ -1442,6 +1528,20 @@ ofpacts_to_openflow11(const struct ofpact ofpacts[], 
struct ofpbuf *openflow,
         NOT_REACHED();
     }
 }
+
+void
+ofpacts_to_openflow11(const struct ofpact ofpacts[], struct ofpbuf *openflow,
+                      enum ofp11_instruction_type type)
+{
+    __ofpacts_to_openflow11(ofpacts, openflow, type, ofpact_to_openflow11);
+}
+
+void
+ofpacts_to_openflow12(const struct ofpact ofpacts[], struct ofpbuf *openflow,
+                      enum ofp11_instruction_type type)
+{
+    __ofpacts_to_openflow11(ofpacts, openflow, type, 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 f2c9861..e8744cd 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -394,6 +394,8 @@ enum ofperr ofpacts_check(const struct ofpact[],
 void ofpacts_to_openflow10(const struct ofpact[], struct ofpbuf *openflow);
 void ofpacts_to_openflow11(const struct ofpact[], struct ofpbuf *openflow,
                            enum ofp11_instruction_type type);
+void ofpacts_to_openflow12(const struct ofpact[], struct ofpbuf *openflow,
+                           enum ofp11_instruction_type type);
 
 /* Working with ofpacts. */
 bool ofpacts_output_to_port(const struct ofpact[], uint16_t port);
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 46a9e59..df6cc09 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -1901,7 +1901,7 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm,
         memset(ofm->pad, 0, sizeof ofm->pad);
         ofputil_put_match(msg, &fm->cr, fm->cookie, fm->cookie_mask, protocol);
         if (fm->ofpacts) {
-            ofpacts_to_openflow11(fm->ofpacts, msg, OFPIT11_APPLY_ACTIONS);
+            ofpacts_to_openflow12(fm->ofpacts, msg, OFPIT11_APPLY_ACTIONS);
         }
         break;
     }
@@ -2384,7 +2384,7 @@ ofputil_append_flow_stats_reply(uint8_t ofp_version,
         ofs->packet_count = htonll(unknown_to_zero(fs->packet_count));
         ofs->byte_count = htonll(unknown_to_zero(fs->byte_count));
         ofputil_put_match(reply, &fs->rule, 0, 0, OFPUTIL_P_OF12);
-        ofpacts_to_openflow11(fs->ofpacts, reply, OFPIT11_APPLY_ACTIONS);
+        ofpacts_to_openflow12(fs->ofpacts, reply, OFPIT11_APPLY_ACTIONS);
         ofs = ofpbuf_at_assert(reply, start_ofs, sizeof *ofs);
         ofs->length = htons(reply->size - start_ofs);
     } else if (osm->type == htons(OFPST_FLOW) && ofp_version == OFP10_VERSION) 
{
-- 
1.7.1.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to