Unix & Linux Stack Exchange
Q&A for users of Linux, FreeBSD and other Unix-like operating systems
Latest Questions
0
votes
0
answers
24
views
Linux bridge forwarding from/to TAP interfaces
As explained [here][1] in my own Q&A, reconsider the following scenario. A Linux host with a two port Linux `bridge` and two Linux guest `VMs` connected to it: the first bridge's port is connected to `TAP` interface `tap0` while the second to `tap1`. `tap0` and `tap1` are backend `TAP` interfaces as...
As explained here in my own Q&A, reconsider the following scenario.
A Linux host with a two port Linux
bridge
and two Linux guest VMs
connected to it: the first bridge's port is connected to TAP
interface tap0
while the second to tap1
. tap0
and tap1
are backend TAP
interfaces associated to virtio-net
(frontend) interfaces each exposed to a QEMU
based VM
(lets say VM0
and VM1
).
As far as I can tell, when VM0
sends a frame/packet targeted to VM1
, VM0
QEMU
process's userland code calls write()
syscall on the fd
virtio-net
interface is associated to. From tap0
driver-code viewpoint, the RX
path is involved (basically tap0
is receiving a packet/frame from its "logical wires"), hence for instance the kernel netif_receive_skb()
function is executed in the context of VM0
QEMU
's process.
Furthermore the packet/frame is forwarded from the Linux bridge to the tap1
interface hence, from tap1
driver-code viewpoint, the TX
path is involved (basically tap1
is transmitting a packet/frame on its "logical wires"), hence for instance the kernel net_dev_xmit()
function is executed/run in the context of VM0
QEMU
's process as well.
Does it makes sense ? Thanks.
CarloC
(385 rep)
Jul 11, 2025, 10:19 AM
• Last activity: Jul 11, 2025, 11:58 AM
2
votes
1
answers
207
views
TCP checksum offloading on virtio-net paravirtualized interfaces
Consider the topology where 2 QEMU VMs running Linux Ubuntu `16.04` kernel version `4.4.0-210` have both `virtio-net` interfaces with `TAP` backends connected to the same (host) Linux `bridge` and an `SSH` connection between them. ubuntu@VM1:~$ uname -a Linux VM1 4.4.0-210-generic #242-Ubuntu SMP Fr...
Consider the topology where 2 QEMU VMs running Linux Ubuntu
16.04
kernel version 4.4.0-210
have both virtio-net
interfaces with TAP
backends connected to the same (host) Linux bridge
and an SSH
connection between them.
ubuntu@VM1:~$ uname -a
Linux VM1 4.4.0-210-generic #242-Ubuntu SMP Fri Apr 16 09:57:56 UTC 2021 x86_64 x86_64 x8x
ubuntu@VM1:~$
Both VMs use paravirtualized virtio-net
interfaces defaulting to TX and RX checksum
offloading.
ubuntu@VM1:~$ ethtool -i eth0
driver: virtio_net
version: 1.0.0
firmware-version:
expansion-rom-version:
bus-info: 0000:00:03.0
supports-statistics: no
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no
ubuntu@VM1:~$
ubuntu@VM1:~$ ethtool -k eth0 | grep -i sum
rx-checksumming: on [fixed]
tx-checksumming: on
tx-checksum-ipv4: off [fixed]
tx-checksum-ip-generic: on
tx-checksum-ipv6: off [fixed]
tx-checksum-fcoe-crc: off [fixed]
tx-checksum-sctp: off [fixed]
ubuntu@VM1:~$
ubuntu@VM2:~$ ethtool -k eth0 | grep -i sum
rx-checksumming: on [fixed]
tx-checksumming: on
tx-checksum-ipv4: off [fixed]
tx-checksum-ip-generic: on
tx-checksum-ipv6: off [fixed]
tx-checksum-fcoe-crc: off [fixed]
tx-checksum-sctp: off [fixed]
ubuntu@VM2:~$
That actually means:
- kernel network stack sends out SSH/TCP
packets without computing & filling the relevant TCP checksum
field inside them (i.e. basically the TCP checksum
inside the packets sent is either zeroed out or incorrect)
- kernel network stack assumes the virtio-net
interface has already checked/verified the TCP checksum
for SSH/TCP
received packets and is therefore allowed to skip it
Hence the SSH
connection works even though traveling SSH/TCP
packets have an *incorrect* TCP
checksum (tcpdump
run inside both VM confirms this).
Later, changing the topology by connecting each VM to a different linux bridge with a virtual router
in the middle, suddenly the SSH
connection stop working. I double checked that virtual router actually forwards TCP/SSH
packets *as-is* from a bridge to the the other (in both directions), so I don't understand why the SSH
connection stopped working this time.
What is going on in the latter case ? Thanks.
CarloC
(385 rep)
Jul 7, 2025, 05:59 AM
• Last activity: Jul 7, 2025, 09:09 AM
2
votes
1
answers
56
views
How to enable internet access for a bridge inside a Linux network namespace?
I've created two Linux network namespaces (ns1 and ns2), and inside each, I have: - A bridge (ns1-br0, ns2-br0) - A TAP device (tap0, tap1) connected to the respective bridge - Each TAP device gets an IP address like 10.0.0.2/24. The problem is: I want devices like tap0 and tap1 to access the intern...
I've created two Linux network namespaces (ns1 and ns2), and inside each, I have:
- A bridge (ns1-br0, ns2-br0)
- A TAP device (tap0, tap1) connected to the respective bridge
- Each TAP device gets an IP address like 10.0.0.2/24.
The problem is: I want devices like tap0 and tap1 to access the internet, but I'm confused about how to set up routing and NAT properly.
The host has internet access via eth0.
How do I:
- Connect the namespace's bridge to the outside world?
- Use NAT or MASQUERADE correctly so that TAP devices can access the internet?
- Assign default gateways?

