CIDR /31 と /32 を実運用で使う:RFC 3021・point-to-point リンク・host-only ルートの背景
CIDR の解説では「/31 は 0.0.0.0/0 の特殊なケース」「/32 はホスト 1 台」と片付けられがちですが、実運用の routing table には両方が頻出します。本記事では「なぜ /31 がそもそも存在するのか」「/32 をルーティング側でどう扱うか」を、RFC と実装の両面から掘り下げます。
出発点:「/31 は使えない」という古い説明
伝統的な IP サブネット理論では、サブネットには ネットワークアドレス(先頭) と ブロードキャストアドレス(末尾) が予約されます。
/30のサブネット(4 アドレス)は先頭・末尾を引いて使用可能ホストが 2 台/31のサブネット(2 アドレス)は先頭・末尾を引くと 使えるアドレスが 0
そのため「/31 は意味がない」とする教科書が多くあります。これは RFC 3021 (2000) で明示的に修正されました。
RFC 3021:point-to-point リンクで /31 を許可
RFC 3021 は、point-to-point リンク(2 端だけを接続するルータ間リンク)では「ネットワーク・ブロードキャスト」の概念が無意味であるとし、/31 の両端を共にホストとして使ってよいと規定しました。
192.0.2.0/31 ← 0 番と 1 番をルータ A・B のインタフェースに割り当てる | アドレス | 伝統的解釈 | RFC 3021 解釈 |
|---|---|---|
192.0.2.0 | ネットワーク | ホスト(ルータ A) |
192.0.2.1 | ブロードキャスト | ホスト(ルータ B) |
/31 を使う動機
ISP やデータセンター内では、ルータ間リンクが大量に存在します。1 リンクあたり 4 アドレス(/30)使うか、2 アドレス(/31)使うかで、IPv4 アドレスの消費量が半分になります。BGP ピアリング・MPLS バックボーン・ファブリック内 link で標準的。
ただし両端のルータが RFC 3021 をサポートしていないと使えません。Cisco IOS は 12.2 以降、Juniper・Linux も対応済みですが、古い L3 スイッチで /31 を設定すると弾かれることがあります。
/32:ホスト 1 つを表す経路
/32 はサブネットマスクが全 1(255.255.255.255)で、1 つの IP アドレスだけを指す経路。
用途 1:loopback アドレス
ルータの loopback(仮想インタフェース)は伝統的に /32 で割り当てます:
ip address 192.0.2.1/32 → loopback0 物理インタフェースの状態と独立した「ルータ自身を指す安定した IP」が必要なとき。OSPF / BGP の router-id、SNMP の管理 IP、syslog 送信元など。
用途 2:ホスト経路(host route)
routing table に「特定の IP だけを別の hop に送る」エントリを書く場合、prefix は /32 になります:
ip route 198.51.100.5/32 via 10.0.0.1 - 特定のサーバへのトラフィックを専用 LB 経由にしたい
- BGP で特定アドレスだけ別経路を広告したい(anycast、DDoS 緩和の hole-punching など)
用途 3:コンテナ・コンテナ network
Kubernetes の Pod IP や Docker の bridge では、Pod 1 つに /32 のホスト経路を打つ実装が多くあります。
ip route add 10.244.1.5/32 dev veth-podX 物理 NIC の subnet と独立に、コンテナ単位で routing できる仕組み。Calico や Cilium が採用している方式です。
/32 経路の罠:longest prefix match と ARP
ホスト経路は longest prefix match によって、より大きな prefix(/24 など)に優先します:
10.0.0.0/24 via 10.0.0.1 ← ゲートウェイ経由
10.0.0.5/32 via 10.0.0.99 ← 例外的に別 hop 10.0.0.5 への送信は /32 のエントリが一致するので 10.0.0.99 経由になります。一方、ARP は L2 の世界なので /32 経路と関係なく、broadcast で MAC を解決します。
Linux の “promiscuous ARP” / proxy ARP
Pod IP のような /32 ホスト経路をホストに広告するには、host が自分宛て以外の ARP に応答する設定が必要です:
sysctl net.ipv4.conf.all.arp_filter=0
sysctl net.ipv4.conf.all.arp_announce=0 設定が間違うと「Pod IP に ping は通るが ARP がタイムアウトする」「同じ subnet の別 Pod に到達できない」など、L3 と L2 の食い違いが発生します。
IPv6 では:/127 と /128
IPv6 にも対応する仕様があります:
/127(RFC 6164): IPv4 の /31 相当。point-to-point リンクで両端を使う/128: IPv4 の /32 相当。ホスト 1 つを指す
IPv6 のアドレス空間は実用上無限なので「アドレス節約」の動機は弱いですが、ルータ間リンクで Neighbor Discovery のオーバーヘッドを減らすために /127 を使う運用があります(RFC 6164 §5.1)。
設計時のチェックリスト
- ルータ間 link で IPv4 アドレスを節約したい →
/31(両端のスイッチ・ルータが RFC 3021 対応か確認) - ルータの loopback / 管理アドレス →
/32 - 特定ホストだけ別経路にしたい →
/32host route(longest prefix match で優先される) - コンテナ・Pod の IP →
/32(CNI 実装が打つ) - IPv6 の point-to-point →
/127+ 必要なら/128host route - L3 では
/32経路を打ったが L2 が解決しない → proxy ARP・arp_filter設定を確認
まとめ
/31 は RFC 3021 で「point-to-point ではネットワーク・ブロードキャストは不要」と決まり、現在は ISP・DC ネットワークの標準的な選択肢。/32 はループバック・ホスト経路・コンテナ network の基本要素で、routing table での longest prefix match と ARP/NDP の挙動を両方意識する必要があります。CIDR 計算ツールで「使えるホスト 0」と表示される /31 は、表示はそうでも実運用では正しく 2 端のホストを表すと理解しておくと、ルーティングテーブルが読めるようになります。
CIDR の prefix とサブネットマスク、利用可能ホスト数の確認は CIDR 計算ツール で行えます。