mirror of
https://github.com/Wojtek242/route0.git
synced 2024-11-22 07:05:25 +01:00
Fixes to IP addresses and subnets lesson
This commit is contained in:
parent
a9787d6932
commit
c4658d3b4f
@ -1,57 +1,57 @@
|
|||||||
# IP Addresses and Subnets
|
# IP Addresses and Subnets
|
||||||
|
|
||||||
This lesson introduces and explains IP addresses, subnets, and routing between
|
This lesson introduces and explains IP addresses, subnets, and forwarding
|
||||||
directly connected devices.
|
between directly connected devices. Here, we will manually setup all the
|
||||||
|
interfaces and routes to achieve network connectivity for the `one_rtr`
|
||||||
|
topology. The best way to learn and understand what is going on with addresses
|
||||||
|
and routes is to actually manually setup the network and inspect the effects of
|
||||||
|
the individual pieces on the connectivity of the network.
|
||||||
|
|
||||||
This lesson is a continuation of the
|
## Starting the network
|
||||||
[introduction](introduction-to-route-0.md). Here, we will manually setup all
|
|
||||||
the interfaces and routes to achieve the network connectivity we had there for
|
|
||||||
the `one_rtr` topology.
|
|
||||||
|
|
||||||
## Assembling the network
|
Start the network as normal using the [`one_rtr` topology](../topology/one_rtr)
|
||||||
|
and the `plain` scenario
|
||||||
|
|
||||||
The best way to learn and understand what is going on with addresses and routes
|
|
||||||
is to actually manually setup the network and inspect the effects of the
|
|
||||||
individual pieces on the connectivity of the network.
|
|
||||||
|
|
||||||
Start the network just like in the introductory lesson, but this time with none
|
|
||||||
of the address and route configuration by running the `plain` scenario
|
|
||||||
```
|
```
|
||||||
sudo python route0.py --topology one_rtr --scenario plain
|
sudo python route0.py --topology one_rtr --scenario plain
|
||||||
```
|
```
|
||||||
|
|
||||||
Start by having a look around using the commands you learned in the previous
|
The plain scenario launches the network, but will not set up any addresses or
|
||||||
lesson, `ip address` and `ip route`, and notice how none of the addresses or
|
routes.
|
||||||
routes are present on any of the nodes. Furthermore, if you try running the
|
|
||||||
pings between any of the nodes, you will find they do not work and fail with a
|
|
||||||
`Network is unreachable` error. In this lesson we will manually reconstruct
|
|
||||||
the `basic` network to illustrate all the different concepts involved.
|
|
||||||
|
|
||||||
### Assigning IP addresses
|
Start by having a look around using the commands, `ip addr` and `ip route`, and
|
||||||
|
notice how no addresses or routes are present on any of the nodes.
|
||||||
|
Furthermore, if you try running the pings between any of the nodes using the
|
||||||
|
addresses specified for the [topology](../topology/one_rtr), you will find they
|
||||||
|
do not work and fail with a `Network is unreachable` error. In this lesson we
|
||||||
|
will manually reconstruct this network to illustrate all the different concepts
|
||||||
|
involved. The end result will behave just like the `basic` scenario for the
|
||||||
|
same topology.
|
||||||
|
|
||||||
|
## Assigning IP addresses
|
||||||
|
|
||||||
A good place to start would be to simply assign all the IP addresses as per the
|
A good place to start would be to simply assign all the IP addresses as per the
|
||||||
[`one_rtr` topology](../topology/one_rtr). The command to assign an IP address
|
[`one_rtr` topology](../topology/one_rtr). The command to assign an IP address
|
||||||
to an interface in Linux has the form
|
to an interface in Linux has the form
|
||||||
```
|
```
|
||||||
ip address add <ip>/<mask-digits> dev <if-name>
|
ip addr add <ip>/<mask-digits> dev <if-name>
|
||||||
```
|
```
|
||||||
|
|
||||||
This command assigns the address `<ip>` associated with the subnet defined by
|
This command assigns the address `<ip>` associated with the subnet defined by
|
||||||
the `<mask-digits>` to the interface `<if-name>`. This should be pretty
|
the `<mask-digits>` to the interface `<if-name>`. This should be pretty
|
||||||
self-explanatory except for the subnet which may be a new concept for some of
|
self-explanatory except for the subnet which may be a new concept.
|
||||||
you.
|
|
||||||
|
|
||||||
An IPv4 address is a 32-bit number. The common representation `x.x.x.x` simply
|
An IPv4 address is just a 32-bit number. The common representation `x.x.x.x`
|
||||||
splits this number into four 8-bit numbers making it more readable for a human.
|
simply splits this number into four 8-bit numbers making it more readable for a
|
||||||
This is why none of the four numbers ever exceed 255 as that is the largest
|
human. This is why none of the four numbers ever exceed 255 as that is the
|
||||||
number you can represent with 8 bits.
|
largest number you can represent with 8 bits.
|
||||||
|
|
||||||
A subnet is a subdivision of an IP network and determines all the possible IP
|
A subnet is a subdivision of an IP network and determines a subset of all the
|
||||||
addresses that can be connected directly to each other over a local network.
|
possible IP addresses that can be connected directly to each other over this
|
||||||
All IP addresses that belong to the same subnet are accessible through the same
|
subdivision, a local network. All IP addresses that belong to the same subnet
|
||||||
local network. Therefore, having an interface that is part of a particular
|
are accessible through the same local network. Having an interface that is
|
||||||
subnet means that we can communicate with all the other addresses in that
|
part of a particular subnet means that we can communicate with all the other
|
||||||
subnet by using this interface.
|
addresses in that subnet by using this interface.
|
||||||
|
|
||||||
The subnet of an IP address is determined by its prefix. The length in bits of
|
The subnet of an IP address is determined by its prefix. The length in bits of
|
||||||
the prefix is determine by the `mask-digits`. Thus, the IP address
|
the prefix is determine by the `mask-digits`. Thus, the IP address
|
||||||
@ -61,10 +61,16 @@ this subnet, such as `10.11.12.1` or `10.11.12.165`, over this interface.
|
|||||||
|
|
||||||
This is how in the example in the previous lesson `R1` was able to forward the
|
This is how in the example in the previous lesson `R1` was able to forward the
|
||||||
packet from `h1_1` to `h1_2`. `R1` received a packet addressed to `10.2.0.1`
|
packet from `h1_1` to `h1_2`. `R1` received a packet addressed to `10.2.0.1`
|
||||||
on its interface with `h1_1`. It quickly determined that `10.2.0.1` belongs to
|
on its interface with `h1_1`. It was able to then determine that `10.2.0.1`
|
||||||
the subnet `10.2.0.0/24` which is connected to its `R1-eth2` interface which
|
belongs to the subnet `10.2.0.0/24` which is connected to its `R1-eth2`
|
||||||
had the address `10.2.0.254/24`. Therefore, it was able to forward the packet
|
interface which had the address `10.2.0.254/24`. Therefore, it was able to
|
||||||
over this interface.
|
forward the packet over this interface.
|
||||||
|
|
||||||
|
Note that a subnet length does not have to match the 8-bit divisions and
|
||||||
|
subnets. `10.11.12.4/30` is also a valid subnet. Such subnets are very
|
||||||
|
practical as it allows an operator to assign a more appropriate number of IP
|
||||||
|
addresses to a particular network than would be otherwise possible. However,
|
||||||
|
we will avoid them in these lessons as they are harder to read.
|
||||||
|
|
||||||
Go ahead and assign all the IP addresses to the interfaces in the network.
|
Go ahead and assign all the IP addresses to the interfaces in the network.
|
||||||
Don't forget to prefix the commands with the name of the node on which you want
|
Don't forget to prefix the commands with the name of the node on which you want
|
||||||
@ -73,27 +79,23 @@ to run the command.
|
|||||||
Once all addresses have been assigned try pinging `h1_1` and `h1_2` from the
|
Once all addresses have been assigned try pinging `h1_1` and `h1_2` from the
|
||||||
middle node, `R1`, and verify that this works. You should also verify that
|
middle node, `R1`, and verify that this works. You should also verify that
|
||||||
both `h1_1` and `h1_2` are able to ping the IP address at the other end of
|
both `h1_1` and `h1_2` are able to ping the IP address at the other end of
|
||||||
their link. However, neither `h1_1` or `h1_2` should be able to ping the
|
their link, `10.1.0.254` and `10.2.0.254`. However, neither `h1_1` or `h1_2`
|
||||||
interface on the other side of `R1` or each other.
|
should be able to ping the other interface on `R1` or each other.
|
||||||
|
|
||||||
Try also running the `ip route` command on the nodes and notice how they have
|
Try also running the `ip route` command on the nodes and notice how they have
|
||||||
the routes associated with the interface subnets installed already without any
|
the routes associated with the interface subnets installed already without any
|
||||||
additional intervention.
|
additional intervention. Adding an IP address on a particular subnet on an
|
||||||
|
interface will automatically add a route to the kernel's routing table that
|
||||||
|
resolves that particular subnet to that interface.
|
||||||
|
|
||||||
|
If you try pinging an IP address that doesn't exist in the network but belongs
|
||||||
|
to a subnet connected to a local interface, such as `10.1.0.5` from `h1_1`, the
|
||||||
|
ping won't fail immediately like before. Instead it will look like it's stuck.
|
||||||
|
This is because it tries to send the request since it has a routing entry for
|
||||||
|
the particular subnet, but it isn't getting any replies.
|
||||||
|
|
||||||
## Address Resolution Protocol (ARP)
|
## Address Resolution Protocol (ARP)
|
||||||
|
|
||||||
In the previous section we said that packets for any address on a given subnet
|
|
||||||
are forwarded through the interface that belongs to that subnet. What if the
|
|
||||||
destination IP address is not connected to that subnet? In our `one_rtr`
|
|
||||||
example we only have `10.1.0.1` and `10.1.0.254` on the network on the subnet
|
|
||||||
`10.1.0.0/24` which is effectively a local network of one point-to-point link.
|
|
||||||
|
|
||||||
Try pinging `10.100.0.5` and `10.1.0.5` from `h1_1`. Notice how both fail, but
|
|
||||||
only the first one returns the `Network is unreachable` error. Why does the
|
|
||||||
second one appear to be stuck? Since `10.1.0.5` belongs to the same subnet as
|
|
||||||
`h1_1-eth1` the host tries to send the ping over this interface, but as the
|
|
||||||
other end does not exist, the response never arrives.
|
|
||||||
|
|
||||||
Let's investigate this using Wireshark. Set up `h1_1` to ping the nonexistent
|
Let's investigate this using Wireshark. Set up `h1_1` to ping the nonexistent
|
||||||
`10.1.0.5` and open Wireshark on its interface from a different terminal window
|
`10.1.0.5` and open Wireshark on its interface from a different terminal window
|
||||||
by running
|
by running
|
||||||
@ -106,10 +108,10 @@ The first thing you will notice is how `h1_1` keeps sending ARP protocol
|
|||||||
messages. ARP stands for the Address Resolution Protocol and is the mechanism
|
messages. ARP stands for the Address Resolution Protocol and is the mechanism
|
||||||
by which a node finds the MAC address of the interface associated with the
|
by which a node finds the MAC address of the interface associated with the
|
||||||
particular IP address. In order to send a packet over a link it must be
|
particular IP address. In order to send a packet over a link it must be
|
||||||
addressed to the right MAC address as otherwise no interface on the local
|
addressed to the right MAC address. Otherwise no interface on the local network
|
||||||
network will pick up the packet. In this case we see packets constantly asking
|
will pick up the packet as they will determine the packet is not addressed for
|
||||||
"Who has 10.1.0.5? Tell 10.1.0.1", but nobody owns that IP address so nobody
|
them. In this case we see packets constantly asking "Who has 10.1.0.5? Tell
|
||||||
responds.
|
10.1.0.1", but nobody owns that IP address so nobody responds.
|
||||||
|
|
||||||
Let's now look at what happens when the IP address exists on the network. Set
|
Let's now look at what happens when the IP address exists on the network. Set
|
||||||
`h1_1` to ping the other end of its link `10.1.0.254` (you don't have to close
|
`h1_1` to ping the other end of its link `10.1.0.254` (you don't have to close
|
||||||
@ -117,54 +119,65 @@ Wireshark). Most of the packets sent and received will be the already known
|
|||||||
ping packets, but every now and then an ARP request is sent. However, this
|
ping packets, but every now and then an ARP request is sent. However, this
|
||||||
time `h1_1` receives a response telling it the MAC address of the interface.
|
time `h1_1` receives a response telling it the MAC address of the interface.
|
||||||
If you inspect the ping packets that originate at `h1_1` you will notice that
|
If you inspect the ping packets that originate at `h1_1` you will notice that
|
||||||
they do use that MAC address as the destination in the Ethernet header.
|
they will use that MAC address as the destination in the Ethernet header.
|
||||||
|
|
||||||
You may wonder why do the nodes need to do this? After all the IP address
|
You may wonder why do the nodes need to do this? After all the IP address
|
||||||
already uniquely identifies the interface. This is because the IP protocol
|
already uniquely identifies the interface. This is because the IP protocol
|
||||||
doesn't actually know how to communicate over a local network using a physical
|
doesn't actually know how to communicate over a local network using a physical
|
||||||
interface, it needs another protocol to do it instead. In this case it's the
|
interface, it needs another protocol to do it instead. The physical
|
||||||
Ethernet protocol, but it could be something entirely different such as Wi-Fi
|
implementation of the local network may be different for different networks
|
||||||
or some older protocol. The ARP protocol is a tool for the IP protocol to find
|
such as Wi-Fi or Ethernet, but IP is able to run over any of them. However, in
|
||||||
out what address to give to the Ethernet protocol so that it can send its
|
order to be able to use the physical network protocol it needs to be able to
|
||||||
packet to the next node.
|
give it an address that protocol understands and it doesn't understand IP
|
||||||
|
addresses. ARP is a tool for IP to find out the physical address to give to
|
||||||
|
the underlying physical protocol, in this case Ethernet, so that it can send
|
||||||
|
its packet to the next node.
|
||||||
|
|
||||||
## Default routes
|
## Default routes
|
||||||
|
|
||||||
At this point `h1_1` and `h1_2` still cannot ping each other. If you try to
|
At this point `h1_1` and `h1_2` still cannot ping each other. If you try to
|
||||||
ping `10.2.0.1` from `h1_1` you will be told that the network is unreachable.
|
ping `10.2.0.1` from `h1_1` you will be told that the network is unreachable.
|
||||||
If you look at the output of `ip route` on the host this error makes sense.
|
If you look at the output of `ip route` on the host this error makes sense.
|
||||||
The routing table doesn't know how to reach any subnet other than
|
The routing table doesn't know how to reach any destination other than
|
||||||
`10.1.0.0/24`. We could just add a route for the `10.2.0.0/24` subnet to go
|
`10.1.0.0/24`. The obvious solution is to just add a route for the
|
||||||
via `R1` which would work for `h1_2`, but would fail as soon as any new host is
|
`10.2.0.0/24` subnet to go via `R1`. This would work for `h1_2` on this small
|
||||||
added to `R1`.
|
one router network, but would fail as soon as any new host is added to `R1`.
|
||||||
|
|
||||||
Instead we will add a default route to our host. A default route is the route
|
Instead we will add a default route to our host. A default route is the route
|
||||||
used for IP addresses that do not match any other more specific route. To add
|
used for IP addresses that do not match any other more specific route. A host
|
||||||
a default route we simply run
|
only has one interface so creating a default route is a pretty straightforward
|
||||||
|
affair. To add a default route we simply run
|
||||||
|
|
||||||
```
|
```
|
||||||
ip route add 0.0.0.0/0 via 10.1.0.254
|
ip route add 0.0.0.0/0 via 10.1.0.254
|
||||||
```
|
```
|
||||||
|
|
||||||
which tells `h1_1` to send all packets via `10.1.0.254` which is the IP address
|
which tells `h1_1` to send all packets via `10.1.0.254` which is the IP address
|
||||||
of the interface on `R1`. `h1_1` knows how to route to this address, because
|
of the interface on `R1` that is connected to `h1_1`. `h1_1` knows how to
|
||||||
it's on the same subnet as its own interface.
|
route to this address, because it's connected to the same subnet with
|
||||||
|
`h1_1-eth1`.
|
||||||
|
|
||||||
Why do we not just install a route to go via the interface directly instead of
|
Why do we not just install a route to go via the interface directly instead of
|
||||||
specifying an IP address? In our topology we only have one node connected to
|
specifying an IP address? In our topology we only have one node on the other
|
||||||
the local network, but in principle we could have more. In that case,
|
side of the local network, `R1`, but in principle we could have more. In that
|
||||||
specifying an interface would not uniquely identify the next hop.
|
case, specifying an interface would not uniquely identify the next hop which.
|
||||||
|
|
||||||
Try pinging `10.2.0.1` from `h1_1` now. You will notice that it no longer
|
Try pinging `10.2.0.1` from `h1_1` now. You will notice that it no longer
|
||||||
fails with a `Network is unreachable` error, but it still doesn't work. Let's
|
fails with a `Network is unreachable` error, but it still doesn't work. Let's
|
||||||
investigate using Wireshark. If you inspect the traffic at `h1_1` you will
|
investigate using Wireshark. If you inspect the traffic at `h1_1` you will
|
||||||
notice that the requests are being sent, but no responses are received. Let's
|
notice that the requests are being sent, but no responses are received. The
|
||||||
check if `R1` is forwarding the packets. If you launch Wireshark on `R1` you
|
situation is different than when we tried pinging an nonexistent interface,
|
||||||
will notice that the packets are received on one interface and are forwarded to
|
because we are actually seeing requests being sent.
|
||||||
the other so that's not it. If you also inspect `h1_2` you will find that the
|
|
||||||
request packets do manage to make their way to the destination, but still no
|
|
||||||
response is sent.
|
|
||||||
|
|
||||||
Can you figure out what's going on? What happens if you try pinging `h1_1`'s
|
Let's then check if `R1` is forwarding the packets. If you launch Wireshark on
|
||||||
interface from `h1_2`?
|
`R1` you will notice that the packets are received on one interface and are
|
||||||
|
forwarded to the other so that can't be it. If you also inspect `h1_2` you
|
||||||
|
will find that the request packets do manage to make their way to the
|
||||||
|
destination, but still no response is sent.
|
||||||
|
|
||||||
|
Can you figure out what's going on?
|
||||||
|
|
||||||
|
What happens if you try pinging `h1_1`'s interface from `h1_2`?
|
||||||
|
|
||||||
The problem is that `h1_2` doesn't have a default route itself. It receives
|
The problem is that `h1_2` doesn't have a default route itself. It receives
|
||||||
the ping packets and it tries to send a response back to the source IP address,
|
the ping packets and it tries to send a response back to the source IP address,
|
||||||
|
Loading…
Reference in New Issue
Block a user