Repository navigation
Conversation
8dbfa8b to
2aacf0d
Compare
2aacf0d to
01f146a
Compare
|
here's what the stdout logged spans look like: The 2 pods in this case are a basic alpine pod on the control plane and on the worker node. |
09c43a0 to
ff14441
Compare
| IpProto::Tcp => { | ||
| let (src_port, dst_port) = parse_l4_ports(data, offset)?; | ||
| Ok(ParsedPacket::Direct { | ||
| five_tuple: FiveTuple { | ||
| src_ip: outer_src_ip, | ||
| dst_ip: outer_dst_ip, | ||
| src_port, | ||
| dst_port, | ||
| protocol: IpProto::Tcp, | ||
| ip_version: if outer_src_ip.is_ipv4() { 4 } else { 6 }, | ||
| }, | ||
| l2_metadata: l2_meta, | ||
| ip_metadata: ip_meta, | ||
| }) | ||
| } | ||
| IpProto::Icmp => { | ||
| let (type_code, _) = parse_icmp_type_code(data, offset)?; | ||
| Ok(ParsedPacket::Direct { | ||
| five_tuple: FiveTuple { | ||
| src_ip: outer_src_ip, | ||
| dst_ip: outer_dst_ip, | ||
| src_port: type_code, | ||
| dst_port: 0, | ||
| protocol: outer_protocol, | ||
| ip_version: if outer_src_ip.is_ipv4() { 4 } else { 6 }, | ||
| }, | ||
| l2_metadata: l2_meta, | ||
| ip_metadata: ip_meta, | ||
| }) | ||
| } | ||
| IpProto::Gre => { | ||
| // TODO: GRE parsing | ||
| Err(ParseError::UnsupportedProtocol) | ||
| } | ||
| _ => Ok(ParsedPacket::Direct { | ||
| five_tuple: FiveTuple { | ||
| src_ip: outer_src_ip, | ||
| dst_ip: outer_dst_ip, | ||
| src_port: 0, | ||
| dst_port: 0, | ||
| protocol: outer_protocol, | ||
| ip_version: if outer_src_ip.is_ipv4() { 4 } else { 6 }, | ||
| }, | ||
| l2_metadata: l2_meta, | ||
| ip_metadata: ip_meta, | ||
| }), |
There was a problem hiding this comment.
I don't think I understand why the rest of this parsing is being removed
There was a problem hiding this comment.
So I removed this parsing because it only produced ParsedPacket::Direct, and direct flows never hit userspace parsing. eBPF already has the 5-tuple, ICMP fields, TCP flags, etc. in FlowStats.
My thought was to make the userspace parser’s job a lot more narrow. Basically, given a tunnel flow key and the UDP payload bytes, extract the inner 5-tuple and VNI.
If we do it this way, it would make the old full-packet parser redundant for direct traffic. And it'd make the old parsing incorrect for the buffer layout that eBPF sends for tunnels.
There was a problem hiding this comment.
@veronica-m-ef also worth noting, the old parse_packet_deep path was dead code on main, and it expected a full ethernet frame while ebpf sends the buffer starting at the VXLAN header, so it couldn't have parsed tunnels anyway.
ff14441 to
27ed7f9
Compare
Parse tunnel UDP payloads from eBPF on new flows and export spans with the inner 5-tuple, community ID, and tunnel metadata. Store the outer eBPF key on tunneled spans so poller stats stay correct; skip duplicate direct-path flows when a tunneled span already exists. Fix Cilium Kind install for e2e. Document Flannel vxlan_port 8472 and update tunnel-capability docs.
27ed7f9 to
54b5769
Compare
Encode inner ICMP as type/code ports like eBPF does so tunneled and direct community IDs match, and take the ICMP type from the inner header before normalization swaps it. Skip a second outer UDP key for an inner flow that already has a span instead of overwriting it.
fb6320a to
693bb59
Compare
This pr adds the ability for mermin to parse VXLAN and Geneve encapsulated traffic. Mermin should now be able to export spans with the inner flow plus tunnel metadata.
Changes
tunnel.*span attributes from the outer encapsulation. Reference used: https://docs.mermin.dev/getting-started/attribute-reference#tunnel-and-ip-in-ip-and-ipsec-attributespullPolicy,ipam.mode, rollout waits) in e2e setupTesting
cargo nextest run -r --workspace --exclude mermin-ebpf(parser unit tests, Linux CI job)CNI=<calico|cilium|flannel|kindnetd> DOCKER_IMAGE_TAG=<tag> bash ./mermin/tests/e2e/cni/test.shProof it works
Parser unit tests (6 passed, Linux Docker):
CNI e2e (all passed locally with
mermin:vxlan-verify):Each e2e run deploys mermin on Kind, generates cross-pod ICMP, and checks agent logs for Kubernetes pod enrichment.