vlab.routing
K J Somaiya School of Engineering·Experiment 08·16010425070

Routing algorithmimplementation.

Watch routers learn the network. Step through Distance Vector and Link State routing, build routing tables, and forward packets hop by hop.

01 · Link State

Link State

Flood what you see.

Then compute your own tree.

02 · Forwarding

Forwarding

One lookup per hop.

A to F, cost thirteen.

Hero section 0 of 3

Aim

To understand and implement routing algorithms — Distance Vector Routing (Bellman-Ford) and Link State Routing (Dijkstra) — and observe how routing tables are built and used for packet forwarding.

Watch routers learn the network.

Four stages, in the order a router lives them: hear from your neighbours, see the whole map, move the packet, then write it down in code.

01

Distance Vector

Trust your neighbours.Share what you know.

Every router hands its own distance estimates to the routers next door, adds the cost of getting to them, and keeps the cheapest answer. Nobody sees the topology — the table is assembled out of hearsay, one hop per round.

Vector from B

D 5via D

F 10via D

Vector from C

D 6via B

F 11via B

Local links at A

B4

C2

Routing table

Router A · converged

DestNext hopCost
BC3
CC2
DC8
EC10
FC13

Converged entries

0 / 5

Exchange rounds
0
Entries updated
0
Neighbours of A
0
Routers in network
0

02

Link State

See the whole map.Plan your own path.

Each router floods a description of its own links to everyone, so all of them hold an identical database. Then each one runs Dijkstra alone and derives its own shortest-path tree — no negotiation, no waiting.

LSDB

9 links · identical in every router

A–B4A–C2B–C1B–D5C–D8C–E10D–E2D–F6E–F3
Dijkstra run · source A

03

Packet Forwarding

Every hop.One lookup.

With the tables built, moving a packet is one table lookup per router. No router knows the whole journey; the packet arrives because every table along the way agrees, and is dropped or looped when one of them does not.

Network / Forwarding workspace

Next hop resolved

A → F

∞→13

At router A

→ via C

At router C

→ via B

At router B

→ via D

At router D

→ via E

At router E

→ via F

Hops

0

Total cost

0

Tables read

0

0 / 5 delivered

04

Implementation

From theoryto working code.

Both algorithms in C, C++, Python and Java. Every program models the default lab network and prints router A's routing table, so its output can be checked against the simulations on this page.

Link State · Dijkstra
dijkstra.c
/* Link State Routing - Dijkstra's shortest path algorithm.
 *
 * Every router floods its own link costs, so every router ends up holding
 * the same Link State Database. This program is what ONE router then runs
 * over that database to build its own shortest-path tree and routing table.
 *
 * Build: gcc dijkstra.c -o dijkstra && ./dijkstra
 */
#include <stdio.h>

#define N   6      /* routers A..F                              */
#define INF 9999   /* "no direct link" / "not reachable yet"     */

/* cost[i][j] = cost of the direct link i-j, INF when there is none.
 * Default lab network:
 *   A-B 4, A-C 2, B-C 1, B-D 5, C-D 8, C-E 10, D-E 2, D-F 6, E-F 3 */
int cost[N][N] = {
/*          A     B     C     D     E     F   */
/* A */ {   0,    4,    2,  INF,  INF,  INF },
/* B */ {   4,    0,    1,    5,  INF,  INF },
/* C */ {   2,    1,    0,    8,   10,  INF },
/* D */ { INF,    5,    8,    0,    2,    6 },
/* E */ { INF,  INF,   10,    2,    0,    3 },
/* F */ { INF,  INF,  INF,    6,    3,    0 }
};

int dist[N];     /* dist[v]    = cheapest known cost source -> v   */
int parent[N];   /* parent[v]  = predecessor of v on that path      */
int done[N];     /* done[v]    = 1 once dist[v] can never improve   */

void dijkstra(int src)
{
    int i, round, u, v;

    /* 1. Initialise: source at 0, everything else at infinity. */
    for (i = 0; i < N; i++) {
        dist[i]   = INF;
        parent[i] = -1;
        done[i]   = 0;
    }
    dist[src] = 0;

    /* 2. Finalise one router per round, always the cheapest one left. */
    for (round = 0; round < N; round++) {
        int best = INF;
        u = -1;
        for (i = 0; i < N; i++)
            if (!done[i] && dist[i] < best) { best = dist[i]; u = i; }

        if (u == -1) break;      /* whatever is left is unreachable */
        done[u] = 1;

        /* 3. Relax every link out of u that leads somewhere unfinished. */
        for (v = 0; v < N; v++) {
            if (done[v] || cost[u][v] >= INF) continue;
            if (dist[u] + cost[u][v] < dist[v]) {
                dist[v]   = dist[u] + cost[u][v];
                parent[v] = u;
            }
        }
    }
}

