OpenFlow「で」おぼえる
ネットワーク
2015/08/08
Tremaday#7
1
@stereocat
SIerでネットワークエンジニア
…的な何か。
IHAnet ASN#64594
2
Motivation
• Flow programmingは結構いろいろ覚えないとい
けないことが多い。
– ネットワークの仕組み
– プログラミング
• 考えること
– やってみたいことを実現するために、ネットワーク
の仕組みを、どうプログラミングしたらよいのか。
• ネットワークがわからないから、ネットワークの
制御とか、どうしていいかわからない??
3
サンプルプログラムを模写したり
ちょっとずつ書き換えたりしながら
プログラミングを学ぶように、
ネットワークも
ちょっとずつ動かしながら
段階的に理解したらよいのでは
なかろうか?
4
というのを考えてみた
• 特にEthernet(L2)の話
– ネットワークやってる人じゃないと普段L2なん
か気にしないよね。
– でも(個人的に)Flow Programmingしててハマる
のはまずL2
– とにかく面倒くさいL2
• 実際にflowベースにネットワークを組みなが
ら、NWがどういう仕掛けなのかを見てみる
チュートリアルなんてどうでしょうね?
5
注意事項
• 対象者
– ネットワーク? なにそれ? な人
• そういう人をどうにかしてネットワークわかるように
仕込みたい人。
• まずは感覚的な理解を得る方向で。
– 厳密ではない/不正確なところがあります。
• L1→L2→L3みたいな流れにしようと思って
たんだけど、時間的な都合でL1のあたりで行
き詰りました!!!!!!
6
ネットワーク知識キホンのキ
7
ネットワークを感覚的にとらえる
• Why
– そもそも
どうしてネットワークが必要なんだっけ?
• What
– ネットワークってなにがあればいいんだっけ?
• How
– ネットワークってなにができればいいんだっけ?
8
ひとりで全部やれるのであれば
べつにネットワークとかいらないですね。
9
ひとりでぜんぶやれるわけじゃない。
複数の人が共同して何かやろうとすると
それぞれの情報交換が必要になります。
→ 「ネットワーク」の発生
10
ネットワーク = コミュニケーション
誰かから (source)
誰か宛に (destination)
情報を送るもの。
かならず2点(以上)の「端点」がある
11
hoge
hoge
hoge
hoge
伝えたいことを表現する方法(言語、文字…)
伝えたいことを伝える媒体(空気、紙…)
伝えたいこと 伝わったこと
音声
手紙
両方が同じになってはじめて「伝わった」といえる
12
表現 解釈
 みんなが同じルールを共有しておく必要がある。
 日本語を使います。
 紙に書きます。
 時候の挨拶をしてから本文を書きます。
 etc
 この「互いに合意すべき情報交換のルール」をプロトコルという。
protocol
【名詞】
1【不可算名詞】 (外交上の)儀礼,典礼.
2【可算名詞】 条約原案; 議定書,プロトコル.
3【可算名詞】 (国家間の)協定.
4【可算名詞】 《主に米国で用いられる》 (実験・治療の)実施要綱[計画].
5【可算名詞】 【電子計算機】 プロトコル 《データ通信の手順》.
protocolの意味 - 英和辞典 Weblio辞書
http://ejje.weblio.jp/content/protocol
伝えたいことを表現する方法(言語、文字…)
伝えたいことを伝える媒体(空気、紙…)
13
メディア: 物質・物理現象
• 物理的特性・特徴に応じた使いどころがある。
– 信号減衰、ノイズ/揺らぎ、強度、コスト、……
– 光の速度を超えた情報交換はできない。
hoge
会話による情報伝達の場合
 情報の表現には日本語を使う
 情報の伝達は音声 = 空気をメディアとして使う
14
ネットワークのカタチ
15
何を使って
情報を伝えるか
(使うもの・メディア)
どこの・誰に
情報を伝えるか
どんな情報を伝えるか
(表現・会話の決め事)
今日はこの辺
p2p
Learning
switch
最小のネットワークを
手動でつくる
h1
h1-eth0
h2
h2-eth0
s1
s1-eth1
(1)
s1-eth2
(2)
16
h1-h2が1本のワイヤで直結している状態と同等
host hostnetwork
stereocat@prjexp01:~/tremaday7$ sudo mn --topo single,2 --mac --controller remote
*** Creating network
*** Adding controller
Unable to contact the remote controller at 127.0.0.1:6633
*** Adding hosts:
h1 h2
*** Adding switches:
s1
*** Adding links:
(h1, s1) (h2, s1)
*** Configuring hosts
h1 h2
*** Starting controller
c0
*** Starting 1 switches
s1 ...
*** Starting CLI:
mininet> net
h1 h1-eth0:s1-eth1
h2 h2-eth0:s1-eth2
s1 lo: s1-eth1:h1-eth0 s1-eth2:h2-eth0
c0
mininet>
stereocat@prjexp01:~$ sudo ovs-ofctl add-flow s1 in_port=1,actions=output:2
stereocat@prjexp01:~$ sudo ovs-ofctl add-flow s1 in_port=2,actions=output:1
stereocat@prjexp01:~$
17
入ってき
たら
もう片方
から出す
mininet> dpctl dump-flows
*** s1 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=35.591s, table=0, n_packets=0, n_bytes=0, idle_age=35, in_port=1
actions=output:2
cookie=0x0, duration=31.365s, table=0, n_packets=0, n_bytes=0, idle_age=31, in_port=2
actions=output:1
mininet> pingall
*** Ping: testing ping reachability
h1 -> h2
h2 -> h1
*** Results: 0% dropped (2/2 received)
mininet>
18
これは何か : 糸電話モデル
hoge hoge
h1
h2
 h1-h2が直結されている
 h1-h2が相互に情報を送り合える。
 h1がしゃべったことがそのままh2に出力される。
 h2がしゃべったことがそのままh1に出力される。 19
h3
複数人で会話するには?
hoge
h1
h2
h4
20
h3
h1
h2
h4
こうか。
hoge
hoge
hoge
hoge
 みんな一続きの糸で直結されている。
 糸を共有している
 誰かがしゃべったことがみんなに聞こえる。
21
h1
h1-eth0
h2
h2-eth0
s1
s1-eth1
(1)
s1-eth2
(2)
h3
h3-eth0
h4
h4-eth0
s1-eth3
(3)
s1-eth4
(4)
?
 誰かがしゃべったことがみんなに聞こえる。
どうつなぐ?
22
stereocat@prjexp01:~/tremaday7$ sudo mn --topo single,4 --mac --controller remote
*** Creating network
*** Adding controller
Unable to contact the remote controller at 127.0.0.1:6633
*** Adding hosts:
h1 h2 h3 h4
*** Adding switches:
s1
*** Adding links:
(h1, s1) (h2, s1) (h3, s1) (h4, s1)
*** Configuring hosts
h1 h2 h3 h4
*** Starting controller
c0
*** Starting 1 switches
s1 ...
*** Starting CLI:
mininet> net
h1 h1-eth0:s1-eth1
h2 h2-eth0:s1-eth2
h3 h3-eth0:s1-eth3
h4 h4-eth0:s1-eth4
s1 lo: s1-eth1:h1-eth0 s1-eth2:h2-eth0 s1-eth3:h3-eth0 s1-eth4:h4-eth0
c0
mininet>
23
stereocat@prjexp01:~$ sudo ovs-ofctl add-flow s1 in_port=1,actions=output:2,3,4
stereocat@prjexp01:~$ sudo ovs-ofctl add-flow s1 in_port=2,actions=output:1,3,4
stereocat@prjexp01:~$ sudo ovs-ofctl add-flow s1 in_port=3,actions=output:1,2,4
stereocat@prjexp01:~$ sudo ovs-ofctl add-flow s1 in_port=4,actions=output:1,2,3
mininet> dpctl dump-flows
*** s1 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=38.301s, table=0, n_packets=12, n_bytes=840, idle_age=23, in_port=3
actions=output:1,output:2,output:4
cookie=0x0, duration=49.157s, table=0, n_packets=12, n_bytes=840, idle_age=23, in_port=1
actions=output:2,output:3,output:4
cookie=0x0, duration=33.757s, table=0, n_packets=12, n_bytes=840, idle_age=23, in_port=4
actions=output:1,output:2,output:3
cookie=0x0, duration=43.459s, table=0, n_packets=12, n_bytes=840, idle_age=23, in_port=2
actions=output:1,output:3,output:4
mininet> pingall
*** Ping: testing ping reachability
h1 -> h2 h3 h4
h2 -> h1 h3 h4
h3 -> h1 h2 h4
h4 -> h1 h2 h3
*** Results: 0% dropped (12/12 received)
mininet>
 誰かがしゃべったことがみんなに聞こえる。
24
入ってき
たら他所
から出す
h1
h1-eth0
h2
h2-eth0
s1
s1-eth1
(1)
s1-eth2
(2)
h3
h3-eth0
h4
h4-eth0
s1-eth3
(3)
s1-eth4
(4)
 誰かがしゃべったことがみんなに聞こえる。
 → フルメッシュ
 入ったポート以外の全部のポートに送る: Flooding
sudo ovs-ofctl add-flow s1 in_port=1,actions=output:2,3,4
↓
sudo ovs-ofctl add-flow s1 in_port=1,actions=FLOOD
25
(原始的な)Ethernetのイメージ = 糸電話
hoge
hoge
hoge
hoge
 メディア = 電線 = 糸と考えてみる。
「糸」を共有する
 実際ひとつのワイヤをみんなで分岐させてた。
26
参考
TheEthernetEvolutionFrom10Megto10GigHowitallWorks!,
HadrielKaplan&RobertNoseworthy,Atlanta,2001.
https://www.iol.unh.edu/sites/default/files/knowledgebase/ether
net/ethernet_evolution.pdf
27
やってみよう! (1)
h1
h1-eth0
s1-eth2
(2)
h2
h2-eth0
h3
h3-eth0
s1-eth1
(1)
s2-eth1
(1)
s2-eth3
(3)
s2-eth2
(2)
s3-eth2
(2)
s3-eth1
(1)
s1 s2 s3
28
from functools import partial
from mininet.cli import CLI
from mininet.net import Mininet
from mininet.link import Link
from mininet.node import RemoteController, OVSSwitch
if '__main__' == __name__:
switch = partial(OVSSwitch, protocols='OpenFlow10,OpenFlow12,OpenFlow13')
net = Mininet(switch=switch)
c0 = RemoteController('c0')
net.addController(c0)
s1 = net.addSwitch('s1')
s2 = net.addSwitch('s2')
s3 = net.addSwitch('s3')
h1 = net.addHost('h1')
h2 = net.addHost('h2')
h3 = net.addHost('h3')
Link(s1, s2, intfName1="s1-eth1", intfName2="s2-eth1")
Link(s2, s3, intfName1="s2-eth2", intfName2="s3-eth1")
Link(h1, s1)
Link(h2, s2)
Link(h3, s3)
net.start()
CLI(net)
net.stop()
29
sudo ovs-ofctl add-flow s1 in_port=1,actions=FLOOD
sudo ovs-ofctl add-flow s1 in_port=2,actions=FLOOD
sudo ovs-ofctl add-flow s2 in_port=1,actions=FLOOD
sudo ovs-ofctl add-flow s2 in_port=2,actions=FLOOD
sudo ovs-ofctl add-flow s2 in_port=3,actions=FLOOD
sudo ovs-ofctl add-flow s3 in_port=1,actions=FLOOD
sudo ovs-ofctl add-flow s3 in_port=2,actions=FLOOD
mininet> dpctl dump-flows
*** s1 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=7.429s, table=0, n_packets=0, n_bytes=0, idle_age=7, in_port=1 actions=FLOOD
cookie=0x0, duration=7.413s, table=0, n_packets=0, n_bytes=0, idle_age=7, in_port=2 actions=FLOOD
*** s2 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=7.369s, table=0, n_packets=0, n_bytes=0, idle_age=7, in_port=3 actions=FLOOD
cookie=0x0, duration=7.401s, table=0, n_packets=0, n_bytes=0, idle_age=7, in_port=1 actions=FLOOD
cookie=0x0, duration=7.385s, table=0, n_packets=0, n_bytes=0, idle_age=7, in_port=2 actions=FLOOD
*** s3 ------------------------------------------------------------------------
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=7.357s, table=0, n_packets=0, n_bytes=0, idle_age=7, in_port=1 actions=FLOOD
cookie=0x0, duration=7.341s, table=0, n_packets=0, n_bytes=0, idle_age=7, in_port=2 actions=FLOOD
mininet> pingall
*** Ping: testing ping reachability
h1 -> h2 h3
h2 -> h1 h3
h3 -> h1 h2
*** Results: 0% dropped (6/6 received)
mininet>
30
入ってき
たら他所
から出す
やってみよう! (2)
h1
h1-eth0
s1-eth3
(3)
h2
h2-eth0
h3
h3-eth0
s1-eth1
(1)
s2-eth1
(1)
s2-eth3
(3)
s2-eth2
(2)
s3-eth3
(3)
s3-eth1
(1)
s1 s2 s3
s1-eth2
(2)
s3-eth2
(2)
三角形にしてみる
31
from functools import partial
from mininet.cli import CLI
from mininet.net import Mininet
from mininet.link import Link
from mininet.node import RemoteController, OVSSwitch
if '__main__' == __name__:
switch = partial(OVSSwitch, protocols='OpenFlow10,OpenFlow12,OpenFlow13')
net = Mininet(switch=switch)
c0 = RemoteController('c0')
net.addController(c0)
s1 = net.addSwitch('s1')
s2 = net.addSwitch('s2')
s3 = net.addSwitch('s3')
h1 = net.addHost('h1')
h2 = net.addHost('h2')
h3 = net.addHost('h3')
Link(s1, s2, intfName1="s1-eth1", intfName2="s2-eth1")
Link(s2, s3, intfName1="s2-eth2", intfName2="s3-eth1")
Link(s3, s1, intfName1="s3-eth2", intfName2="s1-eth2")
Link(h1, s1)
Link(h2, s2)
Link(h3, s3)
net.start()
CLI(net)
net.stop()
32
リンク1本追加
sudo ovs-ofctl add-flow s1 in_port=1,actions=FLOOD
sudo ovs-ofctl add-flow s1 in_port=2,actions=FLOOD
sudo ovs-ofctl add-flow s1 in_port=3,actions=FLOOD
sudo ovs-ofctl add-flow s2 in_port=1,actions=FLOOD
sudo ovs-ofctl add-flow s2 in_port=2,actions=FLOOD
sudo ovs-ofctl add-flow s2 in_port=3,actions=FLOOD
sudo ovs-ofctl add-flow s3 in_port=1,actions=FLOOD
sudo ovs-ofctl add-flow s3 in_port=2,actions=FLOOD
sudo ovs-ofctl add-flow s3 in_port=3,actions=FLOOD
mininet> xterm h3
mininet> h1 ping –c3 h2
h3# tcpdump –i h3-eth0
33
リンク1本追加した分
ルールを追加
sudo ovs-ofctl add-flow s1 in_port=1,actions=output:3
sudo ovs-ofctl add-flow s1 in_port=2,actions=output:3
sudo ovs-ofctl add-flow s1 in_port=3,actions=FLOOD
sudo ovs-ofctl add-flow s2 in_port=1,actions=output:3
sudo ovs-ofctl add-flow s2 in_port=2,actions=output:3
sudo ovs-ofctl add-flow s2 in_port=3,actions=FLOOD
sudo ovs-ofctl add-flow s3 in_port=1,actions=output:3
sudo ovs-ofctl add-flow s3 in_port=2,actions=output:3
sudo ovs-ofctl add-flow s3 in_port=3,actions=FLOOD
なんでもFloodingすればよいというわけではないデスネ
34
「共有メディア」を感覚的にとらえる
hoge
 同じ部屋の人が一つのメディアを共有する
↓
 ある人がしゃべるとほかの人がみんな聞こえる(flooding)
 ある人がしゃべっている間はほかの人はしゃべれない(半二重通信)
35
衝突(collision)
えっと
あの
 同時にしゃべっちゃう (衝突:Collision)
 ぶつかったらランダムに待機してタイミングをずらす
→ CSMA/CD
 衝突が起きる範囲 = Collision Domain
つながってる糸(糸電話モデル)、ひとつの部屋(空気モデル) 36
共有メディアの問題
 発言者はひとり
 人が増えると発言可能な時間が減る
37
リピータ
hoge ????
hoge hoge
 弱くなった信号を増幅してくれる
 コリジョンドメインを操作するものではない。
(L1:物理層のデバイス)
 遠いと信号が弱くなってしまう(減衰)
38
Flooding network
• FloodingするだけのNW機器
– リピータハブ
• リピータハブだけで作れるネットワーク
には限界がある。
– 全部聞こえる
• ノードが増えると各ノードの通信効率が落ちる
• 効率が悪い
– ループ
39
どうする?
• 誰がどこにいるかを知る
• 必要最小限の範囲にだけ声を届ける
– 物理メディアを「区切って」使う
40
• …というのをOpenFlowでやるとどうなる
のか?
• このへんで時間切れということで!!
– 準備的に
– コンテンツの量的に
• あとこういう話ができればどうかな、と
いう話を。
41
だれがいるのかを知る
Cさんって
いる?
A
B
C
 じぶん(Dさん)が会話したい人が、いま糸の先にいるのかどうか?
 Dさんは隣にいる人(同じメディアを共有している人)全員に会話し
たい人かどうか聞く。
→ Broadcast
 自分が呼ばれていたら答える
 いる? → いるよ が成立したら会話できる。
いるよ
D
42
ブリッジ
A
B
C
D
 Cさんから返事→Cさんがどこにいるかがわかる。
 居場所を学習する。
 片側だけ(A-B or C-D)で話をするときには切り離しておく。
→ コリジョンドメインの分離。
→ コリジョンドメイン内では並行して会話ができる。
切り離せば
A-B, C-Dが同時
に会話できる。
43
hoge
hoge
スイッチ
A
B
C
D
 もっと高機能なブリッジ … 直接会話する2点間をだけ直結させる
 最小のコリジョンドメイン: P2P
→ コリジョンは発生しない。
 いまどきのネットワークだといちいちコリジョンドメインとか意
識しません。 44
やってみよう! (案)
• ARP TableはKnownだとして、ARP Request
(Broadcast) + Unicastのコントロールルールを
考えてみる(というくらいなら手動でやれる)
– Single Switch
– Multiple Switch
• Learning Switch
– ARP TableはUnknownだとして。
• 同一セグメント内: Mobility(同じ場所にいるとは限らない)
– プログラミング!
45
会話モデルで考えるNetwork Layer
 「隣にいる」 = 同じ部屋にいる
 同じ「メディア」を共有していて、
直接「会話」できる。
「声」がそのまま届く範囲は限られる。
 「遠くにいる」= 違う部屋にいる
 直接「会話」できない
あ
?
46
よその部屋の人との会話
Pさんと話し
たいのでAさ
んに伝言して
もらう。
A
B
C
D
 この部屋にいるのは[A-D]のグループだというのはあらかじめ
知っている。
 Pさんが部屋の中にいないということが判別できる。
 Aさんがほかの部屋との伝言(中継)役というのも知っている。
 Aさんいるよね? っていうのをみんなに聞く。
 Pさんに伝えたいことをAさんにわたして中継してもらう。
Aさんって
いる?
いるよ
47
あ
会話モデルで考えるNetwork Layer
あこういう全体の伝言ゲームを
どうやって機械で実現するか、
というのがIPの世界の話。
隣のひとから隣の人への「会話」を
どうやってやるか、というのが
Ethernet (Layer2) の話。
途中が
糸電話とか
でもいい
48
D A
P
やってみよう! (案)
• Simple Router
49
会話モデルで考えるNetwork Layer
Layer1: 物理層
どういうメディアを使うか。
(材質、形状、信号、…)
Layer2: データリンク層
同じメディアにつながっている人
同士(隣同士)でどうやって会話を
成立させるか。
Layer3: ネットワーク層
同じメディアでつながっていない
人同士で、どうやって会話を成立
させるか。
Layer4: トランスポート層
会話のしかた
50
会話モデルで考えるNetwork Layer
Layer1: 物理層
どういうメディアを使うか。
(材質、形状、信号、…)
Layer2: データリンク層
同じメディアにつながっている人
同士(隣同士)でどうやって会話を
成立させるか。
Layer3: ネットワーク層
同じメディアでつながっていない
人同士で、どうやって会話を成立
させるか。
Layer4: トランスポート層
会話のしかた
51
何を使って
情報を伝えるか
(使うもの・メディア)
どこの・誰に
情報を伝えるか
どんな情報を伝えるか
(表現・会話の決め事)
注意事項
• とりあえずまず感覚だけつかもう、という内容にした
ので、ちょっとごまかしているところ。
– OVSでのフロー設定と動作模擬: mininet上の操作は「ス
イッチ」でやるのでこの辺は深追いしない方向で。
• コリジョンドメイン
• 全二重と反二重
• 物理メディアの話
– TCP/IPのはなし全般
• 技術的な発展課題
– 経路冗長化とL2ループのトレードオフ
• ループ回避技術(STP)
– ネットワークの仮想化(VLAN)
52

OpenFlowで覚えるネットワーク