Hemanth's World of Networking

Pushing Packets throughout the world

IPv6 Tunneling Mechanism Demystified- 6 to 4 Tunnel

Introduction

Right now I am focused more into IPv6 and here is a another post on IPv6. IPv4 is now completely exhausted. But still i want to use my IPv4 and add new IPv6 domains.  One common problem is that sometimes our individual site networks can upgrade or pilot IPv6 before the carrier ISP is fully ready to go full native IPv6. A similar issue would be if perhaps you want to connect to the IPv6 internet, but your ISP is not ready to give you IPv6 address space.  What happens is that we can end up with several sites running IPv6 “islands”, but those islands are connected via an IPv4 infrastructure.  There are a few technologies that deal with how to connect IPv6 islands over an IPv4 network, and one of those technologies is IPv6 automatic 6to4 tunnels.  We will be looking at that technology in today’s blog.

Let’s say we are in charge of a corporate network.  Our network has three major sites connected over a WAN in a hub and spoke topology.  R5 is our HQ site and is the hub.  R2 and R4 are spoke sites.  R5 has frame-relay PVCs directly to R2 and R4 but R2 and R4 don’t talk directly to each other, only through the hub.  Our company is interested in IPv6, but wants to pilot it between the three major sites before committing to go fully IPv6 in the future.  Unfortunately, our ISP is still only running IPv4 and so what we have are three IPv6 island networks connected through an IPv4 backbone. Let’s check out the diagram and go through what we will be dealing with.

Initial Configurations

First, let’s look at our initial configurations without any IPv6 whatsoever.  We will be running OSPF as our IGP over frame-relay.  Each site will advertise its loopback address into OSPF. Note that the point of this blog is not OSPF over frame-relay so we won’t be covering this configuration in detail. After we look at the frame-relay and OSPF configuration on each router we will verify OSPF adjacencies and make sure we can ping the other loopback addresses to ensure we have full IPv4 reachability between our routers.

R2

interface Serial0/1/0
 ip address 100.100.100.2 255.255.255.0
 encapsulation frame-relay
 ip ospf priority 0
 frame-relay map ip 100.100.100.2 205
 frame-relay map ip 100.100.100.5 205
 frame-relay map ip 100.100.100.4 205 broadcast
 no frame-relay inverse-arp
 frame-relay lmi-type cisco
!
interface Loopback0
 ip address 2.2.2.2 255.255.255.255
!
router ospf 1
 router-id 2.2.2.2
 log-adjacency-changes
 network 2.2.2.2 0.0.0.0 area 0
 network 100.100.100.0 0.0.0.255 area 0

R2#sh ip ospf neigh

Neighbor ID     Pri   State           Dead Time   Address         Interface
5.5.5.5         255   FULL/DR         00:01:58    100.100.100.5   Serial0/1/0

R2#ping 4.4.4.4 so lo0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 4.4.4.4, timeout is 2 seconds:
Packet sent with a source address of 2.2.2.2
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 112/114/116 ms
R2#ping 5.5.5.5 so lo0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 5.5.5.5, timeout is 2 seconds:
Packet sent with a source address of 2.2.2.2
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 56/58/60 ms

R4

interface Serial0/0
 ip address 100.100.100.4 255.255.255.0
 encapsulation frame-relay
 ip ospf priority 0
 frame-relay map ip 100.100.100.2 405 broadcast
 frame-relay map ip 100.100.100.4 405
 frame-relay map ip 100.100.100.5 405
 no frame-relay inverse-arp
 frame-relay lmi-type cisco
!
interface Loopback0
 ip address 4.4.4.4 255.255.255.255
!
router ospf 1
 router-id 4.4.4.4
 log-adjacency-changes
 network 4.4.4.4 0.0.0.0 area 0
 network 100.100.100.0 0.0.0.255 area 0

R4#sh ip ospf neigh

Neighbor ID     Pri   State           Dead Time   Address         Interface
5.5.5.5         255   FULL/DR         00:01:37    100.100.100.5   Serial0/0

R4#ping 2.2.2.2 so lo0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2.2.2.2, timeout is 2 seconds:
Packet sent with a source address of 4.4.4.4
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 112/115/116 ms
R4#ping 5.5.5.5 so lo0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 5.5.5.5, timeout is 2 seconds:
Packet sent with a source address of 4.4.4.4
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 56/59/60 ms

