Nextmini
Design

Custom Routes Configuration Example

How Nextmini persists and distributes explicitly defined routes.

This example uses a full_mesh topology with four nodes and explicit route definitions in the controller configuration. The controller resolves these definitions into its route table, assigns route IDs, and distributes only the entries relevant to each dataplane node.

Configuration file example

protocol = "quic"

[topology]
type = "full_mesh"
full_mesh_config = { n_nodes = 4 }

# Custom routes
[[routes]]
route = [1, 2, 3, 4]

[[routes]]
route = [1, 3, 2, 4]

[[routes]]
route = [1, 3, 4]

[[routes]]
route = [4, 3, 2, 1]

[[routes]]
route = [4, 2, 3, 1]

[[routes]]
route = [4, 3, 1]

[[routes]]
route = [1, 2]

[[routes]]
route = [2, 1]

Routes table in the database

After startup, Nextmini stores the resolved routes in PostgreSQL and assigns stable route_id values.

route_idsrc_node_iddst_node_idroute
012[1, 2]
113[1, 3]
214[1, 4]
321[2, 1]
423[2, 3]
524[2, 4]
631[3, 1]
732[3, 2]
834[3, 4]
941[4, 1]
1042[4, 2]
1143[4, 3]
1214[1, 2, 3, 4]
1314[1, 3, 2, 4]
1414[1, 3, 4]
1541[4, 3, 2, 1]
1641[4, 2, 3, 1]
1741[4, 3, 1]

Custom routes that already exist as topology routes, such as [1, 2] and [2, 1], are treated as duplicates and are not inserted again.

Route entries sent to dataplane nodes

Routes for Node 1 (MessagePack Format)

ControllerToDataplane::InstallRoutes {
    routes: vec![
        // Preset routes (route_id 0-11)
        RoutingTableEntry { route_id: 0,  next_hop: 2, src_node_id: 1, dst_node_id: 2 },  // [1,2]
        RoutingTableEntry { route_id: 1,  next_hop: 3, src_node_id: 1, dst_node_id: 3 },  // [1,3]
        RoutingTableEntry { route_id: 2,  next_hop: 4, src_node_id: 1, dst_node_id: 4 },  // [1,4]
        RoutingTableEntry { route_id: 3,  next_hop: 1, src_node_id: 2, dst_node_id: 1 },  // [2,1] - local delivery
        RoutingTableEntry { route_id: 4,  next_hop: 0, src_node_id: 2, dst_node_id: 3 },  // [2,3] - not via node 1
        RoutingTableEntry { route_id: 5,  next_hop: 0, src_node_id: 2, dst_node_id: 4 },  // [2,4] - not via node 1
        RoutingTableEntry { route_id: 6,  next_hop: 1, src_node_id: 3, dst_node_id: 1 },  // [3,1] - local delivery
        RoutingTableEntry { route_id: 7,  next_hop: 0, src_node_id: 3, dst_node_id: 2 },  // [3,2] - not via node 1
        RoutingTableEntry { route_id: 8,  next_hop: 0, src_node_id: 3, dst_node_id: 4 },  // [3,4] - not via node 1
        RoutingTableEntry { route_id: 9,  next_hop: 1, src_node_id: 4, dst_node_id: 1 },  // [4,1] - local delivery
        RoutingTableEntry { route_id: 10, next_hop: 0, src_node_id: 4, dst_node_id: 2 },  // [4,2] - not via node 1
        RoutingTableEntry { route_id: 11, next_hop: 0, src_node_id: 4, dst_node_id: 3 },  // [4,3] - not via node 1

        // Custom routes (route_id 12-17)
        RoutingTableEntry { route_id: 12, next_hop: 2, src_node_id: 1, dst_node_id: 4 },  // [1,2,3,4]
        RoutingTableEntry { route_id: 13, next_hop: 3, src_node_id: 1, dst_node_id: 4 },  // [1,3,2,4]
        RoutingTableEntry { route_id: 14, next_hop: 3, src_node_id: 1, dst_node_id: 4 },  // [1,3,4]
        RoutingTableEntry { route_id: 15, next_hop: 1, src_node_id: 4, dst_node_id: 1 },  // [4,3,2,1] - local delivery
        RoutingTableEntry { route_id: 16, next_hop: 1, src_node_id: 4, dst_node_id: 1 },  // [4,2,3,1] - local delivery
        RoutingTableEntry { route_id: 17, next_hop: 1, src_node_id: 4, dst_node_id: 1 },  // [4,3,1] - local delivery
    ]
}

Routing behavior

Route resolution is deterministic. The controller first materializes direct topology routes, then adds custom routes and assigns IDs. On each node, it computes the next hop: the destination node uses its own ID to indicate local delivery, intermediate nodes forward to the next node in the configured path, and nodes not on a path receive an INVALID next hop. Route updates propagate through PostgreSQL notifications and are pushed to dataplane nodes via WebSocket whenever the route table changes. The payload is serialized in MessagePack for efficient transport.

On this page