[...] > >> 2. This patch doesn't cover cases where sampling is not actually > >> the last action, but further actions do not yield any datapath > >> actions. E.g. if you have a register resoration afterwards, > >> which happens in automatically built pipelines like in OVN. > >> Or if the last action after sampling is learn(). And things are > >> getting more complicated if we take into account resubmits and > >> processing in different bridges via patch ports. > > > > I agree this could be problematic. Maybe we should make sure the sample > > is the last dp action and "fix it". A trick such as the one done for > > sflow. > > These tricks are not accurate as well. I beleive they do not track > the information well across tunnel encaps at least. >
I am currently testing a patch implements this for both per-bridge and per-flow sampling. I attach the essense (i.e: not the tests) of it at the end [1]. Can you expand on your concerns about tunnel encaps? > > > >> > >> 3. If someone is sampling the drops specifically, they know where > >> to find the packets, because they configured the collector. > >> > > > > I think drop stats and samples are two different things. There are > > typically extacted by different tools and systems. > > > > Besides, what about per-bridge sampling (next patch)? > > The user enables sampling on a bridge without explicitly doing it > > for drops and suddenly the drop statistics dissapear. > > I think 'user enables sampling on a bridge' counts as an explicit > altering of the datapath pipeline. > > > > >> 4. Packets are not actually dropped, they are delivered to userspace > >> or psample. It might make sense though to drop with a reson in > >> case the upcall fails or psample fails to deliver to any entity > >> and it is the last action in the datapath, but that's a kernel > >> change to make. > >> > > > > I don't want to get into another semantic discussion between consume, > > free and drop or the dark corners of the OpenFlow protocol. For me it's > > pretty clear that if the last action is to sample, the packet is > > "dropped" in the sense that, from a switch' perspective, if it's not > > forwarded/sent somewhere, it's dropped. > > > > I know you don't think the same :-). > > > > Would you then agree that the concept of dropping packets is very > > unclear and OpenFlow does not make it easy (or even possible?) to > > express a sampled drops and we should add an extension action to > > explicitly drop packets? > > I agree that dropping packets is not clear in this case. > I'm not a fan of OpenFlow drop action, it may cause extra logical issues. > I'd go with a database knob instead. > > I'd say we can either drop these two patches for now and find a better > solution in the next release cycle, or add an experimental global database > knob that will control this behavior and will be disabled by default. > Once we have better understanding how it behaves in a real world, we > could switch the default or remove the feature if it causes issues or > confusion. > > What do you think? > I guess this new know would be considered a new feature and therefore not backportable to 3.4. So if this affects users (as is my suspicious), we would have a non-fixable bug? [1] Please consider this alternative to the two patches (it does not include tests). FWIF, we could make this tweak configurable (default to false) in the db. --- diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 0a0964348..da1ef0b49 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -3415,6 +3415,7 @@ compose_sample_action(struct xlate_ctx *ctx, struct ofproto *ofproto = &ctx->xin->ofproto->up; uint32_t meter_id = ofproto->slowpath_meter_id; size_t cookie_offset = 0; + size_t observe_offset; /* The meter action is only used to throttle userspace actions. * If they are not needed and the sampling rate is 100%, avoid generating @@ -3432,6 +3433,7 @@ compose_sample_action(struct xlate_ctx *ctx, } if (args->psample) { + observe_offset = ctx->odp_actions->size; odp_put_psample_action(ctx->odp_actions, args->psample->group_id, (void *) &args->psample->cookie, @@ -3443,6 +3445,7 @@ compose_sample_action(struct xlate_ctx *ctx, nl_msg_put_u32(ctx->odp_actions, OVS_ACTION_ATTR_METER, meter_id); } + observe_offset = ctx->odp_actions->size; odp_port_t odp_port = ofp_port_to_odp_port( ctx->xbridge, ctx->xin->flow.in_port.ofp_port); uint32_t pid = dpif_port_get_pid(ctx->xbridge->dpif, odp_port); @@ -3457,6 +3460,9 @@ compose_sample_action(struct xlate_ctx *ctx, if (is_sample) { nl_msg_end_nested(ctx->odp_actions, actions_offset); nl_msg_end_nested(ctx->odp_actions, sample_offset); + ctx->xout->last_observe_offset = sample_offset; + } else { + ctx->xout->last_observe_offset = observe_offset; } return cookie_offset; @@ -8066,12 +8072,13 @@ xlate_wc_finish(struct xlate_ctx *ctx) } } -/* This will optimize the odp actions generated. For now, it will remove - * trailing clone actions that are unnecessary. */ +/* This will tweak the odp actions generated. For now, it will: + * - Remove trailing clone actions that are unnecessary. + * - Add an explicit drop action if the last action is observational. */ static void -xlate_optimize_odp_actions(struct xlate_in *xin) +xlate_tweak_odp_actions(struct xlate_ctx *ctx) { - struct ofpbuf *actions = xin->odp_actions; + struct ofpbuf *actions = ctx->xin->odp_actions; struct nlattr *last_action = NULL; struct nlattr *a; int left; @@ -8085,9 +8092,13 @@ xlate_optimize_odp_actions(struct xlate_in *xin) last_action = a; } + if (!last_action) { + return; + } + /* Remove the trailing clone() action, by directly embedding the nested * actions. */ - if (last_action && nl_attr_type(last_action) == OVS_ACTION_ATTR_CLONE) { + if (nl_attr_type(last_action) == OVS_ACTION_ATTR_CLONE) { void *dest; nl_msg_reset_size(actions, @@ -8096,6 +8107,16 @@ xlate_optimize_odp_actions(struct xlate_in *xin) dest = nl_msg_put_uninit(actions, nl_attr_get_size(last_action)); memmove(dest, nl_attr_get(last_action), nl_attr_get_size(last_action)); + return; + } + + /* If the last action of the list is an observability action, add an + * explicit drop action so that drop statistics remain reliable. */ + if (ctx->xout->last_observe_offset != UINT32_MAX && + (char *) last_action == (char *) actions->data + + ctx->xout->last_observe_offset && + ovs_explicit_drop_action_supported(ctx->xbridge->ofproto)) { + put_drop_action(actions, XLATE_OK); } } @@ -8113,6 +8134,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) *xout = (struct xlate_out) { .slow = 0, .recircs = RECIRC_REFS_EMPTY_INITIALIZER, + .last_observe_offset = UINT32_MAX, }; struct xlate_cfg *xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp); @@ -8541,17 +8563,15 @@ exit: xout->slow = 0; if (xin->odp_actions) { ofpbuf_clear(xin->odp_actions); + /* Make the drop explicit if the datapath supports it. */ + if (ovs_explicit_drop_action_supported(ctx.xbridge->ofproto)) { + put_drop_action(xin->odp_actions, ctx.error); + } } } else { - /* In the non-error case, see if we can further optimize the datapath - * rules by removing redundant (clone) actions. */ - xlate_optimize_odp_actions(xin); - } - - /* Install drop action if datapath supports explicit drop action. */ - if (xin->odp_actions && !xin->odp_actions->size && - ovs_explicit_drop_action_supported(ctx.xbridge->ofproto)) { - put_drop_action(xin->odp_actions, ctx.error); + /* In the non-error case, see if we can further optimize or tweak + * datapath actions. */ + xlate_tweak_odp_actions(&ctx); } /* Since congestion drop and forwarding drop are not exactly diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h index 08f9397d8..d973a634a 100644 --- a/ofproto/ofproto-dpif-xlate.h +++ b/ofproto/ofproto-dpif-xlate.h @@ -61,6 +61,10 @@ struct xlate_out { /* Recirc action IDs on which references are held. */ struct recirc_refs recircs; + + /* Keep track of the last action whose purpose is purely observational. + * e.g: IPFIX, sFlow, local sampling. */ + uint32_t last_observe_offset; }; struct xlate_in { _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev