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