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 <az...@nicira.com> > Signed-off-by: Simon Horman <ho...@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 > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev