8

私はnetlinkプログラミングが初めてです。プロトコルファミリgeneric netlinkを作成するためのプログラムを書いています。インターネットで多くのドキュメントを検索したところ、家族netlinkを定義するための「属性とポリシー」のようなものが見つかりました。netlink

私はこれらのことで完全に混乱しています。

の属性について次のようなものを見つけましたlinux/netlink.h

 <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
+---------------------------+- - -+- - - - - - - - - -+- - -+
|        Header             | Pad |    Payload        | Pad | 
|   (struct nlattr)         | ing |                   | ing |
+---------------------------+- - -+- - - - - - - - - -+- - -+
 <-------------------- nlattr->nla_len -------------->

ポリシーはnla_policy構造体の配列です。私の質問は次のとおりです。

  1. ヘッダーと属性の関係は何ですか? 「属性」について説明してください。
  2. ポリシーとは何ですか? その必要性は何ですか? なぜこれに配列を使用するのでしょうか?

「属性のタイプを定義する」などのポリシーについて見つけましたが、
これはどういう意味ですか? 「属性の型の意味は何ですか?」という意味です。

ナンセンスな質問かもしれませんが、私は完全に混乱しています。私はこれらのことを 3 日以上理解しようとしてきました。助けてください。

ありがとう..

4

1 に答える 1

6

プロトコルを作成/使用する場合netlinknetlink属性は、プロトコルに将来の拡張性を可能にする明確な自己文書化レイアウトを与えることを目的としています。つまり、現在のプロトコルに既に存在するものに加えて別のデータ型を使用したい場合、コードは既存の操作を壊すことなく互換性があります。

「属性」はプロトコルに依存し、そのプロトコルを使用して送信される特定のメッセージに関連しています。

taskstatsインターフェースを例として使用します。

taskstat属性:

enum {
    TASKSTATS_CMD_ATTR_UNSPEC = 0,
    TASKSTATS_CMD_ATTR_PID,
    TASKSTATS_CMD_ATTR_TGID,
    TASKSTATS_CMD_ATTR_REGISTER_CPUMASK,
    TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK,
    __TASKSTATS_CMD_ATTR_MAX,
};

UNSPECこれらの属性では、間にカスタム属性を追加し、MAXその属性を必要な特定の機能または操作にマッピングすることで、簡単に「拡張」できます。

カーネル空間taskstatポリシー:

static const struct nla_policy taskstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1] = {
    [TASKSTATS_CMD_ATTR_PID]  = { .type = NLA_U32 },
    [TASKSTATS_CMD_ATTR_TGID] = { .type = NLA_U32 },
    [TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING },
    [TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },};

プロトコルとインターフェイスstruct nlattrを使用してこの構造体のフィールドをロードする例であるの定義を既にご覧になっていると思います。NETLINK_GENERICtaskstats

struct nlattr na;
na.nla_type = CTRL_ATTR_FAMILY_NAME;         // defined in linux/genetlink.h 
na.nla_len = strlen(TASKSTATS_GENL_NAME) + 1 // defined in linux/taskstats.h

// note: you will need to copy/access nlattr data in the same way the NLMSG_DATA
//       macro operates.

これらの属性を解析するときに、カーネル側で関連する関数が呼び出され、処理方法に関するアクションが意図されます。

あなたが投稿した図があなたをうんざりさせているかどうかはわかりませんが、少しズームアウトしてより広い視野を得るために:

カーネルソースv3.16 include/net/netlink.hによると:

/* ========================================================================
 *         Netlink Messages and Attributes Interface (As Seen On TV)
 * ------------------------------------------------------------------------
 *                          Messages Interface
 * ------------------------------------------------------------------------
 *
 * Message Format:
 *    <--- nlmsg_total_size(payload)  --->
 *    <-- nlmsg_msg_size(payload) ->
 *   +----------+- - -+-------------+- - -+-------- - -
 *   | nlmsghdr | Pad |   Payload   | Pad | nlmsghdr
 *   +----------+- - -+-------------+- - -+-------- - -
 *   nlmsg_data(nlh)---^                   ^
 *   nlmsg_next(nlh)-----------------------+
 *
 * Payload Format:
 *    <---------------------- nlmsg_len(nlh) --------------------->
 *    <------ hdrlen ------>       <- nlmsg_attrlen(nlh, hdrlen) ->
 *   +----------------------+- - -+--------------------------------+
 *   |     Family Header    | Pad |           Attributes           |
 *   +----------------------+- - -+--------------------------------+
 *   nlmsg_attrdata(nlh, hdrlen)---^

ここで、投稿したヘッダーとペイロードの図は、より大きなペイロードの一部に過ぎないことがわかります。struct nlmsghdrそのセグメントは、メッセージ形式の a とともに続きます。

ポリシーでは、netlink メッセージを送信するとき、送信者はプロトコル形式に従う必要があります。メッセージの受信者はstruct nla_policy、ペイロードにアクセスする前に属性を検証するために使用します。

「ファミリ」または識別子は、カーネルが通信する適切なプロトコル インターフェイスを追跡するために使用されます。これは、標準プロトコルまたはGeneric Netlinkのようなカスタム プロトコルに関係なく行われます。

「これを回避できますか?」と尋ねると、独自のカスタム汎用 netlink プロトコルを作成して netlink を拡張している場合、これらが存在するため、関連するすべての操作を実行したり、変更/修正したりすることなく、そのプロトコルを簡単に調整および維持できます。プロトコルが壊れているフラットアウト。長さや型が関連付けられていない、さまざまなデータ型のネストされたメッセージを解析することを他にどのように提案しますか? タイプと長さは、正しいアラインメントでメッセージを解析し、目的のアクションを実行できるようにするためにあります。ペイロードにラベルを付ける属性タイプがなければ、それをどのように解釈しますか、ペイロードは「何」ですか? 長さがなければ、「どのくらいの大きさ」をどのように知ることができますか ペイロードは?それぞれの長さが異なる複数のペイロードが存在する可能性があり、それらのサイズを区別するものがないため、一方の開始点と他方の終了点を区別する方法がありません。

libnl (netlink ソケットを操作するためのライブラリであり、強くお勧めします) ドキュメントの属性へのリンクは次のとおりです。

于 2014-08-27T19:44:30.000 に答える