Gg

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() 결과 하나만 보자.