ぶていのログでぶログ

思い出したが吉日

Neighbor Discovery Protocol(NDP)を受け取ってBIRDの設定ファイルを生成するndppを作った

BIRDとNDPを使ってBGP Unnumbered構成を行うためにndppというのを作った。 作ったと書いたが実は5月くらいにはできていて、いまさらブログで書いている…。

github.com

動機

GoBGP*1とFRRouting*2ではBGP Unnumberedがサポートされているようなのだが、BIRDではBGP Unnumberedはサポートされていない。 が、それはBIRDがルーターのリンクローカルアドレスを取得できない*3というだけだったので、それを補助するツールを作ることにした。

なお、BIRDではなくGoBGPやFRRoutingを使えっていう指摘はノーサンキュー…

使い方

https://github.com/buty4649/ndpp/releases/tag/v1.0.0 からndppをダウンロードして、テキトーな位置に配置し実行する。 実行時にNDPを投げたいNIC名を指定する。 以下はeth0を指定した場合の実行例。

$ export IFACE=eth0
$ sudo ./ndpp $IFACE
- local:
    addr: fe80::xxxx:xxxx:xxxx:xxxx
    interface: eth0
    lladdr: xx:xx:xx:xx:xx:xx
  router:
    addr: fe80::yyyy:yyyy:yyyy:yyyy
    addr_with_zone: fe80::yyyy:yyyy:yyyy:yyyy%eth0
    lladdr: yy:yy:yy:yy:yy:yy

ルーターがRouterAdvertisement(RA)に応答する設定になっていれば上記のような出力になるはず。 そして、以下のように -T bird オプションを追加するとBIRD向けの設定ファイルが生成される。

$ export IFACE=eth0
$ sudo ./ndpp -T bird $IFACE
define eth0_neighbor_address = fe80::xxxx:xxxx:xxxx:xxxx;
define eth0_local_address = fe80::yyyy:yyyy:yyyy:yyyy;
define eth0_lladdr = hex:yy:yy:yy:yy:yy:yy;

#
# The following is a sample configuration. Please uncomment to use.
#
#define remote_asn = <Please set remote ASN>;
#define local_asn = <Please set local ASN>;
#
#protocol radv {
#  interface "eth0" {
#    custom option type 1 value eth0_lladdr;
#  };
#}
#protocol bgp eth0 {
#  neighbor eth0_neighbor_address as remote_asn;
#  interface "eth0";
#  local as local_asn;
#  ipv4 { extended next hop; import all; export all; };
#  ipv6 { import all; export all; };
#}

この出力をテキトーなファイルに保存し、コメントアウト部分を外してbird.confからincludeすれば動くはず。

出力形式の変更

-Tオプションを指定すると出力形式を変更できる。 現バージョンでサポートされているフォーマットは以下の4つ。

  • yaml (デフォルト)
  • json
  • bird
  • shellvar

NDP取得後に任意のコマンドを実行する

-cオプションを指定すると任意のコマンドを取得できる。 コマンドには、-T shellvarな出力内容が標準入力に注入される。 コマンドは標準入力経由でそれを受け取り任意の処理をする想定。 今のところユースケースは思いつかないが(え?)、面白そうなので機能を追加した。

ndppの仕組み

ndppは前述のとおりNDPを使っている。 NDPではICMPv6を使ったいくつかの機能を提供しているが、ndppでは以下の2つを使っている。

  • Router Solicitation(RS)
  • Router Advertisement(RA)

端末がRSをブロードキャストすると、ルーターが応答としてRAを返信するという感じ。 Goにおいてはmdlayher/ndpというライブラリがあるのでこれを使うとシュッと実装できる。

おわりに

BIRDでBGP Unnumberedを扱うためにndppを作った。 本当は自宅サーバ環境で、EdgeRouterとUbuntuをBGP Unumberedでピアリングしたらブログにするつもりだったのだが、当分実現しそうにないのでまずはndppだけ記事にしたのだった。