From: Yi-Hung Wei Date: Mon, 15 May 2017 17:04:58 +0000 (-0700) Subject: ofp-parse: Parse pipeline fields in OF1.5 packet-out X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=880b145831ad1f2b0af2d08c4ad435ca0b6c98ad;p=ovs.git ofp-parse: Parse pipeline fields in OF1.5 packet-out 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 pipeline fileds for a packet-out message. Signed-off-by: Yi-Hung Wei Signed-off-by: Ben Pfaff --- diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index 7b0d23feb..afb8b40cc 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -622,6 +622,7 @@ parse_ofp_packet_out_str__(struct ofputil_packet_out *po, char *string, *po = (struct ofputil_packet_out) { .buffer_id = UINT32_MAX, }; + match_init_catchall(&po->flow_metadata); match_set_in_port(&po->flow_metadata, OFPP_CONTROLLER); act_str = extract_actions(string); @@ -655,8 +656,22 @@ parse_ofp_packet_out_str__(struct ofputil_packet_out *po, char *string, goto out; } } else { - error = xasprintf("unknown keyword %s", name); - goto out; + const struct mf_field *mf = mf_from_name(name); + if (!mf) { + error = xasprintf("unknown keyword %s", name); + goto out; + } + + error = parse_field(mf, value, &po->flow_metadata, + usable_protocols); + if (error) { + goto out; + } + if (!mf_is_pipeline_field(mf)) { + error = xasprintf("%s is not a valid pipeline field " + "for PACKET_OUT", name); + goto out; + } } } diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index 1f6cd8422..743ac2ab3 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 @@ -8368,6 +8369,50 @@ 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 +table=0,reg0=1,reg4=2,reg8=3,reg12=5 actions=controller +table=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_gbp_id=0x01,tun_gbp_flags=0x03 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"]) +AT_CHECK([ovs-ofctl -O OpenFlow15 packet-out br0 "in_port=2,reg0=1,reg4=2,reg8=3,reg12=5 packet=0001020304050010203040503333 actions=table"]) +AT_CHECK([ovs-ofctl -O OpenFlow15 packet-out br0 "in_port=2,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_gbp_id=0x01,tun_gbp_flags=0x03 packet=0001020304050010203040503333 actions=table"]) +AT_CHECK([ovs-ofctl -O OpenFlow15 packet-out br0 "in_port=2,tun_metadata33=3 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_PACKET_IN (OF1.5): cookie=0x0 total_len=14 reg0=0x1,reg4=0x2,reg8=0x3,reg12=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_PACKET_IN (OF1.5): cookie=0x0 total_len=14 tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_gbp_id=1,tun_gbp_flags=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=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 5431f4e8d..6a4e26d98 100644 --- a/tests/ofproto.at +++ b/tests/ofproto.at @@ -4078,6 +4078,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 ed75b32a3..6ebbc526c 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -1920,6 +1920,11 @@ This can be any valid OpenFlow port number, or any of the \fBLOCAL\fR, . This field is required. +.IP \fIpipeline_field\fR=\fIvalue\fR +Optionally, user can specify a list of pipeline fields for a packet-out +message. The supported pipeline fields includes \fBtunnel fields\fR and +\fBregister fields\fR as defined in \fBovs\-fields\fR(7). + .IP \fBpacket=\fIhex-string\fR The actual packet to send, expressed as a string of hexadecimal bytes. .