]> ruderich.org/simon Gitweb - linux-network-namespace-labs/linux-network-namespace-labs.git/blob - README.adoc
a3bc4581aea8baa505aceac823816aac169decf0
[linux-network-namespace-labs/linux-network-namespace-labs.git] / README.adoc
1 = README
2
3 linux-network-namespace-labs is a small program to create networking lab
4 setups based on Linux network namespaces in a simple manner. It provides a
5 quick way to setup labs using a text file describing the architecture
6 (networks, nodes, links, commands). This is much simpler than running each
7 node in a separate virtual machine or manually allocating the IP addresses for
8 each node. It is licensed under GPLv3+.
9
10
11 == Requirements
12
13 === Build
14
15 - Go, no external dependencies
16
17 === Run
18
19 - Linux compiled with `CONFIG_NET_NS` (available on most modern systems)
20 - iproute2 (`ip`)
21
22
23 == Build
24
25     $ go build
26
27 Then copy the binary `linux-network-namespace-labs` to somewhere in your
28 `$PATH`.
29
30
31 == Usage
32
33 The following configuration from `examples/readme/` setups a lab with three
34 nodes (routers) and configures static routes.
35
36 ----
37 # Network range for loopback addresses of the nodes
38 net loops 192.0.2.0/24 3fff::/20
39 # Network range for interfaces between nodes
40 net addrs 198.51.100.0/24 2001:db8::/32
41
42 # Setup three nodes (routers) and assign IPv4 and IPv6 loopback addresses
43 node r1 loops
44 node r2 loops
45 node r3 loops
46
47 # Links between routers: /31 or /127 is used for each interface
48 link r1 r2 addrs
49 link r2 r3 addrs
50
51 # Commands to run on each node; $1 is the node name (= name of network
52 # namespace). Here it's used to setup static routes but can also be used to
53 # start routing daemons like bird.
54 cmd ./setup.sh $1
55 ----
56
57 Then setup the lab by running (as root):
58
59     # cd examples/readme
60     # linux-network-namespace-labs up lab.conf
61     [...]
62
63 Now you can enter the network namespace of each router and test a simple
64 traceroute:
65
66     # ip netns exec r1 sh
67     # ip -br a
68     lo               UNKNOWN        127.0.0.1/8 ::1/128
69     lo2              UNKNOWN        192.0.2.0/32 3fff::/128 fe80::438:67ff:fe0a:4e58/64
70     r2@if287         UP             198.51.100.0/31 2001:db8::/127 fe80::a896:cdff:fe58:5c23/64
71     # traceroute 192.0.2.2
72     traceroute to 192.0.2.2 (192.0.2.2), 30 hops max, 60 byte packets
73      1  r2 (198.51.100.1)  0.937 ms  0.818 ms  0.768 ms
74      2  r3-loop (192.0.2.2)  0.722 ms  0.650 ms  0.603 ms
75
76 Use `exit` to leave the network namespace.
77
78 `/etc/hosts` of each node (via `/etc/netns/<ns>/hosts`) is automatically
79 filled with all known addresses so you can use hostnames as well:
80
81     # ping -c1 r3-loop
82     PING r3-loop(r3-loop (3fff::2)) 56 data bytes
83     64 bytes from r3-loop (3fff::2): icmp_seq=1 ttl=63 time=0.266 ms
84     --- r3-loop ping statistics ---
85     1 packets transmitted, 1 received, 0% packet loss, time 0ms
86     rtt min/avg/max/mdev = 0.266/0.266/0.266/0.000 ms
87
88 When you change the configuration you can simply rerun "up" and it will remove
89 the lab (and killing all processes inside it) before starting it up again:
90
91     # linux-network-namespace-labs up lab.conf
92     [...]
93
94 When you're done you can remove the lab with:
95
96     # linux-network-namespace-labs down lab.conf
97     [...]
98
99 To get an overview of the network you can create a
100 https://en.wikipedia.org/wiki/DOT_(graph_description_language)[DOT] file:
101
102     $ linux-network-namespace-labs dot lab.conf lab.dot
103     $ dot -Tpng lab.dot > lab.png
104
105 image::examples/readme/lab.png[DOT style diagram of network nodes and links]
106
107
108 == Examples
109
110 Have a look at `examples/` for some examples which also include running
111 https://bird.network.cz/[Bird] on each node and spawning a Podman container
112 inside the created nodes running https://frrouting.org/[FRR].
113
114
115 == Syntax of configuration file
116
117 One option per line, empty lines are permitted as well as comments at the
118 beginning of the line with `#`.
119
120 The config files is parsed from top to bottom and the options "net", "node",
121 "link" must be given in this order. "cmd" can be put anywhere (but is only
122 executed at the end).
123
124 === Option "net"
125
126     "net" <name> <prefix>...
127
128 "net" creates a new prefix which is used to allocate addresses for loopback
129 and link interfaces. Multiple IPv4 and IPv6 prefixes can be specified. When
130 the network is used one address of each prefix is assigned to the interface.
131 "net"s used for loopback interfaces must be separate from "net"s used for link
132 interfaces.
133
134 === Option "node"
135
136     "node" <name> [<loopback-net-name>...]
137
138 "node" creates a new node (router) and (if specified) assigns loopback
139 addresses from the given networks. The loopback addresses are assigned to a
140 new interface "lo2".
141
142 === Option "link"
143
144     "link" <node> <node> <net-name>|"-" ["l3"]
145
146 "link" creates links between nodes. The IP addresses are taken from the given
147 network name. /31 is used for IPv4- and /127 for IPv6-prefixes. If "-" is used
148 as net-name then no addresses are assigned (useful for unnumbered links). The
149 MAC address is not static and allocated by the kernel. The link is named after
150 the node "on the other side". Multiple links can be created between two nodes.
151 In this case "_2", "_3", etc. is appended to the interface name. By default
152 veth interfaces are used, adding "l3" changes this to netkit which provide a
153 layer-3 connection without needing ARP (requires kernel 6.7, iproute2 6.8).
154
155 === Option "cmd"
156
157     "cmd" <string-passed-to-sh-c>
158
159 "cmd" runs the given command (by passing it as is to `sh -c`) on each node.
160 The first argument is the name of the node (which is also the name of the
161 network namespace). This can be used to run setup commands or routing daemons
162 on the nodes.
163
164 If "cmd" is not flexible enough you can simply use `ip netns exec` to manually
165 run commands on specific nodes.
166
167
168 == Authors
169
170 Written by Simon Ruderich <simon@ruderich.org>.
171
172 Please report bugs, feature requests and patches via email.
173
174
175 == License
176
177 This program is licensed under GPL version 3 or later.
178
179 Copyright (C) 2024  Simon Ruderich
180
181 This program is free software: you can redistribute it and/or modify
182 it under the terms of the GNU General Public License as published by
183 the Free Software Foundation, either version 3 of the License, or
184 (at your option) any later version.
185
186 This program is distributed in the hope that it will be useful,
187 but WITHOUT ANY WARRANTY; without even the implied warranty of
188 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
189 GNU General Public License for more details.
190
191 You should have received a copy of the GNU General Public License
192 along with this program.  If not, see <https://www.gnu.org/licenses/>.