カーネルが tun/tap を通じて注入されたパケットを「Martian」として扱わないようにする方法

カーネルが tun/tap を通じて注入されたパケットを「Martian」として扱わないようにする方法

新しいテストケースがありますhttps://github.com/xdp-project/bpf-examplesここ https://github.com/tjcw/bpf-examples/tree/tjcw-integration-0.3/AF_XDP-フィルター これはフローをフィルタリングするためのものです。フローの最初のパケットをユーザー空間に送信し、ユーザー空間で (パケットの 5 組を見て) フローが許容可能かどうかを判断して、それに応じて eBPF マップにエントリを設定するという考え方です。フローの 2 番目以降のパケットは、カーネルで eBPF コードによって処理されます。テスト ケースは機能しますが、最初のパケット (tun/tap インターフェイスを介してカーネルに再注入されます) は、カーネルによって「martian」としてドロップされます。その結果、このコードに「ping」を実行すると、最初のパケット以外のすべてのパケットが応答され、「ssh」を実行すると、クライアントの TCP プロトコルがタイムアウトして SYN パケットを再送信する間、開始時に小さな中断が発生します。

実行時の「pwru」(繊毛パケット-どこにいるの?)の出力を添付します。

tjcw@tjcw-Standard-PC-Q35-ICH9-2009:~$ ping -c 2 192.168.122.48
PING 192.168.122.48 (192.168.122.48) 56(84) bytes of data.
64 bytes from 192.168.122.48: icmp_seq=2 ttl=64 time=2.28 ms

--- 192.168.122.48 ping statistics ---
2 packets transmitted, 1 received, 50% packet loss, time 1028ms
rtt min/avg/max/mdev = 2.282/2.282/2.282/0.000 ms
tjcw@tjcw-Standard-PC-Q35-ICH9-2009:~$

これを読んでいる人の中で、カーネルがパケットを火星人として扱う理由と、これを克服する方法があるかどうかを知っている人はいますか?私はUbuntu 22.04を使用していて、uname -aで表示されています

tjcw@tjcw-Standard-PC-Q35-ICH9-2009:~$ uname -a
Linux tjcw-Standard-PC-Q35-ICH9-2009 5.15.0-53-generic #59-Ubuntu SMP
Mon Oct 17 18:53:30 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
tjcw@tjcw-Standard-PC-Q35-ICH9-2009:~$
2022/11/25 11:37:02 Listening for events..
               SKB    CPU          PROCESS                     FUNC
0xffff9478f5038300      1        [<empty>]         pskb_expand_head
0xffff9478f5038300      1        [<empty>]            skb_free_head
0xffff9478f5038300      1        [<empty>] bpf_prog_run_generic_xdp
0xffff9478f5038300      1        [<empty>]  xdp_do_generic_redirect
0xffff9478f5038300      1        [<empty>]              consume_skb
0xffff9478f5038300      1        [<empty>]   skb_release_head_state
0xffff9478f5038300      1        [<empty>]         skb_release_data
0xffff9478f5038300      1        [<empty>]            skb_free_head
0xffff9478f5038300      1        [<empty>]             kfree_skbmem
0xffff9478f5038300      1    [af_xdp_user]        netif_receive_skb
0xffff9478f5038300      1    [af_xdp_user]   skb_defer_rx_timestamp
0xffff9478f5038300      1    [af_xdp_user]      __netif_receive_skb
0xffff9478f5038300      1    [af_xdp_user] __netif_receive_skb_one_core
0xffff9478f5038300      1    [af_xdp_user]                   ip_rcv
0xffff9478f5038300      1    [af_xdp_user]              ip_rcv_core
0xffff9478f5038300      1    [af_xdp_user]               sock_wfree
0xffff9478f5038300      1    [af_xdp_user]     ip_route_input_noref
0xffff9478f5038300      1    [af_xdp_user]       ip_route_input_rcu
0xffff9478f5038300      1    [af_xdp_user]      ip_route_input_slow
0xffff9478f5038300      1    [af_xdp_user]      fib_validate_source
0xffff9478f5038300      1    [af_xdp_user]    __fib_validate_source
0xffff9478f5038300      1    [af_xdp_user] ip_handle_martian_source
0xffff9478f5038300      1    [af_xdp_user]         kfree_skb_reason
0xffff9478f5038300      1    [af_xdp_user]   skb_release_head_state
0xffff9478f5038300      1    [af_xdp_user]         skb_release_data
0xffff9478f5038300      1    [af_xdp_user]            skb_free_head
0xffff9478f5038300      1    [af_xdp_user]             kfree_skbmem
0xffff9478c75d3000      1        [<empty>]         pskb_expand_head
0xffff9478c75d3000      1        [<empty>]            skb_free_head
0xffff9478c75d3000      1        [<empty>] bpf_prog_run_generic_xdp
0xffff9478c75d3000      1        [<empty>]                   ip_rcv
0xffff9478c75d3000      1        [<empty>]              ip_rcv_core
0xffff9478c75d3000      1        [<empty>]                skb_clone
0xffff9478c75d3000      1        [<empty>]              consume_skb
0xffff9478f5038c00      1        [<empty>]     ip_route_input_noref
0xffff9478f5038c00      1        [<empty>]       ip_route_input_rcu
0xffff9478f5038c00      1        [<empty>]      ip_route_input_slow
0xffff9478f5038c00      1        [<empty>]      fib_validate_source
0xffff9478f5038c00      1        [<empty>]    __fib_validate_source
0xffff9478f5038c00      1        [<empty>]         ip_local_deliver
0xffff9478f5038c00      1        [<empty>]  ip_local_deliver_finish
0xffff9478f5038c00      1        [<empty>]  ip_protocol_deliver_rcu
0xffff9478f5038c00      1        [<empty>]        raw_local_deliver
0xffff9478f5038c00      1        [<empty>]                 icmp_rcv
0xffff9478f5038c00      1        [<empty>]  __skb_checksum_complete
0xffff9478f5038c00      1        [<empty>]                icmp_echo
0xffff9478f5038c00      1        [<empty>]               icmp_reply
0xffff9478f5038c00      1        [<empty>]        __ip_options_echo
0xffff9478f5038c00      1        [<empty>]     fib_compute_spec_dst
0xffff9478f5038c00      1        [<empty>] security_skb_classify_flow
0xffff9478f5038c00      1        [<empty>]              consume_skb
0xffff9478f5038c00      1        [<empty>]   skb_release_head_state
0xffff9478f5038c00      1        [<empty>]         skb_release_data
0xffff9478f5038c00      1        [<empty>]             kfree_skbmem
0xffff9478c75d3000      1        [<empty>]               packet_rcv
0xffff9478c75d3000      1        [<empty>]              consume_skb
0xffff9478c75d3000      1        [<empty>]   skb_release_head_state
0xffff9478c75d3000      1        [<empty>]         skb_release_data
0xffff9478c75d3000      1        [<empty>]            skb_free_head

最初の (ドロップされた) パケットは最初の pskb_expand_head から kfree_skbmem までのセクションであり、2 番目の (通過した) パケットは 2 番目の pskb_expand_head から最後までのセクションです。

答え1

この動作は、逆パスフィルタリングによるもので、間違ったインターフェースから入ってくるパケットの処理を避けるためのものです。これを無効にするには、

for device in /proc/sys/net/ipv4/conf/*
do
  echo 0 >${device}/rp_filter
done

サーバーで実行されるスクリプトでこれを実行すると、すべての ping パケットに応答が返されます。

関連情報