今日も秋田で IoT

旧 Trema 日記

Features Request でスイッチから情報を取得する (その5)

前回からだいぶ時間がたってしまいましたが、Features Request を用いた情報取得に関する記事の最終回です。今回は、第一回で作成した ShowFeatures コントローラを改造して、Features Request で取得できる情報を更に出力できるようにしてみます。

class ShowFeatures < Controller
  def switch_ready datapath_id
    send_message datapath_id, FeaturesRequest.new
  end

  def features_reply datapath_id, message
    puts "Datapath ID: #{ datapath_id.to_hex }"
    puts "Max packets: #{ message.n_buffers }"
    puts "Number of tables: #{ message.n_tables }"
    puts "Capabilities: #{ message.capabilities.to_s( 2 ) }"
    puts "Supported actions: #{ message.actions.to_s( 2 ) }"

    message.ports.each do | each |
      puts "Port no: #{ each.number }"
      puts "  Hardware address: #{ each.hw_addr.to_s }"
      puts "  Port name: #{ each.name }"
      puts "  Config: #{ each.config.to_s( 2 ) }"
      puts "  State: #{ each.state.to_s( 2 ) }"
      puts "  Features: #{ each.curr.to_s( 2 ) }"
      puts "    Advertised: #{ each.advertised.to_s( 2 ) }"
      puts "    Supported: #{ each.supported.to_s( 2 ) }"
      puts "    Peer: #{ each.peer.to_s( 2 ) }"
    end
  end
end

実行してみる

ShowFeatures コントローラを実行してみましょう。

$ sudo trema run ./show-features.rb -c ./network.conf 
Datapath ID: 0xabc
Max packets: 256
Number of tables: 1
Capabilities: 10000111
Supported actions: 111111111111
Port no: 2
  Hardware address: 1a:18:a9:7d:35:75
  Port name: trema0-1
  Config: 0
  State: 0
  Features: 11000000
    Advertised: 0
    Supported: 0
    Peer: 0
Port no: 65534
  Hardware address: 02:2a:33:5d:6c:bd
  Port name: vsw_0xabc
  Config: 1
  State: 1
  Features: 10000010
    Advertised: 0
    Supported: 0
    Peer: 0
Port no: 1
  Hardware address: 56:e5:fe:83:bc:9f
  Port name: trema1-1
  Config: 0
  State: 0
  Features: 11000000
    Advertised: 0
    Supported: 0
    Peer: 0
^C
terminated

スイッチのケイパビリティは、10000111 と表示されています。第三回の記事に記載した enum ofp_capabilities と見比べると、このスイッチでは OFPC_FLOW_STATS, OFPC_TABLE_STATS, OFPC_PORT_STATS, OFPC_ARP_MATCH_IP がサポートされていることがわかります。一方で、OFPC_STP, OFPC_RESERVED, OFPC_IP_REASM, OFPC_QUEUE_STATS はサポートされていません。

また、サポートアクションに関しては、111111111111 と表示されています。OpenFlow 1.0 の仕様で定義されているアクションの数は 12 ですので、このスイッチはこれらをすべてサポートしていることを意味しています。

次に各ポートごとの情報を見ていきます。Config と State に関しては、Port 番号 1 と 2 に関しては両方共 0 となっています。Config が 0 ということは定義されている設定は特に行われていないことを意味します。また State が 0 ということは、STP も特に利用していないので、単に Link up していることを意味します。一方で Port 番号 65534 に関しては、Administrative down されていることがわかります。

ポートのフィーチャーに関しては、Port 番号 1, 2 のポートでは OFPPF_10GB_FD, OFPPF_COPPER のフラグが立っています。今回使用している OpenFlow スイッチでは 10GbE のカッパーを使用しておらず、リンクに関してはソフトウェア的に仮想的に作られてものです。今回使用しているソフトウェアスイッチは、ソフトウェア的なリンクを 10GbE のカッパーとして返す実装を行なっているようです。

レビュー「マスタリングTCP/IP OpenFlow編」

ネットワーク技術者御用達のマスタリング TCP/IP シリーズから、OpenFlow 編が出ました。著者の方から献本頂きましたので、レビューをしたいと思います。

マスタリングTCP/IP OpenFlow編

マスタリングTCP/IP OpenFlow編

第 1 章 OpenFlow 概要

成り立ちから動作例まで、OpenFlow の概要について書かれた章です。成り立ちについても紋切り的な説明に終始せず、なぜこのような仕様になったのか、仕様策定の裏側が伺えるような説明がされています。

また、OpenFlow チャネルで使用するためのネットワークについてもきちんと説明されており、一般的なネットワーク技術者が疑問に思うだろう点が丁寧に取り上げられている印象です。

