b1f05504ed
The documentation links which start with "admin-guide" and "networking-guide" are outdated. Fix them to be friendly to new contributors. Change-Id: I656ba3b82df6acd2555735093127ca59f7042d44
482 lines
23 KiB
ReStructuredText
482 lines
23 KiB
ReStructuredText
.. _intro-basic-networking:
|
||
|
||
================
|
||
Basic networking
|
||
================
|
||
|
||
Ethernet
|
||
~~~~~~~~
|
||
|
||
Ethernet is a networking protocol, specified by the IEEE 802.3 standard. Most
|
||
wired network interface cards (NICs) communicate using Ethernet.
|
||
|
||
In the `OSI model <https://en.wikipedia.org/wiki/OSI_model>`_ of networking
|
||
protocols, Ethernet occupies the second layer, which is known as the data
|
||
link layer. When discussing Ethernet, you will often hear terms such as
|
||
*local network*, *layer 2*, *L2*, *link layer* and *data link layer*.
|
||
|
||
In an Ethernet network, the hosts connected to the network communicate
|
||
by exchanging *frames*. Every host on an Ethernet network is uniquely
|
||
identified by an address called the media access control (MAC) address.
|
||
In particular, every virtual machine instance in an OpenStack environment
|
||
has a unique MAC address, which is different from the MAC address of the
|
||
compute host. A MAC address has 48 bits and is typically represented as a
|
||
hexadecimal string, such as ``08:00:27:b9:88:74``. The MAC address is
|
||
hard-coded into the NIC by the manufacturer, although modern NICs
|
||
allow you to change the MAC address programmatically. In Linux, you can
|
||
retrieve the MAC address of a NIC using the :command:`ip` command:
|
||
|
||
.. code-block:: console
|
||
|
||
$ ip link show eth0
|
||
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
|
||
link/ether 08:00:27:b9:88:74 brd ff:ff:ff:ff:ff:ff
|
||
|
||
Conceptually, you can think of an Ethernet network as a single bus
|
||
that each of the network hosts connects to. In early implementations,
|
||
an Ethernet network consisted of a single coaxial cable that hosts
|
||
would tap into to connect to the network. However, network hosts in
|
||
modern Ethernet networks connect directly to a network device called a
|
||
*switch*. Still, this conceptual model is useful, and in network diagrams
|
||
(including those generated by the OpenStack dashboard) an Ethernet network
|
||
is often depicted as if it was a single bus. You'll sometimes hear an
|
||
Ethernet network referred to as a *layer 2 segment*.
|
||
|
||
In an Ethernet network, every host on the network can send a frame directly to
|
||
every other host. An Ethernet network also supports broadcasts so
|
||
that one host can send a frame to every host on the network by sending to the
|
||
special MAC address ``ff:ff:ff:ff:ff:ff``. ARP_ and DHCP_
|
||
are two notable protocols that use Ethernet broadcasts. Because Ethernet
|
||
networks support broadcasts, you will sometimes hear an Ethernet network
|
||
referred to as a *broadcast domain*.
|
||
|
||
When a NIC receives an Ethernet frame, by default the NIC checks to
|
||
see if the destination MAC address matches the address of the NIC (or
|
||
the broadcast address), and the Ethernet frame is discarded if the MAC
|
||
address does not match. For a compute host, this behavior is
|
||
undesirable because the frame may be intended for one of the
|
||
instances. NICs can be configured for *promiscuous mode*, where they
|
||
pass all Ethernet frames to the operating system, even if the MAC
|
||
address does not match. Compute hosts should always have the
|
||
appropriate NICs configured for promiscuous mode.
|
||
|
||
As mentioned earlier, modern Ethernet networks use switches to
|
||
interconnect the network hosts. A switch is a box of networking
|
||
hardware with a large number of ports that forward Ethernet frames
|
||
from one connected host to another. When hosts first send frames over
|
||
the switch, the switch doesn't know which MAC address is associated
|
||
with which port. If an Ethernet frame is destined for an unknown MAC
|
||
address, the switch broadcasts the frame to all ports. The switch learns
|
||
which MAC addresses are at which ports by observing the traffic. Once
|
||
it knows which MAC address is associated with a port, it can send
|
||
Ethernet frames to the correct port instead of broadcasting. The
|
||
switch maintains the mappings of MAC addresses to switch ports in a
|
||
table called a *forwarding table* or *forwarding information base*
|
||
(FIB). Switches can be daisy-chained together, and the resulting
|
||
connection of switches and hosts behaves like a single network.
|
||
|
||
VLANs
|
||
~~~~~
|
||
|
||
VLAN is a networking technology that enables a single switch to act as
|
||
if it was multiple independent switches. Specifically, two hosts that
|
||
are connected to the same switch but on different VLANs do not see
|
||
each other's traffic. OpenStack is able to take advantage of VLANs to
|
||
isolate the traffic of different projects, even if the projects happen
|
||
to have instances running on the same compute host. Each VLAN has an
|
||
associated numerical ID, between 1 and 4095. We say "VLAN 15" to refer
|
||
to the VLAN with a numerical ID of 15.
|
||
|
||
To understand how VLANs work, let's consider VLAN applications in a
|
||
traditional IT environment, where physical hosts are attached to a
|
||
physical switch, and no virtualization is involved. Imagine a scenario
|
||
where you want three isolated networks but you only have a single
|
||
physical switch. The network administrator would choose three VLAN
|
||
IDs, for example, 10, 11, and 12, and would configure the switch to
|
||
associate switchports with VLAN IDs. For example, switchport 2 might be
|
||
associated with VLAN 10, switchport 3 might be associated with VLAN
|
||
11, and so forth. When a switchport is configured for a specific VLAN,
|
||
it is called an *access port*. The switch is responsible for ensuring
|
||
that the network traffic is isolated across the VLANs.
|
||
|
||
Now consider the scenario that all of the switchports in the first
|
||
switch become occupied, and so the organization buys a second switch
|
||
and connects it to the first switch to expand the available number of
|
||
switchports. The second switch is also configured to support VLAN IDs
|
||
10, 11, and 12. Now imagine host A connected to switch 1 on a port
|
||
configured for VLAN ID 10 sends an Ethernet frame intended for host B
|
||
connected to switch 2 on a port configured for VLAN ID 10. When switch
|
||
1 forwards the Ethernet frame to switch 2, it must communicate that
|
||
the frame is associated with VLAN ID 10.
|
||
|
||
If two switches are to be connected together, and the switches are configured
|
||
for VLANs, then the switchports used for cross-connecting the switches must be
|
||
configured to allow Ethernet frames from any VLAN to be
|
||
forwarded to the other switch. In addition, the sending switch must tag each
|
||
Ethernet frame with the VLAN ID so that the receiving switch can ensure that
|
||
only hosts on the matching VLAN are eligible to receive the frame.
|
||
|
||
A switchport that is configured to pass frames from all VLANs and tag them with
|
||
the VLAN IDs is called a *trunk port*. IEEE 802.1Q is the network standard
|
||
that describes how VLAN tags are encoded in Ethernet frames when trunking is
|
||
being used.
|
||
|
||
Note that if you are using VLANs on your physical switches to implement project
|
||
isolation in your OpenStack cloud, you must ensure that all of your
|
||
switchports are configured as trunk ports.
|
||
|
||
It is important that you select a VLAN range not being used by your current
|
||
network infrastructure. For example, if you estimate that your cloud must
|
||
support a maximum of 100 projects, pick a VLAN range outside of that value,
|
||
such as VLAN 200–299. OpenStack, and all physical network infrastructure that
|
||
handles project networks, must then support this VLAN range.
|
||
|
||
Trunking is used to connect between different switches. Each trunk uses a tag
|
||
to identify which VLAN is in use. This ensures that switches on the same VLAN
|
||
can communicate.
|
||
|
||
|
||
.. _ARP:
|
||
|
||
Subnets and ARP
|
||
~~~~~~~~~~~~~~~
|
||
|
||
While NICs use MAC addresses to address network hosts, TCP/IP applications use
|
||
IP addresses. The Address Resolution Protocol (ARP) bridges the gap between
|
||
Ethernet and IP by translating IP addresses into MAC addresses.
|
||
|
||
IP addresses are broken up into two parts: a *network number* and a *host
|
||
identifier*. Two hosts are on the same *subnet* if they have the same network
|
||
number. Recall that two hosts can only communicate directly over Ethernet if
|
||
they are on the same local network. ARP assumes that all machines that are in
|
||
the same subnet are on the same local network. Network administrators must
|
||
take care when assigning IP addresses and netmasks to hosts so that any two
|
||
hosts that are in the same subnet are on the same local network, otherwise ARP
|
||
does not work properly.
|
||
|
||
To calculate the network number of an IP address, you must know the *netmask*
|
||
associated with the address. A netmask indicates how many of the bits in
|
||
the 32-bit IP address make up the network number.
|
||
|
||
There are two syntaxes for expressing a netmask:
|
||
|
||
* dotted quad
|
||
* classless inter-domain routing (CIDR)
|
||
|
||
Consider an IP address of 192.0.2.5, where the first 24 bits of the
|
||
address are the network number. In dotted quad notation, the netmask
|
||
would be written as ``255.255.255.0``. CIDR notation includes both the
|
||
IP address and netmask, and this example would be written as
|
||
``192.0.2.5/24``.
|
||
|
||
.. note::
|
||
|
||
Creating CIDR subnets including a multicast address or a loopback address
|
||
cannot be used in an OpenStack environment. For example, creating a subnet
|
||
using ``224.0.0.0/16`` or ``127.0.1.0/24`` is not supported.
|
||
|
||
Sometimes we want to refer to a subnet, but not any particular IP
|
||
address on the subnet. A common convention is to set the host
|
||
identifier to all zeros to make reference to a subnet. For example, if
|
||
a host's IP address is ``192.0.2.24/24``, then we would say the
|
||
subnet is ``192.0.2.0/24``.
|
||
|
||
To understand how ARP translates IP addresses to MAC addresses,
|
||
consider the following example. Assume host *A* has an IP address of
|
||
``192.0.2.5/24`` and a MAC address of ``fc:99:47:49:d4:a0``, and
|
||
wants to send a packet to host *B* with an IP address of
|
||
``192.0.2.7``. Note that the network number is the same for both
|
||
hosts, so host *A* is able to send frames directly to host *B*.
|
||
|
||
The first time host *A* attempts to communicate with host *B*, the
|
||
destination MAC address is not known. Host *A* makes an ARP request to
|
||
the local network. The request is a broadcast with a message like
|
||
this:
|
||
|
||
*To: everybody (ff:ff:ff:ff:ff:ff). I am looking for the computer who
|
||
has IP address 192.0.2.7. Signed: MAC address fc:99:47:49:d4:a0*.
|
||
|
||
Host *B* responds with a response like this:
|
||
|
||
*To: fc:99:47:49:d4:a0. I have IP address 192.0.2.7. Signed: MAC
|
||
address 54:78:1a:86:00:a5.*
|
||
|
||
Host *A* then sends Ethernet frames to host *B*.
|
||
|
||
You can initiate an ARP request manually using the :command:`arping` command.
|
||
For example, to send an ARP request to IP address ``192.0.2.132``:
|
||
|
||
.. code-block:: console
|
||
|
||
$ arping -I eth0 192.0.2.132
|
||
ARPING 192.0.2.132 from 192.0.2.131 eth0
|
||
Unicast reply from 192.0.2.132 [54:78:1A:86:1C:0B] 0.670ms
|
||
Unicast reply from 192.0.2.132 [54:78:1A:86:1C:0B] 0.722ms
|
||
Unicast reply from 192.0.2.132 [54:78:1A:86:1C:0B] 0.723ms
|
||
Sent 3 probes (1 broadcast(s))
|
||
Received 3 response(s)
|
||
|
||
To reduce the number of ARP requests, operating systems maintain an ARP cache
|
||
that contains the mappings of IP addresses to MAC address. On a Linux machine,
|
||
you can view the contents of the ARP cache by using the :command:`arp`
|
||
command:
|
||
|
||
.. code-block:: console
|
||
|
||
$ arp -n
|
||
Address HWtype HWaddress Flags Mask Iface
|
||
192.0.2.3 ether 52:54:00:12:35:03 C eth0
|
||
192.0.2.2 ether 52:54:00:12:35:02 C eth0
|
||
|
||
.. _DHCP:
|
||
|
||
DHCP
|
||
~~~~
|
||
|
||
Hosts connected to a network use the Dynamic Host Configuration
|
||
Protocol (DHCP) to dynamically obtain IP addresses. A DHCP
|
||
server hands out the IP addresses to network hosts, which are the DHCP
|
||
clients.
|
||
|
||
DHCP clients locate the DHCP server by sending a UDP_ packet from port
|
||
68 to address ``255.255.255.255`` on port 67. Address
|
||
``255.255.255.255`` is the local network broadcast address: all hosts
|
||
on the local network see the UDP packets sent to this address.
|
||
However, such packets are not forwarded to other networks.
|
||
Consequently, the DHCP server must be on the same local network as the
|
||
client, or the server will not receive the broadcast. The DHCP server
|
||
responds by sending a UDP packet from port 67 to port 68 on the
|
||
client. The exchange looks like this:
|
||
|
||
1. The client sends a discover ("I'm a client at MAC address
|
||
``08:00:27:b9:88:74``, I need an IP address")
|
||
2. The server sends an offer ("OK ``08:00:27:b9:88:74``, I'm offering
|
||
IP address ``192.0.2.112``")
|
||
3. The client sends a request ("Server ``192.0.2.131``, I would like
|
||
to have IP ``192.0.2.112``")
|
||
4. The server sends an acknowledgement ("OK ``08:00:27:b9:88:74``, IP
|
||
``192.0.2.112`` is yours")
|
||
|
||
|
||
OpenStack uses a third-party program called
|
||
`dnsmasq <http://www.thekelleys.org.uk/dnsmasq/doc.html>`_
|
||
to implement the DHCP server.
|
||
Dnsmasq writes to the syslog, where you can observe the DHCP request
|
||
and replies::
|
||
|
||
Apr 23 15:53:46 c100-1 dhcpd: DHCPDISCOVER from 08:00:27:b9:88:74 via eth2
|
||
Apr 23 15:53:46 c100-1 dhcpd: DHCPOFFER on 192.0.2.112 to 08:00:27:b9:88:74 via eth2
|
||
Apr 23 15:53:48 c100-1 dhcpd: DHCPREQUEST for 192.0.2.112 (192.0.2.131) from 08:00:27:b9:88:74 via eth2
|
||
Apr 23 15:53:48 c100-1 dhcpd: DHCPACK on 192.0.2.112 to 08:00:27:b9:88:74 via eth2
|
||
|
||
When troubleshooting an instance that is not reachable over the network, it can
|
||
be helpful to examine this log to verify that all four steps of the DHCP
|
||
protocol were carried out for the instance in question.
|
||
|
||
|
||
IP
|
||
~~
|
||
|
||
The Internet Protocol (IP) specifies how to route packets between
|
||
hosts that are connected to different local networks. IP relies on
|
||
special network hosts called *routers* or *gateways*. A router is a
|
||
host that is connected to at least two local networks and can forward
|
||
IP packets from one local network to another. A router has multiple IP
|
||
addresses: one for each of the networks it is connected to.
|
||
|
||
In the OSI model of networking protocols IP occupies the third layer,
|
||
known as the network layer. When discussing IP, you will often hear terms
|
||
such as *layer 3*, *L3*, and *network layer*.
|
||
|
||
A host sending a packet to an IP address consults its *routing table*
|
||
to determine which machine on the local network(s) the packet should
|
||
be sent to. The routing table maintains a list of the subnets
|
||
associated with each local network that the host is directly connected
|
||
to, as well as a list of routers that are on these local networks.
|
||
|
||
On a Linux machine, any of the following commands displays the routing table:
|
||
|
||
.. code-block:: console
|
||
|
||
$ ip route show
|
||
$ route -n
|
||
$ netstat -rn
|
||
|
||
Here is an example of output from :command:`ip route show`:
|
||
|
||
.. code-block:: console
|
||
|
||
$ ip route show
|
||
default via 192.0.2.2 dev eth0
|
||
192.0.2.0/24 dev eth0 proto kernel scope link src 192.0.2.15
|
||
198.51.100.0/25 dev eth1 proto kernel scope link src 198.51.100.100
|
||
198.51.100.192/26 dev virbr0 proto kernel scope link src 198.51.100.193
|
||
|
||
Line 1 of the output specifies the location of the default route,
|
||
which is the effective routing rule if none of the other rules match.
|
||
The router associated with the default route (``192.0.2.2`` in the
|
||
example above) is sometimes referred to as the *default gateway*. A
|
||
DHCP_ server typically transmits the IP address of the default gateway
|
||
to the DHCP client along with the client's IP address and a netmask.
|
||
|
||
Line 2 of the output specifies that IPs in the ``192.0.2.0/24`` subnet are on
|
||
the local network associated with the network interface eth0.
|
||
|
||
Line 3 of the output specifies that IPs in the ``198.51.100.0/25`` subnet
|
||
are on the local network associated with the network interface eth1.
|
||
|
||
Line 4 of the output specifies that IPs in the ``198.51.100.192/26`` subnet are
|
||
on the local network associated with the network interface virbr0.
|
||
|
||
The output of the :command:`route -n` and :command:`netstat -rn` commands are
|
||
formatted in a slightly different way. This example shows how the same
|
||
routes would be formatted using these commands:
|
||
|
||
.. code-block:: console
|
||
|
||
$ route -n
|
||
Kernel IP routing table
|
||
Destination Gateway Genmask Flags MSS Window irtt Iface
|
||
0.0.0.0 192.0.2.2 0.0.0.0 UG 0 0 0 eth0
|
||
192.0.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
|
||
198.51.100.0 0.0.0.0 255.255.255.128 U 0 0 0 eth1
|
||
198.51.100.192 0.0.0.0 255.255.255.192 U 0 0 0 virbr0
|
||
|
||
The :command:`ip route get` command outputs the route for a destination
|
||
IP address. From the below example, destination IP address ``192.0.2.14`` is on
|
||
the local network of eth0 and would be sent directly:
|
||
|
||
.. code-block:: console
|
||
|
||
$ ip route get 192.0.2.14
|
||
192.0.2.14 dev eth0 src 192.0.2.15
|
||
|
||
The destination IP address ``203.0.113.34`` is not on any of the connected
|
||
local networks and would be forwarded to the default gateway at ``192.0.2.2``:
|
||
|
||
.. code-block:: console
|
||
|
||
$ ip route get 203.0.113.34
|
||
203.0.113.34 via 192.0.2.2 dev eth0 src 192.0.2.15
|
||
|
||
It is common for a packet to hop across multiple routers to reach its final
|
||
destination. On a Linux machine, the ``traceroute`` and more recent ``mtr``
|
||
programs prints out the IP address of each router that an IP packet
|
||
traverses along its path to its destination.
|
||
|
||
.. _UDP:
|
||
|
||
TCP/UDP/ICMP
|
||
~~~~~~~~~~~~
|
||
|
||
For networked software applications to communicate over an IP network, they
|
||
must use a protocol layered atop IP. These protocols occupy the fourth
|
||
layer of the OSI model known as the *transport layer* or *layer 4*. See the
|
||
`Protocol Numbers <http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml>`_
|
||
web page maintained by the Internet Assigned Numbers
|
||
Authority (IANA) for a list of protocols that layer atop IP and their
|
||
associated numbers.
|
||
|
||
The *Transmission Control Protocol* (TCP) is the most
|
||
commonly used layer 4 protocol in networked applications. TCP is a
|
||
*connection-oriented* protocol: it uses a client-server model where a client
|
||
connects to a server, where *server* refers to the application that receives
|
||
connections. The typical interaction in a TCP-based application proceeds as
|
||
follows:
|
||
|
||
|
||
1. Client connects to server.
|
||
2. Client and server exchange data.
|
||
3. Client or server disconnects.
|
||
|
||
Because a network host may have multiple TCP-based applications running, TCP
|
||
uses an addressing scheme called *ports* to uniquely identify TCP-based
|
||
applications. A TCP port is associated with a number in the range 1-65535, and
|
||
only one application on a host can be associated with a TCP port at a time, a
|
||
restriction that is enforced by the operating system.
|
||
|
||
A TCP server is said to *listen* on a port. For example, an SSH server
|
||
typically listens on port 22. For a client to connect to a server
|
||
using TCP, the client must know both the IP address of a server's host
|
||
and the server's TCP port.
|
||
|
||
The operating system of the TCP client application automatically
|
||
assigns a port number to the client. The client owns this port number
|
||
until the TCP connection is terminated, after which the operating
|
||
system reclaims the port number. These types of ports are referred to
|
||
as *ephemeral ports*.
|
||
|
||
IANA maintains a `registry of port numbers
|
||
<http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml>`_
|
||
for many TCP-based services, as well as services that use other layer 4
|
||
protocols that employ ports. Registering a TCP port number is not required, but
|
||
registering a port number is helpful to avoid collisions with other
|
||
services. See `firewalls and default ports
|
||
<https://docs.openstack.org/install-guide/firewalls-default-ports.html>`_
|
||
in OpenStack Installation Guide for the default TCP ports used by
|
||
various services involved in an OpenStack deployment.
|
||
|
||
|
||
The most common application programming interface (API) for writing TCP-based
|
||
applications is called *Berkeley sockets*, also known as *BSD sockets* or,
|
||
simply, *sockets*. The sockets API exposes a *stream oriented* interface for
|
||
writing TCP applications. From the perspective of a programmer, sending data
|
||
over a TCP connection is similar to writing a stream of bytes to a file. It is
|
||
the responsibility of the operating system's TCP/IP implementation to break up
|
||
the stream of data into IP packets. The operating system is also
|
||
responsible for automatically retransmitting dropped packets, and for
|
||
handling flow control to ensure that transmitted data does not overrun
|
||
the sender's data buffers, receiver's data buffers, and network
|
||
capacity. Finally, the operating system is responsible for
|
||
re-assembling the packets in the correct order into a stream of data
|
||
on the receiver's side. Because TCP detects and retransmits lost
|
||
packets, it is said to be a *reliable* protocol.
|
||
|
||
The *User Datagram Protocol* (UDP) is another layer 4 protocol that is
|
||
the basis of several well-known networking protocols. UDP is a
|
||
*connectionless* protocol: two applications that communicate over UDP
|
||
do not need to establish a connection before exchanging data. UDP is
|
||
also an *unreliable* protocol. The operating system does not attempt
|
||
to retransmit or even detect lost UDP packets. The operating system
|
||
also does not provide any guarantee that the receiving application
|
||
sees the UDP packets in the same order that they were sent in.
|
||
|
||
UDP, like TCP, uses the notion of ports to distinguish between different
|
||
applications running on the same system. Note, however, that operating systems
|
||
treat UDP ports separately from TCP ports. For example, it is possible for one
|
||
application to be associated with TCP port 16543 and a separate application to
|
||
be associated with UDP port 16543.
|
||
|
||
Like TCP, the sockets API is the most common API for writing UDP-based
|
||
applications. The sockets API provides a *message-oriented* interface for
|
||
writing UDP applications: a programmer sends data over UDP by transmitting a
|
||
fixed-sized message. If an application requires retransmissions of lost packets
|
||
or a well-defined ordering of received packets, the programmer is responsible
|
||
for implementing this functionality in the application code.
|
||
|
||
DHCP_, the Domain Name System (DNS), the Network Time Protocol (NTP), and
|
||
:ref:`VXLAN` are examples of UDP-based protocols used in OpenStack deployments.
|
||
|
||
UDP has support for one-to-many communication: sending a single packet
|
||
to multiple hosts. An application can broadcast a UDP packet to all of
|
||
the network hosts on a local network by setting the receiver IP
|
||
address as the special IP broadcast address ``255.255.255.255``. An
|
||
application can also send a UDP packet to a set of receivers using *IP
|
||
multicast*. The intended receiver applications join a multicast group
|
||
by binding a UDP socket to a special IP address that is one of the
|
||
valid multicast group addresses. The receiving hosts do not have to be
|
||
on the same local network as the sender, but the intervening routers
|
||
must be configured to support IP multicast routing. VXLAN is an
|
||
example of a UDP-based protocol that uses IP multicast.
|
||
|
||
The *Internet Control Message Protocol* (ICMP) is a protocol used for sending
|
||
control messages over an IP network. For example, a router that receives an IP
|
||
packet may send an ICMP packet back to the source if there is no route in the
|
||
router's routing table that corresponds to the destination address
|
||
(ICMP code 1, destination host unreachable) or if the IP packet is too
|
||
large for the router to handle (ICMP code 4, fragmentation required
|
||
and "don't fragment" flag is set).
|
||
|
||
The :command:`ping` and :command:`mtr` Linux command-line tools are two
|
||
examples of network utilities that use ICMP.
|