はじめに
Linuxサーバは日々、大量のネットワーク通信を処理しています。Webサーバへのアクセス、SSHによるリモートログイン、データベースとの通信など、あらゆるネットワーク処理はLinuxカーネルによって管理されています。
しかし、多くのエンジニアはIPアドレス設定やルーティング設定を行う機会はあっても、Linuxカーネル内部でどのように通信が処理されているのかを学ぶ機会はあまりありません。
本記事では、Linuxカーネルがどのようにネットワーク通信を管理しているのかを、TCP/IPスタックやソケット、NICドライバなどの仕組みを交えながら解説します。
Linuxにおけるネットワーク通信の仕組み
Linuxカーネルは、CPU管理やメモリ管理だけでなく、ネットワーク通信の管理も担当しています。例えば、WebブラウザがWebサーバへアクセスするとき、アプリケーションは直接ネットワークカード(NIC)を操作しているわけではありません。アプリケーションはLinuxカーネルへ通信要求を渡し、実際のネットワーク処理はカーネルが担当します。
Linuxでは、アプリケーションが動作するユーザー空間と、カーネルが動作するカーネル空間が分離されています。LinuxカーネルにはTCP/IPスタックと呼ばれるネットワーク通信機能が実装されています。TCP/IPスタックとは、TCPやIPなどのプロトコルを実装し、ネットワーク通信を実現する仕組みです。
主な構成は以下の通りです。
- Socket Layer
- TCP/UDP Layer
- IP Layer
- Device Driver Layer
アプリケーションがデータを送信すると、データはこれらのレイヤを順番に通過してネットワークへ送信されます。データ受信は逆の流れとなります。
送受信時の流れは以下のようになります。仮想サーバを使っている場合はDriver以下のレイヤが異なりますが、大きな流れは同じです。

Linuxカーネルはこれらのレイヤを管理し、アプリケーションとネットワーク機器の橋渡しを行っています。それぞれのレイヤの役割を説明していきます。
ソケットレイヤ
Linuxにおいて、アプリケーションとネットワークの橋渡しを行う仕組みがソケットです。ソケットはアプリケーションがネットワーク通信を行うためのインターフェースであり、多くのプログラムはソケットAPIを利用して通信を実現しています。
代表的なシステムコールには以下があります。
| システムコール | 主な用途 | サーバ側/クライアント側 | 説明 |
|---|---|---|---|
socket() | ソケット作成 | 両方 | 通信の入口となるソケットを作成する |
bind() | アドレス割当 | 主にサーバ側 | IPアドレスやポート番号をソケットへ関連付ける |
listen() | 接続待受 | サーバ側 | ソケットを接続待ち状態にする |
accept() | 接続受付 | サーバ側 | クライアントからの接続を受け付ける |
connect() | 接続要求 | クライアント側 | サーバへ接続要求を送信する |
例えばWebサーバは listen() によって待ち受け状態となり、accept() によってクライアントからの接続を受け付けます。Linuxカーネルはソケットごとに通信状態を管理しており、ポート番号や接続先アドレス、送受信バッファなどの情報を保持しています。TCPでは接続状態(LISTEN、ESTABLISHEDなど)、UDPでは通信に必要なソケット情報を管理しています。
現在のソケット状態は ss -tulnp コマンドで確認できます。オプションは以下の通りです。
-t:TCP
-u:UDP
-l:LISTEN/待受のみ
-n:名前解決しない
-p:プロセス表示
ss -tulnp コマンドの結果をサンプルで記載します。Linuxカーネルが管理しているソケットの一覧を表示しており、どのプロセスがどのポートで通信を待ち受けているかを確認できます
[root@ ~]# ss -tulnp
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 127.0.0.1:323 0.0.0.0:* users:(("chronyd",pid=610,fd=5))
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=958261,fd=3))
tcp LISTEN 0 511 *:443 *:* users:(("httpd",pid=3491698,fd=8),("httpd",pid=3491483,fd=8),("httpd",pid=3491480,fd=8),("httpd",pid=3491479,fd=8),("httpd",pid=845637,fd=8))TCP/IPレイヤ
TCPは信頼性の高い通信を実現するためのプロトコルです。LinuxカーネルはTCP通信において、再送制御、フロー制御、輻輳制御、順序保証などを提供しています。
TCP接続は複数の状態を持っています。代表的な状態は以下の通りです。
- LISTEN:サーバが接続待ちをしている状態
- SYN_SENT:クライアントが接続要求を送った状態
- ESTABLISHED:接続が確立し、データ通信が可能な状態
- FIN_WAIT:接続を終了しようとしている状態
- TIME_WAIT:接続終了後、しばらく待機する状態
TCPコネクション確立、TCPコネクション終了における状態遷移は以下の通りです。