/* A router stores only ONE hop, not the whole path. The next hop is the
 * first router after the source, so walk parent[] back towards src. */
int next_hop(int src, int dest)
{
    int hop = dest;
    if (dest == src || parent[dest] == -1) return -1;
    while (parent[hop] != src) hop = parent[hop];
    return hop;
}

int main(void)
{
    int src = 0;    /* 0 = router A */
    int v;

    dijkstra(src);

    printf("Routing table for router %c (Link State / Dijkstra)\n", 'A' + src);
    printf("%-12s %-10s %s\n", "Destination", "Next Hop", "Cost");
    for (v = 0; v < N; v++) {
        int hop;
        if (v == src) continue;
        hop = next_hop(src, v);
        if (hop == -1)
            printf("%-12c %-10s %s\n", 'A' + v, "-", "INF");
        else
            printf("%-12c %-10c %d\n", 'A' + v, 'A' + hop, dist[v]);
    }
    return 0;
}

/* Expected output:
 *   B  C  3      D  C  8
 *   C  C  2      E  C  10
 *                F  C  13                                        */
Distance Vector · Bellman-Ford
distance_vector.c
/* Distance Vector Routing - distributed Bellman-Ford.
 *
 * Each router keeps one distance vector and periodically hands it to its
 * DIRECT NEIGHBOURS ONLY. On receiving a neighbour's vector it applies
 *
 *     D(x, y) = min over neighbours v of { c(x, v) + D(v, y) }
 *
 * Build: gcc distance_vector.c -o dv && ./dv
 */
#include <stdio.h>

#define N   6    /* routers A..F                                      */
#define INF 16   /* RIP-style infinity: 16 hops means "unreachable"    */

/* Direct link costs. INF means the two routers are not neighbours.
 * Default lab network:
 *   A-B 4, A-C 2, B-C 1, B-D 5, C-D 8, C-E 10, D-E 2, D-F 6, E-F 3 */
int cost[N][N] = {
/*          A     B     C     D     E     F   */
/* A */ {   0,    4,    2,  INF,  INF,  INF },
/* B */ {   4,    0,    1,    5,  INF,  INF },
/* C */ {   2,    1,    0,    8,   10,  INF },
/* D */ { INF,    5,    8,    0,    2,    6 },
/* E */ { INF,  INF,   10,    2,    0,    3 },
/* F */ { INF,  INF,  INF,    6,    3,    0 }
};

int dv[N][N];       /* dv[x][y]      = D(x, y), x's cost to reach y   */
int nexthop[N][N];  /* nexthop[x][y] = neighbour x forwards y through */

/* Every router starts knowing only itself and its direct neighbours. */
void initialise(void)
{
    int x, y;
    for (x = 0; x < N; x++) {
        for (y = 0; y < N; y++) {
            if (x == y) {
                dv[x][y] = 0;    nexthop[x][y] = x;
            } else if (cost[x][y] < INF) {
                dv[x][y] = cost[x][y];  nexthop[x][y] = y;
            } else {
                dv[x][y] = INF;  nexthop[x][y] = -1;
            }
        }
    }
}

/* One synchronous exchange round. Returns 1 if any entry changed.
 * Every router advertises first, so all of them recompute from the same
 * snapshot - that is what "one round" means. */
int exchange_round(void)
{
    int advertised[N][N];
    int x, y, v, changed = 0;

    for (x = 0; x < N; x++)
        for (y = 0; y < N; y++)
            advertised[x][y] = dv[x][y];

    for (x = 0; x < N; x++) {
        for (y = 0; y < N; y++) {
            int best, best_hop;
            if (x == y) continue;

            best = INF;
            best_hop = -1;
            for (v = 0; v < N; v++) {                 /* v = each neighbour */
                int alt;
                if (v == x || cost[x][v] >= INF) continue;
                alt = cost[x][v] + advertised[v][y];  /* Bellman-Ford       */
                if (alt > INF) alt = INF;             /* clamp at infinity  */
                if (alt < best) { best = alt; best_hop = v; }
            }

            if (best != dv[x][y] || best_hop != nexthop[x][y]) changed = 1;
            dv[x][y]      = best;
            nexthop[x][y] = (best >= INF) ? -1 : best_hop;
        }
    }
    return changed;
}

