Date: Mon, 1 Jun 2015 02:59:31 GMT From: btw@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r286504 - in soc2015/btw/head/tools/tools/mq-testing: . udp Message-ID: <201506010259.t512xVN8041711@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: btw Date: Mon Jun 1 02:59:31 2015 New Revision: 286504 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=286504 Log: Add the tools for multiqueue testing: - pktgen: a UDP packet generator based on vme; - server: a UDP server based on socket(2); Added: soc2015/btw/head/tools/tools/mq-testing/README soc2015/btw/head/tools/tools/mq-testing/udp/ soc2015/btw/head/tools/tools/mq-testing/udp/Makefile soc2015/btw/head/tools/tools/mq-testing/udp/common.h soc2015/btw/head/tools/tools/mq-testing/udp/pktgen.c soc2015/btw/head/tools/tools/mq-testing/udp/server.c Added: soc2015/btw/head/tools/tools/mq-testing/README ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2015/btw/head/tools/tools/mq-testing/README Mon Jun 1 02:59:31 2015 (r286504) @@ -0,0 +1,4 @@ +$FreeBSD$ + +This directory contains the applications for multiqueue testing. + Added: soc2015/btw/head/tools/tools/mq-testing/udp/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2015/btw/head/tools/tools/mq-testing/udp/Makefile Mon Jun 1 02:59:31 2015 (r286504) @@ -0,0 +1,12 @@ + +PROGS:= server pktgen +CFLAGS:= -Wall -Werror -O2 -lpthread + +all: ${PROGS} + +server: + +pktgen: + +clean: + rm -f *.o ${PROGS} Added: soc2015/btw/head/tools/tools/mq-testing/udp/common.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2015/btw/head/tools/tools/mq-testing/udp/common.h Mon Jun 1 02:59:31 2015 (r286504) @@ -0,0 +1,34 @@ +/*- + * Copyright (c) 2015, Tiwei Bie <btw@mail.ustc.edu.cn> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* $FreeBSD$ */ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#define SERVER_PORT 8000 + +#endif Added: soc2015/btw/head/tools/tools/mq-testing/udp/pktgen.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2015/btw/head/tools/tools/mq-testing/udp/pktgen.c Mon Jun 1 02:59:31 2015 (r286504) @@ -0,0 +1,299 @@ +/*- + * Copyright (c) 2015, Tiwei Bie <btw@mail.ustc.edu.cn> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* $FreeBSD$ */ + +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <ifaddrs.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pthread.h> +#include <pthread_np.h> + +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/cpuset.h> + +#include <net/if.h> +#include <net/if_dl.h> +#include <net/ethernet.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/udp.h> +#include <arpa/inet.h> + +#include "common.h" + +/* + * TODO: + * #1. Add supports for IPv6; + */ +#define IFCONFIG_BIN "/sbin/ifconfig " +#define IFCONFIG_ARGS "%s inet %s" + +static char vmedev[MAXPATHLEN]; +static uint8_t vmeif_ether[ETHER_ADDR_LEN]; +static in_addr_t vmeif_ip; + +static char vmeif_name[IFNAMSIZ] = "vme0"; +static char vmeif_ipstr[256] = "192.168.10.1"; +static char *payload = "hello, world!"; +static int pktsize = 100; +static int quiet = 0; +static int cpu = -1; +static uint64_t total_sent = 0; + +/* The checksum function is taken from tools/tools/netmap/pkt-gen.c */ +static uint16_t +checksum(const void *data, uint16_t len, uint32_t sum) +{ + const uint8_t *addr = data; + uint32_t i; + + /* Checksum all the pairs of bytes first... */ + for (i = 0; i < (len & ~1U); i += 2) { + sum += (uint16_t)ntohs(*(uint16_t *)(addr + i)); + if (sum > 0xFFFF) + sum -= 0xFFFF; + } + /* + * If there's a single byte left over, checksum it, too. + * Network byte order is big-endian, so the remaining byte is + * the high byte. + */ + if (i < len) { + sum += addr[i] << 8; + if (sum > 0xFFFF) + sum -= 0xFFFF; + } + return (sum); +} + +static uint16_t +wrapsum(uint32_t sum) +{ + sum = ~sum & 0xFFFF; + return (htons(sum)); +} + +static inline int +min(int a, int b) +{ + return (a < b) ? a : b; +} + +static void +build_udp_packet(uint8_t *buf, int pkt_size) +{ + struct ether_header *eh = (struct ether_header *)buf; + struct ip *ip = (struct ip *)(eh + 1); + struct udphdr *udp = (struct udphdr *)(ip + 1); + char *data = (char *)(udp + 1); + + /* Just fake an address */ + eh->ether_shost[0] = 0x01; + eh->ether_shost[1] = 0xbd; + eh->ether_shost[2] = 0xbc; + eh->ether_shost[3] = 0x4d; + eh->ether_shost[4] = 0xfb; + eh->ether_shost[5] = 0xfb; + memcpy(eh->ether_dhost, vmeif_ether, ETHER_ADDR_LEN); + eh->ether_type = htons(ETHERTYPE_IP); + + ip->ip_v = IPVERSION; + ip->ip_hl = sizeof(*ip) >> 2; + ip->ip_tos = IPTOS_LOWDELAY; + ip->ip_len = htons(pkt_size - sizeof(*eh)); + ip->ip_id = 0; + ip->ip_off = htons(IP_DF); /* XXX: Don't fragment */ + ip->ip_ttl = IPDEFTTL; + ip->ip_p = IPPROTO_UDP; + ip->ip_src.s_addr = htonl(0x0a000001 + (rand() % 0xfffffe)); + ip->ip_dst.s_addr = vmeif_ip; + + ip->ip_sum = 0; + ip->ip_sum = wrapsum(checksum(ip, sizeof(*ip), 0)); + + udp->uh_sport = htons(1 + rand() % 65535); + udp->uh_dport = htons(SERVER_PORT); + udp->uh_ulen = htons(pkt_size - sizeof(*eh) - sizeof(*ip)); + udp->uh_sum = 0; + + memcpy(data, payload, min(strlen(payload) + 1, + pkt_size - (sizeof(*eh) + sizeof(*ip) + sizeof(*udp)))); +} + +static int +get_ifaddr(const char *ifname, uint8_t *ether_addr) +{ + struct ifaddrs *ifa, *p; + struct sockaddr_dl *sdl; + char *addr; + int error = -1; + + if (getifaddrs(&ifa) != 0) + return (-1); + + for (p = ifa; p != NULL; p = p->ifa_next) { + if (strcmp(p->ifa_name, ifname) == 0 && + p->ifa_addr->sa_family == AF_LINK && + p->ifa_data != NULL) { + sdl = (struct sockaddr_dl *)p->ifa_addr; + addr = &sdl->sdl_data[sdl->sdl_nlen]; + memcpy(ether_addr, addr, ETHER_ADDR_LEN); + error = 0; + break; + } + } + + freeifaddrs(ifa); + return (error); +} + +static void +bind_cpu(int cpu) +{ + cpuset_t mask; + + CPU_ZERO(&mask); + CPU_SET(cpu, &mask); + if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) != 0) + perror("pthread_setaffinity_np"); +} + +static void +signal_handler(int arg) +{ + printf("\r%lu packets injected.\n", total_sent); + + if (arg == SIGINT) + exit(EXIT_SUCCESS); +} + +static void +usage(const char *prgname) +{ + fprintf(stderr, "%s [-a ip address] [-i vme interface] [-l pktsize] " + "[-p payload] [-q]\n", prgname); + exit(EXIT_FAILURE); +} + +int +main(int argc, char **argv) +{ + int vmefd; + char cmd[sizeof(IFCONFIG_BIN) + sizeof(vmeif_name) + + sizeof(vmeif_ipstr) + 50]; + uint8_t *buf; + int ch; + + while ((ch = getopt(argc, argv, "a:b:i:l:p:q")) != -1) { + switch (ch) { + case 'a': + strlcpy(vmeif_ipstr, optarg, sizeof(vmeif_ipstr)); + break; + case 'b': + sscanf(optarg, "%d", &cpu); + break; + case 'i': + strlcpy(vmeif_name, optarg, sizeof(vmeif_name)); + break; + case 'l': + sscanf(optarg, "%d", &pktsize); + break; + case 'p': + payload = strdup(optarg); + break; + case 'q': + quiet = 1; + break; + default: + usage(argv[0]); + break; + } + } + + if (!quiet) { + printf("vme name: %s\n", vmeif_name); + printf("vme ip: %s\n", vmeif_ipstr); + printf("packet size: %d\n", pktsize); + printf("payload: %s\n", payload); + if (cpu != -1) + printf("cpu: %d\n", cpu); + } + + if (cpu != -1) + bind_cpu(cpu); + + signal(SIGINT, signal_handler); + + snprintf(vmedev, sizeof(vmedev), "/dev/%s", vmeif_name); + + vmefd = open(vmedev, O_RDWR); + if (vmefd == -1) { + fprintf(stderr, "Failed to open %s: %s\n", vmedev, + strerror(errno)); + exit(EXIT_FAILURE); + } + + snprintf(cmd, sizeof(cmd), IFCONFIG_BIN IFCONFIG_ARGS, vmeif_name, + vmeif_ipstr); + if (system(cmd) != 0) { + fprintf(stderr, "Failed to setup %s\n", vmeif_name); + exit(EXIT_FAILURE); + } + + if ((vmeif_ip = inet_addr(vmeif_ipstr)) == INADDR_NONE) { + fprintf(stderr, "Malformed address %s specified\n", + vmeif_ipstr); + exit(EXIT_FAILURE); + } + + if (get_ifaddr(vmeif_name, vmeif_ether) != 0) { + fprintf(stderr, "Failed to get %s's MAC address\n", vmeif_name); + exit(EXIT_FAILURE); + } + + if ((buf = malloc(pktsize)) == NULL) { + perror("Failed to allocate memory for packet"); + exit(EXIT_FAILURE); + } + + /* Keep injecting packets to network stack */ + while (1) { + build_udp_packet(buf, pktsize); + if (write(vmefd, buf, pktsize) == -1) { + perror("write"); + exit(EXIT_FAILURE); + } + total_sent++; + } + + return (0); +} Added: soc2015/btw/head/tools/tools/mq-testing/udp/server.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2015/btw/head/tools/tools/mq-testing/udp/server.c Mon Jun 1 02:59:31 2015 (r286504) @@ -0,0 +1,106 @@ +/*- + * Copyright (c) 2015, Tiwei Bie <btw@mail.ustc.edu.cn> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* $FreeBSD$ */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include "common.h" + +static int verbose = 0; + +static void +usage(const char *prgname) +{ + fprintf(stderr, "%s [-v]\n", prgname); + exit(EXIT_FAILURE); +} + +int +main(int argc, char **argv) +{ + int sd; + struct sockaddr_in lsin, from; + socklen_t length; + char msg[BUFSIZ]; + int n, ch, i; + + while ((ch = getopt(argc, argv, "v")) != -1) { + switch (ch) { + case 'v': + verbose = 1; + break; + default: + usage(argv[0]); + break; + } + } + + sd = socket(AF_INET, SOCK_DGRAM, 0); + if (sd < 0) { + perror("socket"); + exit(EXIT_FAILURE); + } + + memset(&lsin, 0, sizeof(lsin)); + lsin.sin_family = AF_INET; + lsin.sin_addr.s_addr = INADDR_ANY; + lsin.sin_port = htons(SERVER_PORT); + if (bind(sd, (struct sockaddr *)&lsin, sizeof(lsin)) < 0) { + perror("bind"); + exit(EXIT_FAILURE); + } + + while (1) { + length = sizeof(from); + n = recvfrom(sd, msg, sizeof(msg), 0, + (struct sockaddr *)&from, &length); + if (n < 0) { + perror("recvfrom"); + exit(EXIT_FAILURE); + } + + if (verbose) { + printf("from=%s:%d len=%d ", inet_ntoa(from.sin_addr), + ntohs(from.sin_port), n); + for (i = 0; i < n && msg[i]; i++) { + if (isprint(msg[i])) + printf("%c", msg[i]); + } + printf("\n"); + } + } + + return (0); +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506010259.t512xVN8041711>