Skip to content

Commit aae0b82

Browse files
amorenozkuba-moo
authored andcommitted
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 <[email protected]> Reviewed-by: Aaron Conole <[email protected]> Reviewed-by: Ilya Maximets <[email protected]> Acked-by: Eelco Chaudron <[email protected]> Signed-off-by: Adrian Moreno <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 7b1b2b6 commit aae0b82

File tree

5 files changed

+125
-1
lines changed

5 files changed

+125
-1
lines changed

Documentation/netlink/specs/ovs_flow.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,12 @@ attribute-sets:
727727
name: dec-ttl
728728
type: nest
729729
nested-attributes: dec-ttl-attrs
730+
-
731+
name: psample
732+
type: nest
733+
nested-attributes: psample-attrs
734+
doc: |
735+
Sends a packet sample to psample for external observation.
730736
-
731737
name: tunnel-key-attrs
732738
enum-name: ovs-tunnel-key-attr
@@ -938,6 +944,17 @@ attribute-sets:
938944
-
939945
name: gbp
940946
type: u32
947+
-
948+
name: psample-attrs
949+
enum-name: ovs-psample-attr
950+
name-prefix: ovs-psample-attr-
951+
attributes:
952+
-
953+
name: group
954+
type: u32
955+
-
956+
name: cookie
957+
type: binary
941958

942959
operations:
943960
name-prefix: ovs-flow-cmd-

include/uapi/linux/openvswitch.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,31 @@ struct check_pkt_len_arg {
914914
};
915915
#endif
916916

917+
#define OVS_PSAMPLE_COOKIE_MAX_SIZE 16
918+
/**
919+
* enum ovs_psample_attr - Attributes for %OVS_ACTION_ATTR_PSAMPLE
920+
* action.
921+
*
922+
* @OVS_PSAMPLE_ATTR_GROUP: 32-bit number to identify the source of the
923+
* sample.
924+
* @OVS_PSAMPLE_ATTR_COOKIE: An optional variable-length binary cookie that
925+
* contains user-defined metadata. The maximum length is
926+
* OVS_PSAMPLE_COOKIE_MAX_SIZE bytes.
927+
*
928+
* Sends the packet to the psample multicast group with the specified group and
929+
* cookie. It is possible to combine this action with the
930+
* %OVS_ACTION_ATTR_TRUNC action to limit the size of the sample.
931+
*/
932+
enum ovs_psample_attr {
933+
OVS_PSAMPLE_ATTR_GROUP = 1, /* u32 number. */
934+
OVS_PSAMPLE_ATTR_COOKIE, /* Optional, user specified cookie. */
935+
936+
/* private: */
937+
__OVS_PSAMPLE_ATTR_MAX
938+
};
939+
940+
#define OVS_PSAMPLE_ATTR_MAX (__OVS_PSAMPLE_ATTR_MAX - 1)
941+
917942
/**
918943
* enum ovs_action_attr - Action types.
919944
*
@@ -966,6 +991,8 @@ struct check_pkt_len_arg {
966991
* of l3 tunnel flag in the tun_flags field of OVS_ACTION_ATTR_ADD_MPLS
967992
* argument.
968993
* @OVS_ACTION_ATTR_DROP: Explicit drop action.
994+
* @OVS_ACTION_ATTR_PSAMPLE: Send a sample of the packet to external observers
995+
* via psample.
969996
*
970997
* Only a single header can be set with a single %OVS_ACTION_ATTR_SET. Not all
971998
* fields within a header are modifiable, e.g. the IPv4 protocol and fragment
@@ -1004,6 +1031,7 @@ enum ovs_action_attr {
10041031
OVS_ACTION_ATTR_ADD_MPLS, /* struct ovs_action_add_mpls. */
10051032
OVS_ACTION_ATTR_DEC_TTL, /* Nested OVS_DEC_TTL_ATTR_*. */
10061033
OVS_ACTION_ATTR_DROP, /* u32 error code. */
1034+
OVS_ACTION_ATTR_PSAMPLE, /* Nested OVS_PSAMPLE_ATTR_*. */
10071035

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

net/openvswitch/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ config OPENVSWITCH
1010
(NF_CONNTRACK && ((!NF_DEFRAG_IPV6 || NF_DEFRAG_IPV6) && \
1111
(!NF_NAT || NF_NAT) && \
1212
(!NETFILTER_CONNCOUNT || NETFILTER_CONNCOUNT)))
13+
depends on PSAMPLE || !PSAMPLE
1314
select LIBCRC32C
1415
select MPLS
1516
select NET_MPLS_GSO

net/openvswitch/actions.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
#include <net/checksum.h>
2525
#include <net/dsfield.h>
2626
#include <net/mpls.h>
27+
28+
#if IS_ENABLED(CONFIG_PSAMPLE)
29+
#include <net/psample.h>
30+
#endif
31+
2732
#include <net/sctp/checksum.h>
2833

2934
#include "datapath.h"
@@ -1299,6 +1304,40 @@ static int execute_dec_ttl(struct sk_buff *skb, struct sw_flow_key *key)
12991304
return 0;
13001305
}
13011306

