mirror of
https://github.com/openvswitch/ovs
synced 2025-08-22 01:51:26 +00:00
ovs-ofctl: New option "--no-stats" for "ovs-ofctl dump-flows".
It's pretty common to want to omit statistics from output, to make it easier to read. This commit adds an ovs-ofctl option to make that easy. A lot of the OVS internal tests could use this, too, in place of ofctl_strip. This commit adopts it for a subset. Signed-off-by: Ben Pfaff <blp@ovn.org> Acked-by: Aaron Conole <aconole@redhat.com>
This commit is contained in:
parent
89cf41eca7
commit
1b3758c36e
8
NEWS
8
NEWS
@ -1,8 +1,10 @@
|
||||
Post-v2.7.0
|
||||
---------------------
|
||||
- ovs-ofctl can now accept and display port names in place of numbers. By
|
||||
default it always accepts names and in interactive use it displays them;
|
||||
use --names or --no-names to override. See ovs-ofctl(8) for details.
|
||||
- ovs-ofctl:
|
||||
* ovs-ofctl can now accept and display port names in place of numbers. By
|
||||
default it always accepts names and in interactive use it displays them;
|
||||
use --names or --no-names to override. See ovs-ofctl(8) for details.
|
||||
* "ovs-ofctl dump-flows" now accepts --no-stats to omit flow statistics.
|
||||
- Tunnels:
|
||||
* Added support to set packet mark for tunnel endpoint using
|
||||
`egress_pkt_mark` OVSDB option.
|
||||
|
@ -61,7 +61,7 @@ void ofp_print_table_features(
|
||||
const struct ofputil_table_stats *prev_stats);
|
||||
|
||||
void ofp_print_flow_stats(struct ds *, const struct ofputil_flow_stats *,
|
||||
const struct ofputil_port_map *);
|
||||
const struct ofputil_port_map *, bool show_stats);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1682,21 +1682,34 @@ ofp_print_flow_stats_request(struct ds *string, const struct ofp_header *oh,
|
||||
match_format(&fsr.match, port_map, string, OFP_DEFAULT_PRIORITY);
|
||||
}
|
||||
|
||||
/* Appends a textual form of 'fs' to 'string', translating port numbers to
|
||||
* names using 'port_map' (if provided). If 'show_stats' is true, the output
|
||||
* includes the flow duration, packet and byte counts, and its idle and hard
|
||||
* ages, otherwise they are omitted. */
|
||||
void
|
||||
ofp_print_flow_stats(struct ds *string, const struct ofputil_flow_stats *fs,
|
||||
const struct ofputil_port_map *port_map)
|
||||
const struct ofputil_port_map *port_map, bool show_stats)
|
||||
{
|
||||
ds_put_format(string, " %scookie=%s0x%"PRIx64", %sduration=%s",
|
||||
colors.param, colors.end, ntohll(fs->cookie),
|
||||
colors.param, colors.end);
|
||||
if (show_stats || fs->cookie) {
|
||||
ds_put_format(string, "%scookie=%s0x%"PRIx64", ",
|
||||
colors.param, colors.end, ntohll(fs->cookie));
|
||||
}
|
||||
if (show_stats) {
|
||||
ds_put_format(string, "%sduration=%s", colors.param, colors.end);
|
||||
ofp_print_duration(string, fs->duration_sec, fs->duration_nsec);
|
||||
ds_put_cstr(string, ", ");
|
||||
}
|
||||
|
||||
ofp_print_duration(string, fs->duration_sec, fs->duration_nsec);
|
||||
ds_put_format(string, ", %stable=%s%"PRIu8", ",
|
||||
colors.special, colors.end, fs->table_id);
|
||||
ds_put_format(string, "%sn_packets=%s%"PRIu64", ",
|
||||
colors.param, colors.end, fs->packet_count);
|
||||
ds_put_format(string, "%sn_bytes=%s%"PRIu64", ",
|
||||
colors.param, colors.end, fs->byte_count);
|
||||
if (show_stats || fs->table_id) {
|
||||
ds_put_format(string, "%stable=%s%"PRIu8", ",
|
||||
colors.special, colors.end, fs->table_id);
|
||||
}
|
||||
if (show_stats) {
|
||||
ds_put_format(string, "%sn_packets=%s%"PRIu64", ",
|
||||
colors.param, colors.end, fs->packet_count);
|
||||
ds_put_format(string, "%sn_bytes=%s%"PRIu64", ",
|
||||
colors.param, colors.end, fs->byte_count);
|
||||
}
|
||||
if (fs->idle_timeout != OFP_FLOW_PERMANENT) {
|
||||
ds_put_format(string, "%sidle_timeout=%s%"PRIu16", ",
|
||||
colors.param, colors.end, fs->idle_timeout);
|
||||
@ -1712,17 +1725,20 @@ ofp_print_flow_stats(struct ds *string, const struct ofputil_flow_stats *fs,
|
||||
ds_put_format(string, "%simportance=%s%"PRIu16", ",
|
||||
colors.param, colors.end, fs->importance);
|
||||
}
|
||||
if (fs->idle_age >= 0) {
|
||||
if (show_stats && fs->idle_age >= 0) {
|
||||
ds_put_format(string, "%sidle_age=%s%d, ",
|
||||
colors.param, colors.end, fs->idle_age);
|
||||
}
|
||||
if (fs->hard_age >= 0 && fs->hard_age != fs->duration_sec) {
|
||||
if (show_stats && fs->hard_age >= 0 && fs->hard_age != fs->duration_sec) {
|
||||
ds_put_format(string, "%shard_age=%s%d, ",
|
||||
colors.param, colors.end, fs->hard_age);
|
||||
}
|
||||
|
||||
/* Print the match, followed by a space (but omit the space if the match
|
||||
* was an empty string). */
|
||||
size_t length = string->length;
|
||||
match_format(&fs->match, port_map, string, fs->priority);
|
||||
if (string->string[string->length - 1] != ' ') {
|
||||
if (string->length != length) {
|
||||
ds_put_char(string, ' ');
|
||||
}
|
||||
|
||||
@ -1749,8 +1765,8 @@ ofp_print_flow_stats_reply(struct ds *string, const struct ofp_header *oh,
|
||||
}
|
||||
break;
|
||||
}
|
||||
ds_put_char(string, '\n');
|
||||
ofp_print_flow_stats(string, &fs, port_map);
|
||||
ds_put_cstr(string, "\n ");
|
||||
ofp_print_flow_stats(string, &fs, port_map, true);
|
||||
}
|
||||
ofpbuf_uninit(&ofpacts);
|
||||
}
|
||||
|
@ -793,9 +793,9 @@ sbctl_dump_openflow(struct vconn *vconn, const struct uuid *uuid, bool stats)
|
||||
|
||||
ds_clear(&s);
|
||||
if (stats) {
|
||||
ofp_print_flow_stats(&s, fs, NULL);
|
||||
ofp_print_flow_stats(&s, fs, NULL, true);
|
||||
} else {
|
||||
ds_put_format(&s, " %stable=%s%"PRIu8" ",
|
||||
ds_put_format(&s, "%stable=%s%"PRIu8" ",
|
||||
colors.special, colors.end, fs->table_id);
|
||||
match_format(&fs->match, NULL, &s, OFP_DEFAULT_PRIORITY);
|
||||
if (ds_last(&s) != ' ') {
|
||||
@ -805,7 +805,7 @@ sbctl_dump_openflow(struct vconn *vconn, const struct uuid *uuid, bool stats)
|
||||
ds_put_format(&s, "%sactions=%s", colors.actions, colors.end);
|
||||
ofpacts_format(fs->ofpacts, fs->ofpacts_len, NULL, &s);
|
||||
}
|
||||
printf(" %s\n", ds_cstr(&s));
|
||||
printf(" %s\n", ds_cstr(&s));
|
||||
}
|
||||
ds_destroy(&s);
|
||||
}
|
||||
|
@ -1878,13 +1878,9 @@ trace_openflow(const struct ovntrace_flow *f, struct ovs_list *super)
|
||||
struct ds s = DS_EMPTY_INITIALIZER;
|
||||
for (size_t i = 0; i < n_fses; i++) {
|
||||
ds_clear(&s);
|
||||
ofp_print_flow_stats(&s, &fses[i], NULL);
|
||||
|
||||
/* ofp_print_flow_stats() indents its output with a space.
|
||||
* Omit it. */
|
||||
const char *p = ds_cstr(&s);
|
||||
p += strspn(p, " ");
|
||||
ovntrace_node_append(super, OVNTRACE_NODE_ACTION, "%s", p);
|
||||
ofp_print_flow_stats(&s, &fses[i], NULL, true);
|
||||
ovntrace_node_append(super, OVNTRACE_NODE_ACTION,
|
||||
"%s", ds_cstr(&s));
|
||||
}
|
||||
ds_destroy(&s);
|
||||
} else {
|
||||
|
@ -212,9 +212,8 @@ AT_SETUP([bundle action with many ports])
|
||||
AT_KEYWORDS([bundle_action])
|
||||
OVS_VSWITCHD_START
|
||||
AT_CHECK([ovs-ofctl add-flow br0 'actions=set_field:0x1->metadata,set_field:0x2->metadata,set_field:0x3->metadata,set_field:0x4->metadata,bundle(symmetric_l4,0,hrw,ofport,slaves:[[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40]])'])
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 --no-stats], [0], [dnl
|
||||
actions=load:0x1->OXM_OF_METADATA[[]],load:0x2->OXM_OF_METADATA[[]],load:0x3->OXM_OF_METADATA[[]],load:0x4->OXM_OF_METADATA[[]],bundle(symmetric_l4,0,hrw,ofport,slaves:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40)
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
OVS_VSWITCHD_STOP
|
||||
AT_CLEANUP
|
||||
|
@ -132,10 +132,9 @@ mv stdout expout
|
||||
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
|
||||
|
||||
# Check for the MAC learning entry.
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
|
||||
table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:3
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats --sort], [0], [dnl
|
||||
table=1, priority=0 actions=FLOOD
|
||||
NXST_FLOW reply:
|
||||
table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:3
|
||||
])
|
||||
|
||||
# Trace a packet arrival destined for the learned MAC.
|
||||
@ -145,11 +144,10 @@ AT_CHECK([tail -1 stdout], [0], [Datapath actions: 3
|
||||
])
|
||||
|
||||
# Check for both MAC learning entries.
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip |sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats | sort], [0], [dnl
|
||||
table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:3
|
||||
table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:06 actions=output:1
|
||||
table=1, priority=0 actions=FLOOD
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
|
||||
# Trace a packet arrival that updates the first learned MAC entry.
|
||||
@ -163,11 +161,10 @@ mv stdout expout
|
||||
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
|
||||
|
||||
# Check that the MAC learning entry was updated.
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats | sort], [0], [dnl
|
||||
table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:2
|
||||
table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:06 actions=output:1
|
||||
table=1, priority=0 actions=FLOOD
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
OVS_VSWITCHD_STOP
|
||||
AT_CLEANUP
|
||||
@ -204,10 +201,9 @@ mv stdout expout
|
||||
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
|
||||
|
||||
# Check that the MAC learning entry appeared.
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats | sort], [0], [dnl
|
||||
table=1, hard_timeout=10, dl_dst=50:54:00:00:00:07 actions=output:3
|
||||
table=1, priority=0 actions=FLOOD
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
|
||||
# For 25 seconds, make sure that the MAC learning entry doesn't
|
||||
@ -239,9 +235,8 @@ done
|
||||
# Make sure that 15 seconds without refreshing makes the flow time out.
|
||||
ovs-appctl time/warp 15000 5000
|
||||
sleep 1
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats | sort], [0], [dnl
|
||||
table=1, priority=0 actions=FLOOD
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
OVS_VSWITCHD_STOP
|
||||
AT_CLEANUP
|
||||
@ -265,9 +260,8 @@ mv stdout expout
|
||||
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
|
||||
|
||||
# Check for the learning entry.
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats | sort], [0], [dnl
|
||||
table=1, hard_timeout=60, tcp,nw_src=192.168.0.1,nw_dst=192.168.0.2,tp_src=80,tp_dst=40000 actions=drop
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
OVS_VSWITCHD_STOP
|
||||
AT_CLEANUP
|
||||
@ -293,10 +287,9 @@ mv stdout expout
|
||||
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
|
||||
|
||||
# Check for the learning entry.
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
|
||||
table=1, hard_timeout=60, tcp6,ipv6_src=fec0::1,ipv6_dst=2001:db8:85a3::8a2e:370:7334,tp_src=80,tp_dst=40000 actions=load:0x13198a2e03707348->NXM_NX_IPV6_DST[[0..63]],load:0x20010db885a308d3->NXM_NX_IPV6_DST[[64..127]]
|
||||
tcp6 actions=learn(table=1,hard_timeout=60,eth_type=0x86dd,nw_proto=6,NXM_NX_IPV6_SRC[[]]=NXM_NX_IPV6_DST[[]],ipv6_dst=2001:db8:85a3::8a2e:370:7334,NXM_OF_TCP_SRC[[]]=NXM_OF_TCP_DST[[]],NXM_OF_TCP_DST[[]]=NXM_OF_TCP_SRC[[]],load:0x20010db885a308d313198a2e03707348->NXM_NX_IPV6_DST[[]]),FLOOD
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
OVS_VSWITCHD_STOP
|
||||
AT_CLEANUP
|
||||
@ -508,9 +501,8 @@ OVS_VSWITCHD_START(
|
||||
[add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1])
|
||||
AT_CHECK([[ovs-ofctl add-flow br0 'actions=learn(fin_hard_timeout=10, fin_idle_timeout=5, NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], output:NXM_OF_IN_PORT[])']])
|
||||
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=192.168.0.1,tip=192.168.0.2,op=1,sha=50:54:00:00:00:05,tha=00:00:00:00:00:00)' -generate], [0], [ignore])
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip], [0],
|
||||
[NXST_FLOW reply:
|
||||
table=1, dl_dst=50:54:00:00:00:05 actions=fin_timeout(idle_timeout=5,hard_timeout=10),output:1
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats], [0],
|
||||
[ table=1, dl_dst=50:54:00:00:00:05 actions=fin_timeout(idle_timeout=5,hard_timeout=10),output:1
|
||||
])
|
||||
OVS_VSWITCHD_STOP
|
||||
AT_CLEANUP
|
||||
@ -528,65 +520,59 @@ cookie=0x123, table=2, reg0=0x5 actions=drop
|
||||
cookie=0x234, table=1, reg0=0x6 actions=drop
|
||||
])
|
||||
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
|
||||
cookie=0x123, table=1, reg0=0x3 actions=drop
|
||||
cookie=0x123, table=1, reg0=0x4 actions=drop
|
||||
cookie=0x123, table=2, reg0=0x5 actions=drop
|
||||
cookie=0x234, table=1, reg0=0x6 actions=drop
|
||||
reg0=0x1 actions=learn(table=1,delete_learned,cookie=0x123)
|
||||
reg0=0x2 actions=learn(table=1,delete_learned,cookie=0x123)
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
|
||||
# Delete one of the learn actions. The learned flows should stay, since there
|
||||
# is another learn action with the identical target.
|
||||
AT_CHECK([ovs-ofctl del-flows br0 'table=0 reg0=1'])
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
|
||||
cookie=0x123, table=1, reg0=0x3 actions=drop
|
||||
cookie=0x123, table=1, reg0=0x4 actions=drop
|
||||
cookie=0x123, table=2, reg0=0x5 actions=drop
|
||||
cookie=0x234, table=1, reg0=0x6 actions=drop
|
||||
reg0=0x2 actions=learn(table=1,delete_learned,cookie=0x123)
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
|
||||
# Change the flow with the learn action by adding a second action. The learned
|
||||
# flows should stay because the learn action is still there.
|
||||
AT_CHECK([ovs-ofctl mod-flows br0 'table=0 reg0=2 actions=output:1,learn(delete_learned,cookie=0x123)'])
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
|
||||
cookie=0x123, table=1, reg0=0x3 actions=drop
|
||||
cookie=0x123, table=1, reg0=0x4 actions=drop
|
||||
cookie=0x123, table=2, reg0=0x5 actions=drop
|
||||
cookie=0x234, table=1, reg0=0x6 actions=drop
|
||||
reg0=0x2 actions=output:1,learn(table=1,delete_learned,cookie=0x123)
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
|
||||
# Change the flow with the learn action by replacing its learn action by one
|
||||
# with a different target. The (previous) learned flows disappear.
|
||||
AT_CHECK([ovs-ofctl mod-flows br0 'table=0 reg0=2 actions=learn(delete_learned,cookie=0x234)'])
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
|
||||
cookie=0x123, table=2, reg0=0x5 actions=drop
|
||||
cookie=0x234, table=1, reg0=0x6 actions=drop
|
||||
reg0=0x2 actions=learn(table=1,delete_learned,cookie=0x234)
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
|
||||
# Use add-flow to replace the flow with the learn action by one with the
|
||||
# same learn action and an extra action. The (new) learned flow remains.
|
||||
AT_CHECK([ovs-ofctl add-flow br0 'table=0 reg0=2 actions=learn(delete_learned,cookie=0x234),output:2'])
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
|
||||
cookie=0x123, table=2, reg0=0x5 actions=drop
|
||||
cookie=0x234, table=1, reg0=0x6 actions=drop
|
||||
reg0=0x2 actions=learn(table=1,delete_learned,cookie=0x234),output:2
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
|
||||
# Delete the flow with the learn action. The learned flow disappears too.
|
||||
AT_CHECK([ovs-ofctl del-flows br0 table=0])
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
|
||||
cookie=0x123, table=2, reg0=0x5 actions=drop
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
|
||||
# Add a new set of flows to check on a corner case: the learned flows
|
||||
@ -608,7 +594,7 @@ cookie=0x567, table=5, reg0=0x8 actions=drop
|
||||
])
|
||||
AT_CHECK([ovs-ofctl del-flows br0])
|
||||
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
|
||||
cookie=0x123, table=1, reg0=0x3 actions=learn(table=3,delete_learned,cookie=0x345)
|
||||
cookie=0x234, table=2, reg0=0x3 actions=learn(table=4,delete_learned,cookie=0x456)
|
||||
cookie=0x345, table=3, reg0=0x4 actions=learn(table=5,delete_learned,cookie=0x567)
|
||||
@ -618,28 +604,24 @@ AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
|
||||
cookie=0x567, table=5, reg0=0x8 actions=drop
|
||||
reg0=0x1 actions=learn(table=1,delete_learned,cookie=0x123)
|
||||
reg0=0x2 actions=learn(table=2,delete_learned,cookie=0x234)
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
|
||||
# Deleting the flow with reg0=1 should cascade to delete a few levels
|
||||
# of learned flows, but the ones with cookie=0x567 stick around
|
||||
# because of the flow with cookie=0x456.
|
||||
AT_CHECK([ovs-ofctl del-flows br0 'table=0 reg0=1'])
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
|
||||
cookie=0x234, table=2, reg0=0x3 actions=learn(table=4,delete_learned,cookie=0x456)
|
||||
cookie=0x456, table=4, reg0=0x5 actions=learn(table=5,delete_learned,cookie=0x567)
|
||||
cookie=0x567, table=5, reg0=0x6 actions=drop
|
||||
cookie=0x567, table=5, reg0=0x7 actions=drop
|
||||
cookie=0x567, table=5, reg0=0x8 actions=drop
|
||||
reg0=0x2 actions=learn(table=2,delete_learned,cookie=0x234)
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
|
||||
# Deleting the flow with reg0=2 should cascade to delete all the rest:
|
||||
AT_CHECK([ovs-ofctl del-flows br0 'table=0 reg0=2'])
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort])
|
||||
OVS_VSWITCHD_STOP
|
||||
AT_CLEANUP
|
||||
|
||||
@ -656,9 +638,8 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:
|
||||
|
||||
OVS_WAIT_UNTIL([ovs-ofctl dump-ports br0 2 | grep -o 'tx pkts=2' >/dev/null])
|
||||
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
|
||||
AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats], [0], [dnl
|
||||
cookie=0x1, table=1, dl_dst=50:54:00:00:00:01 actions=drop
|
||||
NXST_FLOW reply:
|
||||
])
|
||||
|
||||
dnl Delete the learned flow
|
||||
|
@ -222,8 +222,11 @@ syntax of \fIflows\fR. The output format is described in
|
||||
.IP
|
||||
By default, \fBovs\-ofctl\fR prints flow entries in the same order
|
||||
that the switch sends them, which is unlikely to be intuitive or
|
||||
consistent. See the description of \fB\-\-sort\fR and \fB\-\-rsort\fR,
|
||||
under \fBOPTIONS\fR below, to influence the display order.
|
||||
consistent. Use \fB\-\-sort\fR and \fB\-\-rsort\fR to control display
|
||||
order. The \fB\-\-names\fR/\fB\-\-no\-names\fR and
|
||||
\fB\-\-stats\fR/\fB\-\-no\-stats\fR options also affect output
|
||||
formatting. See the descriptions of these options, under
|
||||
\fBOPTIONS\fR below, for more information
|
||||
.
|
||||
.TP
|
||||
\fBdump\-aggregate \fIswitch \fR[\fIflows\fR]
|
||||
@ -2222,6 +2225,13 @@ be the same; when a switch has two ports with the same (truncated)
|
||||
name, \fBovs\-ofctl\fR refuses to display or accept the name, using
|
||||
the number instead.
|
||||
.
|
||||
.IP "\fB\-\-stats\fR"
|
||||
.IQ "\fB\-\-no\-stats\fR"
|
||||
The \fBdump\-flows\fR command by default, or with \fB\-\-stats\fR,
|
||||
includes flow duration, packet and byte counts, and idle and hard age
|
||||
in its output. With \fB\-\-no\-stats\fR, it omits all of these, as
|
||||
well as cookie values and table IDs if they are zero.
|
||||
.
|
||||
.IP "\fB\-\-read-only\fR"
|
||||
Do not execute read/write commands.
|
||||
.
|
||||
|
@ -135,6 +135,9 @@ static const struct ofputil_port_map *ports_to_show(const char *vconn_name);
|
||||
static bool should_accept_ports(void);
|
||||
static bool should_show_ports(void);
|
||||
|
||||
/* --stats, --no-stats: Show statistics in flow dumps? */
|
||||
static int show_stats = 1;
|
||||
|
||||
static const struct ovs_cmdl_command *get_all_commands(void);
|
||||
|
||||
OVS_NO_RETURN static void usage(void);
|
||||
@ -212,6 +215,8 @@ parse_options(int argc, char *argv[])
|
||||
{"rsort", optional_argument, NULL, OPT_RSORT},
|
||||
{"names", no_argument, &use_port_names, 1},
|
||||
{"no-names", no_argument, &use_port_names, 0},
|
||||
{"stats", no_argument, &show_stats, 1},
|
||||
{"no-stats", no_argument, &show_stats, 0},
|
||||
{"unixctl", required_argument, NULL, OPT_UNIXCTL},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"option", no_argument, NULL, 'o'},
|
||||
@ -1357,7 +1362,7 @@ compare_flows(const void *afs_, const void *bfs_)
|
||||
static void
|
||||
ofctl_dump_flows(struct ovs_cmdl_context *ctx)
|
||||
{
|
||||
if (!n_criteria && !should_show_ports()) {
|
||||
if (!n_criteria && !should_show_ports() && show_stats) {
|
||||
ofctl_dump_flows__(ctx->argc, ctx->argv, false);
|
||||
return;
|
||||
} else {
|
||||
@ -1378,8 +1383,9 @@ ofctl_dump_flows(struct ovs_cmdl_context *ctx)
|
||||
struct ds s = DS_EMPTY_INITIALIZER;
|
||||
for (size_t i = 0; i < n_fses; i++) {
|
||||
ds_clear(&s);
|
||||
ofp_print_flow_stats(&s, &fses[i], ports_to_show(ctx->argv[1]));
|
||||
puts(ds_cstr(&s));
|
||||
ofp_print_flow_stats(&s, &fses[i], ports_to_show(ctx->argv[1]),
|
||||
show_stats);
|
||||
printf(" %s\n", ds_cstr(&s));
|
||||
}
|
||||
ds_destroy(&s);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user