Ich habe einen neuen Testfall fürhttps://github.com/xdp-project/bpf-examplesHier https://github.com/tjcw/bpf-examples/tree/tjcw-integration-0.3/AF_XDP-filter . Es dient zum Filtern von Flows. Die Idee besteht darin, das erste Paket eines Flows an den Benutzerbereich zu senden, den Benutzerbereich (durch Betrachten des Fünfertupels des Pakets) bestimmen zu lassen, ob der Flow akzeptabel ist oder nicht, und entsprechend einen Eintrag in einer eBPF-Map festzulegen. Das zweite und alle weiteren Pakete des Flows werden im Kernel durch eBPF-Code verarbeitet. Der Testfall funktioniert, außer dass das erste Paket (das über eine Tun/Tap-Schnittstelle erneut in den Kernel eingespeist wird) dann vom Kernel als „Marsian“ verworfen wird. Der Effekt ist, dass Sie, wenn Sie versuchen, diesen Code mit „Ping“ zu erreichen, alle Pakete sehen, auf die geantwortet wurde, außer dem ersten, und wenn Sie „SSH“ versuchen, gibt es am Anfang eine kleine Unterbrechung, während das TCP-Protokoll auf dem Client abläuft und das SYN-Paket erneut überträgt.
Ich füge die Ausgabe von 'pwru' (cilium packet-where-are-you) bei der Ausführung an
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:~$
Weiß jemand, der dies liest, warum der Kernel das Paket als Marsianer behandelt und ob es eine Möglichkeit gibt, dies zu umgehen? Ich verwende Ubuntu 22.04 mit uname -a, das
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
Das erste (verworfene) Paket ist der Abschnitt vom ersten pskb_expand_head bis zum kfree_skbmem und das zweite (übergebene) Paket ist der Abschnitt vom zweiten pskb_expand_head bis zum Ende.
Antwort1
Dieses Verhalten ist auf die Rückpfadfilterung zurückzuführen, ein Versuch, die Verarbeitung von Paketen zu vermeiden, die über die „falsche“ Schnittstelle eingehen. Dies kann deaktiviert werden mit
for device in /proc/sys/net/ipv4/conf/*
do
echo 0 >${device}/rp_filter
done
im Skript, das auf dem Server ausgeführt wird. Sobald dies erledigt ist, werden alle Ping-Pakete beantwortet.