feat: 가상화 문서들 추가

This commit is contained in:
DongHyeonka
2026-09-10 08:54:05 +09:00
parent e9f6a93327
commit 43e1aadef0
695 changed files with 153404 additions and 12754 deletions
@@ -0,0 +1,43 @@
# control/setup path 는 QEMU 를 지나고 data path 는 backend 에 따라 QEMU 를 지나기도 안 지나기도 한다
## Alternative text
위쪽 줄은 virsh, libvirt, QEMU, virtio-net Device Model 로 이어지는 control/setup path 이고 아래쪽 줄은 Physical NIC 에서 TAP 까지 이어지는 data path 다. 두 줄이 vhost-net 과 QEMU virtio backend 에서 만나 virtqueue 를 지나 Guest 로 모이는 구성도.
## Long description
왼쪽에서 오른쪽으로 읽는다. 위쪽 줄이 control/setup path 다. virsh 에서 libvirt 와 QEMU 를 지나 virtio-net Device Model 에 닿고, 그 device model 이 virtual NIC 생성과 feature negotiation, virtqueue 설정, vhost-net backend 설정을 맡는다. 아래쪽 줄이 data path 다. Physical NIC 에서 Physical NIC Driver 와 Linux Bridge, TAP 까지 온다. 두 줄은 네 번째 열 다음에서 만난다. device model 은 점선으로 backend 둘을 설정하고, TAP 은 실선으로 그 둘 가운데 실제로 쓰는 쪽에 packet 을 넘긴다. vhost-net 을 쓰면 packet 은 Host Kernel 안에서 처리돼 QEMU 사용자 공간을 지나지 않고, QEMU virtio backend 를 쓰면 같은 packet 이 QEMU 사용자 공간을 지난다. 어느 쪽이든 virtqueue 에서 만나 Guest 로 올라간다. 이 Host 가 둘 중 어느 backend 를 쓰고 있는지는 그림이 말하지 않는다.
## Elements and evidence
- **virsh** (cli): VM/network 관리 CLI. packet datapath 에는 직접 참여하지 않는다. Evidence: L5662L5662, L5687L5689.
- **libvirt** (service): VM lifecycle 과 NIC/network configuration 을 관리한다. Evidence: L5663L5663, L5691L5691.
- **QEMU** (process): 실제로 실행되는 프로세스. 이 안에 virtio-net device model 이 있다. Evidence: L5666L5666, L5693L5693.
- **virtio-net Device Model** (service): control/setup path 가 닿는 자리. 장치를 만들고 backend 를 연결한다. Evidence: L5666L5666, L5695L5700.
- **Physical NIC** (hardware): 밖에서 온 packet 이 처음 닿는 하드웨어. Evidence: L5706L5708.
- **Physical NIC Driver** (driver): 그 하드웨어를 제어하는 Host kernel driver. Evidence: L5674L5674, L5710L5710.
- **Linux Bridge /
Routing / NAT** (network): L2 software switch 와 L3 routing, 주소 변환이 놓이는 자리. Evidence: L5672L5673, L5712L5712.
- **TAP** (network): VM 의 Ethernet frame 과 Host Linux networking 을 잇는 접점. Evidence: L5671L5671, L5714L5714.
- **vhost-net** (kernel): 반복되는 packet datapath 를 Host kernel 에서 처리하는 backend. Evidence: L5669L5669, L5716L5716.
- **QEMU virtio backend** (process): vhost-net 을 쓰지 않을 때 datapath backend 를 맡는 쪽. Evidence: L5668L5668, L5742L5742.
- **virtqueue** (queue): Guest 와 Host backend 가 I/O buffer 를 주고받는 descriptor 기반 공유 큐. Evidence: L5667L5667, L5718L5718.
- **Guest** (service): packet 이 올라가 애플리케이션 socket 에 닿는 쪽. Evidence: L5664L5665, L5720L5726.
## Relationships
- **Linux Bridge /
Routing / NAT → TAP:** Ethernet Frame. Evidence: L5671L5671, L5712L5714.
- **Physical NIC Driver → Linux Bridge /
Routing / NAT:** L2 forwarding. Evidence: L5672L5672, L5710L5712.
- **libvirt → QEMU:** NIC/network configuration. Evidence: L5663L5663, L5691L5693.
- **Physical NIC → Physical NIC Driver:** Ethernet Frame. Evidence: L5671L5671, L5708L5710.
- **QEMU virtio backend → virtqueue:** Data Path. Evidence: L5729L5729, L5742L5744.
- **QEMU → virtio-net Device Model:** QEMU process. Evidence: L5666L5666, L5693L5695.
- **virtio-net Device Model → QEMU virtio backend:** control. Evidence: L5668L5668, L5700L5700.
- **virtio-net Device Model → vhost-net:** vhost-net backend 설정. Evidence: L5700L5700, L5716L5716.
- **TAP → QEMU virtio backend:** data. Evidence: L5729L5729, L5740L5742.
- **TAP → vhost-net:** vhost-net 사용. Evidence: L5703L5703, L5714L5716.
- **vhost-net → virtqueue:** Data Path. Evidence: L5703L5703, L5716L5718.
- **virsh → libvirt:** Control / Setup. Evidence: L5662L5663, L5684L5691.
- **virtqueue → Guest:** virtio-net Frontend Driver. Evidence: L5664L5664, L5718L5726.
@@ -0,0 +1,52 @@
# control/setup path 는 QEMU 를 지나고 data path 는 backend 에 따라 QEMU 를 지나기도 안 지나기도 한다
# Question: 설정하는 경로와 packet 이 흐르는 경로는 어디에서 갈라지고, 그 두 갈래 가운데 어느 쪽이 QEMU 사용자 공간을 지나는가
direction: down
n0: "virsh" {
shape: rectangle
}
n1: "libvirt" {
shape: rectangle
}
n2: "QEMU" {
shape: rectangle
}
n3: "virtio-net Device Model" {
shape: rectangle
}
n4: "Physical NIC" {
shape: rectangle
}
n5: "Physical NIC Driver" {
shape: rectangle
}
n6: "Linux Bridge /\nRouting / NAT" {
shape: rectangle
}
n7: "TAP" {
shape: rectangle
}
n8: "vhost-net" {
shape: rectangle
}
n9: "QEMU virtio backend" {
shape: rectangle
}
n10: "virtqueue" {
shape: queue
}
n11: "Guest" {
shape: rectangle
}
n0 -> n1: "Control / Setup"
n1 -> n2: "NIC/network configuration"
n2 -> n3: "QEMU process"
n4 -> n5: "Ethernet Frame"
n5 -> n6: "L2 forwarding"
n6 -> n7: "Ethernet Frame"
n3 -> n8: "vhost-net backend 설정"
n3 -> n9
n7 -> n8: "vhost-net 사용"
n7 -> n9
n8 -> n10: "Data Path"
n9 -> n10: "Data Path"
n10 -> n11: "virtio-net Frontend Driver"
@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
<diagram id="packet-control-and-data-paths" name="control/setup path 는 QEMU 를 지나고 data path 는 backend 에 따라 QEMU 를 지나기도 안 지나기도 한다">
<mxGraphModel dx="680" dy="1296" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1296" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="n_virsh" value="virsh&lt;br/&gt;User" tooltip="VM/network 관리 CLI. packet datapath 에는 직접 참여하지 않는다. | Evidence: L5662-L5662, L5687-L5689" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="90.5" y="60.0" width="150.0" height="71.0" as="geometry"/>
</mxCell>
<mxCell id="n_physical-nic" value="Physical NIC" tooltip="밖에서 온 packet 이 처음 닿는 하드웨어. | Evidence: L5706-L5708" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="300.5" y="63.5" width="150.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="n_libvirt" value="libvirt" tooltip="VM lifecycle 과 NIC/network configuration 을 관리한다. | Evidence: L5663-L5663, L5691-L5691" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="82.0" y="227.0" width="150.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="n_physical-nic-driver" value="Physical NIC Driver" tooltip="그 하드웨어를 제어하는 Host kernel driver. | Evidence: L5674-L5674, L5710-L5710" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="292.0" y="227.0" width="167.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="n_qemu" value="QEMU&lt;br/&gt;Host Userspace" tooltip="실제로 실행되는 프로세스. 이 안에 virtio-net device model 이 있다. | Evidence: L5666-L5666, L5693-L5693" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="90.5" y="388.5" width="150.0" height="71.0" as="geometry"/>
</mxCell>
<mxCell id="n_linux-bridge" value="Linux Bridge /
Routing / NAT" tooltip="L2 software switch 와 L3 routing, 주소 변환이 놓이는 자리. | Evidence: L5672-L5673, L5712-L5712" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="300.5" y="387.0" width="150.0" height="74.0" as="geometry"/>
</mxCell>
<mxCell id="n_virtio-net-device-model" value="virtio-net Device Model&lt;br/&gt;virtual NIC 생성&lt;br/&gt;feature negotiation&lt;br/&gt;virtqueue 설정&lt;br/&gt;vhost-net backend 설정" tooltip="control/setup path 가 닿는 자리. 장치를 만들고 backend 를 연결한다. | Evidence: L5666-L5666, L5695-L5700" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
<mxGeometry x="70.0" y="557.0" width="174.0" height="142.0" as="geometry"/>
</mxCell>
<mxCell id="n_tap" value="TAP&lt;br/&gt;Host-side interface" tooltip="VM 의 Ethernet frame 과 Host Linux networking 을 잇는 접점. | Evidence: L5671-L5671, L5714-L5714" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="304.0" y="592.5" width="167.0" height="71.0" as="geometry"/>
</mxCell>
<mxCell id="n_qemu-virtio-backend" value="QEMU virtio backend&lt;br/&gt;QEMU Userspace" tooltip="vhost-net 을 쓰지 않을 때 datapath backend 를 맡는 쪽. | Evidence: L5668-L5668, L5742-L5742" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="82.0" y="795.0" width="167.0" height="71.0" as="geometry"/>
</mxCell>
<mxCell id="n_vhost-net" value="vhost-net&lt;br/&gt;Host Kernel" tooltip="반복되는 packet datapath 를 Host kernel 에서 처리하는 backend. | Evidence: L5669-L5669, L5716-L5716" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="309.0" y="795.0" width="150.0" height="71.0" as="geometry"/>
</mxCell>
<mxCell id="n_virtqueue" value="virtqueue&lt;br/&gt;shared queue" tooltip="Guest 와 Host backend 가 I/O buffer 를 주고받는 descriptor 기반 공유 큐. | Evidence: L5667-L5667, L5718-L5718" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="195.5" y="962.0" width="150.0" height="71.0" as="geometry"/>
</mxCell>
<mxCell id="n_guest" value="Guest&lt;br/&gt;virtio-net Frontend Driver&lt;br/&gt;Guest TCP/IP Stack&lt;br/&gt;Socket&lt;br/&gt;Keycloak" tooltip="packet 이 올라가 애플리케이션 socket 에 닿는 쪽. | Evidence: L5664-L5665, L5720-L5726" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="162.5" y="1129.0" width="216.0" height="122.0" as="geometry"/>
</mxCell>
<mxCell id="e_bridge-to-tap" value="Ethernet Frame" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_linux-bridge" target="n_tap">
<mxGeometry relative="1" as="geometry">
<mxPoint x="381.5" y="498.8" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_driver-to-bridge" value="L2 forwarding" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_physical-nic-driver" target="n_linux-bridge">
<mxGeometry relative="1" as="geometry">
<mxPoint x="399.5" y="339.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_libvirt-to-qemu" value="NIC/network configuration" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_libvirt" target="n_qemu">
<mxGeometry relative="1" as="geometry">
<mxPoint x="161.2" y="311.8" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_nic-to-driver" value="Ethernet Frame" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_physical-nic" target="n_physical-nic-driver">
<mxGeometry relative="1" as="geometry">
<mxPoint x="399.5" y="177.2" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_qemu-backend-to-virtqueue" value="Data Path" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_qemu-virtio-backend" target="n_virtqueue">
<mxGeometry relative="1" as="geometry">
<mxPoint x="213.5" y="886.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_qemu-to-device-model" value="QEMU process" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_qemu" target="n_virtio-net-device-model">
<mxGeometry relative="1" as="geometry">
<mxPoint x="161.2" y="480.2" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_setup-qemu-backend" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virtio-net-device-model" target="n_qemu-virtio-backend">
<mxGeometry relative="1" as="geometry">
<mxPoint x="152.2" y="719.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_setup-vhost-backend" value="vhost-net backend 설정" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virtio-net-device-model" target="n_vhost-net">
<mxGeometry relative="1" as="geometry">
<mxPoint x="270.5" y="719.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_tap-to-qemu-backend" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_tap" target="n_qemu-virtio-backend">
<mxGeometry relative="1" as="geometry">
<mxPoint x="276.5" y="701.2" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_tap-to-vhost" value="vhost-net 사용" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_tap" target="n_vhost-net">
<mxGeometry relative="1" as="geometry">
<mxPoint x="394.8" y="701.2" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_vhost-to-virtqueue" value="Data Path" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_vhost-net" target="n_virtqueue">
<mxGeometry relative="1" as="geometry">
<mxPoint x="331.8" y="886.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_virsh-to-libvirt" value="Control / Setup" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virsh" target="n_libvirt">
<mxGeometry relative="1" as="geometry">
<mxPoint x="161.2" y="151.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_virtqueue-to-guest" value="virtio-net Frontend Driver" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_virtqueue" target="n_guest">
<mxGeometry relative="1" as="geometry">
<mxPoint x="294.5" y="1081.0" as="offset"/>
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
@@ -0,0 +1,31 @@
{
"harness_version": "0.2.0",
"spec_id": "packet-control-and-data-paths",
"spec_version": "1.1",
"spec_sha256": "fa2d5e22352fa6cf975665cd431a236deaa4ae88ea0eb8461bb1b3c8b0b03dc6",
"source_context": {
"document": "docs/virtualization/final/document.md",
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
"anchor": {
"kind": "heading",
"value": "125. 최종 기준 구조",
"line": 5682
}
},
"outputs": [
"packet-control-and-data-paths.svg",
"packet-control-and-data-paths.drawio",
"packet-control-and-data-paths.mmd",
"packet-control-and-data-paths.d2",
"packet-control-and-data-paths.excalidraw",
"packet-control-and-data-paths.alt.md"
],
"lint_issue_count": 4,
"assumption_count": 0,
"assumptions_allowed": false,
"composition_profile": "component-flow",
"reference_ids": [
"payment-event-flow"
],
"diagram_only": true
}
@@ -0,0 +1,28 @@
%% control/setup path 는 QEMU 를 지나고 data path 는 backend 에 따라 QEMU 를 지나기도 안 지나기도 한다
%% question: 설정하는 경로와 packet 이 흐르는 경로는 어디에서 갈라지고, 그 두 갈래 가운데 어느 쪽이 QEMU 사용자 공간을 지나는가
flowchart TB
n0["virsh"]
n1["libvirt"]
n2["QEMU"]
n3["virtio-net Device Model"]
n4["Physical NIC"]
n5["Physical NIC Driver"]
n6["Linux Bridge /<br/>Routing / NAT"]
n7["TAP"]
n8["vhost-net"]
n9["QEMU virtio backend"]
n10(["virtqueue"])
n11["Guest"]
n0 -->|"Control / Setup"| n1
n1 -->|"NIC/network configuration"| n2
n2 -->|"QEMU process"| n3
n4 -->|"Ethernet Frame"| n5
n5 -->|"L2 forwarding"| n6
n6 -->|"Ethernet Frame"| n7
n3 -->|"vhost-net backend 설정"| n8
n3 --> n9
n7 -->|"vhost-net 사용"| n8
n7 --> n9
n8 -->|"Data Path"| n10
n9 -->|"Data Path"| n10
n10 -->|"virtio-net Frontend Driver"| n11
@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="680" height="1296" viewBox="0 0 680 1296" role="img" aria-labelledby="diagram-title diagram-description">
<title id="diagram-title">control/setup path 는 QEMU 를 지나고 data path 는 backend 에 따라 QEMU 를 지나기도 안 지나기도 한다</title>
<desc id="diagram-description">왼쪽에서 오른쪽으로 읽는다. 위쪽 줄이 control/setup path 다. virsh 에서 libvirt 와 QEMU 를 지나 virtio-net Device Model 에 닿고, 그 device model 이 virtual NIC 생성과 feature negotiation, virtqueue 설정, vhost-net backend 설정을 맡는다. 아래쪽 줄이 data path 다. Physical NIC 에서 Physical NIC Driver 와 Linux Bridge, TAP 까지 온다. 두 줄은 네 번째 열 다음에서 만난다. device model 은 점선으로 backend 둘을 설정하고, TAP 은 실선으로 그 둘 가운데 실제로 쓰는 쪽에 packet 을 넘긴다. vhost-net 을 쓰면 packet 은 Host Kernel 안에서 처리돼 QEMU 사용자 공간을 지나지 않고, QEMU virtio backend 를 쓰면 같은 packet 이 QEMU 사용자 공간을 지난다. 어느 쪽이든 virtqueue 에서 만나 Guest 로 올라간다. 이 Host 가 둘 중 어느 backend 를 쓰고 있는지는 그림이 말하지 않는다.</desc>
<metadata>{&quot;techviz&quot;:{&quot;spec_version&quot;:&quot;1.1&quot;,&quot;id&quot;:&quot;packet-control-and-data-paths&quot;,&quot;profile&quot;:&quot;component-flow&quot;},&quot;source_context&quot;:{&quot;document&quot;:&quot;docs/virtualization/final/document.md&quot;,&quot;document_sha256&quot;:&quot;181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd&quot;,&quot;anchor&quot;:{&quot;kind&quot;:&quot;heading&quot;,&quot;value&quot;:&quot;125. 최종 기준 구조&quot;,&quot;line&quot;:5682}},&quot;evidence_policy&quot;:&quot;Each factual element cites source lines or is marked assumption.&quot;,&quot;diagram_only&quot;:true}</metadata>
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" />
</marker>
<style>
:root { color-scheme: light; }
text { font-family: Inter, Pretendard, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; fill: #111827; }
.canvas { fill: #ffffff; }
.group-box { fill: #ffffff; stroke: #9ca3af; stroke-width: 1.4; stroke-dasharray: 7 5; }
.group-label-bg { fill: #ffffff; }
.group-label { font-size: 13px; font-weight: 650; fill: #374151; }
.edge { fill: none; stroke: #374151; stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; marker-end: url(#arrow); }
.edge.style-dashed, .edge.semantic-dashed, .edge.assumption { stroke-dasharray: 7 5; }
.edge.style-dotted { stroke-dasharray: 2 5; }
.edge.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
.edge.emphasis-muted { stroke: #9ca3af; }
.edge.emphasis-warning, .edge.kind-failure, .edge.kind-error { stroke: #dc2626; stroke-width: 2.2; }
.edge-label-bg { fill: #ffffff; }
.edge-label { font-size: 12px; font-weight: 560; text-anchor: middle; }
.node-shape { fill: #ffffff; stroke: #4b5563; stroke-width: 1.7; }
.node-shape.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
.node-shape.emphasis-muted { stroke: #9ca3af; fill: #f9fafb; }
.node-shape.emphasis-warning { stroke: #d97706; stroke-width: 2; fill: #fffdf5; }
.node-shape.kind-database, .node-shape.kind-datastore, .node-shape.kind-storage { fill: #f8fafc; }
.node-shape.kind-queue, .node-shape.kind-event, .node-shape.kind-topic { fill: #fafafa; }
.node-shape.assumption { stroke-dasharray: 4 4; }
.storage-bottom, .controller-divider { fill: none; stroke: #4b5563; stroke-width: 1.4; }
.controller-led { fill: #4b5563; }
.actor-symbol { fill: none; stroke: #4b5563; stroke-width: 1.8; stroke-linecap: round; }
.actor-symbol.emphasis-primary { stroke: #2563eb; stroke-width: 2.2; }
.node-label { font-size: 14px; font-weight: 650; text-anchor: middle; }
.node-role { font-size: 10px; letter-spacing: 0.04em; text-anchor: middle; fill: #6b7280; }
.node-detail-divider { stroke: #d1d5db; stroke-width: 1; }
.node-detail { font-size: 11px; fill: #374151; }
.assumption-badge { font-size: 9px; font-weight: 700; fill: #92400e; }
.failure-mark { stroke: #dc2626; stroke-width: 4; stroke-linecap: round; }
.lifeline { stroke: #9ca3af; stroke-width: 1.2; stroke-dasharray: 5 5; }
.timeline-axis { stroke: #374151; stroke-width: 1.8; marker-end: url(#arrow); }
.timeline-stem { stroke: #6b7280; stroke-width: 1.3; }
.timeline-marker { fill: #ffffff; stroke: #374151; stroke-width: 1.7; }
.timeline-marker.primary { fill: #2563eb; stroke: #2563eb; }
.timeline-marker.warning { fill: #dc2626; stroke: #dc2626; }
.timeline-label { font-size: 13px; font-weight: 650; text-anchor: middle; }
.timeline-detail { font-size: 11px; fill: #4b5563; text-anchor: middle; }
</style>
</defs>
<rect class="canvas" width="680" height="1296" />
<polyline class="edge kind-data style-solid emphasis-normal" points="375.5,461.0 375.5,526.8 387.5,526.8 387.5,592.5" data-evidence="5671-5671,5712-5714" />
<rect class="edge-label-bg" x="325.6" y="484.8" width="111.8" height="22" rx="3" />
<text class="edge-label" x="381.5" y="499.8">Ethernet Frame</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="375.5,291.0 375.5,339.0 375.5,339.0 375.5,387.0" data-evidence="5672-5672,5710-5712" />
<rect class="edge-label-bg" x="346.9" y="325.0" width="105.1" height="22" rx="3" />
<text class="edge-label" x="399.5" y="340.0">L2 forwarding</text>
<polyline class="edge kind-control style-solid emphasis-normal" points="157.0,291.0 157.0,339.8 165.5,339.8 165.5,388.5" data-evidence="5663-5663,5691-5693" />
<rect class="edge-label-bg" x="68.5" y="297.8" width="185.5" height="22" rx="3" />
<text class="edge-label" x="161.2" y="312.8">NIC/network configuration</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="375.5,127.5 375.5,177.2 375.5,177.2 375.5,227.0" data-evidence="5671-5671,5708-5710" />
<rect class="edge-label-bg" x="343.6" y="163.2" width="111.8" height="22" rx="3" />
<text class="edge-label" x="399.5" y="178.2">Ethernet Frame</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="165.5,866.0 165.5,914.0 261.5,914.0 261.5,962.0" data-evidence="5729-5729,5742-5744" />
<rect class="edge-label-bg" x="174.3" y="872.0" width="78.3" height="22" rx="3" />
<text class="edge-label" x="213.5" y="887.0">Data Path</text>
<polyline class="edge kind-control style-solid emphasis-normal" points="165.5,459.5 165.5,508.2 157.0,508.2 157.0,557.0" data-evidence="5666-5666,5693-5695" />
<rect class="edge-label-bg" x="112.0" y="466.2" width="98.4" height="22" rx="3" />
<text class="edge-label" x="161.2" y="481.2">QEMU process</text>
<polyline class="edge kind-control style-dashed emphasis-normal" points="148.0,699.0 148.0,747.0 156.5,747.0 156.5,795.0" data-evidence="5668-5668,5700-5700" />
<polyline class="edge kind-control style-dashed emphasis-normal" points="166.0,699.0 166.0,747.0 375.0,747.0 375.0,795.0" data-evidence="5700-5700,5716-5716" />
<rect class="edge-label-bg" x="194.5" y="705.0" width="152.0" height="22" rx="3" />
<text class="edge-label" x="270.5" y="720.0">vhost-net backend 설정</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="378.5,663.5 378.5,729.2 174.5,729.2 174.5,795.0" data-evidence="5729-5729,5740-5742" />
<polyline class="edge kind-data style-solid emphasis-normal" points="396.5,663.5 396.5,729.2 393.0,729.2 393.0,795.0" data-evidence="5703-5703,5714-5716" />
<rect class="edge-label-bg" x="345.6" y="687.2" width="98.4" height="22" rx="3" />
<text class="edge-label" x="394.8" y="702.2">vhost-net 사용</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="384.0,866.0 384.0,914.0 279.5,914.0 279.5,962.0" data-evidence="5703-5703,5716-5718" />
<rect class="edge-label-bg" x="292.6" y="872.0" width="78.3" height="22" rx="3" />
<text class="edge-label" x="331.8" y="887.0">Data Path</text>
<polyline class="edge kind-control style-solid emphasis-normal" points="165.5,131.0 165.5,179.0 157.0,179.0 157.0,227.0" data-evidence="5662-5663,5684-5691" />
<rect class="edge-label-bg" x="102.0" y="137.0" width="118.5" height="22" rx="3" />
<text class="edge-label" x="161.2" y="152.0">Control / Setup</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="270.5,1033.0 270.5,1081.0 270.5,1081.0 270.5,1129.0" data-evidence="5664-5664,5718-5726" />
<rect class="edge-label-bg" x="198.4" y="1067.0" width="192.2" height="22" rx="3" />
<text class="edge-label" x="294.5" y="1082.0">virtio-net Frontend Driver</text>
<g id="node-virsh">
<rect class="node-shape kind-cli emphasis-normal role-actor" data-evidence="5662-5662,5687-5689" x="90.5" y="60.0" width="150.0" height="71.0" rx="7" />
<text class="node-label" x="165.5" y="87.0">virsh</text>
<line class="node-detail-divider" x1="104.5" y1="108.0" x2="226.5" y2="108.0" />
<text class="node-detail" x="106.5" y="125.0">User</text>
</g>
<g id="node-physical-nic">
<rect class="node-shape kind-hardware emphasis-normal role-source" data-evidence="5706-5708" x="300.5" y="63.5" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="375.5" y="93.5">Physical NIC</text>
</g>
<g id="node-libvirt">
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="5663-5663,5691-5691" x="82.0" y="227.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="157.0" y="257.0">libvirt</text>
</g>
<g id="node-physical-nic-driver">
<rect class="node-shape kind-driver emphasis-normal role-service" data-evidence="5674-5674,5710-5710" x="292.0" y="227.0" width="167.0" height="64.0" rx="7" />
<text class="node-label" x="375.5" y="257.0">Physical NIC Driver</text>
</g>
<g id="node-qemu">
<rect class="node-shape kind-process emphasis-normal role-service" data-evidence="5666-5666,5693-5693" x="90.5" y="388.5" width="150.0" height="71.0" rx="7" />
<text class="node-label" x="165.5" y="415.5">QEMU</text>
<line class="node-detail-divider" x1="104.5" y1="436.5" x2="226.5" y2="436.5" />
<text class="node-detail" x="106.5" y="453.5">Host Userspace</text>
</g>
<g id="node-linux-bridge">
<rect class="node-shape kind-network emphasis-normal role-service" data-evidence="5672-5673,5712-5712" x="300.5" y="387.0" width="150.0" height="74.0" rx="7" />
<text class="node-label" x="375.5" y="414.0">Linux Bridge /</text>
<text class="node-label" x="375.5" y="432.0">Routing / NAT</text>
</g>
<g id="node-virtio-net-device-model">
<rect class="node-shape kind-service emphasis-primary role-service" data-evidence="5666-5666,5695-5700" x="70.0" y="557.0" width="174.0" height="142.0" rx="7" />
<text class="node-label" x="157.0" y="585.0">virtio-net Device</text>
<text class="node-label" x="157.0" y="603.0">Model</text>
<line class="node-detail-divider" x1="84.0" y1="624.0" x2="230.0" y2="624.0" />
<text class="node-detail" x="86.0" y="641.0">virtual NIC 생성</text>
<text class="node-detail" x="86.0" y="657.0">feature negotiation</text>
<text class="node-detail" x="86.0" y="673.0">virtqueue 설정</text>
<text class="node-detail" x="86.0" y="689.0">vhost-net backend 설정</text>
</g>
<g id="node-tap">
<rect class="node-shape kind-network emphasis-normal role-service" data-evidence="5671-5671,5714-5714" x="304.0" y="592.5" width="167.0" height="71.0" rx="7" />
<text class="node-label" x="387.5" y="619.5">TAP</text>
<line class="node-detail-divider" x1="318.0" y1="640.5" x2="457.0" y2="640.5" />
<text class="node-detail" x="320.0" y="657.5">Host-side interface</text>
</g>
<g id="node-qemu-virtio-backend">
<rect class="node-shape kind-process emphasis-normal role-service" data-evidence="5668-5668,5742-5742" x="82.0" y="795.0" width="167.0" height="71.0" rx="7" />
<text class="node-label" x="165.5" y="822.0">QEMU virtio backend</text>
<line class="node-detail-divider" x1="96.0" y1="843.0" x2="235.0" y2="843.0" />
<text class="node-detail" x="98.0" y="860.0">QEMU Userspace</text>
</g>
<g id="node-vhost-net">
<rect class="node-shape kind-kernel emphasis-normal role-service" data-evidence="5669-5669,5716-5716" x="309.0" y="795.0" width="150.0" height="71.0" rx="7" />
<text class="node-label" x="384.0" y="822.0">vhost-net</text>
<line class="node-detail-divider" x1="323.0" y1="843.0" x2="445.0" y2="843.0" />
<text class="node-detail" x="325.0" y="860.0">Host Kernel</text>
</g>
<g id="node-virtqueue">
<rect class="node-shape kind-queue emphasis-normal role-queue" data-evidence="5667-5667,5718-5718" x="195.5" y="962.0" width="150.0" height="71.0" rx="7" />
<text class="node-label" x="270.5" y="989.0">virtqueue</text>
<line class="node-detail-divider" x1="209.5" y1="1010.0" x2="331.5" y2="1010.0" />
<text class="node-detail" x="211.5" y="1027.0">shared queue</text>
</g>
<g id="node-guest">
<rect class="node-shape kind-service emphasis-normal role-sink" data-evidence="5664-5665,5720-5726" x="162.5" y="1129.0" width="216.0" height="122.0" rx="7" />
<text class="node-label" x="270.5" y="1156.0">Guest</text>
<line class="node-detail-divider" x1="176.5" y1="1177.0" x2="364.5" y2="1177.0" />
<text class="node-detail" x="178.5" y="1194.0">virtio-net Frontend Driver</text>
<text class="node-detail" x="178.5" y="1210.0">Guest TCP/IP Stack</text>
<text class="node-detail" x="178.5" y="1226.0">Socket</text>
<text class="node-detail" x="178.5" y="1242.0">Keycloak</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB