diff --git a/bpf/flow.h b/bpf/flow.h
index 1248838bfad0911b1f15f1ccfe0082edba3c72bb..a5629d4dd69e24fe17a80b2620d2d0744625823e 100644
--- a/bpf/flow.h
+++ b/bpf/flow.h
@@ -51,4 +51,9 @@ typedef struct flow_record_t {
     flow_id id;
     flow_metrics metrics;
 } __attribute__((packed)) flow_record;
+
+typedef struct payload_meta_t {
+	u32 if_index;
+	u32 pkt_len;
+} __attribute__((packed)) payload_meta;
 #endif
diff --git a/bpf/flows.c b/bpf/flows.c
index 790f24b8a0c4cd93c4f954b4b10843f2794c1714..8f06e28148fcac28372373a13cea5ec18ce3869e 100644
--- a/bpf/flows.c
+++ b/bpf/flows.c
@@ -48,6 +48,14 @@ struct {
     __uint(max_entries, 1 << 24);
 } direct_flows SEC(".maps");
 
+
+// Perf Buffer to submit packet payloads to userspace
+struct {
+    __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
+    __uint(key_size, sizeof(int));
+    __uint(value_size, sizeof(int));
+} packet_payloads SEC(".maps");
+
 // Key: the flow identifier. Value: the flow metrics for that identifier.
 // The userspace will aggregate them into a single flow.
 struct {
@@ -58,7 +66,9 @@ struct {
 
 // Constant definitions, to be overridden by the invoker
 volatile const u32 sampling = 0;
-volatile const u8 trace_messages = 0;
+volatile const u8  trace_messages = 0;
+volatile const u32 payload_size = 64;
+
 
 const u8 ip4in6[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};
 
@@ -232,6 +242,28 @@ static inline int flow_monitor(struct __sk_buff *skb, u8 direction) {
     return TC_ACT_OK;
 
 }
+
+static inline int export_packet_payload (struct __sk_buff *skb) {
+    void *data_end = (void *)(long)skb->data_end;
+    void *data = (void *)(long)skb->data;
+    payload_meta meta;
+
+    meta.if_index = skb->ifindex;
+    meta.pkt_len = data_end - data;
+    bpf_skb_output(skb, &packet_payloads, ((u64) meta.pkt_len << 32) | BPF_F_CURRENT_CPU, &meta, sizeof(meta));
+    return TC_ACT_OK;
+}
+
+SEC("pano_ingress")
+int pano_ingress_parse (struct __sk_buff *skb) {
+    return export_packet_payload(skb);
+}
+
+SEC("pano_egress")
+int pano_egress_parse (struct __sk_buff *skb) {
+    return export_packet_payload(skb);
+}
+
 SEC("tc_ingress")
 int ingress_flow_parse (struct __sk_buff *skb) {
     return flow_monitor(skb, INGRESS);
diff --git a/pkg/ebpf/bpf_bpfeb.go b/pkg/ebpf/bpf_bpfeb.go
index 4c4e73088d7b5abdb5263c616576b1f863f79af7..c9056a6d862606dd71ff34133b38fa89e2a19142 100644
--- a/pkg/ebpf/bpf_bpfeb.go
+++ b/pkg/ebpf/bpf_bpfeb.go
@@ -56,6 +56,8 @@ type bpfSpecs struct {
 type bpfProgramSpecs struct {
 	EgressFlowParse  *ebpf.ProgramSpec `ebpf:"egress_flow_parse"`
 	IngressFlowParse *ebpf.ProgramSpec `ebpf:"ingress_flow_parse"`
+	PanoEgressParse  *ebpf.ProgramSpec `ebpf:"pano_egress_parse"`
+	PanoIngressParse *ebpf.ProgramSpec `ebpf:"pano_ingress_parse"`
 }
 
 // bpfMapSpecs contains maps before they are loaded into the kernel.
@@ -64,6 +66,7 @@ type bpfProgramSpecs struct {
 type bpfMapSpecs struct {
 	AggregatedFlows *ebpf.MapSpec `ebpf:"aggregated_flows"`
 	DirectFlows     *ebpf.MapSpec `ebpf:"direct_flows"`
+	PacketPayloads  *ebpf.MapSpec `ebpf:"packet_payloads"`
 }
 
 // bpfObjects contains all objects after they have been loaded into the kernel.
@@ -87,12 +90,14 @@ func (o *bpfObjects) Close() error {
 type bpfMaps struct {
 	AggregatedFlows *ebpf.Map `ebpf:"aggregated_flows"`
 	DirectFlows     *ebpf.Map `ebpf:"direct_flows"`
+	PacketPayloads  *ebpf.Map `ebpf:"packet_payloads"`
 }
 
 func (m *bpfMaps) Close() error {
 	return _BpfClose(
 		m.AggregatedFlows,
 		m.DirectFlows,
+		m.PacketPayloads,
 	)
 }
 
@@ -102,12 +107,16 @@ func (m *bpfMaps) Close() error {
 type bpfPrograms struct {
 	EgressFlowParse  *ebpf.Program `ebpf:"egress_flow_parse"`
 	IngressFlowParse *ebpf.Program `ebpf:"ingress_flow_parse"`
+	PanoEgressParse  *ebpf.Program `ebpf:"pano_egress_parse"`
+	PanoIngressParse *ebpf.Program `ebpf:"pano_ingress_parse"`
 }
 
 func (p *bpfPrograms) Close() error {
 	return _BpfClose(
 		p.EgressFlowParse,
 		p.IngressFlowParse,
+		p.PanoEgressParse,
+		p.PanoIngressParse,
 	)
 }
 
diff --git a/pkg/ebpf/bpf_bpfeb.o b/pkg/ebpf/bpf_bpfeb.o
index ee6465770f750f986efe7ab54426cac2f1b26477..a1ca06ca391a25745d2e6da4d9d301d991d8a8be 100644
Binary files a/pkg/ebpf/bpf_bpfeb.o and b/pkg/ebpf/bpf_bpfeb.o differ
diff --git a/pkg/ebpf/bpf_bpfel.go b/pkg/ebpf/bpf_bpfel.go
index 4b4c57948580e0ad8f809767834b49f17b81a3b7..9c2253d6a8ba776740d083724d82db2bdfd9e4c8 100644
--- a/pkg/ebpf/bpf_bpfel.go
+++ b/pkg/ebpf/bpf_bpfel.go
@@ -56,6 +56,8 @@ type bpfSpecs struct {
 type bpfProgramSpecs struct {
 	EgressFlowParse  *ebpf.ProgramSpec `ebpf:"egress_flow_parse"`
 	IngressFlowParse *ebpf.ProgramSpec `ebpf:"ingress_flow_parse"`
+	PanoEgressParse  *ebpf.ProgramSpec `ebpf:"pano_egress_parse"`
+	PanoIngressParse *ebpf.ProgramSpec `ebpf:"pano_ingress_parse"`
 }
 
 // bpfMapSpecs contains maps before they are loaded into the kernel.
@@ -64,6 +66,7 @@ type bpfProgramSpecs struct {
 type bpfMapSpecs struct {
 	AggregatedFlows *ebpf.MapSpec `ebpf:"aggregated_flows"`
 	DirectFlows     *ebpf.MapSpec `ebpf:"direct_flows"`
+	PacketPayloads  *ebpf.MapSpec `ebpf:"packet_payloads"`
 }
 
 // bpfObjects contains all objects after they have been loaded into the kernel.
@@ -87,12 +90,14 @@ func (o *bpfObjects) Close() error {
 type bpfMaps struct {
 	AggregatedFlows *ebpf.Map `ebpf:"aggregated_flows"`
 	DirectFlows     *ebpf.Map `ebpf:"direct_flows"`
+	PacketPayloads  *ebpf.Map `ebpf:"packet_payloads"`
 }
 
 func (m *bpfMaps) Close() error {
 	return _BpfClose(
 		m.AggregatedFlows,
 		m.DirectFlows,
+		m.PacketPayloads,
 	)
 }
 
@@ -102,12 +107,16 @@ func (m *bpfMaps) Close() error {
 type bpfPrograms struct {
 	EgressFlowParse  *ebpf.Program `ebpf:"egress_flow_parse"`
 	IngressFlowParse *ebpf.Program `ebpf:"ingress_flow_parse"`
+	PanoEgressParse  *ebpf.Program `ebpf:"pano_egress_parse"`
+	PanoIngressParse *ebpf.Program `ebpf:"pano_ingress_parse"`
 }
 
 func (p *bpfPrograms) Close() error {
 	return _BpfClose(
 		p.EgressFlowParse,
 		p.IngressFlowParse,
+		p.PanoEgressParse,
+		p.PanoIngressParse,
 	)
 }
 
diff --git a/pkg/ebpf/bpf_bpfel.o b/pkg/ebpf/bpf_bpfel.o
index b28228617135f0ee03e3b7426a289ba71b98b12f..8ac6a4873d01a5713e1b2584cb49bceb20368bb2 100644
Binary files a/pkg/ebpf/bpf_bpfel.o and b/pkg/ebpf/bpf_bpfel.o differ