OpenFlow の概要を抑えるのに、まさに十分な章となっています。

第 2 章 OpenFlow 1.0 の仕組み

この章以降で、概要からさらに踏み込んだ説明がされていきます。まずは第 2 章で OpenFlow 1.0 の仕様の詳細が説明されます。

ここで嬉しいのはメッセージのパケットフォーマットが記載されているところですね。デバッグ時、セキュアチャネルを tcpdump で覗く時に役立つこと間違いなしです。

第 3 章 〜 第 6 章

これらの章では、LLDP によるトポロジー検出の仕組みから、ユースケースまで、主に OpenFlow の活用例が紹介されています。LLDP 等 OpenFlow を活用する上で必要不可欠な周辺技術についても丁寧に説明してある点が、この本の良いところです。

第 7 章 〜 第 9 章

OpenFlow 1.1, 1.2, 1.3 で追加された仕様について説明された章です。昨今 OpenFlow 1.3 対応機器が増えつつある中、仕様を理解するために日本語での説明は非常にありがたいです。

これらの章も単に仕様の説明に終始せず、関連するネットワーク技術についても合わせて紹介されており、どのように利用するのかがイメージできるようわかりやすく説明されています。

第 10 章 〜 第 11 章

OpenFlow の留意事項とこれからについて書かれています。使用時に気をつけるべきポイントがまとめてあるため、OpenFlow を実際に使う人には役に立つ章となっています。

全体を通して

この本は、単に仕様や使い方を説明するのみならず、読者が気になるだろう点に関して踏み込んだ説明をしてくれています。OpenFlow の仕組みを理解したい人や、OpenFlow を使って何かをしたい人など、多くの人にとって役立つ本だと思います。

OpenFlow実践入門 Kindle 版

拙著の OpenFlow 実践入門ですが、Kindle 版が 5/10 に発売になるようです。持ち運びに便利な Kindle 版の方も、ぜひよろしくお願いします。

クラウド時代のネットワーク技術 OpenFlow実践入門

クラウド時代のネットワーク技術 OpenFlow実践入門

レビュー : 「次世代ネットワーク制御技術 OpenFlow 入門」

OpenFlow入門が、アスキー・メディアワークス社から発売されました。著者の方から献本いただきましたので、レビューしたいと思います。

次世代ネットワーク制御技術 OpenFlow入門

次世代ネットワーク制御技術 OpenFlow入門

第1章 OpenFlowの歴史

タイトルは歴史となっていますが、歴史を掘り下げて書かれている感じではありませんでした。OpenFlow 誕生のいきさつなどの説明があり、OpenFlow 初心者に対するイントロダクションに位置づけられる章でしょうか?

第2章 OpenFlow : 基本編

OpenFlow スイッチやプロトコルの仕様に関して解説されています。OpenFlow switch specification に書かれていることが中心になりますが、英語が苦手な方は、この解説の方が役に立つかもしれません。また英語の仕様書が読める方でも、この解説を補完的に読むことで、理解が深まるかもしれません。
この仕様解説は、OpenFlowを利用する方に力点が置かれている実践入門の方では、あまり触れられていない部分です。

第3章 OpenFlow : 応用編

Trema を使って C 言語で OpenFlow コントローラをプログラミングしてみるといった内容です。ある機能を持つコントローラを作るというよりも、Packet In ハンドラなど Trema API を使用例に沿って説明しています。

第4章 OpenFlow : 展開編

既存のインフラ上に、OpenFlow-enabled なネットワークをオーバーレイで構成する際の注意点などについて議論されています。著者らが関連しているOpenFlow テストベッド RISE (この本でも付録で紹介されています) 構築の際に得られた知見をまとめたものと思われます。

おわりに

OpenFlow 仕様解説や、C 言語でのプログラミングなど、我々の書いた実践入門とはまた違った切り口での入門書となっています。興味のある方は、ぜひ手にとって見てください。

Features Request でスイッチから情報を取得する (その4)

今回もTremaを少し離れて、OpenFlow 1.0 の仕様の話です。今回は Features Request/Reply で取得できるポートの情報について見ていきます。

ポート情報を格納するための構造体 struct ofp_phy_port は、以下のように定義されています。

struct ofp_phy_port {
    uint16_t port_no;
    uint8_t hw_addr[OFP_ETH_ALEN];
    char name[OFP_MAX_PORT_NAME_LEN]; /* Null-terminated */

    uint32_t config;        /* Bitmap of OFPPC_* flags. */
    uint32_t state;         /* Bitmap of OFPPS_* flags. */

