[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