<commit_before>.. _ch_switching_hub:

スイッチングハブ
================

本章では、簡単なスイッチングハブの実装を題材として、Ryuによるアプリケーションの
実装方法を解説していきます。


スイッチングハブ
----------------

世の中には様々な機能を持つスイッチングハブがありますが、ここでは
次のような単純な機能を持ったスイッチングハブの実装を見てみます。

* ポートに接続されているホストのMACアドレスを学習し、MACアドレステーブル
  に保持する
* 学習済みのホスト宛のパケットを受信したら、ホストの接続されているポートに転送する
* 未知のホスト宛のパケットを受信したら、フラッディングする

このようなスイッチをRyuを使って実現してみましょう。


OpenFlowによるスイッチングハブ
------------------------------

OpenFlowスイッチは、Ryuの様なOpenFlowコントローラからの指示を受けて、
次のようなことを行えます。

* 受信したパケットのアドレスを書き換えたり、指定のポートから転送
* 受信したパケットをコントローラへ転送(Packet-In)
* コントローラから転送されたパケットを指定のポートから転送(Packet-Out)

これらの機能を組み合わせ、スイッチングハブを実現することが出来ます。

まずは、Packet-Inの機能を利用したMACアドレスの学習です。
コントローラは、Packet-Inの機能を利用し、スイッチからパケットを受け取る事が出来ます。
受け取ったパケットを解析し、ホストのMACアドレスや接続されている
ポートの情報を学習することが出来ます。

学習の後は受信したパケットの転送です。
パケットの宛先MACアドレスが学習済みのホストのものか検索します。
検索結果によって次の処理を実行します。

* 学習済みのホストの場合…Packet-Outの機能で、接続先のポートからパケットを転送
* 未知のホストの場合…Packet-Outの機能でパケットをフラッディング

これらの動作を順を追って図とともに説明します。


1. 初期状態

    フローテーブルが空の初期状態です。

    ポート1にホストA、ポート4にホストB、ポート3にホストCが接続されているもの
    とします。

    .. only:: latex

       .. image:: images/switching_hub/fig1.eps
          :scale: 80 %
          :align: center

    .. only:: not latex

       .. image:: images/switching_hub/fig1.png
          :align: center


2. ホストA→ホストB

    ホストAからホストBへのパケットが送信されると、Packet-Inメッセージが送られ、
    ホストAのMACアドレスがポート1に学習されます。ホストBのポートはまだ分かって
    いないため、パケットはフラッディングされ、パケットはホストBとホストCで受信
    されます。

    .. only:: latex

       .. image:: images/switching_hub/fig2.eps
          :scale: 80 %
          :align: center

    .. only:: not latex

       .. image:: images/switching_hub/fig2.png
          :align: center

    Packet-In::

        in-port: 1
        eth-dst: ホストB
        eth-src: ホストA

    Packet-Out::

        action: OUTPUT:フラッディング


3. ホストB→ホストA

    ホストBからホストAにパケットが返されると、フローテーブルにエントリを追加し、
    またパケットはポート1に転送されます。そのため、このパケットはホストCでは
    受信されません。

    .. only:: latex

       .. image:: images/switching_hub/fig3.eps
          :scale: 80 %
          :align: center

    .. only:: not latex

       .. image:: images/switching_hub/fig3.png
          :align: center


    Packet-In::

        in-port: 4
        eth-dst: ホストA
        eth-src: ホストB

    Packet-Out::

        action: OUTPUT:ポート1


4. ホストA→ホストB

    再度、ホストAからホストBへのパケットが送信されると、フローテーブルに
    エントリを追加し、またパケットはポート4に転送されます。

    .. only:: latex

       .. image:: images/switching_hub/fig4.eps
          :scale: 80 %
          :align: center

    .. only:: not latex

       .. image:: images/switching_hub/fig4.png
          :align: center


    Packet-In::

        in-port: 1
        eth-dst: ホストB
        eth-src: ホストA

    Packet-Out::

        action: OUTPUT:ポート4


次に、実際にRyuを使って実装されたスイッチングハブのソースコードを見ていきます。


Ryuによるスイッチングハブの実装
-------------------------------

スイッチングハブのソースコードは、Ryuのソースツリーにあります。

    ryu/app/simple_switch_13.py

OpenFlowのバージョンに応じて、他にもsimple_switch.py(OpenFlow 1.0)、
simple_switch_12.py(OpenFlow 1.2)がありますが、ここではOpenFlow 1.3に対応した
実装を見ていきます。

短いソースコードなので、全体をここに掲載します。

.. rst-class:: sourcecode

.. literalinclude:: sources/simple_switch_13.py<commit_msg>ja: switching_hub: Modify source file for switching hub<commit_after>.. _ch_switching_hub:

スイッチングハブ
================

