扱っているプロトコルによってはまれに IP ToS を設定してパケットを送出したくなることがあります。
使ってるデーモンが対応しているなら適切に設定、もしくはソースを書き換えられるなら setsockopt(SO_PRIORITY) してパケットを送り出すように改造するといいと思います。
この文書では、IP ToS を設定してパケットを送出できないデーモンのパケットを、iptables で ToS 変更して送り出す場合を考えたいと思います。
お題: 外向きの ICMP パケットに IP Precedence 3 を設定する
cisco のルータとかだと policy-map の set ip precedence 3
で表現されるやつです。
解1: iptables の mangle table の OUTPUT chain の TOS target で --set-tos する
TOS
このモジュールは IPv4 ヘッダーの Type of Service フィールド (上位ビットも含む) や IPv6 ヘッダーの Priority フィールドを設定する。 TOS は DSCP と ECN と同じビットを共有する点に注意すること。 TOS ターゲットは mangle テーブルでのみ有効である。--set-tos value[/mask]
mask で指定されたビットを 0 にし (下の「注意」を参照)、 value と TOS/Priority フィールド の XOR を取る。 mask が省略された場合は 0xFF とみなされる。
TOS ターゲットの --set-tos
が使えれば目的を達成できそうです。TOS ターゲットは mangle テーブルでのみ使えるので、mangle テーブルの OUTPUT chain (下図の OUTPUT PATH 内の conntrack の次) にひっかけてみます。
--set-tos
で指定する値についてですが、precedence は IP ToS/DSCP の上位 3 bit 部分なので、0x60 = 0110 0000(2)
を指定します。
# iptables -t mangle -A OUTPUT --protocol icmp -j TOS --set-tos 0x60
# iptables -L -n -t mangle
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
TOS icmp -- 0.0.0.0/0 0.0.0.0/0 TOS set 0x60/0xff
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
こんな感じになります。今回は例として ICMP をひっかけましたが、お使いのデーモンがしゃべるプロトコルのポート番号などにひっかけるようにすれば TCP や UDP での応答にもひっかけられます。
解2: iptables の mangle table の OUTPUT chain で DSCP target で --set-dscp もしくは --set-dscp-class する
DSCP
このターゲットは、 IPv4 パケットの TOS ヘッダーにある DSCP ビットの値の書き換えを可能にする。 これはパケットを操作するので、 mangle テーブルでのみ使用できる。--set-dscp value
DSCP フィールドの数値を設定する (10 進または 16 進)。
--set-dscp-class class
DSCP フィールドの DiffServ クラスを設定する。
DSCP ターゲットでも同様に書き換えできます。ひっかけられるのが mangle テーブルだけというのも TOS ターゲットと同じです。
今回は IP Precedence 3 を示す DSCP クラス名 CS3
で指定してみます
# iptables -t mangle -A OUTPUT --protocol icmp -j DSCP --set-dscp-class CS3
# iptables -L -n -t mangle
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DSCP icmp -- 0.0.0.0/0 0.0.0.0/0 DSCP set 0x18
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
--set-tos
の場合と ToS (DiffServ) フィールドの値は同じになります。