LLDP でトポロジー検出

topology_discovery が LLDP でトポロジー検出を行う仕組みをみてみます。topology_discovery は LLDP メッセージを作り、packet_out でスイッチへと送ります。スイッチから出力された LLDP は隣接するスイッチに届き、packet_in でコントローラへと戻ってきます。これらの動作を通してコントローラ(topology_discovery)はスイッチ間のリンクを検出します。

ネットワークエミュレータ機能を使って、LLDP パケットの中身を見てみましょう。

$ ./trema run -c ../apps/routing_switch/routing_switch_fullmesh.conf -d
$ sudo tshark -i trema4-0 -x
Capturing on trema4-0
  0.000000 12:ce:dd:4d:27:92 -> LLDP_Multicast LLDP 60 Chassis Id = 0xe0 Port Id = 2 TTL = 180 

0000  01 80 c2 00 00 0e 12 ce dd 4d 27 92 88 cc 02 05   .........M'.....
0010  07 30 78 65 30 04 02 07 32 06 02 00 b4 00 00 a5   .0xe0...2.......
0020  a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5   ................
0030  a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5               ............

  0.520852 1e:0c:5f:16:fc:e5 -> LLDP_Multicast LLDP 60 Chassis Id = 0xe1 Port Id = 3 TTL = 180 

0000  01 80 c2 00 00 0e 1e 0c 5f 16 fc e5 88 cc 02 05   ........_.......
0010  07 30 78 65 31 04 02 07 33 06 02 00 b4 00 00 a5   .0xe1...3.......
0020  a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5   ................
0030  a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5               ............

LLDP の Chassis ID としてスイッチの Datapath ID である 0xe0 が、また Port ID として 2 が入っています。これはコントローラが packet_out する際に、そのスイッチ・ポートの ID を格納しています。packet_in する際には受信したスイッチの Datapath ID とポート番号が分かりますので、これらの情報からリンク情報を生成します。生成されたリンク情報は、topology_service_interface.h にて以下のように定義されている構造体に格納されます。

// link status
// length is specified in callback function
typedef struct topology_link_status {
  uint64_t from_dpid;
  uint64_t to_dpid;
  uint16_t from_portno;
  uint16_t to_portno;
  uint8_t status;
  uint8_t pad[ 3 ];
} __attribute__( ( packed ) ) topology_link_status;

この LLDP を用いたトポロジー検出は、他の OpenFlow コントローラでも一般的に広く使われている仕組みです。