void print_table(int x)
{
    int y;
    printf("\nRouting table for router %c (Distance Vector)\n", 'A' + x);
    printf("%-12s %-10s %s\n", "Destination", "Next Hop", "Cost");
    for (y = 0; y < N; y++) {
        if (y == x) continue;
        if (dv[x][y] >= INF) printf("%-12c %-10s %s\n", 'A' + y, "-", "INF");
        else printf("%-12c %-10c %d\n", 'A' + y, 'A' + nexthop[x][y], dv[x][y]);
    }
}

int main(void)
{
    int round = 0;

    initialise();
    while (exchange_round()) {         /* repeat until nothing changes */
        round++;
        printf("Round %d: vectors exchanged, tables updated.\n", round);
        if (round > 100) break;        /* safety net */
    }
    printf("Converged after %d round(s).\n", round);

    print_table(0);                    /* router A */
    return 0;
}

/* Expected table for A:  B C 3 | C C 2 | D C 8 | E C 10 | F C 13 */

Two ways routers learn.

Distance Vector

Talk to neighbours. Converge together.

A router only ever speaks to the routers it is directly wired to. It sends its whole distance vector, they add the link cost, and the network settles one hop per round.

Neighbour
Router
Neighbour

Link State

Flood the map. Compute locally.

Every router describes its own links and floods that description to all of them. Each one then runs Dijkstra by itself over an identical database.

Flooded inTree out
LSP from B
LSP from D
LSP from E
dijkstra>>

Side by side

Run them both
AspectDistance VectorLink State
Knowledge of the networkKnows only its neighbours and the distances they claim. It never sees the topology.Knows the complete topology: every router, every link, every cost.
Information sharedIts own distance vector — one cost per destination.Its own link states (LSPs) — the cost of each directly attached link.
Shared withDirect neighbours only.Every router in the area, by flooding.
AlgorithmDistributed Bellman-Ford, run piecewise across all routers.Dijkstra, run independently and completely inside each router.
ConvergenceSlow — news travels one hop per update period.Fast — flooding is near-immediate and each router then recomputes alone.
Routing loopsPossible; count-to-infinity needs split horizon, poison reverse and hold-down timers.Essentially loop-free, because every router computes from the same map.
Bandwidth usageSmall periodic updates, but sent constantly (RIP: every 30 s).A burst during flooding, then only on change plus a slow refresh.
CPU / memoryCheap — one vector and a simple minimum.Expensive — stores the whole LSDB and runs Dijkstra over it.
Example protocolRIP, RIPv2, IGRP (hop count, max 15).OSPF, IS-IS (cost from interface bandwidth).

Built on the protocols the Internet runs on.

Real-world implementations of these algorithms.

  • RIPRFC 1058DV
  • RIPv2RFC 2453DV
  • OSPFRFC 2328LS
  • IS-ISISO 10589LS
  • EIGRPRFC 7868DV
  • BGPRFC 4271PV

DV — distance vector · LS — link state · PV — path vector

Phase 1 · Baseline assessment

Check what you know.Before the lab.

Ten questions on the foundations: routing against forwarding, what a routing table holds, what a metric measures, static against dynamic routing, and which real protocols belong to which algorithm family.

10 questions · covers

  • Routing versus forwarding — control plane against data plane
  • Routing table structure: Destination, Next Hop, Cost
  • Metrics: hop count, bandwidth-derived cost
  • Static versus dynamic routing
  • Which protocols are Distance Vector and which are Link State

One question at a time. A score and a per-question explanation are shown at the end.

One network. Three views.

The same six routers throughout — A-B 4, A-C 2, B-C 1, B-D 5, C-D 8, C-E 10, D-E 2, D-F 6, E-F 3. Build the tables with Dijkstra, build them again with Bellman-Ford, then send a packet through them. Every algorithm step is logged in the diagnostic console.

Network / Routing workspace
loading simulation▌

Phase 2 · Verification assessment

Now apply it.After the lab.

Ten harder questions: compute a Dijkstra result on a graph given in the question, work through a single Bellman-Ford update step, reason about count-to-infinity and the fixes for it, and compare OSPF against RIP on convergence and metric.

10 questions · covers

  • Running Dijkstra on a graph shown in the question
  • One Bellman-Ford update step, by hand
  • Count-to-infinity, split horizon and poison reverse
  • OSPF against RIP: metric, scope and update behaviour
  • Convergence: why link state settles faster than distance vector

One question at a time. A score and a per-question explanation are shown at the end.

AI use case · KJS-SRS-01

Applying routing algorithms to SomaiyaSat.

SomaiyaSat is a PocketQube released into orbit by SomaiyaPod, its own deployer. Once free, an onboard AI manager decides — pass by pass, inside a sub-1 W budget — what to send home and over which radio mode. Strip the framing away and that is the problem this experiment is about: a cost, a table, and a next hop.

