CIDR /31 と /32 を実運用で使う:RFC 3021・point-to-point リンク・host-only ルートの背景

約8分

CIDR の解説では「/310.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
  • 特定ホストだけ別経路にしたい → /32 host route(longest prefix match で優先される)
  • コンテナ・Pod の IP → /32(CNI 実装が打つ)
  • IPv6 の point-to-point → /127 + 必要なら /128 host route
  • L3 では /32 経路を打ったが L2 が解決しない → proxy ARParp_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 計算ツール で行えます。