EN JA
NG_TAG(4)
NG_TAG(4) FreeBSD Kernel Interfaces Manual NG_TAG(4)

名称

ng_tagnetgraph ノードタイプを操作する mbuf タグ

書式

#include < netgraph/ng_tag.h>

解説

tag ノードタイプによって、mbuf パケットタグ ( mbuf_tags(9) 参照) は、Netgraph ネットワークを横断しながら、データを検査する、ストリップする (取り除く) か、または適用することができます。 mbuf タグは、 vlan(4) で記述される VLAN タグの記憶域、 mac(9) で記述される Mandatory Access Control (MAC) ラベル、 ipsec(4) で記述される IPsec ポリシ情報、および pf(4) によって使用されたパケットフィルタを含んで、 FreeBSD カーネルネットワークサブシステムの多くの部分で使用されています。また、mbuf タグとして実装されている、 ipfw(8) タグを設定するかチェックする役に立つものとして考慮にいれるべきです。

各ノードによって、接続の任意の数字は、フックを任意に指定することができます。各フックが関連づけられている状態で、すべてのタグのリスト中で検索されるタグは、このフックに着信するパケット、適合するパケットのための宛先 (終点) フック、適合しないパケットのための宛先 (終点) フック、このフックを通してノードを離れるデータに追加されるタグ、および様々な統計カウンタにアタッチします。

着信パケットのタグのリストは、指定された typecookie 値でタグを見つけるために横断されます。適合では、指定された tag_len が 0 でなければ、タグの tag_data は、フック構造体で指定されたものと同じになるようにチェックされます。適合するタグがあるパケットは、“match” (適合する) 宛先のフックに転送されるか、またはそうでなければ“non-match” (適合しない) フックに転送されます。両方またはいずれかの宛先フックに空の文字列が指定されるか、または存在しない場合、パケットは落とされます。

ノードを出るパケットのタグリストは、発信フック構造体で指定されている新しいタグを付けて拡張されています (対応する発信フックの構造体で 0 typecookie 値を指定することによって完全に変更されないパケットを渡すために新しいタグの追加を避けることは可能です)。さらに、 strip フラグが設定されるなら、適合の後に着信パケットからタグをストリップする (取り除く) ことができます。発信適合フックにおいてタグ追加と組み合わせるなら、簡単なタグ削除またはタグ置換のためにこれを使用することができます。そのようなタグがリスト中に既に存在しているかどうかチェックしないで、 (これが心配であるかチェックすることは、ユーザ次第です) 新しいタグが無条件に追加されることに注意してください。

新しいフックは、初めに、すべての着信パケット (すべてのフック名が空の文字列として、すべてのパケットを適合しないフックに転送するために 0 値を指定することができます) を落として、任意のタグの追加なしですべて発信パケットを転送するために設定されます。

ノードを通して渡されるパケットのデータのペイロード (訳注: ヘッダ部を除いたデータの本体) は、完全に変更されません、すべての操作はタグリストのみ影響します。

フック

このノードタイプは、任意の名前を持っているいくつものフックをサポートします。内部の最適化を可能とするために、ユーザは、まだ存在していないフックを指す構造体で決してフックを設定しようとするべきではありません。安全な方法は、最初に、すべてのフックを作成して、次に、それらを設定し始めることです。

コントロールメッセージ

このノードタイプは、次を加えて、一般的なコントロールメッセージをサポートします:
NGM_TAG_SET_HOOKIN ( sethookin)
このコマンドは、フックで着信パケットのタグリストで検索されるタグ値を設定します。引数として次の構造体を供給しなければなりません:

struct ng_tag_hookin { 
  char    ifMatch[NG_HOOKSIZ]; 
    /* 適合する宛先フック */ 
  char    ifNotMatch[NG_HOOKSIZ]; 
    /* 適合しない宛先フック */ 
  uint8_t   strip;        /* 見つかればタグをストリップ */ 
  uint32_t   tag_cookie;   /* ABI/モジュール ID */ 
  uint16_t   tag_id;       /* タグ ID */ 
  uint16_t   tag_len;      /* データの長さ */ 
  uint8_t   tag_data[0];  /* タグデータ */ 
};

更新されるフックは、 thisHook で指定されます。指定された tag_id (タイプ) と tag_cookie に対応するタグのデータバイトは、 tag_data 配列に置かれます。それらは、それらの tag_len でなければなりません。適合するから適合しない着信パケットは、それぞれ指定された ifMatchifNotMatch というフックで配信されます。 strip フラグが 0 でなければ、見つけられたタグは、パケットタグのリストから削除されます。

NGM_TAG_GET_HOOKIN ( gethookin)
このコマンドは、 ASCII 文字列引数、フック名を取って、上記に示されるような対応する struct ng_tag_hookin を返します。
NGM_TAG_SET_HOOKOUT ( sethookout)
このコマンドは発信パケットに適用されるタグ値を設定します。引数として次の構造体を供給しなければなりません:

struct ng_tag_hookout { 
  char    thisHook[NG_HOOKSIZ];   /* フックの名前 */ 
  uint32_t   tag_cookie;    /* ABI/モジュール ID */ 
  uint16_t   tag_id;    /* タグ ID */ 
  uint16_t   tag_len;    /* データの長さ */ 
  uint8_t   tag_data[0];    /* タグデータ */ 
};

