How to Calculate MTU for Tunnels

Posted: April 7th, 2011 | Author: | Filed under: Blog, Networking | Tags: , , , , | 3 Comments »

WARNING: BORING ALERT!!!!

Packet Fragmentation Example

If you have any tunnels in your network you may notice at times packet loss between subnets or perhaps stalled web sessions. This usually has to do with a combination of MTU negotiation and packet fragmentation.

MTU 101

Maximum Transmission Unit refers to how much data in bytes the data layer can send forward. For ethernet the size is 1500 bytes, which coincides with how much data can fit in an ethernet frame. Within the MTU is another size called MSS (Maximum Segment Size) which refers to how much TCP data can be transmitted. This is also known as the payload and is usually 1460 bytes. The 40 bytes difference between the MTU and MSS sizes are for TCP/IP headers. But this can create a problem when GRE is introduced.

Enter the Tunnel

The big problem with GRE is that it doesn’t fit into the 7 layer dip of the OSI model. It acts as a separator between the network and transport layers. GRE adds a header to all the packets that will traverse the GRE tunnel, thus consume some of the 1500 bytes of the ethernet frame. The MTU then needs to be decreased to allow the packet to fit within the frame. This can result in packet fragmentation or packet loss as some packets will have a “don’t fragment” bit set.

Determine MTU

To optimize your network performance it would be best practice to determine the MTU through the tunnel. This size my vary depending upon encapsulation, encryption, and routing. To determine the MTU size we will conduct some tests with “don’t fragment” ping packets from a host on one side of the tunnel to a host on the other side of the tunnel.

First let’s take a look at how “don’t fragment” pings work. We’re going to send two pings (-c 2) with the don’t fragment (-D) bit set and specify the payload to be 1472 bytes (-s 1472)

homer:~ jordan$ ping -D -c 2 -s 1472 4.2.2.2
PING 4.2.2.2 (4.2.2.2): 1472 data bytes
1480 bytes from 4.2.2.2: icmp_seq=0 ttl=54 time=37.163 ms
1480 bytes from 4.2.2.2: icmp_seq=1 ttl=54 time=34.799 ms

This shows us that the MTU between us and 4.2.2.2 which is a public root DNS server is 1500. The difference between the MTU size (1500) and ping payload size (1472) is the ICMP headers of 28 bytes. This is important to note, as ping payloads used to test the MTU must be 28 bytes lower than the MTU value you are testing.

If we add one byte to this test it will cause the ping to be lost.

homer:~ jordan$ ping -D -c 2 -s 1473 4.2.2.2
PING 4.2.2.2 (4.2.2.2): 1473 data bytes
ping: sendto: Message too long
ping: sendto: Message too long

So let’s try and determine the MTU for this sample network. We have a host on each side with a default MTU of 1500 and tunnel in between the two of them. To determine the MTU we issue the command listed above

homer:~ jordan$ ping -D -c 2 -s 1472 172.16.10.10
PING 172.16.10.10 (172.16.10.10): 1472 data bytes
ping: sendto: Message too long
ping: sendto: Message too long

Clearly this shows us the payload is too large and thus the MTU is lower than 1500. So let’s lower the payload by 10 bytes and round it down, if it fails decrement the payload by 10 bytes again and again while testing until you have a successful test. Then increment by 1 byte until it stops working. The last test payload size, plus 28 bytes is your MTU.

Example:

homer:~ jordan$ ping -D -c 2 -s 1460 172.16.10.10
PING 172.16.10.10 (172.16.10.10): 1460 data bytes
ping: sendto: Message too long
ping: sendto: Message too long
homer:~ jordan$ ping -D -c 2 -s 1450 172.16.10.10
PING 172.16.10.10 (172.16.10.10): 1450 data bytes
ping: sendto: Message too long
ping: sendto: Message too long
homer:~ jordan$ ping -D -c 2 -s 1440 172.16.10.10
PING 172.16.10.10 (172.16.10.10): 1440 data bytes
1448 bytes from 172.16.10.10: icmp_seq=0 ttl=254 time=72.199 ms
1448 bytes from 172.16.10.10: icmp_seq=1 ttl=254 time=78.266 ms
homer:~ jordan$ ping -D -c 2 -s 1441 172.16.10.10
PING 172.16.10.10 (172.16.10.10): 1441 data bytes
ping: sendto: Message too long
ping: sendto: Message too long

Tada, the last payload that worked was 1440, therefore our MTU is 1468. Ping payload size of 1440 bytes + ICMP header of 28 bytes = MTU of 1468 bytes

I hope you enjoyed yourself as much as I have, please feel free to leave questions in the comments here.


Calculate Subnet Network Masks and CIDR notation

Posted: April 6th, 2011 | Author: | Filed under: Blog, Networking | Tags: , , | No Comments »

How to calculate the network mask from a CIDR notation, or a CIDR notation from a network mask. To figure this out we need to understand the relationship between the two. A network mask when written in binary will be 32 bits long. This also means that each octet of a network mask can hold a total of 8 bits.

255.255.0.0 == 11111111.11111111.00000000.00000000
255.255.255.0 == 11111111.11111111.11111111.00000000
255.255.255.192 == 11111111.11111111.11111111.11000000

Example 1-1: Calculate the network mask from CIDR Notation /16


1. First subtract the CIDR notation from the total number of bits available in CIDR notation. This is the number of bits occupied in the mask.

2. Next, place no more than 8 bits into each octet starting with the one the on the right.

3. Move the bits into an exponent of two and calculate

4. Subtract one from each octet and you now have your reverse mask

5. Inverse the reverse mask to finally find out your network mask

The network mask for CIDR notation /16 is 255.255.0.0



Example 2-1: Calculate the CIDR notation from network mask 255.255.0.0

This is exactly the procedure above but just reversed

1. Inverse the network mask to find out your reverse mask

2. Add one to each populated octet

3. Find the exponent value of 2 for each octet (PROTIP: double 2 in your head until you hit the number, that is the number of bits ie {2 4 8 16} = 4…)

4. Add up all the exponent values and subtract from 32







Example 1-2: Calculate the network mask from CIDR Notation /13

1. First subtract the CIDR notation from the total number of bits available in CIDR notation. This is the number of bits occupied in the mask.

2. Next, place no more than 8 bits into each octet starting with the one the on the right.

3. Move the bits into an exponent of two and calculate

4. Subtract one from each octet and you now have your reverse mask

5. Inverse the reverse mask to finally find out your network mask (PROTIP, for the second octet just subtract 7 from 255)




Example 2-2: Calculate the CIDR notation from network mask 255.248.0.0

This is exactly the procedure above but just reversed

1. Inverse the network mask to find out your reverse mask

2. Add one to each populated octet

3. Find the exponent value of 2 for each octet (PROTIP: double 2 in your head as many bits as you have 2 4 8 16…)

4. Add up all the exponent values and subtract from 32