2026. 9. 11. 11:39ㆍ카테고리 없음
아직 100% 결론은 안 났어. 다만 지금은 거의 끝이야. 지금까지 확정된 건 이거야.
skb_do_redirect()
target ifindex = 10
flags = 0
return = -22 (-EINVAL)
즉 redirect가 실패하고 있는 건 맞아. 다만 딱 하나가 안 갈렸어:
A. ifindex 10을 아예 못 찾음
↓
out_drop
↓
kfree_skb()
↓
-EINVAL
또는
B. ifindex 10은 찾음
↓
__bpf_redirect()
↓
그 안에서 실패
↓
-EINVAL
flags=0이므로 아까 이야기했던 BPF_F_PEER, TC ingress, peer DOWN 같은 건 이번 패킷에는 관계없어.
이제 한 번만 더 찍으면 A/B가 확정돼.
먼저 네 커널에서 함수 인자를 확인해:
bpftrace -lv 'fentry:dev_get_by_index_rcu'
아마 비슷하게:
struct net * net
int ifindex
struct net_device * retval
가 나올 거야.
그렇다면 다음처럼 ifindex=10 조회 결과만 보면 돼:
timeout 15 bpftrace -e '
fexit:dev_get_by_index_rcu
/args.ifindex == 10/
{
printf("dev_get_by_index_rcu: ifindex=%d dev=%p\n",
args.ifindex, retval);
}
'
그리고 네 curl 한 번:
curl -vk --connect-timeout 5 \
--resolve <hostname>:443:10.116.204.202 \
https://<hostname>
결과 1
만약:
dev_get_by_index_rcu: ifindex=10 dev=0x0
이면 범인 확정이야.
네가 가져온 커널 코드 그대로:
dev = dev_get_by_index_rcu(net, ri->tgt_index);
if (unlikely(!dev))
goto out_drop;
이므로:
Cilium/BPF
↓
target ifindex=10 지정
↓
skb_do_redirect()
↓
dev_get_by_index_rcu(net, 10)
↓
NULL
↓
out_drop
↓
kfree_skb()
↓
-EINVAL
끝.
결과 2
반대로:
dev_get_by_index_rcu: ifindex=10 dev=0xff....
이면 ifindex 10은 정상적으로 찾은 거야.
그러면 flags=0이니까 다음으로:
return __bpf_redirect(skb, dev, flags);
에 들어간 거고, 범인은 __bpf_redirect() 내부로 확정돼.
즉 이제 진짜 딱 이것만 확인하면 돼:
dev_get_by_index_rcu(net, 10)의 반환값이 NULL인가 아닌가.
그리고 한 가지. 지금까지 나온 ifindex=10 / ret=-22 패킷이 네 curl 패킷인지 교차확인하는 작업도 마지막에 해야 해. 하지만 redirect 실패 위치를 찾는 작업 자체는 이제 위 한 단계면 크게 갈립니다…!
아까처럼 계속 가지를 넓히지 않을게. 지금은 dev_get_by_index_rcu() 결과 하나만 보자.