diff mbox series

[ovs-dev,v6,8/9] dpif-netlink: Offloading meter to tc police action

Message ID 20220702031832.13282-9-jianbol@nvidia.com
State Superseded
Headers show
Series Add support for ovs metering with tc offload | expand

Checks

Context Check Description
ovsrobot/apply-robot warning apply and check: warning
ovsrobot/intel-ovs-compilation success test: success

Commit Message

Jianbo Liu July 2, 2022, 3:18 a.m. UTC
OVS meters are created in advance and openflow rules refer to them by
their unique ID. New tc_police API is used to offload them. By calling
the API, police actions are created and meters are mapped to them.
These actions then can be used in tc filter rules by the index.

Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
---
 NEWS                             |  2 +
 lib/dpif-netlink.c               | 31 ++++++++--
 tests/system-offloads-traffic.at | 98 ++++++++++++++++++++++++++++++++
 3 files changed, 126 insertions(+), 5 deletions(-)

Comments

Eelco Chaudron July 7, 2022, 11:53 a.m. UTC | #1
On 2 Jul 2022, at 5:18, Jianbo Liu wrote:

> OVS meters are created in advance and openflow rules refer to them by
> their unique ID. New tc_police API is used to offload them. By calling
> the API, police actions are created and meters are mapped to them.
> These actions then can be used in tc filter rules by the index.

Three small change requests on the test cases...

//Eelco

<SNIP>
> +
> +AT_SETUP([offloads - check interface meter offloading ])

Can we stick to the naming convention used by the other test cases?
So this should be:

AT_SETUP([offloads - check interface meter offloading -  offloads enabled])


> +AT_KEYWORDS([offload-meter])
> +AT_SKIP_IF([test $SUPPORT_TC_INGRESS_PPS = "no"])
> +OVS_TRAFFIC_VSWITCHD_START()
> +
> +AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:hw-offload=true])
> +AT_CHECK([ovs-ofctl -O OpenFlow13 add-meter br0 'meter=1 pktps bands=type=drop rate=1'])
> +
> +ADD_NAMESPACES(at_ns0, at_ns1)
> +ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24", "f0:00:00:01:01:01")
> +ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24", "f0:00:00:01:01:02")
> +
> +NS_CHECK_EXEC([at_ns0], [ip neigh add 10.1.1.2 lladdr f0:00:00:01:01:02 dev p0])
> +NS_CHECK_EXEC([at_ns1], [ip neigh add 10.1.1.1 lladdr f0:00:00:01:01:01 dev p1])
> +
> +AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "actions=normal"])
> +NS_CHECK_EXEC([at_ns0], [ping -q -c 10 -i 0.1 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl
> +10 packets transmitted, 10 received, 0% packet loss, time 0ms
> +])
> +
> +NETNS_DAEMONIZE([at_ns1], [nc -u -l 5678 > /dev/null ], [nc0.pid])
> +
> +AT_CHECK([ovs-ofctl -O OpenFlow13 del-flows br0])
> +AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "priority=10,in_port=ovs-p0,udp actions=meter:1,normal"])
> +AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "priority=1 actions=normal"])
> +
> +NS_CHECK_EXEC([at_ns0], [echo "mark" | nc -u 10.1.1.2 5678 -p 6789])
> +AT_CHECK([ovs-appctl dpctl/dump-flows | grep "meter" | DUMP_CLEAN_SORTED], [0], [dnl
> +in_port(2),eth(macs),eth_type(0x0800),ipv4(proto=17,frag=no), packets:0, bytes:0, used:0.001s, actions:outputmeter(0),3
> +])
> +
> +sleep 1
> +
> +for i in `seq 10`; do
> +NS_CHECK_EXEC([at_ns0], [echo "mark" | nc -u 10.1.1.2 5678 -p 6789])
> +done
> +
> +AT_CHECK([ovs-appctl dpctl/dump-flows | grep "meter" | DUMP_CLEAN_SORTED], [0], [dnl
> +in_port(2),eth(macs),eth_type(0x0800),ipv4(proto=17,frag=no), packets:10, bytes:330, used:0.001s, actions:outputmeter(0),3
> +])
> +
> +AT_CHECK([ovs-ofctl -O OpenFlow13 meter-stats br0 | sed -e 's/duration:[[0-9]].[[0-9]]*s/duration:0.001s/'], [0], [dnl
> +OFPST_METER reply (OF1.3) (xid=0x2):
> +meter:1 flow_count:1 packet_in_count:11 byte_in_count:377 duration:0.001s bands:
> +0: packet_count:9 byte_count:0
> +])
> +
> +OVS_TRAFFIC_VSWITCHD_STOP
> +AT_CLEANUP
> +
> +AT_SETUP([unoffload meter - Check DP meter ])

