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