これらの状態は ss -tan コマンドで確認できます。
-t:TCP
-a:すべてのソケットを表示(LISTENを含む)
-n:名前解決しない
また、IPは通信相手までパケットを届けるためのプロトコルであり、ルーティングやIPアドレスによる配送を担当します。
[root@ ~]# ss -ant
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
CLOSE-WAIT 1 0 127.0.0.1:36816 127.0.0.1:8080
ESTAB 0 0 127.0.0.1:5432 127.0.0.1:60876NICドライバと仮想NICドライバ
TCP/IPレイヤで生成されたパケットは、そのままネットワークへ送信されるわけではありません。実際にはNICドライバまたは仮想NICドライバを経由してネットワークデバイスへ受け渡されます。
ドライバはLinuxカーネルとネットワークデバイスを仲介するソフトウェアです。LinuxカーネルはNICごとのハードウェア仕様を直接扱うのではなく、NICドライバを介して共通のインターフェースでデバイスを操作します。
物理サーバでは以下のようなNICドライバが利用されます。だいたいのNICドライバは各Linuxディストリビューションに標準搭載されていて、搭載されているサーバのNICによってドライバが決まってきます。
・ixgbe:Intelの10GbE NIC向けドライバ
・i40e:Intel Ethernet 700シリーズ向けドライバ
・bnxt_en:Broadcom NetXtreme-Eシリーズ向けドライバ
・e1000e:Intelの1GbE NIC向けドライバ
一方、仮想環境では仮想NICドライバが利用されます。
virtio_net:VirtIO規格の仮想NICドライバ。KVM、Nutanix AHV、OpenStackで使用。
vmxnet3:VMwareが提供する準仮想化NICドライバ。VMware ESXiで使用。
e1000:Intel E1000 NICをエミュレートした互換性重視のドライバ。VirtualBox、VMwareで使用。
hv_netvsc:Hyper-V向けの仮想NICドライバ。Microsoft Hyper-V、Azureで使用。
ethtoolコマンドを使うことでドライバの種類を確認することができます。以下VirtualBoxの環境では、e1000 を使っていることが分かります。
[root@ ~]# ethtool -i enp0s3
driver: e1000
version: 5.14.0-570.12.1.el9_6.x86_64
firmware-version:
expansion-rom-version:
bus-info: 0000:00:03.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: no
[root@localhost ~]#
ドライバの主な役割は以下の通りです。
- 送信キュー(TX Queue)の管理
- 受信キュー(RX Queue)の管理
- NICへのデータ受け渡し
- 割り込み処理
- DMA設定
- オフロード機能の利用
仮想スイッチ
仮想化環境では、仮想NICの先に仮想スイッチが存在します。
仮想スイッチは物理スイッチと同様にL2スイッチとして動作し、仮想マシン間や外部ネットワークとの通信を中継します。
代表的な仮想スイッチには以下があります。
- Linux Bridge : Linuxカーネル標準の仮想スイッチ。
- Open vSwitch(OVS): 高機能な仮想スイッチ。Nutanix AHV、OpenStack、Kubernetesで使われる。
- VMware Standard vSwitch : VMware ESXiホスト内で利用される基本的な仮想スイッチ。
- VMware Distributed Switch: 複数のVMware ESXiホストを一元管理できる仮想スイッチ。vCenterサーバによって管理される。
仮想スイッチは主に以下の役割を担います。
| 機能 | 説明 |
|---|---|
| MACアドレス学習 | 「このMACアドレスはどのポートにつながっているか」を自動で覚える機能です。通信するたびに学習し、不要なブロードキャストを減らします。 |
| フレーム転送 | 学習したMACアドレステーブルを参照し、受信したイーサネットフレームを適切なポートへ転送します。宛先が分からない場合はフラッディングします。 |
| VLAN制御 | VLANタグを使ってネットワークを論理的に分離する機能です。同じ仮想スイッチ上でも、異なるVLAN同士は基本的に通信できません。 |
| ポート管理 | VMのvNICを接続するポートを管理する機能です。ポートの作成・削除や、ポートごとの設定(VLAN、セキュリティなど)を行います。 |
| QoS制御 | 通信帯域や優先度を制御する機能です。特定のVMが帯域を使いすぎないよう制限したり、重要な通信を優先したりできます。 |
例えば同一ホスト上に存在する2台の仮想マシンが通信する場合、以下の通り通信は物理NICを経由せず仮想スイッチ内で完結することがあります。そのため、仮想環境の通信トラブルでは物理ネットワークだけでなく、仮想スイッチの状態確認も重要になります。

