どのように私は自分のヘッダが(構造体new_headerを言う)udp_sendmsg()関数内のデータの先頭に追加されていることを確認します。私はこの をskbuffのデータフィールドにコピーしてから、ユーザー空間の実際のデータ をコピーするか、遅くともUDP のチェックサムがデータで計算される前にコピーする必要があります。これはコード で正確にどこに起こりますか?
2あなたが考えることができますオプション:
あなた1.IfあなたがUDPソケットまたはエンキャップからデータグラムを受信した後、ユーザー空間であなたのプロトコルを実装し、あなただけのカーネル、およびプロトコルデキャップを行うために話をするUDPソケットを使用することができますUDPソケットにデータを送信する前に
2.プロトコルをカーネル空間に実装したい場合は、独自のソケットタイプを実装する必要があります。カーネルソースに既に存在するトンネルソケットコードを例(例:L2TP)で確認できます。ソケットタイプをカーネルに登録すると、ユーザスペースからカーネルスペースに送信されるソケットデータは、encapコード(udp_sendmsg()と同等のもの)で処理され、コードをエンコードするとudp_sendmsg()ネットワークスタック
正確には、udp_recvmsg()関数はソケットに渡されるデータですか?私はそれがskb_copy_datagram_iovec()だと思います。
あなたが見ているカーネルのバージョンが不明です。カーネル4.6では、skb_copy_datagram_msg() - > skb_copy_datagram_iter()です。これは、データグラムがbuffにコピーされてからuserspaceに戻る場所です。
実際に、udp_recvmsg()は、ユーザー空間がソケットからデータを受信しようとするときに呼び出されるため、udp_recvmsg()はすでにソケットコンテキスト内にあります。 ネットワークスタックは、データグラムをsk_receive_queueに入れてsock_queue_rcv_skb()のソケットにデータグラムを渡します。このようなカーネル4.6で
コールチェーン:
__udp4_lib_rcv -->
udp_queue_rcv_skb(sk, skb); --> sock_queue_rcv_skb()
その後userpsaceはしてデータを取得する:
recv();
... ...
-------system call ---------
... ...
udp_recvmsg -->
__skb_recv_datagram -->
__skb_try_recv_datagram --> (get the datagram from sk_receive_queue)
出典
2016-06-24 17:14:27
Lin
私は考え出し残り、私の疑問のほとんどを説明する精巧な答え、ありがとうコードを実行してコーディングが有効になっていてもシームレスに動作するので、データグラムの終わりにカスタムヘッダーを追加する方が簡単です(私はUDPのすべての機能を使用する予定です) –