Hello, Bisected problems with setns() and /proc/net/sctp/snmp to this:
commit 1da4d377f943fe4194ffb9fb9c26cc58fad4dd24 Author: Alexey Dobriyan <[email protected]> Date: Fri Apr 13 15:35:42 2018 -0700 proc: revalidate misc dentries Reproduces for example with Fedora 5.9.10-100.fc32.x86_64, so 1fde6f21d90f ("proc: fix /proc/net/* after setns(2)") does not seem to cover /proc/net/sctp/snmp Reproducer attached, that does open+read+close of /proc/net/sctp/snmp before and after setns() syscall. The second open+read+close of /proc/net/sctp/snmp incorrectly produces results for the default namespace, not the target namespace. Example, create netns and do some sctp: # ./iperf-netns + modprobe sctp + ip netns add test + ip netns exec test ip link set lo up + ip netns exec test iperf3 -s -1 ----------------------------------------------------------- Server listening on 5201 ----------------------------------------------------------- + ip netns exec test iperf3 -c 127.0.0.1 --sctp --bitrate 50M --time 4 Connecting to host 127.0.0.1, port 5201 Accepted connection from 127.0.0.1, port 50696 [ 5] local 127.0.0.1 port 54735 connected to 127.0.0.1 port 5201 [ 5] local 127.0.0.1 port 5201 connected to 127.0.0.1 port 54735 [ ID] Interval Transfer Bitrate [ ID] Interval Transfer Bitrate [ 5] 0.00-1.00 sec 6.00 MBytes 50.3 Mbits/sec [ 5] 0.00-1.00 sec 6.00 MBytes 50.3 Mbits/sec [ 5] 1.00-2.00 sec 5.94 MBytes 49.8 Mbits/sec [ 5] 1.00-2.00 sec 5.94 MBytes 49.8 Mbits/sec [ 5] 2.00-3.00 sec 6.00 MBytes 50.3 Mbits/sec [ 5] 2.00-3.00 sec 6.00 MBytes 50.3 Mbits/sec [ 5] 3.00-4.00 sec 5.94 MBytes 49.8 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bitrate [ 5] 0.00-4.00 sec 23.9 MBytes 50.1 Mbits/sec receiver [ 5] 3.00-4.00 sec 5.94 MBytes 49.8 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bitrate [ 5] 0.00-4.00 sec 23.9 MBytes 50.1 Mbits/sec [ 5] 0.00-4.00 sec 23.9 MBytes 50.1 iperf Done. + cat /proc/net/sctp/snmp SctpCurrEstab 0 SctpActiveEstabs 0 SctpPassiveEstabs 0 SctpAborteds 0 SctpShutdowns 0 SctpOutOfBlues 0 SctpChecksumErrors 0 [...] + ip netns exec test cat /proc/net/sctp/snmp SctpCurrEstab 0 SctpActiveEstabs 2 SctpPassiveEstabs 2 SctpAborteds 0 SctpShutdowns 4 SctpOutOfBlues 0 SctpChecksumErrors 0 SctpOutCtrlChunks 1544 SctpOutOrderChunks 1530 [...] + wait But now we see all zeroes in /proc/net/sctp/snmp with the reproducer: $ gcc repro.c -o repro # ./repro /proc/net/sctp/snmp [pid: 175998] SctpCurrEstab 0 SctpActiveEstabs 0 SctpPassiveEstabs 0 SctpAborteds 0 SctpShutdowns 0 [...] setns(/run/netns/test) ... /proc/net/sctp/snmp [pid: 175998] SctpCurrEstab 0 SctpActiveEstabs 0 SctpPassiveEstabs 0 SctpAborteds 0 SctpShutdowns 0 SctpOutOfBlues 0 [...] -Tommi
#define _GNU_SOURCE
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void slurp(const char *fn)
{
char buf[8192];
ssize_t r;
int fd;
printf("%s [pid: %d]\n", fn, getpid()); fflush(stdout);
fd = open(fn, O_RDONLY);
if (fd < 0) { perror("open"); exit(1); }
r = read(fd, buf, sizeof(buf)-1);
if (r < 0) { perror("read"); exit(1); }
buf[r] = 0;
puts(buf); fflush(stdout);
if (close(fd) < 0) { perror("close"); exit(1); }
}
void newnet(const char *ns)
{
int fd;
fd = open(ns, O_RDONLY);
if (fd < 0) { perror("open"); exit(1); }
if (setns(fd, CLONE_NEWNET) < 0) { perror("setns"); exit(1); }
if (close(fd) < 0) { perror("close"); exit(1); }
}
int main(int argc, char **argv)
{
const char *ns = "/run/netns/test";
const char *fn = "/proc/net/sctp/snmp";
int d = 1;
// Optional args: /run/netns/... /proc/net/... n
if (argc >= 2) ns = argv[1];
if (argc >= 3) fn = argv[2];
if (argc >= 4 && argv[3][0] == 'n') d = 0;
if (d) slurp(fn);
printf("setns(%s) ...\n", ns); fflush(stdout);
newnet(ns);
slurp(fn);
}
iperf-netns
Description: iperf-netns

