5

My attempt is modeled on the this tutorial.

I am able to ping from the namespace to the network if the physical interface is not assigned to the bridge.

# Create namespace
ip netns add namespace1

# Create veth pair.
ip link add veth1 type veth peer name br-veth1

# Associate the non `br-` side with the namespace.
ip link set veth1 netns namespace1

# Give namespace-side veth ip addresses.
ip netns exec namespace1 ip addr add 192.168.1.11/24 dev veth1

# Create a bridge device naming it `br1` and set it up.
ip link add name br1 type bridge

# Turn up the bridge.
ip link set br1 up

# Set the bridge veth from the default namespace up.
ip link set br-veth1 up

# Set the veth from the namespace up too.
ip netns exec namespace1 ip link set veth1 up

# Add the br-veth1 interface to the bridge by setting the bridge device as their master.
ip link set br-veth1 master br1

# Add the physical interface to the bridge
ip link set enp3s0 master br1

# Set the address of the `br1` interface (bridge device) to 192.168.1.10/24 and also set the broadcast address to 192.168.1.255 (the `+` symbol sets  the host bits to 255).
ip addr add 192.168.1.10/24 brd + dev br1

# add the default gateway in all the network namespace.
ip netns exec namespace1 ip route add default via 192.168.1.10

# Set us up to have responses from the network.
# -t specifies the table to which the commands should be directed to. By default, it's `filter`.
# -A specifies that we're appending a rule to the chain that we tell the name after it.
# -s specifies a source address (with a mask in this case).
# -j specifies the target to jump to (what action to take).
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE
sysctl -w net.ipv4.ip_forward=1
rur2641
  • 399

2 Answers2

6

Don't use veth + bridge! Use macvlan!

I was struggling with veth + bridge recently like you, fortunately I found this link tonight, which says:

Before MACVLAN, if you wanted to connect to physical network from a VM or namespace, you would have needed to create TAP/VETH devices and attach one side to a bridge and attach a physical interface to the bridge on the host at the same time, as shown below.

Now, with MACVLAN, you can bind a physical interface that is associated with a MACVLAN directly to namespaces, without the need for a bridge.

And this is what I did:

$ sudo ip netns add ns0
$ sudo ip netns exec ns0 ip link set lo up
$ sudo ip link add macvlan0 link eth0 type macvlan mode bridge
$ sudo ip link set macvlan0 netns ns0
$ sudo ip netns exec ns0 ip link set macvlan0 up
$ sudo ip netns exec ns0 ip addr add 172.29.6.123/21 dev macvlan0
$ sudo ip netns exec ns0 ping 172.29.0.1
PING 172.29.0.1 (172.29.0.1) 56(84) bytes of data.
64 bytes from 172.29.0.1: icmp_seq=1 ttl=64 time=0.360 ms
64 bytes from 172.29.0.1: icmp_seq=2 ttl=64 time=0.412 ms

It is working!

Yun Wu
  • 61
  • 2
    For reference, macvlan, macvtap, ipvlan and ipvtap only work on physical interfaces. They won't work on, eg, a tunnel device created by a VPN client. – i336_ Oct 08 '20 at 11:24
  • I don't understand how the routing works. – bomben Feb 11 '21 at 13:02
3

Everything looks good until the last two commands (default gateway in the network namespace + masquerading in the main namespace).

If you skip those two, you should have a configuration where the physical interface is bridged to two internal interfaces, one the internal 192.168.1.10 of the bridge in the main namespace and one the 192.168.1.11 in namespace1.

So this acts in the same way as having two physical network interfaces connected to the same subnet, one from the main namespace and one from namespace. (You can achieve the same effect with a macvlan instead of an veth-pair).

Neither forwarding nor masquerading is necessary, and a default route onto 192.168.1.10 from the main namespace is just wrong.

If the routes are correct for both namespaces (verify that), you should be able to ping the other interface, and also whatever is connected to the physical interface.

For testing, I recommend starting an xterm etc. in namespace1; then you can directly configure everything with having to type ip netns exec namespace1 ip ... all the time.

dirkt
  • 32,309
  • after running the script without the last 2 commands, the interface can no longer ping the same addresses it could before the script: the error "Network is unreachable" is returned. Attempting to ping from the new namespace has no response. Wireshark shows that there is still traffic on the interface. Running ip link show shows that the link is up. Without running the script unplugging and re-plugging a cable to the device causes the interface to be assigned an address which is verified with ifconfig. – rur2641 Jun 11 '19 at 13:50
  • After running the script, the interface retains its address, but if unplugged, it will not re-acquire an address – rur2641 Jun 11 '19 at 13:51
  • The address of the interface before the script is 192.168.65.107. Is it correct if I give 192.168.65.11/24 as an address of the namespace-side veth, 92.168.65.10/24 brd + for he bridge and 192.168.65.10 as a deault gateway for the new interface? – rur2641 Jun 11 '19 at 13:55
  • I don't know enough about the rest of your network to say anything about valid IP addresses. Assuming it's a home router and all devices receive addresses via DHCP, either pick two static addresses outside of the range assigned by DHCP, or run dhclient both in the main namespace and in the new namespace. You can also give br1 the same address that was on enp3s0. You may need to disable system programs that want to interfere, like network manager. (Alternatively, use a macvlan instead of a bridge). As for "can no longer ping", check routes, addresses and everything, as I wrote. – dirkt Jun 11 '19 at 14:13
  • Both the bridge interface and the veth endpoint inside the namespace are simple bridged, so given correct addresses and routes, they should ping just fine. Use ip addr, ip route, and ip route get 192.168.... to verify. – dirkt Jun 11 '19 at 14:14
  • To get my setup working I add to change the default gateway in the network namespace from the IP of the bridge 'br1' to the same same default gateway used by the physical interface. I didn't skip it. Then everything worked like magic (with no need for masquerading as commented in the answer) – Dzseti Oct 16 '23 at 19:51