How is next hop defined in routing table?

Solution 1:

My guess is that the "rtnetlink reply: invalid argument" error is because either the IP address, mask, and gateway are not of the same class (class A or B or C); or because a "static" address conflicts with some DHCP range of addresses.

The table for R8 in your schema is not a routing table, but describes what R8 will do with addresses. Where it says for example 10.0.0.0, this should be taken to mean the 10.0.0.0/24 network segment rather than the IP address.

For sub-networks not directly accessible from R8, such as 16.0.0.0/24, the routing table will direct the message to the router that is the nearest to the target network, and that router will then pass on the message according to its own routing table. In this case, messages addressed to 16.0.0.X get passed to the gateway 10.0.0.2, which is the address of R7, which will forward them to the right recipient.

The routing command executed in R8 should look similar to :

ip route add 16.0.0.0/24 via 10.0.0.2 src 10.0.0.1

The src parameter is used when adding a route to a multihomed host, to have control over the source IP address your host is sending from. It can be omitted in simple cases. This will ensure here that the return message will return through the 10.0.0.0/24 sub-network, but other values can be used if we prefer R7, for some reason, not to return the message through that sub-network.

Note that the src you are giving would only affect the traffic originating at your end. If a foreign packet is being routed, it obviously would already have a source IP address, so it would normally be passed on unaltered (unless using NAT, and this can also be overridden).

I note that in general one does not need to supply routes for every destination. Just like a computer can specify a default gateway in its routing table, which is a catch-all address that receives all messages to addresses that it does not know, so does a router have its own routing table that can contain a gateway. The router's gateway address is represented by the default route of 0.0.0.0.

Note that it is entirely possible to even set up a gateways circuit in the network, for example :
R1 ➝ R4 ➝ R8 ➝ R7 ➝ R6 ➝ R2 ➝ R1.
The number of hops is not optimized here, but messages will still get from every sub-network to every other sub-network. Good network design will normally include one or more centralized routers, in order to minimize the number of hops.

Solution 2:

The other ones are more than one hop (router) away. As far as router R8 is concerned it only wants to know the interface to use and the IP of the next router in line to reach the destination network, then it goes to the next router and that router uses it's own routing table to determine the next hop. So to get to the 15.0.0.0 network the routing table defines interface 3, which is 13.0.0.4 and the hop is the next router it is going to which is 13.0.0.2. Once the traffic is received by R2 then R2 will use it's own routing table to determine the best route to the 15.0.0.0 network, which would be out the 15.0.0.1 interface.

Solution 3:

I'm not sure from where your design and routing table come from. Anyway in an environment like yours, the routes to the remote networks are usually defined through routing protocols (ie. dynamic routing); the use of static routes (defined by the user/admin), with all the redundant paths you have, will cause routing loops or black holes eventually.

In other words, every subnet of your diagram can be reached through every interface of R8 actually, depending by the configuration of the other routers.

For instance: if you define the interface 1 of R8 as the next hop for 14.0.0.0 (meaning that packets destined to any IP of the 14.0.0.0/? subnet will be sent out the interface 1), and if R4 (the actual next-hop out of interface 1 of R8) has another static to 14.0.0.0 through R1, your packet will cross R8->R4->R1->Destination. On the other side, if in this example you still send your packet for 14.0.0.0 to R4, but R4 is configured with a different static for 14.0.0.0 that points to R8, you will have a routing loop and your packet will bounce between R8 and R4 until its TTL will expire.

The same theory is applicable to any other remote network like 12.0.0.0, where it is less obvious if R8 should forward its packet to R2 or R4.

The main thing to remember is that IP packets don't have memory, they're just forwarded by evaluating their destination (ie. routers don't take care about the interface from where the packet was received - unless you use things like source-routing but it's not the case here).

The table you posted doesn't show if static or dynamic routing is used (it misses also the subnet of those networks), but unless this is a particular theoretic exercise, dynamic routing is what you need.

Dynamic routing can define the best path from a router to a destination network, by using different parameters like number of hop, bandwidth, latency, and so (depending by the specific dynamic routing protocol). Also, they can manage failures of redundant links properly.

As another example, if you decide to put a static for 12.0.0.0 pointing to R3 and R3 router crashes, you will continue to forward packets destined to 12.0.0.5 (for instance) to a black hole. If you decide to load balance to 12.0.0.0 with 2 routes (with same metric) through R3 and R4, if R4 goes down (or one of its interfaces is broken), R8 will continue to forward the packet 1 to R3, the packet 2 to R4, the packet 3 to R3, and so on. This will cause apparently random things, because if the packets use TCP, the missed ones will be retransmitted, making less obvious that half of your traffic is trashed (eg. intermittent loss of line of some services, slowness, etc.).

If you're using Linux, Quagga can be the software to use for dynamic routing, but the assumption is that other routers are running a dynamic routing protocol.

However, if your goal is to set a static route, these commands should work (I'm assuming /24 but if classful it might be a /8):

ip route add 14.0.0.0/24 dev eth3

same of:

ip route add 14.0.0.0/24 via 13.0.0.2

Anyway the second one is usually preferred in a multiaccess network (no multicast/broadcast traffic needed, no tons of ARP requests, etc.).