    /* Bitmaps of OFPPF_* that describe features.  All bits zeroed if
     * unsupported or unavailable. */
    uint32_t curr;          /* Current features. */
    uint32_t advertised;    /* Features being advertised by the port. */
    uint32_t supported;     /* Features supported by the port. */
    uint32_t peer;          /* Features advertised by peer. */
};
OFP_ASSERT(sizeof(struct ofp_phy_port) == 48);
  • port_no : ポート番号
  • hw_addr : ハードウェアアドレス (MAC アドレス)
  • name : ポート名。OFP_MAX_PORT_NAME_LEN は 16 (Null-terminated なので、Null を除いて最大 15 文字まで)
  • config : ポートのコンフィグ (後述)
  • state : ポートの状態(後述)
  • curr, advertised, supported, peer : ポートのフィーチャー (後述)

ポートのコンフィグ

config には、ポートがどのようにコンフィグされているかに関する情報を示すビットマップが格納されています。各ビットの意味は、以下のように定義されています。

enum ofp_port_config {
    OFPPC_PORT_DOWN    = 1 << 0,  /* Port is administratively down. */

    OFPPC_NO_STP       = 1 << 1,  /* Disable 802.1D spanning tree on port. */
    OFPPC_NO_RECV      = 1 << 2,  /* Drop all packets except 802.1D spanning
                                     tree packets. */
    OFPPC_NO_RECV_STP  = 1 << 3,  /* Drop received 802.1D STP packets. */
    OFPPC_NO_FLOOD     = 1 << 4,  /* Do not include this port when flooding. */
    OFPPC_NO_FWD       = 1 << 5,  /* Drop packets forwarded to port. */
    OFPPC_NO_PACKET_IN = 1 << 6   /* Do not send packet-in msgs for port. */
};

OFPPC_PORT_DOWN はコンフィグによるダウンである Administratively down を意味します。

ポートの状態

state には、ポートの現在の状態が格納されます。各ビットは、以下のような意味を持ちます。

enum ofp_port_state {
    OFPPS_LINK_DOWN   = 1 << 0, /* No physical link present. */

    /* The OFPPS_STP_* bits have no effect on switch operation.  The
     * controller must adjust OFPPC_NO_RECV, OFPPC_NO_FWD, and
     * OFPPC_NO_PACKET_IN appropriately to fully implement an 802.1D spanning
     * tree. */
    OFPPS_STP_LISTEN  = 0 << 8, /* Not learning or relaying frames. */
    OFPPS_STP_LEARN   = 1 << 8, /* Learning but not relaying frames. */
    OFPPS_STP_FORWARD = 2 << 8, /* Learning and relaying frames. */
    OFPPS_STP_BLOCK   = 3 << 8, /* Not part of spanning tree. */
    OFPPS_STP_MASK    = 3 << 8  /* Bit mask for OFPPS_STP_* values. */
};

OFPPS_LINK_DOWN は、いわゆるケーブルが接続されていない等の理由でリンクアップしていない状態を表します。

ポートのフィーチャー

curr, advertised, supported, peer には、ポートのフィーチャーに関する情報が格納されます。各ビットの意味は、以下のとおりです。

enum ofp_port_features {
    OFPPF_10MB_HD    = 1 << 0,  /* 10 Mb half-duplex rate support. */
    OFPPF_10MB_FD    = 1 << 1,  /* 10 Mb full-duplex rate support. */
    OFPPF_100MB_HD   = 1 << 2,  /* 100 Mb half-duplex rate support. */
    OFPPF_100MB_FD   = 1 << 3,  /* 100 Mb full-duplex rate support. */
    OFPPF_1GB_HD     = 1 << 4,  /* 1 Gb half-duplex rate support. */
    OFPPF_1GB_FD     = 1 << 5,  /* 1 Gb full-duplex rate support. */
    OFPPF_10GB_FD    = 1 << 6,  /* 10 Gb full-duplex rate support. */
    OFPPF_COPPER     = 1 << 7,  /* Copper medium. */
    OFPPF_FIBER      = 1 << 8,  /* Fiber medium. */
    OFPPF_AUTONEG    = 1 << 9,  /* Auto-negotiation. */
    OFPPF_PAUSE      = 1 << 10, /* Pause. */
    OFPPF_PAUSE_ASYM = 1 << 11  /* Asymmetric pause. */
};

各フィールドの違いは以下のとおりです。

  • curr : 現在の状態
  • advertised : 広告したフィーチャー
  • supported : サポートしているフィーチャー
  • peer : 対向から広告されたフィーチャー

ちゃんと仕様通り実装されているのか確認しないと怖くて使えなさそうな感じです。どうしても必要ならば確認して使いましょう。とりあえず curr だけ抑えておけば大丈夫そうな気がします。