Use case ID
KJS-SRS-01
Vertical
Space technology & remote sensing
Collaborator
ReOrbit, Finland
Beneficiaries
Global amateur radio community
SomaiyaSatAI router
full map

Link State

The orbit and pass predictor hands the router a complete graph of upcoming contact windows. Dijkstra over it returns a shortest-path tree: when to transmit, and through whom.

neighbours only

Distance Vector

In an inter-satellite mesh no spacecraft holds the whole topology. Each advertises its own distance to the ground segment and Bellman-Ford converges on the rest.

one lookup per hop

Forwarding

The hot path. Every frame — TT&C, SSTV imagery, M17 or Codec2 voice — is matched against the table and handed to a next hop. No search, no recomputation.

Ground station networkHAM + mission ops

The AI-based manager aboard SomaiyaSat takes link-quality estimates, battery and power telemetry, and a prioritised queue of pending data, then chooses the transmission order and the radio mode for the pass. That is a routing decision with a cost that changes every few seconds. Link State supplies the planning half: the orbit and pass predictor produces a graph of contact windows whose edge weights are predicted SNR, pointing margin and energy per bit, and Dijkstra over that graph yields the tree of cheapest routes to the ground segment — computed once, from a map the satellite already holds.

Distance Vector supplies the distributed half. The moment SomaiyaSat flies alongside other spacecraft, no node has the whole topology, so each advertises its own distance to the ground and Bellman-Ford settles the rest between them. Everything this lab shows about count-to-infinity then stops being an exercise: split horizon, poison reverse and hold-down timers are what keep a loop from stranding housekeeping data, and in orbit a stranded frame means the pass is simply gone.

Forwarding is what actually runs in flight. TT&C and housekeeping are always highest priority, then SSTV imagery, then M17 and Codec2 traffic; each frame costs one table lookup on a microcontroller, with an infinity value — RIP uses 16 — standing for no usable contact this pass. The table is also the safety net the mission requires: when the model's output looks anomalous, the router falls back to the plain rule-based table and the spacecraft still talks.

Where this experiment plugs in.

Course-level mapping for the framework's Part C: what each topic contributes to the mission, and how it would be integrated.

From this experimentRole in the missionMode of integration
Dijkstra, shortest-path treePlans the downlink schedule across a predicted contact graph, where edge cost is predicted SNR, pointing margin and energy per bit.This simulation reused as a pass-planning model
Distributed Bellman-FordConverges inter-satellite routes to the ground segment without any node holding a global map — the only option once the constellation grows.Mini-project on the flight software team
Split horizon, poison reverse, hold-downStops a routing loop from stranding housekeeping data. A loop in orbit is a pass lost, and passes do not come back.Case study inside the theory module
Routing table and next-hop lookupRuns on the PocketQube flight computer inside a sub-1 W budget, so the lookup has to be O(1)-ish and allocation-free.Embedded firmware extension
Metric design and RIP infinityTurns link quality, battery state and data urgency into one comparable cost, with an infinity value standing for no usable contact this pass.Open-ended assignment

Governing an agent that flies alone.

AI security & trustworthinessHigh

Routing decisions must be verifiable. A plain rule-based table is the fallback whenever the model's output looks anomalous.

Agentic AIHigh

The onboard router acts alone for the length of a pass. There is no human in the loop while it is deciding.

Human-in-the-loopMedium

Ground operators keep command override and safe-mode triggers; autonomy is bounded by the last uplink.

RegulatoryHigh

Amateur radio allocation and licensing, plus PocketQube launch and registration compliance.

Distance Vector trusts neighbours.Link State trusts the map.

Routing tables are built, not configured. Distance Vector Routing builds them with a distributed Bellman-Ford: each router shares its own distance estimates with its direct neighbours, which is cheap and simple but converges one hop per period and can count-to-infinity until split horizon, poison reverse and hold-down timers restrain it. Link State Routing builds them by flooding link state packets so that every router holds an identical LSDB, then running Dijkstra locally — far more memory and CPU, but fast convergence and essentially no loops. Both end at the same artefact, a Destination | Next Hop | Cost table, and packet forwarding then needs nothing more than one lookup per router: the packet crosses the network on a chain of independent local decisions, and arrives only because every table along the way agrees.

Dijkstra from A
B 3 · C 2 · D 8 · E 10 · F 13
DV converged
identical costs, next hop C
RIP infinity
16 = unreachable

Submitted by Roll No. 16010425070·Experiment 08·K J Somaiya School of Engineering