feat(mermin): VXLAN and Geneve tunnel flow support#593
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. |
01f146a to
09c43a0
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.
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.
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.