Skip to content
academia.sh

Lesson 01 / 13

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.

Contents

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.
  • AY2The 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.

# 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.

# 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.
"""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.

To keep your progress and take notes, Log in

My notes

Log in to take notes.

Start typing to search.

↑↓ Esc navigate · open · close