[ovs-dev] [PATCH 2/5] ofp-util: Add OpenFlow 1.5 packet-out support
Yi-Hung Wei
yihung.wei at gmail.com
Mon May 15 17:04:56 UTC 2017
This patch implements the encoding and decoding of the new packet-out
format defined in OpenFlow 1.5. Test cases are provided to verify the
encoding and decoding.
This patch is based on [1] and [2].
[1] https://github.com/jean2/openvswitch/commits/jean/ext-427
[2] https://mail.openvswitch.org/pipermail/ovs-dev/2017-April/331032.html
Signed-off-by: Jean Tourrilhes <jt at labs.hpe.com>
Signed-off-by: Zoltan Balogh <zoltan.balogh at ericsson.com>
Co-authored-by: Jan Scheurich <jan.scheurich at ericsson.com>
Signed-off-by: Yi-Hung Wei <yihung.wei at gmail.com>
---
NEWS | 1 +
include/openflow/openflow-1.5.h | 18 ++++++++++++++++
include/openvswitch/ofp-msgs.h | 7 +++++--
lib/ofp-util.c | 46 +++++++++++++++++++++++++++++++++++------
tests/ofp-print.at | 21 +++++++++++++++++++
5 files changed, 85 insertions(+), 8 deletions(-)
diff --git a/NEWS b/NEWS
index 7a2b185bbd84..5e42ce540bee 100644
--- a/NEWS
+++ b/NEWS
@@ -37,6 +37,7 @@ Post-v2.7.0
* Bundles now support hashing by just nw_src or nw_dst.
* The "learn" action now supports a "limit" option (see ovs-ofctl(8)).
* The port status bit OFPPS_LIVE now reflects link aliveness.
+ * OpenFlow 1.5 packet-out is now supported.
- Fedora Packaging:
* OVN services are no longer restarted automatically after upgrade.
- Add --cleanup option to command 'ovs-appctl exit' (see ovs-vswitchd(8)).
diff --git a/include/openflow/openflow-1.5.h b/include/openflow/openflow-1.5.h
index 3649e6c29e63..e6c731054f46 100644
--- a/include/openflow/openflow-1.5.h
+++ b/include/openflow/openflow-1.5.h
@@ -150,4 +150,22 @@ struct ofp15_group_desc_stats {
};
OFP_ASSERT(sizeof(struct ofp15_group_desc_stats) == 16);
+/* Send packet (controller -> datapath). */
+struct ofp15_packet_out {
+ ovs_be32 buffer_id; /* ID assigned by datapath (-1 if none). */
+ ovs_be16 actions_len; /* Size of action array in bytes. */
+ uint8_t pad[2];
+ /* Followed by:
+ * - Match
+ * - List of actions
+ * - Packet data
+ */
+ /* struct ofp12_match match; Packet pipeline fields. Variable size. */
+ /* struct ofp_action_header actions[0]; Action list. */
+ /* uint8_t data[0]; */ /* Packet data. The length is inferred
+ from the length field in the header.
+ (Only meaningful if buffer_id == -1.) */
+};
+OFP_ASSERT(sizeof(struct ofp15_packet_out) == 8);
+
#endif /* openflow/openflow-1.5.h */
diff --git a/include/openvswitch/ofp-msgs.h b/include/openvswitch/ofp-msgs.h
index 34708f3bd846..6dc0b60e1816 100644
--- a/include/openvswitch/ofp-msgs.h
+++ b/include/openvswitch/ofp-msgs.h
@@ -177,8 +177,10 @@ enum ofpraw {
/* OFPT 1.0 (13): struct ofp10_packet_out, uint8_t[]. */
OFPRAW_OFPT10_PACKET_OUT,
- /* OFPT 1.1+ (13): struct ofp11_packet_out, uint8_t[]. */
+ /* OFPT 1.1-1.4 (13): struct ofp11_packet_out, uint8_t[]. */
OFPRAW_OFPT11_PACKET_OUT,
+ /* OFPT 1.5+ (13): struct ofp15_packet_out, uint8_t[]. */
+ OFPRAW_OFPT15_PACKET_OUT,
/* OFPT 1.0 (14): struct ofp10_flow_mod, uint8_t[8][]. */
OFPRAW_OFPT10_FLOW_MOD,
@@ -561,7 +563,8 @@ enum ofptype {
/* Controller command messages. */
OFPTYPE_PACKET_OUT, /* OFPRAW_OFPT10_PACKET_OUT.
- * OFPRAW_OFPT11_PACKET_OUT. */
+ * OFPRAW_OFPT11_PACKET_OUT.
+ * OFPRAW_OFPT15_PACKET_OUT. */
OFPTYPE_FLOW_MOD, /* OFPRAW_OFPT10_FLOW_MOD.
* OFPRAW_OFPT11_FLOW_MOD.
* OFPRAW_NXT_FLOW_MOD. */
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index f79be7389585..b4d63931ecdb 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -4202,11 +4202,30 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po,
{
struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
enum ofpraw raw = ofpraw_pull_assert(&b);
+ enum ofperr error;
ofpbuf_clear(ofpacts);
match_init_catchall(&po->flow_metadata);
- if (raw == OFPRAW_OFPT11_PACKET_OUT) {
- enum ofperr error;
+ if (raw == OFPRAW_OFPT15_PACKET_OUT) {
+ const struct ofp15_packet_out *opo = ofpbuf_pull(&b, sizeof *opo);
+
+ po->buffer_id = ntohl(opo->buffer_id);
+ error = oxm_pull_match_loose(&b, NULL, &po->flow_metadata);
+ if (error) {
+ return error;
+ }
+
+ if (!po->flow_metadata.wc.masks.in_port.ofp_port) {
+ return OFPERR_OFPBRC_BAD_PORT;
+ }
+
+ error = ofpacts_pull_openflow_actions(&b, ntohs(opo->actions_len),
+ oh->version, NULL, NULL,
+ ofpacts);
+ if (error) {
+ return error;
+ }
+ } else if (raw == OFPRAW_OFPT11_PACKET_OUT) {
ofp_port_t in_port;
const struct ofp11_packet_out *opo = ofpbuf_pull(&b, sizeof *opo);
@@ -4224,7 +4243,6 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po,
return error;
}
} else if (raw == OFPRAW_OFPT10_PACKET_OUT) {
- enum ofperr error;
const struct ofp10_packet_out *opo = ofpbuf_pull(&b, sizeof *opo);
po->buffer_id = ntohl(opo->buffer_id);
@@ -7065,9 +7083,7 @@ ofputil_encode_packet_out(const struct ofputil_packet_out *po,
case OFP11_VERSION:
case OFP12_VERSION:
case OFP13_VERSION:
- case OFP14_VERSION:
- case OFP15_VERSION:
- case OFP16_VERSION: {
+ case OFP14_VERSION: {
struct ofp11_packet_out *opo;
size_t len;
@@ -7083,6 +7099,24 @@ ofputil_encode_packet_out(const struct ofputil_packet_out *po,
break;
}
+ case OFP15_VERSION:
+ case OFP16_VERSION: {
+ struct ofp15_packet_out *opo;
+ size_t len;
+
+ /* The final argument is just an estimate of the space required. */
+ msg = ofpraw_alloc(OFPRAW_OFPT15_PACKET_OUT, ofp_version,
+ size + NXM_TYPICAL_LEN);
+ ofpbuf_put_zeros(msg, sizeof *opo);
+ oxm_put_match(msg, &po->flow_metadata, ofp_version);
+ len = ofpacts_put_openflow_actions(po->ofpacts, po->ofpacts_len, msg,
+ ofp_version);
+ opo = msg->msg;
+ opo->buffer_id = htonl(po->buffer_id);
+ opo->actions_len = htons(len);
+ break;
+ }
+
default:
OVS_NOT_REACHED();
}
diff --git a/tests/ofp-print.at b/tests/ofp-print.at
index dfa26e0ce2ae..6b950a0d90e9 100644
--- a/tests/ofp-print.at
+++ b/tests/ofp-print.at
@@ -796,6 +796,27 @@ tcp,vlan_tci=0x0000,dl_src=50:54:00:00:00:06,dl_dst=50:54:00:00:00:05,nw_src=192
])
AT_CLEANUP
+AT_SETUP([OFPT_PACKET_OUT - OF1.5])
+AT_KEYWORDS([ofp-print packet-out])
+AT_CHECK([ovs-ofctl ofp-print "\
+06 0d 00 30 11 22 33 44 ff ff ff 00 00 10 00 00 \
+00 01 00 10 80 00 00 04 00 00 00 01 00 00 00 00 \
+00 00 00 10 ff ff ff fb 05 dc 00 00 00 00 00 00 \
+"], [0], [dnl
+OFPT_PACKET_OUT (OF1.5) (xid=0x11223344): in_port=1 actions=FLOOD buffer=0xffffff00
+])
+
+dnl missing in_port
+AT_CHECK([ovs-ofctl ofp-print "\
+06 0d 00 40 11 22 33 44 ff ff ff 00 00 10 00 00 \
+00 01 00 20 80 00 04 08 00 00 00 00 00 00 00 03 \
+80 00 4C 08 00 00 00 00 00 00 00 05 00 00 00 00 \
+00 00 00 10 ff ff ff fb 05 dc 00 00 00 00 00 00 \
+"], [0], [dnl
+OFPT_PACKET_OUT (OF1.5) (xid=0x11223344): ***decode error: OFPBRC_BAD_PORT***
+])
+AT_CLEANUP
+
# The flow is formatted with cls_rule_format() for the low-verbosity case.
AT_SETUP([OFPT_FLOW_MOD - OF1.0 - low verbosity])
AT_KEYWORDS([ofp-print])
--
2.7.4
More information about the dev
mailing list