This patch adds support for parsing the pipeline match fields of
OpenFlow 1.5 packet-out messages. With this patch, we can use ovs-ofctl
to specify tunnel id and table metadata for a packet-out message.

Signed-off-by: Yi-Hung Wei <yihung....@gmail.com>
---
 lib/ofp-parse.c          | 21 ++++++++++++++++++++-
 tests/ofproto-dpif.at    | 36 ++++++++++++++++++++++++++++++++++++
 tests/ofproto.at         | 29 +++++++++++++++++++++++++++++
 utilities/ovs-ofctl.8.in | 13 +++++++++++++
 4 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 4fc352e03c4f..527b9bd6510b 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -616,6 +616,7 @@ parse_ofp_packet_out_str__(struct ofputil_packet_out *po, 
char *string,
     char *act_str = NULL;
     char *name, *value;
     char *error = NULL;
+    const char *error_msg;
 
     *usable_protocols = OFPUTIL_P_ANY;
 
@@ -649,11 +650,29 @@ parse_ofp_packet_out_str__(struct ofputil_packet_out *po, 
char *string,
             }
             match_set_in_port(&po->flow_metadata, in_port);
         } else if (!strcmp(name, "packet")) {
-            const char *error_msg = eth_from_hex(value, &packet);
+            error_msg = eth_from_hex(value, &packet);
             if (error_msg) {
                 error = xasprintf("%s: %s", name, error_msg);
                 goto out;
             }
+        } else if (!strcmp(name, "tun_id") || !strcmp(name, "tunnel_id")) {
+            uint64_t tun_id;
+            error_msg = str_to_u64(value, &tun_id);
+            if (error_msg) {
+                error = xasprintf("%s: %s", name, error_msg);
+                goto out;
+            }
+            match_set_tun_id(&po->flow_metadata, htonll(tun_id));
+            *usable_protocols |= OFPUTIL_P_OF15_UP;
+        } else if (!strcmp(name, "metadata")) {
+            uint64_t metadata;
+            error_msg = str_to_u64(value, &metadata);
+            if (error_msg) {
+                error = xasprintf("%s: %s", name, error_msg);
+                goto out;
+            }
+            match_set_metadata(&po->flow_metadata, htonll(metadata));
+            *usable_protocols |= OFPUTIL_P_OF15_UP;
         } else {
             error = xasprintf("unknown keyword %s", name);
             goto out;
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index e52ab32b9e5f..c3ec6538a677 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -731,6 +731,7 @@ AT_CHECK([tail -1 stdout], [0], [Datapath actions: 
4,6,8,10,12,2
 ])
 OVS_VSWITCHD_STOP
 AT_CLEANUP
+
 AT_SETUP([ofproto-dpif - push-pop])
 OVS_VSWITCHD_START
 add_of_ports br0 20 21 22 33 90
@@ -8359,6 +8360,41 @@ AT_CHECK([ovs-ofctl -O OpenFlow13 dump-tables br1 ], 
[0], [expout])
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([ofproto-dpif packet-out pipeline match field (OpenFlow 1.5)])
+OVS_VSWITCHD_START
+
+AT_DATA([flows.txt], [dnl
+table=0,in_port=1 actions=controller
+table=0,tun_id=3 actions=controller
+table=0,metadata=5 actions=controller
+])
+AT_CHECK([ovs-ofctl -O OpenFlow15 add-flows br0 flows.txt])
+
+AT_CHECK([ovs-ofctl -O OpenFlow15 -P standard monitor br0 --detach --no-chdir 
--pidfile])
+ovs-appctl -t ovs-ofctl ofctl/send 0609000c0123456700000080
+ovs-appctl -t ovs-ofctl ofctl/barrier
+ovs-appctl -t ovs-ofctl ofctl/set-output-file monitor.log
+AT_CAPTURE_FILE([monitor.log])
+
+AT_CHECK([ovs-ofctl -O OpenFlow15 packet-out br0 "in_port=1 
packet=0001020304050010203040501111 actions=table"])
+AT_CHECK([ovs-ofctl -O OpenFlow15 packet-out br0 "in_port=2 tunnel_id=3 
packet=0001020304050010203040502222 actions=table"])
+AT_CHECK([ovs-ofctl -O OpenFlow15 packet-out br0 "in_port=2 metadata=5 
packet=0001020304050010203040503333 actions=table"])
+
+ovs-appctl -t ovs-ofctl ofctl/barrier
+OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
+
+AT_CHECK([sed 's/ (xid=0x[[0-9a-fA-F]]*)//' monitor.log], [0], [dnl
+OFPT_PACKET_IN (OF1.5): cookie=0x0 total_len=14 in_port=1 (via packet_out) 
data_len=14 (unbuffered)
+vlan_tci=0x0000,dl_src=00:10:20:30:40:50,dl_dst=00:01:02:03:04:05,dl_type=0x1111
+OFPT_PACKET_IN (OF1.5): cookie=0x0 total_len=14 tun_id=0x3,in_port=2 (via 
packet_out) data_len=14 (unbuffered)
+vlan_tci=0x0000,dl_src=00:10:20:30:40:50,dl_dst=00:01:02:03:04:05,dl_type=0x2222
+OFPT_PACKET_IN (OF1.5): cookie=0x0 total_len=14 metadata=0x5,in_port=2 (via 
packet_out) data_len=14 (unbuffered)
+vlan_tci=0x0000,dl_src=00:10:20:30:40:50,dl_dst=00:01:02:03:04:05,dl_type=0x3333
+OFPT_BARRIER_REPLY (OF1.5):
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
 
 AT_SETUP([ofproto-dpif packet-out goto_table])
 OVS_VSWITCHD_START
diff --git a/tests/ofproto.at b/tests/ofproto.at
index 4431c157e9fc..428f8e1b591d 100644
--- a/tests/ofproto.at
+++ b/tests/ofproto.at
@@ -4082,6 +4082,35 @@ OFPT_BARRIER_REPLY (OF1.1):
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([ofproto - packet-out from controller (OpenFlow 1.5)])
+OVS_VSWITCHD_START
+
+# Start a monitor listening for packet-ins.
+AT_CHECK([ovs-ofctl -O OpenFlow15 -P standard monitor br0 --detach --no-chdir 
--pidfile])
+ovs-appctl -t ovs-ofctl ofctl/send 0609000c0123456700000080
+ovs-appctl -t ovs-ofctl ofctl/barrier
+ovs-appctl -t ovs-ofctl ofctl/set-output-file monitor.log
+AT_CAPTURE_FILE([monitor.log])
+
+# Send some packet-outs with OFPP_NONE and OFPP_CONTROLLER (65533) as in_port.
+AT_CHECK([ovs-ofctl -O OpenFlow15 packet-out br0 "in_port=none tun_id=0x11 
metadata=0x22 packet=0001020304050010203040501234 actions=controller"])
+AT_CHECK([ovs-ofctl -O OpenFlow15 packet-out br0 "in_port=controller 
tun_id=0x11 metadata=0x33 packet=0001020304050010203040505678 
actions=controller"])
+
+# Stop the monitor and check its output.
+ovs-appctl -t ovs-ofctl ofctl/barrier
+OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
+
+AT_CHECK([sed 's/ (xid=0x[[0-9a-fA-F]]*)//' monitor.log], [0], [dnl
+OFPT_PACKET_IN (OF1.5): total_len=14 tun_id=0x11,metadata=0x22,in_port=ANY 
(via packet_out) data_len=14 (unbuffered)
+vlan_tci=0x0000,dl_src=00:10:20:30:40:50,dl_dst=00:01:02:03:04:05,dl_type=0x1234
+OFPT_PACKET_IN (OF1.5): total_len=14 
tun_id=0x11,metadata=0x33,in_port=CONTROLLER (via packet_out) data_len=14 
(unbuffered)
+vlan_tci=0x0000,dl_src=00:10:20:30:40:50,dl_dst=00:01:02:03:04:05,dl_type=0x5678
+OFPT_BARRIER_REPLY (OF1.5):
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
 dnl This test checks that metadata and userdata are encoded in NXT_PACKET_IN2.
 AT_SETUP([ofproto - packet-out with metadata and userdata (NXT_PACKET_IN2)])
 OVS_VSWITCHD_START
diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
index a7e805587186..af9be5da962e 100644
--- a/utilities/ovs-ofctl.8.in
+++ b/utilities/ovs-ofctl.8.in
@@ -1920,6 +1920,19 @@ This can be any valid OpenFlow port number, or any of 
the \fBLOCAL\fR,
 .
 This field is required.
 
+.IP \fBtun_id=\fItunnel-id\fR
+.IP \fBtunnel_id=\fItunnel-id\fR
+The tunnel identifier to be considered when processing actions.
+.
+This field is optional.
+
+.IP \fBmetadata=\fIvalue\fR
+The table metadata to be considered when processing actions. \fIvalue\fR
+is 64-bit integer, by default in decimal (use a \fB0x\fR prefix to specify
+hexadecimal).
+.
+This field is optional.
+
 .IP \fBpacket=\fIhex-string\fR
 The actual packet to send, expressed as a string of hexadecimal bytes.
 .
-- 
2.7.4

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to