Skip to content
academia.sh

Lesson 02 / 14

Access Points and Controllers

Whether the decision is made at the access point or at the controller is measured: three points running on separately given budgets associate 25 clients and produce 2 false admits, a shared policy associates 23 clients and leaks zero, and the clients running at full rate rise from 5 to 9.

Contents

The previous lesson counted the decision a single access point makes on its own: it associates the client if it hears it above the threshold, and does not if it does not. 23 of the forty clients associated, 4 inside the cell could not, and no one leaked in from outside.

In a building, though, there is no single access point. There are dozens of points, and each one’s signal budget, channel, and threshold is a given value — set somewhere, at some time, by someone. This lesson’s question is: who gives that value, and where is the decision made? If the same client can get two different answers from two access points, the owner of the answer is not the client’s condition but which one it happens to land on.

Association Is an Exchange

A client “seeing” the network and connecting to it are separate matters. A frame exchange stands between the two, and the decision is made at a specific step of that exchange.

# taught management frame sequence , fictional and not executed

1. access point -> everyone     beacon
                                  network: measurement.test
                                  channel: 4 , band: N
                                  supported tiers: 6 4 2 1

2. client -> everyone           probe request
                                  network: measurement.test

3. access point -> client       probe response
                                  measured signal strength: 26

4. client -> access point       association request
                                  requested tier: 4

5. access point -> client       association response
                                  result: accept , granted tier: 2
                                  <-- THE DECISION IS MADE AT THIS STEP

The fifth step is where the decision is made, and it says two things at once: was the client accepted, and at which rate tier. A “no” answer to the first question means, in the client’s eyes, that the network does not exist; the answer to the second question shows up in no indicator at all.

The critical point is this: who writes the fifth step? The access point sends the frame, but the rule that determines the answer’s content may be defined somewhere else entirely.

Two Management Models

An independent access point carries its own configuration. Its channel, signal budget, and threshold live in its own memory; it makes the association decision by looking only at the signal strength it itself measures. It does not know which channel its neighbor is on, what budget it broadcasts with, or which client it rejected.

The controller-based model splits the decision in two. The control plane is centralized: channel assignments, signal budgets, thresholds, and policies are held in a single place and distributed to the points. The data plane can stay local, or it can be tunnelled to the controller; that is a separate choice, and not what this lesson measures.

What the controller really carries is a shared view. When every point’s measurements are collected in a single place, things a point could never know on its own become knowable: where a channel is being reused, how many points hear a given client, where one point’s budget cuts into its neighbor’s coverage.

This resembles the Switching and Routing course’s axis, but it is not the same. There, the question asked was whether copies of a shared truth agreed with each other; here, the question asked is whether copies exist at all. Independent points do not carry stale copies of a shared truth — there is no shared truth; each point carries its own value alone.

The controller does not have to be a device, either. It can be dedicated hardware, a server on the network, or a role taken on by one of the points; nothing changes from the measurement’s point of view. What is measured is not the box itself but whether the decision comes from a single place.

Where the Data Plane Flows

Centralizing the control plane does not centralize the data plane; that is a second, separate choice.

With local switching, the client’s frame leaves the access point and enters the local network directly. The controller only supplies the rule; it never sees the traffic. The path is short, traffic in flight is unaffected if the controller is cut off, but enforcing the policy depends on the points being correctly configured.

With a tunnelled data plane, the frame is carried to the controller first, and exits to the network from there. What this buys is a policy enforced from a single point: all wireless traffic passes through the same place and hits the same rule. What it costs is the path — even two clients standing side by side have their frames travel all the way to the controller and back — and the controller becoming a bottleneck.

The choice is not binary either: some traffic can be left local while other traffic is tunnelled. This lesson’s measurement changes only the control plane; where the data plane flows does not enter the association decision and does not mix into the measurement.

Configuration Drift

The independent model’s countable flaw is configuration drift. Points are not set up at the same time. The first point is raised in response to a coverage complaint, the second stays as installed, the third is cut back in response to an interference complaint. Every step is reasonable on its own; none of them leaves a record, and no one sees the total.

The inevitability of drift is a scale problem. The interaction of two points can be held in mind; the forty-five pairwise interactions of ten points cannot. Raising one point’s budget does not only grow that point’s coverage; it also changes where its neighbors’ coverage gets cut off. Deciding point by point means there is no place at all that can see this interaction.

The result is three different boundaries drawn within the same network. The measurement sets this up with three budgets: one point at 58, one at 52, one at 46. Set against it, the controller regime distributes a single value, 52, to all three points. The only thing that changes is where the decision is made; the clients, the distances, the interference, and the intent all stay the same.

