In many Unets, not every node can communicate directly with every other node — the network is not fully connected. The ROUTING service delivers datagrams to such distant nodes by forwarding them through intermediate nodes, hop by hop, until they reach their destination.
A routing agent maintains a routing table: a set of entries that map a destination node to the next-hop neighbor (and the link) that should be used to reach it. When a datagram is sent to the routing agent (as a DatagramReq, since the agent provides the DATAGRAM service, Chapter 16), the agent looks up the destination in its table and forwards the datagram to the appropriate next hop. Each entry also carries a metric, which is used to choose between alternative routes to the same destination; the route with the best metric is preferred.
Routes can be managed in three ways:
Statically, by adding entries manually with an EditRouteReq (or the addroute command) — useful when the topology is known and fixed.
Dynamically, by letting the ROUTE_MAINTENANCE service (Chapter 22) discover routes automatically.
Reactively, by editing or disabling entries at runtime, for example to prefer a newly available link.
Routing in larger networks, including static routes, route metrics and multilink routing, is covered with worked examples in Chapter 6 and Section 7.1. The default router is accessed as router.
21.2 Messages
Agents providing this service honor the following requests:
A GetRouteReq for the best route to a destination is answered with a single RouteRsp (or a REFUSE if no matching route exists). With all set, it is answered with a series of RouteRsp messages — one per matching route — terminated by an AGREE response that marks the end of the list (or a REFUSE if there are none). An EditRouteReq is answered with an AGREE once the change is made:
Changes to the routing table — whether made by request or by route discovery — are announced by publishing the following notification on the agent’s topic, so that interested agents can track the topology as it evolves:
Every routing provider must also honor a DatagramTraceReq — a special DatagramReq used to trace the path taken to a destination. Because its behaviour is bound up with how the router forwards datagrams, it is documented separately under Section 21.7.
If a request is invalid, a REFUSE response may be generated. If the request fails, a FAILURE response may be generated.
21.3 Anatomy of a route
Each entry in the routing table — what you see in the routes listing, set with addroute/EditRouteReq, and returned in a RouteRsp — is a RouteInfo record. Its fields fall into three groups.
Where the route goes:
to — the destination node address the route is for. The special destination * (RouteInfo.DEFAULT_ROUTE) is a default route, used for any destination that has no more specific entry.
nextHop — the neighbour to forward to in order to reach to.
link — the link agent (a LINK/DATAGRAM provider, Chapter 18) over which the next hop is reached. On a gateway node with several links, this selects which one carries the traffic.
uuid — a unique identifier assigned to the entry when it is created. Use it to edit, delete or query one specific route (an EditRouteReq/GetRouteReq carrying the uuid, or the delroute command).
How good the route is — used to choose between alternative routes to the same destination:
metric — the overall quality of the route; higher is better. When several enabled routes reach the same destination, the router forwards over the one with the highest metric. By default this rewards higher data rates and penalizes each extra hop (see How it works below); a custom metric closure can replace the policy.
hops — the number of hops to the destination, if known (null/unknown otherwise); recorded as 0 when unspecified.
dataRate — the link’s data rate in bits per second, if known.
reliability — whether the link delivers reliably (acknowledged).
MTU / RTU — the maximum and recommended transmission units of the link (bytes), which tell higher layers how large a datagram the route can carry, and carry efficiently.
How the route behaves over time:
enabled — whether the route is currently in use. A disabled route stays in the table but is skipped during forwarding — for example after its link is reported down — until it is re-enabled.
auto — when true, the router enables or disables the route automatically in response to LinkStatusNtf messages (Chapter 18) from the link, so the table follows link up/down events without manual intervention.
poll — how often, in seconds, the router re-checks a disabled route to see whether its link has recovered; 0 turns polling off.
op — carried only on an EditRouteReq, naming the change to make: CREATE a new route, CHANGE an existing one (identified by uuid), or DELETE it.
Putting it together: when a datagram needs forwarding, the router matches its destination against the to of each enabled route (falling back to the default route), picks the best metric among the matches, and sends the datagram to that route’s nextHop over its link. The uuid lets you address a single entry when editing the table, while enabled, auto and poll govern how routes respond to links coming and going.
Tip
If a route’s link supports reliable delivery, set the route’s reliability flag so each hop is acknowledged and retransmitted at the link level. Per-hop reliability is far cheaper than end-to-end recovery: a lost fragment is retransmitted across one hop rather than the whole path, so the transport layer (Chapter 23) rarely needs to step in.
addroute 27, 29 // add a route to node 27 via node 29
addroute 27, 29, link2, false // add route on link2 with no reliability
addroute to: 27, metric: 3.2 // add route to 27 with metric 3.2
editroute – edit a route in the routing table
The route UUID can be obtained by displaying the routing table using the ‘routes’ command.
Example:
editroute 'as731', metric: 2.1 // edit route to change metric
editroute 'as731', nextHop: 21 // edit route to change next hop
delroute – delete a route from the routing table
The route UUID can be obtained by displaying the routing table using the ‘routes’ command.
Example:
delroute 'as7623' // delete route with UUID as7623
delroutesto – delete all routes to specified node from the routing table
Example:
delroutesto 27 // delete all routes to node 27
delroutes – delete all routes from the routing table
Example:
delroutes // delete all routes
21.6 Examples
Add a static route to a distant node and inspect the routing table. Here node 27 is reachable in two hops via next-hop neighbor 31, so we say so when adding the route (when the hop count is not given, it is recorded as 0, meaning unknown):
> addroute to:27, nextHop:31, hops:2OK> routes uuid to nextHop link reliability hops dataRate metric enabled auto poll------------------------------------------------------------------------------------------ 7nyi32 27 31 uwlink true 2 965 -7.0 true true 0.0
See Chapter 6 for full examples, including multi-hop and multilink routing.
21.7 Route tracing
Beyond ordinary datagrams, the router honors a special request — a DatagramTraceReq:
It is a DatagramReq subclass that adds no fields of its own — setting its to (the destination) is enough. It acts as a marker that switches the router into a trace-forwarding mode, and is the mechanism behind the user-facing trace command (Section 22.6); you do not normally construct one yourself.
A trace probe is forwarded towards its destination like any other datagram, but with two differences that let it record the path it takes:
Each node appends its own address to the datagram before forwarding it, so the probe accumulates the sequence of nodes it has passed through.
It is never short-circuited, even on a one-hop route — the router always adds its routing header rather than taking the header-less fast path — so every node on the path, endpoints included, is recorded.
The route-maintenance agent (Chapter 22) is a client of this mechanism: to trace a route, it sends a DatagramTraceReq from the source to the destination and back, then reports the collected hop sequence. See Section 22.6 for the full trace facility.
21.8 Implementation
21.8.1 Router (router)
Class
Services
Capabilities
Availability
Router
ROUTING, DATAGRAM
CANCELLATION
default stack
The default implementation is the router agent, loaded as part of the default stack (Chapter 13). Datagrams sent to it are forwarded towards their destination using the routing table.
21.8.1.1 How it works
The router keeps a table of routes, each naming a destination, the next-hop neighbor, the link agent to reach that neighbor, and metrics such as the hop count, the link data rate and whether the link is reliable. When a datagram arrives, the router looks up its destination: if it is this node, the datagram is delivered locally; otherwise it is forwarded to the chosen next hop over the assigned link. When several routes to a destination exist, the router picks one using a metric that, by default, penalizes each additional hop and rewards higher link data rates, so short, fast paths are preferred (a custom metric closure can replace this policy). Two parameters change the table’s behavior in bulk: with auto1hop enabled, the router assumes any address is directly reachable in a single hop over defaultLink (useful in fully connected networks where explicit routes are unnecessary), and with relay enabled, the router forwards traffic on behalf of other nodes rather than only sourcing and sinking its own. Routes are normally populated automatically by the route discovery agent (Chapter 22).
21.8.1.2 Automatic failover
Three distinct mechanisms let the routing table follow links as they come and go, without manual intervention:
Link status tracking — when a link publishes a LinkStatusNtf (Chapter 18) reporting that connectivity to a neighbor is lost or restored, the router disables or re-enables every route marked auto that uses that link and next hop. Disabled routes stay in the table but are skipped during forwarding, so traffic immediately shifts to the next best enabled route.
Failure-triggered retry — if a link reports a DatagramFailureNtf for a forwarded datagram, the router selects the best alternative route to the destination excluding the failed link, and silently retransmits the datagram over it. Retries continue for up to retryTimeout seconds (default 30) after the original request, so a transient link failure costs latency rather than a lost datagram. Since end-to-end reliability is only supported on single-hop routes, this retry switches between single-hop alternatives for reliable datagrams.
Poll-based recovery — a disabled route with a non-zero poll is re-checked every poll seconds: the router probes the next hop with a small reliable datagram over the route’s link. A successful probe causes the link to report itself up again, re-enabling the route. Links that detect recovery on their own (e.g. through peer advertisements) do not need polling.
A worked example showing all three mechanisms in action — traffic failing over from a UDP link to an acoustic link and back — is given in Section 7.4.
21.8.1.3 Usage notes
For small fixed networks, set up routes by hand (addroute) or enable auto1hop; for larger or changing networks, let rdp discover them (Chapter 22).
Disable relay on leaf nodes that should never forward other nodes’ traffic.