EIGRP Part 1

Submitted by rayc on Tue, 11/16/2021 - 08:09

EIGRP is considered a hybrid distance vector protocol. While EIGRP does keep track of hop count as a metric, it doesn't so much use it as a metric like RIP does. Instead EIGRP uses path attributes to determine the best route. Don't worry too much about these path attributes as I will go through them later.

Let's start with how EIGRP sends routing information. EIGRP uses the multicast address 224.0.0.9 to send its messages using the EIGRP protocol number 88. There are 5 types of EIGRP messages that a router will send.

Message Type Message Function
Hello Used to establish EIGRP neighbour relationships and also as a form of keepalive.
Update Used to send routing updates to neighbours
Request Used to request more detailed information about a route
Query used to query other routers for an alternate path
Reply used to reply to query messages

 

The hello messages by default are sent every 5 seconds (minus a random time interval to prevent syncronisation) unless the link is at a T1 speed (1.544Mbps) or slower. If the link is T1 or slower, then hello messages are sent every 60 seconds (These types of links use unicast messages). These hello messages contain information about the sending neighbour including the EIGRP version that is running, the router-id, the AS number, Hold Time and the K values that are set. Below is a screenshot of the header and payload information in an EIGRP Hello packet.

EIGRP Hello message header and payload

Within this header is the information that is required in order for an EIGRP router to become a neighbour. If an EIGRP router hears a hello message and certain attributes don't match, then no neighbour relationship will form. In order for two EIGRP routers to become neighbours, the following must match:

  • AS Number
  • Authentication
  • K Values

 

While the Hello interval doesn't have to match, it is advised to have the time set on both sides as if you configure the hello interface for a time that is greater than the hold interval on the other router the neighbour relationship will flap. The same can be said about configuring the hold time for a period that is shorter than the hello interval.

EIGRP Metrics

Let's talk about the EIGRP metrics as it can seem quite complex when you first look at it. As I mentioned above, in order for two EIGRP routers to become neighbours, one of the attributes that must match is their K values. But what are K values? Well K values are part of the mathematical formula that EIGRP uses in order to determine the best path to a prefix. From the packet capture, you can see that there are 5 K values. Coincidentally there are 5 attributes for a path that are used for metric calculation, minimum bandwidth, total delay, load, reliability and MTU. That is just a coincidence though as the 5 K values, do not relate to those metric types at all. They simply tell the router which path attributes to use in the EIGRP formula. The full EIGRP formula is as follows:

