Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Cybozu Lab Youth 12th Enigamict

Enigamict
March 31, 2023
48

Cybozu Lab Youth 12th Enigamict

Enigamict

March 31, 2023
Tweet

Transcript

  1. サイボウズラボユース 成果発表会
    第12期 髙田 敦生

    View Slide

  2. 自己紹介
    ● Twitter & GitHub (@Enigamict)
    ● 好きな事
    ○ Network
    ■ Routing Protocol(BGP etc…)やLinux Network
    ■ Segment Routing Mobile Network eBPF etc…

    View Slide

  3. 作ったもの
    ● Linux上で動作するルーティングソフトウェア
    ○ 名前: neburaといいます
    ○ 言語: Go + c (cgo)
    ○ link: https://github.com/Enigamict/nebura
    ● 開発中...

    View Slide

  4. Agenda
    ● 作ったもの紹介
    ○ ルーティングソフトウェアとは
    ○ 代表的なソフトウェア紹介
    ○ 設計と実装の話
    ○ 簡単な使い方
    ● 今後の展開とまとめ

    View Slide

  5. 経路について & Routing Protocolとは
    ● TCP/IPのインターネット上で、ユーザーが目的のネットワークにたどり着くためにはその宛先に関す
    る情報をルーティングテーブルに追加して通信をする事が可能になります。
    ○ 宛先に関する情報は経路情報と呼ばれます。
    ○ 経路情報は一般的にIPv4 address IPv6 addressなどでやりとりが行われます。(例外もある)
    ● Routing Protocolは経路情報を自動的に処理し、経路情報の交換を円滑にするために作ら
    れた通信プロトコルになります。

    View Slide

  6. ルーティングソフトウェアとは
    ● ネットワーク上の経路に関する操作及び表示や Routing Protocolのサポートを行う事が可能なソフ
    トウェア
    ● 各Routing ProtocolやCLIからの経路追加、及び削除や細かい経路に関する命令を処理し、適用させる事が目的で
    す。
    BGP OSPF IS-IS CLI
    ルーティングソフトウェア(経路の追加 削除...etc)
    経路の追加 & 削除

    View Slide

  7. 紹介
    ● FRRouting
    ○ Linux上で動くルーティングプロトコルスイート
    ○ BGPやOSPF、様々なルーティングプロトコルをサポート
    ○ FRRouting上ではLinux上で経路情報を追加するための、ルーティングソフトウェアが動いている
    ● Zebra
    ○ FRRを支えているルーティングソフトウェア
    ○ 歴史あるソフトウェア
    ○ これが作りたい

    View Slide

  8. 設計と実装
    ● Linux上でルーティングソフトウェアを実現するためには、BGPやCLIからの経路情報を確認するた
    めの通信手段(プロセス間通信)と経路に関する情報を保管するDBのようなもの(RIB)
    そしてLinux Kernelに経路情報を操作するような命令(Netlink)が必要です。
    BGP OSPF IS-IS CLI
    Routing Software(RIB & msg decode)
    経路情報
    Kernel
    経路情報の追加 削除

    View Slide

  9. 設計と実装
    ● メッセージ交換の通信の手法として、 unixドメインソケットという方法を使用します。
    ○ 各プロセスがソケットを通じてメッセージのやり取りを行い、 ZebraではRouting Software側を
    Zserverと呼び、命令を出す側をZclientと呼びます
    ○ unix ドメイン間のメッセージ交換は単純なバイナリデータで通信を行います。
    BGP
    OSPF
    IS-IS
    CLI

    Routing Software
    unix domain send msg
    [0x01 0x01 0x01 0x01 ….]
    socket
    unix domain recv msg
    [0x01 0x01 0x01 0x01 ….]

    View Slide

  10. 設計と実装
    ● 各Routing Protocolの経路情報を受け取った場合、まだ経路情報として登録はしないが仮状
    態で蓄積する経路情報のDBをRIBといいます
    ○ Routing Softwareの機能としてその経路を自由に参照する事が出来たり、確認したりす
    る事が可能である機能が必要になります。
    BGP
    OSPF
    IS-IS
    CLI

    Routing Software
    route info
    Route Add
    BGP: 1.1.1.1/32 via ….
    OSPF 192.168.0.1/24 via …
    BGP RIB
    BGP: 1.1.1.1/32 via ….
    OSPF RIB
    OSPF 192.168.0.1/24 via …

    View Slide

  11. 設計と実装
    ● 経路テーブルに該当する経路を登録したい場合、 Linux kernelに対して「この経路を追加する」という命令
    が必要になります。
    ○ Netlinkはユーザー空間とカーネル空間のやりとりを行う事が出来る Linux kernelのサブシステムと
    して存在しており、対応したメッセージを送信する事で Kernelに対し、経路の操作を行う事が出来ま
    す。
    ○ Netlinkに関する記事: https://eniyo0.hatenablog.com/entry/2022/11/23/180135
    Routing Software
    BGP: 1.1.1.1/32…
    Linux Kernel
    Netlink msg
    0240: 00 00 00 00 00 00 00 00 2c 00 00 00 18 00 01 06
    0250: 00 00 00 00 00 00 00 00 02 20 00 00 fe 03 00 01
    0260: 00 00 00 00 08 00 01 00 01 01 01 01 08 00 05 00
    0270: 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00

    View Slide

  12. 設計と実装
    ● Server側の実装
    ○ メッセージをdecodeしたり、クライアントを受け付けるためのイベント駆動型の実装は
    Zebraの実装を元にGoで
    簡易な実装。
    ○ Clientの受け付け(msgの受信とparse)またメッセージの送信を行う処理を
    Main Threadにし、Sub Threadは
    Clientに対してメッセージの送受信をServer側のコアな処理として機能しています。
    ○ NeburaはGoroutineを使用してMain Threadの処理をClientの受付、msgのparseとし、Sub Threadは実際
    に受け取ったデータを元にNetlink msgの送信を行います。
    Zebra(Server) process
    main thread
    void zserv_event() {
    case accept
    }
    sub thread
    voidzserv_client_event
    () {
    case read
    ….
    }
    Nebura(Server) process
    main thread
    for{
    n.lis.Accept()
    n.MsgRead()
    ….
    }
    fn MsgRead() {
    go n.ClientSendEvent()
    }
    sub thread
    ClientSendEvent() {
    for{
    select {
    case e := <-n.ceventChan:
    }
    }
    }

    View Slide

  13. 設計と実装
    ● Client側の実装
    ○ Client側の実装としては、unix domain socketによる接続を行いGoのInterfaceの実装を生かしたメッセージ
    の作成を行っています。
    ○ Bodyをメッセージを書き込むInterfaceとして定義し、各ヘッダーが持つ構造体ごとの
    writeTo()を作成する事で
    設計しやすく、違いを持てるようにしています。
    Nebura(Client) process
    type Body interface {
    writeTo() ([]byte, error)
    }
    type ApiHeader struct {
    Len uint16
    Type uint8
    Body Body
    }
    func (api *ApiHeader) writeTo()
    func (n *NclientRouteAdd)
    writeTo()


    sendNclientAPI() {
    api := &ApiHeader{

    Body: body,
    }
    buf, _ := api.writeTo()
    }

    View Slide

  14. 設計と実装
    ● Server側の処理
    ○ 以下の経路情報の登録を Netlinkを通じて可能にしています。 (cgoで実装)
    ■ IPv4 IPv6 prefix (IPv6は未完成)
    ■ Segment Routing(Single sidのみ)
    ■ Segment Routing end action(END.DX4)
    ○ 遅延など発生させる事が出来る TraficContorolの実装も行っています。 (cgo)
    ■ TC netem
    ○ またeBPFの仕様を利用した特別なパケット処理を行う事が出来る機能をメッセージを通じて登録出
    来るようにしました。 (GoのNetlink lib & eBPF lib)
    ■ XDP
    ○ Zebraとの通信も可能です。 (FRRなら8.1以上ならおそらく動くはず ...)
    ■ SendHello(Zebraに対してHello msgを送信し、経路元がどこから来ているかを判別してくれる)
    ■ RouteAdd(経路の追加(IPv4のみ)、細かい調整は出来ていません ...)

    View Slide

  15. 簡単に動かしてみる
    ● GoBGPからの経路を実際に登録
    ○ BGP peer up
    ○ 経路を受け取れる状態にする
    仮BGP
    10.0.0.1/24
    GoBGP
    10.0.0.2/24
    2023/03/27 03:15:09 BGP State: Conect
    2023/03/27 03:15:09 BGP Peer Listen...
    2023/03/27 03:15:09 Listen addr 10.0.0.2...
    2023/03/27 03:15:09 BGP State: Active
    2023/03/27 03:15:09 BGP Open Recv...
    2023/03/27 03:15:09 BGP KeepAlive Recv...
    2023/03/27 03:15:09 State Estab...
    Nebura
    Zebra

    View Slide

  16. 簡単に動かしてみる
    ● GoBGPからの経路を実際に登録
    ○ BGP UPDATE MSG
    ○ 経路情報を受け取って、 Neburaにメッセージを送信
    仮BGP
    10.0.0.1/24
    GoBGP
    10.0.0.2/24
    023/03/27 03:24:52 Nebura Conect...
    2023/03/27 03:24:52 Send buf [0 14 2 32 1 1 1
    8 24 10 0 0 2 0]...
    Nebura
    Zebra

    View Slide

  17. Nebura hdr
    ● Len(2byte uint16) + Type code(1byte uint8)のシンプルなヘッダー構造
    ○ Nserver側で受け取るとLenの長さから全体のヘッダーの長さを取得
    ○ Type codeはNclientからの命令で、Typeを読み取って処理を行う
    Len(2byte) Type(1byte) Data hdr…
    Type code : 0x01(IPv4)
    : 0x02(IPv6)
    ….

    View Slide

  18. 簡単に動かしてみる
    ● GoBGPからの経路を実際に登録
    ○ Nebura clientの受け付け
    ○ Clientごとにメッセージを処理する
    仮BGP
    10.0.0.1/24
    Nebura(Server)
    2023/03/27 03:24:45 Nebura Server start...
    2023/03/27 03:24:52 Nebura Accept...
    2023/03/27 03:25:31 Msg Read...

    View Slide

  19. 簡単に動かしてみる
    ● GoBGPからの経路を実際に登録
    ○ Nebura msgの処理とNetlink msgの送信
    ○ メッセージのTypeによって駆動する。Netlinkメッセージを送信
    仮BGP
    10.0.0.1/24
    Nebura(Server)
    RIB SHOW
    BGP: 1.1.1.8/32 via 10.0.0.2
    0000: 3c 00 00 00 18 00 05 05 …
    0010: 02 20 00 00 fe ba 00 01 …
    0020: 01 01 01 08 08 00 05 00 …
    0030: 65 00 00 00 08 00 0f 00 …
    0, Success
    func (n NservMsgSend) NecliEvent(ns *Nserver)
    error {
    switch n.api.Type {
    case IPv4RouteAdd:
    NetlinkSendRouteAdd(n.data)
    case IPv6RouteAdd:
    NetlinkSendIPv6RouteAdd(n.data)
    …..
    )}

    View Slide

  20. 今後の展開とまとめ
    ● 細かい経路情報の処理や未完成の部分を完成させる。
    ○ 所々の実装はまだ完璧ではない
    ...
    ● GoBGPなどといったOSSを使用して、本格的なRouting Softwareとして機能させる。
    ○ 仮BGPの検証ではなく、大きなソフトウェアとの連携を行う事で機能改善を行う
    ● 機能面の強化
    ○ 監視機能や可視化機能などを実装する
    ○ もっと面白い事を募集...

    View Slide

  21. まとめ
    ● 私は一年間ラボユース研究生として活動し、得られたものはとても多かった。
    ○ コードの読み方書き方をプロから教えてもらえる
    ■ コードに対する考え方が変わり、コードの書き方から読み方を意識するようになっ
    た。また難しいOSSのコードが読めるようになったりした。
    ○ 自分の希望で最初はCSの基礎から教えてもらった
    ■ データ構造などをみっちり教えてもらった
    (asmなどもいっぱい読んだ)
    ■ スレッドプログラミングにどっぷりハマった
    ● 非同期ランタイムに興味を持った
    ● 特にプロに教えてもらうmemory orderingの勉強はとても楽しかった。
    ○ 低レイヤはとっても楽しい
    ○ 最初から作りたいソフトウェアを作るのではなくて、作るまでの過程のサポートも行ってく
    れる。
    光成さん、本当にありがとうございました。

    View Slide

  22. END

    View Slide