pg: fix stream pg interface

When an other interface is specified to generate packets from, we should
bind its sw_if_index to the pg interface to use.
Fix if_index_by_sw_if_index variable name, and force to specify a pg
interface to source traffic from.

Type: fix
Change-Id: Ib3e6dca92774b307def82926fc09945b7998267d
Signed-off-by: Maxime Peim <mpeim@cisco.com>
diff --git a/src/vnet/pg/cli.c b/src/vnet/pg/cli.c
index ac22509..f289bec 100644
--- a/src/vnet/pg/cli.c
+++ b/src/vnet/pg/cli.c
@@ -685,7 +685,7 @@
 {
   pg_main_t *pg = &pg_main;
   unformat_input_t _line_input, *line_input = &_line_input;
-  u32 if_id, gso_enabled = 0, gso_size = 0, coalesce_enabled = 0;
+  u32 if_id = ~0, gso_enabled = 0, gso_size = 0, coalesce_enabled = 0;
   clib_error_t *error = NULL;
   pg_interface_mode_t mode = PG_MODE_ETHERNET;
 
diff --git a/src/vnet/pg/input.c b/src/vnet/pg/input.c
index 6f38ed0..f376c74 100644
--- a/src/vnet/pg/input.c
+++ b/src/vnet/pg/input.c
@@ -1639,8 +1639,8 @@
   pg_interface_t *pi;
   int i;
 
-  pi = pool_elt_at_index (pg->interfaces,
-			  pg->if_id_by_sw_if_index[s->sw_if_index[VLIB_RX]]);
+  pi = pool_elt_at_index (
+    pg->interfaces, pg->if_index_by_sw_if_index[s->sw_if_index[VLIB_RX]]);
   bi0 = s->buffer_indices;
 
   n_packets_in_fifo = pg_stream_fill (pg, s, n_packets_to_generate);
@@ -1864,9 +1864,9 @@
       pg_interface_t *pi;
       mac_address_t in;
 
-      pi = pool_elt_at_index
-	(pg->interfaces,
-	 pg->if_id_by_sw_if_index[vnet_buffer (b[0])->sw_if_index[VLIB_RX]]);
+      pi = pool_elt_at_index (
+	pg->interfaces,
+	pg->if_index_by_sw_if_index[vnet_buffer (b[0])->sw_if_index[VLIB_RX]]);
       eth = vlib_buffer_get_current (b[0]);
 
       mac_address_from_bytes (&in, eth->dst_address);
diff --git a/src/vnet/pg/pg.h b/src/vnet/pg/pg.h
index e69ee64..6d5b25b 100644
--- a/src/vnet/pg/pg.h
+++ b/src/vnet/pg/pg.h
@@ -349,7 +349,7 @@
   /* Pool of interfaces. */
   pg_interface_t *interfaces;
   uword *if_index_by_if_id;
-  uword *if_id_by_sw_if_index;
+  uword *if_index_by_sw_if_index;
 
   /* Vector of buffer indices for use in pg_stream_fill_replay, per thread */
   u32 **replay_buffers_by_thread;
@@ -383,7 +383,7 @@
 					   u32 tx_node_index);
 
 /* Find/create free packet-generator interface index. */
-u32 pg_interface_add_or_get (pg_main_t *pg, uword stream_index, u8 gso_enabled,
+u32 pg_interface_add_or_get (pg_main_t *pg, u32 stream_index, u8 gso_enabled,
 			     u32 gso_size, u8 coalesce_enabled,
 			     pg_interface_mode_t mode);
 
diff --git a/src/vnet/pg/stream.c b/src/vnet/pg/stream.c
index 112cc09..d68551b 100644
--- a/src/vnet/pg/stream.c
+++ b/src/vnet/pg/stream.c
@@ -249,7 +249,7 @@
 };
 
 u32
-pg_interface_add_or_get (pg_main_t *pg, uword if_id, u8 gso_enabled,
+pg_interface_add_or_get (pg_main_t *pg, u32 if_id, u8 gso_enabled,
 			 u32 gso_size, u8 coalesce_enabled,
 			 pg_interface_mode_t mode)
 {
@@ -315,8 +315,8 @@
 
       hash_set (pg->if_index_by_if_id, if_id, i);
 
-      vec_validate (pg->if_id_by_sw_if_index, hi->sw_if_index);
-      pg->if_id_by_sw_if_index[hi->sw_if_index] = i;
+      vec_validate (pg->if_index_by_sw_if_index, hi->sw_if_index);
+      pg->if_index_by_sw_if_index[hi->sw_if_index] = i;
 
       if (vlib_num_workers ())
 	{
@@ -560,6 +560,11 @@
        */
       s->sw_if_index[VLIB_RX] = pi->sw_if_index;
     }
+  else if (vec_len (pg->if_index_by_sw_if_index) <= s->sw_if_index[VLIB_RX])
+    {
+      vec_validate (pg->if_index_by_sw_if_index, s->sw_if_index[VLIB_RX]);
+      pg->if_index_by_sw_if_index[s->sw_if_index[VLIB_RX]] = s->pg_if_index;
+    }
 
   /* Connect the graph. */
   s->next_index = vlib_node_add_next (vm, device_input_node.index,