Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bpf: Fix veth tracing + --track-by-stackid
cilium#391 allows --track-skb to track new skb on veth, it relies on a map lookup to decide whether to track or not: ``` SEC("kprobe/veth_convert_skb_to_xdp_buff") int kprobe_veth_convert_skb_to_xdp_buff(struct pt_regs *ctx) { [...] u64 skb_head = (u64) BPF_CORE_READ(skb, head); if (bpf_map_lookup_elem(&skb_heads, &skb_head)) { [...] } return BPF_OK; } ``` However, when --track-skb-by-stackid is used along with --track-skb, the tracked skbs have risks not being recorded in skb_heads map. This is because: 1. cilium#384 no more updates skb_heads map when track reason is "by_stackid". 2. cilium#339 changes --track-skb from tracking &skb to tracking skb->head. So imagine an skb whose original skb->head = 0xa, whose value is updated to 0xb after a while. The first time pwru sees this skb, skb_heads map will insert 0xa entry. However, after skb->head is set to 0xb, pwru sees the skb being tracked due to "by_stackid", we won't insert 0xb entry into skb_heads map. Then when the skb is on veth, we can't find an entry by looking up 0xb from skb_heads map, ending up with losing track of veth skb again. This patch fixes the issue by raising the priority of track_by_filter: if an skb can be defined as tracked_by_filter and tracked_by_stackid, use tracked_by_filter over tracked_by_stackid. Another issue cilium#339 brings about is, an skb can have multiple skb->head stored in skb_heads map during its lifetime, but we only clean the latest value at kprobe_skb_lifetime_termination. This issue is beyond this patch. Signed-off-by: gray <[email protected]>
- Loading branch information