본문 바로가기
컴퓨터

MTU (Maximum Transmission Unit)

by dbadoy 2023. 2. 26.

MTU란 단어는 네트워크 기초를 공부하다보면 한번쯤은 접하게 되는 용어이며, 특정 네트워크 계층에서 전송할 수 있는 최대 크기를 의미한다.

데이터 링크 계층인 이더넷에서 MTU가 몇일까 생각해보면 보통은 1500이란 값을 떠올린다. 이는 기본 MTU 값으로 정해져 있기 때문인데, 초기 네트워크 인터페이스 카드에는 많은 양의 프레임(바이트)을 포함할 수 있는 큰 버퍼가 없었기 때문에 당시에는 1500바이트가 "괜찮은" 것처럼 보였다고 한다. 하지만 현대에 와서는 네트워크 속도가 빨라지고 전송해야 할 데이터의 크기도 급속하게 증가하고 있기 때문에 1500바이트란 값이 작다고 느껴질 수 있다. 큰 데이터를 잘게 잘라서 여러 번 보내는 것보다는 큰 덩어리로 적게 보내는 것이 더 빠른것은 당연한 결과일 것이다. 그렇다면 내 컴퓨터의 이더넷 MTU를 늘리면 전송 속도가 빨라지지 않을까? 

아쉽게도 그렇지는 않다. 내 로컬의 네트워크 인터페이스가 더욱 큰 MTU 값을 지원한다 하더라도, 목적지로 가는 도중 거치는 외부의 장비들은 이더넷 MTU값이 1500으로 설정되어 있을 확률이 높다. 설정된 MTU 값보다 더욱 큰 프레임이 도착한다면 해당 장비는 어떻게 행동할까? 해당 프레임을 아예 처리하지 않고 버리기 때문에 실제적인 통신이 이뤄지지 않게 된다. 따라서 함부로 이더넷 MTU를 늘린다면 통신이 아예 되지 않는 경험을 하게 될 수도 있다.

'점보 프레임'은 이더넷 MTU를 1500보다 큰 값으로 설정하여 전송 속도를 빠르게 할 수 있다는데 어떻게 그럴 수 있을까? 점보 프레임은 주로 내부 네트워크에서 사용되며, 내부의 모든 장비에 큰 MTU를 지원할 수 있는 네트워크 인터페이스 카드를 사용하고 MTU를 증가시키기 때문에 프레임이 버려질 걱정 없이 빠르게 전송을 할 수 있다.   

 

그런데 UDP header의 UDP length는 16 bit로 정해져 있다. 이는 UDP 최대 크기가 65535 byte 라는 것이고, 이더넷은 MTU 보다 큰 프레임을 버리는데 어떻게 세그먼트가 전송되는 걸까?

https://erg.abdn.ac.uk/users/gorry/course/inet-pages/udp.html

 

MTU는 데이터링크 계층에만 존재하는 것이 아니라 IP 계층에도 존재한다. IP 계층은 최종 목적지까지 라우팅하는 것뿐만 아니라 IP MTU 크기에 맞게 세그먼트를 쪼개고, 다시 합치는 역할도 맡고 있다.

예를 들어 3000 byte의 크기를 갖는 UDP 세그먼트를 다른 호스트로 전송한다고 가정해보자. 내 로컬에서 목적지 사이에 설정된 데이터 링크 MTU는 1500이다. 이 때, IP MTU도 1500으로 설정되어 있다면 UDP 세그먼트는 1500, 1500 두개의 데이터그램으로 나뉘어 전송되고, 목적지에 도착한 두 개의 데이터그램은 다시 하나의 UDP 세그먼트로 합쳐진 뒤 윗 레이어에 도달하게 된다(이해하기 쉽도록 헤더 크기에 대한 고려는 제외). 만약 IP MTU가 500이라면? 6개의 데이터그램으로 쪼개져 전송이 되겠다.

즉, IP 계층이 IP MTU 크기를 기준으로 세그먼트를 데이터그램으로 나누고, 데이터 링크 계층은 전달 받은 데이터그램을 단순히 전송한다고 생각하면 된다. (아주 옛날에 정의된 프로토콜일텐데 계층별로 해야 하는 역할을 나누어 놓은 것이 인상적이다)

만약 IP 계층 MTU가 데이터 링크 계층 MTU보다 크게 설정되어 있다면 어떻게 될까?
IP MTU = 2000, 이더넷 MTU = 1500, 세그먼트 크기 = 4000 byte
[이해하기 쉽도록 헤더 크기에 따른 고려는 제외]
세그먼트는 각 2000, 2000 크기의 데이터그램으로 나뉘어 지게 되고, 데이터링크로 전달된 2000 byte 크기의 데이터 그램은 이더넷 MTU인 1500 보다 크기 때문에 버려진다.
따라서 IP 계층 MTU는 데이터링크 계층 MTU와 같거나 더 작게 설정되어야 한다.

(http://switchpacket.blogspot.com/2014/07/understanding-difference-between-mtu.html)

이렇게 UDP를 전송했을 때 세그먼트를 나누고 합치는 과정은 라우터에게 부담이 되고, 해당 과정에서 유실될 가능성도 존재하며 아예 해당 작업을 지원을 하지 않을 가능성도 존재한다. 또, 위의 예시에서는 단순히 총 데이터 크기를 MTU로 나누었지만, 실제로는 각 나누어진 조각마다 헤더가 붙기 때문에 오버헤드가 존재한다. 이에 관한 문제를 IP 단편화라고 하고, 나누어진 데이터들을 Fragment라고 한다.

그러면 UDP 통신을 할 때 단편화 문제를 겪지 않기 위해 얼마의 크기로 전송하는 것이 좋을까? IP 계층의 MTU는 최소한 576(IPv4)은 지원해야 한다는 표준이 정해져 있기 때문에 IP, UDP헤더의 크기를 뺀 576-20-8 = 548 byte, 이보다 더 보수적으로 정하겠다면 IP헤더는 옵션 영역까지 사용하는 경우 최대 60바이트까지 늘어날 수 있는 가변 길이를 갖고 있으니 576-60-8 = 508 byte 가 되겠다. 여기서 주의해야 할 점은, 위 크기로 보낸다고 UDP 패킷 자체가 안전하다고는 할 수 없다. 단순히 단편화를 피할 수 있을 뿐이다. (단편화가 실제 통신 성능에 얼마나 영향을 끼칠지는 모르겠다. 네트워크 장비에 따라 결과가 다를 수도 있고... 요즘은 네트워크 장비의 하드웨어도 많이 발전했으니)

TCP 통신의 경우 단편화를 피하기 위해 최소 MTU를 구하는 PMTUD(Path MTU Discovery) 과정을 거친다. PMTUD는 단순한 방법을 사용하는데, 가장 먼저 IP header의 don't flagment 플래그를 설정하여 목적지로 ping을 보낸다(해당 플래그가 설정되어 있으면 IP계층은 데이터가 MTU보다 크더라도 단편화를 수행하지 않는다). 만약 실패한다면 경로에 지금 설정된 MTU 값보다 작은 구간이 존재한다는 것이기 때문에 ping의 크기를 낮춰 재전송하는 과정을 반복하며 성공하는 값을 MTU값으로 정한다. 

 

(1) 세그먼트 분해, 재조립 과정은 여기 참조 https://code-lab1.tistory.com/32