metric = 256 * [{K1 * (107/Min-BW)+((107/K2 * min-BW)/256-Load)+(K3 *( Total-Delay/10))+(K5/(K4 +Reliability)).

Okay so that looks like a mouthful and a half of a path selection formula but when you break it down to what K values are set to 1 (K1 and K3), it simplifies a bit as K2, K4, and K5 are multiplied by 0, nulling those variables out. Using default values, the formula simplifies to the following:

metric = 256 * [{K1 * (107/min-BW) + K3 * (total-Delay/10)}]

Having the K Values set to 1 breaks it down to:

metric = 256 * [{1 * {107/min-BW) + 1 * (total-delay/10)}]

Calculating the metric based on the below topology and default K values, would mean that for R3 to reach R1's loopback interface 1.1.1.1/32, you would take the total delay out the interfaces G0/0 on R2 and the Lo0 interface on R1 + the minimum bandwidth which is the Gigabit interfaces in this instance as the Loopback interface bandwidth by default is 8Gbps. The total delay to reach the 1.1.1.1/32 network is the delay of the loopback Interface (5000) + R2 g0/0 interface (10), + R3's G1/0 interface (10) making it 5020.

Example topology to calculate EIGRP metric value

The formula becomes 256 * (107/1000000 + 5020/10) = 131072.

sh ip route 1.1.1.1 from R3

You can change the K values that are used for the metric calculation in EIGRP by using the eigrp router configuration subcommand metric weights <type> <K1> <K2> <K3> <K4> <K5>. The type keyword refers to TOS value but only a value of 0 is supported. By default the K values are set as follows, metric weights 0 1 0 1 0 0 but the values for each K value can range from 0 to 255. 

metric weights command

But what if the interface speed is greater than 10Gbps? Well EIGRP has you covered by using wide metrics. To do this, EIGRP does a few things. There is an additional K value added to the formula, K6, and the scale has changed from 256 to 65536. Also, latency is now measured in picoseconds instead of microseconds. This makes the new formula:

Wide Metric Formula

This allows for EIGRP metrics to be scalable for links of up to 655Tbps.

To calculate the same route to 1.1.1.1/32 from R3 using wide metrics, we once again take the default K values (still K1 and K3 only) but instead of multiplying it by 256, we multiply it by 65536 and convert the delay into picoseconds. The delay for R3 and R2's Gigabit interfaces becomes 10000000 each, and the delay for R1's Lo0 interface becomes 5000000000 making the total delay, 5020000000. If we plug those values plus the minimum bandwidth value into the above formula, we get a metric of 329646080.

show ip route 1.1.1.1 with wide metrics

Wide metrics are also backward compatible with standard metrics, as long as the K values from 1-5 match and K6 is not set. If they match, then the neighbours will form an adjacency and advertise routes. When this happens, an EIGRP router using wide metrics detects the standard metric neighbour and scales back the metric calculation when sending updates. 

EIGRP path selection

When two EIGRP routers join a network and start sending hellos and establish an neighbour relationship, they then start sending update messages to each other to exchange their entire routing table. This entire route table update is sent only once when the routers become neighbours, after that there are no periodic full updates, only triggered partial updates. 

Once all routes have been received, the router then needs to choose the best path to take to reach each prefix. There's a lot more to the process than I'm about to describe but I'll go through it in more detail later. So, now all routes are exchanged and the router has found the best metric to a prefix and added it to the route table. This route is called the successor route and the next hop ip is the successor for that route. The metric value to reach that route is called the Feasibile Distance (FD). When you look at the output of the show ip eigrp topology command though, you can see a metric value of [metric[anothervalue]]. This value next to the route metric is called the Reported Distance (RD). The RD is the metric value to that prefix, from the advertising routers point of view. 

showing EIGRP topology table FD and RD values

EIGRP has a route condition called the Feasibility Condition (FC). What the FC is, is that if a neighbouring routers RD, is less than the FD for a route, then that route becomes the Feasible Successor (FS). A FS route is essentially an alternate loop free route to that prefix should the SR fail. You can find FS routes by looking at the EIGRP topology table using the show command show ip eigrp topology

showing R3's EIGRP FS routes

When looking at the above output, if there are two entries for a route to a prefix and the metrics are not identical, then it is a Feasible Successor route. You can also view the metric values for all links and all routes using the keywork all-link at the end of the command show ip eigrp topology.

show ip eigrp topology all-links from R3

Load balancing

Like most other routing protocols, EIGRP supports Equal Cost Load Balancing or Equal Cost MultiPathing (ECMP). ECMP is when you have multiple routes to the same destination with the same metric value through different next-hop addresses. What really separates EIGRP from other routing protocols is the support for Unequal Cost MultiPathing (UCMP).

When an EIGRP router has a FS route, it is possible to configure EIGRP to add that route to the route table and load balance traffic a cross the secondary path. To do this, you configure the metric variance. The variance is a multiplier that tells the router that any FS route that has a metric less than the FD x Variance, add it to the route table. Using our FS example above and non wide metrics, we can see that the FD for the successor is 131072 and the FD for the FS route is 2298112. Taking these values, we divide the FS FD by the Successor FD, and get the variance of 17.5. To configure the variance use the router eigrp configuration subcommand variance <value>. Because we need whole numbers, we always round up when it comes to variance so we need to set the value to 18.

Configuring UCMP on R3 by changing the variance to 18

With EIGRP, the load balancing across UCMP links is not equal. EIGRP will chare the load based on the metric percentages. If we take a look at the output of the show ip route 1.1.1.1 command, we can see that the path via the serial interface, has a traffic share count of 7, and the G1/0 interface has a traffic count of 120.

traffic share count using UCMP

EIGRP Convergence

When an EIGRP router is not performing any DUAL computations, the topology is considered stable, and all routes are considered as in a  Passive state. When an EIGRP router looses a route to a prefix, a few things happen. If the router has a FS route installed in the EIGRP topology table, that route will take over and an Update message is sent to all neighbours advising of the change. The route in this scenario stays in a passive state as the computation is local to thst router. If there is no FS route, the router will sent a Query message requesting information about a possible path to the prefix. When a neighbouring router receives a Query message, it will respond with an Ack, which is a Hello message with the Acknowledgment flag set, to say yes, i've heard your Query and will look for a route. The router that received the query will then do one of two things. If the router has no other route in it's RIB, it will continue to send a Query message of its own to all of it's downstream neighbours. This Query/reply process continues on until all Queries, have heard replies and the route is then removed from the topology if no alternate path is found. If the downstream router has a route to the prefix being Queried, it will respond with an Ak, and an Update message saying yes, I have these prefixes in my topology table, this is my information about them. The Update message is then responded to with an Ack by both peers and the EIGRP topology settles and the routes become passive again. 

Packet capture of EIGRP convergence process

From the output below you can see that the route to 3.3.3.3 is currently active and is being queried. 

sh ip eigrp topology output showing a route as Active

If a route stays in active too long (3 minutes by default) the route is considered SIA (Stuck In Active). If this happens the neighbour that did not reply is removed from the neighbour table and the diffusing computation will consider that neighbour to have an infinite metric. 

Route stuck in active

Below is a debug output of a route Query that is sent using the debug command debug eigrp packets query reply ack update SIAquery SIAreply. 

*Nov 23 15:39:53.711: EIGRP: Received QUERY on Gi0/0 - paklen 45 nbr 10.1.12.2
*Nov 23 15:39:53.711:   AS 100, Flags 0x0:(NULL), Seq 56/0 interfaceQ 0/0 iidbQ un/rely 0/0 peerQ un/rely 0/0
*Nov 23 15:39:53.715:   {type = 602, length = 45}
*Nov 23 15:39:53.719:   {vector = {afi = 1, tid = 0}
*Nov 23 15:39:53.719:             {routerid = 3.3.3.3
*Nov 23 15:39:53.723:             {offset = 0, priority = 0, reliability = 204, load = 0,
*Nov 23 15:39:53.723:              mtu = {0:[00, 00, 00]), hopcount = 255,
*Nov 23 15:39:53.723:              delay = 281474976710655, bw = 4294967295,
*Nov 23 15:39:53.727:              reserved = 00, opaque_flags = 04}
*Nov 23 15:39:53.727:             {nh:00000000}
*Nov 23 15:39:53.735:             {20030303 03}
*Nov 23 15:39:53.743:   }
*Nov 23 15:39:53.743: EIGRP: Enqueueing ACK on Gi0/0 - paklen 0 nbr 10.1.12.2 tid 0
*Nov 23 15:39:53.743:   Ack seq 56 iidbQ un/rely 0/0 peerQ un/rely 1/0 route: 3.3.3.3/32
*Nov 23 15:39:53.747: EIGRP: Sending ACK on Gi0/0 - paklen 0 nbr 10.1.12.2 tid 0
*Nov 23 15:39:53.751:   AS 100, Flags 0x0:(NULL), Seq 0/56 interfaceQ 0/0 iidbQ un/rely 0/0 peerQ un/rely 1/0
*Nov 23 15:39:53.755: EIGRP: Enqueueing QUERY on Gi1/0 - paklen 0 tid 0 iidbQ un/rely 0/1 serno 117-117
*Nov 23 15:39:53.763: EIGRP: Sending QUERY on Gi1/0 - paklen 45 tid 0
*Nov 23 15:39:53.763:   AS 100, Flags 0x0:(NULL), Seq 70/0 interfaceQ 0/0 iidbQ un/rely 0/0 serno 117-117
*Nov 23 15:39:53.767:   {type = 602, length = 45}
*Nov 23 15:39:53.767:   {vector = {afi = 1, tid = 0}
*Nov 23 15:39:53.771:             {routerid = 3.3.3.3
*Nov 23 15:39:53.771:             {offset = 0, priority = 0, reliability = 204, load = 0,
*Nov 23 15:39:53.775:              mtu = {0:[00, 00, 00]), hopcount = 255,
*Nov 23 15:39:53.775:              delay = 281474976710655, bw = 4294967295,
*Nov 23 15:39:53.775:              reserved = 00, opaque_flags = 04}
*Nov 23 15:39:53.775:             {nh:00000000}
*Nov 23 15:39:53.775:      {20030303 03}
*Nov 23 15:39:53.775:   }
*Nov 23 15:39:53.775: EIGRP: Enqueueing QUERY on Gi0/0 - paklen 0 tid 0 iidbQ un/rely 0/1 serno 117-117
*Nov 23 15:39:53.799: EIGRP: Received ACK on Gi1/0 - paklen 0 nbr 10.1.14.4
*Nov 23 15:39:53.803:   AS 100, Flags 0x0:(NULL), Seq 0/70 interfaceQ 0/0 iidbQ un/rely 0/0 peerQ un/rely 0/1
*Nov 23 15:39:53.919: EIGRP: Received REPLY on Gi1/0 - paklen 45 nbr 10.1.14.4
*Nov 23 15:39:53.919:   AS 100, Flags 0x0:(NULL), Seq 59/70 interfaceQ 0/0 iidbQ un/rely 0/0 peerQ un/rely 0/0
*Nov 23 15:39:53.923:   {type = 602, length = 45}
*Nov 23 15:39:53.923:   {vector = {afi = 1, tid = 0}
*Nov 23 15:39:53.927:             {routerid = 3.3.3.3
*Nov 23 15:39:53.927:             {offset = 0, priority = 0, reliability = 204, load = 0,
*Nov 23 15:39:53.931:              mtu = {0:[00, 00, 00]), hopcount = 255,
*Nov 23 15:39:53.931:              delay = 281474976710655, bw = 4294967295,
*Nov 23 15:39:53.935:              reserved = 00, opaque_flags = 00}
*Nov 23 15:39:53.935:             {nh:00000000}
*Nov 23 15:39:53.939:             {20030303 03}
*Nov 23 15:39:53.947:   }
*Nov 23 15:39:53.951: EIGRP: Enqueueing ACK on Gi1/0 - paklen 0 nbr 10.1.14.4 tid 0
*Nov 23 15:39:53.951:   Ack seq 59 iidbQ un/rely 0/0 peerQ un/rely 1/0 route: 3.3.3.3/32
*Nov 23 15:39:53.963: EIGRP: Sending ACK on Gi1/0 - paklen 0 nbr 10.1.14.4 tid 0
*Nov 23 15:39:53.967:   AS 100, Flags 0x0:(NULL), Seq 0/59 interfaceQ 0/0 iidbQ un/rely 0/0 peerQ un/rely 1/0
*Nov 23 15:39:53.971: EIGRP: Enqueueing REPLY on Gi0/0 - paklen 0 nbr 10.1.12.2 tid 0 iidbQ un/rely 0/1 peerQ un/rely 0/0 serno 118-118
*Nov 23 15:39:53.987: EIGRP: Sending REPLY on Gi0/0 - paklen 45 nbr 10.1.12.2 tid 0
*Nov 23 15:39:53.991:   AS 100, Flags 0x0:(NULL), Seq 72/56 interfaceQ 0/0 iidbQ un/rely 0/0 peerQ un/rely 0/1 serno 118-118
*Nov 23 15:39:53.995:   {type = 602, length = 45}
*Nov 23 15:39:53.995:   {vector = {afi = 1, tid = 0}
*Nov 23 15:39:53.999:             {routerid = 3.3.3.3
*Nov 23 15:39:53.999:             {offset = 0, priority = 0, reliability = 204, load = 0,
*Nov 23 15:39:53.999:              mtu = {0:[00, 00, 00]), hopcount = 255,
*Nov 23 15:39:54.003:              delay = 281474976710655, bw = 4294967295,
*Nov 23 15:39:54.003:              reserved = 00, opaque_flags = 00}
*Nov 23 15:39:54.003:             {nh:00000000}
*Nov 23 15:39:54.011:             {20030303 03}
*Nov 23 15:39:54.019:   }
*Nov 23 15:39:54.071: EIGRP: Received ACK on Gi0/0 - paklen 0 nbr 10.1.12.2
*Nov 23 15:39:54.075:   AS 100, Flags 0x0:(NULL), Seq 0/72 interfaceQ 0/0 iidbQ un/rely 0/0 peerQ un/rely 0/1