R5

interface Serial2/0
 ip address 100.100.100.5 255.255.255.0
 encapsulation frame-relay
 ip ospf priority 255
 serial restart-delay 0
 frame-relay map ip 100.100.100.2 502 broadcast
 frame-relay map ip 100.100.100.4 504 broadcast
 frame-relay map ip 100.100.100.5 504
 no frame-relay inverse-arp
 frame-relay lmi-type cisco
!
interface Loopback0
 ip address 5.5.5.5 255.255.255.255
!
router ospf 1
 router-id 5.5.5.5
 log-adjacency-changes
 network 5.5.5.5 0.0.0.0 area 0
 network 100.100.100.0 0.0.0.255 area 0
 neighbor 100.100.100.2
 neighbor 100.100.100.4

R5#sh ip ospf neigh

Neighbor ID     Pri   State           Dead Time   Address         Interface
2.2.2.2           0   FULL/DROTHER    00:01:49    100.100.100.2   Serial2/0
4.4.4.4           0   FULL/DROTHER    00:01:46    100.100.100.4   Serial2/0

R5#ping 2.2.2.2 so lo0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2.2.2.2, timeout is 2 seconds:
Packet sent with a source address of 5.5.5.5
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 56/57/60 ms
R5#ping 4.4.4.4 so lo0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 4.4.4.4, timeout is 2 seconds:
Packet sent with a source address of 5.5.5.5
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 56/59/60 ms

Basic IPv6 Configurations

R2

ipv6 unicast-routing
!
interface FastEthernet0/0
 no ip address
 ipv6 address FE80::2 link-local
 ipv6 address 2001:2222:2222:2222::1/64

R4

ipv6 unicast-routing
!
interface Ethernet0/0
 no ip address
 ipv6 address FE80::4 link-local
 ipv6 address 2001:4444:4444:4444::1/64

R5

ipv6 unicast-routing
!
interface Ethernet0/0
 no ip address
 ipv6 address FE80::5 link-local
 ipv6 address 2001:5555:5555:5555::1/64

How IPv6 6to4 tunneling works

That was a bit of leg work, but now we get to the fun part — How this tunneling is actually going to work.  We have three separate IPv6 islands now, yet we are connected via an IPv4 infrastructure.  Essentially what a 6to4 tunnel does is it encapsulates IPv6 traffic into IPv4 packets.  The IPv4 packet will have a source address of it’s loopback interface and a destination address of the destination router’s loopback interface.  The IPv4 packet on the “outside” will carry IP protocol 41 and on the “inside” will be our IPv6 packet with header and payload.  Up until now, this sounds a lot like a simple ipv6ip tunnel, so what’s the difference?  In an ipv6ip tunnel you specify an IPv4 source and an IPv4 destination manually on the tunnel.  It is strictly point-to-point.  With IPv6 6to4 tunnels, you don’t actually manually specify a tunnel destination, and the technology is multipoint.  On each router we will only need a single 6to4 tunnel interface.  The magic is in how that multipoint technology works, and the secret lies with the addressing. You may have to read this section a few times to get it to “click” but stay with me here.

The IPv6 prefix 2002::/16 is reserved specifically for the 6to4 tunneling technology.  Your 6to4 tunnel interface will use an address from this range.  Built into the address is an encoding scheme that takes your IPv4 address and encodes it into part of the IPv6 address.  This works by encoding the IPv4 address into the IPv6 prefix so that your IPv6 prefix looks something like this: 2002:AABB:CCDD::/48.  AABB:CCDD would be your IPv4 address. Once you have your /48 prefix you can utilize a /64 or whatever for your actual tunnel IPv6 address.  When routers need to send packets to any address in the 2002::/16 range they will actually look at the 32 bits following 2002, convert them into an IPv4 address and thus figure out themselves the destination of the tunnel! Brilliant!!!

IPv6 6to4 Tunnel Configuration & Example

