[ovs-dev] [PATCH v3 06/12] ofp-actions: implement instruction encoder
Isaku Yamahata
yamahata at valinux.co.jp
Mon Jul 23 08:08:45 UTC 2012
Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
---
v3
- changed for OFPACT_{CLEAR_ACTIONS, WRITE_ACTIONS, GOTO_TABLE}
v2
- changed for ofp_instruction
---
lib/ofp-actions.c | 66 +++++++++++++++++++++++++++++++++++++++-------------
lib/ofp-util.c | 26 +++++++++++++++++++++
2 files changed, 75 insertions(+), 17 deletions(-)
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index d7b99f8..25d600b 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -1370,15 +1370,9 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
break;
case OFPACT_CLEAR_ACTIONS:
- NOT_REACHED(); /* TODO:XXX */
- break;
-
case OFPACT_WRITE_ACTIONS:
- NOT_REACHED(); /* TODO:XXX */
- break;
-
case OFPACT_GOTO_TABLE:
- NOT_REACHED(); /* TODO:XXX */
+ NOT_REACHED();
break;
case OFPACT_CONTROLLER:
@@ -1416,18 +1410,10 @@ ofpacts_put_openflow11_actions(const struct ofpact ofpacts[],
}
}
-void
-ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[],
- size_t ofpacts_len,
- struct ofpbuf *openflow)
+static void
+ofpacts_update_instruction_actions(struct ofpbuf *openflow, size_t ofs)
{
struct ofp11_instruction_actions *oia;
- size_t ofs;
-
- /* 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);
/* Update the instruction's length (or, if it's empty, delete it). */
oia = ofpbuf_at_assert(openflow, ofs, sizeof *oia);
@@ -1437,6 +1423,52 @@ 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)
+{
+ bool in_instruction;
+ size_t ofs;
+ const struct ofpact *a;
+
+ in_instruction = false;
+ ofs = 0;
+ OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
+ if (in_instruction && ofpact_is_instruction(a)) {
+ ofpacts_update_instruction_actions(openflow, ofs);
+ in_instruction = false;
+ ofs = 0;
+ }
+
+ if (a->type == OFPACT_CLEAR_ACTIONS) {
+ struct ofp11_instruction_actions *oia;
+ oia = instruction_put_OFPIT11_CLEAR_ACTIONS(openflow);
+ memset(oia->pad, 0, sizeof oia->pad);
+ } else if (a->type == OFPACT_WRITE_ACTIONS) {
+ in_instruction = true;
+ ofs = openflow->size;
+ instruction_put_OFPIT11_WRITE_ACTIONS(openflow);
+ /* TODO:XXX write-metadata */
+ } else if (a->type == OFPACT_GOTO_TABLE) {
+ struct ofp11_instruction_goto_table *oigt;
+ oigt = instruction_put_OFPIT11_GOTO_TABLE(openflow);
+ oigt->table_id = ofpact_get_GOTO_TABLE(a)->table_id;
+ memset(oigt->pad, 0, sizeof oigt->pad);
+ } else {
+ if (!in_instruction) {
+ in_instruction = true;
+ ofs = openflow->size;
+ instruction_put_OFPIT11_APPLY_ACTIONS(openflow);
+ }
+ ofpact_to_openflow11(a, openflow);
+ }
+ }
+ if (in_instruction) {
+ ofpacts_update_instruction_actions(openflow, ofs);
+ }
+}
/* Returns true if 'action' outputs to 'port', false otherwise. */
static bool
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index faa0687..cfa2a53 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -1788,6 +1788,32 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm,
: fm->command);
switch (protocol) {
+#if 0
+ case OFPUTIL_P_OF11: {
+ struct ofp11_flow_mod *ofm11;
+ msg = ofpbuf_new(sizeof *ofm11 + NXM_TYPICAL_LEN + fm->ofpacts_len);
+ ofm11 = put_openflow(sizeof *ofm11, ofp_version, OFPT11_FLOW_MOD, msg);
+ ofm11->cookie = fm->new_cookie;
+ ofm11->cookie_mask = fm->cookie_mask;
+ ofm11->table_id = fm->table_id;
+ ofm11->command = fm->command;
+ ofm11->idle_timeout = htons(fm->idle_timeout);
+ ofm11->hard_timeout = htons(fm->hard_timeout);
+ ofm11->priority = htons(fm->cr.priority);
+ ofm11->buffer_id = htonl(fm->buffer_id);
+ ofm11->out_port = ofputil_port_to_ofp11(fm->out_port);
+ ofm11->out_group = htonl(OFPG11_ANY);
+ ofm11->flags = htons(fm->flags);
+ memset(ofm11->pad, 0, sizeof ofm11->pad);
+ /* TODO:XXX ofm11::match */
+ if (fm->ofpacts) {
+ ofpacts_put_openflow11_instructions(fm->ofpacts, fm->ofpacts_len,
+ msg);
+ }
+ break;
+ }
+#endif
+
case OFPUTIL_P_OF10:
case OFPUTIL_P_OF10_TID:
msg = ofpbuf_new(sizeof *ofm + fm->ofpacts_len);
--
1.7.1.1
More information about the dev
mailing list