This test should be executed before the offloads enabled test case to be the same as all other features.

Also, can we stick to the naming convention used by the other test cases?
So this should be:

AT_SETUP([offloads - check interface meter offloading -  offloads disabled])

> +AT_KEYWORDS([dp-meter])
> +OVS_TRAFFIC_VSWITCHD_START()
> +
> +AT_CHECK([ovs-ofctl -O OpenFlow13 add-meter br0 'meter=1 pktps bands=type=drop rate=1'])
> +
> +ADD_NAMESPACES(at_ns0, at_ns1)
> +ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24", "f0:00:00:01:01:01")
> +ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24", "f0:00:00:01:01:02")
> +
> +NS_CHECK_EXEC([at_ns0], [ip neigh add 10.1.1.2 lladdr f0:00:00:01:01:02 dev p0])
> +NS_CHECK_EXEC([at_ns1], [ip neigh add 10.1.1.1 lladdr f0:00:00:01:01:01 dev p1])
> +
> +AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "actions=normal"])
> +NS_CHECK_EXEC([at_ns0], [ping -q -c 10 -i 0.1 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl
> +10 packets transmitted, 10 received, 0% packet loss, time 0ms
> +])
> +
> +NETNS_DAEMONIZE([at_ns1], [nc -u -l 5678 > /dev/null ], [nc0.pid])
> +
> +AT_CHECK([ovs-ofctl -O OpenFlow13 del-flows br0])
> +AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "priority=10,in_port=ovs-p0,udp actions=meter:1,normal"])
> +AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "priority=1 actions=normal"])
> +
> +NS_CHECK_EXEC([at_ns0], [echo "mark" | nc -u 10.1.1.2 5678 -p 6789])
> +AT_CHECK([ovs-appctl dpctl/dump-flows | grep "meter" | DUMP_CLEAN_SORTED], [0], [dnl
> +in_port(2),eth(macs),eth_type(0x0800),ipv4(proto=17,frag=no), packets:0, bytes:0, used:never, actions:outputmeter(0),3
> +])
> +
> +sleep 1
> +
> +for i in `seq 10`; do
> +NS_CHECK_EXEC([at_ns0], [echo "mark" | nc -u 10.1.1.2 5678 -p 6789])
> +done
> +
> +AT_CHECK([ovs-appctl dpctl/dump-flows | grep "meter" | DUMP_CLEAN_SORTED], [0], [dnl
> +in_port(2),eth(macs),eth_type(0x0800),ipv4(proto=17,frag=no), packets:10, bytes:470, used:0.001s, actions:outputmeter(0),3
> +])
> +
> +AT_CHECK([ovs-ofctl -O OpenFlow13 meter-stats br0 | sed -e 's/duration:[[0-9]].[[0-9]]*s/duration:0.001s/'], [0], [dnl
> +OFPST_METER reply (OF1.3) (xid=0x2):
> +meter:1 flow_count:1 packet_in_count:11 byte_in_count:517 duration:0.001s bands:
> +0: packet_count:9 byte_count:423
> +])
> +
> +OVS_TRAFFIC_VSWITCHD_STOP
> +AT_CLEANUP
> -- 
> 2.26.2
Jianbo Liu July 8, 2022, 1:43 a.m. UTC | #2
On Thu, 2022-07-07 at 13:53 +0200, Eelco Chaudron wrote:
> On 2 Jul 2022, at 5:18, Jianbo Liu wrote:
> 
> > OVS meters are created in advance and openflow rules refer to them
> > by
> > their unique ID. New tc_police API is used to offload them. By
> > calling
> > the API, police actions are created and meters are mapped to them.
> > These actions then can be used in tc filter rules by the index.
> 
> Three small change requests on the test cases...
> 