Whoa…yeah it sounds intense when you first learn it, but the best way to understand is with an example.  Let’s look at how communication between R2 , R4 and R5 will work.  R2, R4 and R5 will each have a 6to4 tunnel interface sourced from their lo0 interfaces.  Each tunnel interface will have an IPv6 address assigned to it from the 2002::/16 reserved range, but we need to actually figure out what that address is. The first 16 bits will be 2002, but what about the next 32 bits?  What we need to do is take our IPv4 source address and encode it into an IPv6 6to4 address. To do that we convert out IPv4 address into hex.

R2′s lo0 is 2.2.2.2.  That is a 32-bit IP address.  Now we need to convert that 32-bit address into hex so we can stick it into that reserved IPv6 prefix 2002::/16.  2.2.2.2 = 0202:0202. Prepend that with your IPv6 6to4 tunnel prefix to give you 2002:0202:0202::/48

R4′s Lo0 is 4.4.4.4.  Converted to hex is 0404:0404 so our IPv6 prefix would be 2002:0404:0404::/48

R5′s Lo0 is 5.5.5.5.  Converted to hex is 0505:0505 so our IPv6 prefix would be 2002:0505:0505::/48

Now, on each router we will configure a static route like this: ipv6 route 2002::/16 tunnel0.  This says “If I need to route to 2002::/16 send it out the tunnel”.  Let’s configure that and then talk through how this will work

R2

interface Tunnel0
 no ip address
 ipv6 address 2002:202:202::2/64
 tunnel source Loopback0
 tunnel mode ipv6ip 6to4
!
ipv6 route 2002::/16 tunnel0

R4

interface Tunnel0
 no ip address
 no ip redirects
 ipv6 address 2002:404:404::4/64
 tunnel source Loopback0
 tunnel mode ipv6ip 6to4
!
ipv6 route 2002::/16 tunnel0

R5

interface Tunnel0
 no ip address
 no ip redirects
 ipv6 address 2002:505:505::5/64
 tunnel source Loopback0
 tunnel mode ipv6ip 6to4
!
ipv6 route 2002::/16 tunnel0

OK, let’s go through the communication.  Let’s say R2 wants to ping R4.  For now, forget about the 2001:: prefix addresses on the individual LANs for a minute.  You need to understand this first.  Say R2 wants to ping R4 sourced from it’s tunnel0 interface.  So we have an IPv6 source address of 2002:0202:0202::2/64 and an IPv6 destination address of 2002:0404:0404::4/64.  What happens?  R2 looks in it’s IPv6 routing table and sees this:

R2#show ipv6 route
IPv6 Routing Table - Default - 6 entries
Codes: C - Connected, L - Local, S - Static, U - Per-user Static route
       B - BGP, M - MIPv6, R - RIP, I1 - ISIS L1
       I2 - ISIS L2, IA - ISIS interarea, IS - ISIS summary, D - EIGRP
       EX - EIGRP external
       O - OSPF Intra, OI - OSPF Inter, OE1 - OSPF ext 1, OE2 - OSPF ext 2
       ON1 - OSPF NSSA ext 1, ON2 - OSPF NSSA ext 2
C   2001:2222:2222:2222::/64 [0/0]
     via FastEthernet0/0, directly connected
L   2001:2222:2222:2222::1/128 [0/0]
     via FastEthernet0/0, receive
S 2002::/16 [1/0]
     via Tunnel0, directly connected
C   2002:202:202::/64 [0/0]
     via Tunnel0, directly connected
L   2002:202:202::2/128 [0/0]
     via Tunnel0, receive
L   FF00::/8 [0/0]
     via Null0, receive

R2 has a static route for 2002::/16 so it will route the packet out the tunnel interface. Now, because the tunnel is configured for “mode ipv6ip 6to4″ the router knows it needs to look at that destination address of 2002:0404:0404::4 and rip out the 32 bits following 2002 to derive the destination of the tunnel. R2 converts 0404:0404 into the IPv4 address 4.4.4.4. NOW R2 has the destination for the tunnel. R2 then encapsulates the IPv6 packet into an IPv4 packet with a source of 2.2.2.2 and a destination of 4.4.4.4. The packet is sent out our frame-relay interface to R5. R5 sees the IPv4 packet and routes it normall to R4. R4 receives the IPv4 packet. R4 recognizes that it is an IPv4 packet carrying IP protocol 41 (IPv6) so it pops off the IPv4 header and sees an IPv6 packet from 2002:0202:0202::2 destined to 2002:0404:0404::4. R4 processes the packet and replies with a packet sourced from 2002:0404:0404::4 destined to 2002:0202:0202::2.

