Skip to content

Commit 71763d8

Browse files
amorenozkuba-moo
authored andcommitted
net: openvswitch: store sampling probability in cb.
When a packet sample is observed, the sampling rate that was used is important to estimate the real frequency of such event. Store the probability of the parent sample action in the skb's cb area and use it in psample action to pass it down to psample module. Reviewed-by: Aaron Conole <[email protected]> Acked-by: Eelco Chaudron <[email protected]> Reviewed-by: Ilya Maximets <[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 aae0b82 commit 71763d8

File tree

4 files changed

+23
-4
lines changed

4 files changed

+23
-4
lines changed

include/uapi/linux/openvswitch.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,8 @@ enum ovs_flow_attr {
649649
* Actions are passed as nested attributes.
650650
*
651651
* Executes the specified actions with the given probability on a per-packet
652-
* basis.
652+
* basis. Nested actions will be able to access the probability value of the
653+
* parent @OVS_ACTION_ATTR_SAMPLE.
653654
*/
654655
enum ovs_sample_attr {
655656
OVS_SAMPLE_ATTR_UNSPEC,

net/openvswitch/actions.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,12 +1048,15 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
10481048
struct nlattr *sample_arg;
10491049
int rem = nla_len(attr);
10501050
const struct sample_arg *arg;
1051+
u32 init_probability;
10511052
bool clone_flow_key;
1053+
int err;
10521054

10531055
/* The first action is always 'OVS_SAMPLE_ATTR_ARG'. */
10541056
sample_arg = nla_data(attr);
10551057
arg = nla_data(sample_arg);
10561058
actions = nla_next(sample_arg, &rem);
1059+
init_probability = OVS_CB(skb)->probability;
10571060

10581061
if ((arg->probability != U32_MAX) &&
10591062
(!arg->probability || get_random_u32() > arg->probability)) {
@@ -1062,9 +1065,16 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
10621065
return 0;
10631066
}
10641067

1068+
OVS_CB(skb)->probability = arg->probability;
1069+
10651070
clone_flow_key = !arg->exec;
1066-
return clone_execute(dp, skb, key, 0, actions, rem, last,
1067-
clone_flow_key);
1071+
err = clone_execute(dp, skb, key, 0, actions, rem, last,
1072+
clone_flow_key);
1073+
1074+
if (!last)
1075+
OVS_CB(skb)->probability = init_probability;
1076+
1077+
return err;
10681078
}
10691079

10701080
/* When 'last' is true, clone() should always consume the 'skb'.
@@ -1311,6 +1321,7 @@ static void execute_psample(struct datapath *dp, struct sk_buff *skb,
13111321
struct psample_group psample_group = {};
13121322
struct psample_metadata md = {};
13131323
const struct nlattr *a;
1324+
u32 rate;
13141325
int rem;
13151326

13161327
nla_for_each_attr(a, nla_data(attr), nla_len(attr), rem) {
@@ -1329,8 +1340,11 @@ static void execute_psample(struct datapath *dp, struct sk_buff *skb,
13291340
psample_group.net = ovs_dp_get_net(dp);
13301341
md.in_ifindex = OVS_CB(skb)->input_vport->dev->ifindex;
13311342
md.trunc_size = skb->len - OVS_CB(skb)->cutlen;
1343+
md.rate_as_probability = 1;
1344+
1345+
rate = OVS_CB(skb)->probability ? OVS_CB(skb)->probability : U32_MAX;
13321346

1333-
psample_sample_packet(&psample_group, skb, 0, &md);
1347+
psample_sample_packet(&psample_group, skb, rate, &md);
13341348
}
13351349
#else
13361350
static void execute_psample(struct datapath *dp, struct sk_buff *skb,

net/openvswitch/datapath.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,15 @@ struct datapath {
115115
* fragmented.
116116
* @acts_origlen: The netlink size of the flow actions applied to this skb.
117117
* @cutlen: The number of bytes from the packet end to be removed.
118+
* @probability: The sampling probability that was applied to this skb; 0 means
119+
* no sampling has occurred; U32_MAX means 100% probability.
118120
*/
119121
struct ovs_skb_cb {
120122
struct vport *input_vport;
121123
u16 mru;
122124
u16 acts_origlen;
123125
u32 cutlen;
126+
u32 probability;
124127
};
125128
#define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
126129

net/openvswitch/vport.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,7 @@ int ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
500500
OVS_CB(skb)->input_vport = vport;
501501
OVS_CB(skb)->mru = 0;
502502
OVS_CB(skb)->cutlen = 0;
503+
OVS_CB(skb)->probability = 0;
503504
if (unlikely(dev_net(skb->dev) != ovs_dp_get_net(vport->dp))) {
504505
u32 mark;
505506

0 commit comments

Comments
 (0)