Skip to content

Commit f7aeef3

Browse files
committed
adds docs for some networking basics
Signed-off-by: Ashraf Fouda <ashraf.m.fouda@gmail.com>
1 parent 7f9dcab commit f7aeef3

17 files changed

Lines changed: 256 additions & 0 deletions
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
# Basic Networking
2+
3+
In this part we will go through some of basic Networking Concepts that is very related to how networking in zos working
4+
5+
## Components
6+
7+
- [Namespaces](<https://en.wikipedia.org/wiki/Linux_namespaces#Network_(net)>): As you may know linux have the concept of Namespaces which includes (users, net, ....) namespaces. which is basically considered as a full copy of the network stack that is fully isolated from the network stack of the machine
8+
- [Bridge](https://wiki.archlinux.org/title/network_bridge): A network bridge is a virtual network device that forwards packets between two or more network segments. A bridge behaves like a virtual network switch and works transparently.
9+
- veth: Virtual Ethernet (veth) pairs act like a cable connecting two endpoints.
10+
11+
## What we are going to achieve in this doc
12+
13+
We aim to create three network namespaces and establish connectivity between them using bridges and routing rules. Bridges operate at Layer 2, so they only broadcast packets to connected nodes without routing.
14+
15+
- the file setup will looks like
16+
![](image-5.png)
17+
18+
## Steps
19+
20+
### Creating the three namespaces
21+
22+
```
23+
sudo ip netns add lan1
24+
sudo ip netns add lan0
25+
sudo ip netns add lan2
26+
```
27+
28+
for more info about `ip netns` check [this](https://man7.org/linux/man-pages/man8/ip-netns.8.html)
29+
so far we have this
30+
![](image-11.png)
31+
![](fig1.png)
32+
33+
### Executing ip command for a specific namespace
34+
35+
- if you did `ip a` command it will print the host interfaces, but will not print anything from any namespace
36+
- for example to execute `ip a` inside the lan0 namespace you need to do the following
37+
38+
```
39+
ip -n lan0 a
40+
```
41+
42+
- this will print the interfaces inside lan0 which now have only `lo` interface
43+
![interfaces](interfaces.png)
44+
- note that the first `ip a` command shows interfaces from the host, while the second one shows the interfaces inside the namespace. so the `lo` in the first command is not the same `lo` from the second command
45+
- to get a shell inside the namespace so we can execute commands directly inside the namespace without the need to specify the `-n lan0` each time we can do
46+
47+
```
48+
sudo ip netns exec lan0 bash
49+
```
50+
51+
- from the second command we see `lo` device is `DOWN` so to bring it up we do this inside lan0 namespace shell
52+
53+
```
54+
ip l set lo up
55+
```
56+
57+
### Creating the bridges
58+
59+
do this in the host shell
60+
61+
```
62+
sudo ip l add br01 type bridge
63+
sudo ip l add br02 type bridge
64+
```
65+
66+
so far we have this
67+
![](fig2.png)
68+
69+
to view the created bridges do `ip l` or `brctl show`
70+
![bridges](bridges.png)
71+
72+
from the above image you can see we have created the bridges but till now we don't have any attached interfaces
73+
74+
### Connecting the wires
75+
76+
- so far we have 3 namespaces and two bridges let's connect the wires between them
77+
- creating veth from `lan1` ns to `br01` bridge
78+
- Connecting a veth between br01 and lan1
79+
80+
```
81+
sudo ip l add lan1 type veth peer name lan1br
82+
```
83+
84+
here if we executer `ip a` we will see something like the following
85+
![](image.png)
86+
87+
the last two items shows we have link `16` and `17` those are the two ends of the veth that we created so lan1br1 <-> lan1
88+
89+
```
90+
16: lan1br@lan1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop master br01 state DOWN group default qlen 1000
91+
link/ether 46:13:d2:d2:b8:95 brd ff:ff:ff:ff:ff:ff
92+
17: lan1@lan1br: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
93+
link/ether 2e:de:7d:76:47:61 brd ff:ff:ff:ff:ff:ff
94+
```
95+
96+
the above command creates veth (link/cable) which have two ends one called `lan1` which we will connect later to `lan1` ns and the other end is `lan1br` which we will connect it later to the bridge `br01`
97+
98+
- connect `lan1br` end to the bridge
99+
100+
```
101+
sudo ip l set lan1br master br01
102+
```
103+
104+
- connect `lan1` end of the veth to `lan1` ns (basically move this end to lan1 ns)
105+
106+
```
107+
ip l set lan1 netns lan1
108+
```
109+
110+
here we if exec `ip a` will find that lan1 end has been moved out of the host interfaces to the lan1 namespace and to see it exec `ip -n lan1 a`
111+
![](image-1.png)
112+
113+
- note that the other end of lan1br is changed to if17 because lan1 is now in a different namesapce we can no longer reference it as lan1 otherwise it is referenced by `if17` which is a unique id generated by the kernel for lan1 also
114+
- also note that the other end of lan1 link in lan1 namespace is if16 which is lan1br but as long as it is not in the same namespace we can not reference it by this name so the unique id is used here
115+
- connecting another veth between br01 and lan0 same as above
116+
117+
```
118+
sudo ip l add lan0 type veth peer name lan0br
119+
sudo ip l set lan0br master br01
120+
sudo ip l set lan0 netns lan0
121+
```
122+
123+
- so far we have done this
124+
125+
![](image-3.png)
126+
127+
- and here is how it looks like if we did `ip a` in each namespace
128+
129+
![](image-2.png)
130+
131+
- as you can see everything now is in `DOWN` state let's turn on all of this
132+
133+
```
134+
sudo ip -n lan0 l set lan0 up # the end in the namespace
135+
sudo ip -n lan0 a a 10.10.1.1/24 dev lan0 # assign ip
136+
sudo ip l set lan0br up # the end in the bridge
137+
sudo ip -n lan1 l set lan1 up # lan1 ifc in lan1 namespace
138+
sudo ip -n lan1 a a 10.10.1.2/24 dev lan1
139+
sudo ip l set lan1br up
140+
sudo ip l set br01 up # the bridge
141+
```
142+
143+
lets have a look on the routing table in the name space for example lan1
144+
145+
```
146+
sudo ip -n lan1 r
147+
```
148+
149+
![](image-4.png)
150+
151+
here we will find a route rule automatically added which says any packet that needs to be sent to any ip with `10.10.1.0/24` will go through `lan1` interface and this happened because we assigned it an ip in that range
152+
note:- till now we can not route any packets out side that range, we don't have a default gw yet
153+
154+
- now lets do the same for connecting br01 with lan0 and lan2
155+
156+
```
157+
sudo ip l add lan2 type veth peer name lan2br
158+
sudo ip l add lan02 type veth peer name lan02br
159+
sudo ip l set lan2br master br02
160+
sudo ip l set lan2 netns lan2
161+
162+
sudo ip l set lan02br master br02
163+
sudo ip l set lan02 netns lan0
164+
165+
sudo ip l set lan02br up
166+
sudo ip l set lan2br up
167+
sudo ip l set br02 up
168+
sudo ip -n lan0 l set lan02 up
169+
sudo ip -n lan2 l set lan2 up
170+
171+
# assign ip for lan02 in lan0 namespace
172+
sudo ip -n lan0 a a 10.10.2.1/24 dev lan02
173+
sudo ip -n lan2 a a 10.10.2.2/24 dev lan2
174+
```
175+
176+
#### so far we have this
177+
178+
![](image-5.png)
179+
180+
this means from lan0 ns I can reach lan1 ns and lan2, but till now we can not reach lan1 from lan2, because we only now have the bridges without any special routing rules (default gw is not set yet). so the bridge now is broadcasting the packets on all directly connected devices and the node that this data is for will pick it
181+
182+
### Testing connectivity
183+
184+
if the following ping examples didn't work for you, this maybe a firewall issue try doing this
185+
186+
```
187+
sudo iptables --policy FORWARD ACCEPT
188+
sudo ip netns exec lan0 echo 1 > /proc/sys/net/ipv4/ip_forward # enable ip forwarding
189+
```
190+
191+
- ping lan1 ns from lan0
192+
193+
![](image-7.png)
194+
195+
- ping lan0 from lan2
196+
197+
![](image-6.png)
198+
199+
- ping lan2 from lan1 (will not work)
200+
201+
![](image-8.png)
202+
203+
### Establishing connectivity between lan1 and lan2
204+
205+
- Adding a rule to lan1 ns to route to lan2
206+
207+
```
208+
sudo ip -n lan1 r a 10.10.2.0/24 via 10.10.1.1
209+
```
210+
211+
- this means if lan1 namespace wants to send any packets to 10.10.2.0/24 range we direct it to `lan0` ns and lan0 namespace is directly connected to lan2
212+
213+
- Note: ping lan2 from lan1 still not working but now we have a different error message `Destination host unreachable` and you will find it already tried to send the ping request many times instead of the previous error `Network is unreachable` because this time we know we should go through lan1 but we don't guarantee the packet will reach the other end
214+
- Configuring the other way around
215+
216+
so far we taught the packet how to go from lan1 to lan2 but we didn't configure the other way from lan2 to lan1 to get a response
217+
218+
```
219+
sudo ip -n lan2 r a 10.10.1.0/24 via 10.10.2.1
220+
```
221+
222+
now we have all connected. so we can ping lan1 from lan2 and lan2 from lan1
223+
224+
### NATting
225+
226+
if we did inspect to the packets sent during ping. lets say for example we are doing ping from lan1 to lan2 and we did `tcpdump` on lan2 namespace
227+
228+
```
229+
sudo ip netns exec lan1 ping 10.10.2.2 # ping lan2 from lan1
230+
```
231+
232+
![](image-9.png)
233+
234+
- Here we see the requests are coming from 10.10.1.2 while in our case we deal with lan0 as a router so in lan0 we can add natting rules so the requests are sent to lan2 as if it is from lan0 without lan2 knows lan1 is the one who is sending the request.
235+
236+
- In this case lan0 will change the source MAC and IP to it's interface ip which is 10.10.2.1 and sent to lan2 and lan2 will reply to lan0 then lan0 will forward the reply to lan1
237+
238+
```
239+
sudo ip netns exec lan0 nft add table nat
240+
sudo ip netns exec lan0 nft 'add chain nat postrouting { type nat hook postrouting priority 100 ; }'
241+
sudo ip netns exec lan0 nft add rule nat postrouting masquerade
242+
```
243+
244+
now lan0 works as a router
245+
![](image-10.png)
246+
247+
we can now remove the routing rules that we created before and only create a default gw rule in lan1 and lan2
248+
249+
```
250+
# remove old routing rules
251+
sudo ip -n lan1 r d 10.10.2.0/24
252+
sudo ip -n lan2 r d 10.10.1.0/24
253+
# create default gw
254+
sudo ip -n lan1 route add default via 10.10.1.1 dev lan1
255+
sudo ip -n lan2 route add default via 10.10.2.1 dev lan2
256+
```
93.9 KB
Loading
40.9 KB
Loading
59.2 KB
Loading
137 KB
Loading
81.2 KB
Loading
9.65 KB
Loading
106 KB
Loading
36.4 KB
Loading
48 KB
Loading

0 commit comments

Comments
 (0)