物理NICと仮想NIC
NIC(Network Interface Card)は、サーバをネットワークへ接続するためのデバイスです。物理サーバではPCIeスロットに搭載された物理NICが利用されます。Linuxでは以下のようなインターフェース名として認識されます。
[root@localhost ~]# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether 08:00:27:92:22:b8 brd ff:ff:ff:ff:ff:ff
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether 08:00:27:54:0c:a9 brd ff:ff:ff:ff:ff:ff
[root@localhost ~]#仮想環境では物理NICの代わりに仮想NICが利用されます。仮想NICはハイパーバイザーが提供する仮想的なネットワークデバイスであり、ゲストOSからは通常のNICとして認識されます。例えばKVM環境ではvirtio-net、VMware環境ではvmxnet3が広く利用されています。
近年のNICやNICドライバは単なる通信デバイスではなく、多くの処理をハードウェア側で実行しています。代表的な機能は以下の通りです。
| 機能 | 概要 | 目的 |
|---|---|---|
| Checksum Offload | TCP/UDP/IPのチェックサム計算をNICが実行する。 | CPU負荷を削減する。 |
| TSO (TCP Segmentation Offload) | OSから受け取った大きなTCPデータを、NICがMTUサイズごとに分割して送信する。 | パケット分割処理のCPU負荷を削減する。 |
| LRO (Large Receive Offload) RSC (Receive Segment Coalescing) | 複数の受信パケットをNIC側でまとめてOSへ渡す。 | 受信処理回数を減らしCPU負荷を削減する。 |
| RSS (Receive Side Scaling) | 受信パケットを複数の受信キューへ分散し、複数CPUで並列処理できるようにする。 | マルチコア環境で受信性能を向上させる。 |
| DMA転送 (Direct Memory Access) | NICがCPUを介さずメモリとの間でデータを直接転送する。 | CPU負荷を削減し、高速にデータを転送する。 |
これらの機能によってCPU負荷を削減し、高速なネットワーク通信を実現しています。Linuxでネットワークトラブルを調査する際は、TCP/IPスタックだけでなく、ドライバ、仮想スイッチ、NICまで含めて確認することが重要です。
まとめ
Linuxのネットワーク通信は、アプリケーションがソケットを通じて通信要求を行い、LinuxカーネルのTCP/IPスタックが通信を制御し、NICドライバやNICを経由してネットワークへ送受信される仕組みになっています。仮想環境では、さらに仮想NICや仮想スイッチが通信経路に加わります。
ネットワーク障害の調査では、IPアドレスやルーティング設定だけでなく、ソケットの状態、TCPコネクション、NICドライバ、仮想スイッチ、NICのオフロード機能など、多くの要素を確認することが重要です。Linuxカーネルがネットワーク通信をどのように管理しているかを理解しておくことで、障害発生時の切り分けや原因特定をより効率的に行えるようになります。
本記事で紹介した内容は、Linuxネットワークの基本的な仕組みです。これらを理解したうえで、NAPI、SoftIRQ、RSS、ソケットバッファ、TCPチューニングなどの仕組みを学ぶことで、Linuxネットワークをより深く理解できるようになるでしょう。


コメント