How to bridge enp0s3 with a peer of veth?

1

0

My Lap: Ubuntu 15.10. And I have a wired NIC enp0s3. I want to create a veth pair veth0 and veth1 and bridge them with enp0s3, and set veth1 to a new netns ns1, so that processes in ns1 can access the Internet through link layer.

But it's strange that veth1 can't ping enp0s3. The following is my steps.

root@qs-vs:~# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:62:3c:59 brd ff:ff:ff:ff:ff:ff
root@qs-vs:~# ip netns add ns1
root@qs-vs:~# ip link add type veth
root@qs-vs:~# ip link set veth1 netns ns1
root@qs-vs:~# ip link add bridge type bridge
root@qs-vs:~# ip link set enp0s3 master bridge
root@qs-vs:~# ip link set veth0 master bridge
root@qs-vs:~# ip link set up veth0
root@qs-vs:~# ip link set up enp0s3
root@qs-vs:~# ip link set up bridge
root@qs-vs:~# ip netns exec ns1 ip link set up veth1
root@qs-vs:~# ip addr add 192.168.222.1/24 dev enp0s3
root@qs-vs:~# ip netns exec ns1 ip addr add 192.168.222.101/24 dev veth1
root@qs-vs:~# ping 192.168.222.101
PING 192.168.222.101 (192.168.222.101) 56(84) bytes of data.
From 192.168.222.1 icmp_seq=1 Destination Host Unreachable
From 192.168.222.1 icmp_seq=2 Destination Host Unreachable
From 192.168.222.1 icmp_seq=3 Destination Host Unreachable
From 192.168.222.1 icmp_seq=4 Destination Host Unreachable
From 192.168.222.1 icmp_seq=5 Destination Host Unreachable
From 192.168.222.1 icmp_seq=6 Destination Host Unreachable
^C
--- 192.168.222.101 ping statistics ---
7 packets transmitted, 0 received, +6 errors, 100% packet loss, time 6028ms
pipe 3

I have also tried turn on promisc with enp0s3, but it doesn't help.

TorosFanny

Posted 2016-01-11T11:45:28.143

Reputation: 217

once an interface becomes a bridge port, IP on it is ignored. so ip link set enp0s3 master bridge and ip addr add 192.168.222.1/24 dev enp0s3 are incompatible – A.B – 2019-03-21T21:47:31.107

Answers

1

There are two mistakes in the above. First, by bridging the veth IF with enp0s3, you will be sending the pings outside your pc, while your intention is to communicate with another part of your own pc. Second, the syntax of the command establishing the veth interface is wrong.

You should bridge the veth interface with another virtual interface, tap0; then you will see your pings coming back. Try it as follows:

    NNS=WhateverYouWantToCallTheNewNetworkNameSpace
    ip netns add $NNS
    ip link add veth-a$NNS type veth peer name veth-b$NNS
    ip link set veth-a$NNS up
    ip tuntap add tap$NNS mode tap user root
    ip link set tap$NNS up
    ip link add br$NNS type bridge
    ip link set tap$NNS master br$NNS
    ip link set veth-a$NNS master br$NNS
    ip addr add 10.0.0.1/24 dev br$NNS
    ip link set br$NNS up
    ip link set veth-b$NNS netns $NNS
    ip netns exec $NNS ip addr add 10.0.0.2/24 dev veth-b$NNS
    ip netns exec $NNS ip link set veth-b$NNS up
    ip netns exec $NNS ip link set dev lo up

I have added the lo interface only because you will find it useful in the future. Now you can ping,

    ping -c1 10.0.0.2

and you will see the pings coming back.

EDIT:

how I can access the Internet throw veth-b$NNS and the veth-b$NNS's MAC have to be visible to my ISP

There is no way to expose the two veth's to your ISP. Still, the following ought to work just fine:

  1. The following, for some reason I do not understand, must be done before all of the previous commands:

    NNS=WhateverYouWantToCallTheNewNetworkNameSpace
    /bin/mkdir -p /etc/netns/$NNS
    echo "nameserver 8.8.8.8" > /etc/netns/$NNS/resolv.conf
    echo "nameserver 8.8.4.4" >> /etc/netns/$NNS/resolv.conf
    

This will give you DNS resolution. But remember, this must be done before the commands above!

  1. On your host, allow IPv4 forwarding and MASQUERADING:

    echo 1 > /proc/sys/net/ipv4/ip_forward 
    iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
    
  2. Add a gateway to your new network namespace:

    ip netns exec $NNS ip route add default via 10.0.0.1
    
  3. Now enter your new network namespace, I do it by creating an xterm and then typing within it commands which are necessarily in the new NNS:

    ip netns exec $NNS su -c xterm YourName &
    

If you do not like xterm's, you can use whatever kind of terminals you like (if you do not have an xterm, just install it, apt-get install xterm).

This should work.

MariusMatutiae

Posted 2016-01-11T11:45:28.143

Reputation: 41 321

Thank you for wonderful reply. It works and you teached me useful tips. – TorosFanny – 2016-01-11T12:19:24.647

@TorosFanny You're welcome!! – MariusMatutiae – 2016-01-11T12:23:21.243

I don't know much about ip tuntap, but could you tell how I can access the Internet throw veth-b$NNS and the veth-b$NNS's MAC have to be visible to my ISP. – TorosFanny – 2016-01-11T12:54:42.173

@TorosFanny Pls read my Edit. – MariusMatutiae – 2016-01-11T13:15:05.313

Maybe, I haven't express my needs clearly. I have to expose an NIC in a namespace to my ISP's gateway. – TorosFanny – 2016-01-11T13:26:08.340

@TorosFanny I told you that cannot be done with network namespaces. If you tell me what you want to achieve, (after all, you are connected to the Internet already, so why another interface? What is that for?), I might be able to help. – MariusMatutiae – 2016-01-11T13:34:47.333

@TorosFanny Ok, you can do that with proxy-arp. You shuld ask a different question, so that others may benefit from it. – MariusMatutiae – 2016-01-11T13:49:17.567

We fellow students have to use a client to gain access to the Internet. The client has many restrictions. It needs your account to login and you have to expose your NIC's MAC to the ISP's gateway and then get an IP. Each account has a limit on bandwidth. I want to make a server which has many accounts logging, so we can share our bandwidth. The key step is to run several clients in their corresponding network namespaces, so I have to expose a link layer address for each namespace. You said using veth is not possible, so maybe macvlan could help. – TorosFanny – 2016-01-11T13:49:34.587

@TorosFanny macvlan is one of the ways to do this. But please ask a new question. – MariusMatutiae – 2016-01-11T13:59:26.997

Yes, I'm writing. – TorosFanny – 2016-01-11T14:00:34.323

-1

ip netns add mynetns
ip netns exec mynetns ip link list
ip netns exec mynetns ip link set dev lo up
#  ip netns exec mynetns ping 127.0.0.1
ip link add veth0 type veth peer name veth1
ip link set veth1 netns mynetns
ip netns exec mynetns ifconfig veth1 10.1.1.1/24 up
ifconfig veth0 10.1.1.2/24 up
#ping 10.1.1.1
#ip netns exec mynetns ping 10.1.1.2

ip netns exec mynetns route
ip netns exec mynetns iptables -L

ip netns exec mynetns bash

user606000

Posted 2016-01-11T11:45:28.143

Reputation: 1

Maybe it is right, maybe it works, I don't know. I down-voted because: (1) the answer is a raw block of code without explanation what it does; (2) there is no explanation how and why this solution is different or better than the one from the other answer. – Kamil Maciorowski – 2016-06-27T06:19:09.037