---
title: 'Interfaces and Addresses'
source: 'https://academia.sh/en/courses/linux-network-administration/interfaces-and-addresses'
course: 'Linux Network Administration and Troubleshooting'
language: en
updated: '2026-08-17T18:09:59+00:00'
license: 'CC BY-SA 4.0'
---

# Interfaces and Addresses

The interface list gives three distinct answers against eight candidate causes; two answers alone eliminate seven candidates each, the third eliminates only two and leaves six remaining.

The previous course ended with storage: the layer where a fault looks quietest. A
filling inode table produced no warning, a filling snapshot left no trace behind it.
But that quiet had one advantage — the fault was **local**. There was one machine to
look at, and every layer of that machine was reachable from the same shell.

That advantage does not exist on a network. A fault can be both silent and **on
someone else's machine**; it can even be on a path that belongs to no one. So the
course's measure changes. The System Administration course counted what a tool cannot
see. This course counts **how many candidate causes a test eliminates**. Its rule is
this: a test's number is not the answer it gives, but the candidates it eliminates;
**a test whose elimination count is not written is not considered measured.** The
first lesson starts with the lowest-level test, the interface and address list.

## The Mock Server and Eight Candidate Causes

A single mock server is followed throughout the course. On it runs a unit named
`data-ingest`, listening on a port; the server connects to the network through an
interface, exits outward through a default gateway, and asks a resolver for names.
Someone trying to connect to this server says "the connection is not working." This is
where diagnosis starts, and the sentence says nothing: eight separate faults produce
exactly this sentence.

- **AY1** — There are eight candidate causes, and each breaks **a single field** of
  the healthy state: interface down, no address, wrong gateway, missing route, silent
  resolver, service not listening, firewall dropping, large packet dropping. No two
  faults are assumed to occur at once.
- **AY2** — **The oracle is the real fault.** Because we chose the setup, we know which
  field is broken; the person performing the test does not. The measurement uses this
  asymmetry.
- **AY3** — There are eight **tests**; each corresponds to a tool and returns **one
  answer**. The answer splits the candidate set: candidates giving the same answer stay
  together, those giving a different answer are eliminated.
- **AY4** — All counts are exhaustive. The count is computed over eight candidates and
  eight tests exhaustively; there is no randomness.

This course is **a single machine's configuration**. Layer models, addressing
arithmetic, name resolution protocols, and routing protocols are the subject of the
Computer Networks curriculum; they are not built here and are left to the lessons
there. The question here is not how the protocol works, but **what this machine's
configuration says** and how many candidates that statement eliminates. Container
networking and namespaces are also outside this course; they are left to the Kernel
Interfaces and Isolation course.

## What the Interface List Shows

An interface is the name the kernel gives to a piece of network hardware or a virtual
link. The listing tool states two separate things for every interface: **administrative
state** (has the interface been brought up) and **carrier state** (is a signal coming
from the other end). These two are separate, and their separateness is the basis of the
measurement.

```text
# example dump — not executed
$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP
3: eth1: <BROADCAST,MULTICAST> mtu 1500 state DOWN
```

The address is a separate question. An interface can be up, have carrier, and still
carry no address at all; in that case no packet can be produced. The short-form address
dump places the two questions side by side.

```text
# example dump — not executed
$ ip -brief addr show
lo     UNKNOWN  127.0.0.1/8
eth0   UP       203.0.113.24/24
eth1   DOWN
```

These two blocks are **not executed**, and no numeric claim is drawn from them. What the
dump teaches is the format: the state field, the interface name, and the address field.
Every address in this lesson is fictional; interface names also vary by the
distribution's naming scheme, and that is said once here and not repeated.

