1

I have an ARM embedded system with kernel 4.9.62 that has two physical interfaces as shown below:

                                                      ________
                              +------------+         /
                              |            |        |
       +----------------------+ Subnet   1 +--------|
       |10.0.0.180            |10.0.0.1    |       /
+------+-------+              +------------+      |
|    eth0      |                                  /
|              |                                  |
|   Host       |                                  |     Internet
|              |                                  |
|    wlan0     |                                  \
+------+-------+              +------------+       |
       |10.0.10.250           |            |       \
       +----------------------+ Subnet 2   +-------|
                              |10.0.10.1   |       |
                              +------------+       \________

>ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether 00:20:c4:04:c2:03 brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT group default qlen 1000
    link/ether 74:da:38:d3:3e:4e brd ff:ff:ff:ff:ff:ff 

>ip route
default via 10.0.0.1 dev eth0
default via 10.0.10.1 dev wlan0  metric 2
10.0.0.0/24 dev eth0  proto kernel  scope link  src 10.0.0.180
10.0.10.0/24 dev wlan0  proto kernel  scope link  src 10.0.10.250

What I'm trying to do is add two network namespaces so that I can run network tests targeted out either of the two interfaces. So what I'd like the result to be is:

>ping google.com
PING google.com (172.217.4.46): 56 data bytes
64 bytes from 172.217.4.46: seq=0 ttl=56 time=53.575 ms

>ip netns exec eth_ns ping google.com
PING google.com (172.217.4.46): 56 data bytes
64 bytes from 172.217.4.46: seq=0 ttl=55 time=53.496 ms

>ip netns exec wlan_ns ping google.com
PING google.com (172.217.4.110): 56 data bytes
64 bytes from 172.217.4.110: seq=0 ttl=55 time=56.443 ms

Currently what I've tried is the following script to setup two network namespaces and each namespace with one end of a veth pair while the other end of the veth pair is nat'd to the appropriate physical interface:

# ############################################
# Create the ethernet namespace
ip netns add eth_ns

# Create veth link.
ip link add v-eth1 type veth peer name v-peer1

# Add peer-1 to NS.
ip link set v-peer1 netns eth_ns

# Setup IP address of v-eth1.
ip addr add 10.200.1.1/24 dev v-eth1
ip link set v-eth1 up

# Setup IP address of v-peer1.
ip netns exec eth_ns ip addr add 10.200.1.2/24 dev v-peer1
ip netns exec eth_ns ip link set v-peer1 up
ip netns exec eth_ns ip link set lo up
ip netns exec eth_ns ip route add default via 10.200.1.1


# ############################################
# Create the wlan namespace
ip netns add wlan_ns

# Create veth link.
ip link add v-wlan1 type veth peer name v-peer2

# Add peer-2 to NS.
ip link set v-peer2 netns wlan_ns

# Setup IP address of v-wlan1.
ip addr add 10.200.2.1/24 dev v-wlan1
ip link set v-wlan1 up

# Setup IP address of v-peer2.
ip netns exec wlan_ns ip addr add 10.200.2.2/24 dev v-peer2
ip netns exec wlan_ns ip link set v-peer2 up
ip netns exec wlan_ns ip link set lo up
ip netns exec wlan_ns ip route add default via 10.200.2.1


# ############################################
# Share internet access between host and NS.

# Enable IP-forwarding.
echo 1 > /proc/sys/net/ipv4/ip_forward

# Flush forward rules, policy DROP by default. Flush nat rules.
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -t nat -F


# ############################################
# Enable masquerading of 10.200.1.0.
iptables -t nat -A POSTROUTING -s 10.200.1.0/255.255.255.0 -o eth0 -j MASQUERADE
# Allow forwarding between eth0 and v-eth1.
iptables -A FORWARD -i eth0 -o v-eth1 -j ACCEPT
iptables -A FORWARD -o eth0 -i v-eth1 -j ACCEPT


# ############################################
# Enable masquerading of 10.200.2.0.
iptables -t nat -A POSTROUTING -s 10.200.2.0/255.255.255.0 -o wlan0 -j MASQUERADE
# Allow forwarding between wlan0 and v-wlan1.
iptables -A FORWARD -i wlan0 -o v-wlan1 -j ACCEPT
iptables -A FORWARD -o wlan0 -i v-wlan1 -j ACCEPT

The result is that the following first two commands work as expected, while the third fails:

>ping google.com
PING google.com (172.217.4.46): 56 data bytes
64 bytes from 172.217.4.46: seq=0 ttl=56 time=53.575 ms
64 bytes from 172.217.4.46: seq=1 ttl=56 time=53.751 ms
64 bytes from 172.217.4.46: seq=2 ttl=56 time=52.709 ms

>ip netns exec eth_ns ping google.com
PING google.com (172.217.4.46): 56 data bytes
64 bytes from 172.217.4.46: seq=0 ttl=55 time=53.496 ms
64 bytes from 172.217.4.46: seq=1 ttl=55 time=52.967 ms
64 bytes from 172.217.4.46: seq=2 ttl=55 time=53.038 ms

>ip netns exec wlan_ns ping google.com
ping: bad address 'google.com'

I can ping the default router from wlan_ns:

>ip netns exec wlan_ns ping 10.0.10.1
PING 10.0.10.1 (10.0.10.1): 56 data bytes
64 bytes from 10.0.10.1: seq=0 ttl=63 time=5.232 ms

But nothing that needs routed works via wlan_ns. I'm sure this is an issue with my two default routes as I can delete the 10.0.0.1 default route and then wlan_ns works.

So how do I configure the routing tables or iptables to make both eth_ns and wlan_ns work at the same time?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.