Match 条件の wildcard について
Match 中の wildcard について説明します。
前回記事で作成した matchtest.rb を動かしてみましょう。
$ ./trema run ./matchtest.rb -c ./network.conf -d $ TREMA_HOME=. ../apps/flow_dumper/flow_dumper [0x00000000000001] priority = 65535, match = [wildcards = 0x3220ef, in_port = 0, dl_src = 00:00:00:00:00:00, dl_dst = 00:00:00:00:00:00, dl_vlan = 0, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 0, nw_src = 0.0.0.0/0, nw_dst = 192.168.1.0/24, tp_src = 0, tp_dst = 0], actions = []
flow_dumper の出力中に wildcards = 0x3220ef という表示があることが確認できます。二進数で表現すると、 11,0010,0010,0000,1110,1111b となります。この値は 12-tuple のうち、どのフィールドを wildcard として扱うかを示しています。各ビットとフィールドの対応は openflow.h 中にて以下のように定義されています。
/* Flow wildcards. */ enum ofp_flow_wildcards { OFPFW_IN_PORT = 1 << 0, /* Switch input port. */ OFPFW_DL_VLAN = 1 << 1, /* VLAN id. */ OFPFW_DL_SRC = 1 << 2, /* Ethernet source address. */ OFPFW_DL_DST = 1 << 3, /* Ethernet destination address. */ OFPFW_DL_TYPE = 1 << 4, /* Ethernet frame type. */ OFPFW_NW_PROTO = 1 << 5, /* IP protocol. */ OFPFW_TP_SRC = 1 << 6, /* TCP/UDP source port. */ OFPFW_TP_DST = 1 << 7, /* TCP/UDP destination port. */ /* IP source address wildcard bit count. 0 is exact match, 1 ignores the * LSB, 2 ignores the 2 least-significant bits, ..., 32 and higher wildcard * the entire field. This is the *opposite* of the usual convention where * e.g. /24 indicates that 8 bits (not 24 bits) are wildcarded. */ OFPFW_NW_SRC_SHIFT = 8, OFPFW_NW_SRC_BITS = 6, OFPFW_NW_SRC_MASK = ((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT, OFPFW_NW_SRC_ALL = 32 << OFPFW_NW_SRC_SHIFT, /* IP destination address wildcard bit count. Same format as source. */ OFPFW_NW_DST_SHIFT = 14, OFPFW_NW_DST_BITS = 6, OFPFW_NW_DST_MASK = ((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT, OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT, OFPFW_DL_VLAN_PCP = 1 << 20, /* VLAN priority. */ OFPFW_NW_TOS = 1 << 21, /* IP ToS (DSCP field, 6 bits). */ /* Wildcard all fields. */ OFPFW_ALL = ((1 << 22) - 1) };
LSB 側から見て 8-13 ビット目は nw_src, 14-19 ビット目は nw_dst の wildcard を表しています。今回の例では nw_dst = 192.168.1.0/24 ですので wildcard として扱うのは下位 8 ビットです。そのため、14-19 ビット目が 001000b となっています。nw_src は 0.0.0.0/0 なので 32 ビット全てが wildcard となり、8-13 ビット目が 100000b つまり 32 となっています。
Ruby を使った場合この wildcard を気にする必要はありませんが、C 言語の場合は、適切な値に設定する必要があります。次回は、この点に注意して C 言語で Match を書く方法について、説明します。