Yes, I will change. Thanks!

> //Eelco
> 
> <SNIP>
> > +
> > +AT_SETUP([offloads - check interface meter offloading ])
> 
> Can we stick to the naming convention used by the other test cases?
> So this should be:
> 
> AT_SETUP([offloads - check interface meter offloading -  offloads
> enabled])
> 
> 
> > +AT_KEYWORDS([offload-meter])
> > +AT_SKIP_IF([test $SUPPORT_TC_INGRESS_PPS = "no"])
> > +OVS_TRAFFIC_VSWITCHD_START()
> > +
> > +AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:hw-
> > offload=true])
> > +AT_CHECK([ovs-ofctl -O OpenFlow13 add-meter br0 'meter=1 pktps
> > bands=type=drop rate=1'])
> > +
> > +ADD_NAMESPACES(at_ns0, at_ns1)
> > +ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24", "f0:00:00:01:01:01")
> > +ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24", "f0:00:00:01:01:02")
> > +
> > +NS_CHECK_EXEC([at_ns0], [ip neigh add 10.1.1.2 lladdr
> > f0:00:00:01:01:02 dev p0])
> > +NS_CHECK_EXEC([at_ns1], [ip neigh add 10.1.1.1 lladdr
> > f0:00:00:01:01:01 dev p1])
> > +
> > +AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "actions=normal"])
> > +NS_CHECK_EXEC([at_ns0], [ping -q -c 10 -i 0.1 -w 2 10.1.1.2 |
> > FORMAT_PING], [0], [dnl
> > +10 packets transmitted, 10 received, 0% packet loss, time 0ms
> > +])
> > +
> > +NETNS_DAEMONIZE([at_ns1], [nc -u -l 5678 > /dev/null ], [nc0.pid])
> > +
> > +AT_CHECK([ovs-ofctl -O OpenFlow13 del-flows br0])
> > +AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0
> > "priority=10,in_port=ovs-p0,udp actions=meter:1,normal"])
> > +AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "priority=1
> > actions=normal"])
> > +
> > +NS_CHECK_EXEC([at_ns0], [echo "mark" | nc -u 10.1.1.2 5678 -p
> > 6789])
> > +AT_CHECK([ovs-appctl dpctl/dump-flows | grep "meter" |
> > DUMP_CLEAN_SORTED], [0], [dnl
> > +in_port(2),eth(macs),eth_type(0x0800),ipv4(proto=17,frag=no),
> > packets:0, bytes:0, used:0.001s, actions:outputmeter(0),3
> > +])
> > +
> > +sleep 1
> > +
> > +for i in `seq 10`; do
> > +NS_CHECK_EXEC([at_ns0], [echo "mark" | nc -u 10.1.1.2 5678 -p
> > 6789])
> > +done
> > +
> > +AT_CHECK([ovs-appctl dpctl/dump-flows | grep "meter" |
> > DUMP_CLEAN_SORTED], [0], [dnl
> > +in_port(2),eth(macs),eth_type(0x0800),ipv4(proto=17,frag=no),
> > packets:10, bytes:330, used:0.001s, actions:outputmeter(0),3
> > +])
> > +
> > +AT_CHECK([ovs-ofctl -O OpenFlow13 meter-stats br0 | sed -e
> > 's/duration:[[0-9]].[[0-9]]*s/duration:0.001s/'], [0], [dnl
> > +OFPST_METER reply (OF1.3) (xid=0x2):
> > +meter:1 flow_count:1 packet_in_count:11 byte_in_count:377
> > duration:0.001s bands:
> > +0: packet_count:9 byte_count:0
> > +])
> > +
> > +OVS_TRAFFIC_VSWITCHD_STOP
> > +AT_CLEANUP
> > +
> > +AT_SETUP([unoffload meter - Check DP meter ])
> 
> This test should be executed before the offloads enabled test case to
> be the same as all other features.
> 
> Also, can we stick to the naming convention used by the other test
> cases?
> So this should be:
> 
> AT_SETUP([offloads - check interface meter offloading -  offloads
> disabled])
> 
> > +AT_KEYWORDS([dp-meter])
> > +OVS_TRAFFIC_VSWITCHD_START()
> > +
> > +AT_CHECK([ovs-ofctl -O OpenFlow13 add-meter br0 'meter=1 pktps
> > bands=type=drop rate=1'])
> > +
> > +ADD_NAMESPACES(at_ns0, at_ns1)
> > +ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24", "f0:00:00:01:01:01")
> > +ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24", "f0:00:00:01:01:02")
> > +
> > +NS_CHECK_EXEC([at_ns0], [ip neigh add 10.1.1.2 lladdr
> > f0:00:00:01:01:02 dev p0])
> > +NS_CHECK_EXEC([at_ns1], [ip neigh add 10.1.1.1 lladdr
> > f0:00:00:01:01:01 dev p1])
> > +
> > +AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "actions=normal"])
> > +NS_CHECK_EXEC([at_ns0], [ping -q -c 10 -i 0.1 -w 2 10.1.1.2 |
> > FORMAT_PING], [0], [dnl
> > +10 packets transmitted, 10 received, 0% packet loss, time 0ms
> > +])
> > +
> > +NETNS_DAEMONIZE([at_ns1], [nc -u -l 5678 > /dev/null ], [nc0.pid])
> > +
> > +AT_CHECK([ovs-ofctl -O OpenFlow13 del-flows br0])
> > +AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0
> > "priority=10,in_port=ovs-p0,udp actions=meter:1,normal"])
> > +AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "priority=1
> > actions=normal"])
> > +
> > +NS_CHECK_EXEC([at_ns0], [echo "mark" | nc -u 10.1.1.2 5678 -p
> > 6789])
> > +AT_CHECK([ovs-appctl dpctl/dump-flows | grep "meter" |
> > DUMP_CLEAN_SORTED], [0], [dnl
> > +in_port(2),eth(macs),eth_type(0x0800),ipv4(proto=17,frag=no),
> > packets:0, bytes:0, used:never, actions:outputmeter(0),3
> > +])
> > +
> > +sleep 1
> > +
> > +for i in `seq 10`; do
> > +NS_CHECK_EXEC([at_ns0], [echo "mark" | nc -u 10.1.1.2 5678 -p
> > 6789])
> > +done
> > +
> > +AT_CHECK([ovs-appctl dpctl/dump-flows | grep "meter" |
> > DUMP_CLEAN_SORTED], [0], [dnl
> > +in_port(2),eth(macs),eth_type(0x0800),ipv4(proto=17,frag=no),
> > packets:10, bytes:470, used:0.001s, actions:outputmeter(0),3
> > +])
> > +
> > +AT_CHECK([ovs-ofctl -O OpenFlow13 meter-stats br0 | sed -e
> > 's/duration:[[0-9]].[[0-9]]*s/duration:0.001s/'], [0], [dnl
> > +OFPST_METER reply (OF1.3) (xid=0x2):
> > +meter:1 flow_count:1 packet_in_count:11 byte_in_count:517
> > duration:0.001s bands:
> > +0: packet_count:9 byte_count:423
> > +])
> > +
> > +OVS_TRAFFIC_VSWITCHD_STOP
> > +AT_CLEANUP
> > -- 
> > 2.26.2
>
diff mbox series

