SNMPでLLDP情報を拾ってくる

何をしたいのか

inet-henge に入力するLLDP情報をSNMPで拾いたい

GitHub - codeout/inet-henge: Generate d3.js based Network Diagram from JSON data.

LLDP-MIB

LLDP-MIBを使うとLLDP情報を拾ってこれる。

www.mibdepot.com

inet-hengeに使う情報は ホスト名ポート名対向ホスト名対向ポート名があれば十分そう。

これらに対応するMIBシンボルは次の通り。

パラメータ MIBシンボル
ホスト名 LLDP-MIB::lldpLocSysName
ポート名 LLDP-MIB::lldpLocPortDesc
対向ホスト名 LLDP-MIB::lldpRemSysName
対向ポート名 LLDP-MIB::lldpRemPortDesc

動作確認

トポロジはこんな感じで f:id:dos1506:20190408221554p:plain

snmpwalkでRouter1とRouter2からLLDP情報を取得してみる

Router1

LLDP-MIB::lldpLocSysName.0 = STRING: Router1
LLDP-MIB::lldpLocPortDesc.1 = STRING: GigabitEthernet0/0
LLDP-MIB::lldpLocPortDesc.2 = STRING: GigabitEthernet0/1
LLDP-MIB::lldpLocPortDesc.3 = STRING: GigabitEthernet0/2
LLDP-MIB::lldpLocPortDesc.4 = STRING: GigabitEthernet0/3
LLDP-MIB::lldpRemSysName.0.2.2 = STRING: Router2
LLDP-MIB::lldpRemSysName.0.3.3 = STRING: Switch1-1
LLDP-MIB::lldpRemSysName.0.4.4 = STRING: Switch1-2
LLDP-MIB::lldpRemPortDesc.0.2.2 = STRING: GigabitEthernet0/1
LLDP-MIB::lldpRemPortDesc.0.3.3 = STRING: GigabitEthernet0/0
LLDP-MIB::lldpRemPortDesc.0.4.4 = STRING: GigabitEthernet0/0

Router2

LLDP-MIB::lldpLocSysName.0 = STRING: Router2
LLDP-MIB::lldpLocPortDesc.1 = STRING: GigabitEthernet0/0
LLDP-MIB::lldpLocPortDesc.2 = STRING: GigabitEthernet0/1
LLDP-MIB::lldpLocPortDesc.3 = STRING: GigabitEthernet0/2
LLDP-MIB::lldpLocPortDesc.4 = STRING: GigabitEthernet0/3
LLDP-MIB::lldpRemSysName.0.2.1 = STRING: Router1
LLDP-MIB::lldpRemSysName.0.3.2 = STRING: Switch2-1
LLDP-MIB::lldpRemSysName.0.4.3 = STRING: Switch2-2
LLDP-MIB::lldpRemPortDesc.0.2.1 = STRING: GigabitEthernet0/1
LLDP-MIB::lldpRemPortDesc.0.3.2 = STRING: GigabitEthernet0/0
LLDP-MIB::lldpRemPortDesc.0.4.3 = STRING: GigabitEthernet0/0

それぞれのフォーマットについて

ポート名は lldpLocPortDesc.<ifindex>
対向ホスト名は lldpRemSysName.x.<ifindex>.x
対向ポート名は lldpRemPortDesc.x.<ifindex>.x

inet-henge用のデータ整形

LLDP-MIB::lldpLocPortDescでifindexが把握できる。 ifindexが分かれば、そこから対向ホスト名、対向ポート名が紐付けられるので、、、いい感じにやる。

LLDP情報を定期的にDBに [ホスト名, ポート名, 対向ホスト名, 対向ポート名] という形で保存しておけばinet-hengeに突っ込む用のデータとしては十分かなと思う。

Cumulus Linux の Prescriptive Topology Manager で配線を検証する

Cumulus Linux では Prescriptive Topology Manager という機能が提供されている。

Prescriptive Topology Manager - PTM - Cumulus Linux 3.7 - Cumulus Networks

これは LLDP の情報を使用して配線情報を検証してくれるというもの。

実際に Cumulus VX と GNS3 で検証してみる。 目的のトポロジはこんな感じ。

f:id:dos1506:20190329225952p:plain  

まず、正しい配線情報を/etc/ptmd/topology.dotに記述する。

graph G {
        "spine-1":"swp3" -- "leaf-1":"swp1"
        "spine-1":"swp4" -- "leaf-2":"swp1"
        "spine-1":"swp5" -- "leaf-3":"swp1"
        "spine-2":"swp3" -- "leaf-1":"swp2"
        "spine-2":"swp4" -- "leaf-2":"swp2"
        "spine-2":"swp5" -- "leaf-3":"swp2"
}

