Linuxパケット処理のためのXDPとeBPF
14分で読めます - 2026年5月27日
XDPとeBPFがNICドライバレベルで毎秒数百万のパケットをどのように処理するか。ベンチマーク、DDoSユースケース、ツールチェーンのセットアップ、ハードウェア要件。
高性能パケット処理のためのXDPとeBPF
XDP(eXpress Data Path)およびeBPF(extended Berkeley Packet Filter)は、Linuxがカーネルの通常のネットワークスタックが関与する前にネットワークパケットを処理することを可能にします。XDPは、着信するパケットごとにメモリ構造体を割り当てる代わりに、NICドライバの段階でトラフィックをインターセプトし、その処理方法を決定して、ドロップ、転送、またはリダイレクトを行います。 その結果、コアあたり毎秒数百万パケットの処理が可能となり、従来のツール(例: iptables.
eBPFとXDPの連携
eBPFは、Linuxカーネル内部の仮想マシンです。安全性が検証された(無限ループや不正なメモリアクセスがない)カスタムバイトコードを実行し、それをJITコンパイルしてネイティブのCPU命令に変換します。プログラムのスコープは制限されています。任意のカーネル関数を呼び出すことはできず、マップの検索やパケットのリダイレクトといったタスクのための、あらかじめ定義されたヘルパー関数のセットのみを使用できます。
状態管理のために、eBPFはマップを使用します。これは、パケットの到着を超えて状態が保持されるキー/バリューストア(ハッシュテーブル、配列、LPMトライ)です。マップはユーザー空間から読み書き可能であるため、プログラムを再読み込みすることなく、ブロックリストやルーティングルールを更新できます。
XDPはeBPFのフックポイントです。これは、カーネルが sk_buff 構造体(従来のネットワークスタックが依存する、パケットあたり200~300バイトのメタデータオブジェクト)を割り当てる前の段階で、NICドライバの受信パスにアタッチされます。この割り当てをスキップすることで、パフォーマンスの向上が実現されます。
XDPには3つのモードがあります:
- ネイティブモード:NICドライバ内部で実行されます。最高のパフォーマンスを発揮します。
- オフロードモード:NICのASIC上で実行されます。CPUを完全に解放します。
- 汎用モード:
sk_buff実行されます。非対応ハードウェアでのテストに有用ですが、パフォーマンス上の利点はありません。
各パケットの処理後、XDPプログラムは判定結果を返します:
| 判定 | 判定 |
|---|---|
XDP_DROP | ドライバレベルでパケットを破棄 |
XDP_PASS | 通常のネットワークスタックへ転送 |
XDP_TX | 同じインターフェースから送信し直す |
XDP_REDIRECT | 別のNICまたはAF_XDPユーザースペースソケットにリダイレクトする |
XDP_ABORTED | プログラムエラーにより破棄し、トレースイベントをログに記録する |
XDP 対 iptables:パフォーマンスベンチマーク
その数値は明白です。 iptables 1コアあたり秒間約20万パケットを処理します。 nftables は、これを約 400,000 pps まで向上させます。ネイティブモードの XDP は、同じハードウェア上で 1 コアあたり 1,000 万から 4,000 万 pps を処理します。
その理由は単純です。 XDP_DROP には、1回の境界チェックと戻り値の処理が必要です。一方、 iptables DROP には sk_buff メモリの割り当て、netfilterチェーンのトラバーサル、接続追跡のルックアップ、DROPアクション自体、そしてメモリの解放が必要です。64バイトのパケットで100 Gbpsの場合、サーバーは1秒あたり1億4800万パケットを処理することになり、パケットあたり約100ナノ秒しか残りません。この規模では、 sk_buff メモリの割り当てがボトルネックとなります。
CPU負荷の軽減も同様に顕著です。あるベンチマークでは、ブロックリストを iptables XDPに移行した結果、100万パケット/秒(pps)において、ソフトウェア割り込みによるCPU使用率が28%から3%に低下しました。これにより解放されたリソースを活用し、同じサーバー上でアプリケーションプロセス、データベース、または仮想マシンを実行することが可能になります。
DDoS対策とセキュリティ
XDPのホスティングにおける最大の活用事例は、DDoS対策です。ドライバーレベルで動作するため、悪意のあるパケットはカーネルのネットワークスタックに到達する前に破棄されます。XDPを実行する単一のコアで、1秒あたり2,600万パケットを破棄することが可能です。
Cloudflareは、少なくとも2018年から、L4Dropと呼ばれるXDPベースのシステムをボリューム型DDoS対策に活用しています。このシステムはXDPコンテキスト内で攻撃トラフィックを処理・破棄し、アプリケーション層に到達するのを防ぎます。MetaのオープンソースXDPレイヤー4ロードバランサーであるKatranは、コアあたり1,000万パケット/秒を超える速度でFacebookおよびInstagramのトラフィックを処理しています。
動的フィルタリングについては、次のようなeBPFマップが BPF_MAP_TYPE_LPM_TRIE を使用することで、個々のIPアドレスやCIDRサブネットを網羅するIPブロックリストを単一のルックアップで管理できます。更新はユーザースペースからリアルタイムで行われ、プログラムの再読み込みは不要です。攻撃が進行中である場合でも、 bpftool:
bpftool map update id <MAP_ID> key <KEY_VALUE> value <VALUE>可観測性については、eBPFがカーネルデータパスから直接、アプリケーション別、IP別、フロー別のメトリクスを収集します。 xdp_md コンテキストは、次のようなテレメトリを提供します ingress_ifindex や rx_queue_indexなどのテレメトリを提供するため、どのインターフェースやキューに負荷がかかっているかを特定できます。長期的な監視には、 ebpf_exporter などのツールが、生のeBPFマップデータをPrometheus互換のメトリクスに変換し、Grafanaでの可視化を可能にします。
ツール、導入、およびハードウェア要件
ツールチェーンは、制限付きCをeBPFバイトコードにコンパイルするためのClangとLLVMから始まります。そこから、ローダーライブラリが必要となります:
libbpf: 実運用向けの標準Cライブラリ。カーネル間移植性を実現するCO-RE(Compile Once, Run Everywhere)をサポートしています。libxdp: XDP専用。単一のインターフェース上で複数のXDPプログラムを実行することをサポートします。cilium/ebpf: Goベースのスタック向けの純粋なGoライブラリ。
管理用には、 bpftool 実行中のプログラムやマップの内容を検査できます。 xdp-loader ( xdp-tools スイート)はロードとアンロードを処理します。BCCはPython/Luaフロントエンドを用いたプロトタイピングに有用ですが、 libbpf 本番環境では CO-RE の方が適しています。
デプロイ前にBPF JITコンパイラを有効にしてください:
sysctl -w net.core.bpf_jit_enable=1ダウンタイムゼロの更新を行うには、 XDP_FLAGS_REPLACE フラグを使用して、実行中のプログラムをアトミックにスワップしてください。マップを /sys/fs/bpf/ に固定して、ローダー終了後もマップが保持されるようにします。
ハードウェアおよびカーネルの互換性
XDPはカーネル4.8で導入されましたが、全機能を利用するには5.x以降が推奨されます。 uname -r を使用してカーネルを確認し、BPFファイルシステムが /sys/fs/bpf/.
利用可能な XDP 機能は、お使いの NIC ドライバによって決まります:
| ドライバ | 基本 XDP | リダイレクト | ゼロコピー (AF_XDP) |
|---|---|---|---|
mlx5_core | はい | はい | はい |
i40e | はい | はい | はい |
ixgbe | はい | はい | はい |
virtio_net | はい | はい | いいえ |
ena (Amazon) | はい | はい | いいえ |
ドライバーを確認するには ethtool -i <interface>。ネイティブモードがサポートされていない場合、システムはジェネリックモードにフォールバックします。ジェネリックモードは sk_buff 割り当て後に実行され、パフォーマンス上の利点はありません。
XDPプログラムをアタッチする前に、GROとLROを無効にしてください。これらは競合するためです:
ethtool -K <iface> gro off lro off標準の XDP では、パケットが 4,096 バイトのメモリページ 1 ページに収まる必要があります。 i40e および ice ドライバーでは、x86のMTU制限は3,046バイトです。
XDPの始め方
まずは環境の評価から始めます。 uname -r を実行してカーネルが 4.8 以上(5.x が推奨)であることを確認し、 ethtool -i <interface> を実行してネイティブ XDP ドライバーのサポートを確認してください。
まずは「監視」から始め、強制適用は後回しにしてください。eBPFマップを使用してトラフィックを分類・集計し、通常のアクティビティのベースラインを確立します。トラフィックパターンを把握したら、強制適用に移行します。 xdpgeneric モードでテストし、本番環境では xdpdrv (ネイティブ) モードに切り替えて本番環境での運用を開始します。
XDP は生帯域幅ではなく、パケットレベルのフィルタリングを処理することを念頭に置いてください。100 Gbps 規模の大規模な攻撃に対しては、ベアメタルインフラストラクチャおよび BGP FlowSpec と組み合わせて、サーバーに到達する前にアップストリームトラフィックを管理してください。
高速なパケットフィルタリングを必要とする高トラフィックなワークロードを実行している場合、FDCの専用サーバーは、XDPの性能を最大限に引き出すためのベアメタル基盤を提供します。
Linuxパケット処理のためのXDPとeBPF
XDPとeBPFがNICドライバレベルで毎秒数百万のパケットをどのように処理するか。ベンチマーク、DDoSユースケース、ツールチェーンのセットアップ、ハードウェア要件。
14分で読めます - 2026年5月27日
パワフルで無制限のVPSが重要な理由
3分で読めます - 2025年5月9日

ご質問またはカスタムソリューションが必要ですか?
柔軟なオプション
グローバル・リーチ
即時展開
柔軟なオプション
グローバル・リーチ
即時展開