本章では、簡単なスイッチングハブの実装を題材として、Ryuによるアプリケーションの
実装方法を解説していきます。


スイッチングハブ
----------------

世の中には様々な機能を持つスイッチングハブがありますが、ここでは
次のような単純な機能を持ったスイッチングハブの実装を見てみます。

* ポートに接続されているホストのMACアドレスを学習し、MACアドレステーブル
  に保持する
* 学習済みのホスト宛のパケットを受信したら、ホストの接続されているポートに転送する
* 未知のホスト宛のパケットを受信したら、フラッディングする

このようなスイッチをRyuを使って実現してみましょう。


OpenFlowによるスイッチングハブ
------------------------------

OpenFlowスイッチは、Ryuの様なOpenFlowコントローラからの指示を受けて、
次のようなことを行えます。

* 受信したパケットのアドレスを書き換えたり、指定のポートから転送
* 受信したパケットをコントローラへ転送(Packet-In)
* コントローラから転送されたパケットを指定のポートから転送(Packet-Out)

これらの機能を組み合わせ、スイッチングハブを実現することが出来ます。

まずは、Packet-Inの機能を利用したMACアドレスの学習です。
コントローラは、Packet-Inの機能を利用し、スイッチからパケットを受け取る事が出来ます。
受け取ったパケットを解析し、ホストのMACアドレスや接続されている
ポートの情報を学習することが出来ます。

学習の後は受信したパケットの転送です。
パケットの宛先MACアドレスが学習済みのホストのものか検索します。
検索結果によって次の処理を実行します。

* 学習済みのホストの場合…Packet-Outの機能で、接続先のポートからパケットを転送
* 未知のホストの場合…Packet-Outの機能でパケットをフラッディング

これらの動作を順を追って図とともに説明します。


1. 初期状態

    フローテーブルが空の初期状態です。

    ポート1にホストA、ポート4にホストB、ポート3にホストCが接続されているもの
    とします。

    .. only:: latex

       .. image:: images/switching_hub/fig1.eps
          :scale: 80 %
          :align: center

    .. only:: not latex

       .. image:: images/switching_hub/fig1.png
          :align: center


2. ホストA→ホストB

    ホストAからホストBへのパケットが送信されると、Packet-Inメッセージが送られ、
    ホストAのMACアドレスがポート1に学習されます。ホストBのポートはまだ分かって
    いないため、パケットはフラッディングされ、パケットはホストBとホストCで受信
    されます。

    .. only:: latex

       .. image:: images/switching_hub/fig2.eps
          :scale: 80 %
          :align: center

    .. only:: not latex

       .. image:: images/switching_hub/fig2.png
          :align: center

    Packet-In::

        in-port: 1
        eth-dst: ホストB
        eth-src: ホストA

    Packet-Out::

        action: OUTPUT:フラッディング


3. ホストB→ホストA

    ホストBからホストAにパケットが返されると、フローテーブルにエントリを追加し、
    またパケットはポート1に転送されます。そのため、このパケットはホストCでは
    受信されません。

    .. only:: latex

       .. image:: images/switching_hub/fig3.eps
          :scale: 80 %
          :align: center

    .. only:: not latex

       .. image:: images/switching_hub/fig3.png
          :align: center


    Packet-In::

        in-port: 4
        eth-dst: ホストA
        eth-src: ホストB

    Packet-Out::

        action: OUTPUT:ポート1


4. ホストA→ホストB

    再度、ホストAからホストBへのパケットが送信されると、フローテーブルに
    エントリを追加し、またパケットはポート4に転送されます。

    .. only:: latex

       .. image:: images/switching_hub/fig4.eps
          :scale: 80 %
          :align: center

    .. only:: not latex

       .. image:: images/switching_hub/fig4.png
          :align: center


    Packet-In::

        in-port: 1
        eth-dst: ホストB
        eth-src: ホストA

    Packet-Out::

        action: OUTPUT:ポート4


次に、実際にRyuを使って実装されたスイッチングハブのソースコードを見ていきます。


Ryuによるスイッチングハブの実装
-------------------------------

スイッチングハブのソースコードは、Ryuのソースツリーにあります。

    ryu/app/example_switch_13.py

OpenFlowのバージョンに応じて、他にもsimple_switch.py(OpenFlow 1.0)、
simple_switch_12.py(OpenFlow 1.2)がありますが、ここではOpenFlow 1.3に対応した
実装を見ていきます。

短いソースコードなので、全体をここに掲載します。

.. rst-class:: sourcecode

.. literalinclude:: ../../ryu/app/example_switch_13.py
{'fraction_non_alphanumeric': 0.11910148674854557, 'fraction_numerical': 0.013897866839043309, 'mean_word_length': 2.762310030395137, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7029284', 'n_tokens_mistral': 4020, 'n_tokens_neox': 3642, 'n_words': 316}