There are two ways to assign an address, and the difference between them is a frequent
point of confusion in diagnosis. An address given with a command **belongs to
runtime**: it is written into the kernel's table and lost on reboot. An address written
into a configuration file or a network manager is **persistent**: it is reapplied at
boot. The two can conflict. A server running with a manually assigned address can look
fine for weeks and come up addressless at the first reboot. This is the same pattern as
the persistent mount entry from the storage course: **running state and persistent
configuration are two separate facts**, and the job is not done if only one has been
tested.

## What the List Cannot See

The interface list merges three separate questions into a single dump, and by merging
them it loses some distinctions. Administrative state says whether the interface has
been brought up, and this is a **configuration** decision. Carrier state says whether a
signal is coming from the other end, and this is a **physical** fact. The third is
whether the address exists, and that too is configuration. An interface that is up but
has no carrier produces a line that looks up in the dump; even with the cable pulled
out, the line stays in place and only the carrier field changes. If the person starting
the diagnosis does not look at that field, they count the interface as healthy.

The same merging exists on the address side. An interface can carry more than one
address, and the dump lists them all one under another; which one will be used as the
source on outgoing packets cannot be read from the list — routing decides that. Two
interfaces getting an address on the same subnet also looks completely normal at the
list level and can carry traffic to an unexpected interface.

- **AY5** — The shared reference collapses these distinctions into **a single field**:
  the `interface-down` candidate means both that the interface is down and that the
  address is absent, because an address is not active on a down interface. The
  difference between carrier state and administrative state is not kept as a separate
  field in the model; this is a deliberate limit of the model, and it is exactly this
  limit that the sweep tests.

## A Test's Measure Is the Candidates It Eliminates

The definition below is the shared reference used throughout the course: the mock
server's healthy state, eight faults, eight tests. Each test returns the answer a tool
would give.

- **AY6** — Tests are invoked independently of one another; one test's answer does not
  change another's. What is measured is how many candidates each test eliminates **on
  its own**.
- **AY7** — "Worst-case remaining" is the size of the **largest group** among the
  answers a test can give; it is a measure independent of the oracle and gives the
  test's ceiling.

```python
"""Shared reference: the mock server's healthy state, eight candidate faults, eight
tests. What is measured is how many candidate causes a test ELIMINATES on its own."""
HEALTHY = {"interface_up": True, "address_present": True, "gateway_correct": True,
           "route_present": True, "resolver_responds": True, "service_listening": True,
           "firewall_allows": True, "path_intact": True}
FAULT = {
    "interface-down":       {"interface_up": False, "address_present": False},
    "no-address":      {"address_present": False},
    "wrong-gateway":        {"gateway_correct": False},
    "missing-route":        {"route_present": False},
    "resolver-silent":      {"resolver_responds": False},
    "service-not-listening": {"service_listening": False},
    "firewall-dropping":    {"firewall_allows": False},
    "large-packet-lost": {"path_intact": False},
}


def state(fault, table):
    d = dict(HEALTHY)
    d.update(table[fault])
    return d


def test_interface(d):
    return ("up-addressed" if d["interface_up"] and d["address_present"]
            else "up-unaddressed" if d["interface_up"] else "down")


def test_route(d):
    if not d["address_present"]:
        return "table-empty"
    return "complete" if d["route_present"] else "default-missing"


def test_gateway_echo(d):
    return "reply" if d["interface_up"] and d["address_present"] else "no-reply"


def test_remote_echo(d):
    return "reply" if (d["interface_up"] and d["address_present"]
                       and d["gateway_correct"] and d["route_present"]) else "no-reply"


def test_name_resolution(d):
    return "resolved" if d["resolver_responds"] else "unresolved"


def test_listening(d):
    return "listening" if d["service_listening"] else "not-listening"


def test_connection(d):
    if not (d["interface_up"] and d["address_present"] and d["gateway_correct"]
            and d["route_present"]):
        return "unreachable"
    if not d["firewall_allows"]:
        return "timeout"
    return "refused" if not d["service_listening"] else "established"


def test_large_packet(d):
    return "passes" if (d["interface_up"] and d["address_present"]
                        and d["gateway_correct"] and d["route_present"]
                        and d["path_intact"]) else "blocked"


TEST = {"interface": test_interface, "route": test_route, "gateway-echo": test_gateway_echo,
        "remote-echo": test_remote_echo, "name-resolution": test_name_resolution,
        "listening": test_listening, "connection": test_connection,
        "large-packet": test_large_packet}


def groups(test, table=FAULT):
    o = {}
    for a in table:
        o.setdefault(TEST[test](state(a, table)), []).append(a)
    return o


print("test            distinct answers  worst-case remaining")
for s in TEST:
    o = groups(s)
    print(f"  {s:14s} {len(o):9d}  {max(len(v) for v in o.values()):13d}")
print()
print("interface test: candidates per answer")
for answer, group in groups("interface").items():
    print(f"  {answer:14s} remaining {len(group):2d}  eliminated {len(FAULT) - len(group):2d}"
          f"  {', '.join(group)}")
print()
print("candidate set sweep")
WITH_EXTRA = dict(FAULT, **{"no-cable": {"interface_up": False, "address_present": False}})
WITHOUT = {k: v for k, v in FAULT.items() if k != "no-address"}
for ad, table in (("base    8 candidates", FAULT), ("+no-cable   9", WITH_EXTRA),
                  ("-no-address  7", WITHOUT)):
    o = groups("interface", table)
    worst = max(len(v) for v in o.values())
    down = len(o.get("down", []))
    print(f"  {ad:20s} distinct answers {len(o)}  worst-case remaining {worst}"
          f"  remaining in 'down' answer {down}"
          f"  eliminated {len(table) - down}")
```

