summaryrefslogtreecommitdiffstats
path: root/net/psample
diff options
context:
space:
mode:
authorIdo Schimmel <idosch@nvidia.com>2021-03-14 14:19:31 +0200
committerDavid S. Miller <davem@davemloft.net>2021-03-14 15:00:43 -0700
commit07e1a5809b595df6e125504dff6245cb2c8ed3de (patch)
tree66779269807aa977b8571968248afbb0da6f765f /net/psample
parenta03e99d39f1943ec88f6fd3b0b9f34c20663d401 (diff)
downloadlinux-07e1a5809b595df6e125504dff6245cb2c8ed3de.tar.bz2
psample: Add additional metadata attributes
Extend psample to report the following attributes when available: * Output traffic class as a 16-bit value * Output traffic class occupancy in bytes as a 64-bit value * End-to-end latency of the packet in nanoseconds resolution * Software timestamp in nanoseconds resolution (always available) * Packet's protocol. Needed for packet dissection in user space (always available) Signed-off-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/psample')
-rw-r--r--net/psample/psample.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/net/psample/psample.c b/net/psample/psample.c
index 065bc887d239..118d5d2a81a0 100644
--- a/net/psample/psample.c
+++ b/net/psample/psample.c
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/module.h>
+#include <linux/timekeeping.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/netlink.h>
@@ -358,6 +359,7 @@ static int psample_tunnel_meta_len(struct ip_tunnel_info *tun_info)
void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
u32 sample_rate, const struct psample_metadata *md)
{
+ ktime_t tstamp = ktime_get_real();
int out_ifindex = md->out_ifindex;
int in_ifindex = md->in_ifindex;
u32 trunc_size = md->trunc_size;
@@ -372,10 +374,15 @@ void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
meta_len = (in_ifindex ? nla_total_size(sizeof(u16)) : 0) +
(out_ifindex ? nla_total_size(sizeof(u16)) : 0) +
+ (md->out_tc_valid ? nla_total_size(sizeof(u16)) : 0) +
+ (md->out_tc_occ_valid ? nla_total_size_64bit(sizeof(u64)) : 0) +
+ (md->latency_valid ? nla_total_size_64bit(sizeof(u64)) : 0) +
nla_total_size(sizeof(u32)) + /* sample_rate */
nla_total_size(sizeof(u32)) + /* orig_size */
nla_total_size(sizeof(u32)) + /* group_num */
- nla_total_size(sizeof(u32)); /* seq */
+ nla_total_size(sizeof(u32)) + /* seq */
+ nla_total_size_64bit(sizeof(u64)) + /* timestamp */
+ nla_total_size(sizeof(u16)); /* protocol */
#ifdef CONFIG_INET
tun_info = skb_tunnel_info(skb);
@@ -425,6 +432,36 @@ void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
if (unlikely(ret < 0))
goto error;
+ if (md->out_tc_valid) {
+ ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_OUT_TC, md->out_tc);
+ if (unlikely(ret < 0))
+ goto error;
+ }
+
+ if (md->out_tc_occ_valid) {
+ ret = nla_put_u64_64bit(nl_skb, PSAMPLE_ATTR_OUT_TC_OCC,
+ md->out_tc_occ, PSAMPLE_ATTR_PAD);
+ if (unlikely(ret < 0))
+ goto error;
+ }
+
+ if (md->latency_valid) {
+ ret = nla_put_u64_64bit(nl_skb, PSAMPLE_ATTR_LATENCY,
+ md->latency, PSAMPLE_ATTR_PAD);
+ if (unlikely(ret < 0))
+ goto error;
+ }
+
+ ret = nla_put_u64_64bit(nl_skb, PSAMPLE_ATTR_TIMESTAMP,
+ ktime_to_ns(tstamp), PSAMPLE_ATTR_PAD);
+ if (unlikely(ret < 0))
+ goto error;
+
+ ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_PROTO,
+ be16_to_cpu(skb->protocol));
+ if (unlikely(ret < 0))
+ goto error;
+
if (data_len) {
int nla_len = nla_total_size(data_len);
struct nlattr *nla;