1307+
#if IS_ENABLED(CONFIG_PSAMPLE)
1308+
static void execute_psample(struct datapath *dp, struct sk_buff *skb,
1309+
const struct nlattr *attr)
1310+
{
1311+
struct psample_group psample_group = {};
1312+
struct psample_metadata md = {};
1313+
const struct nlattr *a;
1314+
int rem;
1315+
1316+
nla_for_each_attr(a, nla_data(attr), nla_len(attr), rem) {
1317+
switch (nla_type(a)) {
1318+
case OVS_PSAMPLE_ATTR_GROUP:
1319+
psample_group.group_num = nla_get_u32(a);
1320+
break;
1321+
1322+
case OVS_PSAMPLE_ATTR_COOKIE:
1323+
md.user_cookie = nla_data(a);
1324+
md.user_cookie_len = nla_len(a);
1325+
break;
1326+
}
1327+
}
1328+
1329+
psample_group.net = ovs_dp_get_net(dp);
1330+
md.in_ifindex = OVS_CB(skb)->input_vport->dev->ifindex;
1331+
md.trunc_size = skb->len - OVS_CB(skb)->cutlen;
1332+
1333+
psample_sample_packet(&psample_group, skb, 0, &md);
1334+
}
1335+
#else
1336+
static void execute_psample(struct datapath *dp, struct sk_buff *skb,
1337+
const struct nlattr *attr)
1338+
{}
1339+
#endif
1340+
13021341
/* Execute a list of actions against 'skb'. */
13031342
static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
13041343
struct sw_flow_key *key,
@@ -1502,6 +1541,15 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
15021541
ovs_kfree_skb_reason(skb, reason);
15031542
return 0;
15041543
}
1544+
1545+
case OVS_ACTION_ATTR_PSAMPLE:
1546+
execute_psample(dp, skb, a);
1547+
OVS_CB(skb)->cutlen = 0;
1548+
if (nla_is_last(a, rem)) {
1549+
consume_skb(skb);
1550+
return 0;
1551+
}
1552+
break;
15051553
}
15061554

15071555
if (unlikely(err)) {

net/openvswitch/flow_netlink.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ static bool actions_may_change_flow(const struct nlattr *actions)
6464
case OVS_ACTION_ATTR_TRUNC:
6565
case OVS_ACTION_ATTR_USERSPACE:
6666
case OVS_ACTION_ATTR_DROP:
67+
case OVS_ACTION_ATTR_PSAMPLE:
6768
break;
6869

6970
case OVS_ACTION_ATTR_CT:
@@ -2409,7 +2410,7 @@ static void ovs_nla_free_nested_actions(const struct nlattr *actions, int len)
24092410
/* Whenever new actions are added, the need to update this
24102411
* function should be considered.
24112412
*/
2412-
BUILD_BUG_ON(OVS_ACTION_ATTR_MAX != 24);
2413+
BUILD_BUG_ON(OVS_ACTION_ATTR_MAX != 25);
24132414

24142415
if (!actions)
24152416
return;
@@ -3157,6 +3158,28 @@ static int validate_and_copy_check_pkt_len(struct net *net,
31573158
return 0;
31583159
}
31593160

3161+
static int validate_psample(const struct nlattr *attr)
3162+
{
3163+
static const struct nla_policy policy[OVS_PSAMPLE_ATTR_MAX + 1] = {
3164+
[OVS_PSAMPLE_ATTR_GROUP] = { .type = NLA_U32 },
3165+
[OVS_PSAMPLE_ATTR_COOKIE] = {
3166+
.type = NLA_BINARY,
3167+
.len = OVS_PSAMPLE_COOKIE_MAX_SIZE,
3168+
},
3169+
};
3170+
struct nlattr *a[OVS_PSAMPLE_ATTR_MAX + 1];
3171+
int err;
3172+
3173+
if (!IS_ENABLED(CONFIG_PSAMPLE))
3174+
return -EOPNOTSUPP;
3175+
3176+
err = nla_parse_nested(a, OVS_PSAMPLE_ATTR_MAX, attr, policy, NULL);
3177+
if (err)
3178+
return err;
3179+
3180+
return a[OVS_PSAMPLE_ATTR_GROUP] ? 0 : -EINVAL;
3181+
}
3182+
31603183
static int copy_action(const struct nlattr *from,
31613184
struct sw_flow_actions **sfa, bool log)
31623185
{
@@ -3212,6 +3235,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
32123235
[OVS_ACTION_ATTR_ADD_MPLS] = sizeof(struct ovs_action_add_mpls),
32133236
[OVS_ACTION_ATTR_DEC_TTL] = (u32)-1,
32143237
[OVS_ACTION_ATTR_DROP] = sizeof(u32),
3238+
[OVS_ACTION_ATTR_PSAMPLE] = (u32)-1,
32153239
};
32163240
const struct ovs_action_push_vlan *vlan;
32173241
int type = nla_type(a);
@@ -3490,6 +3514,12 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
34903514
return -EINVAL;
34913515
break;
34923516

3517+
case OVS_ACTION_ATTR_PSAMPLE:
3518+
err = validate_psample(a);
3519+
if (err)
3520+
return err;
3521+
break;
3522+
34933523
default:
34943524
OVS_NLERR(log, "Unknown Action type %d", type);
34953525
return -EINVAL;

0 commit comments

Comments
 (0)