Skip to content

Commit e615e96

Browse files
committed
Merge pull request appneta#234 from appneta/Bug_#176_bandwidth_too_high
Bug appneta#176 bandwidth too high
2 parents 6157689 + f132dc7 commit e615e96

File tree

6 files changed

+88
-78
lines changed

6 files changed

+88
-78
lines changed

docs/CHANGELOG

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
--/--/---- Version 4.1.1-beta4
2+
- netmap reports impossibly hi capacity (#176)
23
- netmap optimizations (#93)
34

45
12/19/2015 Version 4.1.1-beta3
5-
- Option --unique-ip accepts --duration (#227)
6-
- RFC1624 incremental checksums (#225)
7-
- Option --duration performance optimizations (#223)
8-
- Correct company name in license (#217)
9-
- Compile and mult-arch cross-compile on ARM (#211)
10-
- Switch to wire speed after 30 minutes at 6 Gbps (#210)
11-
- Master doesn't compile on OS X 10.11 (#203)
12-
- Support for tcprewrite multiple IP CIDR (#199)
13-
- Option --loop=0 full wire wire speed after 1st pass (#172 #191)
14-
- Fix incorrect checksums after editing fragmented packets (#190)
15-
- Extra packets sent with -L option (#173)
16-
- Buffer overflow bug in tcpprep (#167)
6+
- Option --unique-ip accepts --duration (#227)
7+
- RFC1624 incremental checksums (#225)
8+
- Option --duration performance optimizations (#223)
9+
- Correct company name in license (#217)
10+
- Compile and mult-arch cross-compile on ARM (#211)
11+
- Switch to wire speed after 30 minutes at 6 Gbps (#210)
12+
- Master doesn't compile on OS X 10.11 (#203)
13+
- Support for tcprewrite multiple IP CIDR (#199)
14+
- Option --loop=0 full wire wire speed after 1st pass (#172 #191)
15+
- Fix incorrect checksums after editing fragmented packets (#190)
16+
- Extra packets sent with -L option (#173)
17+
- Buffer overflow bug in tcpprep (#167)
1718

1819
11/22/2015 Version 4.1.1-beta2
1920
- Tap device support for Linux and FreeBSD from Murat Demirten (#207)

src/common/netmap.c

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,6 @@ sendpacket_open_netmap(const char *device, char *errbuf, void *arg) {
202202
goto IFACENAME_INVALID;
203203
}
204204

205-
206205
/* get the version of the netmap driver. If < 0, driver is not installed */
207206
sp->netmap_version = get_netmap_version();
208207
if (sp->netmap_version < 0) {
@@ -535,17 +534,42 @@ void sendpacket_close_netmap(void *p)
535534
notice("done!");
536535
}
537536

537+
bool netmap_tx_queues_empty(void *p)
538+
{
539+
sendpacket_t *sp = p;
540+
struct netmap_ring *txring;
541+
542+
assert(sp);
543+
544+
txring = NETMAP_TXRING(sp->nm_if, sp->cur_tx_ring);
545+
while (NETMAP_TX_RING_EMPTY(txring)) {
546+
/* current ring is empty- go to next */
547+
++sp->cur_tx_ring;
548+
if (sp->cur_tx_ring > sp->last_tx_ring)
549+
/* last ring */
550+
return true;
551+
552+
txring = NETMAP_TXRING(sp->nm_if, sp->cur_tx_ring);
553+
}
554+
555+
/*
556+
* send TX interrupt signal
557+
*/
558+
ioctl(sp->handle.fd, NIOCTXSYNC, NULL);
559+
560+
return false;
561+
}
562+
538563
int sendpacket_send_netmap(void *p, const u_char *data, size_t len)
539564
{
540-
int retcode = 0;
541565
sendpacket_t *sp = p;
542566
struct netmap_ring *txring;
543567
struct netmap_slot *slot;
544568
char *pkt;
545569
uint32_t cur, avail;
546570

547571
if (sp->abort)
548-
return retcode;
572+
return 0;
549573

550574
txring = NETMAP_TXRING(sp->nm_if, sp->cur_tx_ring);
551575
while ((avail = nm_ring_space(txring)) == 0) {
@@ -559,8 +583,6 @@ int sendpacket_send_netmap(void *p, const u_char *data, size_t len)
559583
* so we have to reset to the first queue and
560584
* wait for available space
561585
*/
562-
struct pollfd pfd;
563-
564586
sp->cur_tx_ring = sp->first_tx_ring;
565587

566588
/* send TX interrupt signal
@@ -573,19 +595,8 @@ int sendpacket_send_netmap(void *p, const u_char *data, size_t len)
573595
*/
574596
ioctl(sp->handle.fd, NIOCTXSYNC, NULL);
575597

576-
if ((avail = nm_ring_space(txring)) == 0) {
577-
pfd.fd = sp->handle.fd;
578-
pfd.events = POLLOUT;
579-
pfd.revents = 0;
580-
if (poll(&pfd, 1, 1000) <= 0) {
581-
if (++sp->tx_timeouts == NETMAP_TX_TIMEOUT_SEC) {
582-
return -1;
583-
}
584-
return -2;
585-
}
586-
}
587-
588-
sp->tx_timeouts = 0;
598+
/* loop again */
599+
return -2;
589600
}
590601

591602
txring = NETMAP_TXRING(sp->nm_if, sp->cur_tx_ring);
@@ -616,7 +627,6 @@ int sendpacket_send_netmap(void *p, const u_char *data, size_t len)
616627
txring->avail--;
617628
#endif
618629
txring->cur = cur;
619-
retcode = len;
620630

621-
return retcode;
631+
return len;
622632
}

src/common/netmap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ typedef struct tcpr_nmreq nmreq_t;
126126
int get_netmap_version(void);
127127
void *sendpacket_open_netmap(const char *device, char *errbuf, void *arg);
128128
void sendpacket_close_netmap(void *p);
129+
bool netmap_tx_queues_empty(void *p);
129130
int sendpacket_send_netmap(void *p, const u_char *data, size_t len);
130131

131132
#endif /* NETMAP_H_ */

src/common/sendpacket.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ sendpacket(sendpacket_t *sp, const u_char *data, size_t len, struct pcap_pkthdr
450450
sendpacket_seterr(sp, "interface hung!!");
451451
} else if (retcode == -2) {
452452
/* this indicates that a retry was requested - this is not a failure */
453+
sp->retry_eagain ++;
453454
retcode = 0;
454455
goto TRY_SEND_AGAIN;
455456
}
@@ -574,13 +575,12 @@ sendpacket_getstat(sendpacket_t *sp, char *buf, size_t buf_size)
574575

575576
memset(buf, 0, buf_size);
576577
offset = snprintf(buf, buf_size, "Statistics for network device: %s\n"
577-
"\tAttempted packets: " COUNTER_SPEC "\n"
578578
"\tSuccessful packets: " COUNTER_SPEC "\n"
579579
"\tFailed packets: " COUNTER_SPEC "\n"
580580
"\tTruncated packets: " COUNTER_SPEC "\n"
581581
"\tRetried packets (ENOBUFS): " COUNTER_SPEC "\n"
582582
"\tRetried packets (EAGAIN): " COUNTER_SPEC "\n",
583-
sp->device, sp->attempt, sp->sent, sp->failed, sp->trunc_packets,
583+
sp->device, sp->sent, sp->failed, sp->trunc_packets,
584584
sp->retry_enobufs, sp->retry_eagain);
585585

586586
if (sp->flow_packets && offset > 0) {

src/send_packets.c

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
489489
bool unique_ip = options->unique_ip;
490490
bool preload = options->file_cache[idx].cached;
491491
bool top_speed = options->speed.mode == speed_topspeed;
492+
bool now_is_now = false;
492493

493494
start_us = TIMEVAL_TO_MICROSEC(&ctx->stats.start_time);
494495

@@ -509,7 +510,6 @@ send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
509510
*/
510511
while (!ctx->abort &&
511512
(pktdata = get_next_packet(ctx, pcap, &pkthdr, idx, prev_packet)) != NULL) {
512-
bool now_is_now;
513513

514514
packetnum++;
515515
#if defined TCPREPLAY || defined TCPREPLAY_EDIT
@@ -646,17 +646,30 @@ send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
646646
if ((end_us > 0 && TIMEVAL_TO_MICROSEC(&now) > end_us) ||
647647
/* ... or stop sending based on the limit -L? */
648648
(limit_send > 0 && ctx->stats.pkts_sent >= limit_send)) {
649-
if (!now_is_now) {
650-
gettimeofday(&now, NULL);
651-
memcpy(&ctx->stats.end_time, &now, sizeof(ctx->stats.end_time));
652-
}
653649
ctx->abort = true;
654650
}
655651
} /* while */
656652

657-
wake_send_queues(ctx->intf1, options);
658-
if (ctx->intf2)
659-
wake_send_queues(ctx->intf2, options);
653+
654+
#ifdef HAVE_NETMAP
655+
/* when completing test, wait until the last packet is sent */
656+
if (options->netmap && (ctx->abort || options->loop == 1)) {
657+
while (ctx->intf1 && !netmap_tx_queues_empty(ctx->intf1)) {
658+
gettimeofday(&now, NULL);
659+
now_is_now = true;
660+
}
661+
662+
while (ctx->intf2 && !netmap_tx_queues_empty(ctx->intf2)) {
663+
gettimeofday(&now, NULL);
664+
now_is_now = true;
665+
}
666+
}
667+
#endif /* HAVE_NETMAP */
668+
669+
if (!now_is_now)
670+
gettimeofday(&now, NULL);
671+
672+
memcpy(&ctx->stats.end_time, &now, sizeof(ctx->stats.end_time));
660673

661674
++ctx->iteration;
662675
}
@@ -688,6 +701,7 @@ send_dual_packets(tcpreplay_t *ctx, pcap_t *pcap1, int cache_file_idx1, pcap_t *
688701
COUNTER skip_length = 0;
689702
bool top_speed = options->speed.mode == speed_topspeed ||
690703
(options->speed.mode == speed_mbpsrate && !options->speed.speed);
704+
bool now_is_now = false;
691705

692706
start_us = TIMEVAL_TO_MICROSEC(&ctx->stats.start_time);
693707

@@ -714,7 +728,6 @@ send_dual_packets(tcpreplay_t *ctx, pcap_t *pcap1, int cache_file_idx1, pcap_t *
714728
*/
715729
while (!ctx->abort &&
716730
!(pktdata1 == NULL && pktdata2 == NULL)) {
717-
bool now_is_now;
718731

719732
packetnum++;
720733

@@ -881,16 +894,29 @@ send_dual_packets(tcpreplay_t *ctx, pcap_t *pcap1, int cache_file_idx1, pcap_t *
881894
if ((end_us > 0 && TIMEVAL_TO_MICROSEC(&now) > end_us) ||
882895
/* ... or stop sending based on the limit -L? */
883896
(limit_send > 0 && ctx->stats.pkts_sent >= limit_send)) {
884-
if (!now_is_now) {
885-
gettimeofday(&now, NULL);
886-
memcpy(&ctx->stats.end_time, &now, sizeof(ctx->stats.end_time));
887-
}
888897
ctx->abort = true;
889898
}
890899
} /* while */
891900

892-
wake_send_queues(ctx->intf1, options);
893-
wake_send_queues(ctx->intf2, options);
901+
#ifdef HAVE_NETMAP
902+
/* when completing test, wait until the last packet is sent */
903+
if (options->netmap && (ctx->abort || options->loop == 1)) {
904+
while (ctx->intf1 && !netmap_tx_queues_empty(ctx->intf1)) {
905+
gettimeofday(&now, NULL);
906+
now_is_now = true;
907+
}
908+
909+
while (ctx->intf2 && !netmap_tx_queues_empty(ctx->intf2)) {
910+
gettimeofday(&now, NULL);
911+
now_is_now = true;
912+
}
913+
}
914+
#endif /* HAVE_NETMAP */
915+
916+
if (!now_is_now)
917+
gettimeofday(&now, NULL);
918+
919+
memcpy(&ctx->stats.end_time, &now, sizeof(ctx->stats.end_time));
894920

895921
++ctx->iteration;
896922
}

src/tcpreplay_api.c

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -264,16 +264,6 @@ tcpreplay_post_args(tcpreplay_t *ctx, int argc)
264264

265265
if (HAVE_OPT(NETMAP)) {
266266
#ifdef HAVE_NETMAP
267-
if (HAVE_OPT(INTF2)) {
268-
tcpreplay_seterr(ctx, "%s", "multiple interfaces not supported in netmap mode");
269-
ret = -1;
270-
goto out;
271-
}
272-
if (HAVE_OPT(CACHEFILE)) {
273-
tcpreplay_seterr(ctx, "%s", "--cachefile option not supported in netmap mode");
274-
ret = -1;
275-
goto out;
276-
}
277267
options->netmap = 1;
278268
ctx->sp_type = SP_TYPE_NETMAP;
279269
#else
@@ -348,16 +338,6 @@ tcpreplay_post_args(tcpreplay_t *ctx, int argc)
348338
ret = -1;
349339
goto out;
350340
}
351-
if (HAVE_OPT(INTF2)) {
352-
tcpreplay_seterr(ctx, "%s", "multiple interfaces not supported in netmap mode");
353-
ret = -1;
354-
goto out;
355-
}
356-
if (HAVE_OPT(CACHEFILE)) {
357-
tcpreplay_seterr(ctx, "%s", "--cachefile option not supported in netmap mode");
358-
ret = -1;
359-
goto out;
360-
}
361341
options->netmap = 1;
362342
ctx->sp_type = SP_TYPE_NETMAP;
363343
#else
@@ -424,14 +404,6 @@ tcpreplay_post_args(tcpreplay_t *ctx, int argc)
424404
}
425405
#endif
426406

427-
#ifdef HAVE_NETMAP
428-
if (!strncmp(intname, "netmap:", 7) || !strncmp(intname, "vale:", 5)) {
429-
tcpreplay_seterr(ctx, "netmap/vale interface aliases not allowed for interface 2: %s", OPT_ARG(INTF2));
430-
ret = -1;
431-
goto out;
432-
}
433-
#endif
434-
435407
options->intf2_name = safe_strdup(intname);
436408

437409
/* open interface for writing */
@@ -963,7 +935,7 @@ const struct timeval *
963935
tcpreplay_get_start_time(tcpreplay_t *ctx)
964936
{
965937
assert(ctx);
966-
memcpy(&ctx->static_stats.start_time, &ctx->stats.end_time, sizeof(ctx->stats.end_time));
938+
memcpy(&ctx->static_stats.start_time, &ctx->stats.start_time, sizeof(ctx->stats.start_time));
967939
return &ctx->static_stats.start_time;
968940
}
969941

0 commit comments

Comments
 (0)