I am unsure about what to do about some of the messages,
as noted with 'FIXME' in the code.

Signed-off-by: Simon Horman <[email protected]>

---

v2
* Initial posting
---
 lib/ofp-actions.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 lib/ofp-actions.h |   3 +-
 lib/ofp-util.c    |   8 +--
 3 files changed, 177 insertions(+), 8 deletions(-)

diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 6e73947..87df5ab 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -973,7 +973,7 @@ ofpacts_check(const struct ofpact ofpacts[],
     return 0;
 }
 
-/* Converting ofpacts to OpenFlow. */
+/* Converting ofpacts to OpenFlow 1.0. */
 
 static void
 ofpact_output_to_openflow10(const struct ofpact_output *output,
@@ -1220,16 +1220,184 @@ ofpact_to_openflow10(const struct ofpact *a, struct 
ofpbuf *out)
     }
 }
 
+/* Converting ofpacts to OpenFlow 1.1. */
+
+static void
+ofpact_output_to_openflow11(const struct ofpact_output *output,
+                            struct ofpbuf *out)
+{
+    struct ofp11_action_output *oao;
+
+    oao = ofputil_put_OFPAT11_OUTPUT(out);
+    oao->port = ofputil_port_to_ofp11(output->port);
+    oao->max_len = htons(output->max_len);
+}
+
+static void
+ofpact_controller_to_openflow11(const struct ofpact_controller *oc,
+                                struct ofpbuf *out)
+{
+    struct ofp11_action_output *oao;
+
+    oao = ofputil_put_OFPAT11_OUTPUT(out);
+    oao->port = htonl(OFPP_CONTROLLER);
+    oao->max_len = htons(oc->max_len);
+}
+
+static void
+ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
+{
+    switch (a->type) {
+    case OFPACT_END:
+    case OFPACT_ENQUEUE:
+        NOT_REACHED();
+
+    case OFPACT_OUTPUT:
+        return ofpact_output_to_openflow11(ofpact_get_OUTPUT(a), out);
+
+    case OFPACT_CONTROLLER:
+        ofpact_controller_to_openflow11(ofpact_get_CONTROLLER(a), out);
+        break;
+
+    case OFPACT_OUTPUT_REG:
+        /* FIXME: Is this generic or is an openflow11 version required ? */
+        ofpact_output_reg_to_openflow10(ofpact_get_OUTPUT_REG(a), out);
+        break;
+
+    case OFPACT_BUNDLE:
+        bundle_to_openflow(ofpact_get_BUNDLE(a), out);
+        break;
+
+    case OFPACT_SET_VLAN_VID:
+        ofputil_put_OFPAT11_SET_VLAN_VID(out)->vlan_vid
+            = htons(ofpact_get_SET_VLAN_VID(a)->vlan_vid);
+        break;
+
+    case OFPACT_SET_VLAN_PCP:
+        ofputil_put_OFPAT11_SET_VLAN_PCP(out)->vlan_pcp
+            = ofpact_get_SET_VLAN_PCP(a)->vlan_pcp;
+        break;
+
+    case OFPACT_STRIP_VLAN:
+        /* FIXME: Is this generic or is an OFPAT11 version required ? */
+        ofputil_put_OFPAT10_STRIP_VLAN(out);
+        break;
+
+    case OFPACT_SET_ETH_SRC:
+        memcpy(ofputil_put_OFPAT11_SET_DL_SRC(out)->dl_addr,
+               ofpact_get_SET_ETH_SRC(a)->mac, ETH_ADDR_LEN);
+        break;
+
+    case OFPACT_SET_ETH_DST:
+        memcpy(ofputil_put_OFPAT11_SET_DL_DST(out)->dl_addr,
+               ofpact_get_SET_ETH_DST(a)->mac, ETH_ADDR_LEN);
+        break;
+
+    case OFPACT_SET_IPV4_SRC:
+        ofputil_put_OFPAT11_SET_NW_SRC(out)->nw_addr
+            = ofpact_get_SET_IPV4_SRC(a)->ipv4;
+        break;
+
+    case OFPACT_SET_IPV4_DST:
+        ofputil_put_OFPAT11_SET_NW_DST(out)->nw_addr
+            = ofpact_get_SET_IPV4_DST(a)->ipv4;
+        break;
+
+    case OFPACT_SET_IPV4_DSCP:
+        ofputil_put_OFPAT11_SET_NW_TOS(out)->nw_tos
+            = ofpact_get_SET_IPV4_DSCP(a)->dscp;
+        break;
+
+    case OFPACT_SET_L4_SRC_PORT:
+        ofputil_put_OFPAT11_SET_TP_SRC(out)->tp_port
+            = htons(ofpact_get_SET_L4_SRC_PORT(a)->port);
+        break;
+
+    case OFPACT_SET_L4_DST_PORT:
+        ofputil_put_OFPAT11_SET_TP_DST(out)->tp_port
+            = htons(ofpact_get_SET_L4_DST_PORT(a)->port);
+        break;
+
+    case OFPACT_REG_MOVE:
+        nxm_reg_move_to_openflow(ofpact_get_REG_MOVE(a), out);
+        break;
+
+    case OFPACT_REG_LOAD:
+        nxm_reg_load_to_openflow(ofpact_get_REG_LOAD(a), out);
+        break;
+
+    case OFPACT_DEC_TTL:
+        ofputil_put_NXAST_DEC_TTL(out);
+        break;
+
+    case OFPACT_SET_TUNNEL:
+        /* FIXME: Is this generic or is an openflow11 version required ? */
+        ofpact_set_tunnel_to_openflow10(ofpact_get_SET_TUNNEL(a), out);
+        break;
+
+    case OFPACT_SET_QUEUE:
+        ofputil_put_NXAST_SET_QUEUE(out)->queue_id
+            = htonl(ofpact_get_SET_QUEUE(a)->queue_id);
+        break;
+
+    case OFPACT_POP_QUEUE:
+        ofputil_put_NXAST_POP_QUEUE(out);
+        break;
+
+    case OFPACT_RESUBMIT:
+        /* FIXME: Is this generic or is an openflow11 version required ? */
+        ofpact_resubmit_to_openflow10(ofpact_get_RESUBMIT(a), out);
+        break;
+
+    case OFPACT_LEARN:
+        learn_to_openflow(ofpact_get_LEARN(a), out);
+        break;
+
+    case OFPACT_MULTIPATH:
+        multipath_to_openflow(ofpact_get_MULTIPATH(a), out);
+        break;
+
+    case OFPACT_AUTOPATH:
+        autopath_to_openflow(ofpact_get_AUTOPATH(a), out);
+        break;
+
+    case OFPACT_NOTE:
+        /* FIXME: Is this generic or is an openflow11 version required ? */
+        ofpact_note_to_openflow10(ofpact_get_NOTE(a), out);
+        break;
+
+    case OFPACT_EXIT:
+        ofputil_put_NXAST_EXIT(out);
+        break;
+
+    case OFPACT_FIN_TIMEOUT:
+        /* FIXME: Is this generic or is an openflow11 version required ? */
+        ofpact_fin_timeout_to_openflow10(ofpact_get_FIN_TIMEOUT(a), out);
+        break;
+    }
+}
+
 /* Converts the ofpacts in 'ofpacts' (terminated by OFPACT_END) into OpenFlow
  * actions in 'openflow', appending the actions to any existing data in
  * 'openflow'. */
 void
