Wie kann ich sicherstellen, dass meine Header (struct new_header sagen) am Anfang der Daten in der udp_sendmsg() Funktion hinzugefügt. Ich nehme an, dass in das Datenfeld von Skbuff kopiert werden sollte, bevor irgendwelche tatsächlichen Daten von Benutzerraum zu ihm oder spätestens kopiert werden, bevor die UDP Prüfsumme auf den Daten berechnet wird. Wo genau passiert das in der Code?
2 Optionen, die Sie betrachten können:
1. Wenn Sie Ihr Protokoll in User-Space implementieren, dann können Sie einfach, auf Kernel verwenden UDP-Sockets zu sprechen und Protokoll decap zu tun, nachdem Sie Datagramms von UDP-Sockets oder encap erhalten bevor Sie Daten an den UDP-Socket senden.
2.Wenn Sie Ihr Protokoll im Kernelraum implementieren wollen. Dann müssen Sie Ihren eigenen Socket-Typ implementieren. Sie können einige Tunnel-Socket-Codes auschecken, die bereits in der Kernel-Quelle als Beispiel existierten (zB L2TP). Sobald Sie Ihren Socket-Typ im Kernel registriert haben, werden Ihre Socket-Daten, die vom Userspace an den Kernel-Space gesendet werden, von Ihrem encap-Code verarbeitet (etwas, das äquivalent zu udp_sendmsg() ist), und dann dekapieren Sie den Code wiederum mit upd_sendmsg() der Netzwerkstapel.
Wo genau in udp_recvmsg() Funktion ist die Daten an die Steckdose übergeben? Ich denke, es ist skb_copy_datagram_iovec().
Nicht sicher, welche Version des Kernels Sie betrachten. Für Kernel 4.6 ist es skb_copy_datagram_msg() -> skb_copy_datagram_iter(). Dies ist, wo das Datagramm zu einem Buff kopiert wird und dann zum Benutzerbereich zurückkehrt.
Tatsächlich wird udp_recvmsg() aufgerufen, wenn der Benutzerbereich versucht, Daten vom Socket zu empfangen, also befindet sich udp_recvmsg() bereits im Socketzusammenhang. Der Netzwerkstapel übergibt das Datagramm an Socket in sock_queue_rcv_skb(), indem das Datagramm in sk_receive_queue gesetzt wird.
Anrufkette im Kernel 4.6 wie folgt aus:
__udp4_lib_rcv -->
udp_queue_rcv_skb(sk, skb); --> sock_queue_rcv_skb()
die userpsace dann durch die Daten erhalten:
recv();
... ...
-------system call ---------
... ...
udp_recvmsg -->
__skb_recv_datagram -->
__skb_try_recv_datagram --> (get the datagram from sk_receive_queue)
Vielen Dank für die aufwendige Antwort, dass die meisten meiner Zweifel erklärt, dachte der Rest I durch gehen durch den Code.Ich fand es einfacher, den benutzerdefinierten Header am Ende des Datagramms in der Funktion 'udp_send_skb' hinzuzufügen, da er nahtlos funktioniert, auch wenn die Verkorkung aktiviert ist (ich beabsichtige, alle Funktionen von UDP zu verwenden). –