shun159 / blog

my blog
3 stars 0 forks source link

ovnのソースを読む(フローテーブル編) #4

Closed shun159 closed 6 years ago

shun159 commented 7 years ago

フローを読む(概論)

3 の続き

物理的(OpenFlow的な)なフローテーブルを読む。

ovn-architectureでも記述されているが、ovnは以下のフローを扱っている。

ovn/controller/lflow.h

/* OpenFlow table numbers.
 *
 * These are heavily documented in ovn-architecture(7), please update it if
 * you make any changes. */
#define OFTABLE_PHY_TO_LOG            0
#define OFTABLE_LOG_INGRESS_PIPELINE 16 /* First of LOG_PIPELINE_LEN tables. */
#define OFTABLE_REMOTE_OUTPUT        32
#define OFTABLE_LOCAL_OUTPUT         33
#define OFTABLE_CHECK_LOOPBACK       34
#define OFTABLE_LOG_EGRESS_PIPELINE  48 /* First of LOG_PIPELINE_LEN tables. */
#define OFTABLE_SAVE_INPORT          64
#define OFTABLE_LOG_TO_PHY           65
#define OFTABLE_MAC_BINDING          66

/* The number of tables for the ingress and egress pipelines. */
#define LOG_PIPELINE_LEN 16

各論理パイプライン処理は16テーブル存在できることになっている。
入力は16から31、出力なら48から63の範囲となる。これらは、論理データパスごとに存在している。

論理スイッチ、ルータ、LB、ACL、DHCPサーバなどの処理がここに記述される。
それ以外は、共通的な転送処理を行う。

ovn/lib/logical-fields.h

/* Logical fields.
 *
 * These values are documented in ovn-architecture(7), please update the
 * documentation if you change any of them. */
#define MFF_LOG_DATAPATH MFF_METADATA /* Logical datapath (64 bits). */
#define MFF_LOG_FLAGS      MFF_REG10  /* One of MLF_* (32 bits). */
#define MFF_LOG_DNAT_ZONE  MFF_REG11  /* conntrack dnat zone for gateway router
                                       * (32 bits). */
#define MFF_LOG_SNAT_ZONE  MFF_REG12  /* conntrack snat zone for gateway router
                                       * (32 bits). */
#define MFF_LOG_CT_ZONE    MFF_REG13  /* Logical conntrack zone for lports
                                       * (32 bits). */
#define MFF_LOG_INPORT     MFF_REG14  /* Logical input port (32 bits). */
#define MFF_LOG_OUTPORT    MFF_REG15  /* Logical output port (32 bits). */

/* Logical registers.
 *
 * Make sure these don't overlap with the logical fields! */
#define MFF_LOG_REG0 MFF_REG0
#define MFF_N_LOG_REGS 10

NXM_NX_REG10は上の通り、Flag用フィールドとして利用されている。以下の通り:

補足であるが、openvswitch 2.6から16個の32bit register(nicira拡張)が利用可能となっている。
また、openflow 1.5から仕様に明記されている、8つの64bit のexteneded register(xreg)に加え、
4つの128bit extended extended register(xxreg)が利用可能となっている。
xreg及びxxregはそれぞれのサイズで、registerをオーバーライドしている.
例:xreg0を使えばreg0とreg1が、xxreg0ならばreg0から3までが利用されることになっている。

かいつまんで説明すれば良いが、もっともこのovn-controllerの解読をすすめる上で、
難関となるのが、論理フローの部分となる。

論理的(OVN的な)なフローテーブルを読む。

論理的なフローテーブルとは、上で触れた通り、
各論理データパスごとに異なる機能をOpenFlow的なフローで表現したフローエントリを、
「お気持ちの分」人間が読みやすいように抽象的にしたものであるが、ここでは論理テーブルパイプラインごとに、
定義されている処理をOpenFlow的におってみる.