Now the reverse happens — R4 has a static route for 2002::/16 out it’s tunnel interface so it routes the packet out the tunnel. Because the tunnel mode is “ipv6ip 6to4″ R4 knows it needs to look at the destination IPv6 address to derive the destination of the tunnel. R4 converts 0202:0202 into the IPv4 address 2.2.2.2. R4 encapsulates the IPv6 ICMPv6 echo-reply sourced from 2002:0404:0404::4 destined to 2002:0202:0202::2 into an IPv4 packet sourced from 4.4.4.4 and destined to 2.2.2.2. The packet gets routed through the IPv4 network to R5 and down to R2. R2 pops off the IPv4 header and processes the IPv6 packet that was encapsulated inside.

Let’s try it!!!

R2#ping 2002:0404:0404::4

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2002:404:404::4, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 136/136/136 ms

That’s what I’m talkin’ about! Now…the cool thing is, think about what happens if I need to now ping R5. I don’t need a separate tunnel because based on the destination IPv6 address, the router will simply figure out the rest.

R2#ping 2002:0505:0505::5

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2002:505:505::5, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 68/68/72 ms

Sweet! NOW…we still don’t have connectivity to our actual IPv6 LAN blocks. That can be fixed with some quick static routing

R2(config)#ipv6 route 2001:4444:4444:4444::/64 2002:0404:0404::4
R2(config)#ipv6 route 2001:5555:5555:5555::/64 2002:0505:0505::5

R4(config)#ipv6 route 2001:2222:2222:2222::/64 2002:0202:0202::2
R4(config)#ipv6 route 2001:5555:5555:5555::/64 2002:0505:0505::5

R5(config)#ipv6 route 2001:2222:2222:2222::/64 2002:0202:0202::2
R5(config)#ipv6 route 2001:4444:4444:4444::/64 2002:0404:0404::4

To grasp this concept, you need to understand recursive routing Think about what happens if R2 wants to ping 2001:4444:4444:4444::1. R2 does an ipv6 route lookup and sees the following entry

S   2001:4444:4444:4444::/64 [1/0]
     via 2002:404:404::4

The next-hop for the static route is 2002:404:404::4. For the router to know how to get to 2002:404:404::4 we need to do a recursive route lookup. We then find our static route out the tunnel to 2002::/16

R2#sh ipv6 route 2002:404:404::4
Routing entry for 2002::/16
  Known via "static", distance 1, metric 0
  Route count is 1/1, share count 0
  Routing paths:
    directly connected via Tunnel0
      Last updated 00:23:44 ago

So, we send the packet out the tunnel and our encapsulation process happens again as described above. Let’s test!

R2#ping 2001:4444:4444:4444::1 so fa0/0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:4444:4444:4444::1, timeout is 2 seconds:
Packet sent with a source address of 2001:2222:2222:2222::1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 136/136/136 ms

R2#ping 2001:5555:5555:5555::1 so fa0/0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:5555:5555:5555::1, timeout is 2 seconds:
Packet sent with a source address of 2001:2222:2222:2222::1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 68/68/72 ms

Man, this is a pretty awesome technology!

Summary

With IPv6 emerging as the new routed L3 protocol of choice, there will be situations where we need to connect IPv6 islands over an IPv4 infrastructure. Automatic 6to4 tunnels are one of a few ways to accomplish that. 6to4 tunneling works by encoding IPv4 addresses into part of the IPv6 address and uses multipoint technology

Advertisements

November 25, 2011 Posted by | Uncategorized | Leave a comment

No Broadcasts in IPv6, then how can one ARP? Here is the way

Introduction

An IPv6 solicited-node address is a link-local multicast address used in IPv6.  Solicited-node IPv6 multicast addresses are used in IPv6 neighbor solicitation messages for layer 3 to layer 2 address resolution.  The use of solicited-node addresses for the function of layer 3 to layer 2 address resolution is far more efficient than something like ARP, which was used for the same purpose in IPv4.

The Problem

