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

XDPを利用したエッジデバイスでのネットワーク制御

Tomoya Amachi
November 13, 2020

 XDPを利用したエッジデバイスでのネットワーク制御

Tomoya Amachi

November 13, 2020
Tweet

More Decks by Tomoya Amachi

Other Decks in Technology

Transcript

  1. XDPを利用したエッジデバイスでのネットワーク制御
    @tomoyamachi

    View Slide

  2. 背景
    ネットワークが不安定なエッジデバイスで、
    アプリケーションごとのネットワーク制御を必要とせず
    通信を行いたい。
    Vehicle
    edge
    Vehicle
    edge
    Cloud
    4G Wi-Fi

    View Slide

  3. 現在のアーキテクチャ
    ● Transparent Proxy
    ○ すべてのリクエストを制御する
    ■ 接続可能なネットワークインタフェース制御
    ■ リクエストのバッファリング
    ■ 設定時間以上バッファリングした場合、リクエストデータを保存
    ○ 外部から動的に設定の変更が可能
    ● Manager Process
    ○ iptablesの変更
    ○ デフォルトで動作する DNS resolver停止
    ○ 不通時のみ固定値を返却する DNS resolver
    ○ 非同期でリクエスト送付

    View Slide

  4. 動作例1 : リクエストのバッファリング
    Offline
    1
    manager proxy
    3. Buffers request
    data
    app
    1. Returns a
    dummy IP
    2. Requests data
    Recover
    2
    manager envoy
    1. Check real ip
    app
    2. Request to target
    server
    3. Return response
    data

    View Slide

  5. 動作例2 : 非同期でのリクエスト管理
    request情報のハッシュ値を元に
    同一リクエストかを判断

    View Slide

  6. 課題
    ● 既存の手法(iptables)の場合、ネットワーク制御の管理が煩雑
    ○ ネットワークの状態などに応じて、動的に制御を行いたい
    ○ iptablesのデバッグが難しく、原因特定が難しい
    要求機能
    ● ネットワークがない状況での名前解決は、ローカルマシン上で行う
    ● すべてのパケットリクエストを、ローカルマシンで動作する透過プロキシのポートへ
    集約する
    ● 透過プロキシが動作するポートからのリクエストのみ、外部へのリクエストを許可す

    View Slide

  7. 今回の解決策
    ● XDPを利用することにより、
    エッジデバイスでもパケット制御をプログラマブルに
    行うことができるのではないか。
    ● 先行事例
    ○ Cilium : Kubernetesで動作するプロキシ。パケット制御を eBPF&XDPを利用して行う。

    View Slide

  8. XDPとは
    ● ネットワークインタフェースをカーネルレベルでプログラマブルに記述
    ● C言語のプログラムをeBPFバイトコードにコンパイルできる
    ● eBPFバイトコードを、ユーザランドからそのままロードできる
    https://medium.com/@fntlnz/load-xdp-programs-using-the-ip-iproute2-command-502043898263

    View Slide

  9. XDPプログラム
    #define KBUILD_MODNAME "filter"
    #include
    #include
    #include
    #include
    #include
    // DNS resolverをポート54で動かす
    int dnsredirect (struct xdp_md *ctx) {
    void *data = (void *)(long)ctx->data;
    void *data_end = (void *)(long)ctx->data_end;
    struct ethhdr *eth = data;
    if ((void*)eth + sizeof(*eth) > data_end) {
    return XDP_PASS;
    }
    struct iphdr *ip = data + sizeof(*eth);
    if ((void*)ip + sizeof(*ip) > data_end) {
    return XDP_PASS;
    }
    if (ip->protocol == IPPROTO_UDP) {
    struct udphdr *udp = (void*)ip + sizeof(*ip);
    if ((void*)udp + sizeof(*udp) <= data_end) {
    if (udp->dest == ntohs(53)) {
    udp->dest = ntohs(54);
    } else if (udp->source == ntohs(54)) {
    udp->source = ntohs(53);
    }
    }
    }
    return XDP_PASS;
    }
    eBPF
    バイトコード
    生成
    verifier (検証)
    BPF XDP
    Kernel Land
    User Land
    名前解決をport 54で行う

    View Slide

  10. 結果
    ● ネットワークがない状況での名前解決は、ローカルマシン上で行う
    ● すべてのパケットリクエストを、ローカルマシンで動作する透過プロキシのポートへ
    集約する
    ● 透過プロキシが動作するポートからのリクエストのみ、外部へのリクエストを許可す

    動作確認済
    動作確認済
    動作確認済

    View Slide

  11. 評価
    ● 元々の目的である、iptablesによる制御の複雑度は下げることができた。
    ○ コードを元に、直感的に経路を把握できる
    ○ パケット制御する関数を動的に変更できるので、ルールセットの定義が容易
    ● 原理的にiptablesよりも高速に動作するので、性能試験なども行いたい
    ● 成熟段階の技術のため、今後より成熟していけばコントロールできる部分が増えて
    いくと予想される
    ● 実際にプロダクトに取り込む場合は、今後のロードマップを確認しながら取り入れた
    ほうがよい。

    View Slide

  12. 今後したいこと
    ● 実装した結果、利用できる関数も充実しており、
    ユーザランドでの制御が困難な操作も行えるため、透過Proxy機能をXDPで実装
    する手法を検討して実装したい
    ○ パケットの解析を行い、リクエスト先に応じて利用する NICを変更する
    ○ 名前解決をXDP内の制御のみで完結させる
    ● eBPFバイトコードをControl Planeから
    配信する形式で動作できるかチェック

    View Slide

  13. 参照
    A practical introduction to XDP
    https://linuxplumbersconf.org/event/2/contributions/71/attachments/17/9/presentati
    on-lpc2018-xdp-tutorial.pdf
    The eXpress Data Path
    https://github.com/tohojo/xdp-paper/blob/master/xdp-the-express-data-path.pdf

    View Slide