```
test            distinct answers  worst-case remaining
  interface              3              6
  route                  3              5
  gateway-echo           2              6
  remote-echo            2              4
  name-resolution         2              7
  listening              2              7
  connection             4              4
  large-packet           2              5

interface test: candidates per answer
  down           remaining  1  eliminated  7  interface-down
  up-unaddressed remaining  1  eliminated  7  no-address
  up-addressed   remaining  6  eliminated  2  wrong-gateway, missing-route, resolver-silent, service-not-listening, firewall-dropping, large-packet-lost

candidate set sweep
  base    8 candidates distinct answers 3  worst-case remaining 6  remaining in 'down' answer 1  eliminated 7
  +no-cable   9        distinct answers 3  worst-case remaining 6  remaining in 'down' answer 2  eliminated 7
  -no-address  7       distinct answers 2  worst-case remaining 6  remaining in 'down' answer 1  eliminated 6
```

Three numbers stand side by side. **Oracle:** one of eight candidates is the real
fault, and the side that built the setup knows which. **Test:** the interface list
produces **three distinct answers** against these eight states — down,
up-unaddressed, up-addressed. **Candidates eliminated:** seven, seven, and **two**
depending on the answer; in the worst case, **six candidates** remain.

## The Three Answers Are Not Equal

In the first table, the interface test giving three distinct answers makes it look like
one of the more detailed tests; only the connection attempt gives more, four answers.
But the number of distinct answers is not elimination power. The second table opens
this up: two of the three answers point to a single candidate, the third leaves six
candidates together.

The practical reading of this is as follows. The interface test is **decisive when it
finds the fault, and almost silent when it does not**. If the list says "down," the job
is done: seven candidates are eliminated, one remains. If the list says
"up-unaddressed," the job is done again. But if the list says, as expected, "up and
addressed" — which is the most common answer the person starting the diagnosis
encounters — only two of eight candidates are eliminated and six remain. The test's
**expected** result is the result carrying the least information.

This asymmetry gives the course's first general rule: **a test that gives a positive
answer does not make a diagnosis, it only closes one door.** Looking at the interface
list and saying "there's no problem here" is correct, and it leaves three-quarters of
the candidates standing. Looking at the same list, on the other hand, and saying "the
interface is up, so the network is working" is drawing six candidates' innocence from
the elimination of two.