The measurement’s assumptions:

  • WN7. Forty clients come from the previous lesson’s fiction; distance and interference are the same. The oracle is again the cell intent: the client inside the 30 m radius cell should have been admitted.
  • WN8. Which access point hears which client comes from a separate generator and is independent of distance. The distance field is the distance to the point that hears the client.
  • WN9. There are three points, and their budgets in the independent regime are 58, 52, and 46. These three values are the fiction of configuration drift, not a power sweep; the sweep itself is the subject of the next lesson.
  • WN10. In the controller regime, all three points’ budget is 52. This is the only thing that changes between the two regimes.
  • WN11. The controller’s distribution is instant and lossless. Distribution delay and the controller becoming unreachable are not measured; both are addressed separately in the text.
  • WN12. The consistency measurement evaluates the same client separately against three budgets. This is not a movement fiction; the client stays put, only the evaluating point changes. The client actually changing location is the subject of the roaming lesson.
  • WN13. The set is forty clients; the smallest measurable difference is 1/40 = 0.025.

Measurement

"""Where the decision sits: independent access points, or a shared controller."""
SEED = 20260811
PLACEMENT = 20260812     # which access point hears which client
RADIUS = 30
SHARED_POWER = 52        # the single value the controller distributes to every point
POINTS = (("A", 58), ("B", 52), ("C", 46))    # separately given budgets
TIERS = ((34, 6), (28, 4), (22, 2), (18, 1))


def generator(seed):
    d = seed % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def clients(count=40, seed=SEED):
    r, pool = generator(seed), []
    for i in range(count):
        pool.append({"no": i + 1, "distance": 5 + r(41), "interference": r(13)})
    y = generator(PLACEMENT)
    for c in pool:
        c["point"] = y(3)
    return pool


def signal(c, power):
    return power - c["distance"] - c["interference"]


def rate_tier(c, power):
    for threshold, tier in TIERS:
        if signal(c, power) >= threshold:
            return tier
    return 0


def cell_intent(c, radius=RADIUS):
    return c["distance"] <= radius


def medium(c, power):
    return rate_tier(c, power) > 0


def gap(events, intent, mechanism):
    d = {"correct_admit": 0, "correct_deny": 0, "false_admit": 0, "false_deny": 0}
    for e in events:
        n, m = intent(e), mechanism(e)
        if n and m:
            d["correct_admit"] += 1
        elif not n and not m:
            d["correct_deny"] += 1
        elif m:
            d["false_admit"] += 1
        else:
            d["false_deny"] += 1
    return d


def local(c):
    """Decision at the access point: the budget of the point that hears the client applies."""
    return medium(c, POINTS[c["point"]][1])


def central(c):
    """Decision at the controller: one policy across every point."""
    return medium(c, SHARED_POWER)


pool = clients()
print(f"{'point':>5s} {'budget':>6s} {'clients':>8s} {'associated':>10s} "
      f"{'false admit':>12s} {'false deny':>12s}")
for i, (name, power) in enumerate(POINTS):
    k = [c for c in pool if c["point"] == i]
    d = gap(k, cell_intent, lambda c, p=power: medium(c, p))
    print(f"{name:>5s} {power:6d} {len(k):8d} {d['correct_admit'] + d['false_admit']:10d} "
          f"{d['false_admit']:12d} {d['false_deny']:12d}")
print()

print(f"{'regime':<12s} {'associated':>10s} {'full rate':>9s} {'correct':>7s} "
      f"{'false admit':>12s} {'false deny':>12s}")
for name, mechanism, tier_fn in (("independent", local, lambda c: rate_tier(c, POINTS[c["point"]][1])),
                                  ("controller", central, lambda c: rate_tier(c, SHARED_POWER))):
    d = gap(pool, cell_intent, mechanism)
    print(f"{name:<12s} {d['correct_admit'] + d['false_admit']:10d} "
          f"{sum(1 for c in pool if tier_fn(c) == 6):9d} "
          f"{d['correct_admit'] + d['correct_deny']:7d} "
          f"{d['false_admit']:12d} {d['false_deny']:12d}")
print()

diverging = [c for c in pool if len({medium(c, p) for _, p in POINTS}) > 1]
tier_diverging = [c for c in pool if len({rate_tier(c, p) for _, p in POINTS}) > 1]
print(f"clients whose association decision changes point to point: {len(diverging)}")
print(f"clients whose rate tier changes point to point: {len(tier_diverging)}")
print()

print(f"{'point pair':<11s} {'only first':>11s} {'only second':>12s} "
      f"{'tier differs':>13s}")
for label, g1, g2 in (("A / B", 58, 52), ("B / C", 52, 46), ("A / C", 58, 46)):
    print(f"{label:<11s} {sum(1 for c in pool if medium(c, g1) and not medium(c, g2)):11d} "
          f"{sum(1 for c in pool if medium(c, g2) and not medium(c, g1)):12d} "
          f"{sum(1 for c in pool if rate_tier(c, g2) != rate_tier(c, g1)):13d}")