If you are reading an article on solicited-node IPv6 addresses, then you probably already know that the generally accepted standard for IPv6 subnets is to allocate a /64 for every subnet on your network.  The first 64 bits of your 128 bit IPv6 address would be used for the network ID where the last 64 bits would be used for your host ID.  Using /64 subnets is easy and allows us to use neat features like automatic IPv6 addressing for our hosts.

OK, so what?  That is a LOT of addresses…I mean a LOT of addresses.  Actually 2^64 possible addresses per segment. That means having a potentially insane amount of hosts attached to the same subnet/VLAN.  For the last decade or more us network engineers have been pushed to be as efficient as possible with our subnet allocations and for good reasons.  We have all been taught to keep our layer 3 subnets and VLANs as small as possible for many reasons.  One of the main reasons was to keep broadcast domains small.  If we had a broadcast domain that was too large, the sheer amount of broadcast traffic on the segment could make our network performance suffer.

One of the biggest challenges we had to worry about there was ARP, the address resolution protocol.  Recall that an ARP request is a layer 2 broadcast sent to the MAC address FF:FF:FF:FF:FF:FF.  ARP is of course used for layer 3 to layer 2 address resolution.  If host A wants to talk to host B and they are on the same ethernet segment, host A would have to broadcast an ARP request requesting host B’s layer 2 MAC address.  This ARP broadcast would in reality be received by every host on the segment.  If our broadcast domain was too large, we could start to see problems with performance. In essence, ARP didn’t scale very well and was not very efficient.

To broadcast or not to broadcast, that is the question

So where does that leave us with IPv6?  If we are to use /64 subnets with potentially billions of hosts on each segment, doesn’t that leave us with a totally unscalable solution for address resolution?  Well, only if we continued to use a broadcast based solution like ARP, and luckily we don’t!  ARP is out, and IPv6 neighbor discovery protocol (ND) is in.  The rules have changed, and there are lots of exciting new features with this protocol suite.

Actually, the entire concept of a broadcast has gone away completely in IPv6.  That’s right, there ARE NO broadcasts.  They are not defined in IPv6.  They do not exist.  We do have a pseudo-broadcast implemented by using the all hosts multicast address for certain things, but for all practical purposes broadcasts are gone in IPv6.

The Solution: IPv6 Solicited-Node Addresses

So if we don’t have ARP and we can’t broadcast at all, how do we solve the problem of address resolution in IPv6.  IPv6 uses the neighbor discovery protocol for these purposes.  Neighbor discovery is part of ICMPv6 and has a few different types of messages defined.  For layer 3 to layer 2 address resolution, we have the neighbor solicitation message and neighbor advertisement message.  The idea is very much like ARP, it just works differently and much more efficiently.  Essentially, host A sends a neighbor solicitation to host B asking for host B’s MAC address.  Host B then responds.  The magic is that host A ONLY asks host B, not everybody like in ARP.  There is no broadcasting involved.  That is where solicited-node addresses come in.

Basically, every IPv6 interface derives a solicited-node address from it’s link-local IPv6 address.  That solicited-node address is actually an IPv6 multicast address.  The host then joins this IPv6 multicast group and at that point is “listening” for messages destined to that multicast group.  When host A wants to get the MAC address of host B, host A simply sends an IPv6 neighbor solicitation message multicast to the solicited-node address of host B.  Host A knows what this address is because host A knows the standard solicited node prefix and it knows host B’s link local IPv6 address. Since this is an IPv6 multicast, only members of that multicast group will receive the request!  Brilliant!!!

So, what is the magic formula?  It is quite simple.  We take the last 24 bits of our IPv6 address and we prepend it with the prefix ff02:0:0:0:0:1:ff00::/104. We then have 104 bit prefix + the last 24 bits of our IPv6 address for a total of 128 bits.

Example

Let’s say we have two hosts on an ethernet segment, host A and host B.  host A has the IPv6 link-local address fe80:100:100:100::A/64 and host B has the link-local address fe80:100:100:100::B/64.  Host A wants to communicate with host B.  Let’s look at the steps

1) Host A will send a neighbor solicitation message to the solicited-node address of host B asking host B what it’s MAC address is.  Host A derives the solicited-node address by taking the prefix ff02:0:0:0:0:1:ff00::/104 and prepending it to the last 24 bits of host B’s link-local address.  The last 24 bits are 0000 0000 0000 0000 0000 1011.  This gives us ff02:0:0:0:0:1:ff00:000B.  We can shorten this to ff02::1:ff00:B.

