summaryrefslogtreecommitdiffstats
path: root/net/openvswitch/actions.c
diff options
context:
space:
mode:
authorAdrian Moreno <amorenoz@redhat.com>2024-07-04 10:56:56 +0200
committerJakub Kicinski <kuba@kernel.org>2024-07-05 17:45:47 -0700
commitaae0b82b46cb5004bdf82a000c004d69a0885c33 (patch)
treeaa4171e7d03a01fe90e3831dbd089a76ea70c87d /net/openvswitch/actions.c
parent7b1b2b60c63f070e0dfbe072ccaae13168b38d01 (diff)
downloadlinux-aae0b82b46cb5004bdf82a000c004d69a0885c33.tar.gz
linux-aae0b82b46cb5004bdf82a000c004d69a0885c33.tar.bz2
linux-aae0b82b46cb5004bdf82a000c004d69a0885c33.zip
net: openvswitch: add psample action
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. Reviewed-by: Michal Kubiak <michal.kubiak@intel.com> Reviewed-by: Aaron Conole <aconole@redhat.com> Reviewed-by: Ilya Maximets <i.maximets@ovn.org> Acked-by: Eelco Chaudron <echaudro@redhat.com> Signed-off-by: Adrian Moreno <amorenoz@redhat.com> Link: https://patch.msgid.link/20240704085710.353845-6-amorenoz@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/openvswitch/actions.c')
-rw-r--r--net/openvswitch/actions.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index 964225580824..892d7e48fc5b 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -24,6 +24,11 @@
#include <net/checksum.h>
#include <net/dsfield.h>
#include <net/mpls.h>
+
+#if IS_ENABLED(CONFIG_PSAMPLE)
+#include <net/psample.h>
+#endif
+
#include <net/sctp/checksum.h>
#include "datapath.h"
@@ -1299,6 +1304,40 @@ 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(&psample_group, skb, 0, &md);
+}
+#else
+static void execute_psample(struct datapath *dp, struct sk_buff *skb,
+ const struct nlattr *attr)
+{}
+#endif
+
/* Execute a list of actions against 'skb'. */
static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
struct sw_flow_key *key,
@@ -1502,6 +1541,15 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
ovs_kfree_skb_reason(skb, reason);
return 0;
}
+
+ case OVS_ACTION_ATTR_PSAMPLE:
+ execute_psample(dp, skb, a);
+ OVS_CB(skb)->cutlen = 0;
+ if (nla_is_last(a, rem)) {
+ consume_skb(skb);
+ return 0;
+ }
+ break;
}
if (unlikely(err)) {