summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--trafgen.c25
-rw-r--r--trafgen_conf.h2
-rw-r--r--trafgen_dev.c48
-rw-r--r--trafgen_dev.h12
-rw-r--r--trafgen_parser.y6
5 files changed, 49 insertions, 44 deletions
diff --git a/trafgen.c b/trafgen.c
index 207b680..97ac046 100644
--- a/trafgen.c
+++ b/trafgen.c
@@ -684,7 +684,7 @@ static void xmit_slowpath_or_die(struct ctx *ctx, unsigned int cpu, unsigned lon
while (likely(sigint == 0 && num > 0 && plen > 0)) {
packet_apply_dyn_elements(i);
retry:
- ret = dev_io_write(ctx->dev_out, packets[i].payload, packets[i].len);
+ ret = dev_io_write(ctx->dev_out, &packets[i]);
if (unlikely(ret < 0)) {
if (errno == ENOBUFS) {
sched_yield();
@@ -937,27 +937,10 @@ static void xmit_packet_precheck(struct ctx *ctx, unsigned int cpu)
static void pcap_load_packets(struct dev_io *dev)
{
- struct timespec tstamp;
- size_t buf_len;
- uint8_t *buf;
- int pkt_len;
+ struct packet *pkt;
- buf_len = round_up(1024 * 1024, RUNTIME_PAGE_SIZE);
- buf = xmalloc_aligned(buf_len, CO_CACHE_LINE_SIZE);
-
- while ((pkt_len = dev_io_read(dev, buf, buf_len, &tstamp)) > 0) {
- struct packet *pkt;
-
- realloc_packet();
-
- pkt = current_packet();
- pkt->len = pkt_len;
- pkt->payload = xzmalloc(pkt_len);
- memcpy(pkt->payload, buf, pkt_len);
- memcpy(&pkt->tstamp, &tstamp, sizeof(tstamp));
- }
-
- free(buf);
+ while ((pkt = dev_io_read(dev)) != 0)
+ /* nothing to do */;
}
static void main_loop(struct ctx *ctx, char *confname, bool slow,
diff --git a/trafgen_conf.h b/trafgen_conf.h
index 2af830d..7e922fe 100644
--- a/trafgen_conf.h
+++ b/trafgen_conf.h
@@ -80,6 +80,6 @@ extern void set_fill(uint8_t val, size_t len);
extern struct packet *current_packet(void);
extern uint32_t current_packet_id(void);
extern struct packet *packet_get(uint32_t id);
-extern void realloc_packet(void);
+extern struct packet *realloc_packet(void);
#endif /* TRAFGEN_CONF */
diff --git a/trafgen_dev.c b/trafgen_dev.c
index d7f1cd5..d613cce 100644
--- a/trafgen_dev.c
+++ b/trafgen_dev.c
@@ -19,6 +19,7 @@
#include "mac80211.h"
#include "linktype.h"
#include "trafgen_dev.h"
+#include "trafgen_conf.h"
static int dev_pcap_open(struct dev_io *dev, const char *name, enum dev_io_mode_t mode)
{
@@ -36,6 +37,8 @@ static int dev_pcap_open(struct dev_io *dev, const char *name, enum dev_io_mode_
}
dev->pcap_mode = PCAP_MODE_RD;
+ dev->buf_len = round_up(1024 * 1024, RUNTIME_PAGE_SIZE);
+ dev->buf = xmalloc_aligned(dev->buf_len, CO_CACHE_LINE_SIZE);
} else if (mode & DEV_IO_OUT) {
if (!strncmp("-", name, strlen("-"))) {
dev->fd = dup_or_die(fileno(stdout));
@@ -69,26 +72,35 @@ static int dev_pcap_open(struct dev_io *dev, const char *name, enum dev_io_mode_
return 0;
}
-static int dev_pcap_read(struct dev_io *dev, uint8_t *buf, size_t len,
- struct timespec *tstamp)
+static struct packet *dev_pcap_read(struct dev_io *dev)
{
+ size_t len = dev->buf_len;
+ uint8_t *buf = dev->buf;
pcap_pkthdr_t phdr;
+ struct packet *pkt;
size_t pkt_len;
if (dev->pcap_ops->read_pcap(dev->fd, &phdr, dev->pcap_magic, buf, len) <= 0)
- return -1;
+ return NULL;
pkt_len = pcap_get_length(&phdr, dev->pcap_magic);
if (!pkt_len)
- return -1;
+ return NULL;
- pcap_get_tstamp(&phdr, dev->pcap_magic, tstamp);
+ pkt = realloc_packet();
- return pkt_len;
+ pkt->len = pkt_len;
+ pkt->payload = xzmalloc(pkt_len);
+ memcpy(pkt->payload, buf, pkt_len);
+ pcap_get_tstamp(&phdr, dev->pcap_magic, &pkt->tstamp);
+
+ return pkt;
}
-static int dev_pcap_write(struct dev_io *dev, const uint8_t *buf, size_t len)
+static int dev_pcap_write(struct dev_io *dev, const struct packet *pkt)
{
+ uint8_t *buf = pkt->payload;
+ size_t len = pkt->len;
struct timeval time;
pcap_pkthdr_t phdr;
int ret;
@@ -130,8 +142,13 @@ static int dev_pcap_write(struct dev_io *dev, const uint8_t *buf, size_t len)
static void dev_pcap_close(struct dev_io *dev)
{
- if (dev->pcap_mode == PCAP_MODE_WR)
+ if (dev->pcap_mode == PCAP_MODE_WR) {
dev->pcap_ops->fsync_pcap(dev->fd);
+ } else if (dev->pcap_mode == PCAP_MODE_RD) {
+ free(dev->buf);
+ dev->buf_len = 0;
+ dev->buf = NULL;
+ }
if (dev->pcap_ops->prepare_close_pcap)
dev->pcap_ops->prepare_close_pcap(dev->fd, dev->pcap_mode);
@@ -155,13 +172,15 @@ static int dev_net_open(struct dev_io *dev, const char *name, enum dev_io_mode_t
return 0;
}
-static int dev_net_write(struct dev_io *dev, const uint8_t *buf, size_t len)
+static int dev_net_write(struct dev_io *dev, const struct packet *pkt)
{
struct sockaddr_ll saddr = {
.sll_family = PF_PACKET,
.sll_halen = ETH_ALEN,
.sll_ifindex = dev->ifindex,
};
+ uint8_t *buf = pkt->payload;
+ size_t len = pkt->len;
return sendto(dev->fd, buf, len, 0, (struct sockaddr *) &saddr, sizeof(saddr));
}
@@ -221,27 +240,26 @@ struct dev_io *dev_io_open(const char *name, enum dev_io_mode_t mode)
return dev;
};
-int dev_io_write(struct dev_io *dev, const uint8_t *buf, size_t len)
+int dev_io_write(struct dev_io *dev, const struct packet *pkt)
{
bug_on(!dev);
bug_on(!dev->ops);
if (dev->ops->write)
- return dev->ops->write(dev, buf, len);
+ return dev->ops->write(dev, pkt);
return 0;
}
-int dev_io_read(struct dev_io *dev, uint8_t *buf, size_t len,
- struct timespec *tstamp)
+struct packet *dev_io_read(struct dev_io *dev)
{
bug_on(!dev);
bug_on(!dev->ops);
if (dev->ops->read)
- return dev->ops->read(dev, buf, len, tstamp);
+ return dev->ops->read(dev);
- return 0;
+ return NULL;
}
const char *dev_io_name_get(struct dev_io *dev)
diff --git a/trafgen_dev.h b/trafgen_dev.h
index 686a577..6708eb8 100644
--- a/trafgen_dev.h
+++ b/trafgen_dev.h
@@ -12,6 +12,7 @@ enum dev_io_mode_t {
};
struct dev_io_ops;
+struct packet;
struct dev_io {
int fd;
@@ -23,6 +24,8 @@ struct dev_io {
uint32_t pcap_magic;
bool is_initialized;
enum pcap_mode pcap_mode;
+ size_t buf_len;
+ uint8_t *buf;
const struct pcap_file_ops *pcap_ops;
const struct dev_io_ops *ops;
@@ -30,16 +33,15 @@ struct dev_io {
struct dev_io_ops {
int(*open) (struct dev_io *dev, const char *name, enum dev_io_mode_t mode);
- int(*write) (struct dev_io *dev, const uint8_t *buf, size_t len);
- int(*read) (struct dev_io *dev, uint8_t *buf, size_t len, struct timespec *tstamp);
+ int(*write) (struct dev_io *dev, const struct packet *pkt);
+ struct packet *(*read) (struct dev_io *dev);
int(*set_link_type) (struct dev_io *dev, int link_type);
void(*close) (struct dev_io *dev);
};
extern struct dev_io *dev_io_open(const char *name, enum dev_io_mode_t mode);
-extern int dev_io_write(struct dev_io *dev, const uint8_t *buf, size_t len);
-extern int dev_io_read(struct dev_io *dev, uint8_t *buf, size_t len,
- struct timespec *tstamp);
+extern int dev_io_write(struct dev_io *dev, const struct packet *pkt);
+extern struct packet *dev_io_read(struct dev_io *dev);
extern int dev_io_ifindex_get(struct dev_io *dev);
extern int dev_io_fd_get(struct dev_io *dev);
extern const char *dev_io_name_get(struct dev_io *dev);
diff --git a/trafgen_parser.y b/trafgen_parser.y
index 656c4f6..74015b5 100644
--- a/trafgen_parser.y
+++ b/trafgen_parser.y
@@ -167,10 +167,10 @@ static inline void __setup_new_csum16(struct csum16 *s, off_t from, off_t to,
s->which = which;
}
-void realloc_packet(void)
+struct packet *realloc_packet(void)
{
if (test_ignore())
- return;
+ return NULL;
plen++;
packets = xrealloc(packets, plen * sizeof(*packets));
@@ -184,6 +184,8 @@ void realloc_packet(void)
__init_new_randomizer_slot(&packet_dyn[packetd_last]);
__init_new_csum_slot(&packet_dyn[packetd_last]);
__init_new_fields_slot(&packet_dyn[packetd_last]);
+
+ return &packets[packet_last];
}
struct packet *current_packet(void)