2) Host B has already figured out it’s solicited-node address and has joined the IPv6 multicast group ff02::1:ff00:B using MLD (IPv6 replacement for IGMP).  Since Host B is a member of the multicast group ff02::1:ff00:B it “hears” the neighbor solicitation request from host A

3) Host B replies with it’s MAC address in the payload of a neighbor advertisement message destined to Host A

*NOTE* These solicited-node multicast addresses are IPv6 layer 3 multicast addresses.  What about layer 2?  If a switch gets a layer 2 multicast message it forwards it to every port in the VLAN.  That kind of defeats the purpose.  That’s why we have MLD snooping to make sure that only the proper switch ports receive the multicast message and that they don’t get flooded out everywhere.

Summary

That about does it for IPv6 solicited-node addresses.  Essentially, the solicited node address is a link-local multicast address derived from a host’s link-local IPv6 address that is used in conjunction with IPv6 neighbor discovery to offer efficient and scalable L3/L2 address resolution.

I know that I for one was wondering for a long time what the repercussions of using /64 bit subnets would be with regards to “broadcast” domains and IPv6, and I’m glad I dug into this technology.

November 15, 2011 Posted by | Uncategorized | 2 Comments

Meet our beloved “Ether” Net

Introduction

Most of us take modern day Ethernet for granted.  This is probably because it is what many of us have always known.  This is especially true if you are like me and got into this crazy business .  Today, Ethernet is a globally recognized and widely used standard.  It is used in networks all over the world, and there really isn’t anything to hold a candle to it in terms of local area networks.

Things weren’t always that way.  Ethernet has evolved over the years, and things have only in the last 15 years or so settled down to what we know and love today.  One of the most notable changes in the evolution of Ethernet has been the frame format.  Today, we will look at the different Ethernet frame formats that have existed over the years.

Brief History Of Ethernet

Why do we have all these different frame types in the first place?  Well, in 1973 this guy named Bob Metcalfe invented the first experimental version of Ethernet for Xerox at Palo Alto labs.  It was based on an early packet radio network called ALOHANET.  Anyways, after that, Digital Equipment Corporation, Intel and Xerox all got together to create their “official” ethernet standard.  This became known as the DIX consortium, and they created DIX ethernet, sometimes known as ethernet II.  Well guess what?  Everybody liked ethernet, and when that happens the industry itself usually wants to standardize things.  In this case, ethernet was something everybody wanted but that only these three huge corporations could control.  Enter the IEEE standardization process.  The IEEE jumped in and decided they would standardize ethernet for the masses.  The 802.3 working group was created for this purpose, and that is why every modern day ethernet standard is 802.3something.  The IEEE being the IEEE couldn’t just rip of DIX ethernet and call it their own — no they had to change it.  This is really why we had different formats to begin with

Original DIX Ethernet (Ethernet II)

The original DIX Ethernet was based on Metcalfe’s work at Xerox.  The header looked like what we have below, and was awesome.  Simple, to the point and it worked.

Pretty simple huh?  Notice the 2 byte type field.  In that field, there would be a 2 byte value indicating what the layer 3 protocol ethernet was carrying inside of it was.  For instance, IP is type value 0×0800 while ARP is 0×0806.  That way, the receiving device would know what to pass the frame up the network stack to.

Original IEEE 802.3

Now, the IEEE came along and changed things around a bit.  Their idea of course was still mostly based on the DIX format, but they did screw with a few things.  Below we first have the same DIX frame I showed you earlier, followed by the original IEEE format for comparison.

First off, they changed the preamble.  They basically ripped off the same exact idea, but called it two different things instead of one.  Then we have the big thing…after the source address field in the DIX header we had type.  In the IEEE header, that was replaced with something called length.

In the IEEE version, they decided to hard code the length of the frame in this 2 byte field.  How in the world would the receiving end know what layer 3 protocol the ethernet frame was carrying then?  Well, they had to invent something else for that!  That is where the 802.2 LLC header comes into play.