また、今回は時間的な都合により省いているが、論理ルータのフローテーブルはmetadataに格納されている論理データパスが示す 論理スイッチか、またルータかによって同じ論理フローパイプライン上に存在することができるようになっている。

まず、論理データパスごとのテーブルパイプラインにどのようなものがあるかを見る。 上から、論理テーブル0から、、、

Logical_Switch

Ingress

Egress

TODO: ovn/actions.covn/controller/lflowを読んで解説をかく

shun159 commented 7 years ago

論理構成は以下の通りとなっているはずである。

ovn_ingress_flow_tables_diagram

Ingress Flow tableを図にすると以下の通りになる。 各フィールドの変化を追って書いてみたものだ。

ovn_ingress_flow_tables
Da1sukeKud0 commented 6 years ago

初めまして。現在自分はOpenFlowに関する研究の一環として、(各スイッチの時刻同期を行い)各スイッチが”同期されたスイッチ内部時刻によって参照するフローテーブルを変更可能”となる様にOVSを拡張したいと考えております。貴方の記事を拝見し、OVSの内部構造に明るいとお見受けし、軽くご質問させて頂ければと思いました。上記の様な拡張が実現出来そうかどうか、ぜひご意見頂戴できればと考えております。

shun159 commented 6 years ago

その研究がよくわかってないので、的確なことを言えないので申し訳ありません。

その場合OVSに手を入れるのは大変辛い作業になるかと思うのですが、 Openflowか何かを喋るアプリケーション側で作り込んだほうが幸せでは無いでしょうか。

”同期されたスイッチ内部時刻によって参照するフローテーブルを変更可能”

「同期された〜内部時刻〜」の辺りですが、ほしいのはvector clockかその類でしょうか。

Da1sukeKud0 commented 6 years ago

曖昧な説明で申し訳御座いません。 時分割多重化を用いたリアルタイム通信方式(時間的制約が厳しい)をOpenFlowにより実現しようという試みなのですが、プロジェクト自体かなり漠然としている現状です。見据えている最終到達点としては、(独自メッセージにて)スイッチ間の高精度な時刻同期を行い、スイッチ側はその同期された時刻に基づいて入力パケットが一次参照するフローテーブル番号を(即時)変更する様にしたいというものであります。

OVS自体を変更するのはかなり高難易度であるのは承知しておりますので、shun159様のおっしゃる様にOVSとの対話ツール(例:https://github.com/digitalocean/go-openvswitch)の様な形で、”vectorclock等から時刻取得し参照するフローテーブルを変更する(もしくは丸ごと書き換える)”為の外部制御機構を作成しようと考えております。 ただ、時間制約が厳しいので、OVSの内部変更ではなく外部制御だと実行時間がネックになるかと心配しています。

長々と申し訳御座いません。まだ手探りなので、前述した様な外部機構を作成する方向性で行ってみようと思っております。ご返信ありがとう御座います。

shun159 commented 6 years ago

OVSの内部変更ではなく外部制御だと実行時間が

openvswitchのkernel moduleはnetlinkを喋れるので、 vswitchdの速度が心配でしたら、netlink(odp)を使ってやるのも手かもしれませんね。 midokuraのmidonet等などはscalaかjavaか覚えていませんが、vswitchdが遅いということで、odp経由で操作していました。また、これはわかりませんが、OVNのコードを読んでもらえばわかるとおりですが、openflowやovs-ofctlコマンド経由ではなく、直接OpenvswitchのC APIを叩いてやっても良いかもしれませんね。

なにか助けになれば幸いです。研究、頑張ってください!

いえいえ、こちらこそありがとうございました。

Da1sukeKud0 commented 6 years ago

シミュレーションレベルであればnetlinkで充分かも知れないです。 netlinkと直API双方について方法を探ってみたいと思います。

自分の稚拙な説明に対し懇切丁寧なご返答をいただき誠に有り難うございます。 頑張ります!