[ovs-dev] [PATCH v8] ofproto: Honour Table Mod settings for table-miss handling
Simon Horman
horms at verge.net.au
Thu Feb 20 02:19:29 UTC 2014
Apologies for sending this twice, both posts contain the same patch,
so please ignore one of them.
On Thu, Feb 20, 2014 at 11:17:41AM +0900, Simon Horman wrote:
> This reworks lookup of rules for both table 0 and table action translation.
> The result is that Table Mod settings, which can alter the miss-behaviour
> of tables, including table 0, on a per-table basis may be honoured.
>
> Previous patches proposed by myself which build on earlier merged patches
> by Andy Zhou implement the ofproto side of Table Mod. So with this patch
> the feature should be complete.
>
> Neither this patch, nor any other patches it builds on, alter the default
> behaviour of Open vSwitch. And in particular the OpenFlow1.1 behaviour is
> the default regardless of which OpenFlow version is negotiated between the
> switch and the controller.
>
> An implementation detail, which lends itself to future work, is the
> handling of OFPTC_TABLE_MISS_CONTINUE. If a table has this behaviour set by
> Table Mod and a miss occurs then a loop is created, skipping to the next
> table. It is quite easy to create a situation where this loop covers ~255
> tables which is very expensive as the lookup for each table involves taking
> locks, amongst other things.
>
> Cc: Andy Zhou <azhou at nicira.com>
> Signed-off-by: Simon Horman <horms at verge.net.au>
>
> ---
> v8
> * Rebase
>
> v7
> * As suggested by Ben Pfaff
> - Used simplified loop/case logic in rule_dpif_lookup_from_table()
> + I re-introduced next_id so that table_id is not advanced to
> ofproto->up.n_tables.
> - Consolidate logic of xlate_table_action() and rule_dpif_lookup()
> into rule_dpif_lookup_from_table()
> - Do not honour table mod settings in the case of a resubmit action
>
> v4 - v6
> * Rebase
>
> v3
> * Remove bogus fall-through comment in OFPTC_TABLE_MISS_CONTROLLER case
> in rule_dpif_lookup_from_table(). This case always returns.
> * Add fall-through from OFPTC_TABLE_MISS_CONTROLLER
> to OFPTC_TABLE_MISS_DROP in xlate_table_action() to handle
> situations where packet_in is not allowed.
> * Re-arrange rule_dpif_lookup_from_table() and xlate_table_action()
> to only have one call to choose_miss_rule(). This seems tidier.
> * Consistently call ovs-ofctl monitor without a -P argument
> * Remove ofproto parameter name from declaration of table_get_config().
> This is in keeping with the coding style of other declarations in
> ofproto.h
> * Only allow supported configurations in table_mod message
>
> v2
> * Use ofproto->up.n_tables instead of N_TABLES as the number
> of tables present.
> * Do not use the presence of rules in a table to indicate that it is
> present. Instead treat all tables, other than TBL_INTERNAL, that
> exist in ofproto.up as present. This simplifies things slightly
> and seems to be a more logical approach.
> * As pointed out by Yamamoto-san
> - Read config for each table that is missed rather
> than just the first one. A logic bug that somehow I was blind to.
> ---
> OPENFLOW-1.1+ | 5 -
> ofproto/ofproto-dpif-xlate.c | 77 ++++++----
> ofproto/ofproto-dpif.c | 183 ++++++++++++++++++++--
> ofproto/ofproto-dpif.h | 12 +-
> ofproto/ofproto.c | 14 +-
> ofproto/ofproto.h | 5 +
> tests/ofproto-dpif.at | 353 +++++++++++++++++++++++++++++++++++++++++++
> 7 files changed, 600 insertions(+), 49 deletions(-)
>
> diff --git a/OPENFLOW-1.1+ b/OPENFLOW-1.1+
> index 1b8a0ee..4363d28 100644
> --- a/OPENFLOW-1.1+
> +++ b/OPENFLOW-1.1+
> @@ -54,11 +54,6 @@ OpenFlow 1.1
> The list of remaining work items for OpenFlow 1.1 is below. It is
> probably incomplete.
>
> - * OFPT_TABLE_MOD message. This is new in OF1.1, so we need to
> - implement it. It should be implemented so that the default OVS
> - behavior does not change. Simon Horman has posted a patch.
> - [required for OF1.1 and OF1.2]
> -
> * MPLS. Simon Horman maintains a patch series that adds this
> feature. This is partially merged.
> [optional for OF1.1+]
> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> index ccf0b75..0b3d963 100644
> --- a/ofproto/ofproto-dpif-xlate.c
> +++ b/ofproto/ofproto-dpif-xlate.c
> @@ -225,8 +225,9 @@ static void xlate_actions__(struct xlate_in *, struct xlate_out *)
> OVS_REQ_RDLOCK(xlate_rwlock);
> static void xlate_normal(struct xlate_ctx *);
> static void xlate_report(struct xlate_ctx *, const char *);
> - static void xlate_table_action(struct xlate_ctx *, ofp_port_t in_port,
> - uint8_t table_id, bool may_packet_in);
> +static void xlate_table_action(struct xlate_ctx *, ofp_port_t in_port,
> + uint8_t table_id, bool may_packet_in,
> + bool force_controller_on_miss);
> static bool input_vid_is_valid(uint16_t vid, struct xbundle *, bool warn);
> static uint16_t input_vid_to_vlan(const struct xbundle *, uint16_t vid);
> static void output_normal(struct xlate_ctx *, const struct xbundle *,
> @@ -1719,14 +1720,14 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
> ctx->xout->slow |= special;
> } else if (may_receive(peer, ctx)) {
> if (xport_stp_forward_state(peer)) {
> - xlate_table_action(ctx, flow->in_port.ofp_port, 0, true);
> + xlate_table_action(ctx, flow->in_port.ofp_port, 0, true, false);
> } else {
> /* Forwarding is disabled by STP. Let OFPP_NORMAL and the
> * learning action look at the packet, then drop it. */
> struct flow old_base_flow = ctx->base_flow;
> size_t old_size = ctx->xout->odp_actions.size;
> mirror_mask_t old_mirrors = ctx->xout->mirrors;
> - xlate_table_action(ctx, flow->in_port.ofp_port, 0, true);
> + xlate_table_action(ctx, flow->in_port.ofp_port, 0, true, false);
> ctx->xout->mirrors = old_mirrors;
> ctx->base_flow = old_base_flow;
> ctx->xout->odp_actions.size = old_size;
> @@ -1861,15 +1862,43 @@ xlate_resubmit_resource_check(struct xlate_ctx *ctx)
> return false;
> }
>
> +struct get_ofp_port_config_cb_data {
> + const struct xbridge *xbridge;
> + ofp_port_t ofp_port;
> + bool may_packet_in;
> +};
> +
> +static enum ofputil_port_config
> +get_ofp_port_config_cb(const void *data_)
> +{
> + const struct get_ofp_port_config_cb_data *data;
> +
> + data = (struct get_ofp_port_config_cb_data *)data_;
> +
> + if (data->may_packet_in) {
> + struct xport *xport;
> +
> + xport = get_ofp_port(data->xbridge, data->ofp_port);
> + return xport->config;
> + } else {
> + return OFPUTIL_PC_NO_PACKET_IN;
> + }
> +}
> +
> static void
> -xlate_table_action(struct xlate_ctx *ctx,
> - ofp_port_t in_port, uint8_t table_id, bool may_packet_in)
> +xlate_table_action(struct xlate_ctx *ctx, ofp_port_t in_port, uint8_t table_id,
> + bool may_packet_in, bool force_controller_on_miss)
> {
> if (xlate_resubmit_resource_check(ctx)) {
> ofp_port_t old_in_port = ctx->xin->flow.in_port.ofp_port;
> bool skip_wildcards = ctx->xin->skip_wildcards;
> uint8_t old_table_id = ctx->table_id;
> struct rule_dpif *rule;
> + struct get_ofp_port_config_cb_data get_ofp_port_config_cb_data = {
> + .xbridge = ctx->xbridge,
> + .ofp_port = ctx->xin->flow.in_port.ofp_port,
> + .may_packet_in = may_packet_in,
> + };
>
> ctx->table_id = table_id;
>
> @@ -1877,29 +1906,20 @@ xlate_table_action(struct xlate_ctx *ctx,
> * original input port (otherwise OFPP_NORMAL and OFPP_IN_PORT will
> * have surprising behavior). */
> ctx->xin->flow.in_port.ofp_port = in_port;
> - rule_dpif_lookup_in_table(ctx->xbridge->ofproto, &ctx->xin->flow,
> - !skip_wildcards ? &ctx->xout->wc : NULL,
> - table_id, &rule);
> + rule_dpif_lookup_from_table(ctx->xbridge->ofproto, &ctx->xin->flow,
> + !skip_wildcards ? &ctx->xout->wc : NULL,
> + ctx->xbridge->miss_rule,
> + ctx->xbridge->no_packet_in_rule,
> + get_ofp_port_config_cb,
> + &get_ofp_port_config_cb_data,
> + force_controller_on_miss,
> + &ctx->table_id, &rule);
> ctx->xin->flow.in_port.ofp_port = old_in_port;
>
> if (ctx->xin->resubmit_hook) {
> ctx->xin->resubmit_hook(ctx->xin, rule, ctx->recurse);
> }
>
> - if (!rule && may_packet_in) {
> - struct xport *xport;
> -
> - /* XXX
> - * check if table configuration flags
> - * OFPTC11_TABLE_MISS_CONTROLLER, default.
> - * OFPTC11_TABLE_MISS_CONTINUE,
> - * OFPTC11_TABLE_MISS_DROP
> - * When OF1.0, OFPTC11_TABLE_MISS_CONTINUE is used. What to do? */
> - xport = get_ofp_port(ctx->xbridge, ctx->xin->flow.in_port.ofp_port);
> - choose_miss_rule(xport ? xport->config : 0,
> - ctx->xbridge->miss_rule,
> - ctx->xbridge->no_packet_in_rule, &rule);
> - }
> if (rule) {
> xlate_recursively(ctx, rule);
> rule_dpif_unref(rule);
> @@ -2032,7 +2052,7 @@ xlate_ofpact_resubmit(struct xlate_ctx *ctx,
> table_id = ctx->table_id;
> }
>
> - xlate_table_action(ctx, in_port, table_id, false);
> + xlate_table_action(ctx, in_port, table_id, false, true);
> }
>
> static void
> @@ -2240,7 +2260,7 @@ xlate_output_action(struct xlate_ctx *ctx,
> break;
> case OFPP_TABLE:
> xlate_table_action(ctx, ctx->xin->flow.in_port.ofp_port,
> - 0, may_packet_in);
> + 0, may_packet_in, false);
> break;
> case OFPP_NORMAL:
> xlate_normal(ctx);
> @@ -2753,7 +2773,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
>
> ovs_assert(ctx->table_id < ogt->table_id);
> xlate_table_action(ctx, ctx->xin->flow.in_port.ofp_port,
> - ogt->table_id, true);
> + ogt->table_id, true, false);
> break;
> }
>
> @@ -2979,8 +2999,9 @@ xlate_actions__(struct xlate_in *xin, struct xlate_out *xout)
> ctx.exit = false;
>
> if (!xin->ofpacts && !ctx.rule) {
> - rule_dpif_lookup(ctx.xbridge->ofproto, flow,
> - !xin->skip_wildcards ? wc : NULL, &rule);
> + ctx.table_id = rule_dpif_lookup(ctx.xbridge->ofproto, flow,
> + !xin->skip_wildcards ? wc : NULL,
> + &rule);
> if (ctx.xin->resubmit_stats) {
> rule_dpif_credit_stats(rule, ctx.xin->resubmit_stats);
> }
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index 328b215..01eb7a2 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -3050,25 +3050,51 @@ rule_dpif_get_actions(const struct rule_dpif *rule)
> return rule_get_actions(&rule->up);
> }
>
> -/* Lookup 'flow' in 'ofproto''s classifier. If 'wc' is non-null, sets
> - * the fields that were relevant as part of the lookup. */
> -void
> -rule_dpif_lookup(struct ofproto_dpif *ofproto, const struct flow *flow,
> - struct flow_wildcards *wc, struct rule_dpif **rule)
> +struct get_ofp_port_config_cb_data {
> + const struct ofproto_dpif *ofproto;
> + ofp_port_t ofp_port;
> +};
> +
> +static enum ofputil_port_config
> +get_ofp_port_config_cb(const void *data_)
> {
> + const struct get_ofp_port_config_cb_data *data;
> struct ofport_dpif *port;
>
> - if (rule_dpif_lookup_in_table(ofproto, flow, wc, 0, rule)) {
> - return;
> - }
> - port = get_ofp_port(ofproto, flow->in_port.ofp_port);
> + data = (struct get_ofp_port_config_cb_data *)data_;
> +
> + port = get_ofp_port(data->ofproto, data->ofp_port);
> if (!port) {
> VLOG_WARN_RL(&rl, "packet-in on unknown OpenFlow port %"PRIu16,
> - flow->in_port.ofp_port);
> + data->ofp_port);
> + return 0;
> }
> + return port->up.pp.config;
> +}
>
> - choose_miss_rule(port ? port->up.pp.config : 0, ofproto->miss_rule,
> - ofproto->no_packet_in_rule, rule);
> +/* Lookup 'flow' in table 0 of 'ofproto''s classifier.
> + * If 'wc' is non-null, sets the fields that were relevant as part of
> + * the lookup. Returns the table_id where a match or miss occurred.
> + *
> + * The return value will be zero unless there was a miss and
> + * OFPTC_TABLE_MISS_CONTINUE is in effect for the sequence of tables
> + * where misses occur. */
> +uint8_t
> +rule_dpif_lookup(struct ofproto_dpif *ofproto, const struct flow *flow,
> + struct flow_wildcards *wc, struct rule_dpif **rule)
> +{
> + uint8_t table_id = 0;
> + struct get_ofp_port_config_cb_data get_ofp_port_config_cb_data = {
> + .ofproto = ofproto,
> + .ofp_port = flow->in_port.ofp_port,
> + };
> +
> + rule_dpif_lookup_from_table(ofproto, flow, wc, ofproto->miss_rule,
> + ofproto->no_packet_in_rule,
> + get_ofp_port_config_cb,
> + &get_ofp_port_config_cb_data, false,
> + &table_id, rule);
> + return table_id;
> }
>
> bool
> @@ -3115,6 +3141,139 @@ rule_dpif_lookup_in_table(struct ofproto_dpif *ofproto,
> return *rule != NULL;
> }
>
> +enum rule_dpif_lookup_verdict {
> + RULE_DPIF_LOOKUP_VERDICT_MATCH, /* A match occurred. */
> + RULE_DPIF_LOOKUP_VERDICT_CONTROLLER, /* A miss occurred and the packet
> + * should be passed to
> + * the controller. */
> + RULE_DPIF_LOOKUP_VERDICT_DROP, /* A miss occurred and the packet
> + * should be dropped. */
> +};
> +
> +/* Lookup 'flow' in 'ofproto''s classifier starting at 'table_id'.
> + *
> + * If 'wc' is non-null, sets the fields that were relevant as part
> + * of the lookup.
> + *
> + * 'table_id' is set to the table where a match or miss occurred.
> + * This value will be the input value of 'table_id' unless there was
> + * a miss and OFPTC_TABLE_MISS_CONTINUE is in effect for the sequence of
> + * tables where misses occur.
> + *
> + * If 'force_controller_on_miss' is true then if a miss occurs
> + * then RULE_OFPTC_TABLE_MISS_CONTROLLER will be returned regarless
> + * of which OFPTC_TABLE_* setting is in effect.
> + *
> + * The return value is:
> + * RULE_DPIF_LOOKUP_VERDICT_MATCH: If a match occurred
> + * RULE_OFPTC_TABLE_MISS_CONTROLLER: If a miss occurred and the packet
> + * should be forwarded to the controller.
> + * RULE_OFPTC_TABLE_MISS_DROP: If a miss occurred and the packet
> + * should be dropped. */
> +static enum rule_dpif_lookup_verdict
> +rule_dpif_lookup_from_table__(struct ofproto_dpif *ofproto,
> + const struct flow *flow,
> + struct flow_wildcards *wc,
> + bool force_controller_on_miss,
> + uint8_t *table_id, struct rule_dpif **rule)
> +{
> + uint8_t next_id = *table_id;
> +
> + while (next_id < ofproto->up.n_tables) {
> + enum ofp_table_config config;
> +
> + *table_id = next_id;
> +
> + if (rule_dpif_lookup_in_table(ofproto, flow, wc, *table_id, rule)) {
> + return RULE_DPIF_LOOKUP_VERDICT_MATCH;
> + }
> +
> + if (force_controller_on_miss) {
> + break;
> + }
> +
> + /* XXX
> + * This does not take into account different
> + * behaviour for different OpenFlow versions
> + *
> + * OFPTC11_TABLE_MISS_CONTINUE: Behaviour of OpenFlow1.0
> + * OFPTC11_TABLE_MISS_CONTROLLER: Default for OpenFlow1.1+
> + * OFPTC11_TABLE_MISS_DROP: Default for OpenFlow1.3+
> + *
> + * Instead the global default is OFPTC_TABLE_MISS_CONTROLLER
> + * which may be configured globally using Table Mod. */
> + config = table_get_config(&ofproto->up, *table_id);
> + switch (config & OFPTC11_TABLE_MISS_MASK) {
> + case OFPTC11_TABLE_MISS_CONTINUE:
> + break;
> + case OFPTC11_TABLE_MISS_CONTROLLER:
> + return RULE_DPIF_LOOKUP_VERDICT_CONTROLLER;
> + case OFPTC11_TABLE_MISS_DROP:
> + return RULE_DPIF_LOOKUP_VERDICT_DROP;
> + }
> +
> + /* Go on to next table. */
> + ++next_id;
> + if (next_id == TBL_INTERNAL) {
> + ++next_id;
> + }
> + }
> +
> + /* Either we fell off the end or
> + * a miss occured with force_controller_on_miss set */
> + return RULE_DPIF_LOOKUP_VERDICT_CONTROLLER;
> +}
> +
> +/* Lookup 'flow' in 'ofproto''s classifier starting at 'table_id'.
> + *
> + * If 'wc' is non-null, sets the fields that were relevant as part
> + * of the lookup.
> + *
> + * 'table_id' is set to the table where a match or miss occurred.
> + * This value will be the input value of 'table_id' unless there was
> + * a miss and OFPTC_TABLE_MISS_CONTINUE is in effect for the sequence of
> + * tables where misses occur.
> + *
> + * If a no matching rule is found, even after continuting if
> + * OFPTC_TABLE_MISS_CONTINUE is in effect, then use miss_rule or
> + * no_packet_in_rule according to the ofputil_port_config returned
> + * by get_ofp_port_config_cb when called with get_ofp_port_config_cb_data
> + * as its parameter. */
> +void
> +rule_dpif_lookup_from_table(struct ofproto_dpif *ofproto,
> + const struct flow *flow, struct flow_wildcards *wc,
> + struct rule_dpif *miss_rule,
> + struct rule_dpif *no_packet_in_rule,
> + enum ofputil_port_config
> + (*get_ofp_port_config_cb)(const void *),
> + void *get_ofp_port_config_cb_data,
> + bool force_controller_on_miss,
> + uint8_t *table_id, struct rule_dpif **rule)
> +{
> + enum rule_dpif_lookup_verdict verdict;
> + enum ofputil_port_config config;
> +
> + verdict = rule_dpif_lookup_from_table__(ofproto, flow, wc,
> + force_controller_on_miss,
> + table_id, rule);
> +
> + switch (verdict) {
> + case RULE_DPIF_LOOKUP_VERDICT_MATCH:
> + return;
> + case RULE_DPIF_LOOKUP_VERDICT_CONTROLLER:
> + config = get_ofp_port_config_cb(get_ofp_port_config_cb_data);
> + break;
> + case RULE_DPIF_LOOKUP_VERDICT_DROP:
> + config = OFPUTIL_PC_NO_PACKET_IN;
> + break;
> + default:
> + OVS_NOT_REACHED();
> + }
> +
> + choose_miss_rule(config, miss_rule, no_packet_in_rule, rule);
> + return;
> +}
> +
> /* Given a port configuration (specified as zero if there's no port), chooses
> * which of 'miss_rule' and 'no_packet_in_rule' should be used in case of a
> * flow table miss. */
> diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h
> index d09e285..f526104 100644
> --- a/ofproto/ofproto-dpif.h
> +++ b/ofproto/ofproto-dpif.h
> @@ -67,8 +67,16 @@ extern struct ovs_rwlock xlate_rwlock;
>
> size_t ofproto_dpif_get_max_mpls_depth(const struct ofproto_dpif *);
>
> -void rule_dpif_lookup(struct ofproto_dpif *, const struct flow *,
> - struct flow_wildcards *, struct rule_dpif **rule);
> +uint8_t rule_dpif_lookup(struct ofproto_dpif *, const struct flow *,
> + struct flow_wildcards *, struct rule_dpif **rule);
> +
> +void rule_dpif_lookup_from_table(struct ofproto_dpif *, const struct flow *,
> + struct flow_wildcards *,
> + struct rule_dpif *miss_rule,
> + struct rule_dpif *no_packet_in_rule,
> + enum ofputil_port_config(*)(const void *),
> + void *, bool, uint8_t *,
> + struct rule_dpif **rule);
>
> bool rule_dpif_lookup_in_table(struct ofproto_dpif *, const struct flow *,
> struct flow_wildcards *, uint8_t table_id,
> diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
> index f69736c..660550f 100644
> --- a/ofproto/ofproto.c
> +++ b/ofproto/ofproto.c
> @@ -5794,11 +5794,21 @@ handle_group_mod(struct ofconn *ofconn, const struct ofp_header *oh)
> }
> }
>
> +enum ofp_table_config
> +table_get_config(const struct ofproto *ofproto, uint8_t table_id)
> +{
> + unsigned int value;
> + atomic_read(&ofproto->tables[table_id].config, &value);
> + return (enum ofp_table_config)value;
> +}
> +
> static enum ofperr
> table_mod(struct ofproto *ofproto, const struct ofputil_table_mod *tm)
> {
> - /* XXX Reject all configurations because none are currently supported */
> - return OFPERR_OFPTMFC_BAD_CONFIG;
> + /* Only accept currently supported configurations */
> + if (tm->config & ~OFPTC11_TABLE_MISS_MASK) {
> + return OFPERR_OFPTMFC_BAD_CONFIG;
> + }
>
> if (tm->table_id == OFPTT_ALL) {
> int i;
> diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
> index 1f9cb15..c028abc 100644
> --- a/ofproto/ofproto.h
> +++ b/ofproto/ofproto.h
> @@ -431,6 +431,11 @@ void ofproto_get_vlan_usage(struct ofproto *, unsigned long int *vlan_bitmap);
> bool ofproto_has_vlan_usage_changed(const struct ofproto *);
> int ofproto_port_set_realdev(struct ofproto *, ofp_port_t vlandev_ofp_port,
> ofp_port_t realdev_ofp_port, int vid);
> +
> +/* Table configuration */
> +
> +enum ofp_table_config table_get_config(const struct ofproto *,
> + uint8_t table_id);
>
> #ifdef __cplusplus
> }
> diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
> index 06c4046..8aacdeb 100644
> --- a/tests/ofproto-dpif.at
> +++ b/tests/ofproto-dpif.at
> @@ -429,6 +429,359 @@ AT_CHECK([tail -1 stdout], [0],
> OVS_VSWITCHD_STOP
> AT_CLEANUP
>
> +AT_SETUP([ofproto-dpif - Table Miss - OFPTC_TABLE_MISS_CONTROLLER])
> +OVS_VSWITCHD_START([dnl
> + add-port br0 p1 -- set Interface p1 type=dummy
> +])
> +ON_EXIT([kill `cat ovs-ofctl.pid`])
> +
> +AT_CAPTURE_FILE([ofctl_monitor.log])
> +
> +AT_CHECK([ovs-ofctl monitor br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log])
> +
> +for i in 1 2 3 ; do
> + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(0x010)'
> +done
> +
> +OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
> +AT_CHECK([cat ofctl_monitor.log], [0], [dnl
> +NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +dnl
> +NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +dnl
> +NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +])
> +
> +AT_CHECK([ovs-appctl time/warp 5000], [0], [ignore])
> +AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
> +NXST_FLOW reply:
> +])
> +
> +OVS_VSWITCHD_STOP
> +AT_CLEANUP
> +
> +AT_SETUP([ofproto-dpif - Table Miss - goto table and OFPTC_TABLE_MISS_CONTROLLER])
> +OVS_VSWITCHD_START([dnl
> + add-port br0 p1 -- set Interface p1 type=dummy
> +])
> +ON_EXIT([kill `cat ovs-ofctl.pid`])
> +
> +AT_CAPTURE_FILE([ofctl_monitor.log])
> +AT_CHECK([ovs-ofctl -OOpenFlow12 add-flow br0 'table=0 actions=goto_table(1)'])
> +
> +AT_CHECK([ovs-ofctl monitor -P openflow10 br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log])
> +
> +for i in 1 2 3 ; do
> + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(0x010)'
> +done
> +
> +OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
> +AT_CHECK([cat ofctl_monitor.log], [0], [dnl
> +OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +dnl
> +OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +dnl
> +OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +])
> +
> +AT_CHECK([ovs-appctl time/warp 5000], [0], [ignore])
> +AT_CHECK([ovs-ofctl -OOpenFlow12 dump-flows br0 | ofctl_strip | sort], [0], [dnl
> + n_packets=3, n_bytes=180, actions=goto_table:1
> +OFPST_FLOW reply (OF1.2):
> +])
> +
> +OVS_VSWITCHD_STOP
> +AT_CLEANUP
> +
> +AT_SETUP([ofproto-dpif - Table Miss - resubmit and OFPTC_TABLE_MISS_CONTROLLER])
> +OVS_VSWITCHD_START([dnl
> + add-port br0 p1 -- set Interface p1 type=dummy
> +])
> +ON_EXIT([kill `cat ovs-ofctl.pid`])
> +
> +AT_CAPTURE_FILE([ofctl_monitor.log])
> +AT_CHECK([ovs-ofctl -OOpenFlow12 add-flow br0 'table=0 actions=resubmit(1,1)'])
> +
> +AT_CHECK([ovs-ofctl monitor -P openflow10 br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log])
> +
> +for i in 1 2 3 ; do
> + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(0x010)'
> +done
> +
> +OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
> +AT_CHECK([cat ofctl_monitor.log], [0], [dnl
> +])
> +
> +AT_CHECK([ovs-appctl time/warp 5000], [0], [ignore])
> +AT_CHECK([ovs-ofctl -OOpenFlow12 dump-flows br0 | ofctl_strip | sort], [0], [dnl
> + n_packets=3, n_bytes=180, actions=resubmit(1,1)
> +OFPST_FLOW reply (OF1.2):
> +])
> +
> +OVS_VSWITCHD_STOP
> +AT_CLEANUP
> +
> +AT_SETUP([ofproto-dpif - Table Miss - OFPTC_TABLE_MISS_CONTINUE])
> +OVS_VSWITCHD_START([dnl
> + add-port br0 p1 -- set Interface p1 type=dummy
> +])
> +ON_EXIT([kill `cat ovs-ofctl.pid`])
> +
> +AT_CAPTURE_FILE([ofctl_monitor.log])
> +AT_CHECK([ovs-ofctl add-flow br0 'table=1 dl_src=10:11:11:11:11:11 actions=controller'])
> +AT_CHECK([ovs-ofctl -OOpenFlow11 mod-table br0 all continue])
> +
> +dnl Miss table 0, Hit table 1
> +AT_CHECK([ovs-ofctl monitor br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log])
> +
> +for i in 1 2 3 ; do
> + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=10:11:11:11:11:11,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(0x010)'
> +done
> +OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
> +
> +AT_CHECK([cat ofctl_monitor.log], [0], [dnl
> +NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=60 in_port=1 (via action) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=10:11:11:11:11:11,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +dnl
> +NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=60 in_port=1 (via action) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=10:11:11:11:11:11,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +dnl
> +NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=60 in_port=1 (via action) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=10:11:11:11:11:11,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +])
> +
> +dnl Hit table 0, Miss all other tables, sent to controller
> +AT_CHECK([ovs-ofctl monitor br0 65534 -P nxm --detach --no-chdir --pidfile 2> ofctl_monitor.log])
> +
> +for i in 1 2 3 ; do
> + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(0x010)'
> +done
> +OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
> +
> +AT_CHECK([cat ofctl_monitor.log], [0], [dnl
> +NXT_PACKET_IN (xid=0x0): table_id=253 cookie=0x0 total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +dnl
> +NXT_PACKET_IN (xid=0x0): table_id=253 cookie=0x0 total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +dnl
> +NXT_PACKET_IN (xid=0x0): table_id=253 cookie=0x0 total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +])
> +
> +AT_CHECK([ovs-appctl time/warp 5000], [0], [ignore])
> +AT_CHECK([ovs-ofctl -OOpenFlow12 dump-flows br0 | ofctl_strip | sort], [0], [dnl
> + table=1, n_packets=3, n_bytes=180, dl_src=10:11:11:11:11:11 actions=CONTROLLER:65535
> +OFPST_FLOW reply (OF1.2):
> +])
> +
> +OVS_VSWITCHD_STOP
> +AT_CLEANUP
> +
> +AT_SETUP([ofproto-dpif - Table Miss - goto table and OFPTC_TABLE_MISS_CONTINUE])
> +OVS_VSWITCHD_START([dnl
> + add-port br0 p1 -- set Interface p1 type=dummy
> +])
> +ON_EXIT([kill `cat ovs-ofctl.pid`])
> +
> +AT_CAPTURE_FILE([ofctl_monitor.log])
> +AT_DATA([flows.txt], [dnl
> +table=0 actions=goto_table(1)
> +table=2 dl_src=10:11:11:11:11:11 actions=controller
> +])
> +AT_CHECK([ovs-ofctl -OOpenFlow12 add-flows br0 flows.txt])
> +AT_CHECK([ovs-ofctl -OOpenFlow11 mod-table br0 all continue])
> +
> +dnl Hit table 0, Miss table 1, Hit table 2
> +AT_CHECK([ovs-ofctl monitor br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log])
> +
> +for i in 1 2 3 ; do
> + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=10:11:11:11:11:11,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(0x010)'
> +done
> +OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
> +
> +AT_CHECK([cat ofctl_monitor.log], [0], [dnl
> +NXT_PACKET_IN (xid=0x0): table_id=2 cookie=0x0 total_len=60 in_port=1 (via action) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=10:11:11:11:11:11,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +dnl
> +NXT_PACKET_IN (xid=0x0): table_id=2 cookie=0x0 total_len=60 in_port=1 (via action) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=10:11:11:11:11:11,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +dnl
> +NXT_PACKET_IN (xid=0x0): table_id=2 cookie=0x0 total_len=60 in_port=1 (via action) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=10:11:11:11:11:11,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +])
> +
> +dnl Hit table 1, Miss all other tables, sent to controller
> +AT_CHECK([ovs-ofctl monitor br0 65534 -P nxm --detach --no-chdir --pidfile 2> ofctl_monitor.log])
> +
> +for i in 1 2 3 ; do
> + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(0x010)'
> +done
> +OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
> +
> +AT_CHECK([cat ofctl_monitor.log], [0], [dnl
> +NXT_PACKET_IN (xid=0x0): table_id=253 cookie=0x0 total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +dnl
> +NXT_PACKET_IN (xid=0x0): table_id=253 cookie=0x0 total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +dnl
> +NXT_PACKET_IN (xid=0x0): table_id=253 cookie=0x0 total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
> +tcp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=8,tp_dst=9,tcp_flags=0x010 tcp_csum:0
> +])
> +
> +AT_CHECK([ovs-appctl time/warp 5000], [0], [ignore])
> +AT_CHECK([ovs-ofctl -OOpenFlow12 dump-flows br0 | ofctl_strip | sort], [0], [dnl
> + n_packets=6, n_bytes=360, actions=goto_table:1
> + table=2, n_packets=3, n_bytes=180, dl_src=10:11:11:11:11:11 actions=CONTROLLER:65535
> +OFPST_FLOW reply (OF1.2):
> +])
> +
> +OVS_VSWITCHD_STOP
> +AT_CLEANUP
> +
> +AT_SETUP([ofproto-dpif - Table Miss - resubmit and OFPTC_TABLE_MISS_CONTINUE])
> +OVS_VSWITCHD_START([dnl
> + add-port br0 p1 -- set Interface p1 type=dummy
> +])
> +ON_EXIT([kill `cat ovs-ofctl.pid`])
> +
> +AT_CAPTURE_FILE([ofctl_monitor.log])
> +AT_DATA([flows.txt], [dnl
> +table=0 actions=resubmit(1,1)
> +table=2 dl_src=10:11:11:11:11:11 actions=controller
> +])
> +AT_CHECK([ovs-ofctl -OOpenFlow12 add-flows br0 flows.txt])
> +AT_CHECK([ovs-ofctl -OOpenFlow11 mod-table br0 all continue])
> +
> +dnl Hit table 0, Miss table 1, Dropped
> +AT_CHECK([ovs-ofctl monitor br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log])
> +
> +for i in 1 2 3 ; do
> + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=10:11:11:11:11:11,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(0x010)'
> +done
> +OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
> +
> +AT_CHECK([cat ofctl_monitor.log], [0], [dnl
> +])
> +
> +dnl Hit table 1, Dropped
> +AT_CHECK([ovs-ofctl monitor br0 65534 -P nxm --detach --no-chdir --pidfile 2> ofctl_monitor.log])
> +
> +for i in 1 2 3 ; do
> + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(0x010)'
> +done
> +OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
> +
> +AT_CHECK([cat ofctl_monitor.log], [0], [dnl
> +])
> +
> +AT_CHECK([ovs-appctl time/warp 5000], [0], [ignore])
> +AT_CHECK([ovs-ofctl -OOpenFlow12 dump-flows br0 | ofctl_strip | sort], [0], [dnl
> + n_packets=6, n_bytes=360, actions=resubmit(1,1)
> + table=2, dl_src=10:11:11:11:11:11 actions=CONTROLLER:65535
> +OFPST_FLOW reply (OF1.2):
> +])
> +
> +OVS_VSWITCHD_STOP
> +AT_CLEANUP
> +
> +AT_SETUP([ofproto-dpif - Table Miss - OFPTC_TABLE_MISS_DROP])
> +OVS_VSWITCHD_START([dnl
> + add-port br0 p1 -- set Interface p1 type=dummy
> +])
> +ON_EXIT([kill `cat ovs-ofctl.pid`])
> +
> +AT_CAPTURE_FILE([ofctl_monitor.log])
> +AT_CHECK([ovs-ofctl -OOpenFlow11 mod-table br0 all drop])
> +
> +AT_CHECK([ovs-ofctl monitor -P openflow10 br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log])
> +
> +dnl Test that missed packets are droped
> +for i in 1 2 3 ; do
> + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(0x010)'
> +done
> +OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
> +
> +AT_CHECK([cat ofctl_monitor.log], [0], [dnl
> +])
> +
> +AT_CHECK([ovs-appctl time/warp 5000], [0], [ignore])
> +AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
> +NXST_FLOW reply:
> +])
> +
> +OVS_VSWITCHD_STOP
> +AT_CLEANUP
> +
> +AT_SETUP([ofproto-dpif - Table Miss - goto table and OFPTC_TABLE_MISS_DROP])
> +OVS_VSWITCHD_START([dnl
> + add-port br0 p1 -- set Interface p1 type=dummy
> +])
> +ON_EXIT([kill `cat ovs-ofctl.pid`])
> +
> +AT_CAPTURE_FILE([ofctl_monitor.log])
> +AT_CHECK([ovs-ofctl del-flows br0])
> +AT_CHECK([ovs-ofctl -OOpenFlow12 add-flow br0 'table=0 actions=goto_table(1)'])
> +AT_CHECK([ovs-ofctl -OOpenFlow11 mod-table br0 all drop])
> +
> +AT_CHECK([ovs-ofctl monitor -P openflow10 br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log])
> +
> +dnl Test that missed packets are droped
> +for i in 1 2 3 ; do
> + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(0x010)'
> +done
> +OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
> +
> +AT_CHECK([cat ofctl_monitor.log], [0], [dnl
> +])
> +
> +AT_CHECK([ovs-appctl time/warp 5000], [0], [ignore])
> +AT_CHECK([ovs-ofctl -OOpenFlow12 dump-flows br0 | ofctl_strip | sort], [0], [dnl
> + n_packets=3, n_bytes=180, actions=goto_table:1
> +OFPST_FLOW reply (OF1.2):
> +])
> +
> +OVS_VSWITCHD_STOP
> +AT_CLEANUP
> +
> +AT_SETUP([ofproto-dpif - Table Miss - resubmit and OFPTC_TABLE_MISS_DROP])
> +OVS_VSWITCHD_START([dnl
> + add-port br0 p1 -- set Interface p1 type=dummy
> +])
> +ON_EXIT([kill `cat ovs-ofctl.pid`])
> +
> +AT_CAPTURE_FILE([ofctl_monitor.log])
> +AT_CHECK([ovs-ofctl del-flows br0])
> +AT_CHECK([ovs-ofctl -OOpenFlow12 add-flow br0 'table=0 actions=resubmit(1,1)'])
> +AT_CHECK([ovs-ofctl -OOpenFlow11 mod-table br0 all drop])
> +
> +AT_CHECK([ovs-ofctl monitor -P openflow10 br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log])
> +
> +dnl Test that missed packets are droped
> +for i in 1 2 3 ; do
> + ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(0x010)'
> +done
> +OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
> +
> +AT_CHECK([cat ofctl_monitor.log], [0], [dnl
> +])
> +
> +AT_CHECK([ovs-appctl time/warp 5000], [0], [ignore])
> +AT_CHECK([ovs-ofctl -OOpenFlow12 dump-flows br0 | ofctl_strip | sort], [0], [dnl
> + n_packets=3, n_bytes=180, actions=resubmit(1,1)
> +OFPST_FLOW reply (OF1.2):
> +])
> +
> +OVS_VSWITCHD_STOP
> +AT_CLEANUP
> +
> AT_SETUP([ofproto-dpif - controller])
> OVS_VSWITCHD_START([dnl
> add-port br0 p1 -- set Interface p1 type=dummy
> --
> 1.8.5.2
>
More information about the dev
mailing list