ptmdを再起動する。これは設定ファイルを書き換えるたび必要になる。

systemctl restart ptmd

これで準備は整ったので、あとは配線をしていく。

まず1本目をつないでみる。spine-1 の swp3 と leaf-1 の swp1 を結線。

f:id:dos1506:20190329234259p:plain

つないだらptmctlで検証結果を確認。

cumulus@spine-1:~$ ptmctl
-----------------------------------------
port  cbl     BFD     BFD   BFD    BFD
      status  status  peer  local  type
-----------------------------------------
swp3  pass    N/A     N/A   N/A    N/A
swp4  N/A     N/A     N/A   N/A    N/A
swp5  N/A     N/A     N/A   N/A    N/A

topology.dot に定義した内容と LLDP の情報が合致しているため、passと出ている。

では間違った配線をするとどうなるかを見てみる。 spine-1 の swp4 に leaf-2 の swp2 を接続する。(正しい接続は spine-1:swp4 <-> leaf-2:swp1) f:id:dos1506:20190329234807p:plain

ptmctlを実行。

cumulus@spine-1:~$ ptmctl
-----------------------------------------
port  cbl     BFD     BFD   BFD    BFD
      status  status  peer  local  type
-----------------------------------------
swp3  pass    N/A     N/A   N/A    N/A
swp4  fail    N/A     N/A   N/A    N/A
swp5  N/A     N/A     N/A   N/A    N/A

swp4 において fail と表示されている。これは LLDP 情報が topology.dot と一致しないため。

ちなみに /var/log/ptmd.log にもいろいろ出てたりする。 接続が正しいとき

2019-03-29T14:42:45.645249+00:00 spine-1 ptmd[2647]: Port swp3 correctly matched  with remote leaf-1.swp1

接続が誤っているとき

2019-03-29T14:47:45.831388+00:00 spine-1 ptmd[2647]: Port swp4 NOT matched with remote - Expected [leaf-2.swp1] != [leaf-2.swp2]

全部つないだところでのテストは以下の通り。topology.dotはすべてのホストで同じファイルが使い回せるのでいちいち書き換える必要はない。 それぞれのホストは自分のホスト名が存在するテスト項目のみ検証を行っていく。

spine-1

cumulus@spine-1:~$ ptmctl
-----------------------------------------
port  cbl     BFD     BFD   BFD    BFD
      status  status  peer  local  type
-----------------------------------------
swp3  pass    N/A     N/A   N/A    N/A
swp4  pass    N/A     N/A   N/A    N/A
swp5  pass    N/A     N/A   N/A    N/A

spine-2

cumulus@spine-2:~$ ptmctl
-----------------------------------------
port  cbl     BFD     BFD   BFD    BFD
      status  status  peer  local  type
-----------------------------------------
swp3  pass    N/A     N/A   N/A    N/A
swp4  pass    N/A     N/A   N/A    N/A
swp5  pass    N/A     N/A   N/A    N/A

leaf-1

cumulus@leaf-1:~$ ptmctl
-----------------------------------------
port  cbl     BFD     BFD   BFD    BFD
      status  status  peer  local  type
-----------------------------------------
swp1  pass    N/A     N/A   N/A    N/A
swp2  pass    N/A     N/A   N/A    N/A

leaf-2

cumulus@leaf-2:~$ ptmctl
-----------------------------------------
port  cbl     BFD     BFD   BFD    BFD
      status  status  peer  local  type
-----------------------------------------
swp1  pass    N/A     N/A   N/A    N/A
swp2  pass    N/A     N/A   N/A    N/A

leaf-3

cumulus@leaf-3:~$ ptmctl
-----------------------------------------
port  cbl     BFD     BFD   BFD    BFD
      status  status  peer  local  type
-----------------------------------------
swp1  pass    N/A     N/A   N/A    N/A
swp2  pass    N/A     N/A   N/A    N/A

実際にどんな場面で使うのか?

結線して LLDP 情報を受け取ったら即テストが走って配線情報を検証してくれるので、構築時などには役立つと思う。

ESXiのvmnic番号と物理ポートのマッピングとか間違えやすいし...

ちなみにESXiはvCenterがないと標準スイッチでCDPしかしゃべれないけど、Cumulus Linuxで使用している lldpd は CDP にも対応しているので大丈夫(だと思う...)。