---
title: Netfilter と BPF/XDP
url: https://doc.liz6.com/ja/linux-kernel/06-network-subsystem/03-netfilter-and-bpf-xdp
locale: ja
area: linux-kernel
tags:
- linux-kernel
- network-subsystem
date: 2026-06-30
modified: 2026-07-16
description: 'カバー範囲: Netfilterフック → iptables/nftables → conntrack → NAT/マスカレード → XDP → BPF/cBPF/eBPF → TC BPF / カーネルバージョン: 2.6 ~ 6.x'
---

# Netfilter と BPF/XDP

> カバー範囲: Netfilterフック → iptables/nftables → conntrack → NAT/マスカレード → XDP → BPF/cBPF/eBPF → TC BPF
> カーネルバージョン: 2.6 ~ 6.x

## 概要

Netfilter は Linux のパケットフィルタリング/変更エンジンであり、iptables（旧）および nftables（新）の基盤を提供します。XDP/eBPF は、より新しいパラダイムを表しており、カーネルの最も早い受信ポイント（NICドライバ層）でユーザー提供プログラムを実行し、高性能なパケット処理を実現します。

## Netfilterフック

```c
// include/uapi/linux/netfilter.h
// 5つのフックポイント（IPv4を例とする）:

enum nf_inet_hooks {
    NF_INET_PRE_ROUTING,   // パケット到着時、ルーティング前
    NF_INET_LOCAL_IN,      // 本体宛のパケット、ルーティング後
    NF_INET_FORWARD,       // フォワードされるパケット
    NF_INET_LOCAL_OUT,     // 本体から送信されるパケット、ルーティング前
    NF_INET_POST_ROUTING,  // 送信される全パケット、ルーティング後
};

// 各フックポイント: 登録されたフック関数が優先度順に呼び出される
// 戻り値:
//   NF_ACCEPT:  パケット通過（正常）
//   NF_DROP:    破棄（送信者に通知しない）
//   NF_STOLEN:  パケットがフックによって奪われる
//   NF_QUEUE:   パケットをユーザー空間キューに追加（nfnetlink_queue）
```

### iptables（旧、xtablesベース）

```c
// net/ipv4/netfilter/ip_tables.c
// filterテーブル（デフォルト）:
//   INPUT:   本体宛のパケット
//   OUTPUT:  本体から送信されるパケット
//   FORWARD: フォワードされるパケット

// natテーブル:
//   PREROUTING  （DNAT）
//   INPUT       （本体宛DNAT）
//   OUTPUT      （本体宛DNAT）
//   POSTROUTING （SNAT/MASQUERADE）

// mangleテーブル: TOS/TTL/MARKの変更
// rawテーブル:    NOTRACK（conntrackをスキップ）
```

### nftables（新、iptablesの代替）

```c
// net/netfilter/nf_tables_api.c
// nftはルールを実行するために仮想マシンを使用する（iptablesの線形マッチングではない）
// より柔軟: set, map, concatenationをネイティブサポート
// より高速: 複数テーブルの複数回走査に代わり、ルールを1回だけ走査

// nft list ruleset
// table inet filter {
//     chain input { type filter hook input priority 0; policy drop;
//         ct state established,related accept
//         iif lo accept
//         tcp dport 22 accept
//     }
// }
```

## 接続追跡（conntrack）

```c
// net/netfilter/nf_conntrack_core.c
// conntrackは各接続（フロー）の状態を追跡する
//   → NATはこれに依存する（戻りパケットがどのフローに属するかを知るため）
//   → iptablesのstateマッチはこれに依存する

// conntrackテーブル:
//   各接続に1つのnf_conn → ハッシュテーブル
//   最大エントリ数: /proc/sys/net/netfilter/nf_conntrack_max
//   タイムアウト: プロトコルごとに独立したタイムアウト（TCP: ESTABLISHEDで432000秒 ≈ 5日）

// 注意! NATゲートウェイでは、conntrackテーブルがいっぱいになる可能性がある
//   → パケットドロップ → 新規接続の失敗
//   → nf_conntrack_maxを増やすか、タイムアウトを短くする
```

## NAT / MASQUERADE

```
SNAT（ソースNAT）:
  ソースIP:portを出口IP:新しいportに変更
  conntrack記録: orig_src:port → reply_dst:port → 返信パケットの逆変換

MASQUERADE:
  動的SNAT — 出口インターフェースの現在のIPを自動で使用
  適している場面: DHCPクライアント（出口IPが変化する）

DNAT（宛先NAT）:
  宛先IP:portを内部サーバーに変更
  → ポートフォワーディング
```

## XDP: eXpress Data Path

```c
// net/core/filter.c + drivers/net/*_xdp.c
// XDP: NICドライバのNAPI poll内、sk_buff割り当て前にBPFプログラムを実行
//   非常に早い処理ポイント → 極めて高いPPS（Mppsレベル）
//   可能な操作: DROP（最速）、TX（転送）、PASS（プロトコルスタックへ）、REDIRECT（別NICへ）

// BPFプログラムの戻り値:
enum xdp_action {
    XDP_DROP,       // 破棄（DDoSフィルタリングなど）
    XDP_PASS,       // プロトコルスタックへ渡す（通常フロー）
    XDP_TX,         // このNICから送信（ヘアピン）
    XDP_REDIRECT,   // 別のNICまたはCPUへリダイレクト
};

// ローディング: bpftoolまたはip link set dev eth0 xdp obj prog.o sec xdp経由
```

## eBPFプログラムタイプ

| 種類 | フックポイント | 用途 |
|------|---------|------|
| XDP | NICドライバ（最も早期） | DDoSフィルタリング、ロードバランシング |
| TC（トラフィックコントロール） | qdisc（ingress/egress） | ファイアウォール、ポリシールーティング |
| cgroup skb | cgroupソケット | コンテナネットワークポリシー（Cilium） |
| socket filter | ソケット作成時 | SO_ATTACH_BPF |
| kprobe/tracepoint | カーネル関数エントリ/tracepoint | 観測性 |

## 参考

- **ソースコード**: `net/netfilter/`, `net/core/filter.c`, `kernel/bpf/`
- **カーネルドキュメント**: `Documentation/networking/filter.rst`, `Documentation/bpf/`
- **LWN**: 「XDP and the packet processing revolution」

*キーワード: netfilter, iptables, nftables, conntrack, NAT, XDP, BPF, eBPF, TC BPF*