Patch

diff --git a/NEWS b/NEWS
index 994fdf6a9..6e07ef08c 100644
--- a/NEWS
+++ b/NEWS
@@ -43,6 +43,8 @@  Post-v2.17.0
      * 'dpif-netdev/subtable-lookup-prio-get' appctl command renamed to
        'dpif-netdev/subtable-lookup-info-get' to better reflect its purpose.
        The old variant is kept for backward compatibility.
+   - Linux datapath:
+     * Add offloading meter tc police.
 
 
 v2.17.0 - 17 Feb 2022
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index 06e1e8ca0..a498d5667 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -4163,11 +4163,18 @@  static int
 dpif_netlink_meter_set(struct dpif *dpif_, ofproto_meter_id meter_id,
                        struct ofputil_meter_config *config)
 {
+    int err;
+
     if (probe_broken_meters(dpif_)) {
         return ENOMEM;
     }
 
-    return dpif_netlink_meter_set__(dpif_, meter_id, config);
+    err = dpif_netlink_meter_set__(dpif_, meter_id, config);
+    if (!err && netdev_is_flow_api_enabled()) {
+        meter_offload_set(meter_id, config);
+    }
+
+    return err;
 }
 
 /* Retrieve statistics and/or delete meter 'meter_id'.  Statistics are
@@ -4258,16 +4265,30 @@  static int
 dpif_netlink_meter_get(const struct dpif *dpif, ofproto_meter_id meter_id,
                        struct ofputil_meter_stats *stats, uint16_t max_bands)
 {
-    return dpif_netlink_meter_get_stats(dpif, meter_id, stats, max_bands,
-                                        OVS_METER_CMD_GET);
+    int err;
+
+    err = dpif_netlink_meter_get_stats(dpif, meter_id, stats, max_bands,
+                                       OVS_METER_CMD_GET);
+    if (!err && netdev_is_flow_api_enabled()) {
+        meter_offload_get(meter_id, stats);
+    }
+
+    return err;
 }
 
 static int
 dpif_netlink_meter_del(struct dpif *dpif, ofproto_meter_id meter_id,
                        struct ofputil_meter_stats *stats, uint16_t max_bands)
 {
-    return dpif_netlink_meter_get_stats(dpif, meter_id, stats, max_bands,
-                                        OVS_METER_CMD_DEL);
+    int err;
+
+    err  = dpif_netlink_meter_get_stats(dpif, meter_id, stats,
+                                        max_bands, OVS_METER_CMD_DEL);
+    if (!err && netdev_is_flow_api_enabled()) {
+        meter_offload_del(meter_id, stats);
+    }
+
+    return err;
 }
 
 static bool
diff --git a/tests/system-offloads-traffic.at b/tests/system-offloads-traffic.at
index 80bc1dd5c..47dfdb8e9 100644
--- a/tests/system-offloads-traffic.at
+++ b/tests/system-offloads-traffic.at
@@ -168,3 +168,101 @@  matchall
 ])
 OVS_TRAFFIC_VSWITCHD_STOP
 AT_CLEANUP
+
+AT_SETUP([offloads - check interface meter offloading ])
+AT_KEYWORDS([offload-meter])
+AT_SKIP_IF([test $SUPPORT_TC_INGRESS_PPS = "no"])
+OVS_TRAFFIC_VSWITCHD_START()
+
+AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:hw-offload=true])
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-meter br0 'meter=1 pktps bands=type=drop rate=1'])
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24", "f0:00:00:01:01:01")
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24", "f0:00:00:01:01:02")
+
+NS_CHECK_EXEC([at_ns0], [ip neigh add 10.1.1.2 lladdr f0:00:00:01:01:02 dev p0])
+NS_CHECK_EXEC([at_ns1], [ip neigh add 10.1.1.1 lladdr f0:00:00:01:01:01 dev p1])
+
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "actions=normal"])
+NS_CHECK_EXEC([at_ns0], [ping -q -c 10 -i 0.1 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl
+10 packets transmitted, 10 received, 0% packet loss, time 0ms
+])
+
+NETNS_DAEMONIZE([at_ns1], [nc -u -l 5678 > /dev/null ], [nc0.pid])
+
+AT_CHECK([ovs-ofctl -O OpenFlow13 del-flows br0])
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "priority=10,in_port=ovs-p0,udp actions=meter:1,normal"])
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "priority=1 actions=normal"])
+
+NS_CHECK_EXEC([at_ns0], [echo "mark" | nc -u 10.1.1.2 5678 -p 6789])
+AT_CHECK([ovs-appctl dpctl/dump-flows | grep "meter" | DUMP_CLEAN_SORTED], [0], [dnl
+in_port(2),eth(macs),eth_type(0x0800),ipv4(proto=17,frag=no), packets:0, bytes:0, used:0.001s, actions:outputmeter(0),3
+])
+
+sleep 1
+
+for i in `seq 10`; do
+NS_CHECK_EXEC([at_ns0], [echo "mark" | nc -u 10.1.1.2 5678 -p 6789])
+done
+
+AT_CHECK([ovs-appctl dpctl/dump-flows | grep "meter" | DUMP_CLEAN_SORTED], [0], [dnl
+in_port(2),eth(macs),eth_type(0x0800),ipv4(proto=17,frag=no), packets:10, bytes:330, used:0.001s, actions:outputmeter(0),3
+])
+
+AT_CHECK([ovs-ofctl -O OpenFlow13 meter-stats br0 | sed -e 's/duration:[[0-9]].[[0-9]]*s/duration:0.001s/'], [0], [dnl
+OFPST_METER reply (OF1.3) (xid=0x2):
+meter:1 flow_count:1 packet_in_count:11 byte_in_count:377 duration:0.001s bands:
+0: packet_count:9 byte_count:0
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([unoffload meter - Check DP meter ])
+AT_KEYWORDS([dp-meter])
+OVS_TRAFFIC_VSWITCHD_START()
+
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-meter br0 'meter=1 pktps bands=type=drop rate=1'])
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24", "f0:00:00:01:01:01")
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24", "f0:00:00:01:01:02")
+
+NS_CHECK_EXEC([at_ns0], [ip neigh add 10.1.1.2 lladdr f0:00:00:01:01:02 dev p0])
+NS_CHECK_EXEC([at_ns1], [ip neigh add 10.1.1.1 lladdr f0:00:00:01:01:01 dev p1])
+
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "actions=normal"])
+NS_CHECK_EXEC([at_ns0], [ping -q -c 10 -i 0.1 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl
+10 packets transmitted, 10 received, 0% packet loss, time 0ms
+])
+
+NETNS_DAEMONIZE([at_ns1], [nc -u -l 5678 > /dev/null ], [nc0.pid])
+
+AT_CHECK([ovs-ofctl -O OpenFlow13 del-flows br0])
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "priority=10,in_port=ovs-p0,udp actions=meter:1,normal"])
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 "priority=1 actions=normal"])
+
+NS_CHECK_EXEC([at_ns0], [echo "mark" | nc -u 10.1.1.2 5678 -p 6789])
+AT_CHECK([ovs-appctl dpctl/dump-flows | grep "meter" | DUMP_CLEAN_SORTED], [0], [dnl
+in_port(2),eth(macs),eth_type(0x0800),ipv4(proto=17,frag=no), packets:0, bytes:0, used:never, actions:outputmeter(0),3
+])
+
+sleep 1
+
+for i in `seq 10`; do
+NS_CHECK_EXEC([at_ns0], [echo "mark" | nc -u 10.1.1.2 5678 -p 6789])
+done
+
+AT_CHECK([ovs-appctl dpctl/dump-flows | grep "meter" | DUMP_CLEAN_SORTED], [0], [dnl
+in_port(2),eth(macs),eth_type(0x0800),ipv4(proto=17,frag=no), packets:10, bytes:470, used:0.001s, actions:outputmeter(0),3
+])
+
+AT_CHECK([ovs-ofctl -O OpenFlow13 meter-stats br0 | sed -e 's/duration:[[0-9]].[[0-9]]*s/duration:0.001s/'], [0], [dnl
+OFPST_METER reply (OF1.3) (xid=0x2):
+meter:1 flow_count:1 packet_in_count:11 byte_in_count:517 duration:0.001s bands:
+0: packet_count:9 byte_count:423
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP