Trema/MyRoutingSwitch(5), Topology Change and Re-route(4)

はじめに

引き続き前回の続きということで、arp table が実際にホストが接続されている位置を表すように固定した上で、これまで見えてきたリンクダウンに伴うフロー再書換の不具合が解決するかどうかを確認してみます。

変更

packet-in が起きて arp table update しようとするときに in_port をチェックして endpoint port かどうかを確認します。

  • MyRoutingSwitch
  def update_arp_table dpid, packet_in
    endpoint_ports = @topology.switch_endpoint
    if endpoint_ports[dpid] and not endpoint_ports[dpid].include?(packet_in.in_port)
      warn "[MyRoutingSwitch::update_arp_table] not endpoint link"
    else
      # if endpoint_ports[dpid] is nil,
      # then switch:dpid is single(stand alone).
      if packet_in.arp?
        @arp_table.update dpid, packet_in.in_port, packet_in.arp_spa, packet_in.arp_sha
      elsif packet_in.ipv4?
        @arp_table.update dpid, packet_in.in_port, packet_in.ipv4_saddr, packet_in.macsa
      end
    end

    # @arp_table.dump
  end

注意が必要なのは、単一スイッチ(スイッチ間リンクを持たないスタンドアロンスイッチ)の場合。実装上、lldp の packet-in でスイッチ間リンク(ポート)を検出して、それ以外のポートを endpoint port と判断しているため、スイッチ間リンクがない(endpoint_ports がない)場合は素直に in_port を使っておく必要があります。

テスト1

リンクダウン後の状態(Step.3)だけ。

  • 経路検索
[MyRoutingSwitch::handle_ipv4]
[MyRoutingSwitch::update_arp_table] not endpoint link
IPv4: dpid:3, port:3, 192.168.0.2->192.168.0.1
[get_path], start:1, goal:4
(略)
flow_mod: dpid:4/port:1 -> dpid:3
flow_mod: dpid:3/port:1 -> dpid:5
flow_mod: dpid:5/port:2 -> dpid:2
flow_mod: dpid:2/port:3 -> dpid:1
  • 状態
##
## 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=0x5, duration=24.619s, table=0, n_packets=10, n_bytes=640, 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=118.303s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop
cookie=0x6, duration=19.383s, 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=118.303s, 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.869s, 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=0x6, duration=19.631s, 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=118.525s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop
cookie=0x2, duration=118.525s, 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.122s, 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.89s, 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=118.74s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop
cookie=0x2, duration=118.74s, 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=0x6, duration=20.139s, table=0, n_packets=10, n_bytes=640, 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=118.958s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop
cookie=0x5, duration=25.369s, 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=118.958s, 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.718s, 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.483s, 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=119.279s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop
cookie=0x2, duration=119.279s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop

リンクダウン後の host1-host2 間通信によって、end-to-end でフローエントリが書き換えられていることがわかります。

テスト2

これも host1-host2 通信〜リンクダウン〜host3-host1 通信を行った最終状態(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
192.168.0.1,1,192.168.0.3,1,5,250
## 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=0x5, duration=33.749s, table=0, n_packets=10, n_bytes=640, 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=92.29s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop
cookie=0x7, duration=6.044s, table=0, n_packets=4, n_bytes=256, priority=65535,ip,dl_dst=00:00:00:01:00:01,nw_dst=192.168.0.1 actions=output:1
cookie=0x2, duration=92.29s, 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=28.747s, 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=92.509s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop
cookie=0x2, duration=92.509s, 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.266s, 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.008s, 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=92.733s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop
cookie=0x2, duration=92.733s, 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=0x6, duration=29.267s, table=0, n_packets=10, n_bytes=640, 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=92.948s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop
cookie=0x5, duration=34.514s, 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=92.948s, 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=34.755s, 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=0x4, duration=29.501s, 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=93.157s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop
cookie=0x2, duration=93.157s, 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=35.017s, 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=0x4, duration=7.313s, 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=0x1, duration=93.38s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=169.254.0.0/16 actions=drop
cookie=0x2, duration=93.38s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=224.0.0.0/24 actions=drop

host3→host1 のフローエントリは

で、host3-host1 は sw6-sw1 になっています。ちゃんと最短経路を通って host3→host1 のパケットも受信できていることがわかります。

おわりに

arp table が endpoint port のみで更新されるように変更することで、arp table の情報と実際のホストの接続位置が食い違うことがなくなります。食い違いがなくなることで、リンクダウンによる局所的なトポロジ計算にはまり込むことなく、end-to-end で経路の再計算を行えるようになります。

次回はもうちょっと複雑なパターンでのテストと、トポロジ変更に対する経路の再設定に関してのその他の課題について。