Re: [ovs-dev] [PATCH v1 11/13] ofproto: xlate: Make flow-sampled drops explicit.

2024-07-11 Thread Adrián Moreno
[...]
> >> 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 = >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 *) >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 {
+   

Re: [ovs-dev] [PATCH net-next v2] selftests: openvswitch: retry instead of sleep

2024-07-11 Thread Adrián Moreno
On Wed, Jul 10, 2024 at 11:04:59AM GMT, Adrian Moreno wrote:
> There are a couple of places where the test script "sleep"s to wait for
> some external condition to be met.
>
> This is error prone, specially in slow systems (identified in CI by
> "KSFT_MACHINE_SLOW=yes").
>
> To fix this, add a "ovs_wait" function that tries to execute a command
> a few times until it succeeds. The timeout used is set to 5s for
> "normal" systems and doubled if a slow CI machine is detected.
>
> This should make the following work:
>
> $ vng --build  \
> --config tools/testing/selftests/net/config \
> --config kernel/configs/debug.config
>
> $ vng --run . --user root -- "make -C tools/testing/selftests/ \
> KSFT_MACHINE_SLOW=yes TARGETS=net/openvswitch run_tests"
>
> Signed-off-by: Adrian Moreno 
> ---
>  .../selftests/net/openvswitch/openvswitch.sh  | 45 +++
>  .../selftests/net/openvswitch/ovs-dpctl.py|  1 +
>  2 files changed, 38 insertions(+), 8 deletions(-)
>
> diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh 
> b/tools/testing/selftests/net/openvswitch/openvswitch.sh
> index bc71dbc18b21..cc0bfae2bafa 100755
> --- a/tools/testing/selftests/net/openvswitch/openvswitch.sh
> +++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh
> @@ -11,6 +11,11 @@ ksft_skip=4
>  PAUSE_ON_FAIL=no
>  VERBOSE=0
>  TRACING=0
> +WAIT_TIMEOUT=5
> +
> +if test "X$KSFT_MACHINE_SLOW" == "Xyes"; then
> + WAIT_TIMEOUT=10
> +fi
>
>  tests="
>   arp_pingeth-arp: Basic arp ping between 
> two NS
> @@ -29,6 +34,30 @@ info() {
>   [ $VERBOSE = 0 ] || echo $*
>  }
>
> +ovs_wait() {
> + info "waiting $WAIT_TIMEOUT s for: $@"
> +
> + if "$@" ; then
> + info "wait succeeded immediately"
> + return 0
> + fi
> +
> + # A quick re-check helps speed up small races in fast systems.
> + # However, fractional sleeps might not necessarily work.
> + local start=0
> + sleep 0.1 || { sleep 1; start=1; }
> +
> + for (( i=start; i + if "$@" ; then
> + info "wait succeeded after $i seconds"
> + return 0
> + fi
> + sleep 1
> + done
> + info "wait failed after $i seconds"
> + return 1
> +}
> +
>  ovs_base=`pwd`
>  sbxs=
>  sbx_add () {
> @@ -278,20 +307,19 @@ test_psample() {
>
>   # Record psample data.
>   ovs_spawn_daemon "test_psample" python3 $ovs_base/ovs-dpctl.py 
> psample-events
> + ovs_wait grep -q "listening for psample events" ${ovs_dir}/stdout
>
>   # Send a single ping.
> - sleep 1
>   ovs_sbx "test_psample" ip netns exec client ping -I c1 172.31.110.20 -c 
> 1 || return 1
> - sleep 1
>
>   # We should have received one userspace action upcall and 2 psample 
> packets.
> - grep -E "userspace action command" $ovs_dir/s0.out >/dev/null 2>&1 || 
> return 1
> + ovs_wait grep -q "userspace action command" $ovs_dir/s0.out || return 1
>
>   # client -> server samples should only contain the first 14 bytes of 
> the packet.
> - grep -E "rate:4294967295,group:1,cookie:c0ffee data:[0-9a-f]{28}$" \
> -  $ovs_dir/stdout >/dev/null 2>&1 || return 1
> - grep -E "rate:4294967295,group:2,cookie:eeff0c" \
> -  $ovs_dir/stdout >/dev/null 2>&1 || return 1
> + ovs_wait grep -qE "rate:4294967295,group:1,cookie:c0ffee 
> data:[0-9a-f]{28}$" \
> + $ovs_dir/stdout || return 1
> +
> + ovs_wait grep -q "rate:4294967295,group:2,cookie:eeff0c" 
> $ovs_dir/stdout || return 1
>
>   return 0
>  }
> @@ -711,7 +739,8 @@ test_upcall_interfaces() {
>   ovs_add_netns_and_veths "test_upcall_interfaces" ui0 upc left0 l0 \
>   172.31.110.1/24 -u || return 1
>
> - sleep 1
> + ovs_wait grep -q "listening on upcall packet handler" 
> ${ovs_dir}/left0.out
> +
>   info "sending arping"
>   ip netns exec upc arping -I l0 172.31.110.20 -c 1 \
>   >$ovs_dir/arping.stdout 2>$ovs_dir/arping.stderr
> diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py 
> b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> index 1e15b0818074..8a0396bfaf99 100644
> --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> @@ -2520,6 +2520,7 @@ class PsampleEvent(EventSocket):
>  marshal_class = psample_msg
>
>  def read_samples(self):
> +print("listening for psample events", flush=True)
>  while True:
>  try:
>  for msg in self.get():
> --
> 2.45.2
>


This patch is supposed to fix openvswitch selftests on "-dbg" machines.
However, as Simon points out, all recent rounds are failing [1]. I don't
see this patch being included in the batches and I was wondering why.

Also I see a (presumably unrelated) build error netdev/build_32bit.
Is there anything I can do?

[1]

Re: [ovs-dev] [PATCH v1 13/13] ofp-actions: Load data from fields in sample action.

2024-07-11 Thread Adrián Moreno
On Thu, Jul 11, 2024 at 12:32:06AM GMT, Ilya Maximets wrote:
> On 7/10/24 23:38, Adrián Moreno wrote:
> > On Wed, Jul 10, 2024 at 11:00:43PM GMT, Ilya Maximets wrote:
> >> On 7/7/24 22:09, Adrian Moreno wrote:
> >>> When sample action gets used as a way of sampling traffic with
> >>> controller-generated metadata (i.e: obs_domain_id and obs_point_id),
> >>> the controller will have to increase the number of flows to ensure each
> >>> part of the pipeline contains the right metadata.
> >>>
> >>> As an example, if the controller decides to sample stateful traffic, it
> >>> could store the computed metadata for each connection in the conntrack
> >>> label. However, for established connections, a flow must be created for
> >>> each different ct_label value with a sample action that contains a
> >>> different hardcoded obs_domain and obs_point id.
> >>>
> >>> This patch adds a new version of the NXAST_RAW_SAMPLE* action (number 4)
> >>> that supports specifying the observation point and domain using an
> >>> OpenFlow field reference, so now the controller can express:
> >>>
> >>>  sample(...
> >>> obs_domain_id=NXM_NX_CT_LABEL[0..31],
> >>> obs_point_id=NXM_NX_CT_LABEL[32..63]
> >>> ...
> >>>)
> >>>
> >>> Signed-off-by: Adrian Moreno 
> >>> ---
> >>>  include/openvswitch/ofp-actions.h |   8 +-
> >>>  lib/ofp-actions.c | 249 +++---
> >>>  ofproto/ofproto-dpif-xlate.c  |  55 ++-
> >>>  python/ovs/flow/ofp.py|   8 +-
> >>>  python/ovs/flow/ofp_act.py|   4 +-
> >>>  tests/ofp-actions.at  |   5 +
> >>>  tests/ofproto-dpif.at |  41 +
> >>>  tests/system-traffic.at   |  74 +
> >>>  8 files changed, 405 insertions(+), 39 deletions(-)
> >>
> >> Not a full review, it's a complicated change.  See a few comments below.
> >>
> >>>
> >>> diff --git a/include/openvswitch/ofp-actions.h 
> >>> b/include/openvswitch/ofp-actions.h
> >>> index 7b57e49ad..56dc2c147 100644
> >>> --- a/include/openvswitch/ofp-actions.h
> >>> +++ b/include/openvswitch/ofp-actions.h
> >>> @@ -1015,14 +1015,16 @@ enum nx_action_sample_direction {
> >>>
> >>>  /* OFPACT_SAMPLE.
> >>>   *
> >>> - * Used for NXAST_SAMPLE, NXAST_SAMPLE2, and NXAST_SAMPLE3. */
> >>> + * Used for NXAST_SAMPLE, NXAST_SAMPLE2, NXAST_SAMPLE3 and 
> >>> NXAST_SAMPLE4. */
> >>>  struct ofpact_sample {
> >>>  OFPACT_PADDED_MEMBERS(
> >>>  struct ofpact ofpact;
> >>>  uint16_t probability;   /* Always positive. */
> >>>  uint32_t collector_set_id;
> >>> -uint32_t obs_domain_id;
> >>> -uint32_t obs_point_id;
> >>> +uint32_t obs_domain_imm;
> >>> +struct mf_subfield obs_domain_src;
> >>> +uint32_t obs_point_imm;
> >>> +struct mf_subfield obs_point_src;
> >>>  ofp_port_t sampling_port;
> >>>  enum nx_action_sample_direction direction;
> >>>  );
> >>> diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
> >>> index da7b1dd31..e329a7e3f 100644
> >>> --- a/lib/ofp-actions.c
> >>> +++ b/lib/ofp-actions.c
> >>> @@ -330,6 +330,8 @@ enum ofp_raw_action_type {
> >>>  NXAST_RAW_SAMPLE2,
> >>>  /* NX1.0+(41): struct nx_action_sample2. */
> >>>  NXAST_RAW_SAMPLE3,
> >>> +/* NX1.0+(51): struct nx_action_sample4, ... VLMFF */
> >>
> >> Why the dots are here?  The structure doesn't seem to have
> >> extra fields at the end.
> >
> > I missread the description then. I thought it was just about alignment.
> >
> >>
> >>> +NXAST_RAW_SAMPLE4,
> >>>
> >>>  /* NX1.0+(34): struct nx_action_conjunction. */
> >>>  NXAST_RAW_CONJUNCTION,
> >>> @@ -6188,6 +6190,34 @@ struct nx_action_sample2 {
> >>>   };
> >>>   OFP_ASSERT(sizeof(struct nx_action_sample2) == 32);
> >>>
> >>> +/* Action structure for NXAST_SAMPLE4
> >>> + *
> >>> + * NXAST_SAMPLE4 was added in Open vSwitch 3.4.0.  Compared to 
> >>> 

Re: [ovs-dev] [PATCH v1 11/13] ofproto: xlate: Make flow-sampled drops explicit.

2024-07-10 Thread Adrián Moreno
On Wed, Jul 10, 2024 at 11:31:42PM GMT, Ilya Maximets wrote:
> On 7/7/24 22:09, Adrian Moreno wrote:
> > When an action set ends in a an OFP_SAMPLE action, it means the packet
> > will be dropped and sampled. Make the drop explicit in this case so that
> > drop statistics remain accurate.
> >
> > This could be done outside of the sample action, i.e: "sample(...),drop"
> > but datapaths optimize sample actions that are found in the last
> > position. So, taking into account that datapaths already report when the
> > last sample probability fails, it is safe to put the drop inside the
> > sample, i.e: "sample(...,drop)".
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  ofproto/ofproto-dpif-xlate.c | 16 +++--
> >  tests/drop-stats.at  | 65 
> >  tests/ofproto-dpif.at| 44 
> >  3 files changed, 123 insertions(+), 2 deletions(-)
>
> Hi, Adrian.  As we discussed before on the kernel list, I'm not sure
> this is a right change to make for a fwe reasons:
>
> 1. We do not know the user's intentions.  We do not know if they
>wanted to drop these packets or their goal was to sample them
>and it just happened to be the last action in the list, because
>they put it after the output action and not before.
>

If there are datapath actions after output action you will probably get
drops reported in both datapaths.

> 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.

>
> 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.

> 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?

> 5. Drop reporting in either datapath implementation is not 100%
>accurate anyway and requires users to know the kernel internals.
>

Shouldn't we try to make them more accurate, not less?

> Some of that also applies to the next patch in the set.
>

I can take some of the critics for this patch but for me, the next one
is bluntly fixing a bug: Per-bridge sflow/IPFIX should not break drop
statistics.

> For the patch itself, you should also check that the action set is
> actually empty (not the action list) after the sample action translation.

Aye, what about doing the sflow trick and look at the datapath flow
alone?

> There is a chance that the clone action is disabled and sample is
> used in place of a clone, I'm not sure this case is covered.

That case does not go through compose_sample_action but encodes the
datapath action directly.

> And the formatting in tests seems very inconsistent.
>

I agree, I tried to follow the drop-stats.at "style" and the result is
pretty bad.

> Best regards, Ilya Maximets.
>

Thanks.

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH v1 13/13] ofp-actions: Load data from fields in sample action.

2024-07-10 Thread Adrián Moreno
On Wed, Jul 10, 2024 at 11:00:43PM GMT, Ilya Maximets wrote:
> On 7/7/24 22:09, Adrian Moreno wrote:
> > When sample action gets used as a way of sampling traffic with
> > controller-generated metadata (i.e: obs_domain_id and obs_point_id),
> > the controller will have to increase the number of flows to ensure each
> > part of the pipeline contains the right metadata.
> >
> > As an example, if the controller decides to sample stateful traffic, it
> > could store the computed metadata for each connection in the conntrack
> > label. However, for established connections, a flow must be created for
> > each different ct_label value with a sample action that contains a
> > different hardcoded obs_domain and obs_point id.
> >
> > This patch adds a new version of the NXAST_RAW_SAMPLE* action (number 4)
> > that supports specifying the observation point and domain using an
> > OpenFlow field reference, so now the controller can express:
> >
> >  sample(...
> > obs_domain_id=NXM_NX_CT_LABEL[0..31],
> > obs_point_id=NXM_NX_CT_LABEL[32..63]
> > ...
> >)
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  include/openvswitch/ofp-actions.h |   8 +-
> >  lib/ofp-actions.c | 249 +++---
> >  ofproto/ofproto-dpif-xlate.c  |  55 ++-
> >  python/ovs/flow/ofp.py|   8 +-
> >  python/ovs/flow/ofp_act.py|   4 +-
> >  tests/ofp-actions.at  |   5 +
> >  tests/ofproto-dpif.at |  41 +
> >  tests/system-traffic.at   |  74 +
> >  8 files changed, 405 insertions(+), 39 deletions(-)
>
> Not a full review, it's a complicated change.  See a few comments below.
>
> >
> > diff --git a/include/openvswitch/ofp-actions.h 
> > b/include/openvswitch/ofp-actions.h
> > index 7b57e49ad..56dc2c147 100644
> > --- a/include/openvswitch/ofp-actions.h
> > +++ b/include/openvswitch/ofp-actions.h
> > @@ -1015,14 +1015,16 @@ enum nx_action_sample_direction {
> >
> >  /* OFPACT_SAMPLE.
> >   *
> > - * Used for NXAST_SAMPLE, NXAST_SAMPLE2, and NXAST_SAMPLE3. */
> > + * Used for NXAST_SAMPLE, NXAST_SAMPLE2, NXAST_SAMPLE3 and NXAST_SAMPLE4. 
> > */
> >  struct ofpact_sample {
> >  OFPACT_PADDED_MEMBERS(
> >  struct ofpact ofpact;
> >  uint16_t probability;   /* Always positive. */
> >  uint32_t collector_set_id;
> > -uint32_t obs_domain_id;
> > -uint32_t obs_point_id;
> > +uint32_t obs_domain_imm;
> > +struct mf_subfield obs_domain_src;
> > +uint32_t obs_point_imm;
> > +struct mf_subfield obs_point_src;
> >  ofp_port_t sampling_port;
> >  enum nx_action_sample_direction direction;
> >  );
> > diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
> > index da7b1dd31..e329a7e3f 100644
> > --- a/lib/ofp-actions.c
> > +++ b/lib/ofp-actions.c
> > @@ -330,6 +330,8 @@ enum ofp_raw_action_type {
> >  NXAST_RAW_SAMPLE2,
> >  /* NX1.0+(41): struct nx_action_sample2. */
> >  NXAST_RAW_SAMPLE3,
> > +/* NX1.0+(51): struct nx_action_sample4, ... VLMFF */
>
> Why the dots are here?  The structure doesn't seem to have
> extra fields at the end.

I missread the description then. I thought it was just about alignment.

>
> > +NXAST_RAW_SAMPLE4,
> >
> >  /* NX1.0+(34): struct nx_action_conjunction. */
> >  NXAST_RAW_CONJUNCTION,
> > @@ -6188,6 +6190,34 @@ struct nx_action_sample2 {
> >   };
> >   OFP_ASSERT(sizeof(struct nx_action_sample2) == 32);
> >
> > +/* Action structure for NXAST_SAMPLE4
> > + *
> > + * NXAST_SAMPLE4 was added in Open vSwitch 3.4.0.  Compared to 
> > NXAST_SAMPLE3,
> > + * it adds support for using field specifiers for observation_domain_id and
> > + * observation_point_id. */
> > +struct nx_action_sample4 {
> > +ovs_be16 type;  /* OFPAT_VENDOR. */
> > +ovs_be16 len;   /* Length is 32. */
>
> Is the length 32?  40, I suppose.

Yep

>
> > +ovs_be32 vendor;/* NX_VENDOR_ID. */
> > +ovs_be16 subtype;   /* NXAST_SAMPLE. */
>
> NXAST_SAMPLE4 ?

Ack.

>
> > +ovs_be16 probability;   /* Fraction of packets to sample. */
> > +ovs_be32 collector_set_id;  /* ID of collector set in OVSDB. */
> > +ovs_be32 obs_domain_src;/* Source of the 
> > observation_domain_id. */
> > +union {
> > +ovs_be16 obs_domain_ofs_nbits;  /* Range to use from source field. 
> > */
> > +ovs_be32 obs_domain_imm;/* Immediate value for domain id. 
> > */
> > +};
> > +ovs_be32 obs_point_src; /* Source of the observation_point_id 
> > */
> > +union {
> > +ovs_be16 obs_point_ofs_nbits;  /* Range to use from source field. 
> > */
> > +ovs_be32 obs_point_imm;/* Immediate value for point id. */
> > +};
> > +ovs_be16 sampling_port; /* Sampling port. */
> > +uint8_t  direction; /* Sampling direction. */
> > +uint8_t  zeros[5];  

Re: [ovs-dev] [PATCH v1 13/13] ofp-actions: Load data from fields in sample action.

2024-07-10 Thread Adrián Moreno
On Wed, Jul 10, 2024 at 10:26:23PM GMT, Ilya Maximets wrote:
> On 7/9/24 16:25, Eelco Chaudron wrote:
> >
> >
> > On 9 Jul 2024, at 16:17, Adrián Moreno wrote:
> >
> >> On Tue, Jul 09, 2024 at 11:46:12AM GMT, Eelco Chaudron wrote:
> >>> On 7 Jul 2024, at 22:09, Adrian Moreno wrote:
> >>>
> >>>> When sample action gets used as a way of sampling traffic with
> >>>> controller-generated metadata (i.e: obs_domain_id and obs_point_id),
> >>>> the controller will have to increase the number of flows to ensure each
> >>>> part of the pipeline contains the right metadata.
> >>>>
> >>>> As an example, if the controller decides to sample stateful traffic, it
> >>>> could store the computed metadata for each connection in the conntrack
> >>>> label. However, for established connections, a flow must be created for
> >>>> each different ct_label value with a sample action that contains a
> >>>> different hardcoded obs_domain and obs_point id.
> >>>>
> >>>> This patch adds a new version of the NXAST_RAW_SAMPLE* action (number 4)
> >>>> that supports specifying the observation point and domain using an
> >>>> OpenFlow field reference, so now the controller can express:
> >>>>
> >>>>  sample(...
> >>>> obs_domain_id=NXM_NX_CT_LABEL[0..31],
> >>>> obs_point_id=NXM_NX_CT_LABEL[32..63]
> >>>> ...
> >>>>)
> >>>>
> >>>> Signed-off-by: Adrian Moreno 
> >>>
> >>> See some comments inline. I’m missing the documentation update.
> >>>
> >>
> >> Yes. I noticed I missed both the NEWS and documentation update.
> >>
>
> You're also missing unit tests in ovs-ofctl.at.
>

Ack.

> >>>> index 323a58cbf..2aff48f5e 100644
> >>>> --- a/ofproto/ofproto-dpif-xlate.c
> >>>> +++ b/ofproto/ofproto-dpif-xlate.c
> >>>> @@ -5909,6 +5909,44 @@ xlate_fin_timeout(struct xlate_ctx *ctx,
> >>>>  }
> >>>>  }
> >>>>
> >>>> +static uint32_t
> >>>> +ofpact_sample_get_domain(struct xlate_ctx *ctx,
> >>>> + const struct ofpact_sample *os)
> >>>> +{
> >>>> +if (os->obs_domain_src.field) {
> >>>> +union mf_subvalue *value = xmalloc(sizeof *value);
> >>>
> >>> Would it be better to just put these 128 bytes on the stack to avoid
> >>> memory fragmentation? Same for the next function.
> >>>
> >>> Or maybe something better, we could do something like we did for
> >>> exact_match_mask?
> >>>
> >>>   const union mf_value exact_match_mask = MF_VALUE_EXACT_INITIALIZER;
> >>>   extern const union mf_value exact_match_mask;
> >>>
> >>
> >> A quick look seemed to indicate dynamic memory was preferred in this
> >> module so I assumed there was a reason for it (I do remember stack size
> >> being a problem at some point, not sure if it was here).
> >>
> >> I'll look at the exact_match_mask case.
> >
> > I guess this function is not called recursively, so we should be ok with 
> > the stack usage. But a const variable might be better (and we can fix the 
> > other place(s) where you copied this code from ;).
>
> While the function itself is not called recursively, the problem is
> that it can be inlined into the main do_xlate_actions and cause
> a significant stack usage increase even if the sampling is not used.
> So, extra investigation on what is getting inlined with different
> compilers and compiler flags is needed if we want to allocate it
> on stack.
>
> Best regards, Ilya Maximets.
>

For the next version, I have implemented Eelco's suggestion: an extern
constant all-one enum mf_subfield. That should avoid both stack increase
and memory fragmentation

Cheers,
Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH v1 06/13] ofproto-dpif-xlate: Use psample for local sample.

2024-07-10 Thread Adrián Moreno
On Wed, Jul 10, 2024 at 06:52:30PM GMT, Ilya Maximets wrote:
> On 7/10/24 15:25, Adrián Moreno wrote:
> > On Wed, Jul 10, 2024 at 02:56:44PM GMT, Ilya Maximets wrote:
> >> On 7/7/24 22:08, Adrian Moreno wrote:
> >>> Use the newly added psample action to implement OpenFlow sample() actions
> >>> with local sampling configuration if possible.
> >>>
> >>> A bit of refactoring in compose_sample_actions arguments helps make it a
> >>> bit more readable.
> >>>
> >>> Signed-off-by: Adrian Moreno 
> >>> ---
> >>>  ofproto/ofproto-dpif-lsample.c |  16 +++
> >>>  ofproto/ofproto-dpif-lsample.h |   5 +
> >>>  ofproto/ofproto-dpif-xlate.c   | 251 +++--
> >>>  ofproto/ofproto-dpif-xlate.h   |   5 +-
> >>>  ofproto/ofproto-dpif.c |   2 +-
> >>>  tests/ofproto-dpif.at  | 146 +++
> >>>  6 files changed, 345 insertions(+), 80 deletions(-)
> >>>
> >>> diff --git a/ofproto/ofproto-dpif-lsample.c 
> >>> b/ofproto/ofproto-dpif-lsample.c
> >>> index d675a116f..534ad96f0 100644
> >>> --- a/ofproto/ofproto-dpif-lsample.c
> >>> +++ b/ofproto/ofproto-dpif-lsample.c
> >>> @@ -140,6 +140,22 @@ dpif_lsample_set_options(struct dpif_lsample 
> >>> *lsample,
> >>>  return changed;
> >>>  }
> >>>
> >>> +/* Returns the group_id for a given collector_set_id, if it exists. */
> >>> +bool
> >>> +dpif_lsample_get_group_id(struct dpif_lsample *ps, uint32_t 
> >>> collector_set_id,
> >>> +  uint32_t *group_id)
> >>> +{
> >>> +struct lsample_exporter_node *node;
> >>> +bool found = false;
> >>> +
> >>> +node = dpif_lsample_find_exporter_node(ps, collector_set_id);
> >>> +if (node) {
> >>> +found = true;
> >>> +*group_id = node->exporter.options.group_id;
> >>> +}
> >>> +return found;
> >>> +}
> >>> +
> >>>  struct dpif_lsample *
> >>>  dpif_lsample_create(void)
> >>>  {
> >>> diff --git a/ofproto/ofproto-dpif-lsample.h 
> >>> b/ofproto/ofproto-dpif-lsample.h
> >>> index bee36c9c5..9c1026551 100644
> >>> --- a/ofproto/ofproto-dpif-lsample.h
> >>> +++ b/ofproto/ofproto-dpif-lsample.h
> >>> @@ -18,6 +18,7 @@
> >>>  #define OFPROTO_DPIF_LSAMPLE_H 1
> >>>
> >>>  #include 
> >>> +#include 
> >>>  #include 
> >>>
> >>>  struct dpif_lsample;
> >>> @@ -33,4 +34,8 @@ bool dpif_lsample_set_options(struct dpif_lsample *,
> >>>const struct ofproto_lsample_options *,
> >>>size_t n_opts);
> >>>
> >>> +bool dpif_lsample_get_group_id(struct dpif_lsample *,
> >>> +   uint32_t collector_set_id,
> >>> +   uint32_t *group_id);
> >>> +
> >>>  #endif /* OFPROTO_DPIF_LSAMPLE_H */
> >>> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> >>> index 7c4950895..5e8113d5e 100644
> >>> --- a/ofproto/ofproto-dpif-xlate.c
> >>> +++ b/ofproto/ofproto-dpif-xlate.c
> >>> @@ -47,6 +47,7 @@
> >>>  #include "ofproto/ofproto-dpif-ipfix.h"
> >>>  #include "ofproto/ofproto-dpif-mirror.h"
> >>>  #include "ofproto/ofproto-dpif-monitor.h"
> >>> +#include "ofproto/ofproto-dpif-lsample.h"
> >>>  #include "ofproto/ofproto-dpif-sflow.h"
> >>>  #include "ofproto/ofproto-dpif-trace.h"
> >>>  #include "ofproto/ofproto-dpif-xlate-cache.h"
> >>> @@ -117,6 +118,7 @@ struct xbridge {
> >>>  struct dpif_sflow *sflow; /* SFlow handle, or null. */
> >>>  struct dpif_ipfix *ipfix; /* Ipfix handle, or null. */
> >>>  struct netflow *netflow;  /* Netflow handle, or null. */
> >>> +struct dpif_lsample *lsample; /* Local sample handle, or null. */
> >>>  struct stp *stp;  /* STP or null if disabled. */
> >>>  struct rstp *rstp;/* RSTP or null if disabled. */
> >>>
> >>> @@ -686,6 +688,7 @@ static void xlate_xbridge_set(struct xbridge *, 
&

Re: [ovs-dev] [PATCH v1 08/13] ofproto-dpif-lsample: Show stats via unixctl.

2024-07-10 Thread Adrián Moreno
On Wed, Jul 10, 2024 at 04:28:55PM GMT, Eelco Chaudron wrote:
>
>
> On 10 Jul 2024, at 15:06, Ilya Maximets wrote:
>
> > On 7/7/24 22:09, Adrian Moreno wrote:
> >> Add a command to dump statistics per exporter.
> >>
> >> Signed-off-by: Adrian Moreno 
> >> ---
> >>  NEWS   |   2 +
> >>  ofproto/ofproto-dpif-lsample.c | 111 +
> >>  ofproto/ofproto-dpif-lsample.h |   1 +
> >>  ofproto/ofproto-dpif.c |   1 +
> >>  4 files changed, 115 insertions(+)
> >>
> >> diff --git a/NEWS b/NEWS
> >> index 15faf9fc3..1c53badea 100644
> >> --- a/NEWS
> >> +++ b/NEWS
> >> @@ -20,6 +20,8 @@ Post-v3.3.0
> >>   allows samples to be emitted locally (instead of via IPFIX) in a
> >>   datapath-specific manner. The Linux kernel datapath is the first to
> >>   support this feature by using the new datapath "psample" action.
> >> + A new unixctl command 'lsample/show' shows packet and bytes 
> >> statistics
> >> + per local sample exporter.
> >
> > Maybe add this as a separate bullet point.
> >
> >>
> >>
> >>  v3.3.0 - 16 Feb 2024
> >> diff --git a/ofproto/ofproto-dpif-lsample.c 
> >> b/ofproto/ofproto-dpif-lsample.c
> >> index 171129d5b..82a87c27d 100644
> >> --- a/ofproto/ofproto-dpif-lsample.c
> >> +++ b/ofproto/ofproto-dpif-lsample.c
> >> @@ -21,7 +21,10 @@
> >>  #include "dpif.h"
> >>  #include "hash.h"
> >>  #include "ofproto.h"
> >> +#include "ofproto-dpif.h"
> >> +#include "openvswitch/dynamic-string.h"
> >>  #include "openvswitch/thread.h"
> >> +#include "unixctl.h"
> >>
> >>  /* Dpif local sampling.
> >>   *
> >> @@ -219,3 +222,111 @@ dpif_lsample_unref(struct dpif_lsample *lsample)
> >>  dpif_lsample_destroy(lsample);
> >>  }
> >>  }
> >> +
> >> +static int
> >> +comp_exporter_collector_id(const void *a_, const void *b_)
> >> +{
> >> +const struct lsample_exporter_node *a, *b;
> >> +
> >> +a = *(struct lsample_exporter_node **) a_;
> >> +b = *(struct lsample_exporter_node **) b_;
> >> +
> >> +if (a->exporter.options.collector_set_id >
> >> +b->exporter.options.collector_set_id) {
> >> +return 1;
> >> +}
> >> +if (a->exporter.options.collector_set_id <
> >> +b->exporter.options.collector_set_id) {
> >> +return -1;
> >> +}
> >> +return 0;
> >> +}
> >> +
> >> +static void
> >> +lsample_exporter_list(struct dpif_lsample *lsample,
> >> +  struct lsample_exporter_node ***list,
> >> +  size_t *num_exporters)
> >> +{
> >> +struct lsample_exporter_node **exporter_list;
> >> +struct lsample_exporter_node *node;
> >> +size_t k = 0, n;
> >> +
> >> +n = cmap_count(>exporters);
> >> +
> >> +exporter_list = xcalloc(n, sizeof *exporter_list);
> >> +
> >> +CMAP_FOR_EACH (node, node, >exporters) {
> >> +if (k >= n) {
> >> +break;
> >> +}
> >> +exporter_list[k++] = node;
> >
> > There is no guarantee that cmap didn't change between getting the
> > number of exporters and iterating over them.  Need to either take
> > a lock or grow the array on demand.
>
> I initially thought the same, but it’s covered by the break above.
>
> Thinking about it again, we might actually not show entries that were 
> displayed before, due to a new one being earlier in the map. So I guess we 
> should probably grow the exporter_list (rather than hold the lock).
>

Right. If the map has grown since we took the size we will break before
iterating over all of them k will be equal to n we will break.
If the the map has shrinked, CMAP_FOR_EACH will finish.

AFAICS, in both cases it's safe to access the data (nodes will not be
freed until the next quiese period).

What can happen is that we don't show exactly what the current state of
the map is, e.g: we show a node that has just been deleted from the map
or we don't show a node that has just been added.

The only reason for having more than one exporter per bridge is if we
want to have multiple "observability applications" having differentt
group ids. In any case, I don't expect the number to be very high nor its
creation/deletion rate.

With all this, I considered that having sporadic slighly-inaccurate
displays was an asumable cost.

What do you think?


> >> +}
> >> +
> >> +qsort(exporter_list, k, sizeof *exporter_list, 
> >> comp_exporter_collector_id);
> >> +
> >> +*list = exporter_list;
> >> +*num_exporters = k;
> >> +}
> >> +
> >> +static void
> >> +lsample_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
> >> + const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
> >> +{
> >> +struct lsample_exporter_node **node_list = NULL;
> >> +struct ds ds = DS_EMPTY_INITIALIZER;
> >> +const struct ofproto_dpif *ofproto;
> >> +size_t i, num;
> >> +
> >> +ofproto = ofproto_dpif_lookup_by_name(argv[1]);
> >> +if (!ofproto) {
> >> +unixctl_command_reply_error(conn, "no such bridge");
> >> +  

Re: [ovs-dev] [PATCH v1 06/13] ofproto-dpif-xlate: Use psample for local sample.

2024-07-10 Thread Adrián Moreno
On Wed, Jul 10, 2024 at 02:56:44PM GMT, Ilya Maximets wrote:
> On 7/7/24 22:08, Adrian Moreno wrote:
> > Use the newly added psample action to implement OpenFlow sample() actions
> > with local sampling configuration if possible.
> >
> > A bit of refactoring in compose_sample_actions arguments helps make it a
> > bit more readable.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  ofproto/ofproto-dpif-lsample.c |  16 +++
> >  ofproto/ofproto-dpif-lsample.h |   5 +
> >  ofproto/ofproto-dpif-xlate.c   | 251 +++--
> >  ofproto/ofproto-dpif-xlate.h   |   5 +-
> >  ofproto/ofproto-dpif.c |   2 +-
> >  tests/ofproto-dpif.at  | 146 +++
> >  6 files changed, 345 insertions(+), 80 deletions(-)
> >
> > diff --git a/ofproto/ofproto-dpif-lsample.c b/ofproto/ofproto-dpif-lsample.c
> > index d675a116f..534ad96f0 100644
> > --- a/ofproto/ofproto-dpif-lsample.c
> > +++ b/ofproto/ofproto-dpif-lsample.c
> > @@ -140,6 +140,22 @@ dpif_lsample_set_options(struct dpif_lsample *lsample,
> >  return changed;
> >  }
> >
> > +/* Returns the group_id for a given collector_set_id, if it exists. */
> > +bool
> > +dpif_lsample_get_group_id(struct dpif_lsample *ps, uint32_t 
> > collector_set_id,
> > +  uint32_t *group_id)
> > +{
> > +struct lsample_exporter_node *node;
> > +bool found = false;
> > +
> > +node = dpif_lsample_find_exporter_node(ps, collector_set_id);
> > +if (node) {
> > +found = true;
> > +*group_id = node->exporter.options.group_id;
> > +}
> > +return found;
> > +}
> > +
> >  struct dpif_lsample *
> >  dpif_lsample_create(void)
> >  {
> > diff --git a/ofproto/ofproto-dpif-lsample.h b/ofproto/ofproto-dpif-lsample.h
> > index bee36c9c5..9c1026551 100644
> > --- a/ofproto/ofproto-dpif-lsample.h
> > +++ b/ofproto/ofproto-dpif-lsample.h
> > @@ -18,6 +18,7 @@
> >  #define OFPROTO_DPIF_LSAMPLE_H 1
> >
> >  #include 
> > +#include 
> >  #include 
> >
> >  struct dpif_lsample;
> > @@ -33,4 +34,8 @@ bool dpif_lsample_set_options(struct dpif_lsample *,
> >const struct ofproto_lsample_options *,
> >size_t n_opts);
> >
> > +bool dpif_lsample_get_group_id(struct dpif_lsample *,
> > +   uint32_t collector_set_id,
> > +   uint32_t *group_id);
> > +
> >  #endif /* OFPROTO_DPIF_LSAMPLE_H */
> > diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> > index 7c4950895..5e8113d5e 100644
> > --- a/ofproto/ofproto-dpif-xlate.c
> > +++ b/ofproto/ofproto-dpif-xlate.c
> > @@ -47,6 +47,7 @@
> >  #include "ofproto/ofproto-dpif-ipfix.h"
> >  #include "ofproto/ofproto-dpif-mirror.h"
> >  #include "ofproto/ofproto-dpif-monitor.h"
> > +#include "ofproto/ofproto-dpif-lsample.h"
> >  #include "ofproto/ofproto-dpif-sflow.h"
> >  #include "ofproto/ofproto-dpif-trace.h"
> >  #include "ofproto/ofproto-dpif-xlate-cache.h"
> > @@ -117,6 +118,7 @@ struct xbridge {
> >  struct dpif_sflow *sflow; /* SFlow handle, or null. */
> >  struct dpif_ipfix *ipfix; /* Ipfix handle, or null. */
> >  struct netflow *netflow;  /* Netflow handle, or null. */
> > +struct dpif_lsample *lsample; /* Local sample handle, or null. */
> >  struct stp *stp;  /* STP or null if disabled. */
> >  struct rstp *rstp;/* RSTP or null if disabled. */
> >
> > @@ -686,6 +688,7 @@ static void xlate_xbridge_set(struct xbridge *, struct 
> > dpif *,
> >const struct mbridge *,
> >const struct dpif_sflow *,
> >const struct dpif_ipfix *,
> > +  const struct dpif_lsample *,
> >const struct netflow *,
> >bool forward_bpdu, bool has_in_band,
> >const struct dpif_backer_support *,
> > @@ -1069,6 +1072,7 @@ xlate_xbridge_set(struct xbridge *xbridge,
> >const struct mbridge *mbridge,
> >const struct dpif_sflow *sflow,
> >const struct dpif_ipfix *ipfix,
> > +  const struct dpif_lsample *lsample,
> >const struct netflow *netflow,
> >bool forward_bpdu, bool has_in_band,
> >const struct dpif_backer_support *support,
> > @@ -1099,6 +1103,11 @@ xlate_xbridge_set(struct xbridge *xbridge,
> >  xbridge->ipfix = dpif_ipfix_ref(ipfix);
> >  }
> >
> > +if (xbridge->lsample != lsample) {
> > +dpif_lsample_unref(xbridge->lsample);
> > +xbridge->lsample = dpif_lsample_ref(lsample);
> > +}
> > +
> >  if (xbridge->stp != stp) {
> >  stp_unref(xbridge->stp);
> >  xbridge->stp = stp_ref(stp);
> > @@ -1213,9 +1222,10 @@ xlate_xbridge_copy(struct xbridge *xbridge)
> >  

Re: [ovs-dev] [PATCH v1 06/13] ofproto-dpif-xlate: Use psample for local sample.

2024-07-10 Thread Adrián Moreno
On Wed, Jul 10, 2024 at 02:18:35PM GMT, Ilya Maximets wrote:
> On 7/9/24 16:03, Eelco Chaudron wrote:
> >
> >
> > On 9 Jul 2024, at 15:52, Adrián Moreno wrote:
> >
> >> On Tue, Jul 09, 2024 at 11:45:51AM GMT, Eelco Chaudron wrote:
> >>> On 7 Jul 2024, at 22:08, Adrian Moreno wrote:
> >>>
> >>>> Use the newly added psample action to implement OpenFlow sample() actions
> >>>> with local sampling configuration if possible.
> >>>>
> >>>> A bit of refactoring in compose_sample_actions arguments helps make it a
> >>>> bit more readable.
> >>>
> >>> Some comments below.
> >>>
> >>> Cheers,
> >>>
> >>> Eelco
> >>>
> >>>> Signed-off-by: Adrian Moreno 
> >>>> ---
> >>>>  ofproto/ofproto-dpif-lsample.c |  16 +++
> >>>>  ofproto/ofproto-dpif-lsample.h |   5 +
> >>>>  ofproto/ofproto-dpif-xlate.c   | 251 +++--
> >>>>  ofproto/ofproto-dpif-xlate.h   |   5 +-
> >>>>  ofproto/ofproto-dpif.c |   2 +-
> >>>>  tests/ofproto-dpif.at  | 146 +++
> >>>>  6 files changed, 345 insertions(+), 80 deletions(-)
> >>>>
> >>>> diff --git a/ofproto/ofproto-dpif-lsample.c 
> >>>> b/ofproto/ofproto-dpif-lsample.c
> >>>> index d675a116f..534ad96f0 100644
> >>>> --- a/ofproto/ofproto-dpif-lsample.c
> >>>> +++ b/ofproto/ofproto-dpif-lsample.c
> >>>> @@ -140,6 +140,22 @@ dpif_lsample_set_options(struct dpif_lsample 
> >>>> *lsample,
> >>>>  return changed;
> >>>>  }
> >>>>
> >>>> +/* Returns the group_id for a given collector_set_id, if it exists. */
> >>>> +bool
> >>>> +dpif_lsample_get_group_id(struct dpif_lsample *ps, uint32_t 
> >>>> collector_set_id,
> >>>> +  uint32_t *group_id)
> >>>> +{
> >>>> +struct lsample_exporter_node *node;
> >>>> +bool found = false;
> >>>> +
> >>>> +node = dpif_lsample_find_exporter_node(ps, collector_set_id);
> >>>> +if (node) {
> >>>> +found = true;
> >>>> +*group_id = node->exporter.options.group_id;
> >>>> +}
> >>>> +return found;
> >>>> +}
> >>>> +
> >>>>  struct dpif_lsample *
> >>>>  dpif_lsample_create(void)
> >>>>  {
> >>>> diff --git a/ofproto/ofproto-dpif-lsample.h 
> >>>> b/ofproto/ofproto-dpif-lsample.h
> >>>> index bee36c9c5..9c1026551 100644
> >>>> --- a/ofproto/ofproto-dpif-lsample.h
> >>>> +++ b/ofproto/ofproto-dpif-lsample.h
> >>>> @@ -18,6 +18,7 @@
> >>>>  #define OFPROTO_DPIF_LSAMPLE_H 1
> >>>>
> >>>>  #include 
> >>>> +#include 
> >>>>  #include 
> >>>>
> >>>>  struct dpif_lsample;
> >>>> @@ -33,4 +34,8 @@ bool dpif_lsample_set_options(struct dpif_lsample *,
> >>>>const struct ofproto_lsample_options *,
> >>>>size_t n_opts);
> >>>>
> >>>> +bool dpif_lsample_get_group_id(struct dpif_lsample *,
> >>>> +   uint32_t collector_set_id,
> >>>> +   uint32_t *group_id);
> >>>> +
> >>>>  #endif /* OFPROTO_DPIF_LSAMPLE_H */
> >>>> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> >>>> index 7c4950895..5e8113d5e 100644
> >>>> --- a/ofproto/ofproto-dpif-xlate.c
> >>>> +++ b/ofproto/ofproto-dpif-xlate.c
> >>>> @@ -47,6 +47,7 @@
> >>>>  #include "ofproto/ofproto-dpif-ipfix.h"
> >>>>  #include "ofproto/ofproto-dpif-mirror.h"
> >>>>  #include "ofproto/ofproto-dpif-monitor.h"
> >>>> +#include "ofproto/ofproto-dpif-lsample.h"
> >>>
> >>> Add in alphabetical order?
> >>
> >> Ack.
> >>
> >>>
> >>>>  #include "ofproto/ofproto-dpif-sflow.h"
> >>>>  #include "ofproto/ofproto-dpif-trace.h"
> >>>>  #include "ofproto

Re: [ovs-dev] [PATCH v1 03/13] ofproto_dpif: Check for psample support.

2024-07-10 Thread Adrián Moreno
On Wed, Jul 10, 2024 at 01:28:29PM GMT, Ilya Maximets wrote:
> On 7/7/24 22:08, Adrian Moreno wrote:
> > Only kernel datapath supports this action so add a function in dpif.c
> > that checks for that.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  lib/dpif.c |  7 +++
> >  lib/dpif.h |  1 +
> >  ofproto/ofproto-dpif.c | 43 ++
> >  ofproto/ofproto-dpif.h |  7 ++-
> >  4 files changed, 57 insertions(+), 1 deletion(-)
> >
> > diff --git a/lib/dpif.c b/lib/dpif.c
> > index 71728badc..0a964ba89 100644
> > --- a/lib/dpif.c
> > +++ b/lib/dpif.c
> > @@ -1953,6 +1953,13 @@ dpif_supports_lb_output_action(const struct dpif 
> > *dpif)
> >  return dpif_is_netdev(dpif);
> >  }
> >
> > +bool
> > +dpif_may_support_psample(const struct dpif *dpif)
> > +{
> > +/* Userspace datapath does not support this action. */
> > +return !dpif_is_netdev(dpif);
> > +}
> > +
> >  /* Meters */
> >  void
> >  dpif_meter_get_features(const struct dpif *dpif,
> > diff --git a/lib/dpif.h b/lib/dpif.h
> > index a764e8a59..6bef7d5b3 100644
> > --- a/lib/dpif.h
> > +++ b/lib/dpif.h
> > @@ -941,6 +941,7 @@ int dpif_get_pmds_for_port(const struct dpif * dpif, 
> > odp_port_t port_no,
> >  char *dpif_get_dp_version(const struct dpif *);
> >  bool dpif_supports_tnl_push_pop(const struct dpif *);
> >  bool dpif_may_support_explicit_drop_action(const struct dpif *);
> > +bool dpif_may_support_psample(const struct dpif *);
> >  bool dpif_synced_dp_layers(struct dpif *);
> >
> >  /* Log functions. */
> > diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> > index 4712d10a8..94c84d697 100644
> > --- a/ofproto/ofproto-dpif.c
> > +++ b/ofproto/ofproto-dpif.c
> > @@ -873,6 +873,12 @@ ovs_lb_output_action_supported(struct ofproto_dpif 
> > *ofproto)
> >  return ofproto->backer->rt_support.lb_output_action;
> >  }
> >
> > +bool
> > +ovs_psample_supported(struct ofproto_dpif *ofproto)
> > +{
> > +return ofproto->backer->rt_support.psample;
> > +}
> > +
> >  /* Tests whether 'backer''s datapath supports recirculation.  Only newer
> >   * datapaths support OVS_KEY_ATTR_RECIRC_ID in keys.  We need to disable 
> > some
> >   * features on older datapaths that don't support this feature.
> > @@ -1609,6 +1615,42 @@ check_add_mpls(struct dpif_backer *backer)
> >  return supported;
> >  }
> >
> > +/* Tests whether 'backer''s datapath supports the OVS_ACTION_ATTR_PSAMPLE
> > + * action. */
> > +static bool
> > +check_psample(struct dpif_backer *backer)
> > +{
> > +uint8_t cookie[OVS_PSAMPLE_COOKIE_MAX_SIZE];
> > +struct odputil_keybuf keybuf;
> > +struct ofpbuf actions;
> > +struct ofpbuf key;
> > +struct flow flow;
> > +bool supported;
> > +
> > +struct odp_flow_key_parms odp_parms = {
> > +.flow = ,
> > +.probe = true,
> > +};
> > +
> > +memset(, 0, sizeof flow);
> > +ofpbuf_use_stack(, , sizeof keybuf);
> > +odp_flow_key_from_flow(_parms, );
> > +ofpbuf_init(, 64);
> > +
> > +/* Generate a random max-size cookie. */
> > +random_bytes(cookie, sizeof(cookie));
>
> Don't parenthesize the argument of sizeof.
>

Ack.

> > +
> > +odp_put_psample_action(, 10, cookie, sizeof cookie);
> > +
> > +supported = dpif_may_support_psample(backer->dpif) &&
> > +dpif_probe_feature(backer->dpif, "psample", , , NULL);
>
> This function actually installs the flow into the kernel.
> You need to make sure that no packet can match it, e.g.
> by setting a bogus eth type as a match.  Some existing
> probe functions require specific matches, some are just
> missing this part as well, but we should not blindly copy
> bad patterns.
>

I guess I was always thinking on a freshly started system but you're
right! If OVS is restarted, the installed flow can affect actual
traffic. I'll add a bogus key to make sure it's not problematic.

> > +
> > +ofpbuf_uninit();
> > +VLOG_INFO("%s: Datapath %s psample", dpif_name(backer->dpif),
>
> '%s: Datapath %s psample action'  will be more clear.
>

Ack.

> > +  supported ? "supports" : "does not support");
> > +return supported;
> > +}
> > +
> >  #define CHECK_FEATURE__(NAME, SUPPORT, FIELD, VALUE, ETHTYPE)  
> >  \
> >  static bool
> >  \
> >  check_##NAME(struct dpif_backer *backer)   
> >  \
> > @@ -1698,6 +1740,7 @@ check_support(struct dpif_backer *backer)
> >  dpif_supports_lb_output_action(backer->dpif);
> >  backer->rt_support.ct_zero_snat = dpif_supports_ct_zero_snat(backer);
> >  backer->rt_support.add_mpls = check_add_mpls(backer);
> > +backer->rt_support.psample = check_psample(backer);
> >
> >  /* Flow fields. */
> >  backer->rt_support.odp.ct_state = check_ct_state(backer);
> > diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h
> > index d33f73df8..bc7a19dab 100644
> > --- 

Re: [ovs-dev] [PATCH v1 02/13] odp-util: Add support OVS_ACTION_ATTR_PSAMPLE.

2024-07-10 Thread Adrián Moreno
On Wed, Jul 10, 2024 at 12:56:57PM GMT, Ilya Maximets wrote:
> On 7/7/24 22:08, Adrian Moreno wrote:
> > Add support for parsing and formatting the new action.
> >
> > Also, flag OVS_ACTION_ATTR_SAMPLE as requiring datapath assistance if it
> > contains a nested OVS_ACTION_ATTR_PSAMPLE. The reason is that the
> > sampling rate form the parent "sample" is made available to the nested
> > "psample" by the kernel.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  include/linux/openvswitch.h  | 28 +++
> >  lib/dpif-netdev.c|  1 +
> >  lib/dpif.c   |  1 +
> >  lib/odp-execute.c| 25 +-
> >  lib/odp-util.c   | 93 
> >  lib/odp-util.h   |  3 ++
> >  ofproto/ofproto-dpif-ipfix.c |  1 +
> >  ofproto/ofproto-dpif-sflow.c |  1 +
> >  python/ovs/flow/odp.py   |  8 
> >  tests/odp.at | 16 +++
> >  10 files changed, 176 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
> > index d9fb991ef..0023b65fb 100644
> > --- a/include/linux/openvswitch.h
> > +++ b/include/linux/openvswitch.h
> > @@ -992,6 +992,31 @@ struct check_pkt_len_arg {
> >  };
> >  #endif
> >
> > +#define OVS_PSAMPLE_COOKIE_MAX_SIZE 16
> > +/**
> > + * enum ovs_pample_attr - Attributes for %OVS_ACTION_ATTR_PSAMPLE
> > + * action.
> > + *
> > + * @OVS_PSAMPLE_ATTR_GROUP: 32-bit number to identify the source of the
> > + * sample.
> > + * @OVS_PSAMPLE_ATTR_COOKIE: An optional variable-length binary cookie that
> > + * contains user-defined metadata. The maximum length is
> > + * OVS_PSAMPLE_COOKIE_MAX_SIZE bytes.
> > + *
> > + * Sends the packet to the psample multicast group with the specified 
> > group and
> > + * cookie. It is possible to combine this action with the
> > + * %OVS_ACTION_ATTR_TRUNC action to limit the size of the sample.
> > + */
> > +enum ovs_psample_attr {
> > +OVS_PSAMPLE_ATTR_GROUP = 1,/* u32 number. */
> > +OVS_PSAMPLE_ATTR_COOKIE,   /* Optional, user specified cookie. 
> > */
> > +
> > +/* private: */
> > +__OVS_PSAMPLE_ATTR_MAX
> > +};
> > +
> > +#define OVS_PSAMPLE_ATTR_MAX (__OVS_PSAMPLE_ATTR_MAX - 1)
> > +
> >  /**
> >   * enum ovs_action_attr - Action types.
> >   *
> > @@ -1056,6 +1081,8 @@ struct check_pkt_len_arg {
> >   * of l3 tunnel flag in the tun_flags field of OVS_ACTION_ATTR_ADD_MPLS
> >   * argument.
> >   * @OVS_ACTION_ATTR_DROP: Explicit drop action.
> > + * @OVS_ACTION_ATTR_PSAMPLE: Send a sample of the packet to external 
> > observers
> > + * via psample.
> >   */
> >
> >  enum ovs_action_attr {
> > @@ -1087,6 +1114,7 @@ enum ovs_action_attr {
> > OVS_ACTION_ATTR_ADD_MPLS, /* struct ovs_action_add_mpls. */
> > OVS_ACTION_ATTR_DEC_TTL,  /* Nested OVS_DEC_TTL_ATTR_*. */
> > OVS_ACTION_ATTR_DROP, /* u32 xlate_error. */
> > +   OVS_ACTION_ATTR_PSAMPLE,  /* Nested OVS_PSAMPLE_ATTR_*. */
> >
> >  #ifndef __KERNEL__
> > OVS_ACTION_ATTR_TUNNEL_PUSH,   /* struct ovs_action_push_tnl*/
> > diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
> > index c7f9e1490..f0594e5f5 100644
> > --- a/lib/dpif-netdev.c
> > +++ b/lib/dpif-netdev.c
> > @@ -9519,6 +9519,7 @@ dp_execute_cb(void *aux_, struct dp_packet_batch 
> > *packets_,
> >  case OVS_ACTION_ATTR_DROP:
> >  case OVS_ACTION_ATTR_ADD_MPLS:
> >  case OVS_ACTION_ATTR_DEC_TTL:
> > +case OVS_ACTION_ATTR_PSAMPLE:
> >  case __OVS_ACTION_ATTR_MAX:
> >  OVS_NOT_REACHED();
> >  }
> > diff --git a/lib/dpif.c b/lib/dpif.c
> > index 23eb18495..71728badc 100644
> > --- a/lib/dpif.c
> > +++ b/lib/dpif.c
> > @@ -1192,6 +1192,7 @@ dpif_execute_helper_cb(void *aux_, struct 
> > dp_packet_batch *packets_,
> >  case OVS_ACTION_ATTR_TUNNEL_PUSH:
> >  case OVS_ACTION_ATTR_TUNNEL_POP:
> >  case OVS_ACTION_ATTR_USERSPACE:
> > +case OVS_ACTION_ATTR_PSAMPLE:
> >  case OVS_ACTION_ATTR_RECIRC: {
> >  struct dpif_execute execute;
> >  struct ofpbuf execute_actions;
> > diff --git a/lib/odp-execute.c b/lib/odp-execute.c
> > index 081e4d432..15577d539 100644
> > --- a/lib/odp-execute.c
> > +++ b/lib/odp-execute.c
> > @@ -818,13 +818,13 @@ requires_datapath_assistance(const struct nlattr *a)
> >  case OVS_ACTION_ATTR_RECIRC:
> >  case OVS_ACTION_ATTR_CT:
> >  case OVS_ACTION_ATTR_METER:
> > +case OVS_ACTION_ATTR_PSAMPLE:
> >  return true;
> >
> >  case OVS_ACTION_ATTR_SET:
> >  case OVS_ACTION_ATTR_SET_MASKED:
> >  case OVS_ACTION_ATTR_PUSH_VLAN:
> >  case OVS_ACTION_ATTR_POP_VLAN:
> > -case OVS_ACTION_ATTR_SAMPLE:
> >  case OVS_ACTION_ATTR_HASH:
> >  case OVS_ACTION_ATTR_PUSH_MPLS:
> >  case OVS_ACTION_ATTR_POP_MPLS:
> > @@ -841,6 +841,28 @@ requires_datapath_assistance(const struct nlattr *a)
> >  case OVS_ACTION_ATTR_DROP:
> >  return false;
> >
> > +case OVS_ACTION_ATTR_SAMPLE: {
> > +   

Re: [ovs-dev] [PATCH v1 02/13] odp-util: Add support OVS_ACTION_ATTR_PSAMPLE.

2024-07-10 Thread Adrián Moreno
On Wed, Jul 10, 2024 at 01:01:03AM GMT, Ilya Maximets wrote:
> On 7/9/24 21:07, Adrián Moreno wrote:
> > On Tue, Jul 09, 2024 at 04:15:12PM GMT, Eelco Chaudron wrote:
> >>
> >>
> >> On 9 Jul 2024, at 15:30, Adrián Moreno wrote:
> >>
> >>> On Tue, Jul 09, 2024 at 11:45:15AM GMT, Eelco Chaudron wrote:
> >>>> On 4 Jul 2024, at 9:52, Adrian Moreno wrote:
> >>>>
> >>>>> Add support for parsing and formatting the new action.
> >>>>>
> >>>>> Also, flag OVS_ACTION_ATTR_SAMPLE as requiring datapath assistance if it
> >>>>> contains a nested OVS_ACTION_ATTR_PSAMPLE. The reason is that the
> >>>>> sampling rate form the parent "sample" is made available to the nested
> >>>>
> >>>> form -> from
> >>>>
> >>>>> "psample" by the kernel.
> >>>>
> >>>> Two small comments below, the rest looks good.
> >>>>
> >>>>> Signed-off-by: Adrian Moreno 
> >>>>> ---
> >>>>>  include/linux/openvswitch.h  | 28 +++
> >>>>>  lib/dpif-netdev.c|  1 +
> >>>>>  lib/dpif.c   |  1 +
> >>>>>  lib/odp-execute.c| 25 +-
> >>>>>  lib/odp-util.c   | 93 
> >>>>>  lib/odp-util.h   |  3 ++
> >>>>>  ofproto/ofproto-dpif-ipfix.c |  1 +
> >>>>>  ofproto/ofproto-dpif-sflow.c |  1 +
> >>>>>  python/ovs/flow/odp.py   |  8 
> >>>>>  tests/odp.at | 16 +++
> >>>>>  10 files changed, 176 insertions(+), 1 deletion(-)
> >>>>>
> >>>>> diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
> >>>>> index d9fb991ef..0023b65fb 100644
> >>>>> --- a/include/linux/openvswitch.h
> >>>>> +++ b/include/linux/openvswitch.h
> >>>>> @@ -992,6 +992,31 @@ struct check_pkt_len_arg {
> >>>>>  };
> >>>>>  #endif
> >>>>>
> >>>>> +#define OVS_PSAMPLE_COOKIE_MAX_SIZE 16
> >>>>> +/**
> >>>>> + * enum ovs_pample_attr - Attributes for %OVS_ACTION_ATTR_PSAMPLE
> >>>>> + * action.
> >>>>> + *
> >>>>> + * @OVS_PSAMPLE_ATTR_GROUP: 32-bit number to identify the source of the
> >>>>> + * sample.
> >>>>> + * @OVS_PSAMPLE_ATTR_COOKIE: An optional variable-length binary cookie 
> >>>>> that
> >>>>> + * contains user-defined metadata. The maximum length is
> >>>>> + * OVS_PSAMPLE_COOKIE_MAX_SIZE bytes.
> >>>>> + *
> >>>>> + * Sends the packet to the psample multicast group with the specified 
> >>>>> group and
> >>>>> + * cookie. It is possible to combine this action with the
> >>>>> + * %OVS_ACTION_ATTR_TRUNC action to limit the size of the sample.
> >>>>> + */
> >>>>> +enum ovs_psample_attr {
> >>>>> +OVS_PSAMPLE_ATTR_GROUP = 1,/* u32 number. */
> >>>>> +OVS_PSAMPLE_ATTR_COOKIE,   /* Optional, user specified 
> >>>>> cookie. */
> >>>>> +
> >>>>> +/* private: */
> >>>>
> >>>> None of the other definitions have this private marking, so I see no 
> >>>> need to
> >>>> start adding it here.
> >>>
> >>> OK. The uAPI file has it (requested by netdev maintainers) but I guess
> >>> it's kernel-specific and this file is not a blind copy of the uAPI
> >>> anyways so I think we can remove it. I'll do on the next version.
>
> I'd keep it.  There is no point in having this header different from
> the kernel one in places where it doesn't surve any purpose.
>
> >>>
> >>>>
> >>>>> +__OVS_PSAMPLE_ATTR_MAX
> >>>>> +};
> >>>>> +
> >>>>> +#define OVS_PSAMPLE_ATTR_MAX (__OVS_PSAMPLE_ATTR_MAX - 1)
> >>>>> +
> >>>>>  /**
> >>>>>   * enum ovs_action_attr - Action types.
> >>>>>   *
> >>>>> @@ -1056,6 +1081,8 @@ struct check_pkt_len_arg {
> >>>>>   * of l3 tunnel flag in the tun_flags field o

Re: [ovs-dev] [PATCH v1 01/13] ofproto-dpif: Allow forcing dp features.

2024-07-09 Thread Adrián Moreno
On Wed, Jul 10, 2024 at 12:13:37AM GMT, Ilya Maximets wrote:
> On 7/7/24 22:08, Adrian Moreno wrote:
> > Datapath features can be set with dpif/set-dp-features unixctl command.
> > This command is not docummented and therefore not supported in
> > production but only useful for unit tests.
> >
> > A limitation was put in place originally to avoid enabling features at
> > runtime that were disabled at boot time to avoid breaking the datapath
> > in unexpected ways.
> >
> > But, considering users should not use this command and it should only be
> > used for testing, we can assume whoever runs it knows what they are
> > doing. Therefore, the limitation should be bypass-able.
> >
> > This patch adds a "--force" flag to the unixctl command to allow
> > bypassing the mentioned limitation.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  ofproto/ofproto-dpif.c | 37 +++--
> >  1 file changed, 27 insertions(+), 10 deletions(-)
> >
> > diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> > index fcd7cd753..4712d10a8 100644
> > --- a/ofproto/ofproto-dpif.c
> > +++ b/ofproto/ofproto-dpif.c
> > @@ -6432,7 +6432,8 @@ display_support_field(const char *name,
> >  static bool
> >  dpif_set_support(struct dpif_backer_support *rt_support,
> >   struct dpif_backer_support *bt_support,
> > - const char *name, const char *value, struct ds *ds)
> > + const char *name, const char *value, bool force,
> > + struct ds *ds)
> >  {
> >  struct shash all_fields = SHASH_INITIALIZER(_fields);
> >  struct dpif_support_field *field;
> > @@ -6484,8 +6485,8 @@ dpif_set_support(struct dpif_backer_support 
> > *rt_support,
> >
> >  if (field->type == DPIF_SUPPORT_FIELD_bool) {
> >  if (!strcasecmp(value, "true")) {
> > -if (*(bool *)field->bt_ptr) {
> > -*(bool *)field->rt_ptr = true;
> > +if (*(bool *) field->bt_ptr || force) {
> > +*(bool *) field->rt_ptr = true;
>
> We discussed having a scary warning message for the force option.
> I don't see it here.
>

You're right. I forgot. Thanks.

> >  changed = true;
> >  } else {
> >  ds_put_cstr(ds, "Can not enable features not supported by 
> > the datapth");
> > @@ -6720,21 +6721,36 @@ ofproto_unixctl_dpif_set_dp_features(struct 
> > unixctl_conn *conn,
> >   void *aux OVS_UNUSED)
> >  {
> >  struct ds ds = DS_EMPTY_INITIALIZER;
> > -const char *br = argv[1];
> > +struct ofproto_dpif *ofproto;
> > +bool changed, force = false;
> >  const char *name, *value;
> > -struct ofproto_dpif *ofproto = ofproto_dpif_lookup_by_name(br);
> > -bool changed;
> > +const char *br = NULL;
> > +
> > +if (!strcmp(argv[1], "--force")) {
> > +force = true;
> > +if (argc > 2) {
> > +br = argv[2];
> > +name = argc > 3 ? argv[3] : NULL;
> > +value = argc > 4 ? argv[4] : NULL;
> > +} else {
> > +unixctl_command_reply_error(conn, "bridge not specified");
> > +return;
> > +}
> > +} else {
> > +br = argv[1];
> > +name = argc > 2 ? argv[2] : NULL;
> > +value = argc > 3 ? argv[3] : NULL;
> > +}
>
> It feels like this can be cleaner if we just eat the --force,
> argv++, argc-- and continue the processing instead of doing
> the same thing with diferent indexes in different branches.
>

Thanks for the suggestion. It does seem to yield cleaner code.

> >
> > +ofproto = ofproto_dpif_lookup_by_name(br);
> >  if (!ofproto) {
> >  unixctl_command_reply_error(conn, "no such bridge");
> >  return;
> >  }
> >
> > -name = argc > 2 ? argv[2] : NULL;
> > -value = argc > 3 ? argv[3] : NULL;
> >  changed = dpif_set_support(>backer->rt_support,
> > >backer->bt_support,
> > -   name, value, );
> > +   name, value, force, );
> >  if (changed) {
> >  xlate_set_support(ofproto, >backer->rt_support);
> >  udpif_flush(ofproto->backer->udpif);
> > @@ -6777,7 +6793,8 @@ ofproto_unixctl_init(void)
> >  unixctl_command_register("dpif/dump-flows",
> >   "[-m] [--names | --no-names] bridge", 1, 
> > INT_MAX,
> >   ofproto_unixctl_dpif_dump_flows, NULL);
> > -unixctl_command_register("dpif/set-dp-features", "bridge", 1, 3 ,
> > +unixctl_command_register("dpif/set-dp-features",
> > + "[--force] bridge [feature] [value]", 1, 4 ,
>
> There is an extra space after '4'.  It was there before, but it's
> a good time to remove it.
>
> Also, [feature [value]] .

Ack.

>
> >   ofproto_unixctl_dpif_set_dp_features, NULL);
> >  }
> >  
>


Re: [ovs-dev] [PATCH v1 12/13] ofproto: xlate: Make bridge-sampled drops explicit.

2024-07-09 Thread Adrián Moreno
On Tue, Jul 09, 2024 at 11:46:09AM GMT, Eelco Chaudron wrote:
> On 7 Jul 2024, at 22:09, Adrian Moreno wrote:
>
> > The decision to add or not the explicit drop action is currently based
> > on whether the resulting dp action list is empty or not.
> >
> > This is OK for most of the cases but if per-flow IPFIX/sFlow sampling
> > is enabled on the bridge, it doesn't work as expected.
> >
> > Fix this by taking into account the size of these sampling actions.
>
> Same comments as on the previous patch.
>
> > Fixes: a13a0209750c ("userspace: Improved packet drop statistics.")
> > Cc: anju.tho...@ericsson.com
> > Signed-off-by: Adrian Moreno 
> > ---
> >  ofproto/ofproto-dpif-xlate.c |  5 ++--
> >  tests/drop-stats.at  | 44 
> >  tests/ofproto-dpif.at|  4 ++--
> >  3 files changed, 49 insertions(+), 4 deletions(-)
> >
> > diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> > index 094fe5d72..323a58cbf 100644
> > --- a/ofproto/ofproto-dpif-xlate.c
> > +++ b/ofproto/ofproto-dpif-xlate.c
> > @@ -8153,6 +8153,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out 
> > *xout)
> >  uint64_t action_set_stub[1024 / 8];
> >  uint64_t frozen_actions_stub[1024 / 8];
> >  uint64_t actions_stub[256 / 8];
> > +size_t sample_actions_len = 0;
> >  struct ofpbuf scratch_actions = OFPBUF_STUB_INITIALIZER(actions_stub);
> >  struct xlate_ctx ctx = {
> >  .xin = xin,
> > @@ -8412,7 +8413,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out 
> > *xout)
> >  user_cookie_offset = compose_sflow_action();
> >  compose_ipfix_action(, ODPP_NONE);
> >  }
> > -size_t sample_actions_len = ctx.odp_actions->size;
> > +sample_actions_len = ctx.odp_actions->size;
> >  bool ecn_drop = !tnl_process_ecn(flow);
> >
> >  if (!ecn_drop
> > @@ -8575,7 +8576,7 @@ exit:
> >  }
> >
> >  /* Install drop action if datapath supports explicit drop action. */
> > -if (xin->odp_actions && !xin->odp_actions->size &&
> > +if (xin->odp_actions && xin->odp_actions->size == sample_actions_len &&
> >  ovs_explicit_drop_action_supported(ctx.xbridge->ofproto)) {
> >  put_drop_action(xin->odp_actions, ctx.error);
>
> See other patch, do we need ctx.error here?

Here we *do* need it.

This is where it was originally placed to flag xlate errors. We are at
the end of xlate_actions main function and the one place where we have
gathered ctx.error.

The change here is not to modify how the drop is added to the action
list. What this change does is change the condition upon which it's
added. Before we were checking if the action list was empty under the
assumption that if do_xlate_actions does not fill in any action, it's a
drop.

However, if per-bridge IPFIX (or sFlow) is enabled, their corresponding
actions are added _before_ calling do_xlate_actions. That's why this
patch only makes the check compare the size of the actions with the one
it had before calling do_xlate_actions.

Calling do_xlate_actions can yield errors and we should definitely flag
them.

>
> >  }
> > diff --git a/tests/drop-stats.at b/tests/drop-stats.at
> > index 44c5cc35b..31782ac52 100644
> > --- a/tests/drop-stats.at
> > +++ b/tests/drop-stats.at
> > @@ -192,6 +192,50 @@ ovs-appctl coverage/read-counter 
> > drop_action_too_many_mpls_labels
> >  OVS_VSWITCHD_STOP(["/|WARN|/d"])
> >  AT_CLEANUP
> >
> > +AT_SETUP([drop-stats - sampling])
>
> Should this maybe be 'bridge sampling'?
>

Ack.

> > +
> > +OVS_VSWITCHD_START([dnl
> > +set bridge br0 datapath_type=dummy \
> > +protocols=OpenFlow10,OpenFlow13,OpenFlow14,OpenFlow15 -- \
> > +add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1])
> > +
> > +AT_DATA([flows.txt], [dnl
> > +table=0,in_port=1,actions=drop
> > +])
> > +
> > +AT_CHECK([
> > +ovs-ofctl del-flows br0
> > +ovs-ofctl -Oopenflow13 add-flows br0 flows.txt
> > +ovs-ofctl -Oopenflow13 dump-flows br0 | ofctl_strip | sort | grep 
> > actions ], [0], [dnl
> > + in_port=1 actions=drop
> > +])
> > +
> > +AT_CHECK([ovs-vsctl -- set bridge br0 ipfix=@fix -- \
> > +--id=@fix create ipfix targets=\"127.0.0.1:4739\" \
> > +  sampling=1],
> > + [0], [ignore])
> > +
> > +AT_CHECK([
> > +ovs-appctl netdev-dummy/receive p1 
> > 'in_port(1),packet_type(ns=0,id=0),eth(src=3a:6d:d2:09:9c:ab,dst=1e:2c:e9:2a:66:9e),ipv4(src=192.168.10.10,dst=192.168.10.30,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'
> > +ovs-appctl netdev-dummy/receive p1 
> > 'in_port(1),packet_type(ns=0,id=0),eth(src=3a:6d:d2:09:9c:ab,dst=1e:2c:e9:2a:66:9e),ipv4(src=192.168.10.10,dst=192.168.10.30,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'
> > +ovs-appctl netdev-dummy/receive p1 
> > 

Re: [ovs-dev] [PATCH v1 02/13] odp-util: Add support OVS_ACTION_ATTR_PSAMPLE.

2024-07-09 Thread Adrián Moreno
On Tue, Jul 09, 2024 at 04:15:12PM GMT, Eelco Chaudron wrote:
>
>
> On 9 Jul 2024, at 15:30, Adrián Moreno wrote:
>
> > On Tue, Jul 09, 2024 at 11:45:15AM GMT, Eelco Chaudron wrote:
> >> On 4 Jul 2024, at 9:52, Adrian Moreno wrote:
> >>
> >>> Add support for parsing and formatting the new action.
> >>>
> >>> Also, flag OVS_ACTION_ATTR_SAMPLE as requiring datapath assistance if it
> >>> contains a nested OVS_ACTION_ATTR_PSAMPLE. The reason is that the
> >>> sampling rate form the parent "sample" is made available to the nested
> >>
> >> form -> from
> >>
> >>> "psample" by the kernel.
> >>
> >> Two small comments below, the rest looks good.
> >>
> >>> Signed-off-by: Adrian Moreno 
> >>> ---
> >>>  include/linux/openvswitch.h  | 28 +++
> >>>  lib/dpif-netdev.c|  1 +
> >>>  lib/dpif.c   |  1 +
> >>>  lib/odp-execute.c| 25 +-
> >>>  lib/odp-util.c   | 93 
> >>>  lib/odp-util.h   |  3 ++
> >>>  ofproto/ofproto-dpif-ipfix.c |  1 +
> >>>  ofproto/ofproto-dpif-sflow.c |  1 +
> >>>  python/ovs/flow/odp.py   |  8 
> >>>  tests/odp.at | 16 +++
> >>>  10 files changed, 176 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
> >>> index d9fb991ef..0023b65fb 100644
> >>> --- a/include/linux/openvswitch.h
> >>> +++ b/include/linux/openvswitch.h
> >>> @@ -992,6 +992,31 @@ struct check_pkt_len_arg {
> >>>  };
> >>>  #endif
> >>>
> >>> +#define OVS_PSAMPLE_COOKIE_MAX_SIZE 16
> >>> +/**
> >>> + * enum ovs_pample_attr - Attributes for %OVS_ACTION_ATTR_PSAMPLE
> >>> + * action.
> >>> + *
> >>> + * @OVS_PSAMPLE_ATTR_GROUP: 32-bit number to identify the source of the
> >>> + * sample.
> >>> + * @OVS_PSAMPLE_ATTR_COOKIE: An optional variable-length binary cookie 
> >>> that
> >>> + * contains user-defined metadata. The maximum length is
> >>> + * OVS_PSAMPLE_COOKIE_MAX_SIZE bytes.
> >>> + *
> >>> + * Sends the packet to the psample multicast group with the specified 
> >>> group and
> >>> + * cookie. It is possible to combine this action with the
> >>> + * %OVS_ACTION_ATTR_TRUNC action to limit the size of the sample.
> >>> + */
> >>> +enum ovs_psample_attr {
> >>> +OVS_PSAMPLE_ATTR_GROUP = 1,/* u32 number. */
> >>> +OVS_PSAMPLE_ATTR_COOKIE,   /* Optional, user specified 
> >>> cookie. */
> >>> +
> >>> +/* private: */
> >>
> >> None of the other definitions have this private marking, so I see no need 
> >> to
> >> start adding it here.
> >
> > OK. The uAPI file has it (requested by netdev maintainers) but I guess
> > it's kernel-specific and this file is not a blind copy of the uAPI
> > anyways so I think we can remove it. I'll do on the next version.
> >
> >>
> >>> +__OVS_PSAMPLE_ATTR_MAX
> >>> +};
> >>> +
> >>> +#define OVS_PSAMPLE_ATTR_MAX (__OVS_PSAMPLE_ATTR_MAX - 1)
> >>> +
> >>>  /**
> >>>   * enum ovs_action_attr - Action types.
> >>>   *
> >>> @@ -1056,6 +1081,8 @@ struct check_pkt_len_arg {
> >>>   * of l3 tunnel flag in the tun_flags field of OVS_ACTION_ATTR_ADD_MPLS
> >>>   * argument.
> >>>   * @OVS_ACTION_ATTR_DROP: Explicit drop action.
> >>> + * @OVS_ACTION_ATTR_PSAMPLE: Send a sample of the packet to external 
> >>> observers
> >>> + * via psample.
> >>>   */
> >>>
> >>>  enum ovs_action_attr {
> >>> @@ -1087,6 +1114,7 @@ enum ovs_action_attr {
> >>>   OVS_ACTION_ATTR_ADD_MPLS, /* struct ovs_action_add_mpls. */
> >>>   OVS_ACTION_ATTR_DEC_TTL,  /* Nested OVS_DEC_TTL_ATTR_*. */
> >>>   OVS_ACTION_ATTR_DROP, /* u32 xlate_error. */
> >>> + OVS_ACTION_ATTR_PSAMPLE,  /* Nested OVS_PSAMPLE_ATTR_*. */
> >>>
> >>>  #ifndef __KERNEL__
> >>>   OVS_ACTION_ATTR_TUNNEL_PUSH,   /* struct ovs_action_push_tnl*/
> >>> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c

Re: [ovs-dev] [PATCH v1 11/13] ofproto: xlate: Make flow-sampled drops explicit.

2024-07-09 Thread Adrián Moreno
On Tue, Jul 09, 2024 at 04:22:04PM GMT, Eelco Chaudron wrote:
>
>
> On 9 Jul 2024, at 16:00, Adrián Moreno wrote:
>
> > On Tue, Jul 09, 2024 at 11:46:06AM GMT, Eelco Chaudron wrote:
> >> On 7 Jul 2024, at 22:09, Adrian Moreno wrote:
> >>
> >>> When an action set ends in a an OFP_SAMPLE action, it means the packet
> >>> will be dropped and sampled. Make the drop explicit in this case so that
> >>> drop statistics remain accurate.
> >>>
> >>> This could be done outside of the sample action, i.e: "sample(...),drop"
> >>> but datapaths optimize sample actions that are found in the last
> >>> position. So, taking into account that datapaths already report when the
> >>> last sample probability fails, it is safe to put the drop inside the
> >>> sample, i.e: "sample(...,drop)".
> >>
> >> Some style comments below, as this was discussed with Ilya, I let him 
> >> comment
> >> on the feature side.
> >>
> >>> Signed-off-by: Adrian Moreno 
> >>> ---
> >>>  ofproto/ofproto-dpif-xlate.c | 16 +++--
> >>>  tests/drop-stats.at  | 65 
> >>>  tests/ofproto-dpif.at| 44 
> >>>  3 files changed, 123 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> >>> index b9546dc5b..094fe5d72 100644
> >>> --- a/ofproto/ofproto-dpif-xlate.c
> >>> +++ b/ofproto/ofproto-dpif-xlate.c
> >>> @@ -715,6 +715,7 @@ static void xlate_xbundle_copy(struct xbridge *, 
> >>> struct xbundle *);
> >>>  static void xlate_xport_copy(struct xbridge *, struct xbundle *,
> >>>   struct xport *);
> >>>  static void xlate_xcfg_free(struct xlate_cfg *);
> >>> +static void put_drop_action(struct ofpbuf *, enum xlate_error);
> >>>  
> >>>  /* Tracing helpers. */
> >>>
> >>> @@ -3392,6 +3393,8 @@ struct sample_userspace_args {
> >>>  struct compose_sample_args {
> >>>  uint32_t probability; /* Number of packets out of
> >>> * UINT32_MAX to sample. */
> >>> +bool last;/* If it's the last action 
> >>> and a
> >>> +   * drop action must be 
> >>> added. */
> >>
> >> Should describing this means this is the last action not be enough?
> >> Maybe also rename it to be last_action, so it's more clear what this means.
> >>
> >
> > Sure "last_action" is pretty much self-explanatory.
> >
> >>>  struct sample_userspace_args *userspace;  /* Optional,
> >>> * arguments for 
> >>> userspace. */
> >>>  struct sample_psample_args *psample;  /* Optional,
> >>> @@ -3456,6 +3459,11 @@ compose_sample_action(struct xlate_ctx *ctx,
> >>>  ovs_assert(res == 0);
> >>>  }
> >>>
> >>> +if (args->last &&
> >>> +ovs_explicit_drop_action_supported(ctx->xbridge->ofproto)) {
> >>> +put_drop_action(ctx->odp_actions, ctx->error);
> >>
> >> Any reason why we use ctx->error here? Should we just not use XLATE_OK?
> >>
> >
> > I was trying to thing in a case where ctx->error would not be XLATE_OK
> > but I couldn't. Nevertheless I thought if there is such case, we should
> > definitely report the right error code, right?
>
> Well, in case of an error all actions are deleted, and only an explicit drop 
> (or no) actions are added.
>
> For the sample() action, the drop reason should always be ok, or else the 
> action should not be there. So I would prefer to make this clear by using 
> XLATE_OK.

OK. I'll change that.

>
> >>> +}
> >>> +
> >>>  if (is_sample) {
> >>>  nl_msg_end_nested(ctx->odp_actions, actions_offset);
> >>>  nl_msg_end_nested(ctx->odp_actions, sample_offset);
> >>> @@ -3490,6 +3498,7 @@ compose_sflow_action(struct xlate_ctx *ctx)
> >>>
> >>>  args.probability = dpif_sflow_get_probability(sflow);
> >>>  args.userspace = 
> >>> +args.last = false;
> >>>

Re: [ovs-dev] [PATCH v1 13/13] ofp-actions: Load data from fields in sample action.

2024-07-09 Thread Adrián Moreno
On Tue, Jul 09, 2024 at 11:46:12AM GMT, Eelco Chaudron wrote:
> On 7 Jul 2024, at 22:09, Adrian Moreno wrote:
>
> > When sample action gets used as a way of sampling traffic with
> > controller-generated metadata (i.e: obs_domain_id and obs_point_id),
> > the controller will have to increase the number of flows to ensure each
> > part of the pipeline contains the right metadata.
> >
> > As an example, if the controller decides to sample stateful traffic, it
> > could store the computed metadata for each connection in the conntrack
> > label. However, for established connections, a flow must be created for
> > each different ct_label value with a sample action that contains a
> > different hardcoded obs_domain and obs_point id.
> >
> > This patch adds a new version of the NXAST_RAW_SAMPLE* action (number 4)
> > that supports specifying the observation point and domain using an
> > OpenFlow field reference, so now the controller can express:
> >
> >  sample(...
> > obs_domain_id=NXM_NX_CT_LABEL[0..31],
> > obs_point_id=NXM_NX_CT_LABEL[32..63]
> > ...
> >)
> >
> > Signed-off-by: Adrian Moreno 
>
> See some comments inline. I’m missing the documentation update.
>

Yes. I noticed I missed both the NEWS and documentation update.

> Cheers,
>
> Eelco
>
> > ---
> >  include/openvswitch/ofp-actions.h |   8 +-
> >  lib/ofp-actions.c | 249 +++---
> >  ofproto/ofproto-dpif-xlate.c  |  55 ++-
> >  python/ovs/flow/ofp.py|   8 +-
> >  python/ovs/flow/ofp_act.py|   4 +-
> >  tests/ofp-actions.at  |   5 +
> >  tests/ofproto-dpif.at |  41 +
> >  tests/system-traffic.at   |  74 +
> >  8 files changed, 405 insertions(+), 39 deletions(-)
> >
> > diff --git a/include/openvswitch/ofp-actions.h 
> > b/include/openvswitch/ofp-actions.h
> > index 7b57e49ad..56dc2c147 100644
> > --- a/include/openvswitch/ofp-actions.h
> > +++ b/include/openvswitch/ofp-actions.h
> > @@ -1015,14 +1015,16 @@ enum nx_action_sample_direction {
> >
> >  /* OFPACT_SAMPLE.
> >   *
> > - * Used for NXAST_SAMPLE, NXAST_SAMPLE2, and NXAST_SAMPLE3. */
> > + * Used for NXAST_SAMPLE, NXAST_SAMPLE2, NXAST_SAMPLE3 and NXAST_SAMPLE4. 
> > */
> >  struct ofpact_sample {
> >  OFPACT_PADDED_MEMBERS(
> >  struct ofpact ofpact;
> >  uint16_t probability;   /* Always positive. */
> >  uint32_t collector_set_id;
> > -uint32_t obs_domain_id;
> > -uint32_t obs_point_id;
> > +uint32_t obs_domain_imm;
> > +struct mf_subfield obs_domain_src;
> > +uint32_t obs_point_imm;
> > +struct mf_subfield obs_point_src;
> >  ofp_port_t sampling_port;
> >  enum nx_action_sample_direction direction;
> >  );
> > diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
> > index da7b1dd31..e329a7e3f 100644
> > --- a/lib/ofp-actions.c
> > +++ b/lib/ofp-actions.c
> > @@ -330,6 +330,8 @@ enum ofp_raw_action_type {
> >  NXAST_RAW_SAMPLE2,
> >  /* NX1.0+(41): struct nx_action_sample2. */
> >  NXAST_RAW_SAMPLE3,
> > +/* NX1.0+(51): struct nx_action_sample4, ... VLMFF */
> > +NXAST_RAW_SAMPLE4,
> >
> >  /* NX1.0+(34): struct nx_action_conjunction. */
> >  NXAST_RAW_CONJUNCTION,
> > @@ -6188,6 +6190,34 @@ struct nx_action_sample2 {
> >   };
> >   OFP_ASSERT(sizeof(struct nx_action_sample2) == 32);
> >
> > +/* Action structure for NXAST_SAMPLE4
> > + *
> > + * NXAST_SAMPLE4 was added in Open vSwitch 3.4.0.  Compared to 
> > NXAST_SAMPLE3,
> > + * it adds support for using field specifiers for observation_domain_id and
> > + * observation_point_id. */
> > +struct nx_action_sample4 {
> > +ovs_be16 type;  /* OFPAT_VENDOR. */
> > +ovs_be16 len;   /* Length is 32. */
> > +ovs_be32 vendor;/* NX_VENDOR_ID. */
> > +ovs_be16 subtype;   /* NXAST_SAMPLE. */
> > +ovs_be16 probability;   /* Fraction of packets to sample. */
> > +ovs_be32 collector_set_id;  /* ID of collector set in OVSDB. */
> > +ovs_be32 obs_domain_src;/* Source of the 
> > observation_domain_id. */
> > +union {
> > +ovs_be16 obs_domain_ofs_nbits;  /* Range to use from source field. 
> > */
> > +ovs_be32 obs_domain_imm;/* Immediate value for domain id. 
> > */
> > +};
> > +ovs_be32 obs_point_src; /* Source of the observation_point_id 
> > */
> > +union {
> > +ovs_be16 obs_point_ofs_nbits;  /* Range to use from source field. 
> > */
> > +ovs_be32 obs_point_imm;/* Immediate value for point id. */
> > +};
> > +ovs_be16 sampling_port; /* Sampling port. */
> > +uint8_t  direction; /* Sampling direction. */
> > +uint8_t  zeros[5];  /* Pad to a multiple of 8 bytes */
> > + };
>
> Maybe align all comments, and make sure all end with a dot.
>
> struct nx_action_sample4 {
>   

Re: [ovs-dev] [PATCH v1 11/13] ofproto: xlate: Make flow-sampled drops explicit.

2024-07-09 Thread Adrián Moreno
On Tue, Jul 09, 2024 at 11:46:06AM GMT, Eelco Chaudron wrote:
> On 7 Jul 2024, at 22:09, Adrian Moreno wrote:
>
> > When an action set ends in a an OFP_SAMPLE action, it means the packet
> > will be dropped and sampled. Make the drop explicit in this case so that
> > drop statistics remain accurate.
> >
> > This could be done outside of the sample action, i.e: "sample(...),drop"
> > but datapaths optimize sample actions that are found in the last
> > position. So, taking into account that datapaths already report when the
> > last sample probability fails, it is safe to put the drop inside the
> > sample, i.e: "sample(...,drop)".
>
> Some style comments below, as this was discussed with Ilya, I let him comment
> on the feature side.
>
> > Signed-off-by: Adrian Moreno 
> > ---
> >  ofproto/ofproto-dpif-xlate.c | 16 +++--
> >  tests/drop-stats.at  | 65 
> >  tests/ofproto-dpif.at| 44 
> >  3 files changed, 123 insertions(+), 2 deletions(-)
> >
> > diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> > index b9546dc5b..094fe5d72 100644
> > --- a/ofproto/ofproto-dpif-xlate.c
> > +++ b/ofproto/ofproto-dpif-xlate.c
> > @@ -715,6 +715,7 @@ static void xlate_xbundle_copy(struct xbridge *, struct 
> > xbundle *);
> >  static void xlate_xport_copy(struct xbridge *, struct xbundle *,
> >   struct xport *);
> >  static void xlate_xcfg_free(struct xlate_cfg *);
> > +static void put_drop_action(struct ofpbuf *, enum xlate_error);
> >  
> >  /* Tracing helpers. */
> >
> > @@ -3392,6 +3393,8 @@ struct sample_userspace_args {
> >  struct compose_sample_args {
> >  uint32_t probability; /* Number of packets out of
> > * UINT32_MAX to sample. */
> > +bool last;/* If it's the last action 
> > and a
> > +   * drop action must be 
> > added. */
>
> Should describing this means this is the last action not be enough?
> Maybe also rename it to be last_action, so it's more clear what this means.
>

Sure "last_action" is pretty much self-explanatory.

> >  struct sample_userspace_args *userspace;  /* Optional,
> > * arguments for userspace. 
> > */
> >  struct sample_psample_args *psample;  /* Optional,
> > @@ -3456,6 +3459,11 @@ compose_sample_action(struct xlate_ctx *ctx,
> >  ovs_assert(res == 0);
> >  }
> >
> > +if (args->last &&
> > +ovs_explicit_drop_action_supported(ctx->xbridge->ofproto)) {
> > +put_drop_action(ctx->odp_actions, ctx->error);
>
> Any reason why we use ctx->error here? Should we just not use XLATE_OK?
>

I was trying to thing in a case where ctx->error would not be XLATE_OK
but I couldn't. Nevertheless I thought if there is such case, we should
definitely report the right error code, right?

> > +}
> > +
> >  if (is_sample) {
> >  nl_msg_end_nested(ctx->odp_actions, actions_offset);
> >  nl_msg_end_nested(ctx->odp_actions, sample_offset);
> > @@ -3490,6 +3498,7 @@ compose_sflow_action(struct xlate_ctx *ctx)
> >
> >  args.probability = dpif_sflow_get_probability(sflow);
> >  args.userspace = 
> > +args.last = false;
> >
> >  return compose_sample_action(ctx, );
> >  }
> > @@ -3542,6 +3551,7 @@ compose_ipfix_action(struct xlate_ctx *ctx, 
> > odp_port_t output_odp_port)
> >
> >  args.probability = dpif_ipfix_get_bridge_exporter_probability(ipfix);
> >  args.userspace = 
> > +args.last = false;
> >
> >  compose_sample_action(ctx, );
> >  }
> > @@ -5974,7 +5984,8 @@ xlate_fill_ipfix_sample(struct xlate_ctx *ctx,
> >
> >  static void
> >  xlate_sample_action(struct xlate_ctx *ctx,
> > -const struct ofpact_sample *os)
> > +const struct ofpact_sample *os,
> > +bool last)
> >  {
> >  uint8_t cookie_buf[sizeof(os->obs_domain_id) + 
> > sizeof(os->obs_point_id)];
> >  struct dpif_lsample *lsample = ctx->xbridge->lsample;
> > @@ -5991,6 +6002,7 @@ xlate_sample_action(struct xlate_ctx *ctx,
> >   * the same percentage. */
> >  compose_args.probability =
> >  ((uint32_t) os->probability << 16) | os->probability;
> > +compose_args.last = last;
> >
> >  if (ipfix) {
> >  xlate_fill_ipfix_sample(ctx, os, ipfix, );
> > @@ -7726,7 +7738,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t 
> > ofpacts_len,
> >  break;
> >
> >  case OFPACT_SAMPLE:
> > -xlate_sample_action(ctx, ofpact_get_SAMPLE(a));
> > +xlate_sample_action(ctx, ofpact_get_SAMPLE(a), last);
> >  break;
> >
> >  case OFPACT_CLONE:
> > diff --git a/tests/drop-stats.at b/tests/drop-stats.at
> > index 1d3af98da..44c5cc35b 100644
> > --- a/tests/drop-stats.at
> > +++ 

Re: [ovs-dev] [PATCH v1 10/13] tests: Test local sampling.

2024-07-09 Thread Adrián Moreno
On Tue, Jul 09, 2024 at 11:46:03AM GMT, Eelco Chaudron wrote:
> On 7 Jul 2024, at 22:09, Adrian Moreno wrote:
>
> > Test simultaneous IPFIX and local sampling including slow-path.
>
> See comments below.
>
> Cheers,
>
> Eelco
>
> > Signed-off-by: Adrian Moreno 
> > ---
> >  tests/system-common-macros.at |   4 +
> >  tests/system-traffic.at   | 285 ++
> >  2 files changed, 289 insertions(+)
> >
> > diff --git a/tests/system-common-macros.at b/tests/system-common-macros.at
> > index 2a68cd664..860d6a8c9 100644
> > --- a/tests/system-common-macros.at
> > +++ b/tests/system-common-macros.at
> > @@ -378,3 +378,7 @@ m4_define([OVS_CHECK_GITHUB_ACTION],
> >  # OVS_CHECK_DROP_ACTION()
> >  m4_define([OVS_CHECK_DROP_ACTION],
> >  [AT_SKIP_IF([! grep -q "Datapath supports explicit drop action" 
> > ovs-vswitchd.log])])
> > +
> > +# OVS_CHECK_PSAMPLE()
> > +m4_define([OVS_CHECK_PSAMPLE],
> > +[AT_SKIP_IF([! grep -q "Datapath supports psample" ovs-vswitchd.log])])
> > diff --git a/tests/system-traffic.at b/tests/system-traffic.at
> > index 3f1a15445..ddab4ece3 100644
> > --- a/tests/system-traffic.at
> > +++ b/tests/system-traffic.at
> > @@ -9103,3 +9103,288 @@ OVS_WAIT_UNTIL([ovs-pcap p2.pcap | grep -q 
> > "m4_join([], [^],
> >
> >  OVS_TRAFFIC_VSWITCHD_STOP
> >  AT_CLEANUP
> > +
> > +AT_BANNER([local-sampling])
> > +
> > +m4_define([SAMPLE_ACTION],
> > +
> > [sample(probability=65535,collector_set_id=$1,obs_domain_id=$2,obs_point_id=$3)]dnl
> > +)
> > +
> > +AT_SETUP([psample - sanity check])
>
> Maybe call it '- ipv4' as it's equal to ipv6, or rename the IPv6 one to
> 'sanity check IPv6'

Ack.

>
> > +OVS_TRAFFIC_VSWITCHD_START()
> > +OVS_CHECK_PSAMPLE()
> > +
> > +ADD_NAMESPACES(at_ns0, at_ns1)
> > +
> > +ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
> > +ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
> > +
> > +AT_CHECK([ovs-vsctl -- --id=@br0 get Bridge br0 \
> > +-- create Flow_Sample_Collector_Set id=1 bridge=@br0 
> > local_group_id=10 \
> > +-- create Flow_Sample_Collector_Set id=2 bridge=@br0 
> > local_group_id=12],
> > + [0], [ignore])
>
> Maybe wrap to stay <80 chars?
>
> AT_CHECK([ovs-vsctl -- --id=@br0 get Bridge br0 \
> -- create Flow_Sample_Collector_Set id=1 bridge=@br0 \
>local_group_id=10 \
> -- create Flow_Sample_Collector_Set id=2 bridge=@br0 \
>local_group_id=12],
>  [0], [ignore])
>

Ack.

> > +
> > +AT_DATA([flows.txt], [dnl
> > +arp actions=NORMAL
> > +in_port=ovs-p0,ip actions=SAMPLE_ACTION(1, 2853183536, 2856341600),ovs-p1
> > +in_port=ovs-p1,ip actions=SAMPLE_ACTION(2, 3138396208, 3141554272),ovs-p0
> > +])
> > +
> > +AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
> > +
> > +OVS_DAEMONIZE([ovstest test-psample > psample.out], [psample.pid])
> > +OVS_WAIT_UNTIL([grep -q "Listening for psample events" psample.out])
> > +
> > +NS_CHECK_EXEC([at_ns0], [ping -q -c 1 10.1.1.2 | FORMAT_PING], [0], [dnl
> > +1 packets transmitted, 1 received, 0% packet loss, time 0ms
> > +])
> > +
> > +AT_CHECK([ovs-appctl dpctl/dump-flows -m --names], [0], [stdout])
> > +AT_CHECK([grep -q 
> > 'actions:psample(group=10,cookie=0xaa102030aa405060),ovs-p1' stdout])
> > +AT_CHECK([grep -q 
> > 'actions:psample(group=12,cookie=0xbb102030bb405060),ovs-p0' stdout])
> > +
> > +m4_define([SAMPLE1], [m4_join([ ],
> > +[group_id=0xa],
> > +[obs_domain=0xaa102030,obs_point=0xaa405060],
> > +[.*icmp.*nw_src=10.1.1.1,nw_dst=10.1.1.2])])
> > +
> > +m4_define([SAMPLE2], [m4_join([ ],
> > +[group_id=0xc],
> > +[obs_domain=0xbb102030,obs_point=0xbb405060],
> > +[.*icmp.*nw_src=10.1.1.2,nw_dst=10.1.1.1])])
> > +
> > +OVS_WAIT_UNTIL([grep -qE 'SAMPLE1' psample.out])
> > +OVS_WAIT_UNTIL([grep -qE 'SAMPLE2' psample.out])
> > +
> > +AT_CHECK([ovs-appctl lsample/show br0], [0], [dnl
> > +Local sample statistics for bridge "br0":
> > +Collector Set ID: 1:
> > +  Group ID : 10
> > +  Total packets: 1
> > +  Total bytes  : 98
> > +
> > +Collector Set ID: 2:
> > +  Group ID : 12
> > +  Total packets: 1
> > +  Total bytes  : 98
> > +])
> > +
>
> We miss OVS_TRAFFIC_VSWITCHD_STOP() here.
>

Yes!

> > +AT_CLEANUP
> > +
> > +AT_SETUP([psample - ipv6])
>
> See comment above, if you decide to keep it ipv6, please change it to IPv6.
>
> > +OVS_TRAFFIC_VSWITCHD_START()
> > +OVS_CHECK_PSAMPLE()
> > +
> > +ADD_NAMESPACES(at_ns0, at_ns1)
> > +
> > +ADD_VETH(p0, at_ns0, br0, "fc00::1/96")
> > +ADD_VETH(p1, at_ns1, br0, "fc00::2/96")
> > +
> > +AT_CHECK([ovs-vsctl -- --id=@br0 get Bridge br0 \
> > +-- create Flow_Sample_Collector_Set id=1 bridge=@br0 
> > local_group_id=10 \
> > +-- create Flow_Sample_Collector_Set id=2 bridge=@br0 
> > local_group_id=12],
> > + [0], [ignore])
> > +
> > +AT_DATA([flows.txt], [dnl
> > +priority=100,in_port=ovs-p0,ip6,icmp6,icmpv6_type=128 
> > 

Re: [ovs-dev] [PATCH v1 08/13] ofproto-dpif-lsample: Show stats via unixctl.

2024-07-09 Thread Adrián Moreno
On Tue, Jul 09, 2024 at 11:45:58AM GMT, Eelco Chaudron wrote:
> On 7 Jul 2024, at 22:09, Adrian Moreno wrote:
>
> > Add a command to dump statistics per exporter.
>
> Small nit below, rest looks good to me. If this is the only change in the
> next series you can add my ACK.
>
> //Eelco
>
> > Signed-off-by: Adrian Moreno 
> > ---
> >  NEWS   |   2 +
> >  ofproto/ofproto-dpif-lsample.c | 111 +
> >  ofproto/ofproto-dpif-lsample.h |   1 +
> >  ofproto/ofproto-dpif.c |   1 +
> >  4 files changed, 115 insertions(+)
> >
> > diff --git a/NEWS b/NEWS
> > index 15faf9fc3..1c53badea 100644
> > --- a/NEWS
> > +++ b/NEWS
> > @@ -20,6 +20,8 @@ Post-v3.3.0
> >   allows samples to be emitted locally (instead of via IPFIX) in a
> >   datapath-specific manner. The Linux kernel datapath is the first to
> >   support this feature by using the new datapath "psample" action.
> > + A new unixctl command 'lsample/show' shows packet and bytes statistics
> > + per local sample exporter.
> >
> >
> >  v3.3.0 - 16 Feb 2024
> > diff --git a/ofproto/ofproto-dpif-lsample.c b/ofproto/ofproto-dpif-lsample.c
> > index 171129d5b..82a87c27d 100644
> > --- a/ofproto/ofproto-dpif-lsample.c
> > +++ b/ofproto/ofproto-dpif-lsample.c
> > @@ -21,7 +21,10 @@
> >  #include "dpif.h"
> >  #include "hash.h"
> >  #include "ofproto.h"
> > +#include "ofproto-dpif.h"
> > +#include "openvswitch/dynamic-string.h"
> >  #include "openvswitch/thread.h"
> > +#include "unixctl.h"
> >
> >  /* Dpif local sampling.
> >   *
> > @@ -219,3 +222,111 @@ dpif_lsample_unref(struct dpif_lsample *lsample)
> >  dpif_lsample_destroy(lsample);
> >  }
> >  }
> > +
> > +static int
> > +comp_exporter_collector_id(const void *a_, const void *b_)
> > +{
> > +const struct lsample_exporter_node *a, *b;
> > +
> > +a = *(struct lsample_exporter_node **) a_;
> > +b = *(struct lsample_exporter_node **) b_;
> > +
> > +if (a->exporter.options.collector_set_id >
> > +b->exporter.options.collector_set_id) {
> > +return 1;
> > +}
> > +if (a->exporter.options.collector_set_id <
> > +b->exporter.options.collector_set_id) {
> > +return -1;
> > +}
> > +return 0;
> > +}
> > +
> > +static void
> > +lsample_exporter_list(struct dpif_lsample *lsample,
> > +  struct lsample_exporter_node ***list,
> > +  size_t *num_exporters)
> > +{
> > +struct lsample_exporter_node **exporter_list;
> > +struct lsample_exporter_node *node;
> > +size_t k = 0, n;
> > +
> > +n = cmap_count(>exporters);
> > +
> > +exporter_list = xcalloc(n, sizeof *exporter_list);
> > +
> > +CMAP_FOR_EACH (node, node, >exporters) {
> > +if (k >= n) {
> > +break;
> > +}
> > +exporter_list[k++] = node;
> > +}
> > +
> > +qsort(exporter_list, k, sizeof *exporter_list, 
> > comp_exporter_collector_id);
> > +
> > +*list = exporter_list;
> > +*num_exporters = k;
> > +}
> > +
> > +static void
> > +lsample_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
> > + const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
> > +{
> > +struct lsample_exporter_node **node_list = NULL;
> > +struct ds ds = DS_EMPTY_INITIALIZER;
> > +const struct ofproto_dpif *ofproto;
> > +size_t i, num;
> > +
> > +ofproto = ofproto_dpif_lookup_by_name(argv[1]);
> > +if (!ofproto) {
> > +unixctl_command_reply_error(conn, "no such bridge");
> > +return;
> > +}
> > +
> > +if (!ofproto->lsample) {
> > +unixctl_command_reply_error(conn,
> > +"no local sampling exporters 
> > configured");
> > +return;
> > +}
> > +
> > +ds_put_format(, "Local sample statistics for bridge \"%s\":\n",
> > +  argv[1]);
> > +
> > +lsample_exporter_list(ofproto->lsample, _list, );
> > +
> > +for (i = 0; i < num; i++) {
> > +uint64_t n_bytes;
> > +uint64_t n_packets;
> > +
> > +struct lsample_exporter_node *node = node_list[i];
> > +
> > +atomic_read_relaxed(>exporter.n_packets, _packets);
> > +atomic_read_relaxed(>exporter.n_bytes, _bytes);
> > +
> > +if (i) {
> > +ds_put_cstr(, "\n");
> > +}
> > +
> > +ds_put_format(, "Collector Set ID: %"PRIu32":\n",
> > +node->exporter.options.collector_set_id);
> > +ds_put_format(, "  Group ID : %"PRIu32"\n",
> > +node->exporter.options.group_id);
> > +ds_put_format(, "  Total packets: %"PRIu64"\n", n_packets);
> > +ds_put_format(, "  Total bytes  : %"PRIu64"\n", n_bytes);
> > +}
> > +
> > +free(node_list);
> > +unixctl_command_reply(conn, ds_cstr());
> > +ds_destroy();
> > +}
> > +
> > +void dpif_lsample_init(void)
> > +{
> > +static struct ovsthread_once once = 

Re: [ovs-dev] [PATCH v1 07/13] ofproto-dpif-xlate-cache: Add lsample to xcache.

2024-07-09 Thread Adrián Moreno
On Tue, Jul 09, 2024 at 11:45:54AM GMT, Eelco Chaudron wrote:
> On 7 Jul 2024, at 22:08, Adrian Moreno wrote:
>
> > Add a cache entry type for local sample objects.
> > Store both the dpif_lsample reference and the collector_set_id so we can
> > quickly find the particular exporter.
> >
> > Using this mechanism, account for packet and byte statistics.
>
> Small nit below, rest looks good to me. If this is the only change in the
> next series you can add my ACK.
>
> //Eelco
>
> > Signed-off-by: Adrian Moreno 
> > ---
> >  ofproto/ofproto-dpif-lsample.c | 18 ++
> >  ofproto/ofproto-dpif-lsample.h |  4 
> >  ofproto/ofproto-dpif-xlate-cache.c | 11 ++-
> >  ofproto/ofproto-dpif-xlate-cache.h |  6 ++
> >  ofproto/ofproto-dpif-xlate.c   | 14 ++
> >  ofproto/ofproto-dpif.c |  1 +
> >  6 files changed, 53 insertions(+), 1 deletion(-)
> >
> > diff --git a/ofproto/ofproto-dpif-lsample.c b/ofproto/ofproto-dpif-lsample.c
> > index 534ad96f0..171129d5b 100644
> > --- a/ofproto/ofproto-dpif-lsample.c
> > +++ b/ofproto/ofproto-dpif-lsample.c
> > @@ -18,6 +18,7 @@
> >  #include "ofproto-dpif-lsample.h"
> >
> >  #include "cmap.h"
> > +#include "dpif.h"
> >  #include "hash.h"
> >  #include "ofproto.h"
> >  #include "openvswitch/thread.h"
> > @@ -44,6 +45,8 @@ struct dpif_lsample {
> >
> >  struct lsample_exporter {
> >  struct ofproto_lsample_options options;
> > +atomic_uint64_t n_packets;
> > +atomic_uint64_t n_bytes;
> >  };
> >
> >  struct lsample_exporter_node {
> > @@ -156,6 +159,21 @@ dpif_lsample_get_group_id(struct dpif_lsample *ps, 
> > uint32_t collector_set_id,
> >  return found;
> >  }
> >
> > +void
> > +dpif_lsample_credit_stats(struct dpif_lsample *lsample,
> > +  uint32_t collector_set_id,
> > +  const struct dpif_flow_stats *stats)
> > +{
> > +struct lsample_exporter_node *node;
> > +uint64_t orig;
> > +
> > +node = dpif_lsample_find_exporter_node(lsample, collector_set_id);
> > +if (node) {
> > +atomic_add_relaxed(>exporter.n_packets, stats->n_packets, 
> > );
> > +atomic_add_relaxed(>exporter.n_bytes, stats->n_bytes, );
> > +}
> > +}
> > +
> >  struct dpif_lsample *
> >  dpif_lsample_create(void)
> >  {
> > diff --git a/ofproto/ofproto-dpif-lsample.h b/ofproto/ofproto-dpif-lsample.h
> > index 9c1026551..2666e5478 100644
> > --- a/ofproto/ofproto-dpif-lsample.h
> > +++ b/ofproto/ofproto-dpif-lsample.h
> > @@ -23,6 +23,7 @@
> >
> >  struct dpif_lsample;
> >  struct ofproto_lsample_options;
> > +struct dpif_flow_stats;
> >
> >  struct dpif_lsample *dpif_lsample_create(void);
> >
> > @@ -38,4 +39,7 @@ bool dpif_lsample_get_group_id(struct dpif_lsample *,
> > uint32_t collector_set_id,
> > uint32_t *group_id);
> >
> > +void dpif_lsample_credit_stats(struct dpif_lsample *,
> > +   uint32_t collector_set_id,
> > +   const struct dpif_flow_stats *);
> >  #endif /* OFPROTO_DPIF_LSAMPLE_H */
> > diff --git a/ofproto/ofproto-dpif-xlate-cache.c 
> > b/ofproto/ofproto-dpif-xlate-cache.c
> > index 2e1fcb3a6..73d79bfc7 100644
> > --- a/ofproto/ofproto-dpif-xlate-cache.c
> > +++ b/ofproto/ofproto-dpif-xlate-cache.c
> > @@ -35,9 +35,10 @@
> >  #include "learn.h"
> >  #include "mac-learning.h"
> >  #include "netdev-vport.h"
> > +#include "ofproto/ofproto-dpif.h"
> > +#include "ofproto/ofproto-dpif-lsample.h"
> >  #include "ofproto/ofproto-dpif-mirror.h"
> >  #include "ofproto/ofproto-dpif-xlate.h"
> > -#include "ofproto/ofproto-dpif.h"
> >  #include "ofproto/ofproto-provider.h"
> >  #include "openvswitch/dynamic-string.h"
> >  #include "openvswitch/vlog.h"
> > @@ -162,6 +163,11 @@ xlate_push_stats_entry(struct xc_entry *entry,
> >  }
> >
> >  break;
> > +case XC_LSAMPLE:
> > +dpif_lsample_credit_stats(entry->lsample.lsample,
> > +  entry->lsample.collector_set_id,
> > +  stats);
> > +break;
> >  default:
> >  OVS_NOT_REACHED();
> >  }
> > @@ -245,6 +251,9 @@ xlate_cache_clear_entry(struct xc_entry *entry)
> >  break;
> >  case XC_TUNNEL_HEADER:
> >  break;
> > +case XC_LSAMPLE:
> > +dpif_lsample_unref(entry->lsample.lsample);
> > +break;
> >  default:
> >  OVS_NOT_REACHED();
> >  }
> > diff --git a/ofproto/ofproto-dpif-xlate-cache.h 
> > b/ofproto/ofproto-dpif-xlate-cache.h
> > index 0fc6d2ea6..df8115419 100644
> > --- a/ofproto/ofproto-dpif-xlate-cache.h
> > +++ b/ofproto/ofproto-dpif-xlate-cache.h
> > @@ -29,6 +29,7 @@
> >  struct bfd;
> >  struct bond;
> >  struct dpif_flow_stats;
> > +struct dpif_lsample;
> >  struct flow;
> >  struct group_dpif;
> >  struct mbridge;
> > @@ -53,6 +54,7 @@ enum xc_type {
> >  XC_GROUP,
> >  XC_TNL_NEIGH,
> >  

Re: [ovs-dev] [PATCH v1 06/13] ofproto-dpif-xlate: Use psample for local sample.

2024-07-09 Thread Adrián Moreno
On Tue, Jul 09, 2024 at 11:45:51AM GMT, Eelco Chaudron wrote:
> On 7 Jul 2024, at 22:08, Adrian Moreno wrote:
>
> > Use the newly added psample action to implement OpenFlow sample() actions
> > with local sampling configuration if possible.
> >
> > A bit of refactoring in compose_sample_actions arguments helps make it a
> > bit more readable.
>
> Some comments below.
>
> Cheers,
>
> Eelco
>
> > Signed-off-by: Adrian Moreno 
> > ---
> >  ofproto/ofproto-dpif-lsample.c |  16 +++
> >  ofproto/ofproto-dpif-lsample.h |   5 +
> >  ofproto/ofproto-dpif-xlate.c   | 251 +++--
> >  ofproto/ofproto-dpif-xlate.h   |   5 +-
> >  ofproto/ofproto-dpif.c |   2 +-
> >  tests/ofproto-dpif.at  | 146 +++
> >  6 files changed, 345 insertions(+), 80 deletions(-)
> >
> > diff --git a/ofproto/ofproto-dpif-lsample.c b/ofproto/ofproto-dpif-lsample.c
> > index d675a116f..534ad96f0 100644
> > --- a/ofproto/ofproto-dpif-lsample.c
> > +++ b/ofproto/ofproto-dpif-lsample.c
> > @@ -140,6 +140,22 @@ dpif_lsample_set_options(struct dpif_lsample *lsample,
> >  return changed;
> >  }
> >
> > +/* Returns the group_id for a given collector_set_id, if it exists. */
> > +bool
> > +dpif_lsample_get_group_id(struct dpif_lsample *ps, uint32_t 
> > collector_set_id,
> > +  uint32_t *group_id)
> > +{
> > +struct lsample_exporter_node *node;
> > +bool found = false;
> > +
> > +node = dpif_lsample_find_exporter_node(ps, collector_set_id);
> > +if (node) {
> > +found = true;
> > +*group_id = node->exporter.options.group_id;
> > +}
> > +return found;
> > +}
> > +
> >  struct dpif_lsample *
> >  dpif_lsample_create(void)
> >  {
> > diff --git a/ofproto/ofproto-dpif-lsample.h b/ofproto/ofproto-dpif-lsample.h
> > index bee36c9c5..9c1026551 100644
> > --- a/ofproto/ofproto-dpif-lsample.h
> > +++ b/ofproto/ofproto-dpif-lsample.h
> > @@ -18,6 +18,7 @@
> >  #define OFPROTO_DPIF_LSAMPLE_H 1
> >
> >  #include 
> > +#include 
> >  #include 
> >
> >  struct dpif_lsample;
> > @@ -33,4 +34,8 @@ bool dpif_lsample_set_options(struct dpif_lsample *,
> >const struct ofproto_lsample_options *,
> >size_t n_opts);
> >
> > +bool dpif_lsample_get_group_id(struct dpif_lsample *,
> > +   uint32_t collector_set_id,
> > +   uint32_t *group_id);
> > +
> >  #endif /* OFPROTO_DPIF_LSAMPLE_H */
> > diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> > index 7c4950895..5e8113d5e 100644
> > --- a/ofproto/ofproto-dpif-xlate.c
> > +++ b/ofproto/ofproto-dpif-xlate.c
> > @@ -47,6 +47,7 @@
> >  #include "ofproto/ofproto-dpif-ipfix.h"
> >  #include "ofproto/ofproto-dpif-mirror.h"
> >  #include "ofproto/ofproto-dpif-monitor.h"
> > +#include "ofproto/ofproto-dpif-lsample.h"
>
> Add in alphabetical order?

Ack.

>
> >  #include "ofproto/ofproto-dpif-sflow.h"
> >  #include "ofproto/ofproto-dpif-trace.h"
> >  #include "ofproto/ofproto-dpif-xlate-cache.h"
> > @@ -117,6 +118,7 @@ struct xbridge {
> >  struct dpif_sflow *sflow; /* SFlow handle, or null. */
> >  struct dpif_ipfix *ipfix; /* Ipfix handle, or null. */
> >  struct netflow *netflow;  /* Netflow handle, or null. */
> > +struct dpif_lsample *lsample; /* Local sample handle, or null. */
>
> I would move above netflow, as you also do the actual init/unref before 
> netflow.


Ack.


>
> >  struct stp *stp;  /* STP or null if disabled. */
> >  struct rstp *rstp;/* RSTP or null if disabled. */
> >
> > @@ -686,6 +688,7 @@ static void xlate_xbridge_set(struct xbridge *, struct 
> > dpif *,
> >const struct mbridge *,
> >const struct dpif_sflow *,
> >const struct dpif_ipfix *,
> > +  const struct dpif_lsample *,
> >const struct netflow *,
> >bool forward_bpdu, bool has_in_band,
> >const struct dpif_backer_support *,
> > @@ -1069,6 +1072,7 @@ xlate_xbridge_set(struct xbridge *xbridge,
> >const struct mbridge *mbridge,
> >const struct dpif_sflow *sflow,
> >const struct dpif_ipfix *ipfix,
> > +  const struct dpif_lsample *lsample,
> >const struct netflow *netflow,
> >bool forward_bpdu, bool has_in_band,
> >const struct dpif_backer_support *support,
> > @@ -1099,6 +1103,11 @@ xlate_xbridge_set(struct xbridge *xbridge,
> >  xbridge->ipfix = dpif_ipfix_ref(ipfix);
> >  }
> >
> > +if (xbridge->lsample != lsample) {
> > +dpif_lsample_unref(xbridge->lsample);
> > +xbridge->lsample = dpif_lsample_ref(lsample);
> > +}
> > +
> >  if (xbridge->stp 

Re: [ovs-dev] [PATCH v1 05/13] vswitchd: Add local sampling to vswitchd schema.

2024-07-09 Thread Adrián Moreno
On Tue, Jul 09, 2024 at 11:45:35AM GMT, Eelco Chaudron wrote:
> On 7 Jul 2024, at 22:08, Adrian Moreno wrote:
>
> > Add as new column in the Flow_Sample_Collector_Set table named
> > "local_group_id" which enables this feature.
>
> Small nit below, if fixed add my ACK to the next revision.
>
> //Eelco
>
> > Signed-off-by: Adrian Moreno 
> > ---
> >  NEWS   |  4 ++
> >  vswitchd/bridge.c  | 78 +++---
> >  vswitchd/vswitch.ovsschema |  9 -
> >  vswitchd/vswitch.xml   | 40 +--
> >  4 files changed, 120 insertions(+), 11 deletions(-)
> >
> > diff --git a/NEWS b/NEWS
> > index e0359b759..15faf9fc3 100644
> > --- a/NEWS
> > +++ b/NEWS
> > @@ -16,6 +16,10 @@ Post-v3.3.0
> > per interface 'options:dpdk-lsc-interrupt' to 'false'.
> > - Python:
> >   * Added custom transaction support to the Idl via add_op().
> > +   - Local sampling is introduced. It reuses the OpenFlow sample action and
> > + allows samples to be emitted locally (instead of via IPFIX) in a
> > + datapath-specific manner. The Linux kernel datapath is the first to
> > + support this feature by using the new datapath "psample" action.
> >
> >
> >  v3.3.0 - 16 Feb 2024
> > diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
> > index 95a65fcdc..b7db681f3 100644
> > --- a/vswitchd/bridge.c
> > +++ b/vswitchd/bridge.c
> > @@ -288,6 +288,7 @@ static void bridge_configure_mac_table(struct bridge *);
> >  static void bridge_configure_mcast_snooping(struct bridge *);
> >  static void bridge_configure_sflow(struct bridge *, int 
> > *sflow_bridge_number);
> >  static void bridge_configure_ipfix(struct bridge *);
> > +static void bridge_configure_lsample(struct bridge *);
> >  static void bridge_configure_spanning_tree(struct bridge *);
> >  static void bridge_configure_tables(struct bridge *);
> >  static void bridge_configure_dp_desc(struct bridge *);
> > @@ -989,6 +990,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch 
> > *ovs_cfg)
> >  bridge_configure_netflow(br);
> >  bridge_configure_sflow(br, _bridge_number);
> >  bridge_configure_ipfix(br);
> > +bridge_configure_lsample(br);
> >  bridge_configure_spanning_tree(br);
> >  bridge_configure_tables(br);
> >  bridge_configure_dp_desc(br);
> > @@ -1537,10 +1539,11 @@ ovsrec_ipfix_is_valid(const struct ovsrec_ipfix 
> > *ipfix)
> >  return ipfix && ipfix->n_targets > 0;
> >  }
> >
> > -/* Returns whether a Flow_Sample_Collector_Set row is valid. */
> > +/* Returns whether a Flow_Sample_Collector_Set row contains a valid IPFIX
> > + * configuration. */
> >  static bool
> > -ovsrec_fscs_is_valid(const struct ovsrec_flow_sample_collector_set *fscs,
> > - const struct bridge *br)
> > +ovsrec_fscs_is_valid_ipfix(const struct ovsrec_flow_sample_collector_set 
> > *fscs,
> > +   const struct bridge *br)
> >  {
> >  return ovsrec_ipfix_is_valid(fscs->ipfix) && fscs->bridge == br->cfg;
> >  }
> > @@ -1558,7 +1561,7 @@ bridge_configure_ipfix(struct bridge *br)
> >  const char *virtual_obs_id;
> >
> >  OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH(fe_cfg, idl) {
> > -if (ovsrec_fscs_is_valid(fe_cfg, br)) {
> > +if (ovsrec_fscs_is_valid_ipfix(fe_cfg, br)) {
> >  n_fe_opts++;
> >  }
> >  }
> > @@ -1621,7 +1624,7 @@ bridge_configure_ipfix(struct bridge *br)
> >  fe_opts = xcalloc(n_fe_opts, sizeof *fe_opts);
> >  opts = fe_opts;
> >  OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH(fe_cfg, idl) {
> > -if (ovsrec_fscs_is_valid(fe_cfg, br)) {
> > +if (ovsrec_fscs_is_valid_ipfix(fe_cfg, br)) {
> >  opts->collector_set_id = fe_cfg->id;
> >  sset_init(>targets);
> >  sset_add_array(>targets, fe_cfg->ipfix->targets,
> > @@ -1667,6 +1670,71 @@ bridge_configure_ipfix(struct bridge *br)
> >  }
> >  }
> >
> > +/* Returns whether a Flow_Sample_Collector_Set row contains a valid local
> > + * sampling configuration. */
> > +static bool
> > +ovsrec_fscs_is_valid_local(const struct ovsrec_flow_sample_collector_set 
> > *fscs,
> > +   const struct bridge *br)
> > +{
> > +return fscs->local_group_id && fscs->n_local_group_id == 1 &&
> > +   fscs->bridge == br->cfg;
> > +}
> > +
> > +/* Set local sample configuration on 'br'. */
> > +static void
> > +bridge_configure_lsample(struct bridge *br)
> > +{
> > +static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
> > +const struct ovsrec_flow_sample_collector_set *fscs;
> > +struct ofproto_lsample_options *opts_array, *opts;
> > +size_t n_opts = 0;
> > +int ret;
> > +
> > +/* Iterate the Flow_Sample_Collector_Set table twice.
> > + * First to get the number of valid configuration entries, then to 
> > process
> > + * each of them and build an array of options. 

Re: [ovs-dev] [PATCH v1 04/13] ofproto: Add ofproto-dpif-lsample.

2024-07-09 Thread Adrián Moreno
On Tue, Jul 09, 2024 at 11:45:19AM GMT, Eelco Chaudron wrote:
> On 7 Jul 2024, at 22:08, Adrian Moreno wrote:
>
> > Add a new resource in ofproto-dpif and the corresponding API in
> > ofproto_provider.h to represent and local sampling configuration.
> >
> > Signed-off-by: Adrian Moreno 
>
> Some small nits below.
>
> //Eelco
>
> > ---
> >  ofproto/automake.mk|   2 +
> >  ofproto/ofproto-dpif-lsample.c | 187 +
> >  ofproto/ofproto-dpif-lsample.h |  36 +++
> >  ofproto/ofproto-dpif.c |  38 +++
> >  ofproto/ofproto-dpif.h |   1 +
> >  ofproto/ofproto-provider.h |   9 ++
> >  ofproto/ofproto.c  |  12 +++
> >  ofproto/ofproto.h  |   8 ++
> >  8 files changed, 293 insertions(+)
> >  create mode 100644 ofproto/ofproto-dpif-lsample.c
> >  create mode 100644 ofproto/ofproto-dpif-lsample.h
> >
> > diff --git a/ofproto/automake.mk b/ofproto/automake.mk
> > index 7c08b563b..cb1361b8a 100644
> > --- a/ofproto/automake.mk
> > +++ b/ofproto/automake.mk
> > @@ -30,6 +30,8 @@ ofproto_libofproto_la_SOURCES = \
> > ofproto/ofproto-dpif.h \
> > ofproto/ofproto-dpif-ipfix.c \
> > ofproto/ofproto-dpif-ipfix.h \
> > +   ofproto/ofproto-dpif-lsample.c \
> > +   ofproto/ofproto-dpif-lsample.h \
> > ofproto/ofproto-dpif-mirror.c \
> > ofproto/ofproto-dpif-mirror.h \
> > ofproto/ofproto-dpif-monitor.c \
> > diff --git a/ofproto/ofproto-dpif-lsample.c b/ofproto/ofproto-dpif-lsample.c
> > new file mode 100644
> > index 0..d675a116f
> > --- /dev/null
> > +++ b/ofproto/ofproto-dpif-lsample.c
> > @@ -0,0 +1,187 @@
> > +/*
> > + * Copyright (c) 2024 Red Hat, Inc.
> > + *
> > + * Licensed under the Apache License, Version 2.0 (the "License");
> > + * you may not use this file except in compliance with the License.
> > + * You may obtain a copy of the License at:
> > + *
> > + * http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing, software
> > + * distributed under the License is distributed on an "AS IS" BASIS,
> > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> > + * See the License for the specific language governing permissions and
> > + * limitations under the License.
> > + */
> > +
> > +#include 
> > +#include "ofproto-dpif-lsample.h"
> > +
> > +#include "cmap.h"
> > +#include "hash.h"
> > +#include "ofproto.h"
> > +#include "openvswitch/thread.h"
> > +
> > +/* Dpif local sampling.
> > + *
> > + * Thread safety: dpif_lsample allows lockless concurrent reads of local
> > + * sampling exporters as long as the following restrictions are met:
> > + *   1) While the last reference is being dropped, i.e: a thread is calling
> > + *  "dpif_lsample_unref" on the last reference, other threads cannot 
> > call
> > + *  "dpif_lsample_ref".
> > + *   2) Threads do not quiese while holding references to internal
> > + *  lsample_exporter objects.
> > + */
> > +
> > +struct dpif_lsample {
> > +struct cmap exporters;  /* Contains lsample_exporter_node 
> > instances
> > +   indexed by collector_set_id. */
> > +struct ovs_mutex mutex; /* Protects concurrent 
> > insertion/deletion
> > + * of exporters. */
> > +
> > +struct ovs_refcount ref_cnt;/* Controls references to this 
> > instance. */
> > +};
> > +
> > +struct lsample_exporter {
> > +struct ofproto_lsample_options options;
> > +};
> > +
> > +struct lsample_exporter_node {
> > +struct cmap_node node;  /* In dpif_lsample->exporters. */
> > +struct lsample_exporter exporter;
> > +};
> > +
> > +static void
> > +dpif_lsample_delete_exporter(struct dpif_lsample *lsample,
> > + struct lsample_exporter_node *node)
> > +{
> > +ovs_mutex_lock(>mutex);
> > +cmap_remove(>exporters, >node,
> > +hash_int(node->exporter.options.collector_set_id, 0));
> > +ovs_mutex_unlock(>mutex);
> > +
> > +ovsrcu_postpone(free, node);
> > +}
> > +
> > +/* Adds an exporter with the provided options which are copied. */
> > +static struct lsample_exporter_node *
> > +dpif_lsample_add_exporter(struct dpif_lsample *lsample,
> > +  const struct ofproto_lsample_options *options)
> > +{
> > +struct lsample_exporter_node *node;
> > +
> > +node = xzalloc(sizeof *node);
> > +node->exporter.options = *options;
> > +
> > +ovs_mutex_lock(>mutex);
> > +cmap_insert(>exporters, >node,
> > +hash_int(options->collector_set_id, 0));
> > +ovs_mutex_unlock(>mutex);
> > +
> > +return node;
> > +}
> > +
> > +static struct lsample_exporter_node *
> > +dpif_lsample_find_exporter_node(const struct dpif_lsample *lsample,
> > +const uint32_t collector_set_id)
> > +{
> > +struct lsample_exporter_node *node;
> > +
> > +

Re: [ovs-dev] [PATCH v1 03/13] ofproto_dpif: Check for psample support.

2024-07-09 Thread Adrián Moreno
On Tue, Jul 09, 2024 at 11:45:17AM GMT, Eelco Chaudron wrote:
> On 4 Jul 2024, at 9:52, Adrian Moreno wrote:
>
> > Only kernel datapath supports this action so add a function in dpif.c
> > that checks for that.
>
> One small nit below, rest looks good. If this is the only change in the
> next series you can add my ACK.
>
> //Eelco
>
> > Signed-off-by: Adrian Moreno 
> > ---
> >  lib/dpif.c |  7 +++
> >  lib/dpif.h |  1 +
> >  ofproto/ofproto-dpif.c | 43 ++
> >  ofproto/ofproto-dpif.h |  7 ++-
> >  4 files changed, 57 insertions(+), 1 deletion(-)
> >
> > diff --git a/lib/dpif.c b/lib/dpif.c
> > index 71728badc..0a964ba89 100644
> > --- a/lib/dpif.c
> > +++ b/lib/dpif.c
> > @@ -1953,6 +1953,13 @@ dpif_supports_lb_output_action(const struct dpif 
> > *dpif)
> >  return dpif_is_netdev(dpif);
> >  }
> >
> > +bool
> > +dpif_may_support_psample(const struct dpif *dpif)
> > +{
> > +/* Userspace datapath does not support this action. */
> > +return !dpif_is_netdev(dpif);
> > +}
> > +
> >  /* Meters */
> >  void
> >  dpif_meter_get_features(const struct dpif *dpif,
> > diff --git a/lib/dpif.h b/lib/dpif.h
> > index a764e8a59..6bef7d5b3 100644
> > --- a/lib/dpif.h
> > +++ b/lib/dpif.h
> > @@ -941,6 +941,7 @@ int dpif_get_pmds_for_port(const struct dpif * dpif, 
> > odp_port_t port_no,
> >  char *dpif_get_dp_version(const struct dpif *);
> >  bool dpif_supports_tnl_push_pop(const struct dpif *);
> >  bool dpif_may_support_explicit_drop_action(const struct dpif *);
> > +bool dpif_may_support_psample(const struct dpif *);
> >  bool dpif_synced_dp_layers(struct dpif *);
> >
> >  /* Log functions. */
> > diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> > index 4712d10a8..94c84d697 100644
> > --- a/ofproto/ofproto-dpif.c
> > +++ b/ofproto/ofproto-dpif.c
> > @@ -873,6 +873,12 @@ ovs_lb_output_action_supported(struct ofproto_dpif 
> > *ofproto)
> >  return ofproto->backer->rt_support.lb_output_action;
> >  }
> >
> > +bool
> > +ovs_psample_supported(struct ofproto_dpif *ofproto)
> > +{
> > +return ofproto->backer->rt_support.psample;
> > +}
> > +
> >  /* Tests whether 'backer''s datapath supports recirculation.  Only newer
> >   * datapaths support OVS_KEY_ATTR_RECIRC_ID in keys.  We need to disable 
> > some
> >   * features on older datapaths that don't support this feature.
> > @@ -1609,6 +1615,42 @@ check_add_mpls(struct dpif_backer *backer)
> >  return supported;
> >  }
> >
> > +/* Tests whether 'backer''s datapath supports the OVS_ACTION_ATTR_PSAMPLE
> > + * action. */
> > +static bool
> > +check_psample(struct dpif_backer *backer)
> > +{
> > +uint8_t cookie[OVS_PSAMPLE_COOKIE_MAX_SIZE];
> > +struct odputil_keybuf keybuf;
> > +struct ofpbuf actions;
> > +struct ofpbuf key;
> > +struct flow flow;
> > +bool supported;
> > +
> > +struct odp_flow_key_parms odp_parms = {
> > +.flow = ,
> > +.probe = true,
> > +};
> > +
> > +memset(, 0, sizeof flow);
> > +ofpbuf_use_stack(, , sizeof keybuf);
> > +odp_flow_key_from_flow(_parms, );
> > +ofpbuf_init(, 64);
> > +
> > +/* Generate a random max-size cookie. */
> > +random_bytes(cookie, sizeof(cookie));
> > +
> > +odp_put_psample_action(, 10, cookie, sizeof cookie);
> > +
> > +supported = dpif_may_support_psample(backer->dpif) &&
> > +dpif_probe_feature(backer->dpif, "psample", , , NULL);
> > +
> > +ofpbuf_uninit();
> > +VLOG_INFO("%s: Datapath %s psample", dpif_name(backer->dpif),
> > +  supported ? "supports" : "does not support");
> > +return supported;
> > +}
> > +
> >  #define CHECK_FEATURE__(NAME, SUPPORT, FIELD, VALUE, ETHTYPE)  
> >  \
> >  static bool
> >  \
> >  check_##NAME(struct dpif_backer *backer)   
> >  \
> > @@ -1698,6 +1740,7 @@ check_support(struct dpif_backer *backer)
> >  dpif_supports_lb_output_action(backer->dpif);
> >  backer->rt_support.ct_zero_snat = dpif_supports_ct_zero_snat(backer);
> >  backer->rt_support.add_mpls = check_add_mpls(backer);
> > +backer->rt_support.psample = check_psample(backer);
> >
> >  /* Flow fields. */
> >  backer->rt_support.odp.ct_state = check_ct_state(backer);
> > diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h
> > index d33f73df8..bc7a19dab 100644
> > --- a/ofproto/ofproto-dpif.h
> > +++ b/ofproto/ofproto-dpif.h
> > @@ -213,7 +213,10 @@ struct group_dpif *group_dpif_lookup(struct 
> > ofproto_dpif *,
> >  DPIF_SUPPORT_FIELD(bool, ct_zero_snat, "Conntrack all-zero IP SNAT")   
> >  \
> > 
> >  \
> >  /* True if the datapath supports add_mpls action. */   
> >  \
> > -DPIF_SUPPORT_FIELD(bool, add_mpls, "MPLS Label add")
> > +DPIF_SUPPORT_FIELD(bool, 

Re: [ovs-dev] [PATCH v1 02/13] odp-util: Add support OVS_ACTION_ATTR_PSAMPLE.

2024-07-09 Thread Adrián Moreno
On Tue, Jul 09, 2024 at 11:45:15AM GMT, Eelco Chaudron wrote:
> On 4 Jul 2024, at 9:52, Adrian Moreno wrote:
>
> > Add support for parsing and formatting the new action.
> >
> > Also, flag OVS_ACTION_ATTR_SAMPLE as requiring datapath assistance if it
> > contains a nested OVS_ACTION_ATTR_PSAMPLE. The reason is that the
> > sampling rate form the parent "sample" is made available to the nested
>
> form -> from
>
> > "psample" by the kernel.
>
> Two small comments below, the rest looks good.
>
> > Signed-off-by: Adrian Moreno 
> > ---
> >  include/linux/openvswitch.h  | 28 +++
> >  lib/dpif-netdev.c|  1 +
> >  lib/dpif.c   |  1 +
> >  lib/odp-execute.c| 25 +-
> >  lib/odp-util.c   | 93 
> >  lib/odp-util.h   |  3 ++
> >  ofproto/ofproto-dpif-ipfix.c |  1 +
> >  ofproto/ofproto-dpif-sflow.c |  1 +
> >  python/ovs/flow/odp.py   |  8 
> >  tests/odp.at | 16 +++
> >  10 files changed, 176 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
> > index d9fb991ef..0023b65fb 100644
> > --- a/include/linux/openvswitch.h
> > +++ b/include/linux/openvswitch.h
> > @@ -992,6 +992,31 @@ struct check_pkt_len_arg {
> >  };
> >  #endif
> >
> > +#define OVS_PSAMPLE_COOKIE_MAX_SIZE 16
> > +/**
> > + * enum ovs_pample_attr - Attributes for %OVS_ACTION_ATTR_PSAMPLE
> > + * action.
> > + *
> > + * @OVS_PSAMPLE_ATTR_GROUP: 32-bit number to identify the source of the
> > + * sample.
> > + * @OVS_PSAMPLE_ATTR_COOKIE: An optional variable-length binary cookie that
> > + * contains user-defined metadata. The maximum length is
> > + * OVS_PSAMPLE_COOKIE_MAX_SIZE bytes.
> > + *
> > + * Sends the packet to the psample multicast group with the specified 
> > group and
> > + * cookie. It is possible to combine this action with the
> > + * %OVS_ACTION_ATTR_TRUNC action to limit the size of the sample.
> > + */
> > +enum ovs_psample_attr {
> > +OVS_PSAMPLE_ATTR_GROUP = 1,/* u32 number. */
> > +OVS_PSAMPLE_ATTR_COOKIE,   /* Optional, user specified cookie. 
> > */
> > +
> > +/* private: */
>
> None of the other definitions have this private marking, so I see no need to
> start adding it here.

OK. The uAPI file has it (requested by netdev maintainers) but I guess
it's kernel-specific and this file is not a blind copy of the uAPI
anyways so I think we can remove it. I'll do on the next version.

>
> > +__OVS_PSAMPLE_ATTR_MAX
> > +};
> > +
> > +#define OVS_PSAMPLE_ATTR_MAX (__OVS_PSAMPLE_ATTR_MAX - 1)
> > +
> >  /**
> >   * enum ovs_action_attr - Action types.
> >   *
> > @@ -1056,6 +1081,8 @@ struct check_pkt_len_arg {
> >   * of l3 tunnel flag in the tun_flags field of OVS_ACTION_ATTR_ADD_MPLS
> >   * argument.
> >   * @OVS_ACTION_ATTR_DROP: Explicit drop action.
> > + * @OVS_ACTION_ATTR_PSAMPLE: Send a sample of the packet to external 
> > observers
> > + * via psample.
> >   */
> >
> >  enum ovs_action_attr {
> > @@ -1087,6 +1114,7 @@ enum ovs_action_attr {
> > OVS_ACTION_ATTR_ADD_MPLS, /* struct ovs_action_add_mpls. */
> > OVS_ACTION_ATTR_DEC_TTL,  /* Nested OVS_DEC_TTL_ATTR_*. */
> > OVS_ACTION_ATTR_DROP, /* u32 xlate_error. */
> > +   OVS_ACTION_ATTR_PSAMPLE,  /* Nested OVS_PSAMPLE_ATTR_*. */
> >
> >  #ifndef __KERNEL__
> > OVS_ACTION_ATTR_TUNNEL_PUSH,   /* struct ovs_action_push_tnl*/
> > diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
> > index c7f9e1490..f0594e5f5 100644
> > --- a/lib/dpif-netdev.c
> > +++ b/lib/dpif-netdev.c
> > @@ -9519,6 +9519,7 @@ dp_execute_cb(void *aux_, struct dp_packet_batch 
> > *packets_,
> >  case OVS_ACTION_ATTR_DROP:
> >  case OVS_ACTION_ATTR_ADD_MPLS:
> >  case OVS_ACTION_ATTR_DEC_TTL:
> > +case OVS_ACTION_ATTR_PSAMPLE:
> >  case __OVS_ACTION_ATTR_MAX:
> >  OVS_NOT_REACHED();
> >  }
> > diff --git a/lib/dpif.c b/lib/dpif.c
> > index 23eb18495..71728badc 100644
> > --- a/lib/dpif.c
> > +++ b/lib/dpif.c
> > @@ -1192,6 +1192,7 @@ dpif_execute_helper_cb(void *aux_, struct 
> > dp_packet_batch *packets_,
> >  case OVS_ACTION_ATTR_TUNNEL_PUSH:
> >  case OVS_ACTION_ATTR_TUNNEL_POP:
> >  case OVS_ACTION_ATTR_USERSPACE:
> > +case OVS_ACTION_ATTR_PSAMPLE:
> >  case OVS_ACTION_ATTR_RECIRC: {
> >  struct dpif_execute execute;
> >  struct ofpbuf execute_actions;
> > diff --git a/lib/odp-execute.c b/lib/odp-execute.c
> > index 081e4d432..15577d539 100644
> > --- a/lib/odp-execute.c
> > +++ b/lib/odp-execute.c
> > @@ -818,13 +818,13 @@ requires_datapath_assistance(const struct nlattr *a)
> >  case OVS_ACTION_ATTR_RECIRC:
> >  case OVS_ACTION_ATTR_CT:
> >  case OVS_ACTION_ATTR_METER:
> > +case OVS_ACTION_ATTR_PSAMPLE:
> >  return true;
> >
> >  case OVS_ACTION_ATTR_SET:
> >  case OVS_ACTION_ATTR_SET_MASKED:
> >  case OVS_ACTION_ATTR_PUSH_VLAN:

Re: [ovs-dev] [PATCH ovn 8/8] northd: Add ACL Sampling.

2024-07-09 Thread Adrián Moreno
On Mon, Jul 08, 2024 at 01:24:14PM GMT, Dumitru Ceara wrote:
> From: Adrian Moreno 
>
> Introduce a new table called Sample where per-flow IPFIX configuration
> can be specified.
> Also, reference rows from such table from the ACL table to enable the
> configuration of ACL sampling. If enabled, northd will add a sample
> action to each ACL related logical flow.
>
> Packets that hit stateful ACLs are sampled in different ways depending
> whether they are initiating a new session or are just forwarded on an
> existing (already allowed) session.  Two new columns ("sample_new" and
> "sample_est") are added to the ACL table to allow for potentially
> different sampling rates for the two cases.
>
> Note: If an ACL has both sampling enabled and a label associated to it
> then the label value overrides the observation point ID defined in the
> sample configuration.  This is a side effect of the implementation
> (observation point IDs are stored in conntrack in the same part of the
> ct_label where ACL labels are also stored).  The two features
> (sampling and ACL labels) serve however similar purposes so it's not
> expected that they're both enabled together.
>
> When sampling is enabled on an ACL additional logical flows are created
> for that ACL (one for stateless ACLs and 3 for stateful ACLs) in the ACL
> action stage of the logical pipeline.  These additional flows match on a
> combination of conntrack state values and observation point id values
> (either against a logical register or against the stored ct_label state)
> in order to determine whether the packets hitting the ACLs must be
> sampled or not.  This comes with a slight increase in the number of
> logical flows and in the number of OpenFlow rules.  The number of
> additional flows _does not_ depend on the original ACL match or action.
>
> New --sample-new and --sample-est optional arguments are added to the
> 'ovn-nbctl acl-add' command to allow configuring these new types of
> sampling for ACLs.
>
> An example workflow of configuring ACL samples is:
>   # Create Sampling_App mappings for ACL traffic types:
>   ovn-nbctl create Sampling_App name="acl-new-traffic-sampling" \
> id="42"
>   ovn-nbctl create sampling_app name="acl-est-traffic-sampling" \
>   id="43"
>   # Create two sample collectors, one that samples all packets (c1)
>   # and another one that samples with a probability of 10% (c2):
>   c1=$(ovn-nbctl create Sample_Collector name=c1 \
>probability=65535 set_id=1)
>   c2=$(ovn-nbctl create Sample_Collector name=c2 \
>probability=6553 set_id=2)
>   # Create two sample configurations (for new and for established
>   # traffic):
>   s1=$(ovn-nbctl create sample collector="$c1 $c2" metadata=4301)
>   s2=$(ovn-nbctl create sample collector="$c1 $c2" metadata=4302)
>   # Create an ingress ACL to allow IP traffic:
>   ovn-nbctl --sample-new=$s1 --sample-est=$s2 acl-add ls \
> from-lport 1 "ip" allow-related
>
> The config above will generate IPFIX samples with:
> - observation domain id set to 42 (Sampling_App
>   "acl-new-traffic-sampling" config) and observation point id
>   set to 4301 (Sample s1) for packets that create a new
>   connection
> - observation domain id set to 43 (Sampling_app
>   "acl-est-traffic-sampling" config) and observation point id
>   set to 4302 (Sample s2) for packets that are part of an already
>   existing connection
>

We assume the dp_key is 0 in this case, right? Maybe worth mentioning
it.

> Reported-at: https://issues.redhat.com/browse/FDP-305
> Signed-off-by: Adrian Moreno 
> Co-authored-by: Dumitru Ceara 
> Signed-off-by: Dumitru Ceara 
> ---
>  NEWS   |   3 +
>  include/ovn/logical-fields.h   |   2 +
>  lib/logical-fields.c   |   6 +
>  northd/northd.c| 519 +++--
>  northd/ovn-northd.8.xml|  26 ++
>  ovn-nb.ovsschema   |  44 ++-
>  ovn-nb.xml |  56 +++
>  tests/atlocal.in   |   6 +
>  tests/ovn-macros.at|   4 +
>  tests/ovn-nbctl.at |  20 +
>  tests/ovn-northd.at| 240 ++--
>  tests/ovn.at   |   3 +
>  tests/system-common-macros.at  |  11 +
>  tests/system-ovn.at| 149 +++
>  utilities/containers/fedora/Dockerfile |   1 +
>  utilities/containers/ubuntu/Dockerfile |   1 +
>  utilities/ovn-nbctl.8.xml  |   8 +-
>  utilities/ovn-nbctl.c  |  43 +-
>  18 files changed, 1079 insertions(+), 63 deletions(-)

I'm not done reviewing. I need to spend some time understanding how
locial flows are built. Not very familiar with this. Plus I want to run
some tests. However, here are some initial thoughts.

>
> diff --git a/NEWS b/NEWS
> index fcf182bc02..7899c623f2 100644
> --- a/NEWS
> +++ b/NEWS
> @@ 

Re: [ovs-dev] [PATCH v1] selftests: openvswitch: retry instead of sleep

2024-07-08 Thread Adrián Moreno
On Mon, Jul 08, 2024 at 09:31:58PM GMT, Ilya Maximets wrote:
> On 7/8/24 15:44, Adrian Moreno wrote:
> > There are a couple of places where the test script "sleep"s to wait for
> > some external condition to be met.
> >
> > This is error prone, specially in slow systems (identified in CI by
> > "KSFT_MACHINE_SLOW=yes").
> >
> > To fix this, add a "ovs_wait" function that tries to execute a command
> > a few times until it succeeds. The timeout used is set to 5s for
> > "normal" systems and doubled if a slow CI machine is detected.
> >
> > This should make the following work:
> >
> > $ vng --build  \
> > --config tools/testing/selftests/net/config \
> > --config kernel/configs/debug.config
> >
> > $ vng --run . --user root -- "make -C tools/testing/selftests/ \
> > KSFT_MACHINE_SLOW=yes TARGETS=net/openvswitch run_tests"
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  .../selftests/net/openvswitch/openvswitch.sh  | 49 ---
> >  .../selftests/net/openvswitch/ovs-dpctl.py|  1 +
> >  2 files changed, 42 insertions(+), 8 deletions(-)
> >
>
> Hi, Adrian.  See a small pile of nitpicks below.
>
> None of them are blocking from my perspective, except for a typo.
> Just listed them since there is a typo anyway.
>
> > diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh 
> > b/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > index bc71dbc18b21..83407b42073a 100755
> > --- a/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > +++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > @@ -11,6 +11,7 @@ ksft_skip=4
> >  PAUSE_ON_FAIL=no
> >  VERBOSE=0
> >  TRACING=0
> > +WAIT_TIMEOUT=5
> >
> >  tests="
> > arp_pingeth-arp: Basic arp ping between 
> > two NS
> > @@ -29,6 +30,32 @@ info() {
> > [ $VERBOSE = 0 ] || echo $*
> >  }
> >
> > +ovs_wait() {
> > +   info "waiting $WAIT_TIMEOUT s for: $@"
> > +
> > +   "$@"
> > +   if [[ $? -eq 0 ]]; then
>
> Maybe just 'if "$@"; then' ?
>

In my head this is a bit less clean but I don't mind.

> > +   info "wait succeeded inmediately"
>
> * immediately

Thanks. Will fix the typo.

>
> > +   return 0
> > +   fi
> > +
> > +   # A quick re-check helps speed up small races in fast systems.
> > +   # However, fractional sleeps might not necessarily work.
> > +   local start=0
> > +   sleep 0.1 || { sleep 1; start=1; }
> > +
> > +   for (( i=start; i
> for i in $(seq ${start} ${WAIT_TIMEOUT}); do
>
> Will need to initialize start to 1 and 2.
>
> It works, but seems like an unnecessary use of non-POSIX constructs.

The reason why I chose this form is that I find it more robust on a
script that changes IFS. If this function is called within a block that
has changed IFS, "i" will take the entire sequence as the value for the
first iteration.

>
> > +   "$@"
> > +   if [[ $? -eq 0 ]]; then
>
> if "$@"; then
>
> > +   info "wait succeeded after $i seconds"
> > +   return 0
> > +   fi
> > +   sleep 1
> > +   done
> > +   info "wait failed after $i seconds"
> > +   return 1
> > +}
> > +
> >  ovs_base=`pwd`
> >  sbxs=
> >  sbx_add () {
> > @@ -278,20 +305,21 @@ test_psample() {
> >
> > # Record psample data.
> > ovs_spawn_daemon "test_psample" python3 $ovs_base/ovs-dpctl.py 
> > psample-events
> > +   ovs_wait grep -q "listening for psample events" ${ovs_dir}/stdout
> >
> > # Send a single ping.
> > -   sleep 1
> > ovs_sbx "test_psample" ip netns exec client ping -I c1 172.31.110.20 -c 
> > 1 || return 1
> > -   sleep 1
> >
> > # We should have received one userspace action upcall and 2 psample 
> > packets.
> > -   grep -E "userspace action command" $ovs_dir/s0.out >/dev/null 2>&1 || 
> > return 1
> > +   ovs_wait grep -q "userspace action command" $ovs_dir/s0.out
> > +   [[ $? -eq 0 ]] || return 1
>
> Why checking separately and not one the same line with || return 1 ?

IMHO, passing complex commands to a function in bash can easily get very
problematic. That's why I try to remove all pipes, redirections or
logical operators like && and ||. At least for me it removes one extra
cycle that my brain has to spend looking at quotes and figuring out if
the operand will be interpreted inside the function or outside.

> Also double brackets seem unnecessary.

That's true.

>
> >
> > # client -> server samples should only contain the first 14 bytes of 
> > the packet.
> > -   grep -E "rate:4294967295,group:1,cookie:c0ffee data:[0-9a-f]{28}$" \
> > -$ovs_dir/stdout >/dev/null 2>&1 || return 1
> > -   grep -E "rate:4294967295,group:2,cookie:eeff0c" \
> > -$ovs_dir/stdout >/dev/null 2>&1 || return 1
> > +   ovs_wait grep -qE "rate:4294967295,group:1,cookie:c0ffee 
> > data:[0-9a-f]{28}$" $ovs_dir/stdout
> > +   [[ $? -eq 0 ]] || return 1
> > +
> > +   ovs_wait grep -q "rate:4294967295,group:2,cookie:eeff0c" $ovs_dir/stdout
> > +   [[ $? -eq 0 ]] || 

Re: [ovs-dev] [PATCH v1] selftests: openvswitch: retry instead of sleep

2024-07-08 Thread Adrián Moreno
On Mon, Jul 08, 2024 at 02:27:45PM GMT, Aaron Conole wrote:
> Adrian Moreno  writes:
>
> > There are a couple of places where the test script "sleep"s to wait for
> > some external condition to be met.
> >
> > This is error prone, specially in slow systems (identified in CI by
> > "KSFT_MACHINE_SLOW=yes").
> >
> > To fix this, add a "ovs_wait" function that tries to execute a command
> > a few times until it succeeds. The timeout used is set to 5s for
> > "normal" systems and doubled if a slow CI machine is detected.
> >
> > This should make the following work:
> >
> > $ vng --build  \
> > --config tools/testing/selftests/net/config \
> > --config kernel/configs/debug.config
> >
> > $ vng --run . --user root -- "make -C tools/testing/selftests/ \
> > KSFT_MACHINE_SLOW=yes TARGETS=net/openvswitch run_tests"
> >
> > Signed-off-by: Adrian Moreno 
> > ---
>
> Looks like this does resolve the issue in question on the -dbg
> environment:
>
> https://netdev.bots.linux.dev/contest.html?executor=vmksft-net-dbg=openvswitch-sh

Nice! I guess the 10s global timeout is enough for now.

>
> Thanks Adrian!  Also, thanks for including the fractional sleep.
>
> Reviewed-by: Aaron Conole 
>

Thanks.

I just realized that I've missed the target branch ("net-next") in the
subject. I'll wait a bit and respin to fix that.

Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH v1 03/13] ofproto_dpif: Check for psample support.

2024-07-08 Thread Adrián Moreno
On Mon, Jul 08, 2024 at 12:10:15PM GMT, Eelco Chaudron wrote:
>
>
> On 8 Jul 2024, at 10:37, Adrián Moreno wrote:
>
> > On Sun, Jul 07, 2024 at 10:08:55PM GMT, Adrian Moreno wrote:
> >> Only kernel datapath supports this action so add a function in dpif.c
> >> that checks for that.
> >>
> >> Signed-off-by: Adrian Moreno 
> >> ---
> >>  lib/dpif.c |  7 +++
> >>  lib/dpif.h |  1 +
> >>  ofproto/ofproto-dpif.c | 43 ++
> >>  ofproto/ofproto-dpif.h |  7 ++-
> >>  4 files changed, 57 insertions(+), 1 deletion(-)
> >>
> >
> > After Dumitru's comment on the last patch, I think we also need a
> > capability for this exposed in the OVSDB. I'll add it in the next
> > version.
>
> ACK, can you wait with the v2 until I review the RFC/v1?

Sure, thanks.

>
> >> diff --git a/lib/dpif.c b/lib/dpif.c
> >> index 71728badc..0a964ba89 100644
> >> --- a/lib/dpif.c
> >> +++ b/lib/dpif.c
> >> @@ -1953,6 +1953,13 @@ dpif_supports_lb_output_action(const struct dpif 
> >> *dpif)
> >>  return dpif_is_netdev(dpif);
> >>  }
> >>
> >> +bool
> >> +dpif_may_support_psample(const struct dpif *dpif)
> >> +{
> >> +/* Userspace datapath does not support this action. */
> >> +return !dpif_is_netdev(dpif);
> >> +}
> >> +
> >>  /* Meters */
> >>  void
> >>  dpif_meter_get_features(const struct dpif *dpif,
> >> diff --git a/lib/dpif.h b/lib/dpif.h
> >> index a764e8a59..6bef7d5b3 100644
> >> --- a/lib/dpif.h
> >> +++ b/lib/dpif.h
> >> @@ -941,6 +941,7 @@ int dpif_get_pmds_for_port(const struct dpif * dpif, 
> >> odp_port_t port_no,
> >>  char *dpif_get_dp_version(const struct dpif *);
> >>  bool dpif_supports_tnl_push_pop(const struct dpif *);
> >>  bool dpif_may_support_explicit_drop_action(const struct dpif *);
> >> +bool dpif_may_support_psample(const struct dpif *);
> >>  bool dpif_synced_dp_layers(struct dpif *);
> >>
> >>  /* Log functions. */
> >> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> >> index 4712d10a8..94c84d697 100644
> >> --- a/ofproto/ofproto-dpif.c
> >> +++ b/ofproto/ofproto-dpif.c
> >> @@ -873,6 +873,12 @@ ovs_lb_output_action_supported(struct ofproto_dpif 
> >> *ofproto)
> >>  return ofproto->backer->rt_support.lb_output_action;
> >>  }
> >>
> >> +bool
> >> +ovs_psample_supported(struct ofproto_dpif *ofproto)
> >> +{
> >> +return ofproto->backer->rt_support.psample;
> >> +}
> >> +
> >>  /* Tests whether 'backer''s datapath supports recirculation.  Only newer
> >>   * datapaths support OVS_KEY_ATTR_RECIRC_ID in keys.  We need to disable 
> >> some
> >>   * features on older datapaths that don't support this feature.
> >> @@ -1609,6 +1615,42 @@ check_add_mpls(struct dpif_backer *backer)
> >>  return supported;
> >>  }
> >>
> >> +/* Tests whether 'backer''s datapath supports the OVS_ACTION_ATTR_PSAMPLE
> >> + * action. */
> >> +static bool
> >> +check_psample(struct dpif_backer *backer)
> >> +{
> >> +uint8_t cookie[OVS_PSAMPLE_COOKIE_MAX_SIZE];
> >> +struct odputil_keybuf keybuf;
> >> +struct ofpbuf actions;
> >> +struct ofpbuf key;
> >> +struct flow flow;
> >> +bool supported;
> >> +
> >> +struct odp_flow_key_parms odp_parms = {
> >> +.flow = ,
> >> +.probe = true,
> >> +};
> >> +
> >> +memset(, 0, sizeof flow);
> >> +ofpbuf_use_stack(, , sizeof keybuf);
> >> +odp_flow_key_from_flow(_parms, );
> >> +ofpbuf_init(, 64);
> >> +
> >> +/* Generate a random max-size cookie. */
> >> +random_bytes(cookie, sizeof(cookie));
> >> +
> >> +odp_put_psample_action(, 10, cookie, sizeof cookie);
> >> +
> >> +supported = dpif_may_support_psample(backer->dpif) &&
> >> +dpif_probe_feature(backer->dpif, "psample", , , NULL);
> >> +
> >> +ofpbuf_uninit();
> >> +VLOG_INFO("%s: Datapath %s psample", dpif_name(backer->dpif),
> >> +  supported ? "supports" : "does not support");
> >> +return supported;
> >> +}
> >

Re: [ovs-dev] [PATCH v1 03/13] ofproto_dpif: Check for psample support.

2024-07-08 Thread Adrián Moreno
On Sun, Jul 07, 2024 at 10:08:55PM GMT, Adrian Moreno wrote:
> Only kernel datapath supports this action so add a function in dpif.c
> that checks for that.
>
> Signed-off-by: Adrian Moreno 
> ---
>  lib/dpif.c |  7 +++
>  lib/dpif.h |  1 +
>  ofproto/ofproto-dpif.c | 43 ++
>  ofproto/ofproto-dpif.h |  7 ++-
>  4 files changed, 57 insertions(+), 1 deletion(-)
>

After Dumitru's comment on the last patch, I think we also need a
capability for this exposed in the OVSDB. I'll add it in the next
version.

Thanks.
Adrián


> diff --git a/lib/dpif.c b/lib/dpif.c
> index 71728badc..0a964ba89 100644
> --- a/lib/dpif.c
> +++ b/lib/dpif.c
> @@ -1953,6 +1953,13 @@ dpif_supports_lb_output_action(const struct dpif *dpif)
>  return dpif_is_netdev(dpif);
>  }
>
> +bool
> +dpif_may_support_psample(const struct dpif *dpif)
> +{
> +/* Userspace datapath does not support this action. */
> +return !dpif_is_netdev(dpif);
> +}
> +
>  /* Meters */
>  void
>  dpif_meter_get_features(const struct dpif *dpif,
> diff --git a/lib/dpif.h b/lib/dpif.h
> index a764e8a59..6bef7d5b3 100644
> --- a/lib/dpif.h
> +++ b/lib/dpif.h
> @@ -941,6 +941,7 @@ int dpif_get_pmds_for_port(const struct dpif * dpif, 
> odp_port_t port_no,
>  char *dpif_get_dp_version(const struct dpif *);
>  bool dpif_supports_tnl_push_pop(const struct dpif *);
>  bool dpif_may_support_explicit_drop_action(const struct dpif *);
> +bool dpif_may_support_psample(const struct dpif *);
>  bool dpif_synced_dp_layers(struct dpif *);
>
>  /* Log functions. */
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index 4712d10a8..94c84d697 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -873,6 +873,12 @@ ovs_lb_output_action_supported(struct ofproto_dpif 
> *ofproto)
>  return ofproto->backer->rt_support.lb_output_action;
>  }
>
> +bool
> +ovs_psample_supported(struct ofproto_dpif *ofproto)
> +{
> +return ofproto->backer->rt_support.psample;
> +}
> +
>  /* Tests whether 'backer''s datapath supports recirculation.  Only newer
>   * datapaths support OVS_KEY_ATTR_RECIRC_ID in keys.  We need to disable some
>   * features on older datapaths that don't support this feature.
> @@ -1609,6 +1615,42 @@ check_add_mpls(struct dpif_backer *backer)
>  return supported;
>  }
>
> +/* Tests whether 'backer''s datapath supports the OVS_ACTION_ATTR_PSAMPLE
> + * action. */
> +static bool
> +check_psample(struct dpif_backer *backer)
> +{
> +uint8_t cookie[OVS_PSAMPLE_COOKIE_MAX_SIZE];
> +struct odputil_keybuf keybuf;
> +struct ofpbuf actions;
> +struct ofpbuf key;
> +struct flow flow;
> +bool supported;
> +
> +struct odp_flow_key_parms odp_parms = {
> +.flow = ,
> +.probe = true,
> +};
> +
> +memset(, 0, sizeof flow);
> +ofpbuf_use_stack(, , sizeof keybuf);
> +odp_flow_key_from_flow(_parms, );
> +ofpbuf_init(, 64);
> +
> +/* Generate a random max-size cookie. */
> +random_bytes(cookie, sizeof(cookie));
> +
> +odp_put_psample_action(, 10, cookie, sizeof cookie);
> +
> +supported = dpif_may_support_psample(backer->dpif) &&
> +dpif_probe_feature(backer->dpif, "psample", , , NULL);
> +
> +ofpbuf_uninit();
> +VLOG_INFO("%s: Datapath %s psample", dpif_name(backer->dpif),
> +  supported ? "supports" : "does not support");
> +return supported;
> +}
> +
>  #define CHECK_FEATURE__(NAME, SUPPORT, FIELD, VALUE, ETHTYPE)   \
>  static bool \
>  check_##NAME(struct dpif_backer *backer)\
> @@ -1698,6 +1740,7 @@ check_support(struct dpif_backer *backer)
>  dpif_supports_lb_output_action(backer->dpif);
>  backer->rt_support.ct_zero_snat = dpif_supports_ct_zero_snat(backer);
>  backer->rt_support.add_mpls = check_add_mpls(backer);
> +backer->rt_support.psample = check_psample(backer);
>
>  /* Flow fields. */
>  backer->rt_support.odp.ct_state = check_ct_state(backer);
> diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h
> index d33f73df8..bc7a19dab 100644
> --- a/ofproto/ofproto-dpif.h
> +++ b/ofproto/ofproto-dpif.h
> @@ -213,7 +213,10 @@ struct group_dpif *group_dpif_lookup(struct ofproto_dpif 
> *,
>  DPIF_SUPPORT_FIELD(bool, ct_zero_snat, "Conntrack all-zero IP SNAT")\
>  \
>  /* True if the datapath supports add_mpls action. */\
> -DPIF_SUPPORT_FIELD(bool, add_mpls, "MPLS Label add")
> +DPIF_SUPPORT_FIELD(bool, add_mpls, "MPLS Label add")\
> +\
> +/* True if the datapath supports psample action. */ \
> +DPIF_SUPPORT_FIELD(bool, psample, "psample")
>
>
>  /* Stores the various features 

Re: [ovs-dev] [RFC PATCH v3 13/13] ofp-actions: Load data from fields in sample action.

2024-07-08 Thread Adrián Moreno
On Thu, Jul 04, 2024 at 11:25:34AM GMT, Dumitru Ceara wrote:
> On 7/4/24 09:52, Adrian Moreno wrote:
> > When sample action gets used as a way of sampling traffic with
> > controller-generated metadata (i.e: obs_domain_id and obs_point_id),
> > the controller will have to increase the number of flows to ensure each
> > part of the pipeline contains the right metadata.
> >
> > As an example, if the controller decides to sample stateful traffic, it
> > could store the computed metadata for each connection in the conntrack
> > label. However, for established connections, a flow must be created for
> > each different ct_label value with a sample action that contains a
> > different hardcoded obs_domain and obs_point id.
> >
> > This patch adds a new version of the NXAST_RAW_SAMPLE* action (number 4)
> > that supports specifying the observation point and domain using an
> > OpenFlow field reference, so now the controller can express:
> >
> >  sample(...
> > obs_domain_id=NXM_NX_CT_LABEL[0..31],
> > obs_point_id=NXM_NX_CT_LABEL[32..63]
> > ...
> >)
> >
> > Signed-off-by: Adrian Moreno 
> > ---
>
> Hi Adrian,
>
> Thanks a lot for working on expanding the sampling support (in the
> kernel too).
>
> I didn't review the patch (or the rest of the series) yet but one thing
> we should definitely add to the non-RFC version is a way for controllers
> to detect that this new action version is supported.
>
> In other occasions we've used the OVSDB.Datapath.Capabilities column to
> report that new actions are supported (e.g., "ct_flush" for the
> extension that allows flushing CT with a generic match).  It might make
> sense to add another capability there for this new action version.
>

Yep. I've sent v1 but it does not contain this since I wanted to do a
quick respin removing the RFC now that the kernel part landed in
net-next.

I'll include it in v2.

Thanks.
Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH net-next 0/3] selftests: openvswitch: Address some flakes in the CI environment

2024-07-05 Thread Adrián Moreno
On Fri, Jul 05, 2024 at 09:49:12AM GMT, Aaron Conole wrote:
> Jakub Kicinski  writes:
>
> > On Tue,  2 Jul 2024 09:28:27 -0400 Aaron Conole wrote:
> >> These patches aim to make using the openvswitch testsuite more reliable.
> >> These should address the major sources of flakiness in the openvswitch
> >> test suite allowing the CI infrastructure to exercise the openvswitch
> >> module for patch series.  There should be no change for users who simply
> >> run the tests (except that patch 3/3 does make some of the debugging a bit
> >> easier by making some output more verbose).
> >
> > Hi Aaron!
> >
> > The results look solid on normal builds now, but with a debug kernel
> > the test is failing consistently:
> >
> > https://netdev.bots.linux.dev/contest.html?executor=vmksft-net-dbg=openvswitch-sh
>
> Yes - it shows a test case issue with the upcall and psample tests.
>
> Adrian and I discussed the correct approach would be using a wait_for
> instead of just sleeping, because it seems the dbg environment might be
> too racy.  I think he is working on a follow up to submit after the
> psample work gets merged - we were hoping not to hold that patch series
> up with more potential conflicts or merge issues if that's okay.
>

Yes. I am working on a patch to solve the failures in slow systems.

Thanks.
Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH net-next v9 00/10] net: openvswitch: Add sample multicasting.

2024-07-05 Thread Adrián Moreno
On Thu, Jul 04, 2024 at 10:56:51AM GMT, Adrian Moreno wrote:
> ** Background **
> Currently, OVS supports several packet sampling mechanisms (sFlow,
> per-bridge IPFIX, per-flow IPFIX). These end up being translated into a
> userspace action that needs to be handled by ovs-vswitchd's handler
> threads only to be forwarded to some third party application that
> will somehow process the sample and provide observability on the
> datapath.
>
> A particularly interesting use-case is controller-driven
> per-flow IPFIX sampling where the OpenFlow controller can add metadata
> to samples (via two 32bit integers) and this metadata is then available
> to the sample-collecting system for correlation.
>
> ** Problem **
> The fact that sampled traffic share netlink sockets and handler thread
> time with upcalls, apart from being a performance bottleneck in the
> sample extraction itself, can severely compromise the datapath,
> yielding this solution unfit for highly loaded production systems.
>
> Users are left with little options other than guessing what sampling
> rate will be OK for their traffic pattern and system load and dealing
> with the lost accuracy.
>
> Looking at available infrastructure, an obvious candidated would be
> to use psample. However, it's current state does not help with the
> use-case at stake because sampled packets do not contain user-defined
> metadata.
>
> ** Proposal **
> This series is an attempt to fix this situation by extending the
> existing psample infrastructure to carry a variable length
> user-defined cookie.
>
> The main existing user of psample is tc's act_sample. It is also
> extended to forward the action's cookie to psample.
>
> Finally, a new OVS action (OVS_SAMPLE_ATTR_PSAMPLE) is created.
> It accepts a group and an optional cookie and uses psample to
> multicast the packet and the metadata.
>
> --
> v8 -> v9:
> - Rebased.
>
> v7 -> v8:
> - Rebased
> - Redirect flow insertion to /dev/null to avoid spat in test.
> - Removed inline keyword in stub execute_psample_action function.
>
> v6 -> v7:
> - Rebased
> - Fixed typo in comment.
>
> v5 -> v6:
> - Renamed emit_sample -> psample
> - Addressed unused variable and conditionally compilation of function.
>
> v4 -> v5:
> - Rebased.
> - Removed lefover enum value and wrapped some long lines in selftests.
>
> v3 -> v4:
> - Rebased.
> - Addressed Jakub's comment on private and unused nla attributes.
>
> v2 -> v3:
> - Addressed comments from Simon, Aaron and Ilya.
> - Dropped probability propagation in nested sample actions.
> - Dropped patch v2's 7/9 in favor of a userspace implementation and
> consume skb if emit_sample is the last action, same as we do with
> userspace.
> - Split ovs-dpctl.py features in independent patches.
>
> v1 -> v2:
> - Create a new action ("emit_sample") rather than reuse existing
>   "sample" one.
> - Add probability semantics to psample's sampling rate.
> - Store sampling probability in skb's cb area and use it in emit_sample.
> - Test combining "emit_sample" with "trunc"
> - Drop group_id filtering and tracepoint in psample.
>
> rfc_v2 -> v1:
> - Accommodate Ilya's comments.
> - Split OVS's attribute in two attributes and simplify internal
> handling of psample arguments.
> - Extend psample and tc with a user-defined cookie.
> - Add a tracepoint to psample to facilitate troubleshooting.
>
> rfc_v1 -> rfc_v2:
> - Use psample instead of a new OVS-only multicast group.
> - Extend psample and tc with a user-defined cookie.
>
> Adrian Moreno (10):
>   net: psample: add user cookie
>   net: sched: act_sample: add action cookie to sample
>   net: psample: skip packet copy if no listeners
>   net: psample: allow using rate as probability
>   net: openvswitch: add psample action
>   net: openvswitch: store sampling probability in cb.
>   selftests: openvswitch: add psample action
>   selftests: openvswitch: add userspace parsing
>   selftests: openvswitch: parse trunc action
>   selftests: openvswitch: add psample test
>
>  Documentation/netlink/specs/ovs_flow.yaml |  17 ++
>  include/net/psample.h |   5 +-
>  include/uapi/linux/openvswitch.h  |  31 +-
>  include/uapi/linux/psample.h  |  11 +-
>  net/openvswitch/Kconfig   |   1 +
>  net/openvswitch/actions.c |  66 -
>  net/openvswitch/datapath.h|   3 +
>  net/openvswitch/flow_netlink.c|  32 ++-
>  net/openvswitch/vport.c   |   1 +
>  net/psample/psample.c |  16 +-
>  net/sched/act_sample.c|  12 +
>  .../selftests/net/openvswitch/openvswitch.sh  | 115 +++-
>  .../selftests/net/openvswitch/ovs-dpctl.py| 272 +-
>  13 files changed, 566 insertions(+), 16 deletions(-)
>
> --
> 2.45.2
>

Hi,

Simon Horman has spotted that openvswitch.sh tests are failing in the
debug executor:

https://netdev.bots.linux.dev/contest.html?test=openvswitch-sh


Re: [ovs-dev] [RFC PATCH v3 00/13] Introduce local sampling with NXAST_SAMPLE action.

2024-07-04 Thread Adrián Moreno
On Thu, Jul 04, 2024 at 09:52:41AM GMT, Adrian Moreno wrote:
> (Was: Add psample support to NXAST_SAMPLE action)
>
> This is the userspace counterpart of the work being done in the kernel
> [1] which is still not merged (hence the RFC state). There, a new
> datapath action is added, called "psample".
>
> From the PoV of ovs-vswitchd, this new action is used to implement
> "local sampling". Local sampling (or lsample for short) is configured
> in a similar way as current per-flow IPFIX sampling, i.e: using the
> Flow_Sample_Collector_Set table and the NXAST_SAMPLE action.
>
> However, instead of sending the sample to an external IPFIX collector
> though the network, the sample is emitted using the new action and
> made available to locally running sample collector.
>
> The specific way emit_sample sends the sample (and the way the local
> collector shall collect it) is datapath-specific.
> Currently, currently only the Linux kernel datapath implements it using
> the psample netlink multicast group.
>
> ~~ Configuration ~~
> Local sampling is configured via a new column in the
> Flow_Sample_Collector_Set (FSCS) table called "local_sample_group".
> Configuring this value is orthogonal to also associating the FSCS
> entry to an entry in the IPFIX table.
>
> Once that entry in the OVSDB is configured, NXAST_SAMPLE actions coming
> from the controller will be translated into the following odp action:
>
>sample(sample={P}%, actions(emit_sample(group={G},cookie={C})))
>
> Where:
> P: Is the sampling probability from NXAST_SAMPLE
> G: Is the group id in the FSCS entry whose "id" matches the one in
> the NXAST_SAMPLE.
> C: Is a 64bit cookie result of concatenating the obs_domain and
> obs_point from the NXAST_SAMPLE in network order, i.e:
> "htonl(obs_domain) << 32 | htonl(obs_point)"
> Notes:
> - The parent sample action might be omitted if the probability is
>   100% and there is no IPFIX sampling that requires the use of a
>   meter.
>
> ~~ Dpif-lsample ~~
> Internally, a new object called "dpif-lsample" is introduced to track
> the configured local sampling exporters and track statistics based on
> odp flow stats (using xcache).
> It exposes the list of configured exporters and their statistics on a
> new unixctl command called "lsample/show".
>

I just realized  I forgot to add a comment explicitly stating that the
above two sections below (which translate to patches 11/13, 12/13 and
13/13) are new in this version of the RFC series.

I know this can be problematic given the late stage we're in so I'll add
a bit os context on why I added them.

> ~~ Drop monitoring ~~
> A common use-case for this action can be to sample drops. However,
> adding sample actions to drops makes the existing drop statistics
> disappear. In order to fix this, patches 11 and 12 make use of explicit
> drop actions to ensure statistics still report drops even if sampled.
>

Drop monitoring and the interaction with local (or even non-local)
sampling has been discussed in the kernel series as I originally tried
to solve the problem in the kernel. After some discussions with Ilya we
agreed to explore the solution to the problem in userspace. That is why
I feel these patches are related to the series.

In any case, IMHO, both patches fix existing bugs: Enabling sampling
(local or not, per-bridge or per-flow) should not hide drop statistics.
One visibility feature should not break an existing one.

> ~~ Extended OpenFlow sample action ~~
> Given the series aims at making sampling production ready, conntrack
> integration must be considered. A common use-case for state-full
> pipelines is to calculate the observation metadata at connection
> establishment, store it in ct_label and then use it for packets of
> established connections. However, this forces OVN to create a big number
> of OFP Flows (one per distinct cookie). Patch 13 solves this by allowing
> controllers to specify the obs_domain and point ids from another OFP
> field.
>

This is an addition that, although discussed informally, did not come
directly from the kernel series but from experimentation and interaction
with the OVN team.

It can be considered a follow-up optimization so if there is controversy
around it, I'm OK postponing it to a future release.

> ~~ Testing ~~
> The series includes an test utility program than can be executed by
> running "tests/ovstest test-psample". This utility listens
> to packets multicasted by the psample module and prints them (also
> printing the obs_domain and obs_point ids).
>
> ~~ HW Offload ~~
> tc offload is not being introduced in this series as existing sample
> or userspace actions are not currently offloadable. Also some
> improvements need to be implemented in tc for it to be feasible.
>
> ~~ DPDK datapath ~~
> By naming the action "psample" it was intentionally restricted to the
> Linux datapath only. A follow up task would be spawned to think of a
> good way of implementing 

Re: [ovs-dev] [PATCH net-next v8 00/10] net: openvswitch: Add sample multicasting.

2024-07-04 Thread Adrián Moreno
On Wed, Jul 03, 2024 at 07:35:19PM GMT, Jakub Kicinski wrote:
> On Tue,  2 Jul 2024 11:53:17 +0200 Adrian Moreno wrote:
> >   selftests: openvswitch: add psample action
> >   selftests: openvswitch: add userspace parsing
> >   selftests: openvswitch: parse trunc action
> >   selftests: openvswitch: add psample test
>
> Sorry for applying things slightly out of order but without Aaron's
> patches we can't check if these work in our CI. Unfortunately, they
> conflict, could you respin one more time?

No problem. I'll respin.

Adrián

> --
> pw-bot: cr
>

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH net-next v7 05/10] net: openvswitch: add psample action

2024-07-02 Thread Adrián Moreno
On Tue, Jul 02, 2024 at 01:33:01PM GMT, Simon Horman wrote:
> On Tue, Jul 02, 2024 at 11:53:01AM +0200, Ilya Maximets wrote:
> > On 7/2/24 11:37, Simon Horman wrote:
> > > On Tue, Jul 02, 2024 at 03:05:02AM -0400, Adrián Moreno wrote:
> > >> On Mon, Jul 01, 2024 at 02:23:12PM GMT, Aaron Conole wrote:
> > >>> Adrian Moreno  writes:
> > >
> > > ...
> > >
> > >>>> diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> > >
> > > ...
> > >
> > >>>> @@ -1299,6 +1304,39 @@ static int execute_dec_ttl(struct sk_buff *skb, 
> > >>>> struct sw_flow_key *key)
> > >>>>return 0;
> > >>>>  }
> > >>>>
> > >>>> +#if IS_ENABLED(CONFIG_PSAMPLE)
> > >>>> +static void execute_psample(struct datapath *dp, struct sk_buff *skb,
> > >>>> +  const struct nlattr *attr)
> > >>>> +{
> > >>>> +  struct psample_group psample_group = {};
> > >>>> +  struct psample_metadata md = {};
> > >>>> +  const struct nlattr *a;
> > >>>> +  int rem;
> > >>>> +
> > >>>> +  nla_for_each_attr(a, nla_data(attr), nla_len(attr), rem) {
> > >>>> +  switch (nla_type(a)) {
> > >>>> +  case OVS_PSAMPLE_ATTR_GROUP:
> > >>>> +  psample_group.group_num = nla_get_u32(a);
> > >>>> +  break;
> > >>>> +
> > >>>> +  case OVS_PSAMPLE_ATTR_COOKIE:
> > >>>> +  md.user_cookie = nla_data(a);
> > >>>> +  md.user_cookie_len = nla_len(a);
> > >>>> +  break;
> > >>>> +  }
> > >>>> +  }
> > >>>> +
> > >>>> +  psample_group.net = ovs_dp_get_net(dp);
> > >>>> +  md.in_ifindex = OVS_CB(skb)->input_vport->dev->ifindex;
> > >>>> +  md.trunc_size = skb->len - OVS_CB(skb)->cutlen;
> > >>>> +
> > >>>> +  psample_sample_packet(_group, skb, 0, );
> > >>>> +}
> > >>>> +#else
> > >>>> +static inline void execute_psample(struct datapath *dp, struct 
> > >>>> sk_buff *skb,
> > >>>> + const struct nlattr *attr) {}
> > >>>
> > >>> I noticed that this got flagged in patchwork since it is 'static inline'
> > >>> while being part of a complete translation unit - but I also see some
> > >>> other places where that has been done.  I guess it should be just
> > >>> 'static' though.  I don't feel very strongly about it.
> > >>>
> > >>
> > >> We had a bit of discussion about this with Ilya. It seems "static
> > >> inline" is a common pattern around the kernel. The coding style
> > >> documentation says:
> > >> "Generally, inline functions are preferable to macros resembling 
> > >> functions."
> > >>
> > >> So I think this "inline" is correct but I might be missing something.
> > >
> > > Hi Adrián,
> > >
> > > TL;DR: Please remove this inline keyword
> > >
> > > For Kernel networking code at least it is strongly preferred not
> > > to use inline in .c files unless there is a demonstrable - usually
> > > performance - reason to do so. Rather, it is preferred to let the
> > > compiler decide when to inline such functions. OTOH, the inline
> > > keyword in .h files is fine.
> >
> > FWIW, the main reason for 'inline' here is not performance, but silencing
> > compiler's potential 'maybe unused' warnings:
> >
> >  Function-like macros with unused parameters should be replaced by static
> >  inline functions to avoid the issue of unused variables
> >
> > I think, the rule for static inline functions in .c files is at odds with
> > the 'Conditional Compilation' section of coding style.  The section does
> > recommend to avoid conditional function declaration in .c files, but I'm not
> > sure it is reasonable to export internal static functions for that reason.
> >
> > In this particular case we can either define a macro, which is discouraged
> > by the coding style:
> >
> >  Generally, inline functions are preferable to macros resembling functions.
> >
> > Or create a static inline function, that is against rule of no static
> > inline functions in .c files.
> >
> > Or create a simple static function and mark all the arguments as unused,
> > which kind of compliant to the coding style, but the least pretty.
>
> Hi Ilya,
>
> I guess I would lean towards the last option.
> But in any case, thanks for pointing out that this is complex:
> I had not realised that when I wrote my previous email.
>

In that case this version (v7) should be good to go? Are there any other
comments? Or is v8 preferred (the only change is between them is
dropping the "inline")?

Thanks.
Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH net-next v7 05/10] net: openvswitch: add psample action

2024-07-02 Thread Adrián Moreno
On Tue, Jul 02, 2024 at 10:37:26AM GMT, Simon Horman wrote:
> On Tue, Jul 02, 2024 at 03:05:02AM -0400, Adrián Moreno wrote:
> > On Mon, Jul 01, 2024 at 02:23:12PM GMT, Aaron Conole wrote:
> > > Adrian Moreno  writes:
>
> ...
>
> > > > diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
>
> ...
>
> > > > @@ -1299,6 +1304,39 @@ static int execute_dec_ttl(struct sk_buff *skb, 
> > > > struct sw_flow_key *key)
> > > > return 0;
> > > >  }
> > > >
> > > > +#if IS_ENABLED(CONFIG_PSAMPLE)
> > > > +static void execute_psample(struct datapath *dp, struct sk_buff *skb,
> > > > +   const struct nlattr *attr)
> > > > +{
> > > > +   struct psample_group psample_group = {};
> > > > +   struct psample_metadata md = {};
> > > > +   const struct nlattr *a;
> > > > +   int rem;
> > > > +
> > > > +   nla_for_each_attr(a, nla_data(attr), nla_len(attr), rem) {
> > > > +   switch (nla_type(a)) {
> > > > +   case OVS_PSAMPLE_ATTR_GROUP:
> > > > +   psample_group.group_num = nla_get_u32(a);
> > > > +   break;
> > > > +
> > > > +   case OVS_PSAMPLE_ATTR_COOKIE:
> > > > +   md.user_cookie = nla_data(a);
> > > > +   md.user_cookie_len = nla_len(a);
> > > > +   break;
> > > > +   }
> > > > +   }
> > > > +
> > > > +   psample_group.net = ovs_dp_get_net(dp);
> > > > +   md.in_ifindex = OVS_CB(skb)->input_vport->dev->ifindex;
> > > > +   md.trunc_size = skb->len - OVS_CB(skb)->cutlen;
> > > > +
> > > > +   psample_sample_packet(_group, skb, 0, );
> > > > +}
> > > > +#else
> > > > +static inline void execute_psample(struct datapath *dp, struct sk_buff 
> > > > *skb,
> > > > +  const struct nlattr *attr) {}
> > >
> > > I noticed that this got flagged in patchwork since it is 'static inline'
> > > while being part of a complete translation unit - but I also see some
> > > other places where that has been done.  I guess it should be just
> > > 'static' though.  I don't feel very strongly about it.
> > >
> >
> > We had a bit of discussion about this with Ilya. It seems "static
> > inline" is a common pattern around the kernel. The coding style
> > documentation says:
> > "Generally, inline functions are preferable to macros resembling functions."
> >
> > So I think this "inline" is correct but I might be missing something.
>
> Hi Adrián,
>
> TL;DR: Please remove this inline keyword
>
> For Kernel networking code at least it is strongly preferred not
> to use inline in .c files unless there is a demonstrable - usually
> performance - reason to do so. Rather, it is preferred to let the
> compiler decide when to inline such functions. OTOH, the inline
> keyword in .h files is fine.
>

Ok. I'll send a new version.

Thanks.
Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH net-next v7 05/10] net: openvswitch: add psample action

2024-07-02 Thread Adrián Moreno
On Tue, Jul 02, 2024 at 03:05:02AM GMT, Adrián Moreno wrote:
> On Mon, Jul 01, 2024 at 02:23:12PM GMT, Aaron Conole wrote:
> > Adrian Moreno  writes:
> >
> > > Add support for a new action: psample.
> > >
> > > This action accepts a u32 group id and a variable-length cookie and uses
> > > the psample multicast group to make the packet available for
> > > observability.
> > >
> > > The maximum length of the user-defined cookie is set to 16, same as
> > > tc_cookie, to discourage using cookies that will not be offloadable.
> > >
> > > Acked-by: Eelco Chaudron 
> > > Signed-off-by: Adrian Moreno 
> > > ---
> >
> > Hi Adrian,
> >
> > Just some nits below.
> >
> > >  Documentation/netlink/specs/ovs_flow.yaml | 17 
> > >  include/uapi/linux/openvswitch.h  | 28 ++
> > >  net/openvswitch/Kconfig   |  1 +
> > >  net/openvswitch/actions.c | 47 +++
> > >  net/openvswitch/flow_netlink.c| 32 ++-
> > >  5 files changed, 124 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/Documentation/netlink/specs/ovs_flow.yaml 
> > > b/Documentation/netlink/specs/ovs_flow.yaml
> > > index 4fdfc6b5cae9..46f5d1cd8a5f 100644
> > > --- a/Documentation/netlink/specs/ovs_flow.yaml
> > > +++ b/Documentation/netlink/specs/ovs_flow.yaml
> > > @@ -727,6 +727,12 @@ attribute-sets:
> > >  name: dec-ttl
> > >  type: nest
> > >  nested-attributes: dec-ttl-attrs
> > > +  -
> > > +name: psample
> > > +type: nest
> > > +nested-attributes: psample-attrs
> > > +doc: |
> > > +  Sends a packet sample to psample for external observation.
> > >-
> > >  name: tunnel-key-attrs
> > >  enum-name: ovs-tunnel-key-attr
> > > @@ -938,6 +944,17 @@ attribute-sets:
> > >-
> > >  name: gbp
> > >  type: u32
> > > +  -
> > > +name: psample-attrs
> > > +enum-name: ovs-psample-attr
> > > +name-prefix: ovs-psample-attr-
> > > +attributes:
> > > +  -
> > > +name: group
> > > +type: u32
> > > +  -
> > > +name: cookie
> > > +type: binary
> > >
> > >  operations:
> > >name-prefix: ovs-flow-cmd-
> > > diff --git a/include/uapi/linux/openvswitch.h 
> > > b/include/uapi/linux/openvswitch.h
> > > index efc82c318fa2..3dd653748725 100644
> > > --- a/include/uapi/linux/openvswitch.h
> > > +++ b/include/uapi/linux/openvswitch.h
> > > @@ -914,6 +914,31 @@ struct check_pkt_len_arg {
> > >  };
> > >  #endif
> > >
> > > +#define OVS_PSAMPLE_COOKIE_MAX_SIZE 16
> > > +/**
> > > + * enum ovs_psample_attr - Attributes for %OVS_ACTION_ATTR_PSAMPLE
> > > + * action.
> > > + *
> > > + * @OVS_PSAMPLE_ATTR_GROUP: 32-bit number to identify the source of the
> > > + * sample.
> > > + * @OVS_PSAMPLE_ATTR_COOKIE: An optional variable-length binary cookie 
> > > that
> > > + * contains user-defined metadata. The maximum length is
> > > + * OVS_PSAMPLE_COOKIE_MAX_SIZE bytes.
> > > + *
> > > + * Sends the packet to the psample multicast group with the specified 
> > > group and
> > > + * cookie. It is possible to combine this action with the
> > > + * %OVS_ACTION_ATTR_TRUNC action to limit the size of the sample.
> > > + */
> > > +enum ovs_psample_attr {
> > > + OVS_PSAMPLE_ATTR_GROUP = 1, /* u32 number. */
> > > + OVS_PSAMPLE_ATTR_COOKIE,/* Optional, user specified cookie. */
> > > +
> > > + /* private: */
> > > + __OVS_PSAMPLE_ATTR_MAX
> > > +};
> > > +
> > > +#define OVS_PSAMPLE_ATTR_MAX (__OVS_PSAMPLE_ATTR_MAX - 1)
> > > +
> > >  /**
> > >   * enum ovs_action_attr - Action types.
> > >   *
> > > @@ -966,6 +991,8 @@ struct check_pkt_len_arg {
> > >   * of l3 tunnel flag in the tun_flags field of OVS_ACTION_ATTR_ADD_MPLS
> > >   * argument.
> > >   * @OVS_ACTION_ATTR_DROP: Explicit drop action.
> > > + * @OVS_ACTION_ATTR_PSAMPLE: Send a sample of the packet to external 
> > > observers
> > > + * via psample.
> > >   *
> > >   * Only a single header can be set wi

Re: [ovs-dev] [PATCH net-next v7 10/10] selftests: openvswitch: add psample test

2024-07-02 Thread Adrián Moreno
On Mon, Jul 01, 2024 at 02:38:44PM GMT, Aaron Conole wrote:
> Adrian Moreno  writes:
>
> > Add a test to verify sampling packets via psample works.
> >
> > In order to do that, create a subcommand in ovs-dpctl.py to listen to
> > on the psample multicast group and print samples.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  .../selftests/net/openvswitch/openvswitch.sh  | 115 +-
> >  .../selftests/net/openvswitch/ovs-dpctl.py|  73 ++-
> >  2 files changed, 182 insertions(+), 6 deletions(-)
> >
> > diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh 
> > b/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > index 15bca0708717..02a366e01004 100755
> > --- a/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > +++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > @@ -20,7 +20,8 @@ tests="
> > nat_related_v4  ip4-nat-related: ICMP related 
> > matches work with SNAT
> > netlink_checks  ovsnl: validate netlink attrs 
> > and settings
> > upcall_interfaces   ovs: test the upcall interfaces
> > -   drop_reason drop: test drop reasons are 
> > emitted"
> > +   drop_reason drop: test drop reasons are 
> > emitted
> > +   psample psample: Sampling packets with 
> > psample"
> >
> >  info() {
> >  [ $VERBOSE = 0 ] || echo $*
> > @@ -102,12 +103,21 @@ ovs_netns_spawn_daemon() {
> > shift
> > netns=$1
> > shift
> > -   info "spawning cmd: $*"
> > -   ip netns exec $netns $*  >> $ovs_dir/stdout  2>> $ovs_dir/stderr &
> > +   if [ "$netns" == "_default" ]; then
> > +   $*  >> $ovs_dir/stdout  2>> $ovs_dir/stderr &
> > +   else
> > +   ip netns exec $netns $*  >> $ovs_dir/stdout  2>> 
> > $ovs_dir/stderr &
> > +   fi
> > pid=$!
> > ovs_sbx "$sbx" on_exit "kill -TERM $pid 2>/dev/null"
> >  }
> >
> > +ovs_spawn_daemon() {
> > +   sbx=$1
> > +   shift
> > +   ovs_netns_spawn_daemon $sbx "_default" $*
> > +}
> > +
> >  ovs_add_netns_and_veths () {
> > info "Adding netns attached: sbx:$1 dp:$2 {$3, $4, $5}"
> > ovs_sbx "$1" ip netns add "$3" || return 1
> > @@ -170,6 +180,19 @@ ovs_drop_reason_count()
> > return `echo "$perf_output" | grep "$pattern" | wc -l`
> >  }
> >
> > +ovs_test_flow_fails () {
> > +   ERR_MSG="Flow actions may not be safe on all matching packets"
> > +
> > +   PRE_TEST=$(dmesg | grep -c "${ERR_MSG}")
> > +   ovs_add_flow $@ &> /dev/null $@ && return 1
> > +   POST_TEST=$(dmesg | grep -c "${ERR_MSG}")
> > +
> > +   if [ "$PRE_TEST" == "$POST_TEST" ]; then
> > +   return 1
> > +   fi
> > +   return 0
> > +}
> > +
> >  usage() {
> > echo
> > echo "$0 [OPTIONS] [TEST]..."
> > @@ -184,6 +207,92 @@ usage() {
> > exit 1
> >  }
> >
> > +
> > +# psample test
> > +# - use psample to observe packets
> > +test_psample() {
> > +   sbx_add "test_psample" || return $?
> > +
> > +   # Add a datapath with per-vport dispatching.
> > +   ovs_add_dp "test_psample" psample -V 2:1 || return 1
> > +
> > +   info "create namespaces"
> > +   ovs_add_netns_and_veths "test_psample" "psample" \
> > +   client c0 c1 172.31.110.10/24 -u || return 1
> > +   ovs_add_netns_and_veths "test_psample" "psample" \
> > +   server s0 s1 172.31.110.20/24 -u || return 1
> > +
> > +   # Check if psample actions can be configured.
> > +   ovs_add_flow "test_psample" psample \
> > +   'in_port(1),eth(),eth_type(0x0806),arp()' 'psample(group=1)'
>
> Might be good to redirect this stdout/stderr line to /dev/null -
> otherwise on an unsupported system there will be the following extra
> splat:
>
>   Traceback (most recent call last):
> File 
> "/home/aconole/git/linux/tools/testing/selftests/net/openvswitch/ovs-dpctl.py",
>  line 2774, in 
>   sys.exit(main(sys.argv))
>...
> File "/usr/lib/python3.12/site-packages/pyroute2/netlink/nlsocket.py", 
> line 489, in get
>   raise msg['header']['error']
>   pyroute2.netlink.exceptions.NetlinkError: (22, 'Invalid argument')
>

I thought knowing the return value was kind of useful but sure, we can
redirect it to /dev/null.

> > +   if [ $? == 1 ]; then
> > +   info "no support for psample - skipping"
> > +   ovs_exit_sig
> > +   return $ksft_skip
> > +   fi
> > +
> > +   ovs_del_flows "test_psample" psample
> > +
> > +   # Test action verification.
> > +   OLDIFS=$IFS
> > +   IFS='*'
> > +   min_key='in_port(1),eth(),eth_type(0x0800),ipv4()'
> > +   for testcase in \
> > +   "cookie to 
> > large"*"psample(group=1,cookie=1615141312111009080706050403020100)" \
> > +   "no group with cookie"*"psample(cookie=abcd)" \
> > +   "no group"*"psample()";
> > +   do
> > +   set -- $testcase;
> > +   ovs_test_flow_fails "test_psample" psample $min_key $2
> > +   if [ $? == 1 ]; then
> > +   

Re: [ovs-dev] [PATCH net-next v7 05/10] net: openvswitch: add psample action

2024-07-02 Thread Adrián Moreno
On Mon, Jul 01, 2024 at 02:23:12PM GMT, Aaron Conole wrote:
> Adrian Moreno  writes:
>
> > Add support for a new action: psample.
> >
> > This action accepts a u32 group id and a variable-length cookie and uses
> > the psample multicast group to make the packet available for
> > observability.
> >
> > The maximum length of the user-defined cookie is set to 16, same as
> > tc_cookie, to discourage using cookies that will not be offloadable.
> >
> > Acked-by: Eelco Chaudron 
> > Signed-off-by: Adrian Moreno 
> > ---
>
> Hi Adrian,
>
> Just some nits below.
>
> >  Documentation/netlink/specs/ovs_flow.yaml | 17 
> >  include/uapi/linux/openvswitch.h  | 28 ++
> >  net/openvswitch/Kconfig   |  1 +
> >  net/openvswitch/actions.c | 47 +++
> >  net/openvswitch/flow_netlink.c| 32 ++-
> >  5 files changed, 124 insertions(+), 1 deletion(-)
> >
> > diff --git a/Documentation/netlink/specs/ovs_flow.yaml 
> > b/Documentation/netlink/specs/ovs_flow.yaml
> > index 4fdfc6b5cae9..46f5d1cd8a5f 100644
> > --- a/Documentation/netlink/specs/ovs_flow.yaml
> > +++ b/Documentation/netlink/specs/ovs_flow.yaml
> > @@ -727,6 +727,12 @@ attribute-sets:
> >  name: dec-ttl
> >  type: nest
> >  nested-attributes: dec-ttl-attrs
> > +  -
> > +name: psample
> > +type: nest
> > +nested-attributes: psample-attrs
> > +doc: |
> > +  Sends a packet sample to psample for external observation.
> >-
> >  name: tunnel-key-attrs
> >  enum-name: ovs-tunnel-key-attr
> > @@ -938,6 +944,17 @@ attribute-sets:
> >-
> >  name: gbp
> >  type: u32
> > +  -
> > +name: psample-attrs
> > +enum-name: ovs-psample-attr
> > +name-prefix: ovs-psample-attr-
> > +attributes:
> > +  -
> > +name: group
> > +type: u32
> > +  -
> > +name: cookie
> > +type: binary
> >
> >  operations:
> >name-prefix: ovs-flow-cmd-
> > diff --git a/include/uapi/linux/openvswitch.h 
> > b/include/uapi/linux/openvswitch.h
> > index efc82c318fa2..3dd653748725 100644
> > --- a/include/uapi/linux/openvswitch.h
> > +++ b/include/uapi/linux/openvswitch.h
> > @@ -914,6 +914,31 @@ struct check_pkt_len_arg {
> >  };
> >  #endif
> >
> > +#define OVS_PSAMPLE_COOKIE_MAX_SIZE 16
> > +/**
> > + * enum ovs_psample_attr - Attributes for %OVS_ACTION_ATTR_PSAMPLE
> > + * action.
> > + *
> > + * @OVS_PSAMPLE_ATTR_GROUP: 32-bit number to identify the source of the
> > + * sample.
> > + * @OVS_PSAMPLE_ATTR_COOKIE: An optional variable-length binary cookie that
> > + * contains user-defined metadata. The maximum length is
> > + * OVS_PSAMPLE_COOKIE_MAX_SIZE bytes.
> > + *
> > + * Sends the packet to the psample multicast group with the specified 
> > group and
> > + * cookie. It is possible to combine this action with the
> > + * %OVS_ACTION_ATTR_TRUNC action to limit the size of the sample.
> > + */
> > +enum ovs_psample_attr {
> > +   OVS_PSAMPLE_ATTR_GROUP = 1, /* u32 number. */
> > +   OVS_PSAMPLE_ATTR_COOKIE,/* Optional, user specified cookie. */
> > +
> > +   /* private: */
> > +   __OVS_PSAMPLE_ATTR_MAX
> > +};
> > +
> > +#define OVS_PSAMPLE_ATTR_MAX (__OVS_PSAMPLE_ATTR_MAX - 1)
> > +
> >  /**
> >   * enum ovs_action_attr - Action types.
> >   *
> > @@ -966,6 +991,8 @@ struct check_pkt_len_arg {
> >   * of l3 tunnel flag in the tun_flags field of OVS_ACTION_ATTR_ADD_MPLS
> >   * argument.
> >   * @OVS_ACTION_ATTR_DROP: Explicit drop action.
> > + * @OVS_ACTION_ATTR_PSAMPLE: Send a sample of the packet to external 
> > observers
> > + * via psample.
> >   *
> >   * Only a single header can be set with a single %OVS_ACTION_ATTR_SET.  
> > Not all
> >   * fields within a header are modifiable, e.g. the IPv4 protocol and 
> > fragment
> > @@ -1004,6 +1031,7 @@ enum ovs_action_attr {
> > OVS_ACTION_ATTR_ADD_MPLS, /* struct ovs_action_add_mpls. */
> > OVS_ACTION_ATTR_DEC_TTL,  /* Nested OVS_DEC_TTL_ATTR_*. */
> > OVS_ACTION_ATTR_DROP, /* u32 error code. */
> > +   OVS_ACTION_ATTR_PSAMPLE,  /* Nested OVS_PSAMPLE_ATTR_*. */
> >
> > __OVS_ACTION_ATTR_MAX,/* Nothing past this will be accepted
> >* from userspace. */
> > diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig
> > index 29a7081858cd..2535f3f9f462 100644
> > --- a/net/openvswitch/Kconfig
> > +++ b/net/openvswitch/Kconfig
> > @@ -10,6 +10,7 @@ config OPENVSWITCH
> >(NF_CONNTRACK && ((!NF_DEFRAG_IPV6 || NF_DEFRAG_IPV6) && \
> >  (!NF_NAT || NF_NAT) && \
> >  (!NETFILTER_CONNCOUNT || 
> > NETFILTER_CONNCOUNT)))
> > +   depends on PSAMPLE || !PSAMPLE
> > select LIBCRC32C
> > select MPLS
> > select NET_MPLS_GSO
> > diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> > index 

Re: [ovs-dev] [PATCH net-next v7 05/10] net: openvswitch: add psample action

2024-07-01 Thread Adrián Moreno
On Mon, Jul 01, 2024 at 01:40:39PM GMT, Michal Kubiak wrote:
> On Sun, Jun 30, 2024 at 09:57:26PM +0200, Adrian Moreno wrote:
> > Add support for a new action: psample.
> >
> > This action accepts a u32 group id and a variable-length cookie and uses
> > the psample multicast group to make the packet available for
> > observability.
> >
> > The maximum length of the user-defined cookie is set to 16, same as
> > tc_cookie, to discourage using cookies that will not be offloadable.
> >
> > Acked-by: Eelco Chaudron 
> > Signed-off-by: Adrian Moreno 
> > ---
> >  Documentation/netlink/specs/ovs_flow.yaml | 17 
> >  include/uapi/linux/openvswitch.h  | 28 ++
> >  net/openvswitch/Kconfig   |  1 +
> >  net/openvswitch/actions.c | 47 +++
> >  net/openvswitch/flow_netlink.c| 32 ++-
> >  5 files changed, 124 insertions(+), 1 deletion(-)
> >
> > diff --git a/Documentation/netlink/specs/ovs_flow.yaml 
> > b/Documentation/netlink/specs/ovs_flow.yaml
> > index 4fdfc6b5cae9..46f5d1cd8a5f 100644
> > --- a/Documentation/netlink/specs/ovs_flow.yaml
> > +++ b/Documentation/netlink/specs/ovs_flow.yaml
> > @@ -727,6 +727,12 @@ attribute-sets:
> >  name: dec-ttl
> >  type: nest
> >  nested-attributes: dec-ttl-attrs
> > +  -
> > +name: psample
> > +type: nest
> > +nested-attributes: psample-attrs
> > +doc: |
> > +  Sends a packet sample to psample for external observation.
> >-
> >  name: tunnel-key-attrs
> >  enum-name: ovs-tunnel-key-attr
> > @@ -938,6 +944,17 @@ attribute-sets:
> >-
> >  name: gbp
> >  type: u32
> > +  -
> > +name: psample-attrs
> > +enum-name: ovs-psample-attr
> > +name-prefix: ovs-psample-attr-
> > +attributes:
> > +  -
> > +name: group
> > +type: u32
> > +  -
> > +name: cookie
> > +type: binary
> >
> >  operations:
> >name-prefix: ovs-flow-cmd-
> > diff --git a/include/uapi/linux/openvswitch.h 
> > b/include/uapi/linux/openvswitch.h
> > index efc82c318fa2..3dd653748725 100644
> > --- a/include/uapi/linux/openvswitch.h
> > +++ b/include/uapi/linux/openvswitch.h
> > @@ -914,6 +914,31 @@ struct check_pkt_len_arg {
> >  };
> >  #endif
> >
> > +#define OVS_PSAMPLE_COOKIE_MAX_SIZE 16
>
> In your patch #2 you use "TC_COOKIE_MAX_SIZE" as an array size for your
> cookie. I know that now OVS_PSAMPLE_COOKIE_MAX_SIZE == TC_COOKIE_MAX_SIZE,
> so this size will be validated correctly.
> But how likely is that those 2 constants will have different values in the
> future?
> Would it be reasonable to create more strict dependency between those
> macros, e.g.:
>
> #define OVS_PSAMPLE_COOKIE_MAX_SIZE TC_COOKIE_MAX_SIZE
>
> or, at least, add a comment that the size shouldn't be bigger than
> TC_COOKIE_MAX_SIZE?
> I'm just considering the risk of exceeding the array from the patch #2 when
> somebody increases OVS_PSAMPLE_COOKIE_MAX_SIZE in the future.
>
> Thanks,
> Michal
>

Hi Michal,

Thanks for sharing your thoughts.

I tried to keep the dependency between both cookie sizes loose.

I don't want a change in TC_COOKIE_MAX_SIZE to inadvertently modify
OVS_PSAMPLE_COOKIE_MAX_SIZE because OVS might not need a bigger cookie
and even if it does, backwards compatibility needs to be guaranteed:
meaning OVS userspace will have to detect the new size and use it or
fall back to a smaller cookie for older kernels. All this needs to be
known and worked on in userspace.

On the other hand, I intentionally made OVS's "psample" action as
similar as possible to act_psample, including setting the same cookie
size to begin with. The reason is that I think we should try to implement
tc-flower offloading of this action using act_sample, plus 16 seemed a
very reasonable max value.

When we decide to support offloading the "psample" action, this must
be done entirely in userspace. OVS must create a act_sample action
(instead of the OVS "psample" one) via netlink. In no circumstances the
openvswitch kmod interacts with tc directly.

Now, back to your concern. If OVS_PSAMPLE_COOKIE_MAX_SIZE grows and
TC_COOKIE_MAX_SIZE does not *and* we already support offloading this
action to tc, the only consequence is that OVS userspace has a
problem because the tc's netlink interface will reject cookies larger
than TC_COOKIE_MAX_SIZE [1].
This guarantees that the array in patch #2 is never overflown.

OVS will have to deal with the different sizes and try to squeeze the
data into TC_COOKIE_MAX_SIZE or fail to offload the action altogether.

Psample does not have a size limit so different parts of the kernel can
use psample with different internal max-sizes without any restriction.

I hope this clears your concerns.

[1] https://github.com/torvalds/linux/blob/master/net/sched/act_api.c#L1299

Thanks.
Adrián

___
dev mailing list
d...@openvswitch.org

Re: [ovs-dev] [RFC v2 5/9] ofproto-dpif-xlate: Use emit_sample for local sample.

2024-07-01 Thread Adrián Moreno
On Mon, Jul 01, 2024 at 01:30:12PM GMT, Eelco Chaudron wrote:
>
>
> On 28 Jun 2024, at 18:40, Adrián Moreno wrote:
>
> > On Wed, Jun 26, 2024 at 02:11:51PM GMT, Eelco Chaudron wrote:
> >> On 5 Jun 2024, at 22:23, Adrian Moreno wrote:
> >>
> >>> Use the newly added emit_sample to implement OpenFlow sample() actions
> >>> with local sampling configuration.
> >>
> >> See some comments below.
> >>
> >> Cheers,
> >>
> >> Eelco
> >>
> >>> Signed-off-by: Adrian Moreno 
> >>> ---
> >>>  ofproto/ofproto-dpif-lsample.c |  17 
> >>>  ofproto/ofproto-dpif-lsample.h |   6 ++
> >>>  ofproto/ofproto-dpif-xlate.c   | 163 -
> >>>  ofproto/ofproto-dpif-xlate.h   |   3 +-
> >>>  ofproto/ofproto-dpif.c |   2 +-
> >>>  5 files changed, 144 insertions(+), 47 deletions(-)
> >>>
> >>> diff --git a/ofproto/ofproto-dpif-lsample.c 
> >>> b/ofproto/ofproto-dpif-lsample.c
> >>> index 7bdafac19..2c0b5da89 100644
> >>> --- a/ofproto/ofproto-dpif-lsample.c
> >>> +++ b/ofproto/ofproto-dpif-lsample.c
> >>> @@ -139,6 +139,23 @@ dpif_lsample_set_options(struct dpif_lsample 
> >>> *lsample,
> >>>  return changed;
> >>>  }
> >>>
> >>> +/* Returns the group_id of the exporter with the given collector_set_id, 
> >>> if it
> >>> + * exists. */
> >>
> >> nit: The below will fit on one line
> >>
> >> /* Returns the exporter group_id for a given collector_set_id, if it 
> >> exists. */
> >>
> >
> > Ack.
> >
> >>> +bool
> >>> +dpif_lsample_get_group_id(struct dpif_lsample *ps, uint32_t 
> >>> collector_set_id,
> >>> +  uint32_t *group_id)
> >>> +{
> >>> +struct lsample_exporter_node *node;
> >>> +bool found = false;
> >>> +
> >>> +node = dpif_lsample_find_exporter_node(ps, collector_set_id);
> >>> +if (node) {
> >>> +found = true;
> >>> +*group_id = node->exporter.options.group_id;
> >>> +}
> >>> +return found;
> >>> +}
> >>> +
> >>>  struct dpif_lsample *
> >>>  dpif_lsample_create(void)
> >>>  {
> >>> diff --git a/ofproto/ofproto-dpif-lsample.h 
> >>> b/ofproto/ofproto-dpif-lsample.h
> >>> index c23ea8372..f13425575 100644
> >>> --- a/ofproto/ofproto-dpif-lsample.h
> >>> +++ b/ofproto/ofproto-dpif-lsample.h
> >>> @@ -19,6 +19,7 @@
> >>>
> >>>  #include 
> >>>  #include 
> >>> +#include 
> >>
> >> Maybe add in alphabetical order.
> >>
> >
> > Ack.
> >
> >>>  struct dpif_lsample;
> >>>  struct ofproto_lsample_options;
> >>> @@ -31,4 +32,9 @@ bool dpif_lsample_set_options(struct dpif_lsample *,
> >>>const struct ofproto_lsample_options *,
> >>>size_t n_opts);
> >>>
> >>> +bool dpif_lsample_get_group_id(struct dpif_lsample *,
> >>> +   uint32_t collector_set_id,
> >>> +   uint32_t *group_id);
> >>> +
> >>>  #endif /* OFPROTO_DPIF_LSAMPLE_H */
> >>> +
> >>
> >> Accedantely added a newline?
> >>
> >
> > Ack.
> >
> >>> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> >>> index 7c4950895..5bd215d31 100644
> >>> --- a/ofproto/ofproto-dpif-xlate.c
> >>> +++ b/ofproto/ofproto-dpif-xlate.c
> >>> @@ -47,6 +47,7 @@
> >>>  #include "ofproto/ofproto-dpif-ipfix.h"
> >>>  #include "ofproto/ofproto-dpif-mirror.h"
> >>>  #include "ofproto/ofproto-dpif-monitor.h"
> >>> +#include "ofproto/ofproto-dpif-lsample.h"
> >>>  #include "ofproto/ofproto-dpif-sflow.h"
> >>>  #include "ofproto/ofproto-dpif-trace.h"
> >>>  #include "ofproto/ofproto-dpif-xlate-cache.h"
> >>> @@ -117,6 +118,7 @@ struct xbridge {
> >>>  struct dpif_sflow *sflow; /* SFlow handle, or null. */
> >>>  struct dpif_ipfix *ipfix; /* Ipfix handle, or null.

Re: [ovs-dev] [RFC v2 9/9] tests: Test local sampling.

2024-07-01 Thread Adrián Moreno
On Mon, Jul 01, 2024 at 01:33:23PM GMT, Eelco Chaudron wrote:
>
>
> On 28 Jun 2024, at 16:11, Adrián Moreno wrote:
>
> > On Wed, Jun 26, 2024 at 02:15:02PM GMT, Eelco Chaudron wrote:
> >> On 5 Jun 2024, at 22:23, Adrian Moreno wrote:
> >>
> >>> Test simultaneous IPFIX and local sampling including slow-path.
> >>
> >> I guess Ilya's comments on this patch summarize most of my comments. I had
> >> one small additional question. See below.
> >>
> >> //Eelco
> >>
> >>> Signed-off-by: Adrian Moreno 
> >>> ---
> >>>  tests/system-common-macros.at |   4 ++
> >>>  tests/system-traffic.at   | 105 ++
> >>>  2 files changed, 109 insertions(+)
> >>>
> >>> diff --git a/tests/system-common-macros.at b/tests/system-common-macros.at
> >>> index 2a68cd664..22b8885e4 100644
> >>> --- a/tests/system-common-macros.at
> >>> +++ b/tests/system-common-macros.at
> >>> @@ -378,3 +378,7 @@ m4_define([OVS_CHECK_GITHUB_ACTION],
> >>>  # OVS_CHECK_DROP_ACTION()
> >>>  m4_define([OVS_CHECK_DROP_ACTION],
> >>>  [AT_SKIP_IF([! grep -q "Datapath supports explicit drop action" 
> >>> ovs-vswitchd.log])])
> >>> +
> >>> +# OVS_CHECK_EMIT_SAMPLE()
> >>> +m4_define([OVS_CHECK_EMIT_SAMPLE],
> >>> +[AT_SKIP_IF([! grep -q "Datapath supports emit_sample" 
> >>> ovs-vswitchd.log])])
> >>> diff --git a/tests/system-traffic.at b/tests/system-traffic.at
> >>> index bd7647cbe..babc56b56 100644
> >>> --- a/tests/system-traffic.at
> >>> +++ b/tests/system-traffic.at
> >>> @@ -8977,3 +8977,108 @@ OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0050: 
> >>> * * *5002 *2000 *b85e *00
> >>>
> >>>  OVS_TRAFFIC_VSWITCHD_STOP
> >>>  AT_CLEANUP
> >>> +
> >>> +AT_SETUP([emit_sample])
> >>> +OVS_TRAFFIC_VSWITCHD_START()
> >>> +OVS_CHECK_EMIT_SAMPLE()
> >>> +
> >>> +ADD_NAMESPACES(at_ns0, at_ns1)
> >>> +NS_CHECK_EXEC([at_ns0], [sysctl -w net.ipv6.conf.all.disable_ipv6=1], 
> >>> [0], [ignore])
> >>> +NS_CHECK_EXEC([at_ns1], [sysctl -w net.ipv6.conf.all.disable_ipv6=1], 
> >>> [0], [ignore])
> >>> +
> >>> +ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24", "e4:11:22:33:44:55")
> >>> +ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24", "e4:11:22:33:44:66")
> >>> +
> >>> +NS_CHECK_EXEC([at_ns0], [arp -s 10.1.1.2 e4:11:22:33:44:66])
> >>> +NS_CHECK_EXEC([at_ns1], [arp -s 10.1.1.1 e4:11:22:33:44:55])
> >>> +
> >>> +
> >>> +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg 
> >>> ofproto_dpif_upcall:dbg])
> >>> +
> >>> +AT_CHECK([ovs-vsctl -- --id=@br0 get Bridge br0 \
> >>> +-- --id=@ipfix create IPFIX 
> >>> targets=\"127.0.0.1:4739\" \
> >>> +-- create Flow_Sample_Collector_Set id=1 bridge=@br0 
> >>> ipfix=@ipfix, local_sample_group=10 \
> >>> +-- create Flow_Sample_Collector_Set id=2 bridge=@br0 
> >>> ipfix=@ipfix, local_sample_group=12],
> >>> + [0], [ignore])
> >>> +
> >>> +AT_DATA([flows.txt], [dnl
> >>> +in_port=ovs-p0,ip 
> >>> actions=sample(probability=65535,collector_set_id=1,obs_domain_id=1431655765,obs_point_id=1717986918),output(port=ovs-p1,max_len=100)
> >>> +in_port=ovs-p1,ip 
> >>> actions=sample(probability=65535,collector_set_id=2,obs_domain_id=2290649224,obs_point_id=2576980377),output(port=ovs-p0,max_len=100)
> >>> +])
> >>> +
> >>> +AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
> >>> +
> >>> +OVS_DAEMONIZE([ovstest test-psample > psample.out], [psample1.pid])
> >>> +
> >>> +NS_CHECK_EXEC([at_ns0], [ping -q -c 1 10.1.1.2 | FORMAT_PING], [0], [dnl
> >>> +1 packets transmitted, 1 received, 0% packet loss, time 0ms
> >>> +])
> >>> +
> >>> +m4_define([SAMPLE1], [group_id=0xa 
> >>> obs_domain=0x,obs_point=0x 
> >>> .*icmp.*nw_src=10.1.1.1,nw_dst=10.1.1.2])
> >>> +m4_define([SAMPLE2], [group_id=0xc 
> >>> obs_domain=0x,obs_point=0x 
> >>> .*icmp.*nw_src=10.1.1.2,nw_dst=10.1.1.1])
> >&g

Re: [ovs-dev] [PATCH net-next v6 00/10] net: openvswitch: Add sample multicasting.

2024-06-28 Thread Adrián Moreno
On Fri, Jun 28, 2024 at 01:05:36PM GMT, Adrian Moreno wrote:
> ** Background **
> Currently, OVS supports several packet sampling mechanisms (sFlow,
> per-bridge IPFIX, per-flow IPFIX). These end up being translated into a
> userspace action that needs to be handled by ovs-vswitchd's handler
> threads only to be forwarded to some third party application that
> will somehow process the sample and provide observability on the
> datapath.
>
> A particularly interesting use-case is controller-driven
> per-flow IPFIX sampling where the OpenFlow controller can add metadata
> to samples (via two 32bit integers) and this metadata is then available
> to the sample-collecting system for correlation.
>
> ** Problem **
> The fact that sampled traffic share netlink sockets and handler thread
> time with upcalls, apart from being a performance bottleneck in the
> sample extraction itself, can severely compromise the datapath,
> yielding this solution unfit for highly loaded production systems.
>
> Users are left with little options other than guessing what sampling
> rate will be OK for their traffic pattern and system load and dealing
> with the lost accuracy.
>
> Looking at available infrastructure, an obvious candidated would be
> to use psample. However, it's current state does not help with the
> use-case at stake because sampled packets do not contain user-defined
> metadata.
>
> ** Proposal **
> This series is an attempt to fix this situation by extending the
> existing psample infrastructure to carry a variable length
> user-defined cookie.
>
> The main existing user of psample is tc's act_sample. It is also
> extended to forward the action's cookie to psample.
>
> Finally, a new OVS action (OVS_SAMPLE_ATTR_EMIT_SAMPLE) is created.
> It accepts a group and an optional cookie and uses psample to
> multicast the packet and the metadata.
>
> --
> v5 -> v6:
> - Renamed emit_sample -> psample
> - Addressed unused variable and conditionally compilation of function.
>
> v4 -> v5:
> - Rebased.
> - Removed lefover enum value and wrapped some long lines in selftests.
>
> v3 -> v4:
> - Rebased.
> - Addressed Jakub's comment on private and unused nla attributes.
>
> v2 -> v3:
> - Addressed comments from Simon, Aaron and Ilya.
> - Dropped probability propagation in nested sample actions.
> - Dropped patch v2's 7/9 in favor of a userspace implementation and
> consume skb if emit_sample is the last action, same as we do with
> userspace.
> - Split ovs-dpctl.py features in independent patches.
>
> v1 -> v2:
> - Create a new action ("emit_sample") rather than reuse existing
>   "sample" one.
> - Add probability semantics to psample's sampling rate.
> - Store sampling probability in skb's cb area and use it in emit_sample.
> - Test combining "emit_sample" with "trunc"
> - Drop group_id filtering and tracepoint in psample.
>
> rfc_v2 -> v1:
> - Accommodate Ilya's comments.
> - Split OVS's attribute in two attributes and simplify internal
> handling of psample arguments.
> - Extend psample and tc with a user-defined cookie.
> - Add a tracepoint to psample to facilitate troubleshooting.
>
> rfc_v1 -> rfc_v2:
> - Use psample instead of a new OVS-only multicast group.
> - Extend psample and tc with a user-defined cookie.
>
>
> Adrian Moreno (10):
>   net: psample: add user cookie
>   net: sched: act_sample: add action cookie to sample
>   net: psample: skip packet copy if no listeners
>   net: psample: allow using rate as probability
>   net: openvswitch: add psample action
>   net: openvswitch: store sampling probability in cb.
>   selftests: openvswitch: add psample action
>   selftests: openvswitch: add userspace parsing
>   selftests: openvswitch: parse trunc action
>   selftests: openvswitch: add psample test
>
>  Documentation/netlink/specs/ovs_flow.yaml |  17 ++
>  include/net/psample.h |   5 +-
>  include/uapi/linux/openvswitch.h  |  31 +-
>  include/uapi/linux/psample.h  |  11 +-
>  net/openvswitch/Kconfig   |   1 +
>  net/openvswitch/actions.c |  65 -
>  net/openvswitch/datapath.h|   3 +
>  net/openvswitch/flow_netlink.c|  32 ++-
>  net/openvswitch/vport.c   |   1 +
>  net/psample/psample.c |  16 +-
>  net/sched/act_sample.c|  12 +
>  .../selftests/net/openvswitch/openvswitch.sh  | 115 +++-
>  .../selftests/net/openvswitch/ovs-dpctl.py| 272 +-
>  13 files changed, 565 insertions(+), 16 deletions(-)
>
> --
> 2.45.2
>

Patchwork says this patch is not applying on net-next. I'll wait for
some reviews and rebase+resubmit it later tonight or tomorrow.

Thanks.
Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [RFC v2 5/9] ofproto-dpif-xlate: Use emit_sample for local sample.

2024-06-28 Thread Adrián Moreno
On Wed, Jun 26, 2024 at 02:11:51PM GMT, Eelco Chaudron wrote:
> On 5 Jun 2024, at 22:23, Adrian Moreno wrote:
>
> > Use the newly added emit_sample to implement OpenFlow sample() actions
> > with local sampling configuration.
>
> See some comments below.
>
> Cheers,
>
> Eelco
>
> > Signed-off-by: Adrian Moreno 
> > ---
> >  ofproto/ofproto-dpif-lsample.c |  17 
> >  ofproto/ofproto-dpif-lsample.h |   6 ++
> >  ofproto/ofproto-dpif-xlate.c   | 163 -
> >  ofproto/ofproto-dpif-xlate.h   |   3 +-
> >  ofproto/ofproto-dpif.c |   2 +-
> >  5 files changed, 144 insertions(+), 47 deletions(-)
> >
> > diff --git a/ofproto/ofproto-dpif-lsample.c b/ofproto/ofproto-dpif-lsample.c
> > index 7bdafac19..2c0b5da89 100644
> > --- a/ofproto/ofproto-dpif-lsample.c
> > +++ b/ofproto/ofproto-dpif-lsample.c
> > @@ -139,6 +139,23 @@ dpif_lsample_set_options(struct dpif_lsample *lsample,
> >  return changed;
> >  }
> >
> > +/* Returns the group_id of the exporter with the given collector_set_id, 
> > if it
> > + * exists. */
>
> nit: The below will fit on one line
>
> /* Returns the exporter group_id for a given collector_set_id, if it exists. 
> */
>

Ack.

> > +bool
> > +dpif_lsample_get_group_id(struct dpif_lsample *ps, uint32_t 
> > collector_set_id,
> > +  uint32_t *group_id)
> > +{
> > +struct lsample_exporter_node *node;
> > +bool found = false;
> > +
> > +node = dpif_lsample_find_exporter_node(ps, collector_set_id);
> > +if (node) {
> > +found = true;
> > +*group_id = node->exporter.options.group_id;
> > +}
> > +return found;
> > +}
> > +
> >  struct dpif_lsample *
> >  dpif_lsample_create(void)
> >  {
> > diff --git a/ofproto/ofproto-dpif-lsample.h b/ofproto/ofproto-dpif-lsample.h
> > index c23ea8372..f13425575 100644
> > --- a/ofproto/ofproto-dpif-lsample.h
> > +++ b/ofproto/ofproto-dpif-lsample.h
> > @@ -19,6 +19,7 @@
> >
> >  #include 
> >  #include 
> > +#include 
>
> Maybe add in alphabetical order.
>

Ack.

> >  struct dpif_lsample;
> >  struct ofproto_lsample_options;
> > @@ -31,4 +32,9 @@ bool dpif_lsample_set_options(struct dpif_lsample *,
> >const struct ofproto_lsample_options *,
> >size_t n_opts);
> >
> > +bool dpif_lsample_get_group_id(struct dpif_lsample *,
> > +   uint32_t collector_set_id,
> > +   uint32_t *group_id);
> > +
> >  #endif /* OFPROTO_DPIF_LSAMPLE_H */
> > +
>
> Accedantely added a newline?
>

Ack.

> > diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> > index 7c4950895..5bd215d31 100644
> > --- a/ofproto/ofproto-dpif-xlate.c
> > +++ b/ofproto/ofproto-dpif-xlate.c
> > @@ -47,6 +47,7 @@
> >  #include "ofproto/ofproto-dpif-ipfix.h"
> >  #include "ofproto/ofproto-dpif-mirror.h"
> >  #include "ofproto/ofproto-dpif-monitor.h"
> > +#include "ofproto/ofproto-dpif-lsample.h"
> >  #include "ofproto/ofproto-dpif-sflow.h"
> >  #include "ofproto/ofproto-dpif-trace.h"
> >  #include "ofproto/ofproto-dpif-xlate-cache.h"
> > @@ -117,6 +118,7 @@ struct xbridge {
> >  struct dpif_sflow *sflow; /* SFlow handle, or null. */
> >  struct dpif_ipfix *ipfix; /* Ipfix handle, or null. */
> >  struct netflow *netflow;  /* Netflow handle, or null. */
> > +struct dpif_lsample *lsample; /* Local sample handle, or null. */
> >  struct stp *stp;  /* STP or null if disabled. */
> >  struct rstp *rstp;/* RSTP or null if disabled. */
> >
> > @@ -687,6 +689,7 @@ static void xlate_xbridge_set(struct xbridge *, struct 
> > dpif *,
> >const struct dpif_sflow *,
> >const struct dpif_ipfix *,
> >const struct netflow *,
> > +  const struct dpif_lsample *,
> >bool forward_bpdu, bool has_in_band,
> >const struct dpif_backer_support *,
> >const struct xbridge_addr *);
> > @@ -1070,6 +1073,7 @@ xlate_xbridge_set(struct xbridge *xbridge,
> >const struct dpif_sflow *sflow,
> >const struct dpif_ipfix *ipfix,
> >const struct netflow *netflow,
> > +  const struct dpif_lsample *lsample,
>
> nit: I would move above netflow, as you also do the actual init/unref before
>  netflow.

Ack.

> >bool forward_bpdu, bool has_in_band,
> >const struct dpif_backer_support *support,
> >const struct xbridge_addr *addr)
> > @@ -1099,6 +1103,11 @@ xlate_xbridge_set(struct xbridge *xbridge,
> >  xbridge->ipfix = dpif_ipfix_ref(ipfix);
> >  }
> >
> > +if (xbridge->lsample != lsample) {
> > +dpif_lsample_unref(xbridge->lsample);
> > +xbridge->lsample = 

Re: [ovs-dev] [RFC v2 9/9] tests: Test local sampling.

2024-06-28 Thread Adrián Moreno
On Wed, Jun 26, 2024 at 02:15:02PM GMT, Eelco Chaudron wrote:
> On 5 Jun 2024, at 22:23, Adrian Moreno wrote:
>
> > Test simultaneous IPFIX and local sampling including slow-path.
>
> I guess Ilya's comments on this patch summarize most of my comments. I had
> one small additional question. See below.
>
> //Eelco
>
> > Signed-off-by: Adrian Moreno 
> > ---
> >  tests/system-common-macros.at |   4 ++
> >  tests/system-traffic.at   | 105 ++
> >  2 files changed, 109 insertions(+)
> >
> > diff --git a/tests/system-common-macros.at b/tests/system-common-macros.at
> > index 2a68cd664..22b8885e4 100644
> > --- a/tests/system-common-macros.at
> > +++ b/tests/system-common-macros.at
> > @@ -378,3 +378,7 @@ m4_define([OVS_CHECK_GITHUB_ACTION],
> >  # OVS_CHECK_DROP_ACTION()
> >  m4_define([OVS_CHECK_DROP_ACTION],
> >  [AT_SKIP_IF([! grep -q "Datapath supports explicit drop action" 
> > ovs-vswitchd.log])])
> > +
> > +# OVS_CHECK_EMIT_SAMPLE()
> > +m4_define([OVS_CHECK_EMIT_SAMPLE],
> > +[AT_SKIP_IF([! grep -q "Datapath supports emit_sample" 
> > ovs-vswitchd.log])])
> > diff --git a/tests/system-traffic.at b/tests/system-traffic.at
> > index bd7647cbe..babc56b56 100644
> > --- a/tests/system-traffic.at
> > +++ b/tests/system-traffic.at
> > @@ -8977,3 +8977,108 @@ OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0050: 
> > * * *5002 *2000 *b85e *00
> >
> >  OVS_TRAFFIC_VSWITCHD_STOP
> >  AT_CLEANUP
> > +
> > +AT_SETUP([emit_sample])
> > +OVS_TRAFFIC_VSWITCHD_START()
> > +OVS_CHECK_EMIT_SAMPLE()
> > +
> > +ADD_NAMESPACES(at_ns0, at_ns1)
> > +NS_CHECK_EXEC([at_ns0], [sysctl -w net.ipv6.conf.all.disable_ipv6=1], [0], 
> > [ignore])
> > +NS_CHECK_EXEC([at_ns1], [sysctl -w net.ipv6.conf.all.disable_ipv6=1], [0], 
> > [ignore])
> > +
> > +ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24", "e4:11:22:33:44:55")
> > +ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24", "e4:11:22:33:44:66")
> > +
> > +NS_CHECK_EXEC([at_ns0], [arp -s 10.1.1.2 e4:11:22:33:44:66])
> > +NS_CHECK_EXEC([at_ns1], [arp -s 10.1.1.1 e4:11:22:33:44:55])
> > +
> > +
> > +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg 
> > ofproto_dpif_upcall:dbg])
> > +
> > +AT_CHECK([ovs-vsctl -- --id=@br0 get Bridge br0 \
> > +-- --id=@ipfix create IPFIX targets=\"127.0.0.1:4739\" 
> > \
> > +-- create Flow_Sample_Collector_Set id=1 bridge=@br0 
> > ipfix=@ipfix, local_sample_group=10 \
> > +-- create Flow_Sample_Collector_Set id=2 bridge=@br0 
> > ipfix=@ipfix, local_sample_group=12],
> > + [0], [ignore])
> > +
> > +AT_DATA([flows.txt], [dnl
> > +in_port=ovs-p0,ip 
> > actions=sample(probability=65535,collector_set_id=1,obs_domain_id=1431655765,obs_point_id=1717986918),output(port=ovs-p1,max_len=100)
> > +in_port=ovs-p1,ip 
> > actions=sample(probability=65535,collector_set_id=2,obs_domain_id=2290649224,obs_point_id=2576980377),output(port=ovs-p0,max_len=100)
> > +])
> > +
> > +AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
> > +
> > +OVS_DAEMONIZE([ovstest test-psample > psample.out], [psample1.pid])
> > +
> > +NS_CHECK_EXEC([at_ns0], [ping -q -c 1 10.1.1.2 | FORMAT_PING], [0], [dnl
> > +1 packets transmitted, 1 received, 0% packet loss, time 0ms
> > +])
> > +
> > +m4_define([SAMPLE1], [group_id=0xa 
> > obs_domain=0x,obs_point=0x 
> > .*icmp.*nw_src=10.1.1.1,nw_dst=10.1.1.2])
> > +m4_define([SAMPLE2], [group_id=0xc 
> > obs_domain=0x,obs_point=0x 
> > .*icmp.*nw_src=10.1.1.2,nw_dst=10.1.1.1])
> > +AT_CHECK([grep -E 'SAMPLE1' psample.out >/dev/null])
> > +AT_CHECK([grep -E 'SAMPLE2' psample.out >/dev/null])
> > +
> > +AT_CHECK([ovs-ofctl dump-ipfix-flow br0 | sed 's/tx pkts=[[0-9]]*/tx 
> > pkts=24/' | sed 's/tx errs=[[0-9]]*/tx errs=0/'], [0], [dnl
>
> Why are we making tx pkts always 24, and are we waiving any potential tx 
> errors?
> Is this something you have seen not being consistent, if so any idea why?
>

Yes. By the time we request the statistics, IPFIX cache should contain
the flows but they might not have been sent yet. When they are sent they
will fail (because IPFIX target is localhost and it returns the socket
returns an error if the listening socket does not exist) so the number
of errors might vary.

I can look deeper into making it more consistent but it looked like a
quick workaround.

> > +NXST_IPFIX_FLOW reply (xid=0x2): 2 ids
> > +  id   1: flows=1, current flows=0, sampled pkts=1, ipv4 ok=1, ipv6 ok=0, 
> > tx pkts=24
> > +  pkts errs=0, ipv4 errs=0, ipv6 errs=0, tx errs=0
> > +  id   2: flows=1, current flows=0, sampled pkts=1, ipv4 ok=1, ipv6 ok=0, 
> > tx pkts=24
> > +  pkts errs=0, ipv4 errs=0, ipv6 errs=0, tx errs=0
> > +])
> > +
> > +AT_CHECK([ovs-appctl lsample/show br0], [0], [dnl
> > +local sample statistics for bridge "br0":
> > +- Collector Set ID: 1
> > +  Local Sample Group: 10
> > +  Total number of bytes: 98
> > +  Total number of packets: 1
> > +
> > +- Collector Set ID: 2
> > +  Local 

Re: [ovs-dev] [RFC v2 8/9] tests: Add test-psample testing utility.

2024-06-28 Thread Adrián Moreno
On Wed, Jun 26, 2024 at 02:14:27PM GMT, Eelco Chaudron wrote:
> On 5 Jun 2024, at 22:23, Adrian Moreno wrote:
>
> > This simple program reads from psample and prints the packets to stdout.
>
> Some comments below.
>
> //Eelco
>
> > Signed-off-by: Adrian Moreno 
> > ---
> >  include/linux/automake.mk |   1 +
> >  include/linux/psample.h   |  68 +
> >  tests/automake.mk |   3 +-
> >  tests/test-psample.c  | 282 ++
> >  4 files changed, 353 insertions(+), 1 deletion(-)
> >  create mode 100644 include/linux/psample.h
> >  create mode 100644 tests/test-psample.c
> >
> > diff --git a/include/linux/automake.mk b/include/linux/automake.mk
> > index cdae5eedc..ac306b53c 100644
> > --- a/include/linux/automake.mk
> > +++ b/include/linux/automake.mk
> > @@ -3,6 +3,7 @@ noinst_HEADERS += \
> > include/linux/netfilter/nf_conntrack_sctp.h \
> > include/linux/openvswitch.h \
> > include/linux/pkt_cls.h \
> > +   include/linux/psample.h \
> > include/linux/gen_stats.h \
> > include/linux/tc_act/tc_mpls.h \
> > include/linux/tc_act/tc_pedit.h \
> > diff --git a/include/linux/psample.h b/include/linux/psample.h
> > new file mode 100644
> > index 0..d5761b730
> > --- /dev/null
> > +++ b/include/linux/psample.h
> > @@ -0,0 +1,68 @@
> > +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> > +#ifndef __LINUX_PSAMPLE_H
> > +#define __LINUX_PSAMPLE_H
> > +
> > +enum {
> > +   PSAMPLE_ATTR_IIFINDEX,
> > +   PSAMPLE_ATTR_OIFINDEX,
> > +   PSAMPLE_ATTR_ORIGSIZE,
> > +   PSAMPLE_ATTR_SAMPLE_GROUP,
> > +   PSAMPLE_ATTR_GROUP_SEQ,
> > +   PSAMPLE_ATTR_SAMPLE_RATE,
> > +   PSAMPLE_ATTR_DATA,
> > +   PSAMPLE_ATTR_GROUP_REFCOUNT,
> > +   PSAMPLE_ATTR_TUNNEL,
> > +
> > +   PSAMPLE_ATTR_PAD,
> > +   PSAMPLE_ATTR_OUT_TC,/* u16 */
> > +   PSAMPLE_ATTR_OUT_TC_OCC,/* u64, bytes */
> > +   PSAMPLE_ATTR_LATENCY,   /* u64, nanoseconds */
> > +   PSAMPLE_ATTR_TIMESTAMP, /* u64, nanoseconds */
> > +   PSAMPLE_ATTR_PROTO, /* u16 */
> > +   PSAMPLE_ATTR_USER_COOKIE,   /* binary, user provided data */
> > +   PSAMPLE_ATTR_SAMPLE_PROBABILITY,/* no argument, interpret rate in
> > +* PSAMPLE_ATTR_SAMPLE_RATE as a
> > +* probability scaled 0 - U32_MAX.
> > +*/
> > +
> > +   __PSAMPLE_ATTR_MAX
> > +};
> > +
> > +enum psample_command {
> > +   PSAMPLE_CMD_SAMPLE,
> > +   PSAMPLE_CMD_GET_GROUP,
> > +   PSAMPLE_CMD_NEW_GROUP,
> > +   PSAMPLE_CMD_DEL_GROUP,
> > +   PSAMPLE_CMD_SAMPLE_FILTER_SET,
> > +};
> > +
> > +enum psample_tunnel_key_attr {
> > +   PSAMPLE_TUNNEL_KEY_ATTR_ID, /* be64 Tunnel ID */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_IPV4_SRC,   /* be32 src IP address. */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_IPV4_DST,   /* be32 dst IP address. */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_TOS,/* u8 Tunnel IP ToS. */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_TTL,/* u8 Tunnel IP TTL. */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_DONT_FRAGMENT,  /* No argument, set DF. */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_CSUM,   /* No argument. CSUM 
> > packet. */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_OAM,/* No argument. OAM frame.  
> > */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_GENEVE_OPTS,/* Array of Geneve options. 
> > */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_TP_SRC, /* be16 src Transport Port. 
> > */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_TP_DST, /* be16 dst Transport Port. 
> > */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_VXLAN_OPTS, /* Nested VXLAN opts* */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_IPV6_SRC,   /* struct in6_addr src IPv6 
> > address. */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_IPV6_DST,   /* struct in6_addr dst IPv6 
> > address. */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_PAD,
> > +   PSAMPLE_TUNNEL_KEY_ATTR_ERSPAN_OPTS,/* struct erspan_metadata */
> > +   PSAMPLE_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE,   /* No argument. 
> > IPV4_INFO_BRIDGE mode.*/
> > +   __PSAMPLE_TUNNEL_KEY_ATTR_MAX
> > +};
> > +
> > +/* Can be overridden at runtime by module option */
> > +#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1)
> > +
> > +#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config"
> > +#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets"
> > +#define PSAMPLE_GENL_NAME "psample"
> > +#define PSAMPLE_GENL_VERSION 1
> > +
> > +#endif
> > diff --git a/tests/automake.mk b/tests/automake.mk
> > index 04f48f2d8..edfc2cb33 100644
> > --- a/tests/automake.mk
> > +++ b/tests/automake.mk
> > @@ -499,7 +499,8 @@ endif
> >  if LINUX
> >  tests_ovstest_SOURCES += \
> > tests/test-netlink-conntrack.c \
> > -   tests/test-netlink-policy.c
> > +   tests/test-netlink-policy.c \
> > +   tests/test-psample.c
> >  endif
> >
> >  tests_ovstest_LDADD = lib/libopenvswitch.la
> > diff --git a/tests/test-psample.c b/tests/test-psample.c
> > new file mode 100644
> > index 

Re: [ovs-dev] [RFC v2 7/9] ofproto-dpif-lsample: Show stats via unixctl.

2024-06-28 Thread Adrián Moreno
On Wed, Jun 26, 2024 at 02:13:40PM GMT, Eelco Chaudron wrote:
> On 5 Jun 2024, at 22:23, Adrian Moreno wrote:
>
> > Add a command to dump statistics per exporter.
>
> Some comments below.
>
> //Eelco
>
> > Signed-off-by: Adrian Moreno 
> > ---
> >  NEWS   |   2 +
> >  ofproto/ofproto-dpif-lsample.c | 113 +
> >  ofproto/ofproto-dpif-lsample.h |   1 +
> >  ofproto/ofproto-dpif.c |   1 +
> >  4 files changed, 117 insertions(+)
> >
> > diff --git a/NEWS b/NEWS
> > index 1c05a7120..a443f9fe1 100644
> > --- a/NEWS
> > +++ b/NEWS
> > @@ -11,6 +11,8 @@ Post-v3.3.0
> >   allows samples to be emitted locally (instead of via IPFIX) in a
> >   datapath-specific manner via the new datapath action called 
> > "emit_sample".
> >   Linux kernel datapath is the first to support this feature.
> > + A new unixctl command 'lsample/show' shows packet and bytes statistics
> > + per local sample exporter.
> >
> >
> >  v3.3.0 - 16 Feb 2024
> > diff --git a/ofproto/ofproto-dpif-lsample.c b/ofproto/ofproto-dpif-lsample.c
> > index 0c71e354d..e31dabac4 100644
> > --- a/ofproto/ofproto-dpif-lsample.c
> > +++ b/ofproto/ofproto-dpif-lsample.c
> > @@ -21,7 +21,10 @@
> >  #include "dpif.h"
> >  #include "hash.h"
> >  #include "ofproto.h"
> > +#include "ofproto-dpif.h"
> > +#include "openvswitch/dynamic-string.h"
> >  #include "openvswitch/thread.h"
> > +#include "unixctl.h"
> >
> >  /* Dpif local sampling.
> >   *
> > @@ -218,3 +221,113 @@ dpif_lsample_unref(struct dpif_lsample *lsample)
> >  dpif_lsample_destroy(lsample);
> >  }
> >  }
> > +
> > +static int
> > +compare_exporter_list(const void *a_, const void *b_)
>
> We are not comparing a list here, so we should choose a more appropriate name,
> maybe something like;  compare_exporter_collector_set_id(), or if you want it
> shorter, maybe comp_exporter_collector_id(), use you fantasy (but not to
> much ;).
>
> > +{
> > +const struct lsample_exporter_node *a, *b;
> > +
> > +a = *(struct lsample_exporter_node **)a_;
> > +b = *(struct lsample_exporter_node **)b_;
>
> Fix space around casting.
>

Ack.

> > +
> > +if (a->exporter.options.collector_set_id >
> > +b->exporter.options.collector_set_id) {
> > +return 1;
> > +}
> > +if (a->exporter.options.collector_set_id <
> > +b->exporter.options.collector_set_id) {
> > +return -1;
> > +}
> > +return 0;
> > +}
> > +
> > +static void
> > +lsample_exporter_list(struct dpif_lsample *lsample,
> > +  struct lsample_exporter_node ***list,
> > +  size_t *num_exporters)
> > +{
> > +struct lsample_exporter_node *node;
> > +struct lsample_exporter_node **exporter_list;
>
> Reverse Christmas tree order.
>

Ack.


> > +size_t k = 0, n;
> > +
> > +n = cmap_count(>exporters);
> > +
> > +exporter_list = xcalloc(n, sizeof *exporter_list);
> > +
> > +CMAP_FOR_EACH (node, node, >exporters) {
> > +if (k >= n) {
> > +break;
> > +}
> > +exporter_list[k++] = node;
> > +}
> > +
> > +qsort(exporter_list, k, sizeof *exporter_list, compare_exporter_list);
> > +
> > +*list = exporter_list;
> > +*num_exporters = k;
> > +}
> > +
> > +static void
> > +lsample_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
> > + const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
> > +{
> > +struct lsample_exporter_node **node_list = NULL;
> > +struct lsample_exporter_node *node;
> > +struct ds ds = DS_EMPTY_INITIALIZER;
>
> Reverse Christmas tree? Or even better move the *node definition inside the
> for loop below.
>

Ack.

> > +const struct ofproto_dpif *ofproto;
> > +size_t i, num;
> > +
> > +ofproto = ofproto_dpif_lookup_by_name(argv[1]);
> > +if (!ofproto) {
> > +unixctl_command_reply_error(conn, "no such bridge");
> > +return;
> > +}
> > +
> > +if (!ofproto->lsample) {
> > +unixctl_command_reply_error(conn, "no local sampling exporters "
> > +"configured");
>
> unixctl_command_reply_error(conn,
> "no local sampling exporters configured");
>
>
> > +return;
> > +}
> > +
> > +ds_put_format(, "local sample statistics for bridge \"%s\":\n",
>
> Maybe capital L for Local?
>

Ack.

> > + argv[1]);
> > +
> > +lsample_exporter_list(ofproto->lsample, _list, );
> > +
> > +for (i = 0; i < num; i++) {
> > +uint64_t n_bytes;
> > +uint64_t n_packets;
>
> Reverse Christmas tree
>

Ack.

> > +
> > +node = node_list[i];
> > +
> > +atomic_read_relaxed(>exporter.n_packets, _packets);
> > +atomic_read_relaxed(>exporter.n_bytes, _bytes);
> > +
> > +if (i) {
> > +ds_put_cstr(, "\n");
> > +}
> > +
> > +ds_put_format(, "- Collector Set ID: 

Re: [ovs-dev] [RFC v2 4/9] vswitchd: Add local sampling to vswitchd schema.

2024-06-28 Thread Adrián Moreno
On Thu, Jun 27, 2024 at 03:57:03PM GMT, Eelco Chaudron wrote:
>
>
> On 27 Jun 2024, at 13:37, Adrián Moreno wrote:
>
> > On Wed, Jun 26, 2024 at 02:11:00PM GMT, Eelco Chaudron wrote:
> >> On 5 Jun 2024, at 22:23, Adrian Moreno wrote:
> >>
> >>> Add as new column in the Flow_Sample_Collector_Set table named
> >>> "local_sample_group" which enables this feature.
> >>>
> >>> Signed-off-by: Adrian Moreno 
> >>> ---
> >>>  NEWS   |  4 ++
> >>>  vswitchd/bridge.c  | 78 +++---
> >>>  vswitchd/vswitch.ovsschema |  9 -
> >>>  vswitchd/vswitch.xml   | 39 +--
> >>>  4 files changed, 119 insertions(+), 11 deletions(-)
> >>>
> >>> diff --git a/NEWS b/NEWS
> >>> index b92cec532..1c05a7120 100644
> >>> --- a/NEWS
> >>> +++ b/NEWS
> >>> @@ -7,6 +7,10 @@ Post-v3.3.0
> >>> - The primary development branch has been renamed from 'master' to 
> >>> 'main'.
> >>>   The OVS tree remains hosted on GitHub.
> >>>https://github.com/openvswitch/ovs.git
> >>> +   - Local sampling is introduced. It reuses the OpenFlow sample action 
> >>> and
> >>> + allows samples to be emitted locally (instead of via IPFIX) in a
> >>> + datapath-specific manner via the new datapath action called 
> >>> "emit_sample".
> >>> + Linux kernel datapath is the first to support this feature.
> >>>
> >>>
> >>>  v3.3.0 - 16 Feb 2024
> >>> diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
> >>> index 95a65fcdc..cd7dc6646 100644
> >>> --- a/vswitchd/bridge.c
> >>> +++ b/vswitchd/bridge.c
> >>> @@ -288,6 +288,7 @@ static void bridge_configure_mac_table(struct bridge 
> >>> *);
> >>>  static void bridge_configure_mcast_snooping(struct bridge *);
> >>>  static void bridge_configure_sflow(struct bridge *, int 
> >>> *sflow_bridge_number);
> >>>  static void bridge_configure_ipfix(struct bridge *);
> >>> +static void bridge_configure_lsample(struct bridge *);
> >>>  static void bridge_configure_spanning_tree(struct bridge *);
> >>>  static void bridge_configure_tables(struct bridge *);
> >>>  static void bridge_configure_dp_desc(struct bridge *);
> >>> @@ -989,6 +990,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch 
> >>> *ovs_cfg)
> >>>  bridge_configure_netflow(br);
> >>>  bridge_configure_sflow(br, _bridge_number);
> >>>  bridge_configure_ipfix(br);
> >>> +bridge_configure_lsample(br);
> >>>  bridge_configure_spanning_tree(br);
> >>>  bridge_configure_tables(br);
> >>>  bridge_configure_dp_desc(br);
> >>> @@ -1537,10 +1539,11 @@ ovsrec_ipfix_is_valid(const struct ovsrec_ipfix 
> >>> *ipfix)
> >>>  return ipfix && ipfix->n_targets > 0;
> >>>  }
> >>>
> >>> -/* Returns whether a Flow_Sample_Collector_Set row is valid. */
> >>> +/* Returns whether a Flow_Sample_Collector_Set row constains valid IPFIX
> >>
> >> constains -> 'contains a'
> >>
> >
> > Ack.
> >
> >>> + * configuration. */
> >>>  static bool
> >>> -ovsrec_fscs_is_valid(const struct ovsrec_flow_sample_collector_set *fscs,
> >>> - const struct bridge *br)
> >>> +ovsrec_fscs_is_valid_ipfix(const struct ovsrec_flow_sample_collector_set 
> >>> *fscs,
> >>> +   const struct bridge *br)
> >>>  {
> >>>  return ovsrec_ipfix_is_valid(fscs->ipfix) && fscs->bridge == br->cfg;
> >>>  }
> >>> @@ -1558,7 +1561,7 @@ bridge_configure_ipfix(struct bridge *br)
> >>>  const char *virtual_obs_id;
> >>>
> >>>  OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH(fe_cfg, idl) {
> >>> -if (ovsrec_fscs_is_valid(fe_cfg, br)) {
> >>> +if (ovsrec_fscs_is_valid_ipfix(fe_cfg, br)) {
> >>>  n_fe_opts++;
> >>>  }
> >>>  }
> >>> @@ -1621,7 +1624,7 @@ bridge_configure_ipfix(struct bridge *br)
> >>>  fe_opts = xcalloc(n_fe_opts, sizeof *fe_opts);
> >>>  opts = fe_opts;
&g

Re: [ovs-dev] [RFC v2 1/9] odp-util: Add support OVS_ACTION_ATTR_EMIT_SAMPLE.

2024-06-28 Thread Adrián Moreno
On Thu, Jun 27, 2024 at 03:42:38PM GMT, Eelco Chaudron wrote:
>
>
> On 27 Jun 2024, at 12:45, Adrián Moreno wrote:
>
> > On Wed, Jun 26, 2024 at 02:08:27PM GMT, Eelco Chaudron wrote:
> >> On 5 Jun 2024, at 22:23, Adrian Moreno wrote:
> >>
> >>> Add support for parsing and formatting the new action.
> >>>
> >>> Also, flag OVS_ACTION_ATTR_SAMPLE as requiring datapath assistance if it
> >>> contains a nested OVS_ACTION_ATTR_EMIT_SAMPLE. The reason is that the
> >>> sampling rate form the parent "sample" is made available to the nested
> >>> "emit_sample" by the kernel.
> >>
> >> Hi Adrian,
> >>
> >> Thanks for this series! This email kicks off my review of the series,
> >> see comments below and in the other patches.
> >>
> >> Cheers,
> >>
> >> Eelco
> >>
> >>> Signed-off-by: Adrian Moreno 
> >>> ---
> >>>  include/linux/openvswitch.h  |  25 +
> >>>  lib/dpif-netdev.c|   1 +
> >>>  lib/dpif.c   |   1 +
> >>>  lib/odp-execute.c|  25 -
> >>>  lib/odp-util.c   | 103 +++
> >>>  lib/odp-util.h   |   3 +
> >>>  ofproto/ofproto-dpif-ipfix.c |   1 +
> >>>  ofproto/ofproto-dpif-sflow.c |   1 +
> >>>  python/ovs/flow/odp.py   |   8 +++
> >>>  tests/odp.at |  16 ++
> >>>  10 files changed, 183 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
> >>> index d9fb991ef..b4e0647bd 100644
> >>> --- a/include/linux/openvswitch.h
> >>> +++ b/include/linux/openvswitch.h
> >>> @@ -992,6 +992,30 @@ struct check_pkt_len_arg {
> >>>  };
> >>>  #endif
> >>>
> >>> +#define OVS_EMIT_SAMPLE_COOKIE_MAX_SIZE 16
> >>> +/**
> >>> + * enum ovs_emit_sample_attr - Attributes for 
> >>> %OVS_ACTION_ATTR_EMIT_SAMPLE
> >>> + * action.
> >>> + *
> >>> + * @OVS_EMIT_SAMPLE_ATTR_GROUP: 32-bit number to identify the source of 
> >>> the
> >>> + * sample.
> >>> + * @OVS_EMIT_SAMPLE_ATTR_COOKIE: A variable-length binary cookie that 
> >>> contains
> >>> + * user-defined metadata. The maximum length is 16 bytes.
> >>> + *
> >>> + * Sends the packet to the psample multicast group with the specified 
> >>> group and
> >>> + * cookie. It is possible to combine this action with the
> >>> + * %OVS_ACTION_ATTR_TRUNC to limit the size of the packet being emitted.
> >>
> >> I'll start the discussion again on the naming. The name "emit_sample()"
> >> does not seem appropriate. This function's primary role is to copy the
> >> packet and send it to a local collector, which varies depending on the
> >> datapath. For the kernel datapath, this collector is psample, while for
> >> userspace, it will likely be some kind of probe. This action is distinct
> >> from the sample() action by design; it is a standalone action that can
> >> be combined with others.
> >>
> >> Furthermore, the action itself does not involve taking a sample; it
> >> consistently pushes the packet to the local collector. Therefore, I
> >> suggest renaming "emit_sample()" to "emit_local()". This same goes for
> >> all the derivative ATTR naming.
> >>
> >
> > Let's discuss this in the kernel ml.
> >
> >>> + */
> >>> +enum ovs_emit_sample_attr {
> >>> + OVS_EMIT_SAMPLE_ATTR_UNPSEC,
> >>> + OVS_EMIT_SAMPLE_ATTR_GROUP, /* u32 number. */
> >>> + OVS_EMIT_SAMPLE_ATTR_COOKIE,/* Optional, user specified cookie. */
> >>
> >> Fix comment alignment? Maybe also change the order to be alphabetical?
> >>
> >
> > What do you mean by comment alignment?
>
> Well you are using tabs to index which might result in it looking like this:
>
> + OVS_EMIT_SAMPLE_ATTR_GROUP, /* u32 number. */
> + OVS_EMIT_SAMPLE_ATTR_COOKIE,/* Optional, user specified cookie. */
>
> (Most) of the other comments use spaces after the definition.
>
> >>> + __OVS_EMIT_SAMPLE_ATTR_MAX
> >>> +};
> >>> +
> >>> +#define OVS_EMIT_SAMPLE_ATTR_MAX (__OVS_EMIT_SAMPLE_ATTR_MAX - 1)
> >>> +
> >>> +
>

Re: [ovs-dev] [PATCH net-next v5 05/10] net: openvswitch: add emit_sample action

2024-06-27 Thread Adrián Moreno
On Thu, Jun 27, 2024 at 09:30:08AM GMT, Aaron Conole wrote:
> Ilya Maximets  writes:
>
> > On 6/27/24 12:15, Adrián Moreno wrote:
> >> On Thu, Jun 27, 2024 at 11:31:41AM GMT, Eelco Chaudron wrote:
> >>>
> >>>
> >>> On 27 Jun 2024, at 11:23, Ilya Maximets wrote:
> >>>
> >>>> On 6/27/24 11:14, Eelco Chaudron wrote:
> >>>>>
> >>>>>
> >>>>> On 27 Jun 2024, at 10:36, Ilya Maximets wrote:
> >>>>>
> >>>>>> On 6/27/24 09:52, Adrián Moreno wrote:
> >>>>>>> On Thu, Jun 27, 2024 at 09:06:46AM GMT, Eelco Chaudron wrote:
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> On 26 Jun 2024, at 22:34, Adrián Moreno wrote:
> >>>>>>>>
> >>>>>>>>> On Wed, Jun 26, 2024 at 04:28:17PM GMT, Eelco Chaudron wrote:
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> On 25 Jun 2024, at 22:51, Adrian Moreno wrote:
> >>>>>>>>>>
> >>>>>>>>>>> Add support for a new action: emit_sample.
> >>>>>>>>>>>
> >>>>>>>>>>> This action accepts a u32 group id and a variable-length cookie 
> >>>>>>>>>>> and uses
> >>>>>>>>>>> the psample multicast group to make the packet available for
> >>>>>>>>>>> observability.
> >>>>>>>>>>>
> >>>>>>>>>>> The maximum length of the user-defined cookie is set to 16, same 
> >>>>>>>>>>> as
> >>>>>>>>>>> tc_cookie, to discourage using cookies that will not be 
> >>>>>>>>>>> offloadable.
> >>>>>>>>>>
> >>>>>>>>>> I’ll add the same comment as I had in the user space part, and that
> >>>>>>>>>> is that I feel from an OVS perspective this action should be called
> >>>>>>>>>> emit_local() instead of emit_sample() to make it Datapath 
> >>>>>>>>>> independent.
> >>>>>>>>>> Or quoting the earlier comment:
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> “I’ll start the discussion again on the naming. The name 
> >>>>>>>>>> "emit_sample()"
> >>>>>>>>>> does not seem appropriate. This function's primary role is to copy 
> >>>>>>>>>> the
> >>>>>>>>>> packet and send it to a local collector, which varies depending on 
> >>>>>>>>>> the
> >>>>>>>>>> datapath. For the kernel datapath, this collector is psample, 
> >>>>>>>>>> while for
> >>>>>>>>>> userspace, it will likely be some kind of probe. This action is 
> >>>>>>>>>> distinct
> >>>>>>>>>> from the sample() action by design; it is a standalone action that 
> >>>>>>>>>> can
> >>>>>>>>>> be combined with others.
> >>>>>>>>>>
> >>>>>>>>>> Furthermore, the action itself does not involve taking a sample; it
> >>>>>>>>>> consistently pushes the packet to the local collector. Therefore, I
> >>>>>>>>>> suggest renaming "emit_sample()" to "emit_local()". This same goes 
> >>>>>>>>>> for
> >>>>>>>>>> all the derivative ATTR naming.”
> >>>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> This is a blurry semantic area.
> >>>>>>>>> IMO, "sample" is the act of extracting (potentially a piece of)
> >>>>>>>>> someting, in this case, a packet. It is common to only take some 
> >>>>>>>>> packets
> >>>>>>>>> as samples, so this action usually comes with some kind of "rate", 
> >>>>>>>>> but
> >>>>>>>>> e

Re: [ovs-dev] [RFC v2 4/9] vswitchd: Add local sampling to vswitchd schema.

2024-06-27 Thread Adrián Moreno
On Wed, Jun 26, 2024 at 02:11:00PM GMT, Eelco Chaudron wrote:
> On 5 Jun 2024, at 22:23, Adrian Moreno wrote:
>
> > Add as new column in the Flow_Sample_Collector_Set table named
> > "local_sample_group" which enables this feature.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  NEWS   |  4 ++
> >  vswitchd/bridge.c  | 78 +++---
> >  vswitchd/vswitch.ovsschema |  9 -
> >  vswitchd/vswitch.xml   | 39 +--
> >  4 files changed, 119 insertions(+), 11 deletions(-)
> >
> > diff --git a/NEWS b/NEWS
> > index b92cec532..1c05a7120 100644
> > --- a/NEWS
> > +++ b/NEWS
> > @@ -7,6 +7,10 @@ Post-v3.3.0
> > - The primary development branch has been renamed from 'master' to 
> > 'main'.
> >   The OVS tree remains hosted on GitHub.
> > https://github.com/openvswitch/ovs.git
> > +   - Local sampling is introduced. It reuses the OpenFlow sample action and
> > + allows samples to be emitted locally (instead of via IPFIX) in a
> > + datapath-specific manner via the new datapath action called 
> > "emit_sample".
> > + Linux kernel datapath is the first to support this feature.
> >
> >
> >  v3.3.0 - 16 Feb 2024
> > diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
> > index 95a65fcdc..cd7dc6646 100644
> > --- a/vswitchd/bridge.c
> > +++ b/vswitchd/bridge.c
> > @@ -288,6 +288,7 @@ static void bridge_configure_mac_table(struct bridge *);
> >  static void bridge_configure_mcast_snooping(struct bridge *);
> >  static void bridge_configure_sflow(struct bridge *, int 
> > *sflow_bridge_number);
> >  static void bridge_configure_ipfix(struct bridge *);
> > +static void bridge_configure_lsample(struct bridge *);
> >  static void bridge_configure_spanning_tree(struct bridge *);
> >  static void bridge_configure_tables(struct bridge *);
> >  static void bridge_configure_dp_desc(struct bridge *);
> > @@ -989,6 +990,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch 
> > *ovs_cfg)
> >  bridge_configure_netflow(br);
> >  bridge_configure_sflow(br, _bridge_number);
> >  bridge_configure_ipfix(br);
> > +bridge_configure_lsample(br);
> >  bridge_configure_spanning_tree(br);
> >  bridge_configure_tables(br);
> >  bridge_configure_dp_desc(br);
> > @@ -1537,10 +1539,11 @@ ovsrec_ipfix_is_valid(const struct ovsrec_ipfix 
> > *ipfix)
> >  return ipfix && ipfix->n_targets > 0;
> >  }
> >
> > -/* Returns whether a Flow_Sample_Collector_Set row is valid. */
> > +/* Returns whether a Flow_Sample_Collector_Set row constains valid IPFIX
>
> constains -> 'contains a'
>

Ack.

> > + * configuration. */
> >  static bool
> > -ovsrec_fscs_is_valid(const struct ovsrec_flow_sample_collector_set *fscs,
> > - const struct bridge *br)
> > +ovsrec_fscs_is_valid_ipfix(const struct ovsrec_flow_sample_collector_set 
> > *fscs,
> > +   const struct bridge *br)
> >  {
> >  return ovsrec_ipfix_is_valid(fscs->ipfix) && fscs->bridge == br->cfg;
> >  }
> > @@ -1558,7 +1561,7 @@ bridge_configure_ipfix(struct bridge *br)
> >  const char *virtual_obs_id;
> >
> >  OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH(fe_cfg, idl) {
> > -if (ovsrec_fscs_is_valid(fe_cfg, br)) {
> > +if (ovsrec_fscs_is_valid_ipfix(fe_cfg, br)) {
> >  n_fe_opts++;
> >  }
> >  }
> > @@ -1621,7 +1624,7 @@ bridge_configure_ipfix(struct bridge *br)
> >  fe_opts = xcalloc(n_fe_opts, sizeof *fe_opts);
> >  opts = fe_opts;
> >  OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH(fe_cfg, idl) {
> > -if (ovsrec_fscs_is_valid(fe_cfg, br)) {
> > +if (ovsrec_fscs_is_valid_ipfix(fe_cfg, br)) {
> >  opts->collector_set_id = fe_cfg->id;
> >  sset_init(>targets);
> >  sset_add_array(>targets, fe_cfg->ipfix->targets,
> > @@ -1667,6 +1670,71 @@ bridge_configure_ipfix(struct bridge *br)
> >  }
> >  }
> >
> > +/* Returns whether a Flow_Sample_Collector_Set row contains valid local
> > + * sampling configuraiton. */
>
> ...row contains a valid local...
>++
>
> configuraiton -> configuration

Ack.

>
> > +static bool
> > +ovsrec_fscs_is_valid_local(const struct ovsrec_flow_sample_collector_set 
> > *fscs,
> > +   const struct bridge *br)
> > +{
> > +return fscs->local_sample_group && fscs->n_local_sample_group == 1 &&
> > +   fscs->bridge == br->cfg;
> > +}
> > +
> > +/* Set local sample configuration on 'br'. */
> > +static void
> > +bridge_configure_lsample(struct bridge *br)
> > +{
> > +static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
> > +const struct ovsrec_flow_sample_collector_set *fscs;
> > +struct ofproto_lsample_options *opts_array, *opts;
> > +size_t n_opts = 0;
> > +int ret;
> > +
> > +/* Iterate the Flow_Sample_Collector_Set table twice.
> > + * First to get the 

Re: [ovs-dev] [RFC v2 3/9] ofproto: Add ofproto-dpif-lsample.

2024-06-27 Thread Adrián Moreno
On Wed, Jun 26, 2024 at 02:10:27PM GMT, Eelco Chaudron wrote:
> On 5 Jun 2024, at 22:23, Adrian Moreno wrote:
>
> > Add a new resource in ofproto-dpif and the corresponding API in
> > ofproto_provider.h to represent and local sampling configuration.
> >
> > Signed-off-by: Adrian Moreno 
>
> See some comments below.
>
> Cheers,
>
> Eelco
>
> > ---
> >  ofproto/automake.mk|   2 +
> >  ofproto/ofproto-dpif-lsample.c | 185 +
> >  ofproto/ofproto-dpif-lsample.h |  34 ++
> >  ofproto/ofproto-dpif.c |  37 +++
> >  ofproto/ofproto-dpif.h |   1 +
> >  ofproto/ofproto-provider.h |   9 ++
> >  ofproto/ofproto.c  |  12 +++
> >  ofproto/ofproto.h  |   8 ++
> >  8 files changed, 288 insertions(+)
> >  create mode 100644 ofproto/ofproto-dpif-lsample.c
> >  create mode 100644 ofproto/ofproto-dpif-lsample.h
> >
> > diff --git a/ofproto/automake.mk b/ofproto/automake.mk
> > index 7c08b563b..fd39bf561 100644
> > --- a/ofproto/automake.mk
> > +++ b/ofproto/automake.mk
> > @@ -34,6 +34,8 @@ ofproto_libofproto_la_SOURCES = \
> > ofproto/ofproto-dpif-mirror.h \
> > ofproto/ofproto-dpif-monitor.c \
> > ofproto/ofproto-dpif-monitor.h \
> > +   ofproto/ofproto-dpif-lsample.c \
> > +   ofproto/ofproto-dpif-lsample.h \
>
> Guess these need to move before the dpif-m* files.
>

Ack

> > ofproto/ofproto-dpif-rid.c \
> > ofproto/ofproto-dpif-rid.h \
> > ofproto/ofproto-dpif-sflow.c \
> > diff --git a/ofproto/ofproto-dpif-lsample.c b/ofproto/ofproto-dpif-lsample.c
> > new file mode 100644
> > index 0..7bdafac19
> > --- /dev/null
> > +++ b/ofproto/ofproto-dpif-lsample.c
> > @@ -0,0 +1,185 @@
> > +/*
> > + * Copyright (c) 2024 Red Hat, Inc.
> > + *
> > + * Licensed under the Apache License, Version 2.0 (the "License");
> > + * you may not use this file except in compliance with the License.
> > + * You may obtain a copy of the License at:
> > + *
> > + * http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing, software
> > + * distributed under the License is distributed on an "AS IS" BASIS,
> > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> > + * See the License for the specific language governing permissions and
> > + * limitations under the License.
> > + */
> > +
> > +#include 
> > +#include "ofproto-dpif-lsample.h"
> > +
> > +#include "cmap.h"
> > +#include "hash.h"
> > +#include "ofproto.h"
> > +#include "openvswitch/thread.h"
> > +
> > +/* Dpif local sampling.
> > + *
> > + * Thread safety: dpif_lsample allows lockless concurrent reads of local
> > + * sampling exporters as long as the following restrictions are met:
> > + *   1) While the last reference is being dropped, i.e: a thread is calling
> > + *  "dpif_lsample_unref" on the last reference, other threads cannot 
> > call
> > + *  "dpif_lsample_ref".
> > + *   2) Threads do not quiese while holding references to internal
> > + *  lsample_exporter objects.
> > + */
> > +
> > +struct dpif_lsample {
> > +struct cmap exporters;  /* Contains lsample_exporter_node 
> > instances
> > +   indexed by collector_set_id. */
> > +struct ovs_mutex mutex; /* Protects concurrent 
> > insertion/deletion
> > + * of exporters. */
> > +
> > +struct ovs_refcount ref_cnt;/* Controls references to this 
> > instance. */
> > +};
> > +
> > +struct lsample_exporter {
> > +struct ofproto_lsample_options options;
> > +};
> > +
> > +struct lsample_exporter_node {
> > +struct cmap_node node;  /* In dpif_lsample->exporters. */
> > +struct lsample_exporter exporter;
> > +};
> > +
> > +static void
> > +dpif_lsample_delete_exporter(struct dpif_lsample *lsample,
> > + struct lsample_exporter_node *node)
> > +{
> > +ovs_mutex_lock(>mutex);
> > +cmap_remove(>exporters, >node,
> > +hash_int(node->exporter.options.collector_set_id, 0));
> > +ovs_mutex_unlock(>mutex);
> > +
> > +ovsrcu_postpone(free, node);
> > +}
> > +
> > +/* Adds an exporter with the provided options which are copied. */
> > +static struct lsample_exporter_node *
> > +dpif_lsample_add_exporter(struct dpif_lsample *lsample,
> > +  const struct ofproto_lsample_options *options)
> > +{
> > +struct lsample_exporter_node *node;
>
> New line between definitions and code.
>

Ack.

> > +node = xzalloc(sizeof *node);
> > +node->exporter.options = *options;
> > +
> > +ovs_mutex_lock(>mutex);
> > +cmap_insert(>exporters, >node,
> > +hash_int(options->collector_set_id, 0));
> > +ovs_mutex_unlock(>mutex);
> > +
> > +return node;
> > +}
> > +
> > +static struct lsample_exporter_node *
> > +dpif_lsample_find_exporter_node(const struct dpif_lsample *lsample,
> > +   

Re: [ovs-dev] [RFC v2 1/9] odp-util: Add support OVS_ACTION_ATTR_EMIT_SAMPLE.

2024-06-27 Thread Adrián Moreno
On Wed, Jun 26, 2024 at 02:08:27PM GMT, Eelco Chaudron wrote:
> On 5 Jun 2024, at 22:23, Adrian Moreno wrote:
>
> > Add support for parsing and formatting the new action.
> >
> > Also, flag OVS_ACTION_ATTR_SAMPLE as requiring datapath assistance if it
> > contains a nested OVS_ACTION_ATTR_EMIT_SAMPLE. The reason is that the
> > sampling rate form the parent "sample" is made available to the nested
> > "emit_sample" by the kernel.
>
> Hi Adrian,
>
> Thanks for this series! This email kicks off my review of the series,
> see comments below and in the other patches.
>
> Cheers,
>
> Eelco
>
> > Signed-off-by: Adrian Moreno 
> > ---
> >  include/linux/openvswitch.h  |  25 +
> >  lib/dpif-netdev.c|   1 +
> >  lib/dpif.c   |   1 +
> >  lib/odp-execute.c|  25 -
> >  lib/odp-util.c   | 103 +++
> >  lib/odp-util.h   |   3 +
> >  ofproto/ofproto-dpif-ipfix.c |   1 +
> >  ofproto/ofproto-dpif-sflow.c |   1 +
> >  python/ovs/flow/odp.py   |   8 +++
> >  tests/odp.at |  16 ++
> >  10 files changed, 183 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
> > index d9fb991ef..b4e0647bd 100644
> > --- a/include/linux/openvswitch.h
> > +++ b/include/linux/openvswitch.h
> > @@ -992,6 +992,30 @@ struct check_pkt_len_arg {
> >  };
> >  #endif
> >
> > +#define OVS_EMIT_SAMPLE_COOKIE_MAX_SIZE 16
> > +/**
> > + * enum ovs_emit_sample_attr - Attributes for %OVS_ACTION_ATTR_EMIT_SAMPLE
> > + * action.
> > + *
> > + * @OVS_EMIT_SAMPLE_ATTR_GROUP: 32-bit number to identify the source of the
> > + * sample.
> > + * @OVS_EMIT_SAMPLE_ATTR_COOKIE: A variable-length binary cookie that 
> > contains
> > + * user-defined metadata. The maximum length is 16 bytes.
> > + *
> > + * Sends the packet to the psample multicast group with the specified 
> > group and
> > + * cookie. It is possible to combine this action with the
> > + * %OVS_ACTION_ATTR_TRUNC to limit the size of the packet being emitted.
>
> I'll start the discussion again on the naming. The name "emit_sample()"
> does not seem appropriate. This function's primary role is to copy the
> packet and send it to a local collector, which varies depending on the
> datapath. For the kernel datapath, this collector is psample, while for
> userspace, it will likely be some kind of probe. This action is distinct
> from the sample() action by design; it is a standalone action that can
> be combined with others.
>
> Furthermore, the action itself does not involve taking a sample; it
> consistently pushes the packet to the local collector. Therefore, I
> suggest renaming "emit_sample()" to "emit_local()". This same goes for
> all the derivative ATTR naming.
>

Let's discuss this in the kernel ml.

> > + */
> > +enum ovs_emit_sample_attr {
> > +   OVS_EMIT_SAMPLE_ATTR_UNPSEC,
> > +   OVS_EMIT_SAMPLE_ATTR_GROUP, /* u32 number. */
> > +   OVS_EMIT_SAMPLE_ATTR_COOKIE,/* Optional, user specified cookie. */
>
> Fix comment alignment? Maybe also change the order to be alphabetical?
>

What do you mean by comment alignment?


> > +   __OVS_EMIT_SAMPLE_ATTR_MAX
> > +};
> > +
> > +#define OVS_EMIT_SAMPLE_ATTR_MAX (__OVS_EMIT_SAMPLE_ATTR_MAX - 1)
> > +
> > +
> >  /**
> >   * enum ovs_action_attr - Action types.
> >   *
> > @@ -1087,6 +,7 @@ enum ovs_action_attr {
> > OVS_ACTION_ATTR_ADD_MPLS, /* struct ovs_action_add_mpls. */
> > OVS_ACTION_ATTR_DEC_TTL,  /* Nested OVS_DEC_TTL_ATTR_*. */
> > OVS_ACTION_ATTR_DROP, /* u32 xlate_error. */
> > +   OVS_ACTION_ATTR_EMIT_SAMPLE,  /* Nested OVS_EMIT_SAMPLE_ATTR_*. */
> >
> >  #ifndef __KERNEL__
> > OVS_ACTION_ATTR_TUNNEL_PUSH,   /* struct ovs_action_push_tnl*/
> > diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
> > index c7f9e1490..c1171890c 100644
> > --- a/lib/dpif-netdev.c
> > +++ b/lib/dpif-netdev.c
> > @@ -9519,6 +9519,7 @@ dp_execute_cb(void *aux_, struct dp_packet_batch 
> > *packets_,
> >  case OVS_ACTION_ATTR_DROP:
> >  case OVS_ACTION_ATTR_ADD_MPLS:
> >  case OVS_ACTION_ATTR_DEC_TTL:
> > +case OVS_ACTION_ATTR_EMIT_SAMPLE:
> >  case __OVS_ACTION_ATTR_MAX:
> >  OVS_NOT_REACHED();
> >  }
> > diff --git a/lib/dpif.c b/lib/dpif.c
> > index 23eb18495..489d6a095 100644
> > --- a/lib/dpif.c
> > +++ b/lib/dpif.c
> > @@ -1192,6 +1192,7 @@ dpif_execute_helper_cb(void *aux_, struct 
> > dp_packet_batch *packets_,
> >  case OVS_ACTION_ATTR_TUNNEL_PUSH:
> >  case OVS_ACTION_ATTR_TUNNEL_POP:
> >  case OVS_ACTION_ATTR_USERSPACE:
> > +case OVS_ACTION_ATTR_EMIT_SAMPLE:
> >  case OVS_ACTION_ATTR_RECIRC: {
> >  struct dpif_execute execute;
> >  struct ofpbuf execute_actions;
> > diff --git a/lib/odp-execute.c b/lib/odp-execute.c
> > index 081e4d432..967abfd0a 100644
> > --- a/lib/odp-execute.c
> > +++ b/lib/odp-execute.c
> > @@ -818,13 +818,13 @@ 

Re: [ovs-dev] [PATCH net-next v5 05/10] net: openvswitch: add emit_sample action

2024-06-27 Thread Adrián Moreno
On Thu, Jun 27, 2024 at 11:31:41AM GMT, Eelco Chaudron wrote:
>
>
> On 27 Jun 2024, at 11:23, Ilya Maximets wrote:
>
> > On 6/27/24 11:14, Eelco Chaudron wrote:
> >>
> >>
> >> On 27 Jun 2024, at 10:36, Ilya Maximets wrote:
> >>
> >>> On 6/27/24 09:52, Adrián Moreno wrote:
> >>>> On Thu, Jun 27, 2024 at 09:06:46AM GMT, Eelco Chaudron wrote:
> >>>>>
> >>>>>
> >>>>> On 26 Jun 2024, at 22:34, Adrián Moreno wrote:
> >>>>>
> >>>>>> On Wed, Jun 26, 2024 at 04:28:17PM GMT, Eelco Chaudron wrote:
> >>>>>>>
> >>>>>>>
> >>>>>>> On 25 Jun 2024, at 22:51, Adrian Moreno wrote:
> >>>>>>>
> >>>>>>>> Add support for a new action: emit_sample.
> >>>>>>>>
> >>>>>>>> This action accepts a u32 group id and a variable-length cookie and 
> >>>>>>>> uses
> >>>>>>>> the psample multicast group to make the packet available for
> >>>>>>>> observability.
> >>>>>>>>
> >>>>>>>> The maximum length of the user-defined cookie is set to 16, same as
> >>>>>>>> tc_cookie, to discourage using cookies that will not be offloadable.
> >>>>>>>
> >>>>>>> I’ll add the same comment as I had in the user space part, and that
> >>>>>>> is that I feel from an OVS perspective this action should be called
> >>>>>>> emit_local() instead of emit_sample() to make it Datapath independent.
> >>>>>>> Or quoting the earlier comment:
> >>>>>>>
> >>>>>>>
> >>>>>>> “I’ll start the discussion again on the naming. The name 
> >>>>>>> "emit_sample()"
> >>>>>>> does not seem appropriate. This function's primary role is to copy the
> >>>>>>> packet and send it to a local collector, which varies depending on the
> >>>>>>> datapath. For the kernel datapath, this collector is psample, while 
> >>>>>>> for
> >>>>>>> userspace, it will likely be some kind of probe. This action is 
> >>>>>>> distinct
> >>>>>>> from the sample() action by design; it is a standalone action that can
> >>>>>>> be combined with others.
> >>>>>>>
> >>>>>>> Furthermore, the action itself does not involve taking a sample; it
> >>>>>>> consistently pushes the packet to the local collector. Therefore, I
> >>>>>>> suggest renaming "emit_sample()" to "emit_local()". This same goes for
> >>>>>>> all the derivative ATTR naming.”
> >>>>>>>
> >>>>>>
> >>>>>> This is a blurry semantic area.
> >>>>>> IMO, "sample" is the act of extracting (potentially a piece of)
> >>>>>> someting, in this case, a packet. It is common to only take some 
> >>>>>> packets
> >>>>>> as samples, so this action usually comes with some kind of "rate", but
> >>>>>> even if the rate is 1, it's still sampling in this context.
> >>>>>>
> >>>>>> OTOH, OVS kernel design tries to be super-modular and define small
> >>>>>> combinable actions, so the rate or probability generation is done with
> >>>>>> another action which is (IMHO unfortunately) named "sample".
> >>>>>>
> >>>>>> With that interpretation of the term it would actually make more sense
> >>>>>> to rename "sample" to something like "random" (of course I'm not
> >>>>>> suggestion we do it). "sample" without any nested action that actually
> >>>>>> sends the packet somewhere is not sampling, it's just doing something 
> >>>>>> or
> >>>>>> not based on a probability. Where as "emit_sample" is sampling even if
> >>>>>> it's not nested inside a "sample".
> >>>>>
> >>>>> You're assuming we are extracting a packet for sampling, but this 
> >>>>> function
> >>>>> can b

Re: [ovs-dev] [PATCH net-next v5 10/10] selftests: openvswitch: add emit_sample test

2024-06-27 Thread Adrián Moreno
On Wed, Jun 26, 2024 at 01:15:21PM GMT, Ilya Maximets wrote:
> On 6/25/24 22:51, Adrian Moreno wrote:
> > Add a test to verify sampling packets via psample works.
> >
> > In order to do that, create a subcommand in ovs-dpctl.py to listen to
> > on the psample multicast group and print samples.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  .../selftests/net/openvswitch/openvswitch.sh  | 114 +-
> >  .../selftests/net/openvswitch/ovs-dpctl.py|  73 ++-
> >  2 files changed, 181 insertions(+), 6 deletions(-)
> >
> > diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh 
> > b/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > index 15bca0708717..aeb9bee772be 100755
> > --- a/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > +++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > @@ -20,7 +20,8 @@ tests="
> > nat_related_v4  ip4-nat-related: ICMP related 
> > matches work with SNAT
> > netlink_checks  ovsnl: validate netlink attrs 
> > and settings
> > upcall_interfaces   ovs: test the upcall interfaces
> > -   drop_reason drop: test drop reasons are 
> > emitted"
> > +   drop_reason drop: test drop reasons are 
> > emitted
> > +   emit_sample emit_sample: Sampling packets 
> > with psample"
>
> There is an extra space character right after emit_sample word.
> This makes './openvswitch.sh emit_sample' to not run the test,
> because 'emit_sample' != 'emit_sample '.
>

Wow, good catch! I'll get rid of that space.

Thanks.
Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH net-next v5 05/10] net: openvswitch: add emit_sample action

2024-06-27 Thread Adrián Moreno
On Thu, Jun 27, 2024 at 09:06:46AM GMT, Eelco Chaudron wrote:
>
>
> On 26 Jun 2024, at 22:34, Adrián Moreno wrote:
>
> > On Wed, Jun 26, 2024 at 04:28:17PM GMT, Eelco Chaudron wrote:
> >>
> >>
> >> On 25 Jun 2024, at 22:51, Adrian Moreno wrote:
> >>
> >>> Add support for a new action: emit_sample.
> >>>
> >>> This action accepts a u32 group id and a variable-length cookie and uses
> >>> the psample multicast group to make the packet available for
> >>> observability.
> >>>
> >>> The maximum length of the user-defined cookie is set to 16, same as
> >>> tc_cookie, to discourage using cookies that will not be offloadable.
> >>
> >> I’ll add the same comment as I had in the user space part, and that
> >> is that I feel from an OVS perspective this action should be called
> >> emit_local() instead of emit_sample() to make it Datapath independent.
> >> Or quoting the earlier comment:
> >>
> >>
> >> “I’ll start the discussion again on the naming. The name "emit_sample()"
> >> does not seem appropriate. This function's primary role is to copy the
> >> packet and send it to a local collector, which varies depending on the
> >> datapath. For the kernel datapath, this collector is psample, while for
> >> userspace, it will likely be some kind of probe. This action is distinct
> >> from the sample() action by design; it is a standalone action that can
> >> be combined with others.
> >>
> >> Furthermore, the action itself does not involve taking a sample; it
> >> consistently pushes the packet to the local collector. Therefore, I
> >> suggest renaming "emit_sample()" to "emit_local()". This same goes for
> >> all the derivative ATTR naming.”
> >>
> >
> > This is a blurry semantic area.
> > IMO, "sample" is the act of extracting (potentially a piece of)
> > someting, in this case, a packet. It is common to only take some packets
> > as samples, so this action usually comes with some kind of "rate", but
> > even if the rate is 1, it's still sampling in this context.
> >
> > OTOH, OVS kernel design tries to be super-modular and define small
> > combinable actions, so the rate or probability generation is done with
> > another action which is (IMHO unfortunately) named "sample".
> >
> > With that interpretation of the term it would actually make more sense
> > to rename "sample" to something like "random" (of course I'm not
> > suggestion we do it). "sample" without any nested action that actually
> > sends the packet somewhere is not sampling, it's just doing something or
> > not based on a probability. Where as "emit_sample" is sampling even if
> > it's not nested inside a "sample".
>
> You're assuming we are extracting a packet for sampling, but this function
> can be used for various other purposes. For instance, it could handle the
> packet outside of the OVS pipeline through an eBPF program (so we are not
> taking a sample, but continue packet processing outside of the OVS
> pipeline). Calling it emit_sampling() in such cases could be very
> confusing.
>

Well, I guess that would be clearly abusing the action. You could say
that of anything really. You could hook into skb_consume and continue
processing the skb but that doesn't change the intended behavior of the
drop action.

The intended behavior of the action is sampling, as is the intended
behavior of "psample".

> > Having said that, I don't have a super strong favor for "emit_sample". I'm
> > OK with "emit_local" or "emit_packet" or even just "emit".
> > I don't think any term will fully satisfy everyone so I hope we can find
> > a reasonable compromise.
>
> My preference would be emit_local() as we hand it off to some local
> datapath entity.
>

I'm OK removing the controversial term. Let's see what others think.

> >>> Signed-off-by: Adrian Moreno 
> >>> ---
> >>>  Documentation/netlink/specs/ovs_flow.yaml | 17 +
> >>>  include/uapi/linux/openvswitch.h  | 28 ++
> >>>  net/openvswitch/Kconfig   |  1 +
> >>>  net/openvswitch/actions.c | 45 +++
> >>>  net/openvswitch/flow_netlink.c| 33 -
> >>>  5 files changed, 123 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/Documentation/

Re: [ovs-dev] [PATCH net-next v5 05/10] net: openvswitch: add emit_sample action

2024-06-26 Thread Adrián Moreno
On Wed, Jun 26, 2024 at 04:28:17PM GMT, Eelco Chaudron wrote:
>
>
> On 25 Jun 2024, at 22:51, Adrian Moreno wrote:
>
> > Add support for a new action: emit_sample.
> >
> > This action accepts a u32 group id and a variable-length cookie and uses
> > the psample multicast group to make the packet available for
> > observability.
> >
> > The maximum length of the user-defined cookie is set to 16, same as
> > tc_cookie, to discourage using cookies that will not be offloadable.
>
> I’ll add the same comment as I had in the user space part, and that
> is that I feel from an OVS perspective this action should be called
> emit_local() instead of emit_sample() to make it Datapath independent.
> Or quoting the earlier comment:
>
>
> “I’ll start the discussion again on the naming. The name "emit_sample()"
> does not seem appropriate. This function's primary role is to copy the
> packet and send it to a local collector, which varies depending on the
> datapath. For the kernel datapath, this collector is psample, while for
> userspace, it will likely be some kind of probe. This action is distinct
> from the sample() action by design; it is a standalone action that can
> be combined with others.
>
> Furthermore, the action itself does not involve taking a sample; it
> consistently pushes the packet to the local collector. Therefore, I
> suggest renaming "emit_sample()" to "emit_local()". This same goes for
> all the derivative ATTR naming.”
>

This is a blurry semantic area.
IMO, "sample" is the act of extracting (potentially a piece of)
someting, in this case, a packet. It is common to only take some packets
as samples, so this action usually comes with some kind of "rate", but
even if the rate is 1, it's still sampling in this context.

OTOH, OVS kernel design tries to be super-modular and define small
combinable actions, so the rate or probability generation is done with
another action which is (IMHO unfortunately) named "sample".

With that interpretation of the term it would actually make more sense
to rename "sample" to something like "random" (of course I'm not
suggestion we do it). "sample" without any nested action that actually
sends the packet somewhere is not sampling, it's just doing something or
not based on a probability. Where as "emit_sample" is sampling even if
it's not nested inside a "sample".

Having said that, I don't have a super strong favor for "emit_sample". I'm
OK with "emit_local" or "emit_packet" or even just "emit".
I don't think any term will fully satisfy everyone so I hope we can find
a reasonable compromise.


> > Signed-off-by: Adrian Moreno 
> > ---
> >  Documentation/netlink/specs/ovs_flow.yaml | 17 +
> >  include/uapi/linux/openvswitch.h  | 28 ++
> >  net/openvswitch/Kconfig   |  1 +
> >  net/openvswitch/actions.c | 45 +++
> >  net/openvswitch/flow_netlink.c| 33 -
> >  5 files changed, 123 insertions(+), 1 deletion(-)
> >
> > diff --git a/Documentation/netlink/specs/ovs_flow.yaml 
> > b/Documentation/netlink/specs/ovs_flow.yaml
> > index 4fdfc6b5cae9..a7ab5593a24f 100644
> > --- a/Documentation/netlink/specs/ovs_flow.yaml
> > +++ b/Documentation/netlink/specs/ovs_flow.yaml
> > @@ -727,6 +727,12 @@ attribute-sets:
> >  name: dec-ttl
> >  type: nest
> >  nested-attributes: dec-ttl-attrs
> > +  -
> > +name: emit-sample
> > +type: nest
> > +nested-attributes: emit-sample-attrs
> > +doc: |
> > +  Sends a packet sample to psample for external observation.
> >-
> >  name: tunnel-key-attrs
> >  enum-name: ovs-tunnel-key-attr
> > @@ -938,6 +944,17 @@ attribute-sets:
> >-
> >  name: gbp
> >  type: u32
> > +  -
> > +name: emit-sample-attrs
> > +enum-name: ovs-emit-sample-attr
> > +name-prefix: ovs-emit-sample-attr-
> > +attributes:
> > +  -
> > +name: group
> > +type: u32
> > +  -
> > +name: cookie
> > +type: binary
> >
> >  operations:
> >name-prefix: ovs-flow-cmd-
> > diff --git a/include/uapi/linux/openvswitch.h 
> > b/include/uapi/linux/openvswitch.h
> > index efc82c318fa2..8cfa1b3f6b06 100644
> > --- a/include/uapi/linux/openvswitch.h
> > +++ b/include/uapi/linux/openvswitch.h
> > @@ -914,6 +914,31 @@ struct check_pkt_len_arg {
> >  };
> >  #endif
> >
> > +#define OVS_EMIT_SAMPLE_COOKIE_MAX_SIZE 16
> > +/**
> > + * enum ovs_emit_sample_attr - Attributes for %OVS_ACTION_ATTR_EMIT_SAMPLE
> > + * action.
> > + *
> > + * @OVS_EMIT_SAMPLE_ATTR_GROUP: 32-bit number to identify the source of the
> > + * sample.
> > + * @OVS_EMIT_SAMPLE_ATTR_COOKIE: A variable-length binary cookie that 
> > contains
> > + * user-defined metadata. The maximum length is 
> > OVS_EMIT_SAMPLE_COOKIE_MAX_SIZE
> > + * bytes.
> > + *
> > + * Sends the packet to the psample multicast group with the specified 
> > group and
> > + * cookie. It is possible 

Re: [ovs-dev] [PATCH net-next v5 05/10] net: openvswitch: add emit_sample action

2024-06-26 Thread Adrián Moreno
On Wed, Jun 26, 2024 at 12:51:19PM GMT, Ilya Maximets wrote:
> On 6/25/24 22:51, Adrian Moreno wrote:
> > Add support for a new action: emit_sample.
> >
> > This action accepts a u32 group id and a variable-length cookie and uses
> > the psample multicast group to make the packet available for
> > observability.
> >
> > The maximum length of the user-defined cookie is set to 16, same as
> > tc_cookie, to discourage using cookies that will not be offloadable.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  Documentation/netlink/specs/ovs_flow.yaml | 17 +
> >  include/uapi/linux/openvswitch.h  | 28 ++
> >  net/openvswitch/Kconfig   |  1 +
> >  net/openvswitch/actions.c | 45 +++
> >  net/openvswitch/flow_netlink.c| 33 -
> >  5 files changed, 123 insertions(+), 1 deletion(-)
> >
> > diff --git a/Documentation/netlink/specs/ovs_flow.yaml 
> > b/Documentation/netlink/specs/ovs_flow.yaml
> > index 4fdfc6b5cae9..a7ab5593a24f 100644
> > --- a/Documentation/netlink/specs/ovs_flow.yaml
> > +++ b/Documentation/netlink/specs/ovs_flow.yaml
> > @@ -727,6 +727,12 @@ attribute-sets:
> >  name: dec-ttl
> >  type: nest
> >  nested-attributes: dec-ttl-attrs
> > +  -
> > +name: emit-sample
> > +type: nest
> > +nested-attributes: emit-sample-attrs
> > +doc: |
> > +  Sends a packet sample to psample for external observation.
> >-
> >  name: tunnel-key-attrs
> >  enum-name: ovs-tunnel-key-attr
> > @@ -938,6 +944,17 @@ attribute-sets:
> >-
> >  name: gbp
> >  type: u32
> > +  -
> > +name: emit-sample-attrs
> > +enum-name: ovs-emit-sample-attr
> > +name-prefix: ovs-emit-sample-attr-
> > +attributes:
> > +  -
> > +name: group
> > +type: u32
> > +  -
> > +name: cookie
> > +type: binary
> >
> >  operations:
> >name-prefix: ovs-flow-cmd-
> > diff --git a/include/uapi/linux/openvswitch.h 
> > b/include/uapi/linux/openvswitch.h
> > index efc82c318fa2..8cfa1b3f6b06 100644
> > --- a/include/uapi/linux/openvswitch.h
> > +++ b/include/uapi/linux/openvswitch.h
> > @@ -914,6 +914,31 @@ struct check_pkt_len_arg {
> >  };
> >  #endif
> >
> > +#define OVS_EMIT_SAMPLE_COOKIE_MAX_SIZE 16
> > +/**
> > + * enum ovs_emit_sample_attr - Attributes for %OVS_ACTION_ATTR_EMIT_SAMPLE
> > + * action.
> > + *
> > + * @OVS_EMIT_SAMPLE_ATTR_GROUP: 32-bit number to identify the source of the
> > + * sample.
> > + * @OVS_EMIT_SAMPLE_ATTR_COOKIE: A variable-length binary cookie that 
> > contains
> > + * user-defined metadata. The maximum length is 
> > OVS_EMIT_SAMPLE_COOKIE_MAX_SIZE
> > + * bytes.
> > + *
> > + * Sends the packet to the psample multicast group with the specified 
> > group and
> > + * cookie. It is possible to combine this action with the
> > + * %OVS_ACTION_ATTR_TRUNC action to limit the size of the packet being 
> > emitted.
> > + */
> > +enum ovs_emit_sample_attr {
> > +   OVS_EMIT_SAMPLE_ATTR_GROUP = 1, /* u32 number. */
> > +   OVS_EMIT_SAMPLE_ATTR_COOKIE,/* Optional, user specified cookie. */
> > +
> > +   /* private: */
> > +   __OVS_EMIT_SAMPLE_ATTR_MAX
> > +};
> > +
> > +#define OVS_EMIT_SAMPLE_ATTR_MAX (__OVS_EMIT_SAMPLE_ATTR_MAX - 1)
> > +
> >  /**
> >   * enum ovs_action_attr - Action types.
> >   *
> > @@ -966,6 +991,8 @@ struct check_pkt_len_arg {
> >   * of l3 tunnel flag in the tun_flags field of OVS_ACTION_ATTR_ADD_MPLS
> >   * argument.
> >   * @OVS_ACTION_ATTR_DROP: Explicit drop action.
> > + * @OVS_ACTION_ATTR_EMIT_SAMPLE: Send a sample of the packet to external
> > + * observers via psample.
> >   *
> >   * Only a single header can be set with a single %OVS_ACTION_ATTR_SET.  
> > Not all
> >   * fields within a header are modifiable, e.g. the IPv4 protocol and 
> > fragment
> > @@ -1004,6 +1031,7 @@ enum ovs_action_attr {
> > OVS_ACTION_ATTR_ADD_MPLS, /* struct ovs_action_add_mpls. */
> > OVS_ACTION_ATTR_DEC_TTL,  /* Nested OVS_DEC_TTL_ATTR_*. */
> > OVS_ACTION_ATTR_DROP, /* u32 error code. */
> > +   OVS_ACTION_ATTR_EMIT_SAMPLE,  /* Nested OVS_EMIT_SAMPLE_ATTR_*. */
> >
> > __OVS_ACTION_ATTR_MAX,/* Nothing past this will be accepted
> >* from userspace. */
> > diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig
> > index 29a7081858cd..2535f3f9f462 100644
> > --- a/net/openvswitch/Kconfig
> > +++ b/net/openvswitch/Kconfig
> > @@ -10,6 +10,7 @@ config OPENVSWITCH
> >(NF_CONNTRACK && ((!NF_DEFRAG_IPV6 || NF_DEFRAG_IPV6) && \
> >  (!NF_NAT || NF_NAT) && \
> >  (!NETFILTER_CONNCOUNT || 
> > NETFILTER_CONNCOUNT)))
> > +   depends on PSAMPLE || !PSAMPLE
> > select LIBCRC32C
> > select MPLS
> > select NET_MPLS_GSO
> > diff --git a/net/openvswitch/actions.c 

Re: [ovs-dev] [PATCH net-next v5 02/10] net: sched: act_sample: add action cookie to sample

2024-06-26 Thread Adrián Moreno
On Wed, Jun 26, 2024 at 04:28:01PM GMT, Eelco Chaudron wrote:
>
>
> On 25 Jun 2024, at 22:51, Adrian Moreno wrote:
>
> > If the action has a user_cookie, pass it along to the sample so it can
> > be easily identified.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  net/sched/act_sample.c | 12 
> >  1 file changed, 12 insertions(+)
> >
> > diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c
> > index a69b53d54039..2ceb4d141b71 100644
> > --- a/net/sched/act_sample.c
> > +++ b/net/sched/act_sample.c
> > @@ -167,7 +167,9 @@ TC_INDIRECT_SCOPE int tcf_sample_act(struct sk_buff 
> > *skb,
> >  {
> > struct tcf_sample *s = to_sample(a);
> > struct psample_group *psample_group;
> > +   u8 cookie_data[TC_COOKIE_MAX_SIZE];
> > struct psample_metadata md = {};
> > +   struct tc_cookie *user_cookie;
> > int retval;
> >
> > tcf_lastuse_update(>tcf_tm);
> > @@ -189,6 +191,16 @@ TC_INDIRECT_SCOPE int tcf_sample_act(struct sk_buff 
> > *skb,
> > if (skb_at_tc_ingress(skb) && tcf_sample_dev_ok_push(skb->dev))
> > skb_push(skb, skb->mac_len);
> >
> > +   rcu_read_lock();
> > +   user_cookie = rcu_dereference(a->user_cookie);
> > +   if (user_cookie) {
> > +   memcpy(cookie_data, user_cookie->data,
> > +  user_cookie->len);
>
> Maybe I’m over paranoid, but can we assume user_cookie->len, will not be 
> larger than TC_COOKIE_MAX_SIZE?
> Or should we do something like min(user_cookie->len, sizeof(cookie_data))
>

I think it's good to be paranoid with this kind of things. I do,
however, think it should be safe to use. The cookie is extracted from
the netlink attribute directly and its length is verified with the
nla_policy [1]. So nothing that comes into the kernel should be larger
than TC_COOKIE_MAX_SIZE.

I guess if there is some previous bug that allows for the size to get
corrupted, then this might happen but doing those kind of checks in the
fast path seems a bit excessive. For example, Ilya argued in v2 [2] that
we should avoid zeroing "u8 cookie_data[TC_COOKIE_MAX_SIZE]" to safe the
unneeded cycles.

[1] 
https://github.com/torvalds/linux/blob/55027e689933ba2e64f3d245fb1ff185b3e7fc81/net/sched/act_api.c#L1299
[2] 
https://patchwork.kernel.org/project/netdevbpf/patch/20240603185647.2310748-3-amore...@redhat.com/

Thanks.
Adrián

> > +   md.user_cookie = cookie_data;
> > +   md.user_cookie_len = user_cookie->len;
> > +   }
> > +   rcu_read_unlock();
> > +
> > md.trunc_size = s->truncate ? s->trunc_size : skb->len;
> > psample_sample_packet(psample_group, skb, s->rate, );
> >
> > --
> > 2.45.1
>

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [RFC v2 5/9] ofproto-dpif-xlate: Use emit_sample for local sample.

2024-06-26 Thread Adrián Moreno
On Wed, Jun 26, 2024 at 11:28:57AM GMT, Ilya Maximets wrote:
> On 6/26/24 07:14, Adrián Moreno wrote:
> > On Tue, Jun 25, 2024 at 11:04:42PM GMT, Ilya Maximets wrote:
> >> On 6/25/24 22:53, Adrián Moreno wrote:
> >>> On Mon, Jun 24, 2024 at 07:43:32PM GMT, Adrián Moreno wrote:
> >>>> On Mon, Jun 24, 2024 at 04:05:36PM GMT, Ilya Maximets wrote:
> >>>>> On 6/24/24 15:19, Adrián Moreno wrote:
> >>>>>> On Mon, Jun 24, 2024 at 01:37:44PM GMT, Ilya Maximets wrote:
> >>>>>>> On 6/5/24 22:23, Adrian Moreno wrote:
> >>>>>>>> Use the newly added emit_sample to implement OpenFlow sample() 
> >>>>>>>> actions
> >>>>>>>> with local sampling configuration.
> >>>>>>>>
> >>>>>>>> Signed-off-by: Adrian Moreno 
> >>>>>>>> ---
> >>>>>>>>  ofproto/ofproto-dpif-lsample.c |  17 
> >>>>>>>>  ofproto/ofproto-dpif-lsample.h |   6 ++
> >>>>>>>>  ofproto/ofproto-dpif-xlate.c   | 163 
> >>>>>>>> -
> >>>>>>>>  ofproto/ofproto-dpif-xlate.h   |   3 +-
> >>>>>>>>  ofproto/ofproto-dpif.c |   2 +-
> >>>>>>>>  5 files changed, 144 insertions(+), 47 deletions(-)
> >>>>>>>
> >>>>>>> Not a full review, just a note that this patch needs tests in 
> >>>>>>> ofproto-dpif.at
> >>>>>>> that would check that we generate correct datapath flows.
> >>>>>>>
> >>>>>>
> >>>>>> I thought about that, but ofproto-dpif.at is based on dummy datapat
> >>>>>> (userspace) which does not support this action. The configuration will
> >>>>>> be ignored and the datapath actions will not be generated. That's why I
> >>>>>> relied on system-traffic.at tests. Do you see any way around this?
> >>>>>
> >>>>> We don't need actual datapath support if we're not sending any actual
> >>>>> trafic.  You should be able to just turn on the capability and check
> >>>>> that ofproto/trace generates correct actions.
> >>>>>
> >>>>> We test kernel tunnels this way, for example.  See the macro
> >>>>> OVS_VSWITCHD_DISABLE_TUNNEL_PUSH_POP.  And some other similar checks.
> >>>>>
> >>>>
> >>>
> >>> Tried it but it doesn't seem to work. I now remember I hit this issue
> >>> originally :-).
> >>> We cannot enable a capability beyond the datapath's "boot time"
> >>> capabilities.
> >>>
> >>> If you try to run
> >>> "ovs-appctl dpif/set-dp-features br0 emit_sample true", the command
> >>> fails with:
> >>> "Can not enable features not supported by the datapth"
> >>>
> >>> The safeguard does make sense in general (prevents users from
> >>> knee-capping themselves) but for testing maybe we want to force it?
> >>>
> >>> OTOH, marking this feature as supported in the userspace datapath would
> >>> not be catastrophic, we could just warn the action is not supported
> >>> in odp_execute(), or consider VLOG_DBG_RL as current implementation
> >>> until we come up with a good one. However, I cannot of a good way of
> >>> of properly reporting this to the user beforehand so I think it could
> >>> still cause a lot of confusion.
> >>>
> >>> Thoughts?
> >>
> >> Hmm.  This command is generally for testing only or experiments.
> >> It's not documented and hence we do not support changing datapath
> >> features in runtime.
> >
> > Oh! It's true that it's docummented, although it does appear in
> > "list-commands". I thought we supported disabling features, I guess we
> > might on a case-by-case basis and through OVSDB.
> >
> >>
> >> It should be fine to add another command like force-dp-features to
> >> overcome the restriction.  Just make sure that it is not documented
> >> and doesn't appear in the list-commands output.
> >>
> >
> > If "set-dp-features" is already an exceptional path, can't we just add a
> > "--force" option to it?
>
> I guess, it's fine to add a flag.  Just don't document it.  But, please,
> add a scary warning in this case saying that unsupported feature is enabled
> and the behavior is unpredictable from this point on.  Tests can ignore the
> warning.
>

I will not documment it but I don't think we should remove from
"list-commands" either.

And sure, I'll add a scary warning.

Thanks.
Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [RFC v2 5/9] ofproto-dpif-xlate: Use emit_sample for local sample.

2024-06-25 Thread Adrián Moreno
On Tue, Jun 25, 2024 at 11:04:42PM GMT, Ilya Maximets wrote:
> On 6/25/24 22:53, Adrián Moreno wrote:
> > On Mon, Jun 24, 2024 at 07:43:32PM GMT, Adrián Moreno wrote:
> >> On Mon, Jun 24, 2024 at 04:05:36PM GMT, Ilya Maximets wrote:
> >>> On 6/24/24 15:19, Adrián Moreno wrote:
> >>>> On Mon, Jun 24, 2024 at 01:37:44PM GMT, Ilya Maximets wrote:
> >>>>> On 6/5/24 22:23, Adrian Moreno wrote:
> >>>>>> Use the newly added emit_sample to implement OpenFlow sample() actions
> >>>>>> with local sampling configuration.
> >>>>>>
> >>>>>> Signed-off-by: Adrian Moreno 
> >>>>>> ---
> >>>>>>  ofproto/ofproto-dpif-lsample.c |  17 
> >>>>>>  ofproto/ofproto-dpif-lsample.h |   6 ++
> >>>>>>  ofproto/ofproto-dpif-xlate.c   | 163 -
> >>>>>>  ofproto/ofproto-dpif-xlate.h   |   3 +-
> >>>>>>  ofproto/ofproto-dpif.c |   2 +-
> >>>>>>  5 files changed, 144 insertions(+), 47 deletions(-)
> >>>>>
> >>>>> Not a full review, just a note that this patch needs tests in 
> >>>>> ofproto-dpif.at
> >>>>> that would check that we generate correct datapath flows.
> >>>>>
> >>>>
> >>>> I thought about that, but ofproto-dpif.at is based on dummy datapat
> >>>> (userspace) which does not support this action. The configuration will
> >>>> be ignored and the datapath actions will not be generated. That's why I
> >>>> relied on system-traffic.at tests. Do you see any way around this?
> >>>
> >>> We don't need actual datapath support if we're not sending any actual
> >>> trafic.  You should be able to just turn on the capability and check
> >>> that ofproto/trace generates correct actions.
> >>>
> >>> We test kernel tunnels this way, for example.  See the macro
> >>> OVS_VSWITCHD_DISABLE_TUNNEL_PUSH_POP.  And some other similar checks.
> >>>
> >>
> >
> > Tried it but it doesn't seem to work. I now remember I hit this issue
> > originally :-).
> > We cannot enable a capability beyond the datapath's "boot time"
> > capabilities.
> >
> > If you try to run
> > "ovs-appctl dpif/set-dp-features br0 emit_sample true", the command
> > fails with:
> > "Can not enable features not supported by the datapth"
> >
> > The safeguard does make sense in general (prevents users from
> > knee-capping themselves) but for testing maybe we want to force it?
> >
> > OTOH, marking this feature as supported in the userspace datapath would
> > not be catastrophic, we could just warn the action is not supported
> > in odp_execute(), or consider VLOG_DBG_RL as current implementation
> > until we come up with a good one. However, I cannot of a good way of
> > of properly reporting this to the user beforehand so I think it could
> > still cause a lot of confusion.
> >
> > Thoughts?
>
> Hmm.  This command is generally for testing only or experiments.
> It's not documented and hence we do not support changing datapath
> features in runtime.

Oh! It's true that it's docummented, although it does appear in
"list-commands". I thought we supported disabling features, I guess we
might on a case-by-case basis and through OVSDB.

>
> It should be fine to add another command like force-dp-features to
> overcome the restriction.  Just make sure that it is not documented
> and doesn't appear in the list-commands output.
>

If "set-dp-features" is already an exceptional path, can't we just add a
"--force" option to it?

Thanks.
Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [RFC v2 5/9] ofproto-dpif-xlate: Use emit_sample for local sample.

2024-06-25 Thread Adrián Moreno
On Mon, Jun 24, 2024 at 07:43:32PM GMT, Adrián Moreno wrote:
> On Mon, Jun 24, 2024 at 04:05:36PM GMT, Ilya Maximets wrote:
> > On 6/24/24 15:19, Adrián Moreno wrote:
> > > On Mon, Jun 24, 2024 at 01:37:44PM GMT, Ilya Maximets wrote:
> > >> On 6/5/24 22:23, Adrian Moreno wrote:
> > >>> Use the newly added emit_sample to implement OpenFlow sample() actions
> > >>> with local sampling configuration.
> > >>>
> > >>> Signed-off-by: Adrian Moreno 
> > >>> ---
> > >>>  ofproto/ofproto-dpif-lsample.c |  17 
> > >>>  ofproto/ofproto-dpif-lsample.h |   6 ++
> > >>>  ofproto/ofproto-dpif-xlate.c   | 163 -
> > >>>  ofproto/ofproto-dpif-xlate.h   |   3 +-
> > >>>  ofproto/ofproto-dpif.c |   2 +-
> > >>>  5 files changed, 144 insertions(+), 47 deletions(-)
> > >>
> > >> Not a full review, just a note that this patch needs tests in 
> > >> ofproto-dpif.at
> > >> that would check that we generate correct datapath flows.
> > >>
> > >
> > > I thought about that, but ofproto-dpif.at is based on dummy datapat
> > > (userspace) which does not support this action. The configuration will
> > > be ignored and the datapath actions will not be generated. That's why I
> > > relied on system-traffic.at tests. Do you see any way around this?
> >
> > We don't need actual datapath support if we're not sending any actual
> > trafic.  You should be able to just turn on the capability and check
> > that ofproto/trace generates correct actions.
> >
> > We test kernel tunnels this way, for example.  See the macro
> > OVS_VSWITCHD_DISABLE_TUNNEL_PUSH_POP.  And some other similar checks.
> >
>

Tried it but it doesn't seem to work. I now remember I hit this issue
originally :-).
We cannot enable a capability beyond the datapath's "boot time"
capabilities.

If you try to run
"ovs-appctl dpif/set-dp-features br0 emit_sample true", the command
fails with:
"Can not enable features not supported by the datapth"

The safeguard does make sense in general (prevents users from
knee-capping themselves) but for testing maybe we want to force it?

OTOH, marking this feature as supported in the userspace datapath would
not be catastrophic, we could just warn the action is not supported
in odp_execute(), or consider VLOG_DBG_RL as current implementation
until we come up with a good one. However, I cannot of a good way of
of properly reporting this to the user beforehand so I think it could
still cause a lot of confusion.

Thoughts?

Thanks.
Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH net-next v4 04/10] net: psample: allow using rate as probability

2024-06-25 Thread Adrián Moreno
On Tue, Jun 25, 2024 at 01:17:19PM GMT, Paolo Abeni wrote:
> On Fri, 2024-06-21 at 12:10 +0200, Adrian Moreno wrote:
> > diff --git a/include/uapi/linux/tc_act/tc_sample.h 
> > b/include/uapi/linux/tc_act/tc_sample.h
> > index fee1bcc20793..7ee0735e7b38 100644
> > --- a/include/uapi/linux/tc_act/tc_sample.h
> > +++ b/include/uapi/linux/tc_act/tc_sample.h
> > @@ -18,6 +18,7 @@ enum {
> > TCA_SAMPLE_TRUNC_SIZE,
> > TCA_SAMPLE_PSAMPLE_GROUP,
> > TCA_SAMPLE_PAD,
> > +   TCA_SAMPLE_PROBABILITY,
> > __TCA_SAMPLE_MAX
> >  };
> >  #define TCA_SAMPLE_MAX (__TCA_SAMPLE_MAX - 1)
>
> I believe Ilya's comment on v3 is correct, this chunk looks unrelated
> and unneeded. I guess you can drop it? Or am I missing something?
>

Thanks both for spotting it. I'll send v5 without it.

> Thanks,
>
> Paolo
>

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [RFC v2 9/9] tests: Test local sampling.

2024-06-25 Thread Adrián Moreno
On Mon, Jun 24, 2024 at 08:26:44PM GMT, Ilya Maximets wrote:
> On 6/24/24 20:00, Adrián Moreno wrote:
> > On Mon, Jun 24, 2024 at 02:03:00PM GMT, Ilya Maximets wrote:
> > [...]
> >>
> >> Why are we adding IPFIX?  This should work without IPFIX.
> >>
> >> Having both together can be a separate test.
> >>
> >>> +
> >>> +AT_DATA([flows.txt], [dnl
> >>> +in_port=ovs-p0,ip 
> >>> actions=sample(probability=65535,collector_set_id=1,obs_domain_id=1431655765,obs_point_id=1717986918),output(port=ovs-p1,max_len=100)
> >>> +in_port=ovs-p1,ip 
> >>> actions=sample(probability=65535,collector_set_id=2,obs_domain_id=2290649224,obs_point_id=2576980377),output(port=ovs-p0,max_len=100)
> >>
> >> It should be possible to wrap these lines a little with dnl.
> >
> > I'm curious about wrapping requirements for flows in tests.
> > None of them seem to be wrapped, splitting matches and actions won't
> > make lines much shorter and having more exotic wrapped & indented
> > action arguments seem strage to read (for eyes made to read flows in
> > a single line). What wrapping do you have in mind?
>
> No hard requirements, but I find lines that long hard to read
> since they are going out of the window width for me and getting
> wrapped in random places.
>
>
> AT_DATA([flows.txt], [dnl
> in_port=ovs-p0,ip dnl
> actions=dnl
>  sample( dnl
>   probability=65535, dnl
>   collector_set_id=1,dnl
>   obs_domain_id=1431655765,  dnl
>   obs_point_id=1717986918),  dnl
>  output(port=ovs-p1,max_len=100)
> ...
>
> I agree that above is not very readable...
>
> Or
>
> AT_DATA([flows.txt], [dnl
> m4_join([], [
>   [in_port=ovs-p0,ip], [ ],
>   [actions=],
>
> [sample(probability=65535,collector_set_id=1,obs_domain_id=1431655765,obs_point_id=1717986918)],
>[output(port=ovs-p1,max_len=100)]
> ]
> m4_join([], [
>   [in_port=ovs-p1,ip], [ ],
>   [actions=],
>
> [sample(probability=65535,collector_set_id=2,obs_domain_id=2290649224,obs_point_id=2576980377)],
>[output(port=ovs-p0,max_len=100)]
> ]
> )
>
> Or maybe just shorten the lines with a macro:
>
> m4_define([SAMPLE_ACTION],
>  
> [sample(probability=65535,collector_set_id=$1,obs_domain_id=$2,obs_point_id=$3)]
> )
>
> AT_DATA([flows.txt], [dnl
> in_port=ovs-p0,ip actions=SAMPLE_ACTION(1, 1431655765, 1717986918), 
> output(port=ovs-p1,max_len=100)
> in_port=ovs-p1,ip actions=SAMPLE_ACTION(2, 2290649224, 2576980377), 
> output(port=ovs-p0,max_len=100)
> ])
>

I prefer this one. I'll give it a try.

Thanks.
Adrián

> (Haven't tested any of these)
>
> Best regards, Ilya Maximets.
>

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [RFC v2 9/9] tests: Test local sampling.

2024-06-25 Thread Adrián Moreno
On Mon, Jun 24, 2024 at 07:57:28PM GMT, Ilya Maximets wrote:
> On 6/24/24 19:38, Adrián Moreno wrote:
> > On Mon, Jun 24, 2024 at 04:15:50PM GMT, Ilya Maximets wrote:
> >> On 6/24/24 15:14, Adrián Moreno wrote:
> >>> On Mon, Jun 24, 2024 at 02:03:00PM GMT, Ilya Maximets wrote:
> >>>> On 6/5/24 22:23, Adrian Moreno wrote:
> >>>>> Test simultaneous IPFIX and local sampling including slow-path.
> >>>>>
> >>>>> Signed-off-by: Adrian Moreno 
> >>>>> ---
> >>>>>  tests/system-common-macros.at |   4 ++
> >>>>>  tests/system-traffic.at   | 105 ++
> >>>>>  2 files changed, 109 insertions(+)
> >>>>>
> >>>>
> >>>> Not a full review, but see a few comments below.
> >>>>
> >>>>> diff --git a/tests/system-common-macros.at 
> >>>>> b/tests/system-common-macros.at
> >>>>> index 2a68cd664..22b8885e4 100644
> >>>>> --- a/tests/system-common-macros.at
> >>>>> +++ b/tests/system-common-macros.at
> >>>>> @@ -378,3 +378,7 @@ m4_define([OVS_CHECK_GITHUB_ACTION],
> >>>>>  # OVS_CHECK_DROP_ACTION()
> >>>>>  m4_define([OVS_CHECK_DROP_ACTION],
> >>>>>  [AT_SKIP_IF([! grep -q "Datapath supports explicit drop action" 
> >>>>> ovs-vswitchd.log])])
> >>>>> +
> >>>>> +# OVS_CHECK_EMIT_SAMPLE()
> >>>>> +m4_define([OVS_CHECK_EMIT_SAMPLE],
> >>>>> +[AT_SKIP_IF([! grep -q "Datapath supports emit_sample" 
> >>>>> ovs-vswitchd.log])])
> >>>>> diff --git a/tests/system-traffic.at b/tests/system-traffic.at
> >>>>> index bd7647cbe..babc56b56 100644
> >>>>> --- a/tests/system-traffic.at
> >>>>> +++ b/tests/system-traffic.at
> >>>>> @@ -8977,3 +8977,108 @@ OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0050: 
> >>>>> * * *5002 *2000 *b85e *00
> >>>>>
> >>>>>  OVS_TRAFFIC_VSWITCHD_STOP
> >>>>>  AT_CLEANUP
> >>>>> +
> >>>>> +AT_SETUP([emit_sample])
> >>>>
> >>>> Other tests have a test group name at the beginning.
> >>>> You're also adding the test into NSH section.  Add a new section, e.g.,
> >>>> 'sampling' for this with AT_BANNER.
> >>>>
> >>>
> >>> Thanks. Will do.
> >>>
> >>>>> +OVS_TRAFFIC_VSWITCHD_START()
> >>>>> +OVS_CHECK_EMIT_SAMPLE()
> >>>>> +
> >>>>> +ADD_NAMESPACES(at_ns0, at_ns1)
> >>>>> +NS_CHECK_EXEC([at_ns0], [sysctl -w net.ipv6.conf.all.disable_ipv6=1], 
> >>>>> [0], [ignore])
> >>>>> +NS_CHECK_EXEC([at_ns1], [sysctl -w net.ipv6.conf.all.disable_ipv6=1], 
> >>>>> [0], [ignore])
> >>>>
> >>>> This looks strange, don't disable IPv6.  Appropriate datapath actions
> >>>> should not forward IPv6 traffic, if that is a desired behavior.
> >>>>
> >>>
> >>> I found tests cleaner if automatic ipv6 traffic is not sent by ports.
> >>> But sure, I can deal with that with OpenFlow.
> >>
> >> Would be good to have two separate tests.  One for IPv4 and one for IPv6.
> >>
> >>>
> >>>> Though, I guess, it would be nice to test capturing both IPv4 and IPv6.
> >>>>
> >>>>> +
> >>>>> +ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24", "e4:11:22:33:44:55")
> >>>>> +ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24", "e4:11:22:33:44:66")
> >>>>> +
> >>>>> +NS_CHECK_EXEC([at_ns0], [arp -s 10.1.1.2 e4:11:22:33:44:66])
> >>>>> +NS_CHECK_EXEC([at_ns1], [arp -s 10.1.1.1 e4:11:22:33:44:55])
> >>>>> +
> >>>>> +
> >>>>> +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg 
> >>>>> ofproto_dpif_upcall:dbg])
> >>>>> +
> >>>>> +AT_CHECK([ovs-vsctl -- --id=@br0 get Bridge br0 \
> >>>>> +-- --id=@ipfix create IPFIX 
> >>>>> targets=\"127.0.0.1:4739\" \
> >>>>> +-- create Flow_Sample_Collector_Set id=1 
> >>>>> bridge=@br0 ipfix=@ipfix, local

Re: [ovs-dev] [RFC v2 9/9] tests: Test local sampling.

2024-06-24 Thread Adrián Moreno
On Mon, Jun 24, 2024 at 02:03:00PM GMT, Ilya Maximets wrote:
[...]
>
> Why are we adding IPFIX?  This should work without IPFIX.
>
> Having both together can be a separate test.
>
> > +
> > +AT_DATA([flows.txt], [dnl
> > +in_port=ovs-p0,ip 
> > actions=sample(probability=65535,collector_set_id=1,obs_domain_id=1431655765,obs_point_id=1717986918),output(port=ovs-p1,max_len=100)
> > +in_port=ovs-p1,ip 
> > actions=sample(probability=65535,collector_set_id=2,obs_domain_id=2290649224,obs_point_id=2576980377),output(port=ovs-p0,max_len=100)
>
> It should be possible to wrap these lines a little with dnl.

I'm curious about wrapping requirements for flows in tests.
None of them seem to be wrapped, splitting matches and actions won't
make lines much shorter and having more exotic wrapped & indented
action arguments seem strage to read (for eyes made to read flows in
a single line). What wrapping do you have in mind?

Thanks.
Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [RFC v2 5/9] ofproto-dpif-xlate: Use emit_sample for local sample.

2024-06-24 Thread Adrián Moreno
On Mon, Jun 24, 2024 at 04:05:36PM GMT, Ilya Maximets wrote:
> On 6/24/24 15:19, Adrián Moreno wrote:
> > On Mon, Jun 24, 2024 at 01:37:44PM GMT, Ilya Maximets wrote:
> >> On 6/5/24 22:23, Adrian Moreno wrote:
> >>> Use the newly added emit_sample to implement OpenFlow sample() actions
> >>> with local sampling configuration.
> >>>
> >>> Signed-off-by: Adrian Moreno 
> >>> ---
> >>>  ofproto/ofproto-dpif-lsample.c |  17 
> >>>  ofproto/ofproto-dpif-lsample.h |   6 ++
> >>>  ofproto/ofproto-dpif-xlate.c   | 163 -
> >>>  ofproto/ofproto-dpif-xlate.h   |   3 +-
> >>>  ofproto/ofproto-dpif.c |   2 +-
> >>>  5 files changed, 144 insertions(+), 47 deletions(-)
> >>
> >> Not a full review, just a note that this patch needs tests in 
> >> ofproto-dpif.at
> >> that would check that we generate correct datapath flows.
> >>
> >
> > I thought about that, but ofproto-dpif.at is based on dummy datapat
> > (userspace) which does not support this action. The configuration will
> > be ignored and the datapath actions will not be generated. That's why I
> > relied on system-traffic.at tests. Do you see any way around this?
>
> We don't need actual datapath support if we're not sending any actual
> trafic.  You should be able to just turn on the capability and check
> that ofproto/trace generates correct actions.
>
> We test kernel tunnels this way, for example.  See the macro
> OVS_VSWITCHD_DISABLE_TUNNEL_PUSH_POP.  And some other similar checks.
>

OK. Thanks for the pointer. I'll give it a try.

Adrián.

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [RFC v2 9/9] tests: Test local sampling.

2024-06-24 Thread Adrián Moreno
On Mon, Jun 24, 2024 at 04:15:50PM GMT, Ilya Maximets wrote:
> On 6/24/24 15:14, Adrián Moreno wrote:
> > On Mon, Jun 24, 2024 at 02:03:00PM GMT, Ilya Maximets wrote:
> >> On 6/5/24 22:23, Adrian Moreno wrote:
> >>> Test simultaneous IPFIX and local sampling including slow-path.
> >>>
> >>> Signed-off-by: Adrian Moreno 
> >>> ---
> >>>  tests/system-common-macros.at |   4 ++
> >>>  tests/system-traffic.at   | 105 ++
> >>>  2 files changed, 109 insertions(+)
> >>>
> >>
> >> Not a full review, but see a few comments below.
> >>
> >>> diff --git a/tests/system-common-macros.at b/tests/system-common-macros.at
> >>> index 2a68cd664..22b8885e4 100644
> >>> --- a/tests/system-common-macros.at
> >>> +++ b/tests/system-common-macros.at
> >>> @@ -378,3 +378,7 @@ m4_define([OVS_CHECK_GITHUB_ACTION],
> >>>  # OVS_CHECK_DROP_ACTION()
> >>>  m4_define([OVS_CHECK_DROP_ACTION],
> >>>  [AT_SKIP_IF([! grep -q "Datapath supports explicit drop action" 
> >>> ovs-vswitchd.log])])
> >>> +
> >>> +# OVS_CHECK_EMIT_SAMPLE()
> >>> +m4_define([OVS_CHECK_EMIT_SAMPLE],
> >>> +[AT_SKIP_IF([! grep -q "Datapath supports emit_sample" 
> >>> ovs-vswitchd.log])])
> >>> diff --git a/tests/system-traffic.at b/tests/system-traffic.at
> >>> index bd7647cbe..babc56b56 100644
> >>> --- a/tests/system-traffic.at
> >>> +++ b/tests/system-traffic.at
> >>> @@ -8977,3 +8977,108 @@ OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0050: 
> >>> * * *5002 *2000 *b85e *00
> >>>
> >>>  OVS_TRAFFIC_VSWITCHD_STOP
> >>>  AT_CLEANUP
> >>> +
> >>> +AT_SETUP([emit_sample])
> >>
> >> Other tests have a test group name at the beginning.
> >> You're also adding the test into NSH section.  Add a new section, e.g.,
> >> 'sampling' for this with AT_BANNER.
> >>
> >
> > Thanks. Will do.
> >
> >>> +OVS_TRAFFIC_VSWITCHD_START()
> >>> +OVS_CHECK_EMIT_SAMPLE()
> >>> +
> >>> +ADD_NAMESPACES(at_ns0, at_ns1)
> >>> +NS_CHECK_EXEC([at_ns0], [sysctl -w net.ipv6.conf.all.disable_ipv6=1], 
> >>> [0], [ignore])
> >>> +NS_CHECK_EXEC([at_ns1], [sysctl -w net.ipv6.conf.all.disable_ipv6=1], 
> >>> [0], [ignore])
> >>
> >> This looks strange, don't disable IPv6.  Appropriate datapath actions
> >> should not forward IPv6 traffic, if that is a desired behavior.
> >>
> >
> > I found tests cleaner if automatic ipv6 traffic is not sent by ports.
> > But sure, I can deal with that with OpenFlow.
>
> Would be good to have two separate tests.  One for IPv4 and one for IPv6.
>
> >
> >> Though, I guess, it would be nice to test capturing both IPv4 and IPv6.
> >>
> >>> +
> >>> +ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24", "e4:11:22:33:44:55")
> >>> +ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24", "e4:11:22:33:44:66")
> >>> +
> >>> +NS_CHECK_EXEC([at_ns0], [arp -s 10.1.1.2 e4:11:22:33:44:66])
> >>> +NS_CHECK_EXEC([at_ns1], [arp -s 10.1.1.1 e4:11:22:33:44:55])
> >>> +
> >>> +
> >>> +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg 
> >>> ofproto_dpif_upcall:dbg])
> >>> +
> >>> +AT_CHECK([ovs-vsctl -- --id=@br0 get Bridge br0 \
> >>> +-- --id=@ipfix create IPFIX 
> >>> targets=\"127.0.0.1:4739\" \
> >>> +-- create Flow_Sample_Collector_Set id=1 bridge=@br0 
> >>> ipfix=@ipfix, local_sample_group=10 \
> >>> +-- create Flow_Sample_Collector_Set id=2 bridge=@br0 
> >>> ipfix=@ipfix, local_sample_group=12],
> >>> + [0], [ignore])
> >>
> >> Why are we adding IPFIX?  This should work without IPFIX.
> >>
> >
> > It is intentional. I want to test both features work simulteaneously.
>
> Tests should be simple.  At least, we should have at least one very simple
> test, so if it fails we know that there is an issue in the basic logic.
>
> It's valuable to test a combination of the two, but it should be a separate
> test.  So, 3 tests so far: IPv4, IPv6, psample+ipfix.  Maybe the 4th separate
> test for the slow path.
>

Ack.

> >
> >> Having both to

Re: [ovs-dev] [RFC v2 5/9] ofproto-dpif-xlate: Use emit_sample for local sample.

2024-06-24 Thread Adrián Moreno
On Mon, Jun 24, 2024 at 01:37:44PM GMT, Ilya Maximets wrote:
> On 6/5/24 22:23, Adrian Moreno wrote:
> > Use the newly added emit_sample to implement OpenFlow sample() actions
> > with local sampling configuration.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  ofproto/ofproto-dpif-lsample.c |  17 
> >  ofproto/ofproto-dpif-lsample.h |   6 ++
> >  ofproto/ofproto-dpif-xlate.c   | 163 -
> >  ofproto/ofproto-dpif-xlate.h   |   3 +-
> >  ofproto/ofproto-dpif.c |   2 +-
> >  5 files changed, 144 insertions(+), 47 deletions(-)
>
> Not a full review, just a note that this patch needs tests in ofproto-dpif.at
> that would check that we generate correct datapath flows.
>

I thought about that, but ofproto-dpif.at is based on dummy datapat
(userspace) which does not support this action. The configuration will
be ignored and the datapath actions will not be generated. That's why I
relied on system-traffic.at tests. Do you see any way around this?

Thanks.
Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [RFC v2 9/9] tests: Test local sampling.

2024-06-24 Thread Adrián Moreno
On Mon, Jun 24, 2024 at 02:03:00PM GMT, Ilya Maximets wrote:
> On 6/5/24 22:23, Adrian Moreno wrote:
> > Test simultaneous IPFIX and local sampling including slow-path.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  tests/system-common-macros.at |   4 ++
> >  tests/system-traffic.at   | 105 ++
> >  2 files changed, 109 insertions(+)
> >
>
> Not a full review, but see a few comments below.
>
> > diff --git a/tests/system-common-macros.at b/tests/system-common-macros.at
> > index 2a68cd664..22b8885e4 100644
> > --- a/tests/system-common-macros.at
> > +++ b/tests/system-common-macros.at
> > @@ -378,3 +378,7 @@ m4_define([OVS_CHECK_GITHUB_ACTION],
> >  # OVS_CHECK_DROP_ACTION()
> >  m4_define([OVS_CHECK_DROP_ACTION],
> >  [AT_SKIP_IF([! grep -q "Datapath supports explicit drop action" 
> > ovs-vswitchd.log])])
> > +
> > +# OVS_CHECK_EMIT_SAMPLE()
> > +m4_define([OVS_CHECK_EMIT_SAMPLE],
> > +[AT_SKIP_IF([! grep -q "Datapath supports emit_sample" 
> > ovs-vswitchd.log])])
> > diff --git a/tests/system-traffic.at b/tests/system-traffic.at
> > index bd7647cbe..babc56b56 100644
> > --- a/tests/system-traffic.at
> > +++ b/tests/system-traffic.at
> > @@ -8977,3 +8977,108 @@ OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0050: 
> > * * *5002 *2000 *b85e *00
> >
> >  OVS_TRAFFIC_VSWITCHD_STOP
> >  AT_CLEANUP
> > +
> > +AT_SETUP([emit_sample])
>
> Other tests have a test group name at the beginning.
> You're also adding the test into NSH section.  Add a new section, e.g.,
> 'sampling' for this with AT_BANNER.
>

Thanks. Will do.

> > +OVS_TRAFFIC_VSWITCHD_START()
> > +OVS_CHECK_EMIT_SAMPLE()
> > +
> > +ADD_NAMESPACES(at_ns0, at_ns1)
> > +NS_CHECK_EXEC([at_ns0], [sysctl -w net.ipv6.conf.all.disable_ipv6=1], [0], 
> > [ignore])
> > +NS_CHECK_EXEC([at_ns1], [sysctl -w net.ipv6.conf.all.disable_ipv6=1], [0], 
> > [ignore])
>
> This looks strange, don't disable IPv6.  Appropriate datapath actions
> should not forward IPv6 traffic, if that is a desired behavior.
>

I found tests cleaner if automatic ipv6 traffic is not sent by ports.
But sure, I can deal with that with OpenFlow.

> Though, I guess, it would be nice to test capturing both IPv4 and IPv6.
>
> > +
> > +ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24", "e4:11:22:33:44:55")
> > +ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24", "e4:11:22:33:44:66")
> > +
> > +NS_CHECK_EXEC([at_ns0], [arp -s 10.1.1.2 e4:11:22:33:44:66])
> > +NS_CHECK_EXEC([at_ns1], [arp -s 10.1.1.1 e4:11:22:33:44:55])
> > +
> > +
> > +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg 
> > ofproto_dpif_upcall:dbg])
> > +
> > +AT_CHECK([ovs-vsctl -- --id=@br0 get Bridge br0 \
> > +-- --id=@ipfix create IPFIX targets=\"127.0.0.1:4739\" 
> > \
> > +-- create Flow_Sample_Collector_Set id=1 bridge=@br0 
> > ipfix=@ipfix, local_sample_group=10 \
> > +-- create Flow_Sample_Collector_Set id=2 bridge=@br0 
> > ipfix=@ipfix, local_sample_group=12],
> > + [0], [ignore])
>
> Why are we adding IPFIX?  This should work without IPFIX.
>

It is intentional. I want to test both features work simulteaneously.

> Having both together can be a separate test.
>
> > +
> > +AT_DATA([flows.txt], [dnl
> > +in_port=ovs-p0,ip 
> > actions=sample(probability=65535,collector_set_id=1,obs_domain_id=1431655765,obs_point_id=1717986918),output(port=ovs-p1,max_len=100)
> > +in_port=ovs-p1,ip 
> > actions=sample(probability=65535,collector_set_id=2,obs_domain_id=2290649224,obs_point_id=2576980377),output(port=ovs-p0,max_len=100)
>
> It should be possible to wrap these lines a little with dnl.
>
> Also, please make IDs non-symmetric, so we can't check that the
> byte order is correct.
>

Originally, I thought just concatenating the values in native endianness
as a kind of replacement for the user_action_cookie (hence the symmetric
values). But I'm having second thoughts. I plan to change it in the next
version and store it in "network" order. I will change the test to
verify it accordingly.

> > +])
> > +
> > +AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
> > +
> > +OVS_DAEMONIZE([ovstest test-psample > psample.out], [psample1.pid])
>
> Should we wait for the test app to start listening?  i.e. there might be
> a race between the listener and the ping below.
>

I guess so.

> > +
> > +NS_CHECK_EXEC([at_ns0], [ping -q -c 1 10.1.1.2 | FORMAT_PING], [0], [dnl
> > +1 packets transmitted, 1 received, 0% packet loss, time 0ms
> > +])
>
> We may need to add -W to the ping.
>

Ack.

> > +
> > +m4_define([SAMPLE1], [group_id=0xa 
> > obs_domain=0x,obs_point=0x 
> > .*icmp.*nw_src=10.1.1.1,nw_dst=10.1.1.2])
> > +m4_define([SAMPLE2], [group_id=0xc 
> > obs_domain=0x,obs_point=0x 
> > .*icmp.*nw_src=10.1.1.2,nw_dst=10.1.1.1])
>
> May use m4_join to wrap these lines.
>
> > +AT_CHECK([grep -E 'SAMPLE1' psample.out >/dev/null])
> > +AT_CHECK([grep -E 'SAMPLE2' psample.out >/dev/null])
>
> 'grep -q' to avoid the 

Re: [ovs-dev] [RFC v2 9/9] tests: Test local sampling.

2024-06-24 Thread Adrián Moreno
On Mon, Jun 24, 2024 at 01:23:55PM GMT, Eelco Chaudron wrote:
>
>
> On 5 Jun 2024, at 22:23, Adrian Moreno wrote:
>
> > Test simultaneous IPFIX and local sampling including slow-path.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  tests/system-common-macros.at |   4 ++
> >  tests/system-traffic.at   | 105 ++
> >  2 files changed, 109 insertions(+)
> >
> > diff --git a/tests/system-common-macros.at b/tests/system-common-macros.at
> > index 2a68cd664..22b8885e4 100644
> > --- a/tests/system-common-macros.at
> > +++ b/tests/system-common-macros.at
> > @@ -378,3 +378,7 @@ m4_define([OVS_CHECK_GITHUB_ACTION],
> >  # OVS_CHECK_DROP_ACTION()
> >  m4_define([OVS_CHECK_DROP_ACTION],
> >  [AT_SKIP_IF([! grep -q "Datapath supports explicit drop action" 
> > ovs-vswitchd.log])])
> > +
> > +# OVS_CHECK_EMIT_SAMPLE()
> > +m4_define([OVS_CHECK_EMIT_SAMPLE],
> > +[AT_SKIP_IF([! grep -q "Datapath supports emit_sample" 
> > ovs-vswitchd.log])])
> > diff --git a/tests/system-traffic.at b/tests/system-traffic.at
> > index bd7647cbe..babc56b56 100644
> > --- a/tests/system-traffic.at
> > +++ b/tests/system-traffic.at
> > @@ -8977,3 +8977,108 @@ OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0050: 
> > * * *5002 *2000 *b85e *00
> >
> >  OVS_TRAFFIC_VSWITCHD_STOP
> >  AT_CLEANUP
> > +
> > +AT_SETUP([emit_sample])
> > +OVS_TRAFFIC_VSWITCHD_START()
> > +OVS_CHECK_EMIT_SAMPLE()
> > +
> > +ADD_NAMESPACES(at_ns0, at_ns1)
> > +NS_CHECK_EXEC([at_ns0], [sysctl -w net.ipv6.conf.all.disable_ipv6=1], [0], 
> > [ignore])
> > +NS_CHECK_EXEC([at_ns1], [sysctl -w net.ipv6.conf.all.disable_ipv6=1], [0], 
> > [ignore])
> > +
> > +ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24", "e4:11:22:33:44:55")
> > +ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24", "e4:11:22:33:44:66")
> > +
> > +NS_CHECK_EXEC([at_ns0], [arp -s 10.1.1.2 e4:11:22:33:44:66])
> > +NS_CHECK_EXEC([at_ns1], [arp -s 10.1.1.1 e4:11:22:33:44:55])
> > +
> > +
> > +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg 
> > ofproto_dpif_upcall:dbg])
> > +
> > +AT_CHECK([ovs-vsctl -- --id=@br0 get Bridge br0 \
> > +-- --id=@ipfix create IPFIX targets=\"127.0.0.1:4739\" 
> > \
> > +-- create Flow_Sample_Collector_Set id=1 bridge=@br0 
> > ipfix=@ipfix, local_sample_group=10 \
> > +-- create Flow_Sample_Collector_Set id=2 bridge=@br0 
> > ipfix=@ipfix, local_sample_group=12],
> > + [0], [ignore])
> > +
> > +AT_DATA([flows.txt], [dnl
> > +in_port=ovs-p0,ip 
> > actions=sample(probability=65535,collector_set_id=1,obs_domain_id=1431655765,obs_point_id=1717986918),output(port=ovs-p1,max_len=100)
> > +in_port=ovs-p1,ip 
> > actions=sample(probability=65535,collector_set_id=2,obs_domain_id=2290649224,obs_point_id=2576980377),output(port=ovs-p0,max_len=100)
> > +])
> > +
> > +AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
> > +
> > +OVS_DAEMONIZE([ovstest test-psample > psample.out], [psample1.pid])
> > +
> > +NS_CHECK_EXEC([at_ns0], [ping -q -c 1 10.1.1.2 | FORMAT_PING], [0], [dnl
> > +1 packets transmitted, 1 received, 0% packet loss, time 0ms
> > +])
> > +
> > +m4_define([SAMPLE1], [group_id=0xa 
> > obs_domain=0x,obs_point=0x 
> > .*icmp.*nw_src=10.1.1.1,nw_dst=10.1.1.2])
> > +m4_define([SAMPLE2], [group_id=0xc 
> > obs_domain=0x,obs_point=0x 
> > .*icmp.*nw_src=10.1.1.2,nw_dst=10.1.1.1])
> > +AT_CHECK([grep -E 'SAMPLE1' psample.out >/dev/null])
> > +AT_CHECK([grep -E 'SAMPLE2' psample.out >/dev/null])
> > +
> > +AT_CHECK([ovs-ofctl dump-ipfix-flow br0 | sed 's/tx pkts=[[0-9]]*/tx 
> > pkts=24/' | sed 's/tx errs=[[0-9]]*/tx errs=0/'], [0], [dnl
> > +NXST_IPFIX_FLOW reply (xid=0x2): 2 ids
> > +  id   1: flows=1, current flows=0, sampled pkts=1, ipv4 ok=1, ipv6 ok=0, 
> > tx pkts=24
> > +  pkts errs=0, ipv4 errs=0, ipv6 errs=0, tx errs=0
> > +  id   2: flows=1, current flows=0, sampled pkts=1, ipv4 ok=1, ipv6 ok=0, 
> > tx pkts=24
> > +  pkts errs=0, ipv4 errs=0, ipv6 errs=0, tx errs=0
> > +])
>
> This is not a review, just a heads up so you are aware that this test fails 
> sometimes:
>
> +++ 
> /home/echaudron/Documents/review/ovs_adrian_psample/tests/system-kmod-testsuite.dir/at-groups/178/stdout
>   2024-06-24 13:05:35.05700 +0200
> @@ -1,6 +1,6 @@
>  NXST_IPFIX_FLOW reply (xid=0x2): 2 ids
> -  id   1: flows=1, current flows=0, sampled pkts=1, ipv4 ok=1, ipv6 ok=0, tx 
> pkts=24
> -  pkts errs=0, ipv4 errs=0, ipv6 errs=0, tx errs=0
>id   2: flows=1, current flows=0, sampled pkts=1, ipv4 ok=1, ipv6 ok=0, tx 
> pkts=24
>pkts errs=0, ipv4 errs=0, ipv6 errs=0, tx errs=0
> +  id   1: flows=1, current flows=0, sampled pkts=1, ipv4 ok=1, ipv6 ok=0, tx 
> pkts=24
> +  pkts errs=0, ipv4 errs=0, ipv6 errs=0, tx errs=0
>
> The order does not seem to be fixed all the time (same for the one below).
>

Ugh, I assumed the output would be ordered. I'll deal with it manually
in the test.

> //Eelco
>
> > +
> > 

Re: [ovs-dev] [RFC v2 0/9] Introduce local sampling with NXAST_SAMPLE action

2024-06-21 Thread Adrián Moreno
On Thu, Jun 20, 2024 at 02:20:53PM GMT, Eelco Chaudron wrote:
>
>
> On 5 Jun 2024, at 22:23, Adrian Moreno wrote:
>
> > (Was: Add psample support to NXAST_SAMPLE action)
> >
> > This is the userspace counterpart of the work being done in the kernel
> > [1] which is still not merged (hence the RFC state). There, a new
> > datapath action is added, called "emit_sample". Being a specific
> > action, it promises a more efficient way of making packet samples
> > available to observability applications.
> >
> > From the PoV of ovs-vswitchd, this new action is used to implement
> > "local sampling". Local sampling (or lsample for short) is configured
> > in a similar way as current per-flow IPFIX sampling, i.e: using the
> > Flow_Sample_Collector_Set table and the NXAST_SAMPLE action.
> >
> > However, instead of sending the sample to an external IPFIX collector
> > though the network, the sample is emitted using the new action and
> > made available to locally running sample collector.
> >
> > The specific way emit_sample sends the sample (and the way the local
> > collector shall collect it) is datapath-specific.
> > Currently, currently only the Linux kernel datapath implements it using
> > the psample netlink multicast group.
> >
> > ~~ Configuration ~~
> > Local sampling is configured via a new column in the
> > Flow_Sample_Collector_Set (FSCS) table called "local_sample_group".
> > Configuring this value is orthogonal to also associating the FSCS
> > entry to an entry in the IPFIX table.
> >
> > Once that entry in the OVSDB is configured, NXAST_SAMPLE actions coming
> > from the controller will be translated into the following odp action:
> >
> >sample(sample={P}%, actions(emit_sample(group={G},cookie={C})))
> >
> > Where:
> > P: Is the sampling probability from NXAST_SAMPLE
> > G: Is the group id in the FSCS entry whose "id" matches the one in
> > the NXAST_SAMPLE.
> > C: Is a 64bit cookie result of concatenating the obs_domain and
> > obs_point from the NXAST_SAMPLE, i.e:
> > "obs_domain << 32 | obs_point"
> > Notes:
> > - The parent sample action might be omitted if the probability is
> >   100% and there is no IPFIX sampling that requires the use of a
> >   meter.
> >
> > ~~ Internal implementation: dpif-lsample ~~
> > Internally, a new object called "dpif-lsample" is introduced to track
> > the configured local sampling exporters and track statistics based on
> > odp flow stats (using xcache).
> > It exposes the list of configured exporters and their statistics on a
> > new unixctl command called "lsample/show".
> >
> > ~~ Testing ~~
> > The series includes an test utility program than can be executed by
> > running "tests/ovstest test-psample". This utility listens
> > to packets multicasted by the psample module and prints them (also
> > printing the obs_domain and obs_point ids).
> >
> > ~~ HW Offload ~~
> > tc offload is not being introduced in this series as existing sample
> > or userspace actions are not currently offloadable. Also some
> > improvements need to be implemented in tc for it to be feasible.
> >
> > [1]
> > https://patchwork.kernel.org/project/netdevbpf/cover/20240603185647.2310748-1-amore...@redhat.com/
>
> Hi Adrian,
>
> I did not finish reviewing, but I was doing some testing, and I noticed I’m 
> not getting any warning/error when configuring all of this without Datapath 
> support.
>
> Are you planning to add some user feedback when trying to enable this without 
> the kernel other than the “Datapath does not support emit_sample” which the 
> user might not understand relates to this feature?
>

I added the following code in bridge.c when it configures local
sampling:


+ret = ofproto_set_local_sample(br->ofproto, opts_array, n_opts);
+
+if (ret == ENOTSUP) {
+if (n_opts) {
+VLOG_WARN_RL(,
+ "bridge %s: ignoring local sampling configuration: "
+ "not supported by this datapath",
+ br->name);
+}
+} else if (ret) {
+VLOG_ERR_RL(, "bridge %s: error configuring local sampling: %s",
+br->name, ovs_strerror(ret));
+}

I believe it should warn the user the local sampling configuration will
not be applied.

Is that not working?

> Cheers,
>
> Eelco
>

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH net-next v3 05/10] net: openvswitch: add emit_sample action

2024-06-20 Thread Adrián Moreno
On Wed, Jun 19, 2024 at 06:39:43PM GMT, Jakub Kicinski wrote:
> On Wed, 19 Jun 2024 23:00:06 +0200 Adrian Moreno wrote:
> > +   OVS_EMIT_SAMPLE_ATTR_UNPSEC,
>
> Are you using this one? Looking closely I presume not, since it's
> misspelled ;) You can assign = 1 to GROUP, no need to name the value
> for 0.

Good point, thanks.
The openvswitch header seems full of unused names for value 0.
I guess it's OK to break the local "style" if we're improving it?
Or is it better to get rid of all of them in a single cleaning patch?

>
> > +   OVS_EMIT_SAMPLE_ATTR_GROUP, /* u32 number. */
> > +   OVS_EMIT_SAMPLE_ATTR_COOKIE,/* Optional, user specified cookie. */
> > +   __OVS_EMIT_SAMPLE_ATTR_MAX
>
> kdoc is complaining that __OVS_EMIT_SAMPLE_ATTR_MAX is not documented.
> You can add:
>
>   /* private: */
>
> before, take a look at include/uapi/linux/netdev.h for example.

Thanks. Will do.
--
Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH net-next v2 7/9] net: openvswitch: do not notify drops inside sample

2024-06-19 Thread Adrián Moreno
On Wed, Jun 19, 2024 at 08:21:02PM GMT, Ilya Maximets wrote:
> On 6/19/24 08:35, Adrián Moreno wrote:
> > On Tue, Jun 18, 2024 at 05:44:05PM GMT, Ilya Maximets wrote:
> >> On 6/18/24 12:50, Adrián Moreno wrote:
> >>> On Tue, Jun 18, 2024 at 12:22:23PM GMT, Ilya Maximets wrote:
> >>>> On 6/18/24 09:00, Adrián Moreno wrote:
> >>>>> On Mon, Jun 17, 2024 at 02:10:37PM GMT, Ilya Maximets wrote:
> >>>>>> On 6/17/24 13:55, Ilya Maximets wrote:
> >>>>>>> On 6/3/24 20:56, Adrian Moreno wrote:
> >>>>>>>> The OVS_ACTION_ATTR_SAMPLE action is, in essence,
> >>>>>>>> observability-oriented.
> >>>>>>>>
> >>>>>>>> Apart from some corner case in which it's used a replacement of 
> >>>>>>>> clone()
> >>>>>>>> for old kernels, it's really only used for sFlow, IPFIX and now,
> >>>>>>>> local emit_sample.
> >>>>>>>>
> >>>>>>>> With this in mind, it doesn't make much sense to report
> >>>>>>>> OVS_DROP_LAST_ACTION inside sample actions.
> >>>>>>>>
> >>>>>>>> For instance, if the flow:
> >>>>>>>>
> >>>>>>>>   actions:sample(..,emit_sample(..)),2
> >>>>>>>>
> >>>>>>>> triggers a OVS_DROP_LAST_ACTION skb drop event, it would be extremely
> >>>>>>>> confusing for users since the packet did reach its destination.
> >>>>>>>>
> >>>>>>>> This patch makes internal action execution silently consume the skb
> >>>>>>>> instead of notifying a drop for this case.
> >>>>>>>>
> >>>>>>>> Unfortunately, this patch does not remove all potential sources of
> >>>>>>>> confusion since, if the sample action itself is the last action, e.g:
> >>>>>>>>
> >>>>>>>> actions:sample(..,emit_sample(..))
> >>>>>>>>
> >>>>>>>> we actually _should_ generate a OVS_DROP_LAST_ACTION event, but we 
> >>>>>>>> aren't.
> >>>>>>>>
> >>>>>>>> Sadly, this case is difficult to solve without breaking the
> >>>>>>>> optimization by which the skb is not cloned on last sample actions.
> >>>>>>>> But, given explicit drop actions are now supported, OVS can just add 
> >>>>>>>> one
> >>>>>>>> after the last sample() and rewrite the flow as:
> >>>>>>>>
> >>>>>>>> actions:sample(..,emit_sample(..)),drop
> >>>>>>>>
> >>>>>>>> Signed-off-by: Adrian Moreno 
> >>>>>>>> ---
> >>>>>>>>  net/openvswitch/actions.c | 13 +++--
> >>>>>>>>  1 file changed, 11 insertions(+), 2 deletions(-)
> >>>>>>>>
> >>>>>>>> diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> >>>>>>>> index 33f6d93ba5e4..54fc1abcff95 100644
> >>>>>>>> --- a/net/openvswitch/actions.c
> >>>>>>>> +++ b/net/openvswitch/actions.c
> >>>>>>>> @@ -82,6 +82,15 @@ static struct action_fifo __percpu *action_fifos;
> >>>>>>>>  static struct action_flow_keys __percpu *flow_keys;
> >>>>>>>>  static DEFINE_PER_CPU(int, exec_actions_level);
> >>>>>>>>
> >>>>>>>> +static inline void ovs_drop_skb_last_action(struct sk_buff *skb)
> >>>>>>>> +{
> >>>>>>>> +/* Do not emit packet drops inside sample(). */
> >>>>>>>> +if (OVS_CB(skb)->probability)
> >>>>>>>> +consume_skb(skb);
> >>>>>>>> +else
> >>>>>>>> +ovs_kfree_skb_reason(skb, OVS_DROP_LAST_ACTION);
> >>>>>>>> +}
> >>>>>>>> +
> >>>>>>>>  /* Make a clone of the 'key', using the pre-allocated percpu 
> >>>>>>>> 'flow_keys'
> >>>>>>>>   * space. Return NULL if out of key 

Re: [ovs-dev] [PATCH net-next v2 7/9] net: openvswitch: do not notify drops inside sample

2024-06-19 Thread Adrián Moreno
On Tue, Jun 18, 2024 at 05:44:05PM GMT, Ilya Maximets wrote:
> On 6/18/24 12:50, Adrián Moreno wrote:
> > On Tue, Jun 18, 2024 at 12:22:23PM GMT, Ilya Maximets wrote:
> >> On 6/18/24 09:00, Adrián Moreno wrote:
> >>> On Mon, Jun 17, 2024 at 02:10:37PM GMT, Ilya Maximets wrote:
> >>>> On 6/17/24 13:55, Ilya Maximets wrote:
> >>>>> On 6/3/24 20:56, Adrian Moreno wrote:
> >>>>>> The OVS_ACTION_ATTR_SAMPLE action is, in essence,
> >>>>>> observability-oriented.
> >>>>>>
> >>>>>> Apart from some corner case in which it's used a replacement of clone()
> >>>>>> for old kernels, it's really only used for sFlow, IPFIX and now,
> >>>>>> local emit_sample.
> >>>>>>
> >>>>>> With this in mind, it doesn't make much sense to report
> >>>>>> OVS_DROP_LAST_ACTION inside sample actions.
> >>>>>>
> >>>>>> For instance, if the flow:
> >>>>>>
> >>>>>>   actions:sample(..,emit_sample(..)),2
> >>>>>>
> >>>>>> triggers a OVS_DROP_LAST_ACTION skb drop event, it would be extremely
> >>>>>> confusing for users since the packet did reach its destination.
> >>>>>>
> >>>>>> This patch makes internal action execution silently consume the skb
> >>>>>> instead of notifying a drop for this case.
> >>>>>>
> >>>>>> Unfortunately, this patch does not remove all potential sources of
> >>>>>> confusion since, if the sample action itself is the last action, e.g:
> >>>>>>
> >>>>>> actions:sample(..,emit_sample(..))
> >>>>>>
> >>>>>> we actually _should_ generate a OVS_DROP_LAST_ACTION event, but we 
> >>>>>> aren't.
> >>>>>>
> >>>>>> Sadly, this case is difficult to solve without breaking the
> >>>>>> optimization by which the skb is not cloned on last sample actions.
> >>>>>> But, given explicit drop actions are now supported, OVS can just add 
> >>>>>> one
> >>>>>> after the last sample() and rewrite the flow as:
> >>>>>>
> >>>>>> actions:sample(..,emit_sample(..)),drop
> >>>>>>
> >>>>>> Signed-off-by: Adrian Moreno 
> >>>>>> ---
> >>>>>>  net/openvswitch/actions.c | 13 +++--
> >>>>>>  1 file changed, 11 insertions(+), 2 deletions(-)
> >>>>>>
> >>>>>> diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> >>>>>> index 33f6d93ba5e4..54fc1abcff95 100644
> >>>>>> --- a/net/openvswitch/actions.c
> >>>>>> +++ b/net/openvswitch/actions.c
> >>>>>> @@ -82,6 +82,15 @@ static struct action_fifo __percpu *action_fifos;
> >>>>>>  static struct action_flow_keys __percpu *flow_keys;
> >>>>>>  static DEFINE_PER_CPU(int, exec_actions_level);
> >>>>>>
> >>>>>> +static inline void ovs_drop_skb_last_action(struct sk_buff *skb)
> >>>>>> +{
> >>>>>> +  /* Do not emit packet drops inside sample(). */
> >>>>>> +  if (OVS_CB(skb)->probability)
> >>>>>> +  consume_skb(skb);
> >>>>>> +  else
> >>>>>> +  ovs_kfree_skb_reason(skb, OVS_DROP_LAST_ACTION);
> >>>>>> +}
> >>>>>> +
> >>>>>>  /* Make a clone of the 'key', using the pre-allocated percpu 
> >>>>>> 'flow_keys'
> >>>>>>   * space. Return NULL if out of key spaces.
> >>>>>>   */
> >>>>>> @@ -1061,7 +1070,7 @@ static int sample(struct datapath *dp, struct 
> >>>>>> sk_buff *skb,
> >>>>>>if ((arg->probability != U32_MAX) &&
> >>>>>>(!arg->probability || get_random_u32() > arg->probability)) 
> >>>>>> {
> >>>>>>if (last)
> >>>>>> -  ovs_kfree_skb_reason(skb, OVS_DROP_LAST_ACTION);
> >>>>>> +  ovs_drop_skb_last_action(skb);
> >>>>
>

Re: [ovs-dev] [PATCH net-next v2 7/9] net: openvswitch: do not notify drops inside sample

2024-06-18 Thread Adrián Moreno
On Tue, Jun 18, 2024 at 12:22:23PM GMT, Ilya Maximets wrote:
> On 6/18/24 09:00, Adrián Moreno wrote:
> > On Mon, Jun 17, 2024 at 02:10:37PM GMT, Ilya Maximets wrote:
> >> On 6/17/24 13:55, Ilya Maximets wrote:
> >>> On 6/3/24 20:56, Adrian Moreno wrote:
> >>>> The OVS_ACTION_ATTR_SAMPLE action is, in essence,
> >>>> observability-oriented.
> >>>>
> >>>> Apart from some corner case in which it's used a replacement of clone()
> >>>> for old kernels, it's really only used for sFlow, IPFIX and now,
> >>>> local emit_sample.
> >>>>
> >>>> With this in mind, it doesn't make much sense to report
> >>>> OVS_DROP_LAST_ACTION inside sample actions.
> >>>>
> >>>> For instance, if the flow:
> >>>>
> >>>>   actions:sample(..,emit_sample(..)),2
> >>>>
> >>>> triggers a OVS_DROP_LAST_ACTION skb drop event, it would be extremely
> >>>> confusing for users since the packet did reach its destination.
> >>>>
> >>>> This patch makes internal action execution silently consume the skb
> >>>> instead of notifying a drop for this case.
> >>>>
> >>>> Unfortunately, this patch does not remove all potential sources of
> >>>> confusion since, if the sample action itself is the last action, e.g:
> >>>>
> >>>> actions:sample(..,emit_sample(..))
> >>>>
> >>>> we actually _should_ generate a OVS_DROP_LAST_ACTION event, but we 
> >>>> aren't.
> >>>>
> >>>> Sadly, this case is difficult to solve without breaking the
> >>>> optimization by which the skb is not cloned on last sample actions.
> >>>> But, given explicit drop actions are now supported, OVS can just add one
> >>>> after the last sample() and rewrite the flow as:
> >>>>
> >>>> actions:sample(..,emit_sample(..)),drop
> >>>>
> >>>> Signed-off-by: Adrian Moreno 
> >>>> ---
> >>>>  net/openvswitch/actions.c | 13 +++--
> >>>>  1 file changed, 11 insertions(+), 2 deletions(-)
> >>>>
> >>>> diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> >>>> index 33f6d93ba5e4..54fc1abcff95 100644
> >>>> --- a/net/openvswitch/actions.c
> >>>> +++ b/net/openvswitch/actions.c
> >>>> @@ -82,6 +82,15 @@ static struct action_fifo __percpu *action_fifos;
> >>>>  static struct action_flow_keys __percpu *flow_keys;
> >>>>  static DEFINE_PER_CPU(int, exec_actions_level);
> >>>>
> >>>> +static inline void ovs_drop_skb_last_action(struct sk_buff *skb)
> >>>> +{
> >>>> +/* Do not emit packet drops inside sample(). */
> >>>> +if (OVS_CB(skb)->probability)
> >>>> +consume_skb(skb);
> >>>> +else
> >>>> +ovs_kfree_skb_reason(skb, OVS_DROP_LAST_ACTION);
> >>>> +}
> >>>> +
> >>>>  /* Make a clone of the 'key', using the pre-allocated percpu 'flow_keys'
> >>>>   * space. Return NULL if out of key spaces.
> >>>>   */
> >>>> @@ -1061,7 +1070,7 @@ static int sample(struct datapath *dp, struct 
> >>>> sk_buff *skb,
> >>>>  if ((arg->probability != U32_MAX) &&
> >>>>  (!arg->probability || get_random_u32() > arg->probability)) 
> >>>> {
> >>>>  if (last)
> >>>> -ovs_kfree_skb_reason(skb, OVS_DROP_LAST_ACTION);
> >>>> +ovs_drop_skb_last_action(skb);
> >>
> >> Always consuming the skb at this point makes sense, since having smaple()
> >> as a last action is a reasonable thing to have.  But this looks more like
> >> a fix for the original drop reason patch set.
> >>
> >
> > I don't think consuming the skb at this point makes sense. It was very
> > intentionally changed to a drop since a very common use-case for
> > sampling is drop-sampling, i.e: replacing an empty action list (that
> > triggers OVS_DROP_LAST_ACTION) with a sample(emit_sample()). Ideally,
> > that replacement should not have any effect on the number of
> > OVS_DROP_LAST_ACTION being reported as the packets are being treated in
> > the same w

Re: [ovs-dev] [PATCH net-next v2 9/9] selftests: openvswitch: add emit_sample test

2024-06-18 Thread Adrián Moreno
On Mon, Jun 17, 2024 at 07:18:05AM GMT, Adrián Moreno wrote:
> On Fri, Jun 14, 2024 at 01:07:33PM GMT, Aaron Conole wrote:
> > Adrian Moreno  writes:
> >
> > > Add a test to verify sampling packets via psample works.
> > >
> > > In order to do that, create a subcommand in ovs-dpctl.py to listen to
> > > on the psample multicast group and print samples.
> > >
> > > In order to also test simultaneous sFlow and psample actions and
> > > packet truncation, add missing parsing support for "userspace" and
> > > "trunc" actions.
> >
> > Maybe split that into a separate patch.  This has a bugfix and 3
> > features being pushed in.  I know it's already getting long as a series,
> > so maybe it's okay to fold the userspace attribute bugfix with the parse
> > support (since it wasn't really usable before).
> >
>
> OK. Sounds reasonable.
>
> > > Signed-off-by: Adrian Moreno 
> > > ---
> > >  .../selftests/net/openvswitch/openvswitch.sh  |  99 +++-
> > >  .../selftests/net/openvswitch/ovs-dpctl.py| 112 +-
> > >  2 files changed, 204 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh 
> > > b/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > > index 5cae53543849..f6e0ae3f6424 100755
> > > --- a/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > > +++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > > @@ -20,7 +20,8 @@ tests="
> > >   nat_related_v4  ip4-nat-related: ICMP related 
> > > matches work with SNAT
> > >   netlink_checks  ovsnl: validate netlink attrs 
> > > and settings
> > >   upcall_interfaces   ovs: test the upcall interfaces
> > > - drop_reason drop: test drop reasons are 
> > > emitted"
> > > + drop_reason drop: test drop reasons are 
> > > emitted
> > > + emit_sample emit_sample: Sampling packets 
> > > with psample"
> > >
> > >  info() {
> > >  [ $VERBOSE = 0 ] || echo $*
> > > @@ -170,6 +171,19 @@ ovs_drop_reason_count()
> > >   return `echo "$perf_output" | grep "$pattern" | wc -l`
> > >  }
> > >
> > > +ovs_test_flow_fails () {
> > > + ERR_MSG="Flow actions may not be safe on all matching packets"
> > > +
> > > + PRE_TEST=$(dmesg | grep -c "${ERR_MSG}")
> > > + ovs_add_flow $@ &> /dev/null $@ && return 1
> > > + POST_TEST=$(dmesg | grep -c "${ERR_MSG}")
> > > +
> > > + if [ "$PRE_TEST" == "$POST_TEST" ]; then
> > > + return 1
> > > + fi
> > > + return 0
> > > +}
> > > +
> > >  usage() {
> > >   echo
> > >   echo "$0 [OPTIONS] [TEST]..."
> > > @@ -184,6 +198,89 @@ usage() {
> > >   exit 1
> > >  }
> > >
> > > +
> > > +# emit_sample test
> > > +# - use emit_sample to observe packets
> > > +test_emit_sample() {
> > > + sbx_add "test_emit_sample" || return $?
> > > +
> > > + # Add a datapath with per-vport dispatching.
> > > + ovs_add_dp "test_emit_sample" emit_sample -V 2:1 || return 1
> > > +
> > > + info "create namespaces"
> > > + ovs_add_netns_and_veths "test_emit_sample" "emit_sample" \
> > > + client c0 c1 172.31.110.10/24 -u || return 1
> > > + ovs_add_netns_and_veths "test_emit_sample" "emit_sample" \
> > > + server s0 s1 172.31.110.20/24 -u || return 1
> > > +
> > > + # Check if emit_sample actions can be configured.
> > > + ovs_add_flow "test_emit_sample" emit_sample \
> > > + 'in_port(1),eth(),eth_type(0x0806),arp()' 'emit_sample(group=1)'
> > > + if [ $? == 1 ]; then
> > > + info "no support for emit_sample - skipping"
> > > + ovs_exit_sig
> > > + return $ksft_skip
> > > + fi
> > > +
> > > + ovs_del_flows "test_emit_sample" emit_sample
> > > +
> > > + # Allow ARP
> > > + ovs_add_flow "test_emit_sample" emit_sample \
> > > + 'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1
> > > + ovs

Re: [ovs-dev] [PATCH net-next v2 2/9] net: sched: act_sample: add action cookie to sample

2024-06-18 Thread Adrián Moreno
On Mon, Jun 17, 2024 at 12:00:04PM GMT, Ilya Maximets wrote:
> On 6/3/24 20:56, Adrian Moreno wrote:
> > If the action has a user_cookie, pass it along to the sample so it can
> > be easily identified.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  net/sched/act_sample.c | 12 
> >  1 file changed, 12 insertions(+)
> >
> > diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c
> > index a69b53d54039..5c3f86ec964a 100644
> > --- a/net/sched/act_sample.c
> > +++ b/net/sched/act_sample.c
> > @@ -165,9 +165,11 @@ TC_INDIRECT_SCOPE int tcf_sample_act(struct sk_buff 
> > *skb,
> >  const struct tc_action *a,
> >  struct tcf_result *res)
> >  {
> > +   u8 cookie_data[TC_COOKIE_MAX_SIZE] = {};
>
> Is it necessary to initialize these 16 bytes on every call?
> Might be expensive.  We're passing the data length around,
> so the uninitialized parts should not be accessed.
>

They "should" not, indeed. I was just trying to be extra careful.
Are you worried TC_COOKIE_MAX_SIZE could grow or the cycles needed to
clear the current 16 bytes?

> Best regards, Ilya Maximets.
>
> > struct tcf_sample *s = to_sample(a);
> > struct psample_group *psample_group;
> > struct psample_metadata md = {};
> > +   struct tc_cookie *user_cookie;
> > int retval;
> >
> > tcf_lastuse_update(>tcf_tm);
> > @@ -189,6 +191,16 @@ TC_INDIRECT_SCOPE int tcf_sample_act(struct sk_buff 
> > *skb,
> > if (skb_at_tc_ingress(skb) && tcf_sample_dev_ok_push(skb->dev))
> > skb_push(skb, skb->mac_len);
> >
> > +   rcu_read_lock();
> > +   user_cookie = rcu_dereference(a->user_cookie);
> > +   if (user_cookie) {
> > +   memcpy(cookie_data, user_cookie->data,
> > +  user_cookie->len);
> > +   md.user_cookie = cookie_data;
> > +   md.user_cookie_len = user_cookie->len;
> > +   }
> > +   rcu_read_unlock();
> > +
> > md.trunc_size = s->truncate ? s->trunc_size : skb->len;
> > psample_sample_packet(psample_group, skb, s->rate, );
> >
>

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH net-next v2 6/9] net: openvswitch: store sampling probability in cb.

2024-06-18 Thread Adrián Moreno
On Mon, Jun 17, 2024 at 01:26:39PM GMT, Ilya Maximets wrote:
> On 6/17/24 09:08, Adrián Moreno wrote:
> > On Fri, Jun 14, 2024 at 12:55:59PM GMT, Aaron Conole wrote:
> >> Adrian Moreno  writes:
> >>
> >>> The behavior of actions might not be the exact same if they are being
> >>> executed inside a nested sample action. Store the probability of the
> >>> parent sample action in the skb's cb area.
> >>
> >> What does that mean?
> >>
> >
> > Emit action, for instance, needs the probability so that psample
> > consumers know what was the sampling rate applied. Also, the way we
> > should inform about packet drops (via kfree_skb_reason) changes (see
> > patch 7/9).
> >
> >>> Use the probability in emit_sample to pass it down to psample.
> >>>
> >>> Signed-off-by: Adrian Moreno 
> >>> ---
> >>>  include/uapi/linux/openvswitch.h |  3 ++-
> >>>  net/openvswitch/actions.c| 25 ++---
> >>>  net/openvswitch/datapath.h   |  3 +++
> >>>  net/openvswitch/vport.c  |  1 +
> >>>  4 files changed, 28 insertions(+), 4 deletions(-)
> >>>
> >>> diff --git a/include/uapi/linux/openvswitch.h 
> >>> b/include/uapi/linux/openvswitch.h
> >>> index a0e9dde0584a..9d675725fa2b 100644
> >>> --- a/include/uapi/linux/openvswitch.h
> >>> +++ b/include/uapi/linux/openvswitch.h
> >>> @@ -649,7 +649,8 @@ enum ovs_flow_attr {
> >>>   * Actions are passed as nested attributes.
> >>>   *
> >>>   * Executes the specified actions with the given probability on a 
> >>> per-packet
> >>> - * basis.
> >>> + * basis. Nested actions will be able to access the probability value of 
> >>> the
> >>> + * parent @OVS_ACTION_ATTR_SAMPLE.
> >>>   */
> >>>  enum ovs_sample_attr {
> >>>   OVS_SAMPLE_ATTR_UNSPEC,
> >>> diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> >>> index 3b4dba0ded59..33f6d93ba5e4 100644
> >>> --- a/net/openvswitch/actions.c
> >>> +++ b/net/openvswitch/actions.c
> >>> @@ -1048,12 +1048,15 @@ static int sample(struct datapath *dp, struct 
> >>> sk_buff *skb,
> >>>   struct nlattr *sample_arg;
> >>>   int rem = nla_len(attr);
> >>>   const struct sample_arg *arg;
> >>> + u32 init_probability;
> >>>   bool clone_flow_key;
> >>> + int err;
> >>>
> >>>   /* The first action is always 'OVS_SAMPLE_ATTR_ARG'. */
> >>>   sample_arg = nla_data(attr);
> >>>   arg = nla_data(sample_arg);
> >>>   actions = nla_next(sample_arg, );
> >>> + init_probability = OVS_CB(skb)->probability;
> >>>
> >>>   if ((arg->probability != U32_MAX) &&
> >>>   (!arg->probability || get_random_u32() > arg->probability)) {
> >>> @@ -1062,9 +1065,21 @@ static int sample(struct datapath *dp, struct 
> >>> sk_buff *skb,
> >>>   return 0;
> >>>   }
> >>>
> >>> + if (init_probability) {
> >>> + OVS_CB(skb)->probability = ((u64)OVS_CB(skb)->probability *
> >>> + arg->probability / U32_MAX);
> >>> + } else {
> >>> + OVS_CB(skb)->probability = arg->probability;
> >>> + }
> >>> +
> >>
> >> I'm confused by this.  Eventually, integer arithmetic will practically
> >> guarantee that nested sample() calls will go to 0.  So eventually, the
> >> test above will be impossible to meet mathematically.
> >>
> >> OTOH, you could argue that a 1% of 50% is low anyway, but it still would
> >> have a positive probability count, and still be possible for
> >> get_random_u32() call to match.
> >>
> >
> > Using OVS's probability semantics, we can express probabilities as low
> > as (100/U32_MAX)% which is pretty low indeed. However, just because the
> > probability of executing the action is low I don't think we should not
> > report it.
> >
> > Rethinking the integer arithmetics, it's true that we should avoid
> > hitting zero on the division, eg: nesting 6x 1% sampling rates will make
> > the result be zero which will make probability restoration fail on the
> > way back. Threrefore, the new probability should be at least 1.
> >
> >
> >> I'm not sure 

Re: [ovs-dev] [PATCH net-next v2 5/9] net: openvswitch: add emit_sample action

2024-06-18 Thread Adrián Moreno
On Mon, Jun 17, 2024 at 12:44:45PM GMT, Ilya Maximets wrote:
> On 6/3/24 20:56, Adrian Moreno wrote:
> > Add support for a new action: emit_sample.
> >
> > This action accepts a u32 group id and a variable-length cookie and uses
> > the psample multicast group to make the packet available for
> > observability.
> >
> > The maximum length of the user-defined cookie is set to 16, same as
> > tc_cookie, to discourage using cookies that will not be offloadable.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  Documentation/netlink/specs/ovs_flow.yaml | 17 
> >  include/uapi/linux/openvswitch.h  | 25 
> >  net/openvswitch/actions.c | 50 +++
> >  net/openvswitch/flow_netlink.c| 33 ++-
> >  4 files changed, 124 insertions(+), 1 deletion(-)
>
> Some nits below, beside ones already mentioned.
>

Thanks, Ilya.

> >
> > diff --git a/Documentation/netlink/specs/ovs_flow.yaml 
> > b/Documentation/netlink/specs/ovs_flow.yaml
> > index 4fdfc6b5cae9..a7ab5593a24f 100644
> > --- a/Documentation/netlink/specs/ovs_flow.yaml
> > +++ b/Documentation/netlink/specs/ovs_flow.yaml
> > @@ -727,6 +727,12 @@ attribute-sets:
> >  name: dec-ttl
> >  type: nest
> >  nested-attributes: dec-ttl-attrs
> > +  -
> > +name: emit-sample
> > +type: nest
> > +nested-attributes: emit-sample-attrs
> > +doc: |
> > +  Sends a packet sample to psample for external observation.
> >-
> >  name: tunnel-key-attrs
> >  enum-name: ovs-tunnel-key-attr
> > @@ -938,6 +944,17 @@ attribute-sets:
> >-
> >  name: gbp
> >  type: u32
> > +  -
> > +name: emit-sample-attrs
> > +enum-name: ovs-emit-sample-attr
> > +name-prefix: ovs-emit-sample-attr-
> > +attributes:
> > +  -
> > +name: group
> > +type: u32
> > +  -
> > +name: cookie
> > +type: binary
> >
> >  operations:
> >name-prefix: ovs-flow-cmd-
> > diff --git a/include/uapi/linux/openvswitch.h 
> > b/include/uapi/linux/openvswitch.h
> > index efc82c318fa2..a0e9dde0584a 100644
> > --- a/include/uapi/linux/openvswitch.h
> > +++ b/include/uapi/linux/openvswitch.h
> > @@ -914,6 +914,30 @@ struct check_pkt_len_arg {
> >  };
> >  #endif
> >
> > +#define OVS_EMIT_SAMPLE_COOKIE_MAX_SIZE 16
> > +/**
> > + * enum ovs_emit_sample_attr - Attributes for %OVS_ACTION_ATTR_EMIT_SAMPLE
> > + * action.
> > + *
> > + * @OVS_EMIT_SAMPLE_ATTR_GROUP: 32-bit number to identify the source of the
> > + * sample.
> > + * @OVS_EMIT_SAMPLE_ATTR_COOKIE: A variable-length binary cookie that 
> > contains
> > + * user-defined metadata. The maximum length is 16 bytes.
>
> s/16/OVS_EMIT_SAMPLE_COOKIE_MAX_SIZE/
>
> > + *
> > + * Sends the packet to the psample multicast group with the specified 
> > group and
> > + * cookie. It is possible to combine this action with the
> > + * %OVS_ACTION_ATTR_TRUNC action to limit the size of the packet being 
> > emitted.
> > + */
> > +enum ovs_emit_sample_attr {
> > +   OVS_EMIT_SAMPLE_ATTR_UNPSEC,
> > +   OVS_EMIT_SAMPLE_ATTR_GROUP, /* u32 number. */
> > +   OVS_EMIT_SAMPLE_ATTR_COOKIE,/* Optional, user specified cookie. */
> > +   __OVS_EMIT_SAMPLE_ATTR_MAX
> > +};
> > +
> > +#define OVS_EMIT_SAMPLE_ATTR_MAX (__OVS_EMIT_SAMPLE_ATTR_MAX - 1)
> > +
> > +
> >  /**
> >   * enum ovs_action_attr - Action types.
> >   *
> > @@ -1004,6 +1028,7 @@ enum ovs_action_attr {
> > OVS_ACTION_ATTR_ADD_MPLS, /* struct ovs_action_add_mpls. */
> > OVS_ACTION_ATTR_DEC_TTL,  /* Nested OVS_DEC_TTL_ATTR_*. */
> > OVS_ACTION_ATTR_DROP, /* u32 error code. */
> > +   OVS_ACTION_ATTR_EMIT_SAMPLE,  /* Nested OVS_EMIT_SAMPLE_ATTR_*. */
> >
> > __OVS_ACTION_ATTR_MAX,/* Nothing past this will be accepted
> >* from userspace. */
> > diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> > index 964225580824..3b4dba0ded59 100644
> > --- a/net/openvswitch/actions.c
> > +++ b/net/openvswitch/actions.c
> > @@ -24,6 +24,11 @@
> >  #include 
> >  #include 
> >  #include 
> > +
> > +#if IS_ENABLED(CONFIG_PSAMPLE)
> > +#include 
> > +#endif
> > +
> >  #include 
> >
> >  #include "datapath.h"
> > @@ -1299,6 +1304,46 @@ static int execute_dec_ttl(struct sk_buff *skb, 
> > struct sw_flow_key *key)
> > return 0;
> >  }
> >
> > +static int execute_emit_sample(struct datapath *dp, struct sk_buff *skb,
> > +  const struct sw_flow_key *key,
> > +  const struct nlattr *attr)
> > +{
> > +#if IS_ENABLED(CONFIG_PSAMPLE)
> > +   struct psample_group psample_group = {};
> > +   struct psample_metadata md = {};
> > +   struct vport *input_vport;
> > +   const struct nlattr *a;
> > +   int rem;
> > +
> > +   for (a = nla_data(attr), rem = nla_len(attr); rem > 0;
> > +a = nla_next(a, )) {
>
> Since the action is strictly validated, can use use 

Re: [ovs-dev] [PATCH net-next v2 7/9] net: openvswitch: do not notify drops inside sample

2024-06-18 Thread Adrián Moreno
On Mon, Jun 17, 2024 at 02:10:37PM GMT, Ilya Maximets wrote:
> On 6/17/24 13:55, Ilya Maximets wrote:
> > On 6/3/24 20:56, Adrian Moreno wrote:
> >> The OVS_ACTION_ATTR_SAMPLE action is, in essence,
> >> observability-oriented.
> >>
> >> Apart from some corner case in which it's used a replacement of clone()
> >> for old kernels, it's really only used for sFlow, IPFIX and now,
> >> local emit_sample.
> >>
> >> With this in mind, it doesn't make much sense to report
> >> OVS_DROP_LAST_ACTION inside sample actions.
> >>
> >> For instance, if the flow:
> >>
> >>   actions:sample(..,emit_sample(..)),2
> >>
> >> triggers a OVS_DROP_LAST_ACTION skb drop event, it would be extremely
> >> confusing for users since the packet did reach its destination.
> >>
> >> This patch makes internal action execution silently consume the skb
> >> instead of notifying a drop for this case.
> >>
> >> Unfortunately, this patch does not remove all potential sources of
> >> confusion since, if the sample action itself is the last action, e.g:
> >>
> >> actions:sample(..,emit_sample(..))
> >>
> >> we actually _should_ generate a OVS_DROP_LAST_ACTION event, but we aren't.
> >>
> >> Sadly, this case is difficult to solve without breaking the
> >> optimization by which the skb is not cloned on last sample actions.
> >> But, given explicit drop actions are now supported, OVS can just add one
> >> after the last sample() and rewrite the flow as:
> >>
> >> actions:sample(..,emit_sample(..)),drop
> >>
> >> Signed-off-by: Adrian Moreno 
> >> ---
> >>  net/openvswitch/actions.c | 13 +++--
> >>  1 file changed, 11 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> >> index 33f6d93ba5e4..54fc1abcff95 100644
> >> --- a/net/openvswitch/actions.c
> >> +++ b/net/openvswitch/actions.c
> >> @@ -82,6 +82,15 @@ static struct action_fifo __percpu *action_fifos;
> >>  static struct action_flow_keys __percpu *flow_keys;
> >>  static DEFINE_PER_CPU(int, exec_actions_level);
> >>
> >> +static inline void ovs_drop_skb_last_action(struct sk_buff *skb)
> >> +{
> >> +  /* Do not emit packet drops inside sample(). */
> >> +  if (OVS_CB(skb)->probability)
> >> +  consume_skb(skb);
> >> +  else
> >> +  ovs_kfree_skb_reason(skb, OVS_DROP_LAST_ACTION);
> >> +}
> >> +
> >>  /* Make a clone of the 'key', using the pre-allocated percpu 'flow_keys'
> >>   * space. Return NULL if out of key spaces.
> >>   */
> >> @@ -1061,7 +1070,7 @@ static int sample(struct datapath *dp, struct 
> >> sk_buff *skb,
> >>if ((arg->probability != U32_MAX) &&
> >>(!arg->probability || get_random_u32() > arg->probability)) {
> >>if (last)
> >> -  ovs_kfree_skb_reason(skb, OVS_DROP_LAST_ACTION);
> >> +  ovs_drop_skb_last_action(skb);
>
> Always consuming the skb at this point makes sense, since having smaple()
> as a last action is a reasonable thing to have.  But this looks more like
> a fix for the original drop reason patch set.
>

I don't think consuming the skb at this point makes sense. It was very
intentionally changed to a drop since a very common use-case for
sampling is drop-sampling, i.e: replacing an empty action list (that
triggers OVS_DROP_LAST_ACTION) with a sample(emit_sample()). Ideally,
that replacement should not have any effect on the number of
OVS_DROP_LAST_ACTION being reported as the packets are being treated in
the same way (only observed in one case).


> >>return 0;
> >>}
> >>
> >> @@ -1579,7 +1588,7 @@ static int do_execute_actions(struct datapath *dp, 
> >> struct sk_buff *skb,
> >>}
> >>}
> >>
> >> -  ovs_kfree_skb_reason(skb, OVS_DROP_LAST_ACTION);
> >> +  ovs_drop_skb_last_action(skb);
> >
> > I don't think I agree with this one.  If we have a sample() action with
> > a lot of different actions inside and we reached the end while the last
> > action didn't consume the skb, then we should report that.  E.g.
> > "sample(emit_sample(),push_vlan(),set(eth())),2"  should report that the
> > cloned skb was dropped.  "sample(push_vlan(),emit_sample())" should not.
> >

What is the use case for such action list? Having an action branch
executed randomly doesn't make sense to me if it's not some
observability thing (which IMHO should not trigger drops).

> > The only actions that are actually consuming the skb are "output",
> > "userspace", "recirc" and now "emit_sample".  "output" and "recirc" are
> > consuming the skb "naturally" by stealing it when it is the last action.
> > "userspace" has an explicit check to consume the skb if it is the last
> > action.  "emit_sample" should have the similar check.  It should likely
> > be added at the point of action introduction instead of having a separate
> > patch.
> >

Unlinke "output", "recirc", "userspace", etc. with emit_sample the
packet does not continue it's way through the datapath.

It would be very confusing if OVS starts monitoring drops 

Re: [ovs-dev] [RFC net-next 3/7] selftests: openvswitch: Add set() and set_masked() support.

2024-06-17 Thread Adrián Moreno
On Thu, Jun 13, 2024 at 02:13:29PM GMT, Aaron Conole wrote:
> These will be used in upcoming commits to set specific attributes for
> interacting with tunnels.  Since set() will use the key parsing routine, we
> also make sure to prepend it with an open paren, for the action parsing to
> properly understand it.
>
> Signed-off-by: Aaron Conole 
> ---
>  .../selftests/net/openvswitch/ovs-dpctl.py| 39 +--
>  1 file changed, 35 insertions(+), 4 deletions(-)
>
> diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py 
> b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> index 73768f3af6e5..fee64c31d4d4 100644
> --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> @@ -284,7 +284,7 @@ class ovsactions(nla):
>  ("OVS_ACTION_ATTR_UNSPEC", "none"),
>  ("OVS_ACTION_ATTR_OUTPUT", "uint32"),
>  ("OVS_ACTION_ATTR_USERSPACE", "userspace"),
> -("OVS_ACTION_ATTR_SET", "none"),
> +("OVS_ACTION_ATTR_SET", "ovskey"),
>  ("OVS_ACTION_ATTR_PUSH_VLAN", "none"),
>  ("OVS_ACTION_ATTR_POP_VLAN", "flag"),
>  ("OVS_ACTION_ATTR_SAMPLE", "none"),
> @@ -292,7 +292,7 @@ class ovsactions(nla):
>  ("OVS_ACTION_ATTR_HASH", "none"),
>  ("OVS_ACTION_ATTR_PUSH_MPLS", "none"),
>  ("OVS_ACTION_ATTR_POP_MPLS", "flag"),
> -("OVS_ACTION_ATTR_SET_MASKED", "none"),
> +("OVS_ACTION_ATTR_SET_MASKED", "ovskey"),
>  ("OVS_ACTION_ATTR_CT", "ctact"),
>  ("OVS_ACTION_ATTR_TRUNC", "uint32"),
>  ("OVS_ACTION_ATTR_PUSH_ETH", "none"),
> @@ -469,6 +469,14 @@ class ovsactions(nla):
>  print_str += "clone("
>  print_str += datum.dpstr(more)
>  print_str += ")"
> +elif field[0] == "OVS_ACTION_ATTR_SET" or \
> + field[0] == "OVS_ACTION_ATTR_SET_MASKED":
> +print_str += "set"
> +if field[0] == "OVS_ACTION_ATTR_SET_MASKED":
> +print_str += "_masked"
> +print_str += "("
> +print_str += datum.dpstr(more)
> +print_str += ")"
>  else:
>  try:
>  print_str += datum.dpstr(more)
> @@ -547,6 +555,25 @@ class ovsactions(nla):
>  self["attrs"].append(("OVS_ACTION_ATTR_CLONE", subacts))
>  actstr = actstr[parsedLen:]
>  parsed = True
> +elif parse_starts_block(actstr, "set(", False):
> +parencount += 1
> +k = ovskey()
> +actstr = actstr[len("set("):]
> +actstr = k.parse(actstr, None)
> +self["attrs"].append(("OVS_ACTION_ATTR_SET", k))
> +if not actstr.startswith(")"):
> +actstr = ")" + actstr
> +parsed = True
> +elif parse_starts_block(actstr, "set_masked(", False):
> +parencount += 1
> +k = ovskey()
> +m = ovskey()
> +actstr = actstr[len("set_masked("):]
> +actstr = k.parse(actstr, m)
> +self["attrs"].append(("OVS_ACTION_ATTR_SET_MASKED", [k, m]))
> +if not actstr.startswith(")"):
> +actstr = ")" + actstr
> +parsed = True
>  elif parse_starts_block(actstr, "ct(", False):
>  parencount += 1
>  actstr = actstr[len("ct(") :]
> @@ -1312,7 +1339,7 @@ class ovskey(nla):
>  mask["attrs"].append([field[0], m])
>  self["attrs"].append([field[0], k])
>
> -flowstr = flowstr[strspn(flowstr, "),") :]
> +flowstr = flowstr[strspn(flowstr, "), ") :]
>
>  return flowstr
>
> @@ -1898,7 +1925,11 @@ class OvsFlow(GenericNetlinkSocket):
>  ):
>  print_str += "drop"
>  else:
> -print_str += actsmsg.dpstr(more)
> +if type(actsmsg) == "list":

nit: I belive the recommended way of comparing types is using
"isinstance":

https://www.flake8rules.com/rules/E721.html

Also, I don't see what can make actmsg be a list. It should always be an
instance of "ovsactions", right?


> +for act in actsmsg:
> +print_str += act.dpstr(more)
> +else:
> +print_str += actsmsg.dpstr(more)
>
>  return print_str
>
> --
> 2.45.1
>

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH net-next v2 9/9] selftests: openvswitch: add emit_sample test

2024-06-17 Thread Adrián Moreno
On Fri, Jun 14, 2024 at 01:07:33PM GMT, Aaron Conole wrote:
> Adrian Moreno  writes:
>
> > Add a test to verify sampling packets via psample works.
> >
> > In order to do that, create a subcommand in ovs-dpctl.py to listen to
> > on the psample multicast group and print samples.
> >
> > In order to also test simultaneous sFlow and psample actions and
> > packet truncation, add missing parsing support for "userspace" and
> > "trunc" actions.
>
> Maybe split that into a separate patch.  This has a bugfix and 3
> features being pushed in.  I know it's already getting long as a series,
> so maybe it's okay to fold the userspace attribute bugfix with the parse
> support (since it wasn't really usable before).
>

OK. Sounds reasonable.

> > Signed-off-by: Adrian Moreno 
> > ---
> >  .../selftests/net/openvswitch/openvswitch.sh  |  99 +++-
> >  .../selftests/net/openvswitch/ovs-dpctl.py| 112 +-
> >  2 files changed, 204 insertions(+), 7 deletions(-)
> >
> > diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh 
> > b/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > index 5cae53543849..f6e0ae3f6424 100755
> > --- a/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > +++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh
> > @@ -20,7 +20,8 @@ tests="
> > nat_related_v4  ip4-nat-related: ICMP related 
> > matches work with SNAT
> > netlink_checks  ovsnl: validate netlink attrs 
> > and settings
> > upcall_interfaces   ovs: test the upcall interfaces
> > -   drop_reason drop: test drop reasons are 
> > emitted"
> > +   drop_reason drop: test drop reasons are 
> > emitted
> > +   emit_sample emit_sample: Sampling packets 
> > with psample"
> >
> >  info() {
> >  [ $VERBOSE = 0 ] || echo $*
> > @@ -170,6 +171,19 @@ ovs_drop_reason_count()
> > return `echo "$perf_output" | grep "$pattern" | wc -l`
> >  }
> >
> > +ovs_test_flow_fails () {
> > +   ERR_MSG="Flow actions may not be safe on all matching packets"
> > +
> > +   PRE_TEST=$(dmesg | grep -c "${ERR_MSG}")
> > +   ovs_add_flow $@ &> /dev/null $@ && return 1
> > +   POST_TEST=$(dmesg | grep -c "${ERR_MSG}")
> > +
> > +   if [ "$PRE_TEST" == "$POST_TEST" ]; then
> > +   return 1
> > +   fi
> > +   return 0
> > +}
> > +
> >  usage() {
> > echo
> > echo "$0 [OPTIONS] [TEST]..."
> > @@ -184,6 +198,89 @@ usage() {
> > exit 1
> >  }
> >
> > +
> > +# emit_sample test
> > +# - use emit_sample to observe packets
> > +test_emit_sample() {
> > +   sbx_add "test_emit_sample" || return $?
> > +
> > +   # Add a datapath with per-vport dispatching.
> > +   ovs_add_dp "test_emit_sample" emit_sample -V 2:1 || return 1
> > +
> > +   info "create namespaces"
> > +   ovs_add_netns_and_veths "test_emit_sample" "emit_sample" \
> > +   client c0 c1 172.31.110.10/24 -u || return 1
> > +   ovs_add_netns_and_veths "test_emit_sample" "emit_sample" \
> > +   server s0 s1 172.31.110.20/24 -u || return 1
> > +
> > +   # Check if emit_sample actions can be configured.
> > +   ovs_add_flow "test_emit_sample" emit_sample \
> > +   'in_port(1),eth(),eth_type(0x0806),arp()' 'emit_sample(group=1)'
> > +   if [ $? == 1 ]; then
> > +   info "no support for emit_sample - skipping"
> > +   ovs_exit_sig
> > +   return $ksft_skip
> > +   fi
> > +
> > +   ovs_del_flows "test_emit_sample" emit_sample
> > +
> > +   # Allow ARP
> > +   ovs_add_flow "test_emit_sample" emit_sample \
> > +   'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1
> > +   ovs_add_flow "test_emit_sample" emit_sample \
> > +   'in_port(2),eth(),eth_type(0x0806),arp()' '1' || return 1
> > +
> > +   # Test action verification.
> > +   OLDIFS=$IFS
> > +   IFS='*'
> > +   min_key='in_port(1),eth(),eth_type(0x0800),ipv4()'
> > +   for testcase in \
> > +   "cookie to 
> > large"*"emit_sample(group=1,cookie=1615141312111009080706050403020100)" \
> > +   "no group with cookie"*"emit_sample(cookie=abcd)" \
> > +   "no group"*"sample()";
> > +   do
> > +   set -- $testcase;
> > +   ovs_test_flow_fails "test_emit_sample" emit_sample $min_key $2
> > +   if [ $? == 1 ]; then
> > +   info "failed - $1"
> > +   return 1
> > +   fi
> > +   done
> > +   IFS=$OLDIFS
> > +
> > +   # Sample first 14 bytes of all traffic.
> > +   ovs_add_flow "test_emit_sample" emit_sample \
> > +   
> > "in_port(1),eth(),eth_type(0x0800),ipv4(src=172.31.110.10,proto=1),icmp()" 
> > "trunc(14),emit_sample(group=1,cookie=c0ffee),2"
> > +
> > +   # Sample all traffic. In this case, use a sample() action with both
> > +   # emit_sample and an upcall emulating simultaneous local sampling and
> > +   # sFlow / IPFIX.
> > +   nlpid=$(grep -E "listening on upcall packet 

Re: [ovs-dev] [PATCH net-next v2 6/9] net: openvswitch: store sampling probability in cb.

2024-06-17 Thread Adrián Moreno
On Fri, Jun 14, 2024 at 12:55:59PM GMT, Aaron Conole wrote:
> Adrian Moreno  writes:
>
> > The behavior of actions might not be the exact same if they are being
> > executed inside a nested sample action. Store the probability of the
> > parent sample action in the skb's cb area.
>
> What does that mean?
>

Emit action, for instance, needs the probability so that psample
consumers know what was the sampling rate applied. Also, the way we
should inform about packet drops (via kfree_skb_reason) changes (see
patch 7/9).

> > Use the probability in emit_sample to pass it down to psample.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  include/uapi/linux/openvswitch.h |  3 ++-
> >  net/openvswitch/actions.c| 25 ++---
> >  net/openvswitch/datapath.h   |  3 +++
> >  net/openvswitch/vport.c  |  1 +
> >  4 files changed, 28 insertions(+), 4 deletions(-)
> >
> > diff --git a/include/uapi/linux/openvswitch.h 
> > b/include/uapi/linux/openvswitch.h
> > index a0e9dde0584a..9d675725fa2b 100644
> > --- a/include/uapi/linux/openvswitch.h
> > +++ b/include/uapi/linux/openvswitch.h
> > @@ -649,7 +649,8 @@ enum ovs_flow_attr {
> >   * Actions are passed as nested attributes.
> >   *
> >   * Executes the specified actions with the given probability on a 
> > per-packet
> > - * basis.
> > + * basis. Nested actions will be able to access the probability value of 
> > the
> > + * parent @OVS_ACTION_ATTR_SAMPLE.
> >   */
> >  enum ovs_sample_attr {
> > OVS_SAMPLE_ATTR_UNSPEC,
> > diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> > index 3b4dba0ded59..33f6d93ba5e4 100644
> > --- a/net/openvswitch/actions.c
> > +++ b/net/openvswitch/actions.c
> > @@ -1048,12 +1048,15 @@ static int sample(struct datapath *dp, struct 
> > sk_buff *skb,
> > struct nlattr *sample_arg;
> > int rem = nla_len(attr);
> > const struct sample_arg *arg;
> > +   u32 init_probability;
> > bool clone_flow_key;
> > +   int err;
> >
> > /* The first action is always 'OVS_SAMPLE_ATTR_ARG'. */
> > sample_arg = nla_data(attr);
> > arg = nla_data(sample_arg);
> > actions = nla_next(sample_arg, );
> > +   init_probability = OVS_CB(skb)->probability;
> >
> > if ((arg->probability != U32_MAX) &&
> > (!arg->probability || get_random_u32() > arg->probability)) {
> > @@ -1062,9 +1065,21 @@ static int sample(struct datapath *dp, struct 
> > sk_buff *skb,
> > return 0;
> > }
> >
> > +   if (init_probability) {
> > +   OVS_CB(skb)->probability = ((u64)OVS_CB(skb)->probability *
> > +   arg->probability / U32_MAX);
> > +   } else {
> > +   OVS_CB(skb)->probability = arg->probability;
> > +   }
> > +
>
> I'm confused by this.  Eventually, integer arithmetic will practically
> guarantee that nested sample() calls will go to 0.  So eventually, the
> test above will be impossible to meet mathematically.
>
> OTOH, you could argue that a 1% of 50% is low anyway, but it still would
> have a positive probability count, and still be possible for
> get_random_u32() call to match.
>

Using OVS's probability semantics, we can express probabilities as low
as (100/U32_MAX)% which is pretty low indeed. However, just because the
probability of executing the action is low I don't think we should not
report it.

Rethinking the integer arithmetics, it's true that we should avoid
hitting zero on the division, eg: nesting 6x 1% sampling rates will make
the result be zero which will make probability restoration fail on the
way back. Threrefore, the new probability should be at least 1.


> I'm not sure about this particular change.  Why do we need it?
>

Why do we need to propagate the probability down to nested "sample"
actions? or why do we need to store the probability in the cb area in
the first place?

The former: Just for correctness as only storing the last one would be
incorrect. Although I don't know of any use for nested "sample" actions.
The latter: To pass it down to psample so that sample receivers know how
the sampling rate applied (and, e.g: do throughput estimations like OVS
does with IPFIX).


> > clone_flow_key = !arg->exec;
> > -   return clone_execute(dp, skb, key, 0, actions, rem, last,
> > -clone_flow_key);
> > +   err = clone_execute(dp, skb, key, 0, actions, rem, last,
> > +   clone_flow_key);
> > +
> > +   if (!last)
>
> Is this right?  Don't we only want to set the probability on the last
> action?  Should the test be 'if (last)'?
>

This is restoring the parent's probability after the actions in the
current sample action have been executed.

If it was the last action there is no need to restore the probability
back to the parent's (or zero if it's there's only one level) since no
further action will require it. And more importantly, if it's the last
action, the packet gets free'ed inside that "branch" so we must not
access its memory.


> > + 

Re: [ovs-dev] [PATCH net-next v2 4/9] net: psample: allow using rate as probability

2024-06-17 Thread Adrián Moreno
On Fri, Jun 14, 2024 at 05:11:30PM GMT, Simon Horman wrote:
> On Mon, Jun 03, 2024 at 08:56:38PM +0200, Adrian Moreno wrote:
> > Although not explicitly documented in the psample module itself, the
> > definition of PSAMPLE_ATTR_SAMPLE_RATE seems inherited from act_sample.
> >
> > Quoting tc-sample(8):
> > "RATE of 100 will lead to an average of one sampled packet out of every
> > 100 observed."
> >
> > With this semantics, the rates that we can express with an unsigned
> > 32-bits number are very unevenly distributed and concentrated towards
> > "sampling few packets".
> > For example, we can express a probability of 2.32E-8% but we
> > cannot express anything between 100% and 50%.
> >
> > For sampling applications that are capable of sampling a decent
> > amount of packets, this sampling rate semantics is not very useful.
> >
> > Add a new flag to the uAPI that indicates that the sampling rate is
> > expressed in scaled probability, this is:
> > - 0 is 0% probability, no packets get sampled.
> > - U32_MAX is 100% probability, all packets get sampled.
> >
> > Signed-off-by: Adrian Moreno 
>
> Hi Adrian,
>
> Would it be possible to add appropriate documentation for
> rate - both the original ratio variant, and the new probability
> variant - somewhere?
>

Hi Simon, thanks for the suggestion. Would the uapi header be a good
place for such documentation?

> That aside, this looks good to me.
>
> ...
>

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH net-next v2 5/9] net: openvswitch: add emit_sample action

2024-06-11 Thread Adrián Moreno
On Tue, Jun 11, 2024 at 09:54:49AM GMT, Aaron Conole wrote:
> Adrián Moreno  writes:
>
> > On Mon, Jun 10, 2024 at 11:46:14AM GMT, Aaron Conole wrote:
> >> Adrian Moreno  writes:
> >>
> >> > Add support for a new action: emit_sample.
> >> >
> >> > This action accepts a u32 group id and a variable-length cookie and uses
> >> > the psample multicast group to make the packet available for
> >> > observability.
> >> >
> >> > The maximum length of the user-defined cookie is set to 16, same as
> >> > tc_cookie, to discourage using cookies that will not be offloadable.
> >> >
> >> > Signed-off-by: Adrian Moreno 
> >> > ---
> >>
> >> I saw some of the nits Simon raised - I'll add one more below.
> >>
> >> I haven't gone through the series thoroughly enough to make a detailed
> >> review.
> >>
> >> >  Documentation/netlink/specs/ovs_flow.yaml | 17 
> >> >  include/uapi/linux/openvswitch.h  | 25 
> >> >  net/openvswitch/actions.c | 50 +++
> >> >  net/openvswitch/flow_netlink.c| 33 ++-
> >> >  4 files changed, 124 insertions(+), 1 deletion(-)
> >> >
> >> > diff --git a/Documentation/netlink/specs/ovs_flow.yaml 
> >> > b/Documentation/netlink/specs/ovs_flow.yaml
> >> > index 4fdfc6b5cae9..a7ab5593a24f 100644
> >> > --- a/Documentation/netlink/specs/ovs_flow.yaml
> >> > +++ b/Documentation/netlink/specs/ovs_flow.yaml
> >> > @@ -727,6 +727,12 @@ attribute-sets:
> >> >  name: dec-ttl
> >> >  type: nest
> >> >  nested-attributes: dec-ttl-attrs
> >> > +  -
> >> > +name: emit-sample
> >> > +type: nest
> >> > +nested-attributes: emit-sample-attrs
> >> > +doc: |
> >> > +  Sends a packet sample to psample for external observation.
> >> >-
> >> >  name: tunnel-key-attrs
> >> >  enum-name: ovs-tunnel-key-attr
> >> > @@ -938,6 +944,17 @@ attribute-sets:
> >> >-
> >> >  name: gbp
> >> >  type: u32
> >> > +  -
> >> > +name: emit-sample-attrs
> >> > +enum-name: ovs-emit-sample-attr
> >> > +name-prefix: ovs-emit-sample-attr-
> >> > +attributes:
> >> > +  -
> >> > +name: group
> >> > +type: u32
> >> > +  -
> >> > +name: cookie
> >> > +type: binary
> >> >
> >> >  operations:
> >> >name-prefix: ovs-flow-cmd-
> >> > diff --git a/include/uapi/linux/openvswitch.h 
> >> > b/include/uapi/linux/openvswitch.h
> >> > index efc82c318fa2..a0e9dde0584a 100644
> >> > --- a/include/uapi/linux/openvswitch.h
> >> > +++ b/include/uapi/linux/openvswitch.h
> >> > @@ -914,6 +914,30 @@ struct check_pkt_len_arg {
> >> >  };
> >> >  #endif
> >> >
> >> > +#define OVS_EMIT_SAMPLE_COOKIE_MAX_SIZE 16
> >> > +/**
> >> > + * enum ovs_emit_sample_attr - Attributes for 
> >> > %OVS_ACTION_ATTR_EMIT_SAMPLE
> >> > + * action.
> >> > + *
> >> > + * @OVS_EMIT_SAMPLE_ATTR_GROUP: 32-bit number to identify the source of 
> >> > the
> >> > + * sample.
> >> > + * @OVS_EMIT_SAMPLE_ATTR_COOKIE: A variable-length binary cookie that 
> >> > contains
> >> > + * user-defined metadata. The maximum length is 16 bytes.
> >> > + *
> >> > + * Sends the packet to the psample multicast group with the specified 
> >> > group and
> >> > + * cookie. It is possible to combine this action with the
> >> > + * %OVS_ACTION_ATTR_TRUNC action to limit the size of the packet being 
> >> > emitted.
> >> > + */
> >> > +enum ovs_emit_sample_attr {
> >> > +OVS_EMIT_SAMPLE_ATTR_UNPSEC,
> >> > +OVS_EMIT_SAMPLE_ATTR_GROUP, /* u32 number. */
> >> > +OVS_EMIT_SAMPLE_ATTR_COOKIE,/* Optional, user specified 
> >> > cookie. */
> >> > +__OVS_EMIT_SAMPLE_ATTR_MAX
> >> > +};
> >> > +
> >> > +#define OVS_EMIT_SAMPLE_ATTR_MAX (__OVS_EMIT_SAMPLE_ATTR_MAX - 1)
> >> > +

Re: [ovs-dev] [PATCH net-next 2/2] selftests: openvswitch: set value to nla flags

2024-06-11 Thread Adrián Moreno
On Mon, Jun 03, 2024 at 03:02:46PM GMT, Aaron Conole wrote:
> Adrian Moreno  writes:
>
> > Netlink flags, although they don't have payload at the netlink level,
> > are represented as having a "True" value in pyroute2.
> >
> > Without it, trying to add a flow with a flag-type action (e.g: pop_vlan)
> > fails with the following traceback:
> >
> > Traceback (most recent call last):
> >   File "[...]/ovs-dpctl.py", line 2498, in 
> > sys.exit(main(sys.argv))
> >  ^^
> >   File "[...]/ovs-dpctl.py", line 2487, in main
> > ovsflow.add_flow(rep["dpifindex"], flow)
> >   File "[...]/ovs-dpctl.py", line 2136, in add_flow
> > reply = self.nlm_request(
> > ^
> >   File "[...]/pyroute2/netlink/nlsocket.py", line 822, in nlm_request
> > return tuple(self._genlm_request(*argv, **kwarg))
> >  ^^^
> >   File "[...]/pyroute2/netlink/generic/__init__.py", line 126, in
> > nlm_request
> > return tuple(super().nlm_request(*argv, **kwarg))
> >^^
> >   File "[...]/pyroute2/netlink/nlsocket.py", line 1124, in nlm_request
> > self.put(msg, msg_type, msg_flags, msg_seq=msg_seq)
> >   File "[...]/pyroute2/netlink/nlsocket.py", line 389, in put
> > self.sendto_gate(msg, addr)
> >   File "[...]/pyroute2/netlink/nlsocket.py", line 1056, in sendto_gate
> > msg.encode()
> >   File "[...]/pyroute2/netlink/__init__.py", line 1245, in encode
> > offset = self.encode_nlas(offset)
> >  
> >   File "[...]/pyroute2/netlink/__init__.py", line 1560, in encode_nlas
> > nla_instance.setvalue(cell[1])
> >   File "[...]/pyroute2/netlink/__init__.py", line 1265, in setvalue
> > nlv.setvalue(nla_tuple[1])
> >  ~^^^
> > IndexError: list index out of range
> >
> > Signed-off-by: Adrian Moreno 
> > ---
>
> Acked-by: Aaron Conole 
>
> I don't know which pyroute2 version I had used when I tested this
> previously, but even on my current system I get this error now.  Thanks
> for the fix.
>

Thanks Aaron. I'll resend as v2 with your ack as a stand-alone patch
since the other patch of this series will be fixed by your soon-to-come
series.

> >  tools/testing/selftests/net/openvswitch/ovs-dpctl.py | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py 
> > b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> > index b76907ac0092..a2395c3f37a1 100644
> > --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> > +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> > @@ -537,7 +537,7 @@ class ovsactions(nla):
> >  for flat_act in parse_flat_map:
> >  if parse_starts_block(actstr, flat_act[0], False):
> >  actstr = actstr[len(flat_act[0]):]
> > -self["attrs"].append([flat_act[1]])
> > +self["attrs"].append([flat_act[1], True])
> >  actstr = actstr[strspn(actstr, ", ") :]
> >  parsed = True
>

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH net-next v2 5/9] net: openvswitch: add emit_sample action

2024-06-11 Thread Adrián Moreno
On Mon, Jun 10, 2024 at 11:46:14AM GMT, Aaron Conole wrote:
> Adrian Moreno  writes:
>
> > Add support for a new action: emit_sample.
> >
> > This action accepts a u32 group id and a variable-length cookie and uses
> > the psample multicast group to make the packet available for
> > observability.
> >
> > The maximum length of the user-defined cookie is set to 16, same as
> > tc_cookie, to discourage using cookies that will not be offloadable.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
>
> I saw some of the nits Simon raised - I'll add one more below.
>
> I haven't gone through the series thoroughly enough to make a detailed
> review.
>
> >  Documentation/netlink/specs/ovs_flow.yaml | 17 
> >  include/uapi/linux/openvswitch.h  | 25 
> >  net/openvswitch/actions.c | 50 +++
> >  net/openvswitch/flow_netlink.c| 33 ++-
> >  4 files changed, 124 insertions(+), 1 deletion(-)
> >
> > diff --git a/Documentation/netlink/specs/ovs_flow.yaml 
> > b/Documentation/netlink/specs/ovs_flow.yaml
> > index 4fdfc6b5cae9..a7ab5593a24f 100644
> > --- a/Documentation/netlink/specs/ovs_flow.yaml
> > +++ b/Documentation/netlink/specs/ovs_flow.yaml
> > @@ -727,6 +727,12 @@ attribute-sets:
> >  name: dec-ttl
> >  type: nest
> >  nested-attributes: dec-ttl-attrs
> > +  -
> > +name: emit-sample
> > +type: nest
> > +nested-attributes: emit-sample-attrs
> > +doc: |
> > +  Sends a packet sample to psample for external observation.
> >-
> >  name: tunnel-key-attrs
> >  enum-name: ovs-tunnel-key-attr
> > @@ -938,6 +944,17 @@ attribute-sets:
> >-
> >  name: gbp
> >  type: u32
> > +  -
> > +name: emit-sample-attrs
> > +enum-name: ovs-emit-sample-attr
> > +name-prefix: ovs-emit-sample-attr-
> > +attributes:
> > +  -
> > +name: group
> > +type: u32
> > +  -
> > +name: cookie
> > +type: binary
> >
> >  operations:
> >name-prefix: ovs-flow-cmd-
> > diff --git a/include/uapi/linux/openvswitch.h 
> > b/include/uapi/linux/openvswitch.h
> > index efc82c318fa2..a0e9dde0584a 100644
> > --- a/include/uapi/linux/openvswitch.h
> > +++ b/include/uapi/linux/openvswitch.h
> > @@ -914,6 +914,30 @@ struct check_pkt_len_arg {
> >  };
> >  #endif
> >
> > +#define OVS_EMIT_SAMPLE_COOKIE_MAX_SIZE 16
> > +/**
> > + * enum ovs_emit_sample_attr - Attributes for %OVS_ACTION_ATTR_EMIT_SAMPLE
> > + * action.
> > + *
> > + * @OVS_EMIT_SAMPLE_ATTR_GROUP: 32-bit number to identify the source of the
> > + * sample.
> > + * @OVS_EMIT_SAMPLE_ATTR_COOKIE: A variable-length binary cookie that 
> > contains
> > + * user-defined metadata. The maximum length is 16 bytes.
> > + *
> > + * Sends the packet to the psample multicast group with the specified 
> > group and
> > + * cookie. It is possible to combine this action with the
> > + * %OVS_ACTION_ATTR_TRUNC action to limit the size of the packet being 
> > emitted.
> > + */
> > +enum ovs_emit_sample_attr {
> > +   OVS_EMIT_SAMPLE_ATTR_UNPSEC,
> > +   OVS_EMIT_SAMPLE_ATTR_GROUP, /* u32 number. */
> > +   OVS_EMIT_SAMPLE_ATTR_COOKIE,/* Optional, user specified cookie. */
> > +   __OVS_EMIT_SAMPLE_ATTR_MAX
> > +};
> > +
> > +#define OVS_EMIT_SAMPLE_ATTR_MAX (__OVS_EMIT_SAMPLE_ATTR_MAX - 1)
> > +
> > +
> >  /**
> >   * enum ovs_action_attr - Action types.
> >   *
> > @@ -1004,6 +1028,7 @@ enum ovs_action_attr {
> > OVS_ACTION_ATTR_ADD_MPLS, /* struct ovs_action_add_mpls. */
> > OVS_ACTION_ATTR_DEC_TTL,  /* Nested OVS_DEC_TTL_ATTR_*. */
> > OVS_ACTION_ATTR_DROP, /* u32 error code. */
> > +   OVS_ACTION_ATTR_EMIT_SAMPLE,  /* Nested OVS_EMIT_SAMPLE_ATTR_*. */
> >
> > __OVS_ACTION_ATTR_MAX,/* Nothing past this will be accepted
> >* from userspace. */
> > diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> > index 964225580824..3b4dba0ded59 100644
> > --- a/net/openvswitch/actions.c
> > +++ b/net/openvswitch/actions.c
> > @@ -24,6 +24,11 @@
> >  #include 
> >  #include 
> >  #include 
> > +
> > +#if IS_ENABLED(CONFIG_PSAMPLE)
> > +#include 
> > +#endif
> > +
> >  #include 
> >
> >  #include "datapath.h"
> > @@ -1299,6 +1304,46 @@ static int execute_dec_ttl(struct sk_buff *skb, 
> > struct sw_flow_key *key)
> > return 0;
> >  }
> >
> > +static int execute_emit_sample(struct datapath *dp, struct sk_buff *skb,
> > +  const struct sw_flow_key *key,
> > +  const struct nlattr *attr)
> > +{
> > +#if IS_ENABLED(CONFIG_PSAMPLE)
> > +   struct psample_group psample_group = {};
> > +   struct psample_metadata md = {};
> > +   struct vport *input_vport;
> > +   const struct nlattr *a;
> > +   int rem;
> > +
> > +   for (a = nla_data(attr), rem = nla_len(attr); rem > 0;
> > +a = nla_next(a, )) {
> > +   switch (nla_type(a)) {
> > 

Re: [ovs-dev] [PATCH net-next v2 9/9] selftests: openvswitch: add emit_sample test

2024-06-10 Thread Adrián Moreno
On Wed, Jun 05, 2024 at 08:43:14PM GMT, Simon Horman wrote:
> On Mon, Jun 03, 2024 at 08:56:43PM +0200, Adrian Moreno wrote:
> > Add a test to verify sampling packets via psample works.
> >
> > In order to do that, create a subcommand in ovs-dpctl.py to listen to
> > on the psample multicast group and print samples.
> >
> > In order to also test simultaneous sFlow and psample actions and
> > packet truncation, add missing parsing support for "userspace" and
> > "trunc" actions.
> >
> > Signed-off-by: Adrian Moreno 
>
> ...
>
> > @@ -803,6 +819,25 @@ class ovsactions(nla):
> >  self["attrs"].append(["OVS_ACTION_ATTR_EMIT_SAMPLE", 
> > emitact])
> >  parsed = True
> >
> > +elif parse_starts_block(actstr, "userspace(", False):
> > +uact = self.userspace()
> > +actstr = uact.parse(actstr[len("userpsace(") : ])
>
> nit: userspace
>
>  Flagged by checkpatch.pl --codespell
>

Thanks. Will fix it.

> > +self["attrs"].append(["OVS_ACTION_ATTR_USERSPACE", uact])
> > +parsed = True
> > +
> > +elif parse_starts_block(actstr, "trunc", False):
> > +parencount += 1
> > +actstr, val = parse_extract_field(
> > +actstr,
> > +"trunc(",
> > +r"([0-9]+)",
> > +int,
> > +False,
> > +None,
> > +)
> > +self["attrs"].append(["OVS_ACTION_ATTR_TRUNC", val])
> > +parsed = True
> > +
> >  actstr = actstr[strspn(actstr, ", ") :]
> >  while parencount > 0:
> >  parencount -= 1
>

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [BUG][revalidator] ovs crash and could NOT fix again after set request_mtu

2024-06-10 Thread Adrián Moreno
On Mon, Jun 03, 2024 at 10:18:05AM GMT, Simon Jones wrote:
> In ovs code, bridge_reconfigure function should ONLY be called in
> ovs-vswitchd thread.
>
> But how about this case:
> - ovs-vswitchd is starting, the ovs-vswitch thread calls bridge_reconfigure
> function.
> - at the same time, ovs-vsctl set port xxx request_mtu=4800 comes to
> ovs-vswitchd thread.
> - the ovs-vswitchd interrupt to process request_mtu.

ovs-vsctl does not interrupt ovs-vswitchd. It writes into the
ovsdb-server. Changes in the content of the database, in particular
changes in the port configuration, will be picked up and processed by
ovs-vswitchd's main thread on the next run of bridge_run().

There should be no race condition here.

Maybe the port failed to ge reconfigured and was left in some
partially-initialzed state.

Could you please enable netdev-dpdk and ofproto debug logs and attach
the full ovs-vswitchd.log?

>
> ???
>
> 
> Simon Jones
>
>
> Ilya Maximets  于2024年5月31日周五 17:43写道:
>
> > On 5/31/24 04:00, Simon Jones wrote:
> > > Hi all,
> > >
> > > I'm using ovs-dpdk(ovs:2.17.1, dpdk:21.11.1).
> > > Now I found a BUG that ovs crash and could NOT fix again after set
> > > request_mtu.
> > >
> > > 1. How to reproduce and my Analysis:
> > > ```
> > > # start ovs and add bridge and port and openflow
> > >
> > > [root@bogon ~]# ovs-vsctl show
> > > 0444869c-dc4d-462f-8caf-074ecbab1a55
> > > Bridge br-int
> > > datapath_type: netdev
> > > Port p0
> > > Interface p0
> > > type: dpdk
> > > options: {dpdk-devargs=":c1:00.0"}
> > > Port br-int
> > > Interface br-int
> > > type: internal
> > > Bridge br-phy
> > > datapath_type: netdev
> > > Port pf1vf0
> > > Interface pf1vf0
> > > type: dpdk
> > > options: {dpdk-devargs=":c1:00.1,representor=[0]"}
> > > Port pf1vf1
> > > Interface pf1vf1
> > > type: dpdk
> > > options: {dpdk-devargs=":c1:00.1,representor=[1]"}
> > > Port br-phy
> > > Interface br-phy
> > > type: internal
> > > Port pf1vf3
> > > Interface pf1vf3
> > > type: dpdk
> > > options: {dpdk-devargs=":c1:00.1,representor=[3]"}
> > > Port pf1vf2
> > > Interface pf1vf2
> > > type: dpdk
> > > options: {dpdk-devargs=":c1:00.1,representor=[2]"}
> > > ovs_version: "2.17.2"
> > >
> > > [root@bogon ~]# ovs-ofctl dump-flows br-int
> > >  cookie=0x0, duration=60216.364s, table=0, n_packets=16923639262,
> > > n_bytes=984712027272, priority=0 actions=NORMAL
> > >
> > >  865084 root  10 -10  522.9g   1.6g  42808 S  17.3   0.6 175:48.23
> > > revalidator53
> > >  865123 root  10 -10  522.9g   1.6g  42808 S  17.3   0.6 175:00.43
> > > revalidator92
> > >  865158 root  10 -10  522.9g   1.6g  42808 S  17.3   0.6 175:58.49
> > > revalidator127
> > >  865171 root  10 -10  522.9g   1.6g  42808 S  17.3   0.6 176:29.69
> > > revalidator140
> > >  865058 root  10 -10  522.9g   1.6g  42808 S  16.9   0.6 176:58.03
> > > revalidator27
> > >  865091 root  10 -10  522.9g   1.6g  42808 S  16.9   0.6 175:41.81
> > > revalidator60
> > >  865111 root  10 -10  522.9g   1.6g  42808 S  16.9   0.6 176:05.97
> > > revalidator80
> > >  865113 root  10 -10  522.9g   1.6g  42808 S  16.9   0.6 177:09.64
> > > revalidator82
> > >  865130 root  10 -10  522.9g   1.6g  42808 S  16.9   0.6 176:16.27
> > > revalidator99
> > >  865155 root  10 -10  522.9g   1.6g  42808 S  16.9   0.6 176:11.22
> > > revalidator124
> > >  865097 root  10 -10  522.9g   1.6g  42808 S  16.6   0.6 177:00.22
> > > revalidator66
> > >  865110 root  10 -10  522.9g   1.6g  42808 S  16.6   0.6 175:16.52
> > > revalidator79
> > >  865149 root  10 -10  522.9g   1.6g  42808 S  16.6   0.6 176:00.84
> > > revalidator118
> > >  865151 root  10 -10  522.9g   1.6g  42808 S  16.6   0.6 176:29.06
> > > revalidator120
> > >  865057 root  10 -10  522.9g   1.6g  42808 S  16.3   0.6 178:03.60
> > > revalidator26
> > >  865070 root  10 -10  522.9g   1.6g  42808 S  16.3   0.6 176:17.63
> > > revalidator39
> > >  865112 root  10 -10  522.9g   1.6g  42808 S  16.3   0.6 175:35.65
> > > revalidator81
> > >  865083 root  10 -10  522.9g   1.6g  42808 S  15.9   0.6 176:21.53
> > > revalidator52
> > >  865124 root  10 -10  522.9g   1.6g  42808 S  15.9   0.6 175:31.27
> > > revalidator93
> > >  865127 root  10 -10  522.9g   1.6g  42808 S  15.9   0.6 176:59.65
> > > revalidator96
> > >  865147 root  10 -10  522.9g   1.6g  42808 S  15.9   0.6 176:51.85
> > > revalidator116
> > >  865164 root  10 -10  522.9g   1.6g  42808 S  15.9   0.6 177:34.16
> > > revalidator133
> > >  865051 root  10 -10  522.9g   1.6g  42808 S  15.6   0.6 175:27.68
> > > revalidator20
> 

Re: [ovs-dev] [PATCH v2] checkpatch: Don't warn on pointer to pointer.

2024-06-07 Thread Adrián Moreno
On Fri, Jun 07, 2024 at 08:57:11AM GMT, Eelco Chaudron wrote:
>
>
> On 5 Jun 2024, at 15:51, Adrian Moreno wrote:
>
> > Current regexp used to check whitespaces around operators does not
> > consider that there can be more than one "*" together to express pointer
> > to pointer.
> >
> > As a result, false positive warnings are raised when the
> > patch contains a simple list of pointers, e.g: "char **errrp").
> >
> > Fix the regexp to allow more than one consecutive "+" characters.
> >

I just noticed "+" should actually be "*"!

> > Signed-off-by: Adrian Moreno 
>
> Thanks for fixing this Adrian.
>
> Acked-by: Eelco Chaudron 
>

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH] python: ovs: flow: Fix nested check_pkt_len acts.

2024-06-06 Thread Adrián Moreno
On Thu, Jun 06, 2024 at 06:00:26PM GMT, Ilya Maximets wrote:
> On 6/6/24 17:15, Adrian Moreno wrote:
> > Add check_pkt_len action to the decoder list that it, itself, uses.
> >
> > This makes nested check_pkt_len (i.e:a check_pkt_len inside another)
> > work.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  python/ovs/flow/odp.py   | 43 ++--
> >  python/ovs/tests/test_odp.py | 29 
> >  2 files changed, 51 insertions(+), 21 deletions(-)
>
> Hi, Adrian.
>
> Could you, please, provide a Fixes tag for this?
> No need to send v2 just for this, just reply with it to this thread.
> (Tags should start from the beginning of the line for patchwork to
> recognize them.)
>

Sure, how about this:

Reported-by: Ilya Maximets 
Fixes: 076663b31edc ("python: Add ovs datapath flow parsing.")

Thanks
Adrián

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH ovn v4] Text respresntations for drop sampling.

2024-06-06 Thread Adrián Moreno
On Mon, Jun 03, 2024 at 03:47:25PM GMT, Jacob Tanenbaum wrote:
> Created a new column in the southbound database to hardcode a human readable
> description for flows. This first use is describing why the flow is dropping 
> packets.
> The new column is called flow_desc and will create southbound database 
> entries like this
>
> _uuid   : 20f1897b-477e-47ae-a32c-c546d83ec097
> actions : 
> "sample(probability=65535,collector_set=123,obs_domain=1,obs_point=$cookie); 
> /* drop */"
> controller_meter: []
> external_ids: {source="northd.c:8721", stage-name=ls_in_l2_unknown}
> flow_desc   : "No L2 destination"
> logical_datapath: []
> logical_dp_group: ee3c3db5-98a2-4f34-8a84-409deae140a7
> match   : "outport == \"none\""
> pipeline: ingress
> priority: 50
> table_id: 27
> tags: {}
> hash: 0
>
> future work includes entering more flow_desc for more flows and adding
> flow_desc to the actions as a comment.

Is this future work planned for the next OVN version?

>
> Signed-off-by: Jacob Tanenbaum 
> Suggested-by: Dumitru Ceara 
> Reported-at: https://issues.redhat.com/browse/FDP-307
>
> ---
>
> v1: initial version
> v2: correct commit message
> make the flow_desc a char*
> correct a typo in the ovn-sb.xml
> correct the test
> v3: rebase issue with NEWS file
> v4: remove options:debug_drop_domain_id="1" from testing as we
> do not depend on it
>
> merge
>
> diff --git a/NEWS b/NEWS
> index 81c958f9a..04c441ada 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -21,6 +21,8 @@ Post v24.03.0
>  MAC addresses configured on the LSP with "unknown", are learnt via the
>  OVN native FDB.
>- Add support for ovsdb-server `--config-file` option in ovn-ctl.
> +  - Added a new column in the southbound database "flow_desc" to provide
> +human readable context to flows.
>
>  OVN v24.03.0 - 01 Mar 2024
>  --
> diff --git a/northd/lflow-mgr.c b/northd/lflow-mgr.c
> index b2c60b5de..e27558a32 100644
> --- a/northd/lflow-mgr.c
> +++ b/northd/lflow-mgr.c
> @@ -36,7 +36,7 @@ static void ovn_lflow_init(struct ovn_lflow *, struct 
> ovn_datapath *od,
> uint16_t priority, char *match,
> char *actions, char *io_port,
> char *ctrl_meter, char *stage_hint,
> -   const char *where);
> +   const char *where, char *flow_desc);
>  static struct ovn_lflow *ovn_lflow_find(const struct hmap *lflows,
>  enum ovn_stage stage,
>  uint16_t priority, const char *match,
> @@ -52,7 +52,7 @@ static struct ovn_lflow *do_ovn_lflow_add(
>  const char *actions, const char *io_port,
>  const char *ctrl_meter,
>  const struct ovsdb_idl_row *stage_hint,
> -const char *where);
> +const char *where, const char *flow_desc);
>
>
>  static struct ovs_mutex *lflow_hash_lock(const struct hmap *lflow_table,
> @@ -173,6 +173,7 @@ struct ovn_lflow {
>* 'dpg_bitmap'. */
>  struct ovn_dp_group *dpg;/* Link to unique Sb datapath group. */
>  const char *where;
> +char *flow_desc;
>
>  struct uuid sb_uuid; /* SB DB row uuid, specified by northd. */
>  struct ovs_list referenced_by;  /* List of struct lflow_ref_node. */
> @@ -659,7 +660,7 @@ lflow_table_add_lflow(struct lflow_table *lflow_table,
>const char *match, const char *actions,
>const char *io_port, const char *ctrl_meter,
>const struct ovsdb_idl_row *stage_hint,
> -  const char *where,
> +  const char *where, const char *flow_desc,
>struct lflow_ref *lflow_ref)
>  OVS_EXCLUDED(fake_hash_mutex)
>  {
> @@ -679,7 +680,7 @@ lflow_table_add_lflow(struct lflow_table *lflow_table,
>  do_ovn_lflow_add(lflow_table,
>   od ? ods_size(od->datapaths) : dp_bitmap_len,
>   hash, stage, priority, match, actions,
> - io_port, ctrl_meter, stage_hint, where);
> + io_port, ctrl_meter, stage_hint, where, flow_desc);
>
>  if (lflow_ref) {
>  struct lflow_ref_node *lrn =
> @@ -733,7 +734,7 @@ lflow_table_add_lflow_default_drop(struct lflow_table 
> *lflow_table,
>  {
>  lflow_table_add_lflow(lflow_table, od, NULL, 0, stage, 0, "1",
>debug_drop_action(), NULL, NULL, NULL,
> -  where, lflow_ref);
> +  where, NULL, lflow_ref);
>  }
>
>  struct ovn_dp_group *
> @@ -856,7 +857,7 @@ static void
>  ovn_lflow_init(struct ovn_lflow *lflow, struct ovn_datapath *od,
> size_t dp_bitmap_len, enum ovn_stage stage, uint16_t priority,
>   

Re: [ovs-dev] [PATCH net-next 1/2] selftests: openvswitch: fix action formatting

2024-06-06 Thread Adrián Moreno
On Mon, Jun 03, 2024 at 03:00:03PM GMT, Aaron Conole wrote:
> Adrian Moreno  writes:
>
> > In the action formatting function ("dpstr"), the iteration is made over
> > the nla_map, so if there are more than one attribute from the same type
> > we only print the first one.
> >
> > Fix this by iterating over the actual attributes.
> >
> > Signed-off-by: Adrian Moreno 
> > ---
> >  .../selftests/net/openvswitch/ovs-dpctl.py| 48 +++
> >  1 file changed, 27 insertions(+), 21 deletions(-)
> >
> > diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py 
> > b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> > index 1dd057afd3fb..b76907ac0092 100644
> > --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> > +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> > @@ -437,40 +437,46 @@ class ovsactions(nla):
> >  def dpstr(self, more=False):
> >  print_str = ""
> >
> > -for field in self.nla_map:
> > -if field[1] == "none" or self.get_attr(field[0]) is None:
> > +for attr_name, value in self["attrs"]:
> > +attr_desc = next(filter(lambda x: x[0] == attr_name, 
> > self.nla_map),
> > + None)
> > +if not attr_desc:
> > +raise ValueError("Unknown attribute: %s" % attr)
> > +
> > +attr_type = attr_desc[1]
> > +
> > +if attr_type == "none":
>
> I agree, this is an issue.  BUT I think it might be better to just
> filter by field type up front.  See:
>
> https://github.com/apconole/linux-next-work/commit/7262107de7170d44b6dbf6c5ea6f7e6c0bb71d36#diff-3e72e7405c6bb4e9842bed5f63883ca930387086bb40d4034e92ed83a5decb4bR441
>
> That version I think ends up being much easier to follow.  If you want
> to take it for your series, feel free.  If you disagree, maybe there's
> something I'm not considering about it.
>

I agree. It's better to check field attribute names first. I found this
during manual testing of the "emit_sample" series but I ended up not
needing it for the automated one, so I'm OK waiting for your cleanup
series.

In fact, I also have some patches that try some rework of this part. In
particular, I tried to unify all attributes under a common base class
that would handle printing and parsing. That way, most cases would fall
into "print_str += datum.dpstr(more)" and the "if/elif" block would
shrink significantly.

> NOTE that version is just a bunch of independent changes that are
> squashed together.  I have a cleaner version.
>
> I can also bundle up the series I have so far and submit, but I didn't
> want to do that until I got all the pmtu.sh support working.  Maybe it
> makes sense to send it now though.  Simon, Jakub - wdyt?
>
> >  continue
> >  if print_str != "":
> >  print_str += ","
> >
> > -if field[1] == "uint32":
> > -if field[0] == "OVS_ACTION_ATTR_OUTPUT":
> > -print_str += "%d" % int(self.get_attr(field[0]))
> > -elif field[0] == "OVS_ACTION_ATTR_RECIRC":
> > -print_str += "recirc(0x%x)" % 
> > int(self.get_attr(field[0]))
> > -elif field[0] == "OVS_ACTION_ATTR_TRUNC":
> > -print_str += "trunc(%d)" % int(self.get_attr(field[0]))
> > -elif field[0] == "OVS_ACTION_ATTR_DROP":
> > -print_str += "drop(%d)" % int(self.get_attr(field[0]))
> > -elif field[1] == "flag":
> > -if field[0] == "OVS_ACTION_ATTR_CT_CLEAR":
> > +if attr_type == "uint32":
> > +if attr_name == "OVS_ACTION_ATTR_OUTPUT":
> > +print_str += "%d" % int(value)
> > +elif attr_name == "OVS_ACTION_ATTR_RECIRC":
> > +print_str += "recirc(0x%x)" % int(value)
> > +elif attr_name == "OVS_ACTION_ATTR_TRUNC":
> > +print_str += "trunc(%d)" % int(value)
> > +elif attr_name == "OVS_ACTION_ATTR_DROP":
> > +print_str += "drop(%d)" % int(value)
> > +elif attr_type == "flag":
> > +if attr_name == "OVS_ACTION_ATTR_CT_CLEAR":
> >  print_str += "ct_clear"
> > -elif field[0] == "OVS_ACTION_ATTR_POP_VLAN":
> > +elif attr_name == "OVS_ACTION_ATTR_POP_VLAN":
> >  print_str += "pop_vlan"
> > -elif field[0] == "OVS_ACTION_ATTR_POP_ETH":
> > +elif attr_name == "OVS_ACTION_ATTR_POP_ETH":
> >  print_str += "pop_eth"
> > -elif field[0] == "OVS_ACTION_ATTR_POP_NSH":
> > +elif attr_name == "OVS_ACTION_ATTR_POP_NSH":
> >  print_str += "pop_nsh"
> > -elif field[0] == "OVS_ACTION_ATTR_POP_MPLS":
> > +elif attr_name == "OVS_ACTION_ATTR_POP_MPLS":
> >  print_str += 

Re: [ovs-dev] [RFC v2 4/9] vswitchd: Add local sampling to vswitchd schema.

2024-06-06 Thread Adrián Moreno
On Wed, Jun 05, 2024 at 10:23:32PM GMT, Adrian Moreno wrote:
> Add as new column in the Flow_Sample_Collector_Set table named
> "local_sample_group" which enables this feature.
>
> Signed-off-by: Adrian Moreno 

Ugh...It seems a merge conflict with the NEWS file is breaking robot
builds.

> ---
>  NEWS   |  4 ++
>  vswitchd/bridge.c  | 78 +++---
>  vswitchd/vswitch.ovsschema |  9 -
>  vswitchd/vswitch.xml   | 39 +--
>  4 files changed, 119 insertions(+), 11 deletions(-)
>
> diff --git a/NEWS b/NEWS
> index b92cec532..1c05a7120 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -7,6 +7,10 @@ Post-v3.3.0
> - The primary development branch has been renamed from 'master' to 'main'.
>   The OVS tree remains hosted on GitHub.
>   https://github.com/openvswitch/ovs.git
> +   - Local sampling is introduced. It reuses the OpenFlow sample action and
> + allows samples to be emitted locally (instead of via IPFIX) in a
> + datapath-specific manner via the new datapath action called 
> "emit_sample".
> + Linux kernel datapath is the first to support this feature.
>
>
>  v3.3.0 - 16 Feb 2024
> diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
> index 95a65fcdc..cd7dc6646 100644
> --- a/vswitchd/bridge.c
> +++ b/vswitchd/bridge.c
> @@ -288,6 +288,7 @@ static void bridge_configure_mac_table(struct bridge *);
>  static void bridge_configure_mcast_snooping(struct bridge *);
>  static void bridge_configure_sflow(struct bridge *, int 
> *sflow_bridge_number);
>  static void bridge_configure_ipfix(struct bridge *);
> +static void bridge_configure_lsample(struct bridge *);
>  static void bridge_configure_spanning_tree(struct bridge *);
>  static void bridge_configure_tables(struct bridge *);
>  static void bridge_configure_dp_desc(struct bridge *);
> @@ -989,6 +990,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch 
> *ovs_cfg)
>  bridge_configure_netflow(br);
>  bridge_configure_sflow(br, _bridge_number);
>  bridge_configure_ipfix(br);
> +bridge_configure_lsample(br);
>  bridge_configure_spanning_tree(br);
>  bridge_configure_tables(br);
>  bridge_configure_dp_desc(br);
> @@ -1537,10 +1539,11 @@ ovsrec_ipfix_is_valid(const struct ovsrec_ipfix 
> *ipfix)
>  return ipfix && ipfix->n_targets > 0;
>  }
>
> -/* Returns whether a Flow_Sample_Collector_Set row is valid. */
> +/* Returns whether a Flow_Sample_Collector_Set row constains valid IPFIX
> + * configuration. */
>  static bool
> -ovsrec_fscs_is_valid(const struct ovsrec_flow_sample_collector_set *fscs,
> - const struct bridge *br)
> +ovsrec_fscs_is_valid_ipfix(const struct ovsrec_flow_sample_collector_set 
> *fscs,
> +   const struct bridge *br)
>  {
>  return ovsrec_ipfix_is_valid(fscs->ipfix) && fscs->bridge == br->cfg;
>  }
> @@ -1558,7 +1561,7 @@ bridge_configure_ipfix(struct bridge *br)
>  const char *virtual_obs_id;
>
>  OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH(fe_cfg, idl) {
> -if (ovsrec_fscs_is_valid(fe_cfg, br)) {
> +if (ovsrec_fscs_is_valid_ipfix(fe_cfg, br)) {
>  n_fe_opts++;
>  }
>  }
> @@ -1621,7 +1624,7 @@ bridge_configure_ipfix(struct bridge *br)
>  fe_opts = xcalloc(n_fe_opts, sizeof *fe_opts);
>  opts = fe_opts;
>  OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH(fe_cfg, idl) {
> -if (ovsrec_fscs_is_valid(fe_cfg, br)) {
> +if (ovsrec_fscs_is_valid_ipfix(fe_cfg, br)) {
>  opts->collector_set_id = fe_cfg->id;
>  sset_init(>targets);
>  sset_add_array(>targets, fe_cfg->ipfix->targets,
> @@ -1667,6 +1670,71 @@ bridge_configure_ipfix(struct bridge *br)
>  }
>  }
>
> +/* Returns whether a Flow_Sample_Collector_Set row contains valid local
> + * sampling configuraiton. */
> +static bool
> +ovsrec_fscs_is_valid_local(const struct ovsrec_flow_sample_collector_set 
> *fscs,
> +   const struct bridge *br)
> +{
> +return fscs->local_sample_group && fscs->n_local_sample_group == 1 &&
> +   fscs->bridge == br->cfg;
> +}
> +
> +/* Set local sample configuration on 'br'. */
> +static void
> +bridge_configure_lsample(struct bridge *br)
> +{
> +static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
> +const struct ovsrec_flow_sample_collector_set *fscs;
> +struct ofproto_lsample_options *opts_array, *opts;
> +size_t n_opts = 0;
> +int ret;
> +
> +/* Iterate the Flow_Sample_Collector_Set table twice.
> + * First to get the number of valid configuration entries, then to 
> process
> + * each of them and build an array of options. */
> +OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH (fscs, idl) {
> +if (ovsrec_fscs_is_valid_local(fscs, br)) {
> +n_opts ++;
> +}
> +}
> +
> +if (n_opts == 0) {
> +

Re: [ovs-dev] [PATCH net-next v2 5/9] net: openvswitch: add emit_sample action

2024-06-06 Thread Adrián Moreno
On Wed, Jun 05, 2024 at 08:51:17PM GMT, Simon Horman wrote:
> On Mon, Jun 03, 2024 at 08:56:39PM +0200, Adrian Moreno wrote:
> > Add support for a new action: emit_sample.
> >
> > This action accepts a u32 group id and a variable-length cookie and uses
> > the psample multicast group to make the packet available for
> > observability.
> >
> > The maximum length of the user-defined cookie is set to 16, same as
> > tc_cookie, to discourage using cookies that will not be offloadable.
> >
> > Signed-off-by: Adrian Moreno 
>
> Hi Adrian,
>
> Some minor nits from my side.
>
> ...
>
> > diff --git a/include/uapi/linux/openvswitch.h 
> > b/include/uapi/linux/openvswitch.h
> > index efc82c318fa2..a0e9dde0584a 100644
> > --- a/include/uapi/linux/openvswitch.h
> > +++ b/include/uapi/linux/openvswitch.h
> > @@ -914,6 +914,30 @@ struct check_pkt_len_arg {
> >  };
> >  #endif
> >
> > +#define OVS_EMIT_SAMPLE_COOKIE_MAX_SIZE 16
> > +/**
> > + * enum ovs_emit_sample_attr - Attributes for %OVS_ACTION_ATTR_EMIT_SAMPLE
> > + * action.
> > + *
> > + * @OVS_EMIT_SAMPLE_ATTR_GROUP: 32-bit number to identify the source of the
> > + * sample.
> > + * @OVS_EMIT_SAMPLE_ATTR_COOKIE: A variable-length binary cookie that 
> > contains
> > + * user-defined metadata. The maximum length is 16 bytes.
> > + *
> > + * Sends the packet to the psample multicast group with the specified 
> > group and
> > + * cookie. It is possible to combine this action with the
> > + * %OVS_ACTION_ATTR_TRUNC action to limit the size of the packet being 
> > emitted.
> > + */
> > +enum ovs_emit_sample_attr {
> > +   OVS_EMIT_SAMPLE_ATTR_UNPSEC,
> > +   OVS_EMIT_SAMPLE_ATTR_GROUP, /* u32 number. */
> > +   OVS_EMIT_SAMPLE_ATTR_COOKIE,/* Optional, user specified cookie. */
> > +   __OVS_EMIT_SAMPLE_ATTR_MAX
> > +};
> > +
> > +#define OVS_EMIT_SAMPLE_ATTR_MAX (__OVS_EMIT_SAMPLE_ATTR_MAX - 1)
> > +
> > +
>
> nit: One blank line is enough.
>

Ack.

>  Flagged by checkpatch.pl
>
> >  /**
> >   * enum ovs_action_attr - Action types.
> >   *
> > @@ -1004,6 +1028,7 @@ enum ovs_action_attr {
> > OVS_ACTION_ATTR_ADD_MPLS, /* struct ovs_action_add_mpls. */
> > OVS_ACTION_ATTR_DEC_TTL,  /* Nested OVS_DEC_TTL_ATTR_*. */
> > OVS_ACTION_ATTR_DROP, /* u32 error code. */
> > +   OVS_ACTION_ATTR_EMIT_SAMPLE,  /* Nested OVS_EMIT_SAMPLE_ATTR_*. */
>
> nit: Please add OVS_ACTION_ATTR_EMIT_SAMPLE to the Kenrel doc
>  for this structure.
>

Thanks for spotting this. Will do.


> >
> > __OVS_ACTION_ATTR_MAX,/* Nothing past this will be accepted
> >* from userspace. */
>
> ...
>

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH net-next v2 6/9] net: openvswitch: store sampling probability in cb.

2024-06-05 Thread Adrián Moreno
On Tue, Jun 04, 2024 at 04:49:39PM GMT, kernel test robot wrote:
> Hi Adrian,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on net-next/main]
>
> url:
> https://github.com/intel-lab-lkp/linux/commits/Adrian-Moreno/net-psample-add-user-cookie/20240604-030055
> base:   net-next/main
> patch link:
> https://lore.kernel.org/r/20240603185647.2310748-7-amorenoz%40redhat.com
> patch subject: [PATCH net-next v2 6/9] net: openvswitch: store sampling 
> probability in cb.
> config: m68k-allyesconfig 
> (https://download.01.org/0day-ci/archive/20240604/202406041623.ycwsup85-...@intel.com/config)
> compiler: m68k-linux-gcc (GCC) 13.2.0
> reproduce (this is a W=1 build): 
> (https://download.01.org/0day-ci/archive/20240604/202406041623.ycwsup85-...@intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version 
> of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot 
> | Closes: 
> https://lore.kernel.org/oe-kbuild-all/202406041623.ycwsup85-...@intel.com/
>
> All errors (new ones prefixed by >>):
>
>m68k-linux-ld: net/openvswitch/actions.o: in function `do_execute_actions':
> >> actions.c:(.text+0x214e): undefined reference to `__udivdi3'
>

I forgot about architectures that don't have native u64 division. I will
use "do_div" in the next version of the series.

> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki
>

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


  1   2   >