diff --git a/test/zdtm.sh b/test/zdtm.sh index cae8f8bdd..c6b2db263 100755 --- a/test/zdtm.sh +++ b/test/zdtm.sh @@ -69,6 +69,7 @@ static/cmdlinenv00 static/socket_listen static/socket_listen6 static/packet_sock +static/packet_sock_mmap static/socket_udp static/sock_filter static/socket6_udp @@ -224,6 +225,7 @@ ns/static/sk-unix-unconn ns/static/socket_listen ns/static/socket_listen6 ns/static/packet_sock +ns/static/packet_sock_mmap ns/static/socket_udp ns/static/sock_filter ns/static/socket6_udp @@ -288,6 +290,7 @@ sock_opts00 sock_opts01 cmdlinenv00 packet_sock +packet_sock_mmap fanotify00 sk-netlink tun diff --git a/test/zdtm/live/static/Makefile b/test/zdtm/live/static/Makefile index b4cd62f92..90d35acac 100644 --- a/test/zdtm/live/static/Makefile +++ b/test/zdtm/live/static/Makefile @@ -34,6 +34,7 @@ TST_NOFILE = \ socket_udplite \ socket_aio \ packet_sock \ + packet_sock_mmap \ sock_filter \ msgque \ inotify_system \ diff --git a/test/zdtm/live/static/packet_sock_mmap.c b/test/zdtm/live/static/packet_sock_mmap.c new file mode 100644 index 000000000..265d61348 --- /dev/null +++ b/test/zdtm/live/static/packet_sock_mmap.c @@ -0,0 +1,103 @@ +#include "zdtmtst.h" + +const char *test_doc = "static test for packet sockets mmaps"; +const char *test_author = "Pavel Emelyanov "; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) + +struct tpacket_req3 { + unsigned int tp_block_size; + unsigned int tp_block_nr; + unsigned int tp_frame_size; + unsigned int tp_frame_nr; + unsigned int tp_retire_blk_tov; + unsigned int tp_sizeof_priv; + unsigned int tp_feature_req_word; +}; + +#endif + +static void check_map_is_there(unsigned long addr, int sk) +{ + char name[128]; + struct stat sk_s, link_s; + + sprintf(name, "/proc/self/map_files/%lx-%lx", + addr, addr + 2 * 4096); + + if (stat(name, &link_s) < 0) { + fail("No socket mapping\n"); + return; + } + + fstat(sk, &sk_s); + if ((sk_s.st_dev != link_s.st_dev) || (sk_s.st_ino != link_s.st_ino)) { + fail("Non-socket mapping restored\n"); + return; + } + + pass(); +} + +int main(int argc, char **argv) +{ + int sk; + struct tpacket_req3 ring; + void *mem; + + test_init(argc, argv); + + sk = socket(PF_PACKET, SOCK_RAW, 0); + if (sk < 0) { + err("Can't create socket 1"); + return 1; + } + + memset(&ring, 0, sizeof(ring)); + ring.tp_block_size = 4096; + ring.tp_block_nr = 1; + ring.tp_frame_size = 1024; + ring.tp_frame_nr = 4; + if (setsockopt(sk, SOL_PACKET, PACKET_RX_RING, &ring, sizeof(ring)) < 0) { + err("Can't set rx ring %m"); + return 1; + } + + memset(&ring, 0, sizeof(ring)); + ring.tp_block_size = 4096; + ring.tp_block_nr = 1; + ring.tp_frame_size = 1024; + ring.tp_frame_nr = 4; + if (setsockopt(sk, SOL_PACKET, PACKET_TX_RING, &ring, sizeof(ring)) < 0) { + err("Can't set tx ring %m"); + return 1; + } + + mem = mmap(NULL, 2 * 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FILE, sk, 0); + if (mem == MAP_FAILED) { + err("Can't mmap socket %m"); + return 1; + } + + test_daemon(); + test_waitsig(); + + check_map_is_there((unsigned long)mem, sk); + + return 0; +}