With kernel 3.19, a read() from a TUN/TAP file descriptor in non-blocking mode will return 0 when no data is available, rather than fail with EAGAIN. This breaks certain applications which will interpret the 0 return value as a zero-length packet and happily go on reading more packets. Here's relevant parts of my application showing the change of behavior and how the application locks up with kernel 3.19. -- strace with 3.18 -- open("/dev/net/tun", O_RDWR) = 5 ioctl(5, TUNSETIFF, 0x7ffe24f1e620) = 0 socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 6 ioctl(6, SIOCGIFMTU, {ifr_name="tun4", ifr_mtu=1500}) = 0 close(6) = 0 fcntl(5, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 epoll_ctl(3, EPOLL_CTL_ADD, 5, {0, {u32=6509592, u64=6509592}}) = 0 read(5, 0xac8010, 1500) = -1 EAGAIN (Resource temporarily unavailable) epoll_ctl(3, EPOLL_CTL_MOD, 5, {EPOLLIN, {u32=6509592, u64=6509592}}) = 0 -- strace with 3.19 -- open("/dev/net/tun", O_RDWR) = 5 ioctl(5, TUNSETIFF, 0x7ffea2f4d970) = 0 socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 6 ioctl(6, SIOCGIFMTU, {ifr_name="tun4", ifr_mtu=1500}) = 0 close(6) = 0 fcntl(5, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 epoll_ctl(3, EPOLL_CTL_ADD, 5, {0, {u32=6509592, u64=6509592}}) = 0 read(5, "", 1500) = 0 read(5, "", 1500) = 0 read(5, "", 1500) = 0 read(5, "", 1500) = 0 read(5, "", 1500) = 0 ...
Think I ran into this. Using Boost ASIO to do async reads from TAP fd. Now that I've upgraded to Ubuntu 15.04 (kernel 3.19.0-15), the application behaves differently where ASIO returns immediately with EOF error when attempting to read from the TAP fd.
Anyone know if this was ever fixed?