CachyOS / CachyOS/linux-cachyos

[BUG] PF_PACKET raw socket returns ENETDOWN on 7.1.6 bore-LTO

Open
#1,017 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Shell
Stars
4.5k
Forks
160
Avg merge
2d 12h
Merged PRs (30d)
1

Description

# Bug: PF_PACKET raw socket returns ENETDOWN on CachyOS 7.1.6 bore-LTO

## Environment

- Distro: CachyOS (x86_64)
- Kernel: `7.1.6-1-cachyos-bore-lto`
- GNS3 + ubridge 0.9.19-1 (ubridge is the reporter, but the failure is in the kernel's raw socket layer)
- Interfaces tested: `wlan0` (Wi-Fi), `ext-inet` (veth pair) — both fail identically

## Symptom

When ubridge binds a raw `AF_PACKET SOCK_RAW` socket to a host interface and starts reading, `recv()` immediately returns `-1` with `errno = ENETDOWN (100)`, "Network is down" — **even though the interface is UP with carrier**:

```
$ ip -br link show ext-inet
ext-inet@veth-peer UP aa:c4:ce:1c:aa:29

$ cat /sys/class/net/ext-inet/carrier
1
```

ubridge logs (stderr → `ubridge.log`):

```
bridge 'a325e4e8-4a98-48f0-9168-c2a661dcd142-1' is running
Source NIO: 10000:127.0.0.1:10001
Destination NIO: ext-inet
recv: Network is down <-- perror("recv") with ENETDOWN
```

Same result on `wlan0` and on `ext-inet` (veth). Both interfaces are UP and have carrier.

## Minimal reproducer

```c
/* rawtest.c — bind PF_PACKET SOCK_RAW to iface, recv() */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

int main(int argc, char **argv) {
if (argc < 2) { fprintf(stderr, "usage: %s \n", argv[0]); return 1; }
const char *iface = argv[1];

int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (fd < 0) { perror("socket"); return 1; }

struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, iface, IFNAMSIZ-1);
if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { perror("SIOCGIFINDEX"); return 1; }

struct sockaddr_ll sa;
memset(&sa, 0, sizeof(sa));
sa.sll_family = AF_PACKET;
sa.sll_protocol = htons(ETH_P_ALL);
sa.sll_ifindex = ifr.ifr_ifindex;
if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("bind"); return 1; }
printf("[ok] bound to %s (ifindex %d)\n", iface, ifr.ifr_ifindex);

struct packet_mreq mreq;
memset(&mreq, 0, sizeof(mreq));
mreq.mr_ifindex = ifr.ifr_ifindex;
mreq.mr_type = PACKET_MR_PROMISC;
if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
perror("promisc (non-fatal)");

int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
char buf[2048];
for (int i = 0; i < 5; i++) {
ssize_t n = recv(fd, buf, sizeof(buf), 0);
if (n < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
printf("[%d] recv: EAGAIN (normal, no traffic)\n", i);
} else {
printf("[%d] recv FAILED: errno=%d (%s) <-- BUG\n", i, errno, strerror(errno));
}
} else {
printf("[%d] recv: %zd bytes\n", i, n);
}
usleep(200000);
}
close(fd);
return 0;
}
```

Compile and run (root required for raw sockets):

```bash
gcc -o rawtest rawtest.c
sudo ./rawtest wlan0
sudo ./rawtest ext-inet
```

Expected: `recv: EAGAIN` (socket bound, waiting for packets).
Actual on 7.1.6-1-cachyos-bore-lto: `recv FAILED: errno=100 (Network is down)`.

## Bisect hint

User plans to test `linux-lts` to confirm whether this is specific to the bore-LTO build. This smells like a regression in the packet socket path (`net/packet/af_packet.c`) — possibly the `packet_recvmsg` device-state check — introduced somewhere after the last known-good kernel (7.0.x era, GNS3 cloud worked).

## Impact

Anything using `AF_PACKET SOCK_RAW` against a specific interface is broken: GNS3 cloud nodes (ubridge `add_nio_linux_raw`), tcpdump-style monitoring tools that bind an interface, packet builders. Not limited to veth; Wi-Fi interface fails too.

Contributor guide

Open the contributing guide

Research direction

Start by compiling and running rawtest.c on wlan0 and ext-inet, then compare the result with linux-lts and a known-good 7.0.x-era kernel. Inspect the PF_PACKET receive path in net/packet/af_packet.c, especially the suspected packet_recvmsg device-state check. Done means identifying the regression and restoring EAGAIN for an up interface without traffic.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, linux
Domain
networking, operating-systems
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.