The reason the test is still done first is not its elimination power but its
**cost**. The interface list is read locally, has no side effect, returns in under a
second, and when it is wrong, points definitively to two candidates. Tests that look
stronger in the first table — the connection attempt and the remote echo, both leaving
**four** candidates in the worst case — require reaching the far end, an open target,
and a wait; both say "unreachable" or "no reply" while the interface is down, and that
answer fits **four** separate candidates at once. This is the logic of the ordering:
**cheap and decisive first, expensive and discriminating later.** How many candidates
are eliminated gives a test's value; the ratio of value to cost decides the order it is
done in.

## Candidate Set Sweep

Because there is no randomness in this course, the measurement cannot be repeated with a
second seed. The way to see how much the result depends on the setup is to **sweep the
candidate set**: a candidate is added to the list and one is removed, and how the
elimination counts change is read.

- **AY8** — The added candidate, `no-cable`, is the case of the physical link being cut,
  and for the interface test it produces **the same answer** as `interface-down`.
- **AY9** — The removed candidate, `no-address`, is the case of the interface being
  left without an address, and it alone fills the test's third answer.
- **AY10** — The sweep changes only the candidate list; the healthy state, the test
  definitions, and the measurement method stay the same.

The third table shows two separate fragilities. When a candidate is added, the
"worst-case remaining" count stays fixed at six, meaning the test's ceiling does not
change; but **the answer thought to be decisive loses its decisiveness**. In the
nine-candidate list, the "down" answer still eliminates seven candidates, but what
remains is no longer one candidate but **two**: `interface-down` and `no-cable` cannot
be told apart from the interface list. What separates them is a different reading —
carrier state. The test's power is not in the test, it is **in the candidate list**.

When a candidate is removed, the answer count drops from three to **two**, and the
"down" answer's elimination count drops from seven to **six**. The number shrank, but
the test did not get weaker; what shrank was the problem. This shows a trap that will
come up repeatedly in interpreting this measure: **the elimination count is not a
property of the test, it is a joint property of the test and the candidate set.**
Elimination counts measured in two setups are comparable only if the candidate lists
are the same.

The sweep's practical counterpart is writing down the candidate list before starting
diagnosis. Without a written list, the elimination count cannot be computed and the
order tests are done in is left to intuition; with a written list, every answer shows
how many lines it strikes out. The rest of this course uses the same eight lines and,
in each lesson, counts how the list narrows as one or two tests are added. The list
itself is also a configuration decision: which faults are considered plausible directly
determines which tests are found worth doing.

## Summary

- This course reads a single machine's network configuration and measures every test
  by **how many candidate causes it eliminates**; a test whose elimination count is not
  written is not considered measured.
- The mock server has eight candidate causes and eight tests; each fault breaks a
  single field of the healthy state, and the oracle is the real fault known to the side
  that built the setup.
- The interface list gives **three distinct answers**, and the answers are not equal:
  the down and up-unaddressed answers each eliminate **seven** candidates, the expected
  up-addressed answer eliminates only **two** and leaves **six candidates** remaining.
- The address at runtime and the address in persistent configuration are two separate
  facts; if only one has been tested, the configuration has not been verified.
- The candidate set sweep shows the fragility of the elimination count: when a ninth
  candidate is added, the "down" answer no longer leaves a single candidate; when
  `no-address` is removed, the answer count drops from three to two. The
  elimination count is a joint property of the test and the candidate set, not of the
  test alone.

## Next Step

Once the interface comes up as up and addressed, six candidates remain, and two of
them concern where the packet is sent: the default gateway can be wrong, or the route
may not exist at all. The next lesson reads the routing table and applies the same
measure to it. What will be seen there is that the table gives three distinct answers,
but it is unexpectedly hard-pressed to tell two candidates apart — a wrong gateway and
a missing route: when the two echo-based tests are done back to back, these two
candidates still sit in the same group.
