diff options
Diffstat (limited to 'trafgen.c')
-rw-r--r-- | trafgen.c | 85 |
1 files changed, 56 insertions, 29 deletions
@@ -82,7 +82,8 @@ struct ctx { struct dev_io *dev_out; struct dev_io *dev_in; unsigned long num; - unsigned int cpus; + unsigned int cpu_start; + unsigned int cpu_num; uid_t uid; gid_t gid; char *device, *rhost; struct sockaddr_in dest; @@ -140,7 +141,8 @@ static const struct option long_options[] = { {NULL, 0, NULL, 0} }; -static const char *copyright = "Please report bugs to <netsniff-ng@googlegroups.com>\n" +static const char *copyright = + "Please report bugs at https://github.com/netsniff-ng/netsniff-ng/issues\n" "Copyright (C) 2011-2013 Daniel Borkmann <dborkma@tik.ee.ethz.ch>,\n" "Swiss federal institute of technology (ETH Zurich)\n" "License: GNU GPL version 2.0\n" @@ -194,9 +196,9 @@ static void __noreturn help(void) " -s|--smoke-test <ipv4> Probe if machine survived fuzz-tested packet\n" " -n|--num <uint> Number of packets until exit (def: 0)\n" " -r|--rand Randomize packet selection (def: round robin)\n" - " -P|--cpus <uint> Specify number of forks(<= CPUs) (def: #CPUs)\n" + " -P|--cpus <uint>[-<uint>] Specify number of forks(<= CPUs) (def: #CPUs)\n" " -t|--gap <time> Set approx. interpacket gap (s/ms/us/ns, def: us)\n" - " -b|--rate <rate> Send traffic at specified rate (pps/B/kB/MB/GB/kbit/Mbit/Gbit/KiB/MiB/GiB)\n" + " -b|--rate <rate> Send traffic at specified rate (pps/kpps/Mpps/B/kB/MB/GB/kbit/Mbit/Gbit/KiB/MiB/GiB)\n" " -S|--ring-size <size> Manually set mmap size (KiB/MiB/GiB)\n" " -E|--seed <uint> Manually set srand(3) seed\n" " -u|--user <userid> Drop privileges and change to userid\n" @@ -212,6 +214,7 @@ static void __noreturn help(void) " -h|--help Guess what?!\n\n" "Examples:\n" " trafgen --dev eth0 --conf trafgen.cfg\n" + " trafgen --dev eth0 --conf trafgen.cfg --cpus 2-4\n" " trafgen -e | trafgen -i - -o eth0 --cpp -n 1\n" " trafgen --dev eth0 --conf fuzzing.cfg --smoke-test 10.0.0.1\n" " trafgen --dev wlan0 --rfraw --conf beacon-test.txf -V --cpus 2\n" @@ -829,7 +832,7 @@ static unsigned long __wait_and_sum_others(struct ctx *ctx, unsigned int cpu) unsigned int i; unsigned long total; - for (i = 0, total = plen; i < ctx->cpus; i++) { + for (i = 0, total = plen; i < ctx->cpu_num; i++) { if (i == cpu) continue; @@ -852,7 +855,7 @@ static void __correct_global_delta(struct ctx *ctx, unsigned int cpu, unsigned l int cpu_sel; long long delta_correction = 0; - for (i = 0, total = ctx->num; i < ctx->cpus; i++) { + for (i = 0, total = ctx->num; i < ctx->cpu_num; i++) { if (i == cpu) continue; @@ -870,7 +873,7 @@ static void __correct_global_delta(struct ctx *ctx, unsigned int cpu, unsigned l if (total < orig) delta_correction = +1 * ((long long) orig - total); - for (cpu_sel = -1, i = 0; i < ctx->cpus; i++) { + for (cpu_sel = -1, i = 0; i < ctx->cpu_num; i++) { if (stats[i].cd_packets > 0) { if ((long long) stats[i].cd_packets + delta_correction >= 0) { @@ -928,9 +931,7 @@ static void xmit_packet_precheck(struct ctx *ctx, unsigned int cpu) static void pcap_load_packets(struct dev_io *dev) { - struct packet *pkt; - - while ((pkt = dev_io_read(dev)) != 0) + while (dev_io_read(dev)) /* nothing to do */; } @@ -957,7 +958,7 @@ static void main_loop(struct ctx *ctx, char *confname, bool slow, unsigned int i; size_t total_len = 0, total_pkts = 0; - for (i = 0; i < ctx->cpus; ++i) { + for (i = 0; i < ctx->cpu_num; ++i) { total_len += stats[i].cf_bytes; total_pkts += stats[i].cf_packets; } @@ -1012,7 +1013,7 @@ int main(int argc, char **argv) uint64_t gap = 0; unsigned int i; char *confname = NULL, *ptr; - unsigned long cpus_tmp, orig_num = 0; + unsigned long cpu_n, orig_num = 0; unsigned long long tx_packets, tx_bytes; struct ctx ctx; int min_opts = 5; @@ -1023,7 +1024,7 @@ int main(int argc, char **argv) struct timespec delay; memset(&ctx, 0, sizeof(ctx)); - ctx.cpus = get_number_cpus_online(); + ctx.cpu_num = get_number_cpus_online(); ctx.uid = getuid(); ctx.gid = getgid(); ctx.qdisc_path = false; @@ -1057,9 +1058,20 @@ int main(int argc, char **argv) ctx.verbose = true; break; case 'P': - cpus_tmp = strtoul(optarg, NULL, 0); - if (cpus_tmp > 0 && cpus_tmp < ctx.cpus) - ctx.cpus = cpus_tmp; + if (slow) + break; + cpu_n = strtoul(optarg, &ptr, 0); + if (ptr && *ptr == '-') { + if (cpu_n < 0 || cpu_n >= ctx.cpu_num) + break; + ctx.cpu_start = cpu_n; + cpu_n = strtoul(ptr + 1, NULL, 0); + if (cpu_n < ctx.cpu_start || cpu_n >= ctx.cpu_num) + ctx.cpu_num -= ctx.cpu_start; + else + ctx.cpu_num = cpu_n - ctx.cpu_start + 1; + } else if (cpu_n > 0 && cpu_n <= ctx.cpu_num) + ctx.cpu_num = cpu_n; break; case 'd': case 'o': @@ -1082,7 +1094,8 @@ int main(int argc, char **argv) break; case 's': slow = true; - ctx.cpus = 1; + ctx.cpu_start = 0; + ctx.cpu_num = 1; ctx.smoke_test = true; ctx.rhost = xstrdup(optarg); break; @@ -1098,8 +1111,10 @@ int main(int argc, char **argv) if (c == 'i' && strstr(confname, ".pcap")) { ctx.sh.type = SHAPER_TSTAMP; ctx.pcap_in = confname; - } else if (!strncmp("-", confname, strlen("-"))) - ctx.cpus = 1; + } else if (!strncmp("-", confname, strlen("-"))) { + ctx.cpu_start = 0; + ctx.cpu_num = 1; + } break; case 'u': ctx.uid = strtoul(optarg, NULL, 0); @@ -1154,6 +1169,12 @@ int main(int argc, char **argv) if (strncmp(ptr, "pps", strlen("pps")) == 0) { shape_type = SHAPER_PKTS; + } else if (strncmp(ptr, "kpps", strlen("kpps")) == 0) { + shape_type = SHAPER_PKTS; + rate *= 1000; + } else if (strncmp(ptr, "Mpps", strlen("Mpps")) == 0) { + shape_type = SHAPER_PKTS; + rate *= 1000 * 1000; } else if (strncmp(ptr, "B", strlen("B")) == 0) { shape_type = SHAPER_BYTES; } else if (strncmp(ptr, "kB", strlen("kB")) == 0) { @@ -1286,7 +1307,8 @@ int main(int argc, char **argv) /* Fall back to single core to not mess up correct timing. * We are slow anyway! */ - ctx.cpus = 1; + ctx.cpu_start = 0; + ctx.cpu_num = 1; slow = true; } @@ -1296,16 +1318,21 @@ int main(int argc, char **argv) * packets than intended or none at all. */ if (ctx.num) - ctx.cpus = min_t(unsigned int, ctx.num, ctx.cpus); + ctx.cpu_num = min_t(unsigned int, ctx.num, ctx.cpu_num); if (set_irq_aff && dev_io_is_netdev(ctx.dev_out)) { irq = device_irq_number(ctx.device); - device_set_irq_affinity_list(irq, 0, ctx.cpus - 1); + device_set_irq_affinity_list(irq, ctx.cpu_start, + ctx.cpu_start + ctx.cpu_num - 1); } - stats = setup_shared_var(ctx.cpus); + stats = setup_shared_var(ctx.cpu_num); + - for (i = 0; i < ctx.cpus; i++) { + if (ctx.verbose) + printf("Start %u worker processes on cpus [%u-%u].\n", + ctx.cpu_num, ctx.cpu_start, ctx.cpu_start + ctx.cpu_num - 1); + for (i = 0; i < ctx.cpu_num; i++) { pid_t pid = fork(); switch (pid) { @@ -1314,7 +1341,7 @@ int main(int argc, char **argv) seed = generate_srand_seed(); srand(seed); - cpu_affinity(i); + cpu_affinity(ctx.cpu_start + i); main_loop(&ctx, confname, slow, i, invoke_cpp, cpp_argv, orig_num); @@ -1324,7 +1351,7 @@ int main(int argc, char **argv) } } - for (i = 0; i < ctx.cpus; i++) { + for (i = 0; i < ctx.cpu_num; i++) { int status; wait(&status); @@ -1335,7 +1362,7 @@ int main(int argc, char **argv) if (set_sock_mem) reset_system_socket_memory(vals, array_size(vals)); - for (i = 0, tx_packets = tx_bytes = 0; i < ctx.cpus; i++) { + for (i = 0, tx_packets = tx_bytes = 0; i < ctx.cpu_num; i++) { while ((__get_state(i) & CPU_STATS_STATE_RES) == 0) sched_yield(); @@ -1347,7 +1374,7 @@ int main(int argc, char **argv) printf("\n"); printf("\r%12llu packets outgoing\n", tx_packets); printf("\r%12llu bytes outgoing\n", tx_bytes); - for (i = 0; cpustats && i < ctx.cpus; i++) { + for (i = 0; cpustats && i < ctx.cpu_num; i++) { printf("\r%12lu sec, %lu usec on CPU%d (%llu packets)\n", stats[i].tv_sec, stats[i].tv_usec, i, stats[i].tx_packets); @@ -1355,7 +1382,7 @@ int main(int argc, char **argv) thread_out: xunlockme(); - destroy_shared_var(stats, ctx.cpus); + destroy_shared_var(stats, ctx.cpu_num); if (dev_io_is_netdev(ctx.dev_out) && set_irq_aff) device_restore_irq_affinity_list(); |