I like playing with Linux Kernel.
shun159 / blog Goto Github PK
View Code? Open in Web Editor NEWmy blog
my blog
I like playing with Linux Kernel.
#2 の続き
ovn/controller/ovn-controller.c:main(int argc, char *argv[])
ざっくりと飛ばすが、次の関数が順に呼ばれている:
ofctrl_initはovn/controller/ofctrl.c
にあります。
void
ofctrl_init(struct group_table *group_table)
{
swconn = rconn_create(5, 0, DSCP_DEFAULT, 1 << OFP13_VERSION);
tx_counter = rconn_packet_counter_create();
hmap_init(&installed_flows);
ovs_list_init(&flow_updates);
groups = group_table;
}
関数の一行目では、OpenFlow1.3で接続しているのだろうとおもいます。
関数の2行目では、投入されたフローを記録する変数というコメントがあります。これを起動時に初期化している。
関数の3行目も同様です、こちらは投入前のフローを記録する変数の初期化です。
4行目は見たとおりなので、省略します。
pinctrl_initはovn/controller/pinctrl.c
にあります。
ofctrl_initと同様、関数の一行目では、OpenFlow1.3で接続しているのだろうとおもいます。
void
pinctrl_init(void)
{
swconn = rconn_create(5, 0, DSCP_DEFAULT, 1 << OFP13_VERSION);
conn_seq_no = 0;
init_put_mac_bindings();
init_send_garps();
}
get_ovnsb_remoteはovn/controller/ovn-controller
に定義されている。
ここでovn-controllerはリモートにある OVN Southbound DBへ接続される.
Open_vSwitch
のexternal_idsにovn-remote
が定義されるまで待っている...
static char *
get_ovnsb_remote(struct ovsdb_idl *ovs_idl)
{
while (1) {
ovsdb_idl_run(ovs_idl);
const struct ovsrec_open_vswitch *cfg
= ovsrec_open_vswitch_first(ovs_idl);
if (cfg) {
const char *remote = smap_get(&cfg->external_ids, "ovn-remote");
if (remote) {
return xstrdup(remote);
}
}
VLOG_INFO("OVN OVSDB remote not specified. Waiting...");
ovsdb_idl_wait(ovs_idl);
poll_block();
}
}
ovsdb_idl_track_add_all(ovnsb_idl_loop.idl)はlib/ovsdb-idl.c
に定義されている.
これは全カラムを監視対象とし、変更を受け取れるように監視対象のDBを指定できるものに読める。
void
ovsdb_idl_track_add_column(struct ovsdb_idl *idl,
const struct ovsdb_idl_column *column)
{
if (!(*ovsdb_idl_get_mode(idl, column) & OVSDB_IDL_ALERT)) {
ovsdb_idl_add_column(idl, column);
}
*ovsdb_idl_get_mode(idl, column) |= OVSDB_IDL_TRACK;
}
ovsdb_idl_get_initial_snapshotはlib/ovsdb-idl.c
に定義されている...
OVSDBサーバへ接続し、DBの内容を取り出すことも可能。
void
ovsdb_idl_get_initial_snapshot(struct ovsdb_idl *idl)
{
while (1) {
ovsdb_idl_run(idl);
if (ovsdb_idl_has_ever_connected(idl)) {
return;
}
ovsdb_idl_wait(idl);
poll_block();
}
}
..以降、メインループとなる。
ovn-architecture。まずはこちらを読む。
CMS
|
|
+-----------|-----------+
| | |
| OVN/CMS Plugin |
| | |
| | |
| OVN Northbound DB |
| | |
| | |
| ovn-northd |
| | |
+-----------|-----------+
|
|
+-------------------+
| OVN Southbound DB |
+-------------------+
|
|
+------------------+------------------+
| | |
HV 1 | | HV n |
+---------------|---------------+ . +---------------|---------------+
| | | . | | |
| ovn-controller | . | ovn-controller |
| | | | . | | | |
| | | | | | | |
| ovs-vswitchd ovsdb-server | | ovs-vswitchd ovsdb-server |
| | | |
+-------------------------------+ +-------------------------------+
The main difference relies on the underlying distributed storage engine.
Emqtt and RabbitMQ use Mnesia (http://erlang.org/doc/apps/mnesia/Mnesia_overview.html) for its underlying distributed storage engine.
VerneMQ uses an eventual consistent datastore backed by LevelDB.
We decided to not use Mnesia because Mnesia doesn't tolerate network partitions very well.
Before starting VerneMQ our company consulted on RabbitMQ setups and we experienced those issues hands-on.
This made us following a completely different approach to enable clustering.
https://github.com/erlio/vernemq/issues/83
snabbの作者、lukegoさんがgithubのissueにブログを書くのをみて
これはよい、私もやってみようよ!と思いたった次第です。
Erlangは内部的に無駄なコピーをしていないのか?
#3 の続き
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
の解読をすすめる上で、
難関となるのが、論理フローの部分となる。
論理的なフローテーブルとは、上で触れた通り、
各論理データパスごとに異なる機能をOpenFlow的なフローで表現したフローエントリを、
「お気持ちの分」人間が読みやすいように抽象的にしたものであるが、ここでは論理テーブルパイプラインごとに、
定義されている処理をOpenFlow的におってみる.
また、今回は時間的な都合により省いているが、論理ルータのフローテーブルはmetadataに格納されている論理データパスが示す
論理スイッチか、またルータかによって同じ論理フローパイプライン上に存在することができるようになっている。
まず、論理データパスごとのテーブルパイプラインにどのようなものがあるかを見る。
上から、論理テーブル0から、、、
vlan_vid
== untagged
かつ、src_mac
!= mcast
なパケットをdrop
。それ以外はresubmit(,17)
となる。lsp-set-port-security
で指定したIPアドレスとDHCPリスエストパケットを通すが、IPアドレス無指定の場合はresubmit(,18)
となっている.lsp-set-address
で指定したIPアドレスがある場合、ipv4アドレスの場合,arp\_spa
, ipv6の場合はnd_{sll|tll}がチェック対象となる.次はPRE_ACLresubmit(,19)
resubmit(,20)
resubmit(,21)
ct(table=22)
)resubmit(,23)
resubmit(,24)
group_id=1,type=select,bucket=weight:100,actions=ct(commit,table=25,zone=NXM_NX_REG13[0..15],nat(dst=10.0.0.1)),bucket=weight:100,actions=ct(commit,table=25,zone=NXM_NX_REG13[0..15],nat(dst=10.0.0.2))
TODO: ovn/actions.c
とovn/controller/lflow
を読んで解説をかく
2年目のErlangプログラマが身につけておきたい12のデバッグ術
Poptrie: A Compressed Trie with Population Count for Fast and Scalable Software IP Routing Table Lookup
SAIL, DXR, TreeBitMapと比較して、強力である。と言った特徴がある。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.