886 lines
19 KiB
Markdown
886 lines
19 KiB
Markdown
# Mininet Topology JSON Language: Rationale and Reference
|
|
|
|
## 1. Purpose and design rationale
|
|
|
|
This document explains why the topology language has its current shape, then
|
|
serves as a reference for its JSON fields, defaults, and semantic constraints.
|
|
The starting point is the assignment: describe hosts, switches, a router, two
|
|
subnets, and DHCP configuration in a form that can also express other valid
|
|
topologies.
|
|
|
|
### 1.1 Describe network intent
|
|
|
|
The JSON describes the desired network and its configuration.
|
|
A reader should be able to identify participants, connections, addresses, and
|
|
services without tracing a sequence of Python or shell commands.
|
|
This makes a topology easier to inspect and change independently of the code
|
|
that constructs it.
|
|
|
|
The design combines top-down modeling with bottom-up implementability.
|
|
We start with the concepts needed to describe the network, while requiring each
|
|
concept to have a clear translation into Mininet and Linux networking
|
|
primitives.
|
|
Nodes, interfaces, links, network-stack settings, and processes provide that
|
|
translation without requiring a separate abstraction for every assignment step.
|
|
|
|
This is why the language distinguishes a router from a host even though both
|
|
can use similar underlying construction mechanisms.
|
|
Their network roles differ, so the description expresses that distinction.
|
|
Conversely, DHCP is a service on a node rather than a new kind of network node.
|
|
|
|
### 1.2 Give each property a clear owner
|
|
|
|
The network structure leads to five core entities:
|
|
|
|
| Entity | Question it answers |
|
|
| --- | --- |
|
|
| Node | What participates in the network, and what role does it have? |
|
|
| Interface | Where does a node attach, and how is that attachment configured? |
|
|
| Link | Which two interfaces are connected? |
|
|
| Node settings | How should the node's network stack behave? |
|
|
| Service | Which service runs on a node, and where is it bound? |
|
|
|
|
An interface belongs to its node because addressing, MAC, and MTU describe that
|
|
node's attachment to the network.
|
|
A link references two interfaces and owns connection properties such as delay
|
|
or bandwidth.
|
|
Keeping endpoint configuration out of links gives each property one clear
|
|
place in the description.
|
|
|
|
The same interface structure works for hosts, routers, and switches.
|
|
An interface is an attachment point even when it has no IP address, which makes
|
|
unaddressed switch ports natural to represent.
|
|
Addressing is therefore optional, while MAC and MTU remain independent fields.
|
|
|
|
### 1.3 Separate behavior from services
|
|
|
|
Forwarding and reverse-path filtering describe network-stack behavior and
|
|
belong in node settings.
|
|
A DHCP server is a running service with its own configuration, so it belongs in
|
|
`services`.
|
|
This separation lets a node host a service without changing its node type.
|
|
|
|
A service's `node` and `interface` fields describe its placement.
|
|
Its `settings` describe its behavior, such as the DHCP address range and
|
|
advertised gateway.
|
|
Keeping placement outside service-specific settings preserves the same shape
|
|
for future service types.
|
|
|
|
### 1.4 Make identity explicit where it matters
|
|
|
|
Logical interface tags such as `lan` and `wan` express the meaning of a
|
|
connection without depending on generated operating-system interface names.
|
|
Explicit tags let a topology identify a particular attachment point.
|
|
The `auto` selector avoids unnecessary port naming when only connectivity
|
|
matters, as is often the case for a switch.
|
|
|
|
An omitted interface set allows automatic allocation as needed.
|
|
An explicitly declared set defines the available ports, so automatic selection
|
|
must stay within that set.
|
|
This distinction preserves both convenience and the ability to express a fixed
|
|
interface limit; an explicit empty set consequently means zero available ports.
|
|
|
|
### 1.5 Describe configuration without recording runtime state
|
|
|
|
Static addressing declares a known address and, optionally, a default gateway.
|
|
DHCP addressing declares how configuration will be obtained; the acquired
|
|
address and lease are runtime results.
|
|
The language therefore does not require a DHCP client to contain an address
|
|
that is not yet known.
|
|
|
|
The same boundary excludes learned ARP entries, packet counters, captures, and
|
|
experimental commands from the topology description.
|
|
Those observations change as the network runs, while the declared topology
|
|
continues to describe its configuration intent.
|
|
|
|
### 1.6 Keep the language small and predictable
|
|
|
|
The current assignment needs a static default gateway, rather than a general
|
|
routing-policy language.
|
|
It needs a DHCP service with an address range and an optional advertised
|
|
gateway, rather than arbitrary daemon command lines.
|
|
The chosen fields cover those requirements while leaving settings and services
|
|
as clear places for future extensions.
|
|
|
|
Unknown fields are rejected so a misspelled setting cannot silently change the
|
|
meaning of a topology.
|
|
The reference below defines the supported vocabulary and the constraints that
|
|
make declarations consistent.
|
|
It proceeds from the entity model through nodes, interfaces, links, and
|
|
services, then collects the grammar and semantic rules before a complete
|
|
example.
|
|
|
|
For setup and usage, see the [README](README.md).
|
|
Its [Architecture section](README.md#architecture) describes the Python
|
|
processing pipeline, generated code, and execution behavior.
|
|
|
|
---
|
|
|
|
## 2. High-level entity model
|
|
|
|
The current grammar is:
|
|
|
|
```text
|
|
Network
|
|
├── Nodes
|
|
│ ├── name
|
|
│ ├── type
|
|
│ ├── interfaces
|
|
│ └── settings
|
|
│
|
|
├── Links
|
|
│ ├── name?
|
|
│ ├── endpoints
|
|
│ │ ├── node
|
|
│ │ └── interface
|
|
│ └── settings
|
|
│
|
|
└── Services
|
|
├── type
|
|
├── node
|
|
├── interface
|
|
└── settings
|
|
```
|
|
|
|
The actual JSON keys are lowercase: `nodes`, `links`, and `services`.
|
|
Each top-level list may be omitted and defaults to an empty list.
|
|
Node `interfaces` and node/link `settings` are optional.
|
|
Service `settings` must contain the fields required by its type.
|
|
|
|
The main entities intentionally have different responsibilities.
|
|
|
|
```text
|
|
Node
|
|
identifies a network participant
|
|
|
|
Link
|
|
connects two network attachment points
|
|
|
|
Service
|
|
represents a process or daemon running on a node
|
|
```
|
|
|
|
Common entities used in these entities are:
|
|
|
|
```text
|
|
Interface
|
|
identifies a network attachment point owned by a node
|
|
|
|
Settings
|
|
configure the node/link/service or its networking stack
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Nodes
|
|
|
|
A node represents a logical network participant.
|
|
|
|
The current structure is:
|
|
|
|
```text
|
|
Node
|
|
├── name
|
|
├── type
|
|
├── interfaces
|
|
└── settings
|
|
```
|
|
|
|
### 3.1 Node name
|
|
|
|
`name` is the logical identifier used by the rest of the topology.
|
|
|
|
For example:
|
|
|
|
```json
|
|
{
|
|
"name": "r0",
|
|
"type": "router"
|
|
}
|
|
```
|
|
|
|
Node names are expected to be unique.
|
|
|
|
Duplicate node names are invalid.
|
|
|
|
### 3.2 Node type
|
|
|
|
The currently supported node types are:
|
|
|
|
```text
|
|
host
|
|
switch
|
|
router
|
|
```
|
|
|
|
A `host` is an end system.
|
|
A `switch` is an autonomous Layer-2 learning switch.
|
|
A `router` connects IP networks and supports forwarding and reverse-path-filter
|
|
settings.
|
|
Selecting `router` does not implicitly enable forwarding.
|
|
|
|
### 3.3 Node settings
|
|
|
|
`settings` contains configuration that changes the behavior of the node itself.
|
|
|
|
For a router, the currently supported settings are:
|
|
|
|
```json
|
|
"settings": {
|
|
"ip_forward": true,
|
|
"rp_filter": false
|
|
}
|
|
```
|
|
|
|
These values configure the networking behavior of the node namespace.
|
|
Omitted router settings leave the corresponding behavior unspecified.
|
|
Hosts and switches currently accept only empty settings objects.
|
|
|
|
They are not modeled as services because they do not represent independent
|
|
user-space processes.
|
|
|
|
The distinction is:
|
|
|
|
```text
|
|
Node settings
|
|
-> properties of the node or its networking stack
|
|
|
|
Services
|
|
-> processes or daemons running on the node
|
|
```
|
|
|
|
Node settings are type-specific.
|
|
|
|
Unknown settings for the selected node type are invalid.
|
|
|
|
---
|
|
|
|
## 4. Interfaces
|
|
|
|
Interfaces belong to nodes.
|
|
|
|
This is a deliberate modeling decision.
|
|
|
|
```text
|
|
Node owns Interfaces
|
|
Link connects Interfaces
|
|
```
|
|
|
|
An interface is broader than an object that merely owns an IP address.
|
|
|
|
It is a network attachment point with optional Layer-3 configuration and
|
|
optional interface-level properties.
|
|
|
|
Conceptually:
|
|
|
|
```text
|
|
Interface
|
|
=
|
|
network attachment point
|
|
+ optional L3 configuration
|
|
+ optional interface properties
|
|
```
|
|
|
|
A host or router interface will commonly have Layer-3 addressing.
|
|
|
|
A Layer-2 switch port normally will not.
|
|
|
|
Using one interface abstraction for all node types keeps link endpoints
|
|
uniform.
|
|
|
|
### 4.1 Logical interface tags
|
|
|
|
Interfaces are declared as members of the `interfaces` object.
|
|
|
|
The JSON key is the logical interface tag.
|
|
|
|
For example:
|
|
|
|
```json
|
|
"interfaces": {
|
|
"lan": {
|
|
"addressing": "static",
|
|
"address": "192.168.1.1/24"
|
|
},
|
|
"wan": {
|
|
"addressing": "static",
|
|
"address": "192.168.2.1/24"
|
|
}
|
|
}
|
|
```
|
|
|
|
`lan` and `wan` are topology-level identifiers.
|
|
|
|
They are not required to be the real Linux interface names.
|
|
|
|
Logical tags identify interfaces within the JSON independently of generated
|
|
operating-system interface names.
|
|
|
|
The same mechanism may be used for meaningful switch-port names.
|
|
|
|
For example:
|
|
|
|
```json
|
|
"interfaces": {
|
|
"client1": {},
|
|
"client2": {},
|
|
"server": {},
|
|
"uplink": {}
|
|
}
|
|
```
|
|
|
|
### 4.2 Interface properties
|
|
|
|
The current interface structure is flat.
|
|
|
|
There is no nested addressing object.
|
|
|
|
The currently modeled properties are:
|
|
|
|
```text
|
|
addressing? static | dhcp | none
|
|
address? required with static addressing
|
|
gateway? optional with static addressing
|
|
mac? optional interface property
|
|
mtu? optional interface property
|
|
```
|
|
|
|
Possible future interface properties can be added at the same level.
|
|
|
|
### 4.3 Addressing semantics
|
|
|
|
The supported addressing values are:
|
|
|
|
```text
|
|
static
|
|
dhcp
|
|
none
|
|
```
|
|
|
|
The `addressing` field is optional.
|
|
|
|
Omitting it is semantically equivalent to:
|
|
|
|
```json
|
|
"addressing": "none"
|
|
```
|
|
|
|
Therefore these two declarations mean the same thing:
|
|
|
|
```json
|
|
"p1": {}
|
|
```
|
|
|
|
```json
|
|
"p1": {
|
|
"addressing": "none"
|
|
}
|
|
```
|
|
|
|
Both mean that no Layer-3 addressing configuration is requested.
|
|
|
|
#### Static addressing
|
|
|
|
A static interface is written as:
|
|
|
|
```json
|
|
"net0": {
|
|
"addressing": "static",
|
|
"address": "192.168.2.10/24",
|
|
"gateway": "192.168.2.1"
|
|
}
|
|
```
|
|
|
|
`address` is required.
|
|
|
|
`gateway` is optional.
|
|
|
|
The gateway is kept with static interface configuration because this matches
|
|
the simple configuration model used by traditional Linux network
|
|
configuration.
|
|
|
|
For the scope of this assignment, this is simpler than introducing a general
|
|
routing language.
|
|
|
|
#### DHCP addressing
|
|
|
|
A DHCP interface is written as:
|
|
|
|
```json
|
|
"net0": {
|
|
"addressing": "dhcp"
|
|
}
|
|
```
|
|
|
|
A DHCP interface does not contain a predetermined address or gateway.
|
|
|
|
Those values are runtime configuration learned from the DHCP server.
|
|
|
|
The resulting distinction is:
|
|
|
|
```text
|
|
static
|
|
address and optional gateway are configured locally
|
|
|
|
dhcp
|
|
address and gateway are learned dynamically
|
|
|
|
none / omitted
|
|
no L3 configuration is requested
|
|
```
|
|
|
|
### 4.4 Switch interfaces
|
|
|
|
Switch ports use the same interface abstraction.
|
|
|
|
For example, a switch with a fixed set of four logical ports may be written as:
|
|
|
|
```json
|
|
{
|
|
"name": "s1",
|
|
"type": "switch",
|
|
"interfaces": {
|
|
"p1": {},
|
|
"p2": {},
|
|
"p3": {},
|
|
"uplink": {}
|
|
}
|
|
}
|
|
```
|
|
|
|
This is useful when link placement should refer to specific switch ports.
|
|
|
|
If exact port identity does not matter, the `interfaces` field may be omitted
|
|
and links may use automatic interface allocation.
|
|
|
|
### 4.5 Omitted interfaces versus an empty interface set
|
|
|
|
The distinction between these two forms is intentional.
|
|
|
|
```json
|
|
{
|
|
"name": "s1",
|
|
"type": "switch"
|
|
}
|
|
```
|
|
|
|
means:
|
|
|
|
```text
|
|
interface set omitted
|
|
-> dynamic interface set
|
|
```
|
|
|
|
while:
|
|
|
|
```json
|
|
{
|
|
"name": "s1",
|
|
"type": "switch",
|
|
"interfaces": {}
|
|
}
|
|
```
|
|
|
|
means:
|
|
|
|
```text
|
|
interface set explicitly declared
|
|
-> fixed interface set containing zero interfaces
|
|
```
|
|
|
|
This distinction is important for the semantics of `auto`.
|
|
|
|
### 4.6 Connected and unused interfaces
|
|
|
|
An interface requesting addressing, an address, a gateway, a MAC address, or an
|
|
MTU must be attached to a link.
|
|
Unused empty interface declarations may remain in a fixed interface pool.
|
|
An interface used by a service must also be attached to a link.
|
|
|
|
---
|
|
|
|
## 5. Links
|
|
|
|
A link is a first-class entity connecting exactly two endpoints.
|
|
|
|
The current structure is:
|
|
|
|
```text
|
|
Link
|
|
├── name?
|
|
├── endpoints
|
|
│ ├── endpoint A
|
|
│ │ ├── node
|
|
│ │ └── interface
|
|
│ └── endpoint B
|
|
│ ├── node
|
|
│ └── interface
|
|
└── settings
|
|
```
|
|
|
|
Keeping the `endpoints` wrapper is intentional.
|
|
|
|
A link may carry properties other than its endpoints, so flattening the link
|
|
into a raw pair would make future link-level configuration awkward.
|
|
|
|
### 5.1 Explicit interface references
|
|
|
|
An endpoint may reference an explicitly declared interface.
|
|
|
|
For example:
|
|
|
|
```json
|
|
{
|
|
"node": "r0",
|
|
"interface": "lan"
|
|
}
|
|
```
|
|
|
|
The referenced interface tag must exist on that node.
|
|
|
|
### 5.2 Automatic interface allocation
|
|
|
|
An endpoint may instead use:
|
|
|
|
```json
|
|
{
|
|
"node": "s1",
|
|
"interface": "auto"
|
|
}
|
|
```
|
|
|
|
The meaning of `auto` depends on whether the node declared an interface set.
|
|
|
|
If `interfaces` is omitted:
|
|
|
|
```text
|
|
dynamic interface set
|
|
-> auto may allocate/create interfaces as needed
|
|
```
|
|
|
|
If `interfaces` is explicitly declared:
|
|
|
|
```text
|
|
fixed interface set
|
|
-> auto selects an unused declared interface
|
|
-> auto must not silently create an additional interface
|
|
```
|
|
|
|
For example:
|
|
|
|
```json
|
|
"interfaces": {
|
|
"p1": {},
|
|
"p2": {},
|
|
"p3": {},
|
|
"uplink": {}
|
|
}
|
|
```
|
|
|
|
allows an explicit link to select:
|
|
|
|
```json
|
|
"interface": "uplink"
|
|
```
|
|
|
|
or an automatic link to select one of the remaining unused ports.
|
|
|
|
Explicit references reserve their interfaces before `auto` selections are made.
|
|
Each `auto` selection consumes the first remaining declared interface in
|
|
interface declaration order, following link and endpoint order.
|
|
If the fixed interface pool is exhausted, the topology is invalid.
|
|
|
|
### 5.3 Why interfaces remain under nodes
|
|
|
|
Interfaces remain under nodes because they may carry or receive:
|
|
|
|
- addressing configuration,
|
|
- MAC configuration,
|
|
- MTU configuration,
|
|
- service bindings,
|
|
- future interface-specific properties.
|
|
|
|
The selected relationship therefore remains:
|
|
|
|
```text
|
|
Node owns Interface
|
|
Link references Interface
|
|
```
|
|
|
|
### 5.4 Link settings
|
|
|
|
Links contain a `settings` object for provisioning properties.
|
|
|
|
The supported provisioning fields are:
|
|
|
|
```text
|
|
bandwidth_mbps?
|
|
delay_ms?
|
|
loss_percent?
|
|
jitter_ms?
|
|
```
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"endpoints": [
|
|
{
|
|
"node": "h1",
|
|
"interface": "net0"
|
|
},
|
|
{
|
|
"node": "s1",
|
|
"interface": "auto"
|
|
}
|
|
],
|
|
"settings": {
|
|
"bandwidth_mbps": 100,
|
|
"delay_ms": 1.5,
|
|
"loss_percent": 0.1
|
|
}
|
|
}
|
|
```
|
|
|
|
Bandwidth is expressed in megabits per second, delay and jitter in milliseconds,
|
|
and loss as a percentage.
|
|
|
|
The allowed ranges are:
|
|
|
|
```text
|
|
bandwidth_mbps > 0
|
|
delay_ms >= 0
|
|
jitter_ms >= 0
|
|
0 <= loss_percent <= 100
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Services
|
|
|
|
A service represents a process or daemon running on a topology node.
|
|
|
|
The generic structure is:
|
|
|
|
```text
|
|
Service
|
|
├── type
|
|
├── node
|
|
├── interface
|
|
└── settings
|
|
```
|
|
|
|
The currently supported service type is:
|
|
|
|
```text
|
|
dhcp-server
|
|
```
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"type": "dhcp-server",
|
|
"node": "r0",
|
|
"interface": "lan",
|
|
"settings": {
|
|
"range": {
|
|
"start": "192.168.1.100",
|
|
"end": "192.168.1.200"
|
|
},
|
|
"gateway": "192.168.1.1"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 6.1 Service binding
|
|
|
|
`node` and `interface` describe where the service runs and where it is bound.
|
|
|
|
They therefore remain outside `settings`.
|
|
|
|
The service interface grammar reserves:
|
|
|
|
```text
|
|
<tag>
|
|
auto
|
|
all
|
|
```
|
|
|
|
The validity and meaning of special selectors are service-type-specific.
|
|
|
|
A DHCP service accepts a specific declared interface tag.
|
|
|
|
The service also supports `auto` only when exactly one suitable statically
|
|
addressed interface can be selected unambiguously from the declared set.
|
|
|
|
The DHCP server does not support `all`.
|
|
|
|
### 6.2 DHCP settings
|
|
|
|
The current DHCP server settings are:
|
|
|
|
```text
|
|
range.start
|
|
range.end
|
|
gateway?
|
|
```
|
|
|
|
The service `gateway` is the gateway advertised to DHCP clients.
|
|
|
|
This is distinct from a static interface gateway.
|
|
|
|
```text
|
|
static interface gateway
|
|
-> locally configured default gateway
|
|
|
|
DHCP service gateway
|
|
-> gateway distributed to DHCP clients
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Grammar summary
|
|
|
|
### Node
|
|
|
|
```text
|
|
name
|
|
required unique logical node identifier
|
|
|
|
type
|
|
host | switch | router
|
|
|
|
interfaces
|
|
optional map of logical interface tags to Interface objects
|
|
|
|
settings
|
|
optional node-type-specific configuration
|
|
```
|
|
|
|
### Interface
|
|
|
|
```text
|
|
<tag>
|
|
logical interface identifier
|
|
|
|
addressing
|
|
optional: static | dhcp | none
|
|
omission is equivalent to none
|
|
|
|
address
|
|
required when addressing = static
|
|
forbidden otherwise
|
|
|
|
gateway
|
|
optional when addressing = static
|
|
forbidden otherwise
|
|
|
|
mac
|
|
optional
|
|
|
|
mtu
|
|
optional
|
|
```
|
|
|
|
### Link
|
|
|
|
```text
|
|
name
|
|
optional logical link name
|
|
|
|
endpoints
|
|
exactly two endpoints
|
|
|
|
endpoint.node
|
|
node name
|
|
|
|
endpoint.interface
|
|
declared interface tag | auto
|
|
|
|
settings.bandwidth_mbps
|
|
optional
|
|
|
|
settings.delay_ms
|
|
optional
|
|
|
|
settings.loss_percent
|
|
optional
|
|
|
|
settings.jitter_ms
|
|
optional
|
|
```
|
|
|
|
### Service
|
|
|
|
```text
|
|
type
|
|
currently dhcp-server
|
|
|
|
node
|
|
node on which the service runs
|
|
|
|
interface
|
|
interface tag | auto | all
|
|
validity depends on service type
|
|
|
|
settings
|
|
service-type-specific configuration
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Strict grammar
|
|
|
|
Unknown fields and unsupported tokens are invalid.
|
|
For example, `ip_foward` is not an alias for `ip_forward`, and `bananas` is not
|
|
an addressing mode.
|
|
|
|
Field names, value types, and closed token sets define the JSON grammar.
|
|
Cross-references and network constraints define semantic validity.
|
|
A recognized `static` addressing mode without an address is therefore a
|
|
semantic error, as is a link referring to an unknown node.
|
|
|
|
Only the fields described in this reference are currently supported.
|
|
Additional node types, services, or settings require a language extension.
|
|
|
|
---
|
|
|
|
## 9. Semantic constraints
|
|
|
|
A topology must satisfy the following constraints in addition to the JSON
|
|
grammar.
|
|
Invalid configurations include:
|
|
|
|
- duplicate node names,
|
|
- duplicate explicit link names,
|
|
- empty logical names,
|
|
- reserved interface tags,
|
|
- static interfaces without an address,
|
|
- invalid IPv4/CIDR syntax,
|
|
- invalid gateway syntax,
|
|
- gateways outside the interface subnet,
|
|
- addresses or gateways used with DHCP or no addressing,
|
|
- invalid MAC syntax,
|
|
- invalid MTU values,
|
|
- explicit link references to unknown nodes,
|
|
- explicit link references to unknown interfaces,
|
|
- explicit interface reuse across links,
|
|
- fixed interface-pool exhaustion caused by `auto`,
|
|
- invalid link provisioning ranges,
|
|
- services referencing unknown nodes,
|
|
- services referencing unknown interfaces,
|
|
- DHCP services bound to interfaces without static addressing,
|
|
- invalid DHCP IPv4 ranges,
|
|
- reversed DHCP ranges,
|
|
- DHCP range values outside the bound interface subnet,
|
|
- DHCP network or broadcast addresses,
|
|
- DHCP pools that include the server address,
|
|
- DHCP pools that include the advertised gateway.
|
|
|
|
Switch interfaces may not request Layer-3 addressing.
|
|
Only one static default gateway is supported per node.
|
|
Configured interfaces and service bindings must be connected as described in
|
|
[Connected and unused interfaces](#46-connected-and-unused-interfaces).
|
|
|