point budget  clients associated  false admit   false deny
    A     58       10          8            2            0
    B     52       18          9            0            2
    C     46       12          8            0            2

regime       associated full rate correct  false admit   false deny
independent          25         5      34            2            4
controller           23         9      36            0            4

clients whose association decision changes point to point: 14
clients whose rate tier changes point to point: 29

point pair   only first  only second  tier differs
A / B                 8            0            22
B / C                 6            0            21
A / C                14            0            29

More Connect, Fewer Work

The independent regime associates 25 clients, the controller regime 23. A comparison that looked only at this column would declare the independent model the winner: two more clients connected.

The column next to it upsets this. Clients running at full rate tier are 5 in the independent regime, 9 in the controller regime. More clients associate and fewer work. The reason shows up in the table above: point A, pulled up to a budget of 58, gathers its share of clients from too far away, while point C, cut down to 46, drops its share into lower tiers. The average is a distribution that loses at both ends.

Reading the two directions separately clarifies the table further. False admit is 2 in the independent regime, 0 in the controller regime. Both leaks come from point A — the table above shows this directly: A’s false admit is 2, the other two’s is 0. False deny, on the other hand, is 4 in both regimes.

This equality is the lesson’s most important line. Raising one point’s budget bought two leaks and did not reduce the shortfall by a single client. The coverage gain went not to where it was needed but outside the area already covered. This is the course’s second claim: growing the apparatus does not bring it closer to intent.

Who Owns the Decision

The bottom two lines measure consistency. For 14 of the forty clients the association decision changes depending on which point evaluates it; for 29 the rate tier changes. So for roughly two-thirds of the forty clients, the answer to “what does this client get” is written not in the client’s condition but in which one it lands on.

The last table separates the pairs. Between A and C, 14 clients can associate only with A, and none can associate only with C — the asymmetry is total, because a lower budget only costs. The number of clients whose tier differs is 22 between A and B, 21 between B and C, 29 between A and C.

These numbers do not look like a coverage problem. A complaining user says “the network is slow in that corner of the building”; a measurement finds no coverage gap in that corner, because there is none. What has to be found instead is that the point covering that corner runs on a different budget.

A direct consequence of the inconsistency is paid in roaming. As a client moves between two points, it decides “I’m staying here” versus “I’m moving to the other one” based on the signal strength it itself measures; and the signal it measures depends on the point’s budget. A high-budget point keeps holding a client from far away, and the handover comes late; a low-budget point lets the client go early. When two budgets stand side by side within the same network, the handover threshold does not mean the same thing everywhere in the network. What this lesson measures is only the separation of the decision; when the handover itself should happen, and early versus late handover being two separate errors, is the subject of the roaming lesson.

The Controller’s Own Flaws

The controller model’s measured advantage is not free, and it is paid in two places.

The first is a single point of failure. What do the points do when the controller becomes unreachable? There are two behaviors: either they stop new association and preserve the policy, or they keep running with the last configuration in hand, falling back to standalone. If the second is chosen and the outage runs long, the network slowly drifts back to the independent regime — this time with no one noticing. The measurement’s independent row is the state at the end of a long stretch spent without a controller.

The second is a shared flaw. In the independent model, a wrong value breaks one point; in the controller model, a wrong value is distributed to every point. The controller regime in the measurement leaks zero because it distributes 52; had it distributed 58, the leak would have spread across the whole network. A shared view shares the shared error too.

Both of these flaws are narrowed by recording the configuration: if what value was distributed, when it changed, and which point it reached are written down, drift becomes a matter of measurement. If it is not written down, drift shows up only through user complaints, and the complaint points to the wrong place.

Summary

  • Association is a frame exchange, and the decision is made at the last step; that step writes both the acceptance and the granted rate tier, and the second shows up in no indicator.
  • An independent access point decides with its own budget and does not know its neighbor; the controller model builds a shared view by centralizing the control plane.
  • Configuration drift is a measurable flaw: three separate budgets associate 25 clients and produce 2 false admits, a shared policy associates 23 and leaks 0.
  • False deny is 4 in both regimes. Raising one point’s budget bought only leakage; it never reduced the shortfall.
  • For 14 of the forty clients the association decision, and for 29 the rate tier, changes with which point they land on; this does not look like a coverage gap.

Next Step

In this measurement the budgets came from the fiction, and why they were set to those values was never asked. Yet a wireless network’s design is exactly this question: which channel, which budget goes to each point, and where should the cells touch? The next lesson sweeps the budget alone — 58, 52, 46, and 40 — and counts both directions at every value. There it will be seen that lowering the budget zeroes out the leak, and the moment it does, the shortfall it leaves inside the cell grows silently.

To keep your progress and take notes, Log in

My notes

Log in to take notes.

Start typing to search.

↑↓ Esc navigate · open · close