Signed-off-by: Isaku Yamahata <[email protected]>
---
v2
newly created
---
lib/ofp-actions.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++-
lib/ofp-actions.h | 3 +-
lib/ofp-parse.c | 1 +
lib/ofp-util.c | 8 +++--
lib/ofp-util.def | 2 +-
5 files changed, 84 insertions(+), 7 deletions(-)
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 0b1945f..63cc2b6 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -648,6 +648,72 @@ ofpacts_from_openflow11(const union ofp_action *in, size_t
n_in,
return ofpacts_from_openflow(in, n_in, out, ofpact_from_openflow11);
}
+static enum ofperr
+decode_openflow12_action(const union ofp_action *a,
+ enum ofputil_action_code *code)
+{
+ switch (a->type) {
+ case CONSTANT_HTONS(OFPAT12_EXPERIMENTER):
+ return decode_nxast_action(a, code);
+
+#define OFPAT12_ACTION(ENUM, STRUCT, NAME) \
+ case CONSTANT_HTONS(ENUM): \
+ if (a->header.len == htons(sizeof(struct STRUCT))) { \
+ *code = OFPUTIL_##ENUM; \
+ return 0; \
+ } else { \
+ return OFPERR_OFPBAC_BAD_LEN; \
+ } \
+ break;
+#include "ofp-util.def"
+
+ default:
+ return OFPERR_OFPBAC_BAD_TYPE;
+ }
+}
+
+static enum ofperr
+ofpact_from_openflow12(const union ofp_action *a, struct ofpbuf *out)
+{
+ /* XXX */
+ enum ofputil_action_code code;
+ enum ofperr error;
+
+ error = decode_openflow12_action(a, &code);
+ if (error) {
+ return error;
+ }
+
+ switch (code) {
+ case OFPUTIL_ACTION_INVALID:
+#define OFPAT10_ACTION(ENUM, STRUCT, NAME) case OFPUTIL_##ENUM:
+#define OFPAT11_ACTION(ENUM, STRUCT, NAME) case OFPUTIL_##ENUM:
+#include "ofp-util.def"
+ NOT_REACHED();
+
+ case OFPUTIL_OFPAT12_OUTPUT:
+ return output_from_openflow11((const struct ofp11_action_output *) a,
+ out);
+
+ case OFPUTIL_OFPAT12_SET_FIELD:
+ return nxm_reg_load_from_openflow12_set_field(
+ (const struct ofp12_action_set_field *)a, out);
+
+#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) case OFPUTIL_##ENUM:
+#include "ofp-util.def"
+ return ofpact_from_nxast(a, code, out);
+ }
+
+ return error;
+}
+
+static enum ofperr
+ofpacts_from_openflow12(const union ofp_action *in, size_t n_in,
+ struct ofpbuf *out)
+{
+ return ofpacts_from_openflow(in, n_in, out, ofpact_from_openflow12);
+}
+
/* OpenFlow 1.1 instructions. */
#define OVS_INSTRUCTIONS \
@@ -778,7 +844,8 @@ get_actions_from_instruction(const struct ofp11_instruction
*inst,
}
enum ofperr
-ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow,
+ofpacts_pull_openflow11_instructions(uint8_t ofp_version,
+ struct ofpbuf *openflow,
unsigned int instructions_len,
struct ofpbuf *ofpacts)
{
@@ -819,7 +886,13 @@ ofpacts_pull_openflow11_instructions(struct ofpbuf
*openflow,
get_actions_from_instruction(insts[OVSINST_OFPIT11_APPLY_ACTIONS],
&actions, &n_actions);
- error = ofpacts_from_openflow11(actions, n_actions, ofpacts);
+ if (ofp_version == OFP12_VERSION) {
+ error = ofpacts_from_openflow12(actions, n_actions, ofpacts);
+ } else if (ofp_version == OFP11_VERSION){
+ error = ofpacts_from_openflow11(actions, n_actions, ofpacts);
+ } else {
+ NOT_REACHED();
+ }
if (error) {
goto exit;
}
diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h
index 47c9b7d..f2c9861 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -383,7 +383,8 @@ struct ofpact_note {
enum ofperr ofpacts_pull_openflow10(struct ofpbuf *openflow,
unsigned int actions_len,
struct ofpbuf *ofpacts);
-enum ofperr ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow,
+enum ofperr ofpacts_pull_openflow11_instructions(uint8_t ofp_version,
+ struct ofpbuf *openflow,
unsigned int instructions_len,
struct ofpbuf *ofpacts);
enum ofperr ofpacts_check(const struct ofpact[],
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 09fdc4a..f2ad4b2 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -294,6 +294,7 @@ parse_named_action(enum ofputil_action_code code, const
struct flow *flow,
case OFPUTIL_OFPAT10_OUTPUT:
case OFPUTIL_OFPAT11_OUTPUT:
+ case OFPUTIL_OFPAT12_OUTPUT:
parse_output(arg, ofpacts);
break;
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index fe95137..46a9e59 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -1744,7 +1744,8 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
return error;
}
- error = ofpacts_pull_openflow11_instructions(&b, b.size, ofpacts);
+ error = ofpacts_pull_openflow11_instructions(oh->version,
+ &b, b.size, ofpacts);
if (error) {
return error;
}
@@ -2239,7 +2240,8 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats
*fs,
return EINVAL;
}
- if (ofpacts_pull_openflow11_instructions(msg, msg->size, ofpacts)) {
+ if (ofpacts_pull_openflow11_instructions(oh->version,
+ msg, msg->size, ofpacts)) {
VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply bad instructions");
return EINVAL;
}
@@ -2905,7 +2907,7 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po,
return error;
}
- error = ofpacts_pull_openflow11_instructions(&b,
+ error = ofpacts_pull_openflow11_instructions(oh->version, &b,
ntohs(opo->actions_len),
ofpacts);
if (error) {
diff --git a/lib/ofp-util.def b/lib/ofp-util.def
index 8f21e90..dfffd61 100644
--- a/lib/ofp-util.def
+++ b/lib/ofp-util.def
@@ -39,7 +39,7 @@ OFPAT11_ACTION(OFPAT11_SET_TP_DST, ofp_action_tp_port,
"mod_tp_dst")
#ifndef OFPAT12_ACTION
#define OFPAT12_ACTION(ENUM, STRUCT, NAME)
#endif
-//OFPAT12_ACTION(OFPAT12_OUTPUT, , "output")
+OFPAT12_ACTION(OFPAT12_OUTPUT, ofp11_action_output, "output")
//OFPAT12_ACTION(OFPAT12_COPY_TTL_OUT, ofp_action_header, "copy_ttl_out")
//OFPAT12_ACTION(OFPAT12_COPY_TTL_IN, ofp_action_header, "copy_ttl_in")
//OFPAT12_ACTION(OFPAT12_SET_MPLS_TTL, , "set_mpls_ttl")
--
1.7.1.1
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev