Trema/MyRoutingSwitch(5), Topology Change and Re-route(3)
はじめに
前回の話を実際に確認してみます。まずは、単純に、port_status (リンクダウン) が発生したときに、リンクダウンしたポートに対して output しているフローを消すだけだとあまり良くない、という話ところです。
テスト1
変更点
- MyRoutingSwitch
- start: トポロジ状態変化の処理は Topology で行われるのですが、Controller 側にフロー変更要求を通知させられるように self をわたしておきます。
def start # 略 @topology = Topology.new( @command_line.view, self ) # 略 end
-
- flow_delete_by_port: port_status でトポロジ変化が検出されたときに呼び出します。
def flow_delete_by_port dpid, port puts "[MyRoutingSwitch::flow_remove_by_port] switch:#{dpid}, port:#{port}" send_flow_mod_delete( dpid, :out_port => port ) end
- Topology
- delete_link_by: MyRoutingSwitch::port_status でポート状態変化(リンクダウン)が検出されると最終的にこれが呼び出されて、observer に通知されます。
def delete_link_by dpid, port puts "[topology::delete_link_by] switch:#{dpid}, port:#{port.number}" link = @linkindex.link_of dpid, port.number if link puts "delete link: #{link.dpid1}/#{link.port1} - #{link.dpid2}/#{link.port2}" @controller.flow_delete_by_port link.dpid1, link.port1 @controller.flow_delete_by_port link.dpid2, link.port2 changed @links -= [ link ] end notify_observers self end
トポロジ
vswitch("sw1") { dpid "0x1" } vswitch("sw2") { dpid "0x2" } vswitch("sw3") { dpid "0x3" } vswitch("sw4") { dpid "0x4" } vswitch("sw5") { dpid "0x5" } vhost ("host1") { ip "192.168.0.1" netmask "255.255.255.0" mac "00:00:00:01:00:01" } vhost ("host2") { ip "192.168.0.2" netmask "255.255.255.0" mac "00:00:00:01:00:02" } link "sw1", "sw2" link "sw2", "sw3" link "sw3", "sw4" link "sw2", "sw5" link "sw3", "sw5" link "sw1", "host1" link "sw4", "host2"
シナリオ
以下の一連の流れをシナリオとしてスクリプト化しておきます。テキトーだけど。
- Step.1: host1-host2 間で通信を行ってスイッチ内に双方向にフローを入れます。
- Step.2: sw2-sw3 間のリンクをダウンさせます。
- Step.3: 再度 host1-host2 間で通信を行って各スイッチ内のフローを確認します。
- シナリオ共通機能(test-common.sh)
sendpackets_host1() { echo "# send packets 2times" for time in 1 2 do echo "## turn: $time" for host in $* do trema send_packets --source host1 --dest $host --n_pkts 5 sleep 1 trema send_packets --source $host --dest host1 --n_pkts 5 sleep 1 done done sleep 3 } sendpackets_a2b() { echo "# send packets $1 to $2" trema send_packets --source $1 --dest $2 --n_pkts 5 sleep 1 } showstats() { echo "# show host status" for host in $* do echo "## $host packet stats" trema show_stats $host done } dumpflows() { echo "# dump switch flows" for sw in $* do echo "## $sw flows" sudo trema dump_flows $sw done } linkdown() { echo "# linkdown switch:$1, port:$2" trema port_down --switch $1 --port $2 sleep 1 } step() { echo "##" echo "## step $1 ####################################" echo "##" sleep 1 }
- シナリオ
#!/bin/sh . ./test-common.sh # scenario step 1 sendpackets_host1 host2 showstats host1 host2 dumpflows sw1 sw2 sw3 sw4 sw5 step 2 linkdown sw2 1 dumpflows sw1 sw2 sw3 sw4 sw5 step 3 sendpackets_host1 host2 showstats host1 host2 dumpflows sw1 sw2 sw3 sw4 sw5
実行結果
ステップごとにフロー状態を見ていきます。ARP Table までは出してないですが。
Trema の場合、Switch Daemon が Flow の Cookie を変換していて、Cookie 指定して複数フローを束ねることをしていなければ、スイッチへのフロー設定順に連番になっているようです。なので、スイッチ名 + Cookie でフローエントリを参照できます。
- トポロジ(初期状態)
[LinkIndex::update] 0x1 (port 1) <-> 0x2 (port 3) 0x2 (port 1) <-> 0x3 (port 2) 0x2 (port 2) <-> 0x5 (port 2) 0x2 (port 3) <-> 0x1 (port 1) 0x3 (port 1) <-> 0x5 (port 1) 0x3 (port 2) <-> 0x2 (port 1) 0x3 (port 3) <-> 0x4 (port 1) 0x4 (port 1) <-> 0x3 (port 3) 0x5 (port 1) <-> 0x3 (port 1) 0x5 (port 2) <-> 0x2 (port 2) topology updated
- Step.1
## ## step 1 #################################### ## # send packets 2times ## turn: 1 ## turn: 2 # show host status ## host1 packet stats Sent packets: ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets 192.168.0.2,1,192.168.0.1,1,10,500 Received packets: ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets 192.168.0.1,1,192.168.0.2,1,10,500 ## host2 packet stats Sent packets: ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets 192.168.0.1,1,192.168.0.2,1,10,500 Received packets: ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets 192.168.0.2,1,192.168.0.1,1,10,500 # dump switch flows ## sw1 flows NXST_FLOW reply (xid=0x4): cookie=0x4, duration=14.256s, table=0, n_packets=4, n_bytes=256, priority=65535,ip,dl_src=00:00:00:01:00:01,dl_dst=00:00:00:01:00:02,nw_src=192.168.0.1,nw_dst=192.168.0.2 actions=output:1 cookie=0x1, duration=494.504s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x3, duration=19.509s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_dst=00:00:00:01:00:01,nw_dst=192.168.0.1 actions=output:2 cookie=0x2, duration=494.504s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw2 flows NXST_FLOW reply (xid=0x4): cookie=0x4, duration=14.52s, table=0, n_packets=4, n_bytes=256, priority=65535,ip,dl_src=00:00:00:01:00:01,dl_dst=00:00:00:01:00:02,nw_src=192.168.0.1,nw_dst=192.168.0.2 actions=output:1 cookie=0x3, duration=19.777s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:02,dl_dst=00:00:00:01:00:01,nw_src=192.168.0.2,nw_dst=192.168.0.1 actions=output:3 cookie=0x1, duration=494.647s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x2, duration=494.647s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw3 flows NXST_FLOW reply (xid=0x4): cookie=0x4, duration=14.797s, table=0, n_packets=4, n_bytes=256, priority=65535,ip,dl_src=00:00:00:01:00:01,dl_dst=00:00:00:01:00:02,nw_src=192.168.0.1,nw_dst=192.168.0.2 actions=output:3 cookie=0x3, duration=20.056s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:02,dl_dst=00:00:00:01:00:01,nw_src=192.168.0.2,nw_dst=192.168.0.1 actions=output:2 cookie=0x1, duration=495.835s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x2, duration=495.835s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw4 flows NXST_FLOW reply (xid=0x4): cookie=0x3, duration=20.33s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:02,dl_dst=00:00:00:01:00:01,nw_src=192.168.0.2,nw_dst=192.168.0.1 actions=output:1 cookie=0x1, duration=496.085s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x4, duration=15.071s, table=0, n_packets=4, n_bytes=256, priority=65535,ip,dl_dst=00:00:00:01:00:02,nw_dst=192.168.0.2 actions=output:2 cookie=0x2, duration=496.085s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw5 flows NXST_FLOW reply (xid=0x4): cookie=0x1, duration=496.345s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x2, duration=496.345s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop
-
- 初期状態では sw1-sw4 は双方向にフローが入ります。(各スイッチの Cookie=0x3, 0x4 のエントリ)。sw5 はフローが経由しないので特に何もなし。
- Step.2
## ## step 2 #################################### ## # linkdown switch:sw2, port:1 # dump switch flows ## sw1 flows NXST_FLOW reply (xid=0x4): cookie=0x4, duration=18.186s, table=0, n_packets=4, n_bytes=256, priority=65535,ip,dl_src=00:00:00:01:00:01,dl_dst=00:00:00:01:00:02,nw_src=192.168.0.1,nw_dst=192.168.0.2 actions=output:1 cookie=0x1, duration=498.434s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x3, duration=23.439s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_dst=00:00:00:01:00:01,nw_dst=192.168.0.1 actions=output:2 cookie=0x2, duration=498.434s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw2 flows NXST_FLOW reply (xid=0x4): cookie=0x3, duration=23.719s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:02,dl_dst=00:00:00:01:00:01,nw_src=192.168.0.2,nw_dst=192.168.0.1 actions=output:3 cookie=0x1, duration=498.589s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x2, duration=498.589s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw3 flows NXST_FLOW reply (xid=0x4): cookie=0x4, duration=18.737s, table=0, n_packets=4, n_bytes=256, priority=65535,ip,dl_src=00:00:00:01:00:01,dl_dst=00:00:00:01:00:02,nw_src=192.168.0.1,nw_dst=192.168.0.2 actions=output:3 cookie=0x1, duration=499.775s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x2, duration=499.775s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw4 flows NXST_FLOW reply (xid=0x4): cookie=0x3, duration=24.377s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:02,dl_dst=00:00:00:01:00:01,nw_src=192.168.0.2,nw_dst=192.168.0.1 actions=output:1 cookie=0x1, duration=500.132s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x4, duration=19.118s, table=0, n_packets=4, n_bytes=256, priority=65535,ip,dl_dst=00:00:00:01:00:02,nw_dst=192.168.0.2 actions=output:2 cookie=0x2, duration=500.132s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw5 flows NXST_FLOW reply (xid=0x4): cookie=0x1, duration=500.402s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x2, duration=500.402s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop
-
- リンクダウンを発生させた直後のフローエントリの状態です。落ちたリンクに対して output していた以下のエントリが消えます。
- Step.3
## ## step 3 #################################### ## # send packets 2times ## turn: 1 ## turn: 2 # show host status ## host1 packet stats Sent packets: ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets 192.168.0.2,1,192.168.0.1,1,20,1000 Received packets: ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets 192.168.0.1,1,192.168.0.2,1,20,1000 ## host2 packet stats Sent packets: ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets 192.168.0.1,1,192.168.0.2,1,20,1000 Received packets: ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets 192.168.0.2,1,192.168.0.1,1,20,1000 # dump switch flows ## sw1 flows NXST_FLOW reply (xid=0x4): cookie=0x4, duration=45.6s, table=0, n_packets=14, n_bytes=896, priority=65535,ip,dl_src=00:00:00:01:00:01,dl_dst=00:00:00:01:00:02,nw_src=192.168.0.1,nw_dst=192.168.0.2 actions=output:1 cookie=0x1, duration=525.848s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x3, duration=50.853s, table=0, n_packets=19, n_bytes=1216, priority=65535,ip,dl_dst=00:00:00:01:00:01,nw_dst=192.168.0.1 actions=output:2 cookie=0x2, duration=525.848s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw2 flows NXST_FLOW reply (xid=0x4): cookie=0x5, duration=24.909s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:01,dl_dst=00:00:00:01:00:02,nw_src=192.168.0.1,nw_dst=192.168.0.2 actions=output:2 cookie=0x3, duration=51.122s, table=0, n_packets=18, n_bytes=1152, priority=65535,ip,dl_src=00:00:00:01:00:02,dl_dst=00:00:00:01:00:01,nw_src=192.168.0.2,nw_dst=192.168.0.1 actions=output:3 cookie=0x1, duration=525.992s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x6, duration=19.645s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,dl_dst=00:00:00:01:00:01,nw_dst=192.168.0.1 actions=output:3 cookie=0x2, duration=525.992s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw3 flows NXST_FLOW reply (xid=0x4): cookie=0x5, duration=25.181s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:01,dl_dst=00:00:00:01:00:02,nw_src=192.168.0.1,nw_dst=192.168.0.2 actions=output:3 cookie=0x6, duration=19.919s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:02,dl_dst=00:00:00:01:00:01,nw_src=192.168.0.2,nw_dst=192.168.0.1 actions=output:1 cookie=0x1, duration=527.172s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x2, duration=527.172s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw4 flows NXST_FLOW reply (xid=0x4): cookie=0x3, duration=51.666s, table=0, n_packets=19, n_bytes=1216, priority=65535,ip,dl_src=00:00:00:01:00:02,dl_dst=00:00:00:01:00:01,nw_src=192.168.0.2,nw_dst=192.168.0.1 actions=output:1 cookie=0x1, duration=527.421s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x5, duration=25.454s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_dst=00:00:00:01:00:02,nw_dst=192.168.0.2 actions=output:2 cookie=0x2, duration=527.421s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw5 flows NXST_FLOW reply (xid=0x4): cookie=0x3, duration=25.721s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:01,dl_dst=00:00:00:01:00:02,nw_src=192.168.0.1,nw_dst=192.168.0.2 actions=output:1 cookie=0x4, duration=20.458s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:02,dl_dst=00:00:00:01:00:01,nw_src=192.168.0.2,nw_dst=192.168.0.1 actions=output:2 cookie=0x1, duration=527.683s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x2, duration=527.683s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop
[LinkIndex::update] [MyRoutingSwitch::handle_ipv4] [ARPTable::update] DPID=2, port=3, ipaddr=192.168.0.1, hwaddr=00:00:00:01:00:01 [ARPEntry::update] Update entry: DPID=2, MAC addr=00:00:00:01:00:01, port=3 IPv4: dpid:2, port:3, 192.168.0.1->192.168.0.2 (略) flow_mod: dpid:2/port:2 -> dpid:5 flow_mod: dpid:5/port:1 -> dpid:3 flow_mod: dpid:3/port:3 -> dpid:4
-
-
- Cookie=0x6 は host2 → host1 のフローで設定されたフローエントリです。これは sw3 で発生した packet-in で生成されています。sw3-sw5-sw2 で経路計算されています。
-
[MyRoutingSwitch::handle_ipv4] [ARPTable::update] DPID=3, port=3, ipaddr=192.168.0.2, hwaddr=00:00:00:01:00:02 [ARPEntry::update] Update entry: DPID=3, MAC addr=00:00:00:01:00:02, port=3 IPv4: dpid:3, port:3, 192.168.0.2->192.168.0.1 (略) flow_mod: dpid:3/port:1 -> dpid:5 flow_mod: dpid:5/port:2 -> dpid:2
テスト2
"ANY→host" で宛先ホストが接続されているスイッチ(last hop)にルールを設定して、フローエントリが多くなることを避けています。これをやめて中間経路と同等の規則でフローを入れれば、テスト1の実行結果は arp table の中身と実際の接続が食い違ってもフローテーブルとしては統一されるように見えます。
ただ、リンクダウン箇所の近傍に対して arp table が再設定されてしまう(実際のホスト接続位置と、リンクダウン後の arp table 情報が異なる)という状況が残ってしまうのがやっぱりよろしくないです。例えば下図のような状況。
- (前回までの例と同様) host1-host2 間で相互に通信を行った後で sw2-sw3 間リンクダウン
- リンクダウン発生後再度 host1-host2 間で相互に通信
- この状態では、controller は host1 は host1' の位置に、host2 は host2' の位置にいるように見えているので、host3 → host1 で通信を行おうとすると、sw6-sw5(or sw6)-sw2 という計算をすることになります。集約ルール(ANY→host)を使わないことにするなら、sw2 には "host3→host1 to outurt:X" というルールが入ってここまで。sw1 には host3→host1 のルールは入りません。
ということで、この場合は集約ルールを使わないと通信が成立しません。集約ルール使っていれば、sw1,sw2 には "ANY→host1, output:1"(sw1), "ANY→host1, output:3"(sw2) なルールがはいっているはずです。
まあ試してみりゃいいね。
シナリオ
- シナリオ (Step.3 まではテスト1と同様)
#!/bin/sh . ./test-common.sh # scenario step 1 sendpackets_host1 host2 showstats host1 host2 host3 dumpflows sw1 sw2 sw3 sw4 sw5 sw6 step 2 linkdown sw2 1 dumpflows sw1 sw2 sw3 sw4 sw5 sw6 step 3 sendpackets_host1 host2 showstats host1 host2 host3 dumpflows sw1 sw2 sw3 sw4 sw5 sw6 step 4 sendpackets_a2b host3 host1 showstats host1 host2 host3 dumpflows sw1 sw2 sw3 sw4 sw5 sw6
- トポロジ
[LinkIndex::update] 0x1 (port 2) <-> 0x2 (port 3) 0x1 (port 3) <-> 0x6 (port 3) 0x2 (port 1) <-> 0x3 (port 2) 0x2 (port 2) <-> 0x5 (port 3) 0x2 (port 3) <-> 0x1 (port 2) 0x3 (port 1) <-> 0x5 (port 2) 0x3 (port 2) <-> 0x2 (port 1) 0x3 (port 3) <-> 0x4 (port 1) 0x4 (port 1) <-> 0x3 (port 3) 0x5 (port 1) <-> 0x6 (port 2) 0x5 (port 2) <-> 0x3 (port 1) 0x5 (port 3) <-> 0x2 (port 2) 0x6 (port 2) <-> 0x5 (port 1) 0x6 (port 3) <-> 0x1 (port 3) topology updated
実行結果
- Step.4 実行時のコントローラの状態 (host3 通信開始時の packet-in および経路計算)
[MyRoutingSwitch::handle_ipv4] [ARPTable::update] DPID=1, port=2, ipaddr=192.168.0.3, hwaddr=00:00:00:01:00:03 [ARPEntry::update] Update entry: DPID=1, MAC addr=00:00:00:01:00:03, port=2 IPv4: dpid:1, port:2, 192.168.0.3->192.168.0.1 [get_path], start:2, goal:1 (略) flow_mod: dpid:1/port:2 -> dpid:2
- Step.4 後の各スイッチおよびホストの状態
## ## step 4 #################################### ## # send packets host3 to host1 # show host status ## host1 packet stats Sent packets: ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets 192.168.0.2,1,192.168.0.1,1,20,1000 Received packets: ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets 192.168.0.1,1,192.168.0.2,1,20,1000 ## host2 packet stats Sent packets: ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets 192.168.0.1,1,192.168.0.2,1,20,1000 Received packets: ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets 192.168.0.2,1,192.168.0.1,1,20,1000 ## host3 packet stats Sent packets: ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets 192.168.0.1,1,192.168.0.3,1,5,250 Received packets: # dump switch flows ## sw1 flows NXST_FLOW reply (xid=0x4): cookie=0x4, duration=53.488s, table=0, n_packets=14, n_bytes=896, priority=65535,ip,dl_src=00:00:00:01:00:01,dl_dst= 00:00:00:01:00:02,nw_src=192.168.0.1,nw_dst=192.168.0.2 actions=output:2 cookie=0x5, duration=6.178s, table=0, n_packets=5, n_bytes=320, priority=65535,ip,dl_src=00:00:00:01:00:03,dl_dst=00 :00:00:01:00:01,nw_src=192.168.0.3,nw_dst=192.168.0.1 actions=output:2 cookie=0x3, duration=58.747s, table=0, n_packets=19, n_bytes=1216, priority=65535,ip,dl_src=00:00:00:01:00:02,dl_dst =00:00:00:01:00:01,nw_src=192.168.0.2,nw_dst=192.168.0.1 actions=output:1 cookie=0x1, duration=81.482s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x2, duration=81.482s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw2 flows NXST_FLOW reply (xid=0x4): cookie=0x5, duration=34.338s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:01,dl_dst=0 0:00:00:01:00:02,nw_src=192.168.0.1,nw_dst=192.168.0.2 actions=output:2 cookie=0x8, duration=6.481s, table=0, n_packets=4, n_bytes=256, priority=65535,ip,dl_src=00:00:00:01:00:03,dl_dst=00 :00:00:01:00:01,nw_src=192.168.0.3,nw_dst=192.168.0.1 actions=output:3 cookie=0x6, duration=29.056s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:02,dl_dst=0 0:00:00:01:00:01,nw_src=192.168.0.2,nw_dst=192.168.0.1 actions=output:3 cookie=0x1, duration=81.755s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x2, duration=81.755s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw3 flows NXST_FLOW reply (xid=0x4): cookie=0x5, duration=34.619s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:01,dl_dst=00:00:00:01:00:02,nw_src=192.168.0.1,nw_dst=192.168.0.2 actions=output:3 cookie=0x6, duration=29.349s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:02,dl_dst=00:00:00:01:00:01,nw_src=192.168.0.2,nw_dst=192.168.0.1 actions=output:1 cookie=0x1, duration=82.002s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x2, duration=82.002s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw4 flows NXST_FLOW reply (xid=0x4): cookie=0x5, duration=34.919s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:01,dl_dst=00:00:00:01:00:02,nw_src=192.168.0.1,nw_dst=192.168.0.2 actions=output:2 cookie=0x3, duration=59.634s, table=0, n_packets=19, n_bytes=1216, priority=65535,ip,dl_src=00:00:00:01:00:02,dl_dst=00:00:00:01:00:01,nw_src=192.168.0.2,nw_dst=192.168.0.1 actions=output:1 cookie=0x1, duration=82.274s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x2, duration=82.274s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw5 flows NXST_FLOW reply (xid=0x4): cookie=0x3, duration=35.201s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:01,dl_dst=00:00:00:01:00:02,nw_src=192.168.0.1,nw_dst=192.168.0.2 actions=output:2 cookie=0x5, duration=7.371s, table=0, n_packets=4, n_bytes=256, priority=65535,ip,dl_src=00:00:00:01:00:03,dl_dst=00:00:00:01:00:01,nw_src=192.168.0.3,nw_dst=192.168.0.1 actions=output:3 cookie=0x4, duration=29.927s, table=0, n_packets=9, n_bytes=576, priority=65535,ip,dl_src=00:00:00:01:00:02,dl_dst=00:00:00:01:00:01,nw_src=192.168.0.2,nw_dst=192.168.0.1 actions=output:3 cookie=0x1, duration=82.523s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x2, duration=82.523s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop ## sw6 flows NXST_FLOW reply (xid=0x4): cookie=0x3, duration=7.653s, table=0, n_packets=4, n_bytes=256, priority=65535,ip,dl_src=00:00:00:01:00:03,dl_dst=00:00:00:01:00:01,nw_src=192.168.0.3,nw_dst=192.168.0.1 actions=output:2 cookie=0x1, duration=82.764s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop cookie=0x2, duration=82.764s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop
以下のルールが host3 → host1 のフローですが、まあおかしいですね。host1 の受信パケットカウント(Received packets)をみると host3 からのパケットを受信できていないことを示しています。
対策
arp table の固定
問題は集約ルール使うかどうかじゃなくて arp table の情報が実際にホストが接続されている位置と食い違ってしまうこと、ということになります。なぜ食い違ってしまうのかというと、
- arp table update は packet-in で行っている
- リンクダウンが起こると、本来ホストが接続されている位置ではないところで packet-in が起きる
からです。したがって、packet-in + トポロジ情報を元に arp table update を行えば良いことになります。LinkIndex では endpoint の接続されているポートと switch 間接続ポートの情報を持っています。問題を起こすのは、スイッチ間リンクになっているポートで起こる packet-in です。
プロアクティブ経路計算の廃止
あるいは、packet-in に応じて個別に経路計算してしまうのをやめてしまって、トポロジ変更検出→全スイッチ間の最短経路を計算してキャッシュしておく、なんて考え方もありそうです。全対最短経路計算のアルゴリズムで、フロイド・ワーシャル(Floyd-Warshall)法ってのがあるそう。ただ、これはアルゴリズム理解できていないし実装もできていないので当面見送り…。
- 作者: George T. Heineman,Gary Pollice,Stanley Selkow,黒川利明,黒川洋
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/04/26
- メディア: 単行本(ソフトカバー)
- 購入: 11人 クリック: 656回
- この商品を含むブログ (72件) を見る