Skip to content

Commit

Permalink
Merge pull request appneta#234 from appneta/Bug_#176_bandwidth_too_high
Browse files Browse the repository at this point in the history
Bug appneta#176 bandwidth too high
  • Loading branch information
fklassen committed Dec 29, 2015
2 parents 6157689 + f132dc7 commit e615e96
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 78 deletions.
25 changes: 13 additions & 12 deletions docs/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
--/--/---- Version 4.1.1-beta4
- netmap reports impossibly hi capacity (#176)
- netmap optimizations (#93)

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

11/22/2015 Version 4.1.1-beta2
- Tap device support for Linux and FreeBSD from Murat Demirten (#207)
Expand Down
50 changes: 30 additions & 20 deletions src/common/netmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ sendpacket_open_netmap(const char *device, char *errbuf, void *arg) {
goto IFACENAME_INVALID;
}


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

bool netmap_tx_queues_empty(void *p)
{
sendpacket_t *sp = p;
struct netmap_ring *txring;

assert(sp);

txring = NETMAP_TXRING(sp->nm_if, sp->cur_tx_ring);
while (NETMAP_TX_RING_EMPTY(txring)) {
/* current ring is empty- go to next */
++sp->cur_tx_ring;
if (sp->cur_tx_ring > sp->last_tx_ring)
/* last ring */
return true;

txring = NETMAP_TXRING(sp->nm_if, sp->cur_tx_ring);
}

/*
* send TX interrupt signal
*/
ioctl(sp->handle.fd, NIOCTXSYNC, NULL);

return false;
}

int sendpacket_send_netmap(void *p, const u_char *data, size_t len)
{
int retcode = 0;
sendpacket_t *sp = p;
struct netmap_ring *txring;
struct netmap_slot *slot;
char *pkt;
uint32_t cur, avail;

if (sp->abort)
return retcode;
return 0;

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

sp->cur_tx_ring = sp->first_tx_ring;

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

if ((avail = nm_ring_space(txring)) == 0) {
pfd.fd = sp->handle.fd;
pfd.events = POLLOUT;
pfd.revents = 0;
if (poll(&pfd, 1, 1000) <= 0) {
if (++sp->tx_timeouts == NETMAP_TX_TIMEOUT_SEC) {
return -1;
}
return -2;
}
}

sp->tx_timeouts = 0;
/* loop again */
return -2;
}

txring = NETMAP_TXRING(sp->nm_if, sp->cur_tx_ring);
Expand Down Expand Up @@ -616,7 +627,6 @@ int sendpacket_send_netmap(void *p, const u_char *data, size_t len)
txring->avail--;
#endif
txring->cur = cur;
retcode = len;

return retcode;
return len;
}
1 change: 1 addition & 0 deletions src/common/netmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ typedef struct tcpr_nmreq nmreq_t;
int get_netmap_version(void);
void *sendpacket_open_netmap(const char *device, char *errbuf, void *arg);
void sendpacket_close_netmap(void *p);
bool netmap_tx_queues_empty(void *p);
int sendpacket_send_netmap(void *p, const u_char *data, size_t len);

#endif /* NETMAP_H_ */
4 changes: 2 additions & 2 deletions src/common/sendpacket.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ sendpacket(sendpacket_t *sp, const u_char *data, size_t len, struct pcap_pkthdr
sendpacket_seterr(sp, "interface hung!!");
} else if (retcode == -2) {
/* this indicates that a retry was requested - this is not a failure */
sp->retry_eagain ++;
retcode = 0;
goto TRY_SEND_AGAIN;
}
Expand Down Expand Up @@ -574,13 +575,12 @@ sendpacket_getstat(sendpacket_t *sp, char *buf, size_t buf_size)

memset(buf, 0, buf_size);
offset = snprintf(buf, buf_size, "Statistics for network device: %s\n"
"\tAttempted packets: " COUNTER_SPEC "\n"
"\tSuccessful packets: " COUNTER_SPEC "\n"
"\tFailed packets: " COUNTER_SPEC "\n"
"\tTruncated packets: " COUNTER_SPEC "\n"
"\tRetried packets (ENOBUFS): " COUNTER_SPEC "\n"
"\tRetried packets (EAGAIN): " COUNTER_SPEC "\n",
sp->device, sp->attempt, sp->sent, sp->failed, sp->trunc_packets,
sp->device, sp->sent, sp->failed, sp->trunc_packets,
sp->retry_enobufs, sp->retry_eagain);

if (sp->flow_packets && offset > 0) {
Expand Down
56 changes: 41 additions & 15 deletions src/send_packets.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
bool unique_ip = options->unique_ip;
bool preload = options->file_cache[idx].cached;
bool top_speed = options->speed.mode == speed_topspeed;
bool now_is_now = false;

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

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

packetnum++;
#if defined TCPREPLAY || defined TCPREPLAY_EDIT
Expand Down Expand Up @@ -646,17 +646,30 @@ send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
if ((end_us > 0 && TIMEVAL_TO_MICROSEC(&now) > end_us) ||
/* ... or stop sending based on the limit -L? */
(limit_send > 0 && ctx->stats.pkts_sent >= limit_send)) {
if (!now_is_now) {
gettimeofday(&now, NULL);
memcpy(&ctx->stats.end_time, &now, sizeof(ctx->stats.end_time));
}
ctx->abort = true;
}
} /* while */

wake_send_queues(ctx->intf1, options);
if (ctx->intf2)
wake_send_queues(ctx->intf2, options);

#ifdef HAVE_NETMAP
/* when completing test, wait until the last packet is sent */
if (options->netmap && (ctx->abort || options->loop == 1)) {
while (ctx->intf1 && !netmap_tx_queues_empty(ctx->intf1)) {
gettimeofday(&now, NULL);
now_is_now = true;
}

while (ctx->intf2 && !netmap_tx_queues_empty(ctx->intf2)) {
gettimeofday(&now, NULL);
now_is_now = true;
}
}
#endif /* HAVE_NETMAP */

if (!now_is_now)
gettimeofday(&now, NULL);

memcpy(&ctx->stats.end_time, &now, sizeof(ctx->stats.end_time));

++ctx->iteration;
}
Expand Down Expand Up @@ -688,6 +701,7 @@ send_dual_packets(tcpreplay_t *ctx, pcap_t *pcap1, int cache_file_idx1, pcap_t *
COUNTER skip_length = 0;
bool top_speed = options->speed.mode == speed_topspeed ||
(options->speed.mode == speed_mbpsrate && !options->speed.speed);
bool now_is_now = false;

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

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

packetnum++;

Expand Down Expand Up @@ -881,16 +894,29 @@ send_dual_packets(tcpreplay_t *ctx, pcap_t *pcap1, int cache_file_idx1, pcap_t *
if ((end_us > 0 && TIMEVAL_TO_MICROSEC(&now) > end_us) ||
/* ... or stop sending based on the limit -L? */
(limit_send > 0 && ctx->stats.pkts_sent >= limit_send)) {
if (!now_is_now) {
gettimeofday(&now, NULL);
memcpy(&ctx->stats.end_time, &now, sizeof(ctx->stats.end_time));
}
ctx->abort = true;
}
} /* while */

wake_send_queues(ctx->intf1, options);
wake_send_queues(ctx->intf2, options);
#ifdef HAVE_NETMAP
/* when completing test, wait until the last packet is sent */
if (options->netmap && (ctx->abort || options->loop == 1)) {
while (ctx->intf1 && !netmap_tx_queues_empty(ctx->intf1)) {
gettimeofday(&now, NULL);
now_is_now = true;
}

while (ctx->intf2 && !netmap_tx_queues_empty(ctx->intf2)) {
gettimeofday(&now, NULL);
now_is_now = true;
}
}
#endif /* HAVE_NETMAP */

if (!now_is_now)
gettimeofday(&now, NULL);

memcpy(&ctx->stats.end_time, &now, sizeof(ctx->stats.end_time));

++ctx->iteration;
}
Expand Down
30 changes: 1 addition & 29 deletions src/tcpreplay_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,16 +264,6 @@ tcpreplay_post_args(tcpreplay_t *ctx, int argc)

if (HAVE_OPT(NETMAP)) {
#ifdef HAVE_NETMAP
if (HAVE_OPT(INTF2)) {
tcpreplay_seterr(ctx, "%s", "multiple interfaces not supported in netmap mode");
ret = -1;
goto out;
}
if (HAVE_OPT(CACHEFILE)) {
tcpreplay_seterr(ctx, "%s", "--cachefile option not supported in netmap mode");
ret = -1;
goto out;
}
options->netmap = 1;
ctx->sp_type = SP_TYPE_NETMAP;
#else
Expand Down Expand Up @@ -348,16 +338,6 @@ tcpreplay_post_args(tcpreplay_t *ctx, int argc)
ret = -1;
goto out;
}
if (HAVE_OPT(INTF2)) {
tcpreplay_seterr(ctx, "%s", "multiple interfaces not supported in netmap mode");
ret = -1;
goto out;
}
if (HAVE_OPT(CACHEFILE)) {
tcpreplay_seterr(ctx, "%s", "--cachefile option not supported in netmap mode");
ret = -1;
goto out;
}
options->netmap = 1;
ctx->sp_type = SP_TYPE_NETMAP;
#else
Expand Down Expand Up @@ -424,14 +404,6 @@ tcpreplay_post_args(tcpreplay_t *ctx, int argc)
}
#endif

#ifdef HAVE_NETMAP
if (!strncmp(intname, "netmap:", 7) || !strncmp(intname, "vale:", 5)) {
tcpreplay_seterr(ctx, "netmap/vale interface aliases not allowed for interface 2: %s", OPT_ARG(INTF2));
ret = -1;
goto out;
}
#endif

options->intf2_name = safe_strdup(intname);

/* open interface for writing */
Expand Down Expand Up @@ -963,7 +935,7 @@ const struct timeval *
tcpreplay_get_start_time(tcpreplay_t *ctx)
{
assert(ctx);
memcpy(&ctx->static_stats.start_time, &ctx->stats.end_time, sizeof(ctx->stats.end_time));
memcpy(&ctx->static_stats.start_time, &ctx->stats.start_time, sizeof(ctx->stats.start_time));
return &ctx->static_stats.start_time;
}

Expand Down

0 comments on commit e615e96

Please sign in to comment.