Bhautik Chudasama
(121 rep)
Jun 18, 2025, 04:03 PM
• Last activity: Jun 18, 2025, 08:57 PM
8
votes
1
answers
78298
views
How to properly configure a tun/tap Interface in linux?
Basically I am trying to create a custom TCP Stack. As you might know I cant use eth0 because linux kernel TCP stack uses that, Due to that I need to create a tun/tap interface and use it for my Custom TCP Stack. /etc/network/interfaces: auto lo iface lo inet loopback allow-hotplug eth0 auto eth0 if...
Basically I am trying to create a custom TCP Stack. As you might know I cant use eth0 because linux kernel TCP stack uses that, Due to that I need to create a tun/tap interface and use it for my Custom TCP Stack.
/etc/network/interfaces:
auto lo
iface lo inet loopback
allow-hotplug eth0
auto eth0
iface eth0 inet static
address 192.168.1.152
netmask 255.255.255.0
broadcast 192.168.1.255
gateway 192.168.1.1
dns-server 192.168.1.1
allow-hotplug tap0
auto tap0
iface tap0 inet manual
pre-up ip tuntap add tap0 mode tap user root
pre-up ip addr add 192.168.1.153/24 dev tap0
up ip link set dev tap0 up
post-up ip route del 192.168.1.0/24 dev tap0
post-up ip route add 192.168.1.152/32 dev tap0
post-down ip link del dev tap0
ifconfig
inet addr:192.168.1.152 bcast:192.168.1.255 netmask 255.255.255.0
lo:
inet addr:127.0.0.1 mask 255.0.0.0
tap0:
inet addr: 192.168.1.153 bcast:0.0.0.0 mask 255.255.255.0
with following config I can reach wan/lan using eth0 but I cant reach not even my gateway with tap0.
I would really appreciate if you could tell me what mistake am I making here?
Mr. Nobody
(81 rep)
Jan 25, 2018, 04:51 PM
• Last activity: May 14, 2025, 07:11 AM
0
votes
1
answers
111
views
I cannot receive any packets on a tap interface
I want to test an application that runs a complete IPv6 stack in user space. The application is supposed to process and send ethernet frames. For that I want to set up a network interface on Linux that I can access from my local computer like if it were another participant in the network. I read tha...
I want to test an application that runs a complete IPv6 stack in user space. The application is supposed to process and send ethernet frames. For that I want to set up a network interface on Linux that I can access from my local computer like if it were another participant in the network. I read that I should use a tap device for that. So I created a script to set up an interface and a test application.
Here is my script to set up the interface:
#!/bin/bash
MAC_ADDR="00:11:22:33:44:55"
IP_ADDR="2001:db8::2"
setup() {
# Create the TAP interface (if not already created)
ip tuntap add dev tap0 mode tap
# Assign an IPv6 address to the TAP interface
ip -6 addr add "${IP_ADDR}/64" dev tap0
# Bring the TAP interface up
ip link set dev tap0 up
# Set a custom MAC address for the TAP interface
# (Replace with your desired MAC address)
ip link set dev tap0 address $MAC_ADDR
# Disable kernel IPv6 handling on this interface
sysctl -w net.ipv6.conf.tap0.forwarding=0
sysctl -w net.ipv6.conf.tap0.accept_ra=0
# Print interface details to verify the MAC address and IP
ip addr show dev tap0
}
cleanup() {
ip link set tap0 down || true
ip tuntap del dev tap0 mode tap
}
# Setup tap interface
setup
# Cleanup when exiting
trap cleanup SIGINT
# Keep the interface up indefinitely
echo "Press Ctrl+C to bring down the interface"
sleep infinity
This is my test application:
++
// TunInterface.h
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class TunInterface {
public:
TunInterface(const std::string& dev_name,
std::function recv_callback,
const unsigned char* mac_address = nullptr)
: dev_name(dev_name), receive_callback(recv_callback), mac_filter(mac_address) {
// Open the TUN device
tun_fd = open("/dev/net/tun", O_RDWR);
if (tun_fd receive_callback;
const unsigned char* mac_filter; // If nullptr, no filtering is done
bool is_mac_filtered(const unsigned char* packet) {
if (mac_filter) {
struct ethhdr* eth_header = reinterpret_cast(const_cast(packet));
return std::memcmp(eth_header->h_dest, mac_filter, ETH_ALEN) == 0;
}
return true; // No filter if mac_filter is nullptr
}
};
#endif
++
#include "TapInterface.h"
#include
int main() {
// Define the MAC address for filtering (e.g., 00:11:22:33:44:55)
uint8_t macAddr = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
// Create a TapInterface with MAC filtering enabled
TapInterface tap("tap0", macAddr);
if (!tap.isValid()) {
std::cerr << "Failed to create TAP interface\n";
return 1;
}
// Register a callback to handle received frames
tap.registerReceiveCallback([](const uint8_t* data, size_t len) {
std::cout << "Received frame of length " << len << " bytes\n";
});
std::cout << "Listening on tap0. Press Ctrl-C to exit.\n";
while (true) pause(); // Or use any other suitable loop
}
When I run ping6 2001:db8::2
I expect to see at least neighbour discovery ethernet frames in my test application. But I see nothing. Instead, I get replies to my ping6 attempts as soon as I start the test application. Looks like the kernel is still interfering. I tried a similar approach using a tun device and that worked, but that didn't operate on Layer 2. I am running on Ubuntu 24.04.
What could be wrong? Thanks.
Richard W
(103 rep)
Apr 9, 2025, 06:49 AM
• Last activity: Apr 11, 2025, 08:25 AM
0
votes
2
answers
108
views
How to communciate between two tap interfaces on two machines?
I have two debian based machines with IP adresses XXX.XXX.8.76/26 and XXX.XXX.8.77/26. Now i need to create a tap0 interface on both machines for an application that communicates with UDP messages. But it is not possible for me to send a UDP messages between both tap0's. tap0 eno1 eno1 tap0 I simply...
I have two debian based machines with IP adresses XXX.XXX.8.76/26 and XXX.XXX.8.77/26.
Now i need to create a tap0 interface on both machines for an application that communicates with UDP messages.
But it is not possible for me to send a UDP messages between both tap0's.
tap0 eno1 eno1 tap0
I simply created the tap0 with
ip tuntap add dev tap0 mode tap
After this I bridge the tap0 and the physical ethernet adapter with the following script:
#!/bin/bash
# Exit on error
set -e
# Define variables
BRIDGE=br0
ETH_IFACE=eno1
TAP_IFACE=tap0
IP_ADDR=XXX.XXX.8.76/26
GATEWAY=XXX:XXX.8.65
# Check if run as root
if [ "$EUID" -ne 0 ]; then
echo "Please run as root"
exit
fi
echo "Creating bridge $BRIDGE..."
ip link add $BRIDGE type bridge
echo "Bringing up the bridge..."
ip link set $BRIDGE up
echo "Adding $ETH_IFACE and $TAP_IFACE to $BRIDGE..."
ip link set $ETH_IFACE master $BRIDGE
ip link set $TAP_IFACE master $BRIDGE
echo "Bringing up $ETH_IFACE and $TAP_IFACE..."
ip link set $ETH_IFACE up
ip link set $TAP_IFACE up
echo "Assigning IP address to $BRIDGE..."
ip addr flush dev $ETH_IFACE
ip addr add $IP_ADDR dev $BRIDGE
echo "Setting up default gateway..."
ip route add default via $GATEWAY dev $BRIDGE
echo "Bridge setup complete. Current configuration:"
ip addr show $BRIDGE
bridge link show
If you have solutions that don't include a bridge I'm glad to hear them too :)
The program I want to run is the lwIP Stack.
Simon
(1 rep)
Feb 27, 2025, 09:48 PM
• Last activity: Mar 11, 2025, 09:56 AM
0
votes
1
answers
602
views
A solution to bridge wlan0 or permit to use the same lan for tap/br?
I have a tftp server on lan 192.168.0.0/24 I want a qemu vm reach it, with ethernet is simple a) First create br0 MAC1="52:54:$(dd if=/dev/urandom count=1 2>/dev/null | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\).*$/\1:\2:\3:\4/')"; nmcli con add ifname br0 type bridge con-name br0 bridge.mac-address...
I have a tftp server on lan 192.168.0.0/24
I want a qemu vm reach it, with ethernet is simple
a) First create br0
MAC1="52:54:$(dd if=/dev/urandom count=1 2>/dev/null | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\).*$/\1:\2:\3:\4/')";
nmcli con add ifname br0 type bridge con-name br0 bridge.mac-address $MAC1
b) then add eth0 as slave, then you can add vnet* or tap* interfaces with qemu or libvirt
With wlan is impossible
brctl addif br0 wlan1
can't add wlan1 to bridge br0: Operation not supported
nmcli fail also with timeout
So I have two solutions, create a "virbr" with libvirt and the use iptables rules
for natting it, but the virbr must have a different lan address (192.168.1.0/24 or 10.2.1.0/24 or whatever you want but not an address of ip range used by wlan because exit with errors) or create an empty br0 with network-manager and then assign a ip address to it and with iptables route to wlan0
iptables -A FORWARD -i br0 -o wlan1 -j ACCEPT
iptables -A FORWARD -i wlan1 -o br0 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -o wlan1 -j MASQUERADE
but when I try to get a dhcp address from 192.168.0.0/24 lan it fail.
Any advice to use 192.168.0.0/24 ip for wlan "bridge"? Thanks
Edit: the iw command to "enable" the wlan0 as slave fail
iw dev wlan1 set 4addr on
command failed: Operation not supported (-95)
Another thing: today I have installed VirtualBox on Debian 12
and using wifi bridge work, I can ping the vm using the same ip class of wlan0 wifi (88x2bu driver), but ip addr and ip link sh don't report interface, where is the bridge?
elbarna
(13690 rep)
Oct 27, 2023, 02:51 PM
• Last activity: Oct 6, 2024, 08:25 PM
4
votes
1
answers
6403
views
Theoretical: TAP interface w/ WIFI parent interface
I'm trying to create multiple Linux TAP interfaces and allow them to send/receive packets over a single WIFI adapter. For all intents and purposes I'd like the TAP interfaces to act as full fledged network adapters. They should be able to request their own DHCP addresses and interact on the local ne...
I'm trying to create multiple Linux TAP interfaces and allow them to send/receive packets over a single WIFI adapter. For all intents and purposes I'd like the TAP interfaces to act as full fledged network adapters. They should be able to request their own DHCP addresses and interact on the local network as any other network adapter might.
I've managed to get this working with an Ethernet adapter but I've heard WiFi is a different beast. I can't remember the exact reasoning but it had something to do with "1 IP address per radio broadcast address".
Is it possible, using TAP interfaces, to essentially do bridged networking over a WiFi connection? Could I do any of the configuration with networkmanager? Can someone link an article or two? I'm having a tough time finding anything on this.
TheFunk
(153 rep)
Nov 27, 2019, 02:13 AM
• Last activity: Feb 8, 2024, 12:21 AM
3
votes
2
answers
2380
views
How to get the Linux network namespace for a tap/tun device referenced in /proc/[PID]/fdinfo/[FD]?
I want to correctly match TAP/TUN devices with the processes they are using, and I want to do this from *outside* of these processes using TAP/TUN devices (that is, I cannot issue any `ioctl()`s because I don't have access to a particular file descriptor inside its process itself). I'm aware of the...
I want to correctly match TAP/TUN devices with the processes they are using, and I want to do this from *outside* of these processes using TAP/TUN devices (that is, I cannot issue any
ioctl()
s because I don't have access to a particular file descriptor inside its process itself).
I'm aware of the answers to How to find the connection between tap interface and its file descriptor? , that is: /proc/[PID]/fdinfo/[FD]
has an additional iff:
key-value pair that gives the name of the corresponding TAP/TUN network interface.
However, there's a problem with network namespaces, especially when TAP/TUN network interfaces get moved around network namespaces after their user-space processes have attached to them; for instance (here, tapclient
is a simple variation of a34729t's tunclient.c
, which accepts a tap network name and attaches to it):
$ sudo ip tuntap add tap123 mode tap
$ sudo tapclient tap123 &
$ sudo ip netns add fooz
$ sudo ip link set tap123 netns fooz
$ PID=$(ps faux | grep tapclient | grep -v -e sudo -e grep | awk '{print $2}')
$ sudo cat /proc/$PID/fdinfo/3
...which then gives: iff: tap123
-- but not the network namespace where the tap123
network interface is currently located in.
Of course, tap123
can be located by iterating over all network namespaces and looking for a matching network interface inside one of them. Unfortunately, there might be duplicate names, such as when creating another tap123
in the host namespace after we've moved the first one of this name into the fooz
network namespace above:
$ sudo ip tuntap add tap123 mode tap
$ ip link show tap123
$ sudo ip netns exec fooz ip link show tap123
So we now have **two** tap123
s in separate network namespaces, and fdinfo
only gives us an ambiguous iff: tap123
.
Unfortunately, looking at the /proc/$PID/ns/net
network namespace of the tapclient won't help either, since that doesn't match the current network namespace of tap123
any longer:
$ findmnt -t nsfs | grep /run/netns/fooz
$ sudo readlink /proc/$PID/ns/net
For instance, this gives net:
versus net:
.
It there a way to unambiguously match the tapclient
process with the correct tap123
network interface instance it is attached to?
TheDiveO
(1427 rep)
Mar 7, 2019, 08:36 AM
• Last activity: Jul 3, 2023, 01:49 PM
1
votes
0
answers
1310
views
Network routing through veth0 / bridge for userspace QEMU VM?
I would like to filter and capture traffic from a virtual machine. This VM must run in userspace. Capturing requires root, I know (though I hope to minimise root activity needed later). The easiest way to capture and filter - as I understand - is having a dedicated, virtual network interface like `v...
I would like to filter and capture traffic from a virtual machine. This VM must run in userspace. Capturing requires root, I know (though I hope to minimise root activity needed later).
The easiest way to capture and filter - as I understand - is having a dedicated, virtual network interface like
vnet0
used exclusively by the VM. Then I can run tshark
, tcpdump
, iptables
etc. on it.
**How do I set up (create) the network interfaces (as root), and how do I connect to them (as non-root) with a KVM/QEMU virtual machine?**
I am looking for ip
commands (iproute2 style) and qemu configuration options.
I have started working on interfaces like this:
(root 1) ip link add br0 type bridge
(root 2) ip addr add dev br0 10.10.0.1/24
(root 3) ip link set dev br0 up
(root 4) ip link add vm1-host type veth peer name vm1-net
(root 5) ip link set dev vm1-host master br0
(root 6) ip link set dev vm1-host up
(root 7) ip tuntap add vm1-tap mode tap
(root 8) ip addr add 10.10.0.2/24 dev vm1-net
(root 9) ip addr add 10.0.2.2/24 dev vm1-tap
(root 10) ip link set dev vm1-tap up
(root 10b) echo 1 > /proc/sys/net/ipv4/ip_forward
Then tried to connect with QEMU to the bridge but could not do so as a non-root user.
I edited /etc/qemu/bridge.conf
to allow the user to connect to the bridge via /usr/libexec/qemu-bridge-helper
:
(root 11) grep -v # /etc/qemu/bridge.conf
allow veth0
allow vm1-tap
allow vm1-host
allow vm1-net
(root 12) ll /usr/libexec/qemu-bridge-helper
-rwsr-x--- 1 root kvm 312888 Aug 25 16:16 /usr/libexec/qemu-bridge-helper
The user is indeed a member of the kvm
group (id
shows it). However, I get the following error message when usingvirt-manager
running as $USERNAME
with a bridge interface:
Error starting domain: /usr/libexec/qemu-bridge-helper --use-vnet --br=vm1-tap --fd=34: failed to communicate with bridge helper: stderr=failed to add interface tap0' to bridge
vm1-tap': Operation not supported
: Transport endpoint is not connected
Traceback (most recent call last):
File "/usr/share/virt-manager/virtManager/asyncjob.py", line 72, in cb_wrapper
callback(asyncjob, *args, **kwargs)
File "/usr/share/virt-manager/virtManager/asyncjob.py", line 108, in tmpcb
callback(*args, **kwargs)
File "/usr/share/virt-manager/virtManager/object/libvirtobject.py", line 57, in newfn
ret = fn(self, *args, **kwargs)
File "/usr/share/virt-manager/virtManager/object/domain.py", line 1425, in startup
self._backend.create()
File "/usr/lib64/python3.10/site-packages/libvirt.py", line 1362, in create
raise libvirtError('virDomainCreate() failed')
libvirt.libvirtError: /usr/libexec/qemu-bridge-helper --use-vnet --br=vm1-tap --fd=34: failed to communicate with bridge helper: stderr=failed to add interface tap0' to bridge
vm1-tap': Operation not supported
: Transport endpoint is not connected
Some **capabilities** may additionally be necessary? - **how do I make a user have them only for starting the VM?**
Perhaps this will help?
(root 13) ip tuntap add vm1-tap mode tap user $USERNAME
ioctl(TUNSETIFF): Device or resource busy
I experimented with commands found online but **do I need tun/tap at all?**, and I could not find the correct way to do this.
References (helpful but not solutions for my problem):
* [Howto setup a veth
virtual network](https://superuser.com/questions/764986/howto-setup-a-veth-virtual-network)
* https://unix.stackexchange.com/questions/456449/qemu-network-bridge
* https://unix.stackexchange.com/questions/219952/routing-only-vm-traffic-through-vpn
Ned64
(9256 rep)
Sep 1, 2022, 04:43 PM
• Last activity: Jun 30, 2023, 05:21 PM
2
votes
1
answers
902
views
How do I get the interface name created with `ip tuntap add mode tap`
I want to create a tap with sudo, and then attach the user space program (ssh) to it. I don't want to hard code the interface name, as multiple users will be using it, so I want the interface name to be generated dynamically. So I creating the tap like this: ``` sudo ip tuntap add mode tap user $USE...
I want to create a tap with sudo, and then attach the user space program (ssh) to it.
I don't want to hard code the interface name, as multiple users will be using it, so I want the interface name to be generated dynamically.
So I creating the tap like this:
sudo ip tuntap add mode tap user $USER
How do I get the ip command to return the name of the created interface, so that I can use it to pass to ssh?
Gary van der Merwe
(1830 rep)
Jan 9, 2023, 11:06 AM
• Last activity: Mar 18, 2023, 07:11 PM
10
votes
3
answers
11446
views
Why is CAP_NET_ADMIN insufficient permissions for ioctl(TUNSETIFF)?
I'm trying to write a tun/tap program in Rust. Since I don't want it to run as root I've added CAP_NET_ADMIN to the binary's capabilities: $sudo setcap cap_net_admin=eip target/release/tunnel $getcap target/release/tunnel target/release/tunnel = cap_net_admin+eip However, this is not working. Everyt...
I'm trying to write a tun/tap program in Rust. Since I don't want it to run as root I've added CAP_NET_ADMIN to the binary's capabilities:
$sudo setcap cap_net_admin=eip target/release/tunnel
$getcap target/release/tunnel
target/release/tunnel = cap_net_admin+eip
However, this is not working. Everything I've read says that this is the only capability required to create tuns, but the program gets an EPERM on the ioctl. In strace, I see this error:
openat(AT_FDCWD, "/dev/net/tun", O_RDWR|O_CLOEXEC) = 3
fcntl(3, F_GETFD) = 0x1 (flags FD_CLOEXEC)
ioctl(3, TUNSETIFF, 0x7ffcdac7c7c0) = -1 EPERM (Operation not permitted)
I've verified that the binary runs successfully with full root permissions, but I don't want this to require sudo to run. Why is CAP_NET_ADMIN not sufficient here?
For reference, I'm on
Linux version 4.15.0-45
there are only a few ways I see that this ioctl can return EPERM in the kernel (https://elixir.bootlin.com/linux/v4.15/source/drivers/net/tun.c#L2194) and at least one of them seems to be satisfied. I'm not sure how to probe the others:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
...
if (tun_not_capable(tun))
return -EPERM;
...
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
return -EPERM;
Teague Lasser
(103 rep)
Mar 17, 2019, 04:29 AM
• Last activity: Feb 17, 2023, 05:45 PM
1
votes
0
answers
153
views
Change tap device gateway
I have vps server, install softether on it , softether use tap device name tap_se with subnet 192.168.24.0/21 netmask 255.255.248.0 broadcast 192.168.31.259, clients connect with openvpn or l2tp to softether , and softether use local dhcp to assign ip in subnet 192,168.24.0/21 to them; i want to soc...
I have vps server, install softether on it , softether use tap device name tap_se with
subnet 192.168.24.0/21 netmask 255.255.248.0 broadcast 192.168.31.259,
clients connect with openvpn or l2tp to softether , and softether use local dhcp to assign ip
in subnet 192,168.24.0/21 to them;
i want to socksify outgoin traffic of softether to another server use tun2socks or alternative , and need to change routes table to do this , what must happen must be :
tap_se ==> tun0 ==> eth0
some suggested routes are :
# Bypass upstream socks5 server
sudo ip route add SOCKS5_SERVER dev DEFAULT_IFACE metric 10
sudo ip -6 route add SOCKS5_SERVER dev DEFAULT_IFACE metric 10
# Route others
sudo ip route add default dev tun0 metric 20
sudo ip -6 route add default dev tun0 metric 20
or :
ip route del default
ip route add default via 198.18.0.1 dev tun0 metric 1
ip route add default via 172.17.0.1 dev eth0 metric 10
and i create tun0 with these commands :
ip tuntap add mode tun dev tun0
ip addr add 198.18.0.1/15 dev tun0
ip link set dev tun0 up
but when do this , i lost my connection to server and need to reboot to routes restore to default, what is correct rules to do all outgoing traffic of tap_se goes through tun0 without lost connection to vps
Arman Kabir
(11 rep)
Feb 9, 2023, 02:29 PM
0
votes
0
answers
251
views
How to redirect VM DNS question to host machine localhost dnsmasq
My local network shcema is something like this: internet (WAN) | router host IP (resolv.conf) | | +------- eth0 - br0 - tap0 - VM (resolv.conf) | | localnet localhost (dnsmasq) (.home) My host computer is used mainly for testing virtual machines. The goal is to let the VM to see the local net only,...
My local network shcema is something like this:
internet (WAN)
|
router host IP (resolv.conf)
| |
+------- eth0 - br0 - tap0 - VM (resolv.conf)
| |
localnet localhost (dnsmasq)
(.home)
My host computer is used mainly for testing virtual machines.
The goal is to let the VM to see the local net only, not to get DNS from the WAN, but get it from
dnsmasq
, which is configured to listen on host lo
interface and to know just hosts from the localnet: pc1.home
pc2.home
www.home
data.home
printer.home
...
I succefully configured the dnsmasq to listen on tcp/udp 127.0.0.1:53
on the host machine, and check it by getting answer form host cli:
# dig www.google.com ... 142.251.36.68 (ANSWER 1)
and
# dig @127.0.0.1 www.google.com ... (ANSWER 0)
# dig @127.0.0.1 www.home ... 192.168.1.2 (ANSWER 1)
I set the ip_forwarding in various ways
# echo "1" > /proc/sys/net/ip4/conf/all/forwarding
# echo "1" > /proc/sys/net/ipv4/conf/tap0/route_localnet
Then I tried to compose the iptables rule:
# iptables -t nat -A PREROUTING -i tap0 -p tcp --dport 53 -j DNAT --to-destination 127.0.0.1:53
# iptables -t nat -A PREROUTING -i tap0 -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:53
followed by check
# iptables -v -t nat -L
pkts bytes target prot opt in out source destination
0 0 DNAT udp -- tap0 any anywhere anywhere udp dpt:domain to:127.0.0.1:53
0 0 DNAT tcp -- tap0 any anywhere anywhere tcp dpt:domain to:127.0.0.1:53
But while running my virtual linux, the DNS is still answered from router nameserver listed in /etc/resolv.conf
.
Well, you can advice me to rewrite the resolv.conf
of virtual machine manulaly, but as I test the installation of many VM it is annoying to do that each time, and it is hardly to say, what to write there, because the dnsmasq listens at localhost of the host machine. Hence the content of VM resolv.conf
like
nameserver 127.0.0.1
could be very confusing and useless.
I tried to capture some packets with Wireshark, but it just showed me that no redirection takes place, but not why.
schweik
(1440 rep)
Feb 2, 2023, 10:50 PM
0
votes
3
answers
157
views
How to determine next available network interface name and ip range?
I am working on an application which can create TUN/TAP interface on host machine. I can create such interfaces using: sudo ip tuntap add tap0 mode tap Now the thing is, `tap0` is hardcoded here. It should be dynamic. When I create next tap device, it should be `tap1` and so on. Now when I go ahead...
I am working on an application which can create TUN/TAP interface on host machine. I can create such interfaces using:
sudo ip tuntap add tap0 mode tap
Now the thing is,
tap0
is hardcoded here. It should be dynamic.
When I create next tap device, it should be tap1
and so on.
Now when I go ahead to give range to the device, I can manually do like this:
sudo ip addr add 172.16.0.1/24 dev tap0
Now when I create tap1, I don't want to overlap the ip.
Is there any easy way to manage these tap devices?
Santosh Kumar
(4203 rep)
Jul 25, 2022, 09:28 AM
• Last activity: Jul 25, 2022, 08:15 PM
10
votes
1
answers
20090
views
Create Network Interface from SSH Tunnel
To route your network traffic through SSH, most people would tell you to pass the `-D` option to create a SOCKS proxy on localhost that you can configure your applications to use. However, a simple proxy isn't the most practical solution for me. Is there any way to access a SSH tunnel as it's own in...
To route your network traffic through SSH, most people would tell you to pass the
-D
option to create a SOCKS proxy on localhost that you can configure your applications to use.
However, a simple proxy isn't the most practical solution for me. Is there any way to access a SSH tunnel as it's own interface, perhaps with TUN/TAP?
I'm using Linux.
Billy
(755 rep)
Jun 16, 2019, 05:12 AM
• Last activity: Mar 12, 2022, 11:18 AM
1
votes
1
answers
1664
views
How to make a Machine-In-The-Middle with a dual NIC PC in Linux?
I would like to use a Linux PC fitted with two network interface cards as a transparent bridge in order to capture (with wireshark or equivalent) all the traffic in both directions between my router/gateway and my main host (a Windows PC). The following figure illustrates what i'm talking about, my...
I would like to use a Linux PC fitted with two network interface cards as a transparent bridge in order to capture (with wireshark or equivalent) all the traffic in both directions between my router/gateway and my main host (a Windows PC).
The following figure illustrates what i'm talking about, my Linux PC will be inserted as a spy or MITM in the link:
![Machine in the middle ][1]
Source:
I know that using a managed switch with port mirroring is the most common solution for that but i'd prefer to try setting up this one in order to learn. I have already installed CentOS 7 on the spy PC and can I see my two NICs with an

ip a
command: eno1
and enp1s0
. I would appreciate some help for the next steps please, since i'm not so familiar with Linux bridges (if bridging is the solution, you will tell).
GBo
(13 rep)
Nov 14, 2021, 07:22 AM
• Last activity: Nov 14, 2021, 02:12 PM
0
votes
0
answers
348
views
Issue with Tap interface and routing
I am getting stuck in a bit of a rut and not sure if it's a limitation with EC2 servers, my attempts to get it working or a limitation with Softether. I have an EC2 server with 2 NICs; eth0 and eth1. Each NIC is mapped to a public IP address. Softether is running on the server. I am trying to create...
I am getting stuck in a bit of a rut and not sure if it's a limitation with EC2 servers, my attempts to get it working or a limitation with Softether.
I have an EC2 server with 2 NICs; eth0 and eth1. Each NIC is mapped to a public IP address. Softether is running on the server. I am trying to create an environment where one login (user1) goes out via eth0 and given the public IP assigned to that NIC, for another user (user2) I want to send traffic out via eth1 and the public IP mapped to that.
I am using secureNAT for user1 and that all works successfully. For user2, I have turned off secureNAT and linked the hub to a local bridge device called tap_secondary. I can connect to the internet via both ethernet interfaces so I know they can see the internet.
I've then allocated an ip address of 10.10.11.1/24 to tap_secondary. I'm using dnsmasq to assign IP addresses from this. I can successfully log into the VPN server and user2 is given an IP address from the 10.10.11.0/24 range.
From the linux server I can ping the 10.10.11.xx address allocated to user2 but if I ping using the source IP of eth1 this fails. I've tried numerous guides on IP tables to send traffic from the TAP to eth1 but nothing seems to work successfully. I also cannot ping addresses on the internet from 10.10.11.1 (the ip allocated to tap_secondary).
What's not clear is whether the above should work, whether my IP tables are just not right, whether ec2 supports this and I just seem to be going around in circles.
Any pointers would be helpful.
Many thanks,
Dean
Dean Baldwin
(1 rep)
Jul 27, 2021, 08:45 AM
7
votes
2
answers
16767
views
Why are incoming packets on a TAP interface seen with tcpdump but not with iptables?
A program injects packets on a Linux [TAP](http://en.wikipedia.org/wiki/TAP_%28network_driver%29) interface (these packets are coming from a virtual machine). Specifically, these are DHCP requests (so they're UDP). I can see the packets with `tcpdump` but not with `iptables`, and they don't reach th...
A program injects packets on a Linux [TAP](http://en.wikipedia.org/wiki/TAP_%28network_driver%29) interface (these packets are coming from a virtual machine). Specifically, these are DHCP requests (so they're UDP). I can see the packets with
tcpdump
but not with iptables
, and they don't reach the local DHCP server either. Why not, and how do I fix that?
**Update**: I tried injecting IP packets directed to the address of the tap0
interface. I see the ARP requests coming in from the VM in tcpdump -i tap0
, but the network layer does not reply. If I send ARP requests to the VM, it sees them and replies to the host (and the replies show up in tcpdump
but are otherwise lost).
Another observation: ifconfig tap0
shows that the TX dropped packet count is incremented for each packet that's injected onto the host. Why TX?
# ifconfig tap0
…
TX packets:0 errors:0 dropped:958 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
----
*The long story:* On a Linux host (running Ubuntu 10.04), I'm running a virtual machine which amongst other things emulates an Ethernet card. It does so by communicating with a helper program that's in charge of injecting and capturing Ethernet packets onto the hosts's network stack. The virtual machine is an ARM chip emulator, and the helper program is called nicserver
; all I know about it is what is found in the [ARM documentation](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0424b/BEIIIAJD.html) .
I want to establish an Ethernet link between the VM and the host, and above that I want an IP link. The VM obtains its IP address over DHCP. I do not want any communication between the VM and the rest of the world, only with the host, so I created a virtual network interface tap0
with
tunctl -u gilles
ifconfig tap0 192.168.56.1 netmask 255.255.255.0 up
nicserver -p 7801 -a tap0 &
Now I boot the VM, and I can see it's sending DHCP requests with tcpdump -n -i tap0 -vv
(the DHCP client doesn't time out, I'm just showing one sample request here):
tcpdump: listening on tap0, link-type EN10MB (Ethernet), capture size 96 bytes
18:29:23.941574 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 576)
0.0.0.0.68 > 255.255.255.255.67: [no cksum] BOOTP/DHCP, Request from 02:52:56:47:50:03, length 548, xid 0x238a7979, secs 46, Flags [none] (0x0000)
Client-Ethernet-Address 02:52:56:47:50:03 [|bootp]
I've set up Dnsmasq on the host to serve the requests, but it's not seeing any incoming request. The Dnsmasq server doesn't even see the incoming requests (I straced it). So I tried observing the packets with Iptables. (All the filter/INPUT rules are shown; there are no mangle or nat rules).
Chain INPUT (policy ACCEPT 2366K packets, 5334M bytes)
pkts bytes target prot opt in out source destination
119 39176 LOG udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:67 LOG flags 4 level 4 prefix `[DHCP request] '
119 39176 DROP udp -- eth1 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67
2 490 LOG udp -- tap0 * 0.0.0.0/0 0.0.0.0/0 LOG flags 4 level 4 prefix `[in=tap0] '
26 6370 ACCEPT udp -- tap0 * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- tap0 * 0.0.0.0/0 0.0.0.0/0
3864 457K ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0
All these incoming DHCP requests are on eth1
(and I'm careful not to ignore these so as not to anger my colleagues and my network admin). Those UDP packets on tap0
come from the local Samba server. The DHCP request packets that I see with tcpdump do not appear to go through the packet filter!
Why do I see incoming broadcast packets on tap0
with tcpdump
but not with iptables
(nor with programs listening on the machine)? And what do I need to fix so that these packets are seen, as they would be if they were coming on an Ethernet interface?
Gilles 'SO- stop being evil'
(862317 rep)
Nov 8, 2011, 06:01 PM
• Last activity: Jul 5, 2021, 12:22 PM
30
votes
7
answers
52140
views
How to know if a network interface is tap, tun, bridge or physical?
As far as I know, there are 4 main types of network interfaces in Linux: tun, tap, bridge and physical. When I'm doing sys admin on machines running KVM, I usually come across tap, bridge and physical interfaces on the same machine, without being able to tell them apart. I can't see any significant...
As far as I know, there are 4 main types of network interfaces in Linux: tun, tap, bridge and physical.
When I'm doing sys admin on machines running KVM, I usually come across tap, bridge and physical interfaces on the same machine, without being able to tell them apart. I can't see any significant differences in
ifconfig
results, as in ip
results.
How can I know if an interface is a tun, tap, bridge, or physical?
*note: I don't claim that there are no other types of network interfaces in Linux, but I know only these 4.*
user368507
(2223 rep)
Jun 11, 2012, 10:58 PM
• Last activity: Jun 10, 2021, 06:23 AM
Showing page 1 of 20 total questions