diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 1f9c484e524..eba9816dce9 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -234,6 +234,8 @@ static void upcall_unixctl_set_flow_limit(struct unixctl_conn *conn, int argc, const char *argv[], void *aux); static void upcall_unixctl_dump_wait(struct unixctl_conn *conn, int argc, const char *argv[], void *aux); +static void upcall_unixctl_purge(struct unixctl_conn *conn, int argc, + const char *argv[], void *aux); static struct udpif_key *ukey_create(const struct nlattr *key, size_t key_len, long long int used); @@ -273,6 +275,8 @@ udpif_create(struct dpif_backer *backer, struct dpif *dpif) upcall_unixctl_set_flow_limit, NULL); unixctl_command_register("revalidator/wait", "", 0, 0, upcall_unixctl_dump_wait, NULL); + unixctl_command_register("revalidator/purge", "", 0, 0, + upcall_unixctl_purge, NULL); ovsthread_once_done(&once); } @@ -1768,3 +1772,19 @@ upcall_unixctl_dump_wait(struct unixctl_conn *conn, unixctl_command_reply_error(conn, "can't wait on multiple udpifs."); } } + +static void +upcall_unixctl_purge(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) +{ + struct udpif *udpif; + + LIST_FOR_EACH (udpif, list_node, &all_udpifs) { + int n; + + for (n = 0; n < udpif->n_revalidators; n++) { + revalidator_purge(&udpif->revalidators[n]); + } + } + unixctl_command_reply(conn, ""); +} diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index 53493869361..9c72a99675d 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -3410,7 +3410,8 @@ recirc_id(0),in_port(90),eth_type(0x0800),ipv4(proto=6,frag=later), packets:0, b mode=drop -AT_CHECK([ovs-appctl dpctl/del-flows], [0]) +ovs-appctl revalidator/wait +AT_CHECK([ovs-appctl revalidator/purge], [0]) AT_CHECK([ovs-ofctl set-frags br0 $mode]) for type in no first later; do eval flow=\$${type}_flow @@ -3427,7 +3428,8 @@ recirc_id(0),in_port(90),eth_type(0x0800),ipv4(frag=later), packets:0, bytes:0, mode=nx-match -AT_CHECK([ovs-appctl dpctl/del-flows], [0]) +ovs-appctl revalidator/wait +AT_CHECK([ovs-appctl revalidator/purge], [0]) AT_CHECK([ovs-ofctl set-frags br0 $mode]) for type in no first later; do eval flow=\$${type}_flow @@ -3513,7 +3515,8 @@ recirc_id(0),in_port(90),eth_type(0x0800),ipv4(proto=6,frag=first),tcp(src=33419 recirc_id(0),in_port(90),eth_type(0x0800),ipv4(proto=6,frag=later), packets:1, bytes:74, used:0.001s, actions:1 ]) -AT_CHECK([ovs-appctl dpctl/del-flows], [0]) +ovs-appctl revalidator/wait +AT_CHECK([ovs-appctl revalidator/purge], [0]) AT_CHECK([ovs-ofctl set-frags br0 $mode]) for frag in 4000 6000 6008 4010; do printf "\n%s\n" "----$mode $frag truncated transport header -----" @@ -3527,7 +3530,8 @@ recirc_id(0),in_port(90),eth_type(0x0800),ipv4(proto=6,frag=first),tcp(src=0), p recirc_id(0),in_port(90),eth_type(0x0800),ipv4(proto=6,frag=later), packets:1, bytes:60, used:0.001s, actions:1 ]) -AT_CHECK([ovs-appctl dpctl/del-flows], [0]) +ovs-appctl revalidator/wait +AT_CHECK([ovs-appctl revalidator/purge], [0]) AT_CHECK([ovs-ofctl set-frags br0 $mode]) for frag in 4000 6000 6001 4002; do printf "\n%s\n" "----$mode $frag missing transport header-----"