diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-15 01:17:12 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-15 01:17:12 +0300 |
commit | 5d89d9f502f9c33ed0270d716f238429861e1942 (patch) | |
tree | 6a353640e6836ca465f2dcf00323a7f8a793ae59 /Documentation/networking | |
parent | 50cff89837a43a7c62ac080de9742a298d6418b3 (diff) | |
parent | fecf861e765b2f9ce1a0487c3940afaed80ef7a8 (diff) | |
download | linux-5d89d9f502f9c33ed0270d716f238429861e1942.tar.xz |
Merge tag 'linux-kselftest-4.9-rc1-update' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
Pull kselftest updates from Shuah Khan:
"This update consists of:
- Fixes and improvements to existing tests
- Moving code from Documentation to selftests, samples, and tools:
* Moves dnotify_test, prctl, ptp, vDSO, ia64, watchdog, and
networking tests from Documentation to selftests.
* Moves mic/mpssd, misc-devices/mei, timers, watchdog, auxdisplay,
and blackfin examples from Documentation to samples.
* Moves accounting, laptops/dslm, and pcmcia/crc32hash tools from
Documentation to tools.
* Deletes BUILD_DOCSRC and its dependencies"
* tag 'linux-kselftest-4.9-rc1-update' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (21 commits)
selftests/futex: Check ANSI terminal color support
Doc: update 00-INDEX files to reflect the runnable code move
samples: move blackfin gptimers-example from Documentation
tools: move pcmcia crc32hash tool from Documentation
tools: move laptops dslm tool from Documentation
tools: move accounting tool from Documentation
samples: move auxdisplay example code from Documentation
samples: move watchdog example code from Documentation
samples: move timers example code from Documentation
samples: move misc-devices/mei example code from Documentation
samples: move mic/mpssd example code from Documentation
selftests: Move networking/timestamping from Documentation
selftests: move watchdog tests from Documentation/watchdog
selftests: move ia64 tests from Documentation/ia64
selftests: move vDSO tests from Documentation/vDSO
selftests: move ptp tests from Documentation/ptp
selftests: move prctl tests from Documentation/prctl
selftests: move dnotify_test from Documentation/filesystems
selftests/timers: Add missing error code assignment before test
selftests/zram: replace ZRAM_LZ4_COMPRESS
...
Diffstat (limited to 'Documentation/networking')
-rw-r--r-- | Documentation/networking/00-INDEX | 2 | ||||
-rw-r--r-- | Documentation/networking/Makefile | 1 | ||||
-rw-r--r-- | Documentation/networking/timestamping/.gitignore | 3 | ||||
-rw-r--r-- | Documentation/networking/timestamping/Makefile | 14 | ||||
-rw-r--r-- | Documentation/networking/timestamping/hwtstamp_config.c | 134 | ||||
-rw-r--r-- | Documentation/networking/timestamping/timestamping.c | 528 | ||||
-rw-r--r-- | Documentation/networking/timestamping/txtimestamp.c | 549 |
7 files changed, 0 insertions, 1231 deletions
diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX index a7697783ac4c..c6beb5f1637f 100644 --- a/Documentation/networking/00-INDEX +++ b/Documentation/networking/00-INDEX @@ -10,8 +10,6 @@ LICENSE.qlge - GPLv2 for QLogic Linux qlge NIC Driver LICENSE.qlcnic - GPLv2 for QLogic Linux qlcnic NIC Driver -Makefile - - Makefile for docsrc. PLIP.txt - PLIP: The Parallel Line Internet Protocol device driver README.ipw2100 diff --git a/Documentation/networking/Makefile b/Documentation/networking/Makefile deleted file mode 100644 index 4c5d7c485439..000000000000 --- a/Documentation/networking/Makefile +++ /dev/null @@ -1 +0,0 @@ -subdir-y := timestamping diff --git a/Documentation/networking/timestamping/.gitignore b/Documentation/networking/timestamping/.gitignore deleted file mode 100644 index 9e69e982fb38..000000000000 --- a/Documentation/networking/timestamping/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -timestamping -txtimestamp -hwtstamp_config diff --git a/Documentation/networking/timestamping/Makefile b/Documentation/networking/timestamping/Makefile deleted file mode 100644 index 8c20dfaa4d6e..000000000000 --- a/Documentation/networking/timestamping/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# To compile, from the source root -# -# make headers_install -# make M=documentation - -# List of programs to build -hostprogs-y := hwtstamp_config timestamping txtimestamp - -# Tell kbuild to always build the programs -always := $(hostprogs-y) - -HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include -HOSTCFLAGS_txtimestamp.o += -I$(objtree)/usr/include -HOSTCFLAGS_hwtstamp_config.o += -I$(objtree)/usr/include diff --git a/Documentation/networking/timestamping/hwtstamp_config.c b/Documentation/networking/timestamping/hwtstamp_config.c deleted file mode 100644 index e8b685a7f15f..000000000000 --- a/Documentation/networking/timestamping/hwtstamp_config.c +++ /dev/null @@ -1,134 +0,0 @@ -/* Test program for SIOC{G,S}HWTSTAMP - * Copyright 2013 Solarflare Communications - * Author: Ben Hutchings - */ - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <sys/socket.h> -#include <sys/ioctl.h> - -#include <linux/if.h> -#include <linux/net_tstamp.h> -#include <linux/sockios.h> - -static int -lookup_value(const char **names, int size, const char *name) -{ - int value; - - for (value = 0; value < size; value++) - if (names[value] && strcasecmp(names[value], name) == 0) - return value; - - return -1; -} - -static const char * -lookup_name(const char **names, int size, int value) -{ - return (value >= 0 && value < size) ? names[value] : NULL; -} - -static void list_names(FILE *f, const char **names, int size) -{ - int value; - - for (value = 0; value < size; value++) - if (names[value]) - fprintf(f, " %s\n", names[value]); -} - -static const char *tx_types[] = { -#define TX_TYPE(name) [HWTSTAMP_TX_ ## name] = #name - TX_TYPE(OFF), - TX_TYPE(ON), - TX_TYPE(ONESTEP_SYNC) -#undef TX_TYPE -}; -#define N_TX_TYPES ((int)(sizeof(tx_types) / sizeof(tx_types[0]))) - -static const char *rx_filters[] = { -#define RX_FILTER(name) [HWTSTAMP_FILTER_ ## name] = #name - RX_FILTER(NONE), - RX_FILTER(ALL), - RX_FILTER(SOME), - RX_FILTER(PTP_V1_L4_EVENT), - RX_FILTER(PTP_V1_L4_SYNC), - RX_FILTER(PTP_V1_L4_DELAY_REQ), - RX_FILTER(PTP_V2_L4_EVENT), - RX_FILTER(PTP_V2_L4_SYNC), - RX_FILTER(PTP_V2_L4_DELAY_REQ), - RX_FILTER(PTP_V2_L2_EVENT), - RX_FILTER(PTP_V2_L2_SYNC), - RX_FILTER(PTP_V2_L2_DELAY_REQ), - RX_FILTER(PTP_V2_EVENT), - RX_FILTER(PTP_V2_SYNC), - RX_FILTER(PTP_V2_DELAY_REQ), -#undef RX_FILTER -}; -#define N_RX_FILTERS ((int)(sizeof(rx_filters) / sizeof(rx_filters[0]))) - -static void usage(void) -{ - fputs("Usage: hwtstamp_config if_name [tx_type rx_filter]\n" - "tx_type is any of (case-insensitive):\n", - stderr); - list_names(stderr, tx_types, N_TX_TYPES); - fputs("rx_filter is any of (case-insensitive):\n", stderr); - list_names(stderr, rx_filters, N_RX_FILTERS); -} - -int main(int argc, char **argv) -{ - struct ifreq ifr; - struct hwtstamp_config config; - const char *name; - int sock; - - if ((argc != 2 && argc != 4) || (strlen(argv[1]) >= IFNAMSIZ)) { - usage(); - return 2; - } - - if (argc == 4) { - config.flags = 0; - config.tx_type = lookup_value(tx_types, N_TX_TYPES, argv[2]); - config.rx_filter = lookup_value(rx_filters, N_RX_FILTERS, argv[3]); - if (config.tx_type < 0 || config.rx_filter < 0) { - usage(); - return 2; - } - } - - sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock < 0) { - perror("socket"); - return 1; - } - - strcpy(ifr.ifr_name, argv[1]); - ifr.ifr_data = (caddr_t)&config; - - if (ioctl(sock, (argc == 2) ? SIOCGHWTSTAMP : SIOCSHWTSTAMP, &ifr)) { - perror("ioctl"); - return 1; - } - - printf("flags = %#x\n", config.flags); - name = lookup_name(tx_types, N_TX_TYPES, config.tx_type); - if (name) - printf("tx_type = %s\n", name); - else - printf("tx_type = %d\n", config.tx_type); - name = lookup_name(rx_filters, N_RX_FILTERS, config.rx_filter); - if (name) - printf("rx_filter = %s\n", name); - else - printf("rx_filter = %d\n", config.rx_filter); - - return 0; -} diff --git a/Documentation/networking/timestamping/timestamping.c b/Documentation/networking/timestamping/timestamping.c deleted file mode 100644 index 5cdfd743447b..000000000000 --- a/Documentation/networking/timestamping/timestamping.c +++ /dev/null @@ -1,528 +0,0 @@ -/* - * This program demonstrates how the various time stamping features in - * the Linux kernel work. It emulates the behavior of a PTP - * implementation in stand-alone master mode by sending PTPv1 Sync - * multicasts once every second. It looks for similar packets, but - * beyond that doesn't actually implement PTP. - * - * Outgoing packets are time stamped with SO_TIMESTAMPING with or - * without hardware support. - * - * Incoming packets are time stamped with SO_TIMESTAMPING with or - * without hardware support, SIOCGSTAMP[NS] (per-socket time stamp) and - * SO_TIMESTAMP[NS]. - * - * Copyright (C) 2009 Intel Corporation. - * Author: Patrick Ohly <patrick.ohly@intel.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> - -#include <sys/time.h> -#include <sys/socket.h> -#include <sys/select.h> -#include <sys/ioctl.h> -#include <arpa/inet.h> -#include <net/if.h> - -#include <asm/types.h> -#include <linux/net_tstamp.h> -#include <linux/errqueue.h> - -#ifndef SO_TIMESTAMPING -# define SO_TIMESTAMPING 37 -# define SCM_TIMESTAMPING SO_TIMESTAMPING -#endif - -#ifndef SO_TIMESTAMPNS -# define SO_TIMESTAMPNS 35 -#endif - -#ifndef SIOCGSTAMPNS -# define SIOCGSTAMPNS 0x8907 -#endif - -#ifndef SIOCSHWTSTAMP -# define SIOCSHWTSTAMP 0x89b0 -#endif - -static void usage(const char *error) -{ - if (error) - printf("invalid option: %s\n", error); - printf("timestamping interface option*\n\n" - "Options:\n" - " IP_MULTICAST_LOOP - looping outgoing multicasts\n" - " SO_TIMESTAMP - normal software time stamping, ms resolution\n" - " SO_TIMESTAMPNS - more accurate software time stamping\n" - " SOF_TIMESTAMPING_TX_HARDWARE - hardware time stamping of outgoing packets\n" - " SOF_TIMESTAMPING_TX_SOFTWARE - software fallback for outgoing packets\n" - " SOF_TIMESTAMPING_RX_HARDWARE - hardware time stamping of incoming packets\n" - " SOF_TIMESTAMPING_RX_SOFTWARE - software fallback for incoming packets\n" - " SOF_TIMESTAMPING_SOFTWARE - request reporting of software time stamps\n" - " SOF_TIMESTAMPING_RAW_HARDWARE - request reporting of raw HW time stamps\n" - " SIOCGSTAMP - check last socket time stamp\n" - " SIOCGSTAMPNS - more accurate socket time stamp\n"); - exit(1); -} - -static void bail(const char *error) -{ - printf("%s: %s\n", error, strerror(errno)); - exit(1); -} - -static const unsigned char sync[] = { - 0x00, 0x01, 0x00, 0x01, - 0x5f, 0x44, 0x46, 0x4c, - 0x54, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01, - - /* fake uuid */ - 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, - - 0x00, 0x01, 0x00, 0x37, - 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, - 0x49, 0x05, 0xcd, 0x01, - 0x29, 0xb1, 0x8d, 0xb0, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, - - /* fake uuid */ - 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, - - 0x00, 0x00, 0x00, 0x37, - 0x00, 0x00, 0x00, 0x04, - 0x44, 0x46, 0x4c, 0x54, - 0x00, 0x00, 0xf0, 0x60, - 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0xf0, 0x60, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, - 0x44, 0x46, 0x4c, 0x54, - 0x00, 0x01, - - /* fake uuid */ - 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, - - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -static void sendpacket(int sock, struct sockaddr *addr, socklen_t addr_len) -{ - struct timeval now; - int res; - - res = sendto(sock, sync, sizeof(sync), 0, - addr, addr_len); - gettimeofday(&now, 0); - if (res < 0) - printf("%s: %s\n", "send", strerror(errno)); - else - printf("%ld.%06ld: sent %d bytes\n", - (long)now.tv_sec, (long)now.tv_usec, - res); -} - -static void printpacket(struct msghdr *msg, int res, - char *data, - int sock, int recvmsg_flags, - int siocgstamp, int siocgstampns) -{ - struct sockaddr_in *from_addr = (struct sockaddr_in *)msg->msg_name; - struct cmsghdr *cmsg; - struct timeval tv; - struct timespec ts; - struct timeval now; - - gettimeofday(&now, 0); - - printf("%ld.%06ld: received %s data, %d bytes from %s, %zu bytes control messages\n", - (long)now.tv_sec, (long)now.tv_usec, - (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular", - res, - inet_ntoa(from_addr->sin_addr), - msg->msg_controllen); - for (cmsg = CMSG_FIRSTHDR(msg); - cmsg; - cmsg = CMSG_NXTHDR(msg, cmsg)) { - printf(" cmsg len %zu: ", cmsg->cmsg_len); - switch (cmsg->cmsg_level) { - case SOL_SOCKET: - printf("SOL_SOCKET "); - switch (cmsg->cmsg_type) { - case SO_TIMESTAMP: { - struct timeval *stamp = - (struct timeval *)CMSG_DATA(cmsg); - printf("SO_TIMESTAMP %ld.%06ld", - (long)stamp->tv_sec, - (long)stamp->tv_usec); - break; - } - case SO_TIMESTAMPNS: { - struct timespec *stamp = - (struct timespec *)CMSG_DATA(cmsg); - printf("SO_TIMESTAMPNS %ld.%09ld", - (long)stamp->tv_sec, - (long)stamp->tv_nsec); - break; - } - case SO_TIMESTAMPING: { - struct timespec *stamp = - (struct timespec *)CMSG_DATA(cmsg); - printf("SO_TIMESTAMPING "); - printf("SW %ld.%09ld ", - (long)stamp->tv_sec, - (long)stamp->tv_nsec); - stamp++; - /* skip deprecated HW transformed */ - stamp++; - printf("HW raw %ld.%09ld", - (long)stamp->tv_sec, - (long)stamp->tv_nsec); - break; - } - default: - printf("type %d", cmsg->cmsg_type); - break; - } - break; - case IPPROTO_IP: - printf("IPPROTO_IP "); - switch (cmsg->cmsg_type) { - case IP_RECVERR: { - struct sock_extended_err *err = - (struct sock_extended_err *)CMSG_DATA(cmsg); - printf("IP_RECVERR ee_errno '%s' ee_origin %d => %s", - strerror(err->ee_errno), - err->ee_origin, -#ifdef SO_EE_ORIGIN_TIMESTAMPING - err->ee_origin == SO_EE_ORIGIN_TIMESTAMPING ? - "bounced packet" : "unexpected origin" -#else - "probably SO_EE_ORIGIN_TIMESTAMPING" -#endif - ); - if (res < sizeof(sync)) - printf(" => truncated data?!"); - else if (!memcmp(sync, data + res - sizeof(sync), - sizeof(sync))) - printf(" => GOT OUR DATA BACK (HURRAY!)"); - break; - } - case IP_PKTINFO: { - struct in_pktinfo *pktinfo = - (struct in_pktinfo *)CMSG_DATA(cmsg); - printf("IP_PKTINFO interface index %u", - pktinfo->ipi_ifindex); - break; - } - default: - printf("type %d", cmsg->cmsg_type); - break; - } - break; - default: - printf("level %d type %d", - cmsg->cmsg_level, - cmsg->cmsg_type); - break; - } - printf("\n"); - } - - if (siocgstamp) { - if (ioctl(sock, SIOCGSTAMP, &tv)) - printf(" %s: %s\n", "SIOCGSTAMP", strerror(errno)); - else - printf("SIOCGSTAMP %ld.%06ld\n", - (long)tv.tv_sec, - (long)tv.tv_usec); - } - if (siocgstampns) { - if (ioctl(sock, SIOCGSTAMPNS, &ts)) - printf(" %s: %s\n", "SIOCGSTAMPNS", strerror(errno)); - else - printf("SIOCGSTAMPNS %ld.%09ld\n", - (long)ts.tv_sec, - (long)ts.tv_nsec); - } -} - -static void recvpacket(int sock, int recvmsg_flags, - int siocgstamp, int siocgstampns) -{ - char data[256]; - struct msghdr msg; - struct iovec entry; - struct sockaddr_in from_addr; - struct { - struct cmsghdr cm; - char control[512]; - } control; - int res; - - memset(&msg, 0, sizeof(msg)); - msg.msg_iov = &entry; - msg.msg_iovlen = 1; - entry.iov_base = data; - entry.iov_len = sizeof(data); - msg.msg_name = (caddr_t)&from_addr; - msg.msg_namelen = sizeof(from_addr); - msg.msg_control = &control; - msg.msg_controllen = sizeof(control); - - res = recvmsg(sock, &msg, recvmsg_flags|MSG_DONTWAIT); - if (res < 0) { - printf("%s %s: %s\n", - "recvmsg", - (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular", - strerror(errno)); - } else { - printpacket(&msg, res, data, - sock, recvmsg_flags, - siocgstamp, siocgstampns); - } -} - -int main(int argc, char **argv) -{ - int so_timestamping_flags = 0; - int so_timestamp = 0; - int so_timestampns = 0; - int siocgstamp = 0; - int siocgstampns = 0; - int ip_multicast_loop = 0; - char *interface; - int i; - int enabled = 1; - int sock; - struct ifreq device; - struct ifreq hwtstamp; - struct hwtstamp_config hwconfig, hwconfig_requested; - struct sockaddr_in addr; - struct ip_mreq imr; - struct in_addr iaddr; - int val; - socklen_t len; - struct timeval next; - - if (argc < 2) - usage(0); - interface = argv[1]; - - for (i = 2; i < argc; i++) { - if (!strcasecmp(argv[i], "SO_TIMESTAMP")) - so_timestamp = 1; - else if (!strcasecmp(argv[i], "SO_TIMESTAMPNS")) - so_timestampns = 1; - else if (!strcasecmp(argv[i], "SIOCGSTAMP")) - siocgstamp = 1; - else if (!strcasecmp(argv[i], "SIOCGSTAMPNS")) - siocgstampns = 1; - else if (!strcasecmp(argv[i], "IP_MULTICAST_LOOP")) - ip_multicast_loop = 1; - else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_HARDWARE")) - so_timestamping_flags |= SOF_TIMESTAMPING_TX_HARDWARE; - else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_SOFTWARE")) - so_timestamping_flags |= SOF_TIMESTAMPING_TX_SOFTWARE; - else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_HARDWARE")) - so_timestamping_flags |= SOF_TIMESTAMPING_RX_HARDWARE; - else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_SOFTWARE")) - so_timestamping_flags |= SOF_TIMESTAMPING_RX_SOFTWARE; - else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SOFTWARE")) - so_timestamping_flags |= SOF_TIMESTAMPING_SOFTWARE; - else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RAW_HARDWARE")) - so_timestamping_flags |= SOF_TIMESTAMPING_RAW_HARDWARE; - else - usage(argv[i]); - } - - sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (sock < 0) - bail("socket"); - - memset(&device, 0, sizeof(device)); - strncpy(device.ifr_name, interface, sizeof(device.ifr_name)); - if (ioctl(sock, SIOCGIFADDR, &device) < 0) - bail("getting interface IP address"); - - memset(&hwtstamp, 0, sizeof(hwtstamp)); - strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name)); - hwtstamp.ifr_data = (void *)&hwconfig; - memset(&hwconfig, 0, sizeof(hwconfig)); - hwconfig.tx_type = - (so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ? - HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; - hwconfig.rx_filter = - (so_timestamping_flags & SOF_TIMESTAMPING_RX_HARDWARE) ? - HWTSTAMP_FILTER_PTP_V1_L4_SYNC : HWTSTAMP_FILTER_NONE; - hwconfig_requested = hwconfig; - if (ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) < 0) { - if ((errno == EINVAL || errno == ENOTSUP) && - hwconfig_requested.tx_type == HWTSTAMP_TX_OFF && - hwconfig_requested.rx_filter == HWTSTAMP_FILTER_NONE) - printf("SIOCSHWTSTAMP: disabling hardware time stamping not possible\n"); - else - bail("SIOCSHWTSTAMP"); - } - printf("SIOCSHWTSTAMP: tx_type %d requested, got %d; rx_filter %d requested, got %d\n", - hwconfig_requested.tx_type, hwconfig.tx_type, - hwconfig_requested.rx_filter, hwconfig.rx_filter); - - /* bind to PTP port */ - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(INADDR_ANY); - addr.sin_port = htons(319 /* PTP event port */); - if (bind(sock, - (struct sockaddr *)&addr, - sizeof(struct sockaddr_in)) < 0) - bail("bind"); - - /* set multicast group for outgoing packets */ - inet_aton("224.0.1.130", &iaddr); /* alternate PTP domain 1 */ - addr.sin_addr = iaddr; - imr.imr_multiaddr.s_addr = iaddr.s_addr; - imr.imr_interface.s_addr = - ((struct sockaddr_in *)&device.ifr_addr)->sin_addr.s_addr; - if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, - &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0) - bail("set multicast"); - - /* join multicast group, loop our own packet */ - if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, - &imr, sizeof(struct ip_mreq)) < 0) - bail("join multicast group"); - - if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, - &ip_multicast_loop, sizeof(enabled)) < 0) { - bail("loop multicast"); - } - - /* set socket options for time stamping */ - if (so_timestamp && - setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, - &enabled, sizeof(enabled)) < 0) - bail("setsockopt SO_TIMESTAMP"); - - if (so_timestampns && - setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS, - &enabled, sizeof(enabled)) < 0) - bail("setsockopt SO_TIMESTAMPNS"); - - if (so_timestamping_flags && - setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, - &so_timestamping_flags, - sizeof(so_timestamping_flags)) < 0) - bail("setsockopt SO_TIMESTAMPING"); - - /* request IP_PKTINFO for debugging purposes */ - if (setsockopt(sock, SOL_IP, IP_PKTINFO, - &enabled, sizeof(enabled)) < 0) - printf("%s: %s\n", "setsockopt IP_PKTINFO", strerror(errno)); - - /* verify socket options */ - len = sizeof(val); - if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &val, &len) < 0) - printf("%s: %s\n", "getsockopt SO_TIMESTAMP", strerror(errno)); - else - printf("SO_TIMESTAMP %d\n", val); - - if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS, &val, &len) < 0) - printf("%s: %s\n", "getsockopt SO_TIMESTAMPNS", - strerror(errno)); - else - printf("SO_TIMESTAMPNS %d\n", val); - - if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &val, &len) < 0) { - printf("%s: %s\n", "getsockopt SO_TIMESTAMPING", - strerror(errno)); - } else { - printf("SO_TIMESTAMPING %d\n", val); - if (val != so_timestamping_flags) - printf(" not the expected value %d\n", - so_timestamping_flags); - } - - /* send packets forever every five seconds */ - gettimeofday(&next, 0); - next.tv_sec = (next.tv_sec + 1) / 5 * 5; - next.tv_usec = 0; - while (1) { - struct timeval now; - struct timeval delta; - long delta_us; - int res; - fd_set readfs, errorfs; - - gettimeofday(&now, 0); - delta_us = (long)(next.tv_sec - now.tv_sec) * 1000000 + - (long)(next.tv_usec - now.tv_usec); - if (delta_us > 0) { - /* continue waiting for timeout or data */ - delta.tv_sec = delta_us / 1000000; - delta.tv_usec = delta_us % 1000000; - - FD_ZERO(&readfs); - FD_ZERO(&errorfs); - FD_SET(sock, &readfs); - FD_SET(sock, &errorfs); - printf("%ld.%06ld: select %ldus\n", - (long)now.tv_sec, (long)now.tv_usec, - delta_us); - res = select(sock + 1, &readfs, 0, &errorfs, &delta); - gettimeofday(&now, 0); - printf("%ld.%06ld: select returned: %d, %s\n", - (long)now.tv_sec, (long)now.tv_usec, - res, - res < 0 ? strerror(errno) : "success"); - if (res > 0) { - if (FD_ISSET(sock, &readfs)) - printf("ready for reading\n"); - if (FD_ISSET(sock, &errorfs)) - printf("has error\n"); - recvpacket(sock, 0, - siocgstamp, - siocgstampns); - recvpacket(sock, MSG_ERRQUEUE, - siocgstamp, - siocgstampns); - } - } else { - /* write one packet */ - sendpacket(sock, - (struct sockaddr *)&addr, - sizeof(addr)); - next.tv_sec += 5; - continue; - } - } - - return 0; -} diff --git a/Documentation/networking/timestamping/txtimestamp.c b/Documentation/networking/timestamping/txtimestamp.c deleted file mode 100644 index 5df07047ca86..000000000000 --- a/Documentation/networking/timestamping/txtimestamp.c +++ /dev/null @@ -1,549 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * Author: willemb@google.com (Willem de Bruijn) - * - * Test software tx timestamping, including - * - * - SCHED, SND and ACK timestamps - * - RAW, UDP and TCP - * - IPv4 and IPv6 - * - various packet sizes (to test GSO and TSO) - * - * Consult the command line arguments for help on running - * the various testcases. - * - * This test requires a dummy TCP server. - * A simple `nc6 [-u] -l -p $DESTPORT` will do - * - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#define _GNU_SOURCE - -#include <arpa/inet.h> -#include <asm/types.h> -#include <error.h> -#include <errno.h> -#include <inttypes.h> -#include <linux/errqueue.h> -#include <linux/if_ether.h> -#include <linux/net_tstamp.h> -#include <netdb.h> -#include <net/if.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <netinet/udp.h> -#include <netinet/tcp.h> -#include <netpacket/packet.h> -#include <poll.h> -#include <stdarg.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/select.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <sys/types.h> -#include <time.h> -#include <unistd.h> - -/* command line parameters */ -static int cfg_proto = SOCK_STREAM; -static int cfg_ipproto = IPPROTO_TCP; -static int cfg_num_pkts = 4; -static int do_ipv4 = 1; -static int do_ipv6 = 1; -static int cfg_payload_len = 10; -static bool cfg_show_payload; -static bool cfg_do_pktinfo; -static bool cfg_loop_nodata; -static uint16_t dest_port = 9000; - -static struct sockaddr_in daddr; -static struct sockaddr_in6 daddr6; -static struct timespec ts_prev; - -static void __print_timestamp(const char *name, struct timespec *cur, - uint32_t key, int payload_len) -{ - if (!(cur->tv_sec | cur->tv_nsec)) - return; - - fprintf(stderr, " %s: %lu s %lu us (seq=%u, len=%u)", - name, cur->tv_sec, cur->tv_nsec / 1000, - key, payload_len); - - if ((ts_prev.tv_sec | ts_prev.tv_nsec)) { - int64_t cur_ms, prev_ms; - - cur_ms = (long) cur->tv_sec * 1000 * 1000; - cur_ms += cur->tv_nsec / 1000; - - prev_ms = (long) ts_prev.tv_sec * 1000 * 1000; - prev_ms += ts_prev.tv_nsec / 1000; - - fprintf(stderr, " (%+" PRId64 " us)", cur_ms - prev_ms); - } - - ts_prev = *cur; - fprintf(stderr, "\n"); -} - -static void print_timestamp_usr(void) -{ - struct timespec ts; - struct timeval tv; /* avoid dependency on -lrt */ - - gettimeofday(&tv, NULL); - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000; - - __print_timestamp(" USR", &ts, 0, 0); -} - -static void print_timestamp(struct scm_timestamping *tss, int tstype, - int tskey, int payload_len) -{ - const char *tsname; - - switch (tstype) { - case SCM_TSTAMP_SCHED: - tsname = " ENQ"; - break; - case SCM_TSTAMP_SND: - tsname = " SND"; - break; - case SCM_TSTAMP_ACK: - tsname = " ACK"; - break; - default: - error(1, 0, "unknown timestamp type: %u", - tstype); - } - __print_timestamp(tsname, &tss->ts[0], tskey, payload_len); -} - -/* TODO: convert to check_and_print payload once API is stable */ -static void print_payload(char *data, int len) -{ - int i; - - if (!len) - return; - - if (len > 70) - len = 70; - - fprintf(stderr, "payload: "); - for (i = 0; i < len; i++) - fprintf(stderr, "%02hhx ", data[i]); - fprintf(stderr, "\n"); -} - -static void print_pktinfo(int family, int ifindex, void *saddr, void *daddr) -{ - char sa[INET6_ADDRSTRLEN], da[INET6_ADDRSTRLEN]; - - fprintf(stderr, " pktinfo: ifindex=%u src=%s dst=%s\n", - ifindex, - saddr ? inet_ntop(family, saddr, sa, sizeof(sa)) : "unknown", - daddr ? inet_ntop(family, daddr, da, sizeof(da)) : "unknown"); -} - -static void __poll(int fd) -{ - struct pollfd pollfd; - int ret; - - memset(&pollfd, 0, sizeof(pollfd)); - pollfd.fd = fd; - ret = poll(&pollfd, 1, 100); - if (ret != 1) - error(1, errno, "poll"); -} - -static void __recv_errmsg_cmsg(struct msghdr *msg, int payload_len) -{ - struct sock_extended_err *serr = NULL; - struct scm_timestamping *tss = NULL; - struct cmsghdr *cm; - int batch = 0; - - for (cm = CMSG_FIRSTHDR(msg); - cm && cm->cmsg_len; - cm = CMSG_NXTHDR(msg, cm)) { - if (cm->cmsg_level == SOL_SOCKET && - cm->cmsg_type == SCM_TIMESTAMPING) { - tss = (void *) CMSG_DATA(cm); - } else if ((cm->cmsg_level == SOL_IP && - cm->cmsg_type == IP_RECVERR) || - (cm->cmsg_level == SOL_IPV6 && - cm->cmsg_type == IPV6_RECVERR)) { - serr = (void *) CMSG_DATA(cm); - if (serr->ee_errno != ENOMSG || - serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) { - fprintf(stderr, "unknown ip error %d %d\n", - serr->ee_errno, - serr->ee_origin); - serr = NULL; - } - } else if (cm->cmsg_level == SOL_IP && - cm->cmsg_type == IP_PKTINFO) { - struct in_pktinfo *info = (void *) CMSG_DATA(cm); - print_pktinfo(AF_INET, info->ipi_ifindex, - &info->ipi_spec_dst, &info->ipi_addr); - } else if (cm->cmsg_level == SOL_IPV6 && - cm->cmsg_type == IPV6_PKTINFO) { - struct in6_pktinfo *info6 = (void *) CMSG_DATA(cm); - print_pktinfo(AF_INET6, info6->ipi6_ifindex, - NULL, &info6->ipi6_addr); - } else - fprintf(stderr, "unknown cmsg %d,%d\n", - cm->cmsg_level, cm->cmsg_type); - - if (serr && tss) { - print_timestamp(tss, serr->ee_info, serr->ee_data, - payload_len); - serr = NULL; - tss = NULL; - batch++; - } - } - - if (batch > 1) - fprintf(stderr, "batched %d timestamps\n", batch); -} - -static int recv_errmsg(int fd) -{ - static char ctrl[1024 /* overprovision*/]; - static struct msghdr msg; - struct iovec entry; - static char *data; - int ret = 0; - - data = malloc(cfg_payload_len); - if (!data) - error(1, 0, "malloc"); - - memset(&msg, 0, sizeof(msg)); - memset(&entry, 0, sizeof(entry)); - memset(ctrl, 0, sizeof(ctrl)); - - entry.iov_base = data; - entry.iov_len = cfg_payload_len; - msg.msg_iov = &entry; - msg.msg_iovlen = 1; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = ctrl; - msg.msg_controllen = sizeof(ctrl); - - ret = recvmsg(fd, &msg, MSG_ERRQUEUE); - if (ret == -1 && errno != EAGAIN) - error(1, errno, "recvmsg"); - - if (ret >= 0) { - __recv_errmsg_cmsg(&msg, ret); - if (cfg_show_payload) - print_payload(data, cfg_payload_len); - } - - free(data); - return ret == -1; -} - -static void do_test(int family, unsigned int opt) -{ - char *buf; - int fd, i, val = 1, total_len; - - if (family == AF_INET6 && cfg_proto != SOCK_STREAM) { - /* due to lack of checksum generation code */ - fprintf(stderr, "test: skipping datagram over IPv6\n"); - return; - } - - total_len = cfg_payload_len; - if (cfg_proto == SOCK_RAW) { - total_len += sizeof(struct udphdr); - if (cfg_ipproto == IPPROTO_RAW) - total_len += sizeof(struct iphdr); - } - - buf = malloc(total_len); - if (!buf) - error(1, 0, "malloc"); - - fd = socket(family, cfg_proto, cfg_ipproto); - if (fd < 0) - error(1, errno, "socket"); - - if (cfg_proto == SOCK_STREAM) { - if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, - (char*) &val, sizeof(val))) - error(1, 0, "setsockopt no nagle"); - - if (family == PF_INET) { - if (connect(fd, (void *) &daddr, sizeof(daddr))) - error(1, errno, "connect ipv4"); - } else { - if (connect(fd, (void *) &daddr6, sizeof(daddr6))) - error(1, errno, "connect ipv6"); - } - } - - if (cfg_do_pktinfo) { - if (family == AF_INET6) { - if (setsockopt(fd, SOL_IPV6, IPV6_RECVPKTINFO, - &val, sizeof(val))) - error(1, errno, "setsockopt pktinfo ipv6"); - } else { - if (setsockopt(fd, SOL_IP, IP_PKTINFO, - &val, sizeof(val))) - error(1, errno, "setsockopt pktinfo ipv4"); - } - } - - opt |= SOF_TIMESTAMPING_SOFTWARE | - SOF_TIMESTAMPING_OPT_CMSG | - SOF_TIMESTAMPING_OPT_ID; - if (cfg_loop_nodata) - opt |= SOF_TIMESTAMPING_OPT_TSONLY; - - if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, - (char *) &opt, sizeof(opt))) - error(1, 0, "setsockopt timestamping"); - - for (i = 0; i < cfg_num_pkts; i++) { - memset(&ts_prev, 0, sizeof(ts_prev)); - memset(buf, 'a' + i, total_len); - - if (cfg_proto == SOCK_RAW) { - struct udphdr *udph; - int off = 0; - - if (cfg_ipproto == IPPROTO_RAW) { - struct iphdr *iph = (void *) buf; - - memset(iph, 0, sizeof(*iph)); - iph->ihl = 5; - iph->version = 4; - iph->ttl = 2; - iph->daddr = daddr.sin_addr.s_addr; - iph->protocol = IPPROTO_UDP; - /* kernel writes saddr, csum, len */ - - off = sizeof(*iph); - } - - udph = (void *) buf + off; - udph->source = ntohs(9000); /* random spoof */ - udph->dest = ntohs(dest_port); - udph->len = ntohs(sizeof(*udph) + cfg_payload_len); - udph->check = 0; /* not allowed for IPv6 */ - } - - print_timestamp_usr(); - if (cfg_proto != SOCK_STREAM) { - if (family == PF_INET) - val = sendto(fd, buf, total_len, 0, (void *) &daddr, sizeof(daddr)); - else - val = sendto(fd, buf, total_len, 0, (void *) &daddr6, sizeof(daddr6)); - } else { - val = send(fd, buf, cfg_payload_len, 0); - } - if (val != total_len) - error(1, errno, "send"); - - /* wait for all errors to be queued, else ACKs arrive OOO */ - usleep(50 * 1000); - - __poll(fd); - - while (!recv_errmsg(fd)) {} - } - - if (close(fd)) - error(1, errno, "close"); - - free(buf); - usleep(400 * 1000); -} - -static void __attribute__((noreturn)) usage(const char *filepath) -{ - fprintf(stderr, "\nUsage: %s [options] hostname\n" - "\nwhere options are:\n" - " -4: only IPv4\n" - " -6: only IPv6\n" - " -h: show this message\n" - " -I: request PKTINFO\n" - " -l N: send N bytes at a time\n" - " -n: set no-payload option\n" - " -r: use raw\n" - " -R: use raw (IP_HDRINCL)\n" - " -p N: connect to port N\n" - " -u: use udp\n" - " -x: show payload (up to 70 bytes)\n", - filepath); - exit(1); -} - -static void parse_opt(int argc, char **argv) -{ - int proto_count = 0; - char c; - - while ((c = getopt(argc, argv, "46hIl:np:rRux")) != -1) { - switch (c) { - case '4': - do_ipv6 = 0; - break; - case '6': - do_ipv4 = 0; - break; - case 'I': - cfg_do_pktinfo = true; - break; - case 'n': - cfg_loop_nodata = true; - break; - case 'r': - proto_count++; - cfg_proto = SOCK_RAW; - cfg_ipproto = IPPROTO_UDP; - break; - case 'R': - proto_count++; - cfg_proto = SOCK_RAW; - cfg_ipproto = IPPROTO_RAW; - break; - case 'u': - proto_count++; - cfg_proto = SOCK_DGRAM; - cfg_ipproto = IPPROTO_UDP; - break; - case 'l': - cfg_payload_len = strtoul(optarg, NULL, 10); - break; - case 'p': - dest_port = strtoul(optarg, NULL, 10); - break; - case 'x': - cfg_show_payload = true; - break; - case 'h': - default: - usage(argv[0]); - } - } - - if (!cfg_payload_len) - error(1, 0, "payload may not be nonzero"); - if (cfg_proto != SOCK_STREAM && cfg_payload_len > 1472) - error(1, 0, "udp packet might exceed expected MTU"); - if (!do_ipv4 && !do_ipv6) - error(1, 0, "pass -4 or -6, not both"); - if (proto_count > 1) - error(1, 0, "pass -r, -R or -u, not multiple"); - - if (optind != argc - 1) - error(1, 0, "missing required hostname argument"); -} - -static void resolve_hostname(const char *hostname) -{ - struct addrinfo *addrs, *cur; - int have_ipv4 = 0, have_ipv6 = 0; - - if (getaddrinfo(hostname, NULL, NULL, &addrs)) - error(1, errno, "getaddrinfo"); - - cur = addrs; - while (cur && !have_ipv4 && !have_ipv6) { - if (!have_ipv4 && cur->ai_family == AF_INET) { - memcpy(&daddr, cur->ai_addr, sizeof(daddr)); - daddr.sin_port = htons(dest_port); - have_ipv4 = 1; - } - else if (!have_ipv6 && cur->ai_family == AF_INET6) { - memcpy(&daddr6, cur->ai_addr, sizeof(daddr6)); - daddr6.sin6_port = htons(dest_port); - have_ipv6 = 1; - } - cur = cur->ai_next; - } - if (addrs) - freeaddrinfo(addrs); - - do_ipv4 &= have_ipv4; - do_ipv6 &= have_ipv6; -} - -static void do_main(int family) -{ - fprintf(stderr, "family: %s\n", - family == PF_INET ? "INET" : "INET6"); - - fprintf(stderr, "test SND\n"); - do_test(family, SOF_TIMESTAMPING_TX_SOFTWARE); - - fprintf(stderr, "test ENQ\n"); - do_test(family, SOF_TIMESTAMPING_TX_SCHED); - - fprintf(stderr, "test ENQ + SND\n"); - do_test(family, SOF_TIMESTAMPING_TX_SCHED | - SOF_TIMESTAMPING_TX_SOFTWARE); - - if (cfg_proto == SOCK_STREAM) { - fprintf(stderr, "\ntest ACK\n"); - do_test(family, SOF_TIMESTAMPING_TX_ACK); - - fprintf(stderr, "\ntest SND + ACK\n"); - do_test(family, SOF_TIMESTAMPING_TX_SOFTWARE | - SOF_TIMESTAMPING_TX_ACK); - - fprintf(stderr, "\ntest ENQ + SND + ACK\n"); - do_test(family, SOF_TIMESTAMPING_TX_SCHED | - SOF_TIMESTAMPING_TX_SOFTWARE | - SOF_TIMESTAMPING_TX_ACK); - } -} - -const char *sock_names[] = { NULL, "TCP", "UDP", "RAW" }; - -int main(int argc, char **argv) -{ - if (argc == 1) - usage(argv[0]); - - parse_opt(argc, argv); - resolve_hostname(argv[argc - 1]); - - fprintf(stderr, "protocol: %s\n", sock_names[cfg_proto]); - fprintf(stderr, "payload: %u\n", cfg_payload_len); - fprintf(stderr, "server port: %u\n", dest_port); - fprintf(stderr, "\n"); - - if (do_ipv4) - do_main(PF_INET); - if (do_ipv6) - do_main(PF_INET6); - - return 0; -} |