-ofpacts_to_openflow(const struct ofpact ofpacts[], struct ofpbuf *openflow)
+ofpacts_to_openflow(const struct ofpact ofpacts[], struct ofpbuf *openflow,
+                    enum ofputil_protocol protocol)
 {
     const struct ofpact *a;
+    uint8_t ofp_version = ofputil_protocol_to_ofp_version(protocol);
+    static void (*f)(const struct ofpact *, struct ofpbuf *);
+
+    if (ofp_version == OFP11_VERSION || ofp_version == OFP12_VERSION) {
+        f = ofpact_to_openflow11;
+    } else if (ofp_version == OFP10_VERSION) {
+        f = ofpact_to_openflow10;
+    } else {
+        NOT_REACHED();
+    }
 
     OFPACT_FOR_EACH (a, ofpacts) {
-        ofpact_to_openflow10(a, openflow);
+        f(a, openflow);
     }
 }
 
diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h
index 6b86e25..915c147 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -389,7 +389,8 @@ enum ofperr ofpacts_check(const struct ofpact[],
                           const struct flow *, int max_ports);
 
 /* Converting ofpacts to OpenFlow. */
-void ofpacts_to_openflow(const struct ofpact[], struct ofpbuf *openflow);
+void ofpacts_to_openflow(const struct ofpact[], struct ofpbuf *openflow,
+                         enum ofputil_protocol protocol);
 
 /* 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 756c0f8..eaf7b04 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -1776,7 +1776,7 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm,
     }
 
     if (fm->ofpacts) {
-        ofpacts_to_openflow(fm->ofpacts, msg);
+        ofpacts_to_openflow(fm->ofpacts, msg, protocol);
     }
     update_openflow_length(msg);
     return msg;
@@ -2118,7 +2118,7 @@ ofputil_append_flow_stats_reply(const struct 
ofputil_flow_stats *fs,
                            htonll(unknown_to_zero(fs->packet_count)));
         put_32aligned_be64(&ofs->byte_count,
                            htonll(unknown_to_zero(fs->byte_count)));
-        ofpacts_to_openflow(fs->ofpacts, reply);
+        ofpacts_to_openflow(fs->ofpacts, reply, OFPUTIL_P_OF10);
 
         ofs = ofpbuf_at_assert(reply, start_ofs, sizeof *ofs);
         ofs->length = htons(reply->size - start_ofs);
@@ -2144,7 +2144,7 @@ ofputil_append_flow_stats_reply(const struct 
ofputil_flow_stats *fs,
         nfs->cookie = fs->cookie;
         nfs->packet_count = htonll(fs->packet_count);
         nfs->byte_count = htonll(fs->byte_count);
-        ofpacts_to_openflow(fs->ofpacts, reply);
+        ofpacts_to_openflow(fs->ofpacts, reply, OFPUTIL_P_NXM);
 
         nfs = ofpbuf_at_assert(reply, start_ofs, sizeof *nfs);
         nfs->length = htons(reply->size - start_ofs);
@@ -3064,7 +3064,7 @@ ofputil_encode_packet_out(const struct ofputil_packet_out 
*po)
 
     msg = ofpbuf_new(size);
     put_openflow(sizeof *opo, OFPT10_PACKET_OUT, msg);
-    ofpacts_to_openflow(po->ofpacts, msg);
+    ofpacts_to_openflow(po->ofpacts, msg, OFPUTIL_P_OF10);
 
     opo = msg->data;
     opo->buffer_id = htonl(po->buffer_id);
-- 
1.7.10.2.484.gcd07cc5

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to