The 802.2 header immediately follows the length field and has 3 fields of it’s own — DSAP, SSAP and ctrl.  Instead of just saying “Hey I’m carrying IP” or whatever layer 3 protocol, the IEEE decided to specify the source protocol and the destination protocol (SSAP and DSAP).  So follow me here…you had all the usual junk, then you had the length field, then after that, as part of a completely different header called LLC you had SSAP and DSAP which told you what protocol ethernet was carrying.  What a pain in the butt. I assure you, it gets worse : )

As it turns out, mucking around with a simple idea and making it more cryptic wasn’t the greatest idea for the IEEE.  You see, they figured out later that making the field that specifies what upper layer protocol ethernet is carrying (the DSAP field) only 1 byte instead of 2 was a terrible idea. With only 1 byte, that limited them to 256 values.  On top of that, they used some of those bits for other things, so that left it extremely limited.  Uh-Oh….and so we have IEEE 802.3 with SNAP extensions : )

IEEE 802.3 with SNAP

This is the part in the story where it actually becomes pretty funny to me.  IEEE screwed up with a 1 byte DSAP field.  They knew it, and everybody knew it.  Solution?  Bow out gracefully, and return peace by changing the standard back to something that makes sense? No, let’s screw things up even more with an even more cryptic frame format, ANOTHER new header and more overhead : )  IEEE needed a fix.  They didn’t have enough room in the DSAP field for the appease the industry.  They also didn’t have a freaking DSAP value for ARP which KIND OF CAUSES A PROBLEM FOR IP traffic.  What they did was create an additional header called SNAP that goes after the LLC header.  In that new SNAP header they had, suprise!!!! A TWO BYTE type field ….which is sort of what DIX said to begin with.  Here it is

So the idea was this…IF the values of DSAP and SSAP were both 0xAA that was sort of the secret code to go ahead and know there was a SNAP header after the LLC header.  In the SNAP header Type field they had 2 bytes to work with, and everything was OK.  Sigh…I feel dirty.

Making It Work

Guess what?  Some companies ran DIX ethernet, some ran IEEE.  Since the frame formats were different, how would a piece of equipment understand which one it was?  Well, the main difference was the type/length field right?  They figured that the maximum size of an ethernet frame was 1500 bytes.  So…if what came after the source address field was <= 1500 bytes that meant it MUST be talking about the length of the frame, and therefore it MUST be IEEE 802.3.  If the field after the source address was >= 1536 bytes that meant the frame was DIX Ethernet II and that the field was talking about the ethertype value.  Well what happened to 1501 – 1535?  “Undefined” : )

So basically if you figured out the frame was IEEE then you looked at the LLC header field at the DSAP value to see what the frame was carrying inside it.  If the DSAP and SSAP both happened to be 0xAA then you looked even further into the SNAP header. If you figured out the frame was DIX, it was very simple — Look at the type value to find out what you are carrying.

In the middle of all that craziness, you had Novell trying to screw things up even more.  You see, Novell was working on their very own layer 3 routing protocol at the time. That protocol was IPX.  They wanted to use this new ethernet thing to carry IPX on local area networks.  But hey…why bother following the standards, we’ll just make our very own proprietary ethernet frame format!  Novell basically ripped off the IEEE 802.3 frame, but guess what?  They modified it so that there was no concept of the LLC header…no DSAP, SSAP or SNAP garbage.  Why?  They ONLY wanted it to carry IPX, no other layer 3 protocols.  Therefore, they didn’t have a need to specify what layer 3 protocol was being carried in the ethernet frame.  If it was novell, it was IPX baby!  This became known as Novell Ethernet or RAW Ethernet.

Redemption: 1997 IEEE 802.3 Revised

After all the years, all the craziness, all the blood shed, and all the standards, the IEEE actually did something that made sense.  They made peace with the collective ethernet world and basically said “OK we get it…we were wrong. You win.”  How did they do that?  They revised the 802.3 standard to formally acknowledge both the original DIX frame and the original IEEE frame format for compatibility.  Check it out

Now the field after source address in the IEEE 802.3 header is officially called “length/type”.  Same rules apply here, they are just officially and formally recognized.  Peace at last!

The last header here is what has been widely accepted as “standard” since 1997. It’s always nice to appreciate history though.  You will gain a better understanding of why things work the way they do now!

November 15, 2011 Posted by | Uncategorized | 6 Comments