更新されるフックは、 thisHook で指定されます。他の変数は、新しいタグの値を設定するために使用されることを除いて、上記に示された struct ng_tag_hookin と基本的に同じであること意味します。

NGM_TAG_GET_HOOKOUT ( gethookout)
このコマンドは、 ASCII 文字列引数、フック名を取って、上記に示されるような対応する struct ng_tag_hookout を返します。
NGM_TAG_GET_STATS ( getstats)
このコマンドは、 ASCII 文字列引数、フック名を取って、 struct ng_tag_hookstat としてフックに関連づけられた統計値を返します。
NGM_TAG_CLR_STATS ( clrstats)
このコマンドは、 ASCII 文字列引数、フック名を取って、フックに関連している統計値をクリアします。
NGM_TAG_GETCLR_STATS ( getclrstats)
このコマンドは、統計値が不可分にクリアされることを除いて、 NGM_TAG_GET_STATS と同じです。

注: コードが NG_TAG_DEBUG オプションでコンパイルされた場合にだけ、上記の 3 つの統計メッセージと同様に統計カウンタは動作します。この理由は統計値が実際にはめったに使用されないのですが、あらゆるパケットのためにまだ CPU サイクルを費やしているということです。さらに、それは、これが非常に高価であるので、スレッドの間の同期の不足のために SMP システム上で正確でさえありません。

シャットダウン

このノードは、 NGM_SHUTDOWN コントロールメッセージを受け取るか、すべてのフックが切断されている時、シャットダウンします。

使用例

ng_bpf(4) トラフィックアナライザ (分析器) に関連して ipfw(8) タグを使用して簡単な L7 フィルタリングをすることは可能です。次の例はランダムなポートを使用するとき普通の手段によってできない DirectConnect P2P ネットワークデータトラフィックをフィルタリングする方法を説明しています。そのようなデータ接続は、常に 6 バイトのペイロード文字列 "$Send|"がある TCP パケットを含むことが知られています。したがって、ipfw の netgraph 動作は、すべての TCP パケットを指定された文字列をチェックする、 ng_bpf(4) へ配信するために使用され、 ipfw(8) へ適合しないパケットを返します。適合しているパケットは、すべてのパケットを受け付けて、それらを ipfw(8) に戻すようにプログラムされたフック上の ng_bpf(4) ノードにタグを設定して、それらを戻す、 ng_tag(4) ノードに渡されます。 ng_bpf(4) マニュアルページに提供されたスクリプトは、プログラミングノードに使用されます。 ipfw(8) から Netgraph に配信されるパケットは、リンクレベルヘッダがないので、 tcpdump(1) 表現におけるオフセットをそれに応じて変更しなければならないことに注意してください。したがって、着信フックと ng_tag(4) からすべてのパケットに適合するための空の式において、式“ ether[40:2]=0x244c && ether[42:4]=0x6f636b20”があります。

したがって、これは次をより簡単にアクセスするために作成して、名前付けするノードのための ngctl(8) スクリプトです。

/usr/sbin/ngctl -f- <<-SEQ 
 mkpeer ipfw: bpf 41 ipfw 
 name ipfw:41 dcbpf 
 mkpeer dcbpf: tag matched th1 
 name dcbpf:matched ngdc 
SEQ

今、(タイプ ng_tag である) “ ngdc”は、アタッチされた ipfw(8) タグ 412 で“ th1”フックの後ろで受信されたすべてのパケットをエコー (echo) するためにプログラムされなければなりません。 tag_cookie のための MTAG_IPFW 値は、ファイル < netinet/ip_fw.h> から取られ、 tag_id のための値は、0 タグの長さで、タグ番号 (412) です:

ngctl msg ngdc: sethookin { thisHook=\"th1\" ifNotMatch=\"th1\" } 
ngctl msg ngdc: sethookout { thisHook=\"th1\"\ 
  tag_cookie=1148380143 \ 
  tag_id=412 }

上記の式 (これを行うスクリプトについて ng_bpf(4) を参照) と空の式で“ matched” (適合する) フックで ng_bpf(4)ipfw”フックをプログラムすることを忘れないでください:

ngctl msg dcbpf: setprogram { thisHook=\"matched\" ifMatch=\"ipfw\"\ 
  bpf_prog_len=1 bpf_prog=[ { code=6 k=8192 } ] }

netgraph(4) ノードで終わった後に、 ipfw(8) 規則が、パケットフローを有効にするために追加されなければなりません:

ipfw add 100 netgraph 41 tcp from any to any iplen 46 
ipfw add 110 reset tcp from any to any tagged 412

注: パケットが、適切な sysctl(8) 変数を設定することによって netgraph(4) の中で処理した後に ipfw に返されることを確実にするべきです:

sysctl net.inet.ip.fw.one_pass=0

歴史

ng_tag ノードタイプは、 FreeBSD 6.2 で実装されました。

作者

Vadim Goncharov <vadimnuclight@tpu.ru>

バグ

データペイロードで任意のタグ (すなわち、0 でない tag_len があるすべてのタグ) を操作するために、バイトストリームとして低レベルでのタグの移植性がないマシン依存の表現について注意するべきです。たぶん、手動よりもむしろ別のプログラムによってこれを行うべきです。
June 10, 2006 FreeBSD