Hello, Bisected problems with setns() and /proc/net/sctp/snmp to this: commit 1da4d377f943fe4194ffb9fb9c26cc58fad4dd24 Author: Alexey Dobriyan <adobriyan@xxxxxxxxx> 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); }
Attachment:
iperf-netns
Description: iperf-netns