Packet generator: preserve pcap file timestamps

Set vnet_buffer2(b0)->pg_replay_timestamp, for use when desired.

Fix a memory leak in pg_stream_free(...), which wasn't freeing the
replay packet templates.

Change-Id: I01822a9e91a52de4774d2b95cf0c2ee254a915e9
Signed-off-by: Dave Barach <dave@barachs.net>
diff --git a/src/vnet/buffer.h b/src/vnet/buffer.h
index dfb05ac..86bee6f 100644
--- a/src/vnet/buffer.h
+++ b/src/vnet/buffer.h
@@ -403,6 +403,11 @@
       u16 *trajectory_trace;
 #endif
     };
+    struct
+    {
+      u64 pad[1];
+      u64 pg_replay_timestamp;
+    };
     u32 unused[10];
   };
 } vnet_buffer_opaque2_t;
diff --git a/src/vnet/pg/cli.c b/src/vnet/pg/cli.c
index 3c249a7..745b9b2 100644
--- a/src/vnet/pg/cli.c
+++ b/src/vnet/pg/cli.c
@@ -228,6 +228,7 @@
   pm.file_name = file_name;
   error = pcap_read (&pm);
   s->replay_packet_templates = pm.packets_read;
+  s->replay_packet_timestamps = pm.timestamps;
   s->min_packet_bytes = pm.min_packet_bytes;
   s->max_packet_bytes = pm.max_packet_bytes;
   s->buffer_bytes = pm.max_packet_bytes;
diff --git a/src/vnet/pg/input.c b/src/vnet/pg/input.c
index a743082..a9510b7 100644
--- a/src/vnet/pg/input.c
+++ b/src/vnet/pg/input.c
@@ -1083,6 +1083,7 @@
       vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
 
       d0 = vec_elt (s->replay_packet_templates, i);
+      vnet_buffer2 (b0)->pg_replay_timestamp = s->replay_packet_timestamps[i];
 
       n0 = n_data;
       if (data_offset + n_data >= vec_len (d0))
diff --git a/src/vnet/pg/pg.h b/src/vnet/pg/pg.h
index 20852ba..b2b5798 100644
--- a/src/vnet/pg/pg.h
+++ b/src/vnet/pg/pg.h
@@ -169,6 +169,7 @@
   pg_buffer_index_t *buffer_indices;
 
   u8 **replay_packet_templates;
+  u64 *replay_packet_timestamps;
   u32 current_replay_packet_index;
 } pg_stream_t;
 
@@ -192,6 +193,7 @@
 always_inline void
 pg_stream_free (pg_stream_t * s)
 {
+  int i;
   pg_edit_group_t *g;
   pg_edit_t *e;
   vec_foreach (e, s->non_fixed_edits) pg_edit_free (e);
@@ -201,6 +203,10 @@
   vec_free (s->fixed_packet_data);
   vec_free (s->fixed_packet_data_mask);
   vec_free (s->name);
+  for (i = 0; i < vec_len (s->replay_packet_templates); i++)
+    vec_free (s->replay_packet_templates[i]);
+  vec_free (s->replay_packet_templates);
+  vec_free (s->replay_packet_timestamps);
 
   {
     pg_buffer_index_t *bi;
diff --git a/src/vnet/unix/pcap.c b/src/vnet/unix/pcap.c
index 0832b16..473430a 100644
--- a/src/vnet/unix/pcap.c
+++ b/src/vnet/unix/pcap.c
@@ -216,6 +216,9 @@
   while ((n = read (fd, &ph, sizeof (ph))) != 0)
     {
       u8 *data;
+      u64 timestamp;
+      u32 timestamp_sec;
+      u32 timestamp_usec;
 
       if (need_swap)
 	{
@@ -242,7 +245,11 @@
 	    clib_max (pm->max_packet_bytes, ph.n_bytes_in_packet);
 	}
 
+      timestamp_sec = ph.time_in_sec;
+      timestamp_usec = ph.time_in_usec;
+      timestamp = ((u64) timestamp_sec) * 1000000 + (u64) timestamp_usec;
       vec_add1 (pm->packets_read, data);
+      vec_add1 (pm->timestamps, timestamp);
     }
 
 done:
diff --git a/src/vnet/unix/pcap.h b/src/vnet/unix/pcap.h
index e3fac45..7d55db3 100644
--- a/src/vnet/unix/pcap.h
+++ b/src/vnet/unix/pcap.h
@@ -151,6 +151,9 @@
   /** Packets read from file. */
   u8 **packets_read;
 
+  /** Timestamps */
+  u64 *timestamps;
+
   /** Min/Max Packet bytes */
   u32 min_packet_bytes, max_packet_bytes;
 } pcap_main_t;