Vhost multi-q support
[vpp.git] / vnet / vnet / devices / dpdk / device.c
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <vnet/vnet.h>
16 #include <vppinfra/vec.h>
17 #include <vppinfra/format.h>
18 #include <vlib/unix/cj.h>
19 #include <assert.h>
20
21 #include <vnet/ethernet/ethernet.h>
22 #include <vnet/devices/dpdk/dpdk.h>
23
24 #include "dpdk_priv.h"
25 #include <vppinfra/error.h>
26
27 #define foreach_dpdk_tx_func_error                      \
28   _(BAD_RETVAL, "DPDK tx function returned an error")   \
29   _(RING_FULL, "Tx packet drops (ring full)")           \
30   _(PKT_DROP, "Tx packet drops (dpdk tx failure)")      \
31   _(REPL_FAIL, "Tx packet drops (replication failure)")
32
33 typedef enum {
34 #define _(f,s) DPDK_TX_FUNC_ERROR_##f,
35   foreach_dpdk_tx_func_error
36 #undef _
37   DPDK_TX_FUNC_N_ERROR,
38 } dpdk_tx_func_error_t;
39
40 static char * dpdk_tx_func_error_strings[] = {
41 #define _(n,s) s,
42     foreach_dpdk_tx_func_error
43 #undef _
44 };
45
46 static struct rte_mbuf * dpdk_replicate_packet_mb (vlib_buffer_t * b)
47 {
48   vlib_main_t * vm = vlib_get_main();
49   vlib_buffer_main_t * bm = vm->buffer_main;
50   struct rte_mbuf * first_mb = 0, * new_mb, * pkt_mb, ** prev_mb_next = 0;
51   u8 nb_segs, nb_segs_left;
52   u32 copy_bytes;
53   unsigned socket_id = rte_socket_id();
54
55   ASSERT (bm->pktmbuf_pools[socket_id]);
56   pkt_mb = ((struct rte_mbuf *)b)-1;
57   nb_segs = pkt_mb->nb_segs;
58   for (nb_segs_left = nb_segs; nb_segs_left; nb_segs_left--)
59     {
60       if (PREDICT_FALSE(pkt_mb == 0))
61         {
62           clib_warning ("Missing %d mbuf chain segment(s):   "
63                         "(nb_segs = %d, nb_segs_left = %d)!",
64                         nb_segs - nb_segs_left, nb_segs, nb_segs_left);
65           if (first_mb)
66             rte_pktmbuf_free(first_mb);
67           return NULL;
68         }
69       new_mb = rte_pktmbuf_alloc (bm->pktmbuf_pools[socket_id]);
70       if (PREDICT_FALSE(new_mb == 0))
71         {
72           if (first_mb)
73             rte_pktmbuf_free(first_mb);
74           return NULL;
75         }
76       
77       /*
78        * Copy packet info into 1st segment.
79        */
80       if (first_mb == 0)
81         {
82           first_mb = new_mb;
83           rte_pktmbuf_pkt_len (first_mb) = pkt_mb->pkt_len;
84           first_mb->nb_segs = pkt_mb->nb_segs;
85           first_mb->port = pkt_mb->port;
86 #ifdef DAW_FIXME // TX Offload support TBD
87           first_mb->vlan_macip = pkt_mb->vlan_macip;
88           first_mb->hash = pkt_mb->hash;
89           first_mb->ol_flags = pkt_mb->ol_flags
90 #endif
91         }
92       else
93         {
94           ASSERT(prev_mb_next != 0);
95           *prev_mb_next = new_mb;
96         }
97       
98       /*
99        * Copy packet segment data into new mbuf segment.
100        */
101       rte_pktmbuf_data_len (new_mb) = pkt_mb->data_len;
102       copy_bytes = pkt_mb->data_len + RTE_PKTMBUF_HEADROOM;
103       ASSERT(copy_bytes <= pkt_mb->buf_len);
104       memcpy(new_mb->buf_addr, pkt_mb->buf_addr, copy_bytes);
105
106       prev_mb_next = &new_mb->next;
107       pkt_mb = pkt_mb->next;
108     }
109
110   ASSERT(pkt_mb == 0);
111   __rte_mbuf_sanity_check(first_mb, 1);
112
113   return first_mb;
114 }
115
116 typedef struct {
117   u32 buffer_index;
118   u16 device_index;
119   u8 queue_index;
120   struct rte_mbuf mb;
121   /* Copy of VLIB buffer; packet data stored in pre_data. */
122   vlib_buffer_t buffer;
123 } dpdk_tx_dma_trace_t;
124
125 static void
126 dpdk_tx_trace_buffer (dpdk_main_t * dm,
127                       vlib_node_runtime_t * node,
128                       dpdk_device_t * xd,
129                       u16 queue_id,
130                       u32 buffer_index,
131                       vlib_buffer_t * buffer)
132 {
133   vlib_main_t * vm = vlib_get_main();
134   dpdk_tx_dma_trace_t * t0;
135   struct rte_mbuf * mb;
136
137   mb = ((struct rte_mbuf *)buffer)-1;
138
139   t0 = vlib_add_trace (vm, node, buffer, sizeof (t0[0]));
140   t0->queue_index = queue_id;
141   t0->device_index = xd->device_index;
142   t0->buffer_index = buffer_index;
143   memcpy (&t0->mb, mb, sizeof (t0->mb));
144   memcpy (&t0->buffer, buffer, sizeof (buffer[0]) - sizeof (buffer->pre_data));
145   memcpy (t0->buffer.pre_data, buffer->data + buffer->current_data,
146           sizeof (t0->buffer.pre_data));
147 }
148
149 /*
150  * This function calls the dpdk's tx_burst function to transmit the packets
151  * on the tx_vector. It manages a lock per-device if the device does not
152  * support multiple queues. It returns the number of packets untransmitted 
153  * on the tx_vector. If all packets are transmitted (the normal case), the 
154  * function returns 0.
155  * 
156  * The tx_burst function may not be able to transmit all packets because the 
157  * dpdk ring is full. If a flowcontrol callback function has been configured
158  * then the function simply returns. If no callback has been configured, the 
159  * function will retry calling tx_burst with the remaining packets. This will 
160  * continue until all packets are transmitted or tx_burst indicates no packets
161  * could be transmitted. (The caller can drop the remaining packets.)
162  *
163  * The function assumes there is at least one packet on the tx_vector.
164  */
165 static_always_inline
166 u32 tx_burst_vector_internal (vlib_main_t * vm, 
167                               dpdk_device_t * xd,
168                               struct rte_mbuf ** tx_vector)
169 {
170   dpdk_main_t * dm = &dpdk_main;
171   u32 n_packets;
172   u32 tx_head;
173   u32 tx_tail;
174   u32 n_retry;
175   int rv;
176   int queue_id;
177   tx_ring_hdr_t *ring;
178
179   ring = vec_header(tx_vector, sizeof(*ring));
180
181   n_packets = ring->tx_head - ring->tx_tail;
182
183   tx_head = ring->tx_head % DPDK_TX_RING_SIZE;
184
185   /*
186    * Ensure rte_eth_tx_burst is not called with 0 packets, which can lead to
187    * unpredictable results.
188    */
189   ASSERT(n_packets > 0);
190
191   /*
192    * Check for tx_vector overflow. If this fails it is a system configuration
193    * error. The ring should be sized big enough to handle the largest un-flowed
194    * off burst from a traffic manager. A larger size also helps performance
195    * a bit because it decreases the probability of having to issue two tx_burst
196    * calls due to a ring wrap.
197    */
198   ASSERT(n_packets < DPDK_TX_RING_SIZE);
199
200   /*
201    * If there is no flowcontrol callback, there is only temporary buffering
202    * on the tx_vector and so the tail should always be 0.
203    */
204   ASSERT(dm->flowcontrol_callback || ring->tx_tail == 0);
205
206   /*
207    * If there is a flowcontrol callback, don't retry any incomplete tx_bursts. 
208    * Apply backpressure instead. If there is no callback, keep retrying until
209    * a tx_burst sends no packets. n_retry of 255 essentially means no retry 
210    * limit.
211    */
212   n_retry = dm->flowcontrol_callback ? 0 : 255;
213
214   queue_id = vm->cpu_index;
215
216   do {
217       /* start the burst at the tail */
218       tx_tail = ring->tx_tail % DPDK_TX_RING_SIZE;
219
220       /* 
221        * This device only supports one TX queue,
222        * and we're running multi-threaded...
223        */
224       if (PREDICT_FALSE(xd->lockp != 0))
225         {
226           queue_id = 0;
227           while (__sync_lock_test_and_set (xd->lockp, 1))
228             /* zzzz */;
229         }
230
231       if (PREDICT_TRUE(xd->dev_type == VNET_DPDK_DEV_ETH)) 
232         {
233           if (PREDICT_TRUE(tx_head > tx_tail)) 
234             {
235               /* no wrap, transmit in one burst */
236               rv = rte_eth_tx_burst(xd->device_index, 
237                                     (uint16_t) queue_id,
238                                     &tx_vector[tx_tail], 
239                                     (uint16_t) (tx_head-tx_tail));
240             }
241           else 
242             {
243               /* 
244                * This can only happen if there is a flowcontrol callback.
245                * We need to split the transmit into two calls: one for
246                * the packets up to the wrap point, and one to continue
247                * at the start of the ring.
248                * Transmit pkts up to the wrap point.
249                */
250               rv = rte_eth_tx_burst(xd->device_index, 
251                                     (uint16_t) queue_id,
252                                     &tx_vector[tx_tail], 
253                                     (uint16_t) (DPDK_TX_RING_SIZE - tx_tail));
254
255               /* 
256                * If we transmitted everything we wanted, then allow 1 retry 
257                * so we can try to transmit the rest. If we didn't transmit
258                * everything, stop now.
259                */
260               n_retry = (rv == DPDK_TX_RING_SIZE - tx_tail) ? 1 : 0;
261             }
262         } 
263       else if (xd->dev_type == VNET_DPDK_DEV_VHOST_USER)
264         {
265           u32 offset = 0;
266 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0)
267           if (PREDICT_TRUE(xd->lockp == NULL)) {
268               dpdk_device_and_queue_t * dq;
269               vec_foreach (dq, dm->devices_by_cpu[vm->cpu_index])
270               {
271                 if (xd->device_index == dq->device)
272                     break; 
273               }
274               assert (dq);
275               offset = dq->queue_id * VIRTIO_QNUM;
276           } else {
277               offset = queue_id * VIRTIO_QNUM;
278           }
279 #endif
280           if (PREDICT_TRUE(tx_head > tx_tail)) 
281             {
282               /* no wrap, transmit in one burst */
283               rv = rte_vhost_enqueue_burst(&xd->vu_vhost_dev, offset + VIRTIO_RXQ,
284                                            &tx_vector[tx_tail],
285                                            (uint16_t) (tx_head-tx_tail));
286               if (PREDICT_TRUE(rv > 0))
287                 {
288                   if (dpdk_vhost_user_want_interrupt(xd, offset + VIRTIO_RXQ)) {
289                     dpdk_vu_vring *vring = &(xd->vu_intf->vrings[offset + VIRTIO_RXQ]);
290                     vring->n_since_last_int += rv;
291
292                     f64 now = vlib_time_now (vm);
293                     if (vring->int_deadline < now ||
294                         vring->n_since_last_int > dm->vhost_coalesce_frames)
295                       dpdk_vhost_user_send_interrupt(vm, xd, offset + VIRTIO_RXQ);
296                   }
297
298                   int c = rv;
299                   while(c--)
300                     rte_pktmbuf_free (tx_vector[tx_tail+c]);
301                 }
302             }
303           else
304             {
305               /*
306                * If we transmitted everything we wanted, then allow 1 retry
307                * so we can try to transmit the rest. If we didn't transmit
308                * everything, stop now.
309                */
310               rv = rte_vhost_enqueue_burst(&xd->vu_vhost_dev, offset + VIRTIO_RXQ,
311                                            &tx_vector[tx_tail], 
312                                            (uint16_t) (DPDK_TX_RING_SIZE - tx_tail));
313
314               if (PREDICT_TRUE(rv > 0))
315                 {
316                   if (dpdk_vhost_user_want_interrupt(xd, offset + VIRTIO_RXQ)) {
317                     dpdk_vu_vring *vring = &(xd->vu_intf->vrings[offset + VIRTIO_RXQ]);
318                     vring->n_since_last_int += rv;
319
320                     f64 now = vlib_time_now (vm);
321                     if (vring->int_deadline < now ||
322                         vring->n_since_last_int > dm->vhost_coalesce_frames)
323                       dpdk_vhost_user_send_interrupt(vm, xd, offset + VIRTIO_RXQ);
324                   }
325
326                   int c = rv;
327                   while(c--)
328                     rte_pktmbuf_free (tx_vector[tx_tail+c]);
329                 }
330
331               n_retry = (rv == DPDK_TX_RING_SIZE - tx_tail) ? 1 : 0;
332             }
333         }
334       else if (xd->dev_type == VNET_DPDK_DEV_KNI)
335         {
336           if (PREDICT_TRUE(tx_head > tx_tail)) 
337             {
338               /* no wrap, transmit in one burst */
339               rv = rte_kni_tx_burst(xd->kni, 
340                                     &tx_vector[tx_tail], 
341                                     (uint16_t) (tx_head-tx_tail));
342             }
343           else 
344             {
345               /* 
346                * This can only happen if there is a flowcontrol callback.
347                * We need to split the transmit into two calls: one for
348                * the packets up to the wrap point, and one to continue
349                * at the start of the ring.
350                * Transmit pkts up to the wrap point.
351                */
352               rv = rte_kni_tx_burst(xd->kni, 
353                                     &tx_vector[tx_tail], 
354                                     (uint16_t) (DPDK_TX_RING_SIZE - tx_tail));
355
356               /* 
357                * If we transmitted everything we wanted, then allow 1 retry 
358                * so we can try to transmit the rest. If we didn't transmit
359                * everything, stop now.
360                */
361               n_retry = (rv == DPDK_TX_RING_SIZE - tx_tail) ? 1 : 0;
362             }
363         } 
364       else
365         {
366           ASSERT(0);
367           rv = 0;
368         }
369
370       if (PREDICT_FALSE(xd->lockp != 0))
371           *xd->lockp = 0;
372
373       if (PREDICT_FALSE(rv < 0))
374         {
375           // emit non-fatal message, bump counter
376           vnet_main_t * vnm = dm->vnet_main;
377           vnet_interface_main_t * im = &vnm->interface_main;
378           u32 node_index;
379
380           node_index = vec_elt_at_index(im->hw_interfaces, 
381                                         xd->vlib_hw_if_index)->tx_node_index;
382
383           vlib_error_count (vm, node_index, DPDK_TX_FUNC_ERROR_BAD_RETVAL, 1);
384           clib_warning ("rte_eth_tx_burst[%d]: error %d", xd->device_index, rv);
385           return n_packets; // untransmitted packets
386         }
387       ring->tx_tail += (u16)rv;
388       n_packets -= (uint16_t) rv;
389   } while (rv && n_packets && (n_retry>0));
390
391   return n_packets;
392 }
393
394
395 /*
396  * This function transmits any packets on the interface's tx_vector and returns
397  * the number of packets untransmitted on the tx_vector. If the tx_vector is 
398  * empty the function simply returns 0. 
399  *
400  * It is intended to be called by a traffic manager which has flowed-off an
401  * interface to see if the interface can be flowed-on again.
402  */
403 u32 dpdk_interface_tx_vector (vlib_main_t * vm, u32 dev_instance)
404 {
405   dpdk_main_t * dm = &dpdk_main;
406   dpdk_device_t * xd;
407   int queue_id;
408   struct rte_mbuf ** tx_vector;
409   tx_ring_hdr_t *ring;
410  
411   /* param is dev_instance and not hw_if_index to save another lookup */
412   xd = vec_elt_at_index (dm->devices, dev_instance);
413
414   queue_id = vm->cpu_index;
415   tx_vector = xd->tx_vectors[queue_id];
416
417   /* If no packets on the ring, don't bother calling tx function */
418   ring = vec_header(tx_vector, sizeof(*ring));
419   if (ring->tx_head == ring->tx_tail) 
420     {
421       return 0;
422     }
423
424   return tx_burst_vector_internal (vm, xd, tx_vector);
425 }
426
427 /*
428  * Transmits the packets on the frame to the interface associated with the
429  * node. It first copies packets on the frame to a tx_vector containing the 
430  * rte_mbuf pointers. It then passes this vector to tx_burst_vector_internal 
431  * which calls the dpdk tx_burst function.
432  *
433  * The tx_vector is treated slightly differently depending on whether or
434  * not a flowcontrol callback function has been configured. If there is no
435  * callback, the tx_vector is a temporary array of rte_mbuf packet pointers.
436  * Its entries are written and consumed before the function exits. 
437  *
438  * If there is a callback then the transmit is being invoked in the presence
439  * of a traffic manager. Here the tx_vector is treated like a ring of rte_mbuf
440  * pointers. If not all packets can be transmitted, the untransmitted packets
441  * stay on the tx_vector until the next call. The callback allows the traffic
442  * manager to flow-off dequeues to the interface. The companion function
443  * dpdk_interface_tx_vector() allows the traffic manager to detect when
444  * it should flow-on the interface again.
445  */
446 static uword
447 dpdk_interface_tx (vlib_main_t * vm,
448            vlib_node_runtime_t * node,
449            vlib_frame_t * f)
450 {
451   dpdk_main_t * dm = &dpdk_main;
452   vnet_interface_output_runtime_t * rd = (void *) node->runtime_data;
453   dpdk_device_t * xd = vec_elt_at_index (dm->devices, rd->dev_instance);
454   u32 n_packets = f->n_vectors;
455   u32 n_left;
456   u32 * from;
457   struct rte_mbuf ** tx_vector;
458   int i;
459   int queue_id;
460   u32 my_cpu;
461   u32 tx_pkts = 0;
462   tx_ring_hdr_t *ring;
463   u32 n_on_ring;
464
465   my_cpu = vm->cpu_index;
466
467   queue_id = my_cpu;
468
469   tx_vector = xd->tx_vectors[queue_id];
470   ring = vec_header(tx_vector, sizeof(*ring));
471
472   n_on_ring = ring->tx_head - ring->tx_tail;
473   from = vlib_frame_vector_args (f);
474
475   ASSERT(n_packets <= VLIB_FRAME_SIZE);
476
477   if (PREDICT_FALSE(n_on_ring + n_packets > DPDK_TX_RING_SIZE))
478     {
479       /*
480        * Overflowing the ring should never happen. 
481        * If it does then drop the whole frame.
482        */
483       vlib_error_count (vm, node->node_index, DPDK_TX_FUNC_ERROR_RING_FULL,
484                         n_packets);
485
486       while (n_packets--) 
487         {
488           u32 bi0 = from[n_packets];
489           vlib_buffer_t *b0 = vlib_get_buffer (vm, bi0);
490           struct rte_mbuf *mb0 = ((struct rte_mbuf *)b0) - 1;
491           rte_pktmbuf_free (mb0);
492         }
493       return n_on_ring;
494     }
495
496   if (PREDICT_FALSE(dm->tx_pcap_enable))
497     {
498       n_left = n_packets;
499       while (n_left > 0)
500         {
501           u32 bi0 = from[0];
502           vlib_buffer_t * b0 = vlib_get_buffer (vm, bi0);
503           if (dm->pcap_sw_if_index == 0 ||
504               dm->pcap_sw_if_index == vnet_buffer(b0)->sw_if_index [VLIB_TX])
505               pcap_add_buffer (&dm->pcap_main, vm, bi0, 512);
506           from++;
507           n_left--;
508         }
509     }
510
511   from = vlib_frame_vector_args (f);
512   n_left = n_packets;
513   i = ring->tx_head % DPDK_TX_RING_SIZE;
514
515   while (n_left >= 4)
516     {
517       u32 bi0, bi1;
518       u32 pi0, pi1;
519       struct rte_mbuf * mb0, * mb1;
520       struct rte_mbuf * prefmb0, * prefmb1;
521       vlib_buffer_t * b0, * b1;
522       vlib_buffer_t * pref0, * pref1;
523       i16 delta0, delta1;
524       u16 new_data_len0, new_data_len1;
525       u16 new_pkt_len0, new_pkt_len1;
526       u32 any_clone;
527
528       pi0 = from[2];
529       pi1 = from[3];
530       pref0 = vlib_get_buffer (vm, pi0);
531       pref1 = vlib_get_buffer (vm, pi1);
532
533       prefmb0 = ((struct rte_mbuf *)pref0) - 1;
534       prefmb1 = ((struct rte_mbuf *)pref1) - 1;
535       
536       CLIB_PREFETCH(prefmb0, CLIB_CACHE_LINE_BYTES, LOAD);
537       CLIB_PREFETCH(pref0, CLIB_CACHE_LINE_BYTES, LOAD);
538       CLIB_PREFETCH(prefmb1, CLIB_CACHE_LINE_BYTES, LOAD);
539       CLIB_PREFETCH(pref1, CLIB_CACHE_LINE_BYTES, LOAD);
540
541       bi0 = from[0];
542       bi1 = from[1];
543       from += 2;
544       
545       b0 = vlib_get_buffer (vm, bi0);
546       b1 = vlib_get_buffer (vm, bi1);
547
548       mb0 = ((struct rte_mbuf *)b0) - 1;
549       mb1 = ((struct rte_mbuf *)b1) - 1;
550
551       any_clone = b0->clone_count | b1->clone_count;
552       if (PREDICT_FALSE(any_clone != 0))
553         {
554           if (PREDICT_FALSE(b0->clone_count != 0))
555         {
556           struct rte_mbuf * mb0_new = dpdk_replicate_packet_mb (b0);
557           if (PREDICT_FALSE(mb0_new == 0))
558             {
559               vlib_error_count (vm, node->node_index,
560                     DPDK_TX_FUNC_ERROR_REPL_FAIL, 1);
561               b0->flags |= VLIB_BUFFER_REPL_FAIL;
562             }
563           else
564             mb0 = mb0_new;
565           vec_add1 (dm->recycle[my_cpu], bi0);
566         }
567           if (PREDICT_FALSE(b1->clone_count != 0))
568         {
569           struct rte_mbuf * mb1_new = dpdk_replicate_packet_mb (b1);
570           if (PREDICT_FALSE(mb1_new == 0))
571             {
572               vlib_error_count (vm, node->node_index,
573                     DPDK_TX_FUNC_ERROR_REPL_FAIL, 1);
574               b1->flags |= VLIB_BUFFER_REPL_FAIL;
575             }
576           else
577             mb1 = mb1_new;
578           vec_add1 (dm->recycle[my_cpu], bi1);
579         }
580     }
581
582       delta0 = PREDICT_FALSE(b0->flags & VLIB_BUFFER_REPL_FAIL) ? 0 :
583     vlib_buffer_length_in_chain (vm, b0) - (i16) mb0->pkt_len;
584       delta1 = PREDICT_FALSE(b1->flags & VLIB_BUFFER_REPL_FAIL) ? 0 :
585     vlib_buffer_length_in_chain (vm, b1) - (i16) mb1->pkt_len;
586       
587       new_data_len0 = (u16)((i16) mb0->data_len + delta0);
588       new_data_len1 = (u16)((i16) mb1->data_len + delta1);
589       new_pkt_len0 = (u16)((i16) mb0->pkt_len + delta0);
590       new_pkt_len1 = (u16)((i16) mb1->pkt_len + delta1);
591
592       b0->current_length = new_data_len0;
593       b1->current_length = new_data_len1;
594       mb0->data_len = new_data_len0;
595       mb1->data_len = new_data_len1;
596       mb0->pkt_len = new_pkt_len0;
597       mb1->pkt_len = new_pkt_len1;
598
599       mb0->data_off = (PREDICT_FALSE(b0->flags & VLIB_BUFFER_REPL_FAIL)) ?
600           mb0->data_off : (u16)(RTE_PKTMBUF_HEADROOM + b0->current_data);
601       mb1->data_off = (PREDICT_FALSE(b1->flags & VLIB_BUFFER_REPL_FAIL)) ?
602           mb1->data_off : (u16)(RTE_PKTMBUF_HEADROOM + b1->current_data);
603
604       if (PREDICT_FALSE(node->flags & VLIB_NODE_FLAG_TRACE))
605     {
606           if (b0->flags & VLIB_BUFFER_IS_TRACED)
607               dpdk_tx_trace_buffer (dm, node, xd, queue_id, bi0, b0);
608           if (b1->flags & VLIB_BUFFER_IS_TRACED)
609               dpdk_tx_trace_buffer (dm, node, xd, queue_id, bi1, b1);
610     }
611
612       if (PREDICT_TRUE(any_clone == 0))
613         {
614       tx_vector[i % DPDK_TX_RING_SIZE] = mb0;
615           i++;
616       tx_vector[i % DPDK_TX_RING_SIZE] = mb1;
617           i++;
618         }
619       else
620         {
621           /* cloning was done, need to check for failure */
622           if (PREDICT_TRUE((b0->flags & VLIB_BUFFER_REPL_FAIL) == 0))
623             {
624           tx_vector[i % DPDK_TX_RING_SIZE] = mb0;
625               i++;
626             }
627           if (PREDICT_TRUE((b1->flags & VLIB_BUFFER_REPL_FAIL) == 0))
628             {
629           tx_vector[i % DPDK_TX_RING_SIZE] = mb1;
630               i++;
631             }
632         }
633
634       n_left -= 2;
635     }
636   while (n_left > 0)
637     {
638       u32 bi0;
639       struct rte_mbuf * mb0;
640       vlib_buffer_t * b0;
641       i16 delta0;
642       u16 new_data_len0;
643       u16 new_pkt_len0;
644
645       bi0 = from[0];
646       from++;
647       
648       b0 = vlib_get_buffer (vm, bi0);
649
650       mb0 = ((struct rte_mbuf *)b0) - 1;
651       if (PREDICT_FALSE(b0->clone_count != 0))
652     {
653       struct rte_mbuf * mb0_new = dpdk_replicate_packet_mb (b0);
654       if (PREDICT_FALSE(mb0_new == 0))
655         {
656           vlib_error_count (vm, node->node_index,
657                 DPDK_TX_FUNC_ERROR_REPL_FAIL, 1);
658           b0->flags |= VLIB_BUFFER_REPL_FAIL;
659         }
660       else
661         mb0 = mb0_new;
662       vec_add1 (dm->recycle[my_cpu], bi0);
663     }
664
665       delta0 = PREDICT_FALSE(b0->flags & VLIB_BUFFER_REPL_FAIL) ? 0 :
666     vlib_buffer_length_in_chain (vm, b0) - (i16) mb0->pkt_len;
667       
668       new_data_len0 = (u16)((i16) mb0->data_len + delta0);
669       new_pkt_len0 = (u16)((i16) mb0->pkt_len + delta0);
670       
671       b0->current_length = new_data_len0;
672       mb0->data_len = new_data_len0;
673       mb0->pkt_len = new_pkt_len0;
674       mb0->data_off = (PREDICT_FALSE(b0->flags & VLIB_BUFFER_REPL_FAIL)) ?
675           mb0->data_off : (u16)(RTE_PKTMBUF_HEADROOM + b0->current_data);
676
677       if (PREDICT_FALSE(node->flags & VLIB_NODE_FLAG_TRACE))
678           if (b0->flags & VLIB_BUFFER_IS_TRACED)
679               dpdk_tx_trace_buffer (dm, node, xd, queue_id, bi0, b0);
680
681       if (PREDICT_TRUE((b0->flags & VLIB_BUFFER_REPL_FAIL) == 0))
682         {
683       tx_vector[i % DPDK_TX_RING_SIZE] = mb0;
684           i++;
685         }
686       n_left--;
687     }
688
689   /* account for additional packets in the ring */
690   ring->tx_head += n_packets;
691   n_on_ring = ring->tx_head - ring->tx_tail;
692
693   /* transmit as many packets as possible */
694   n_packets = tx_burst_vector_internal (vm, xd, tx_vector);
695
696   /*
697    * tx_pkts is the number of packets successfully transmitted
698    * This is the number originally on ring minus the number remaining on ring
699    */
700   tx_pkts = n_on_ring - n_packets; 
701
702   if (PREDICT_FALSE(dm->flowcontrol_callback != 0))
703     {
704       if (PREDICT_FALSE(n_packets))
705         {
706           /* Callback may want to enable flowcontrol */
707           dm->flowcontrol_callback(vm, xd->vlib_hw_if_index, ring->tx_head - ring->tx_tail);
708         } 
709       else 
710         {
711           /* Reset head/tail to avoid unnecessary wrap */
712           ring->tx_head = 0;
713           ring->tx_tail = 0;
714         }
715     }
716   else 
717     {
718       /* If there is no callback then drop any non-transmitted packets */
719       if (PREDICT_FALSE(n_packets))
720         {
721           vlib_simple_counter_main_t * cm;
722           vnet_main_t * vnm = vnet_get_main();
723
724           cm = vec_elt_at_index (vnm->interface_main.sw_if_counters,
725                                  VNET_INTERFACE_COUNTER_TX_ERROR);
726
727           vlib_increment_simple_counter (cm, my_cpu, xd->vlib_sw_if_index, n_packets);
728
729           vlib_error_count (vm, node->node_index, DPDK_TX_FUNC_ERROR_PKT_DROP,
730                 n_packets);
731
732           while (n_packets--)
733             rte_pktmbuf_free (tx_vector[ring->tx_tail + n_packets]);
734         }
735
736         /* Reset head/tail to avoid unnecessary wrap */
737         ring->tx_head = 0;
738         ring->tx_tail = 0;
739     }
740
741   /* Recycle replicated buffers */
742   if (PREDICT_FALSE(vec_len(dm->recycle[my_cpu])))
743     {
744       vlib_buffer_free (vm, dm->recycle[my_cpu], vec_len(dm->recycle[my_cpu]));
745       _vec_len(dm->recycle[my_cpu]) = 0;
746     }
747
748   ASSERT(ring->tx_head >= ring->tx_tail);
749
750   return tx_pkts;
751 }
752
753 static int dpdk_device_renumber (vnet_hw_interface_t * hi,
754                                  u32 new_dev_instance)
755 {
756   dpdk_main_t * dm = &dpdk_main;
757   dpdk_device_t * xd = vec_elt_at_index (dm->devices, hi->dev_instance);
758
759   if (!xd || xd->dev_type != VNET_DPDK_DEV_VHOST_USER) {
760       clib_warning("cannot renumber non-vhost-user interface (sw_if_index: %d)",
761               hi->sw_if_index);
762       return 0;
763   }
764
765   xd->vu_if_id = new_dev_instance;
766   return 0;
767 }
768
769 static u8 * format_dpdk_device_name (u8 * s, va_list * args)
770 {
771   dpdk_main_t * dm = &dpdk_main;
772   char *devname_format;
773   char *device_name;
774   u32 i = va_arg (*args, u32);
775   struct rte_eth_dev_info dev_info;
776   u8 * ret;
777
778   if (dm->interface_name_format_decimal)
779     devname_format = "%s%d/%d/%d";
780   else
781     devname_format = "%s%x/%x/%x";
782
783   if (dm->devices[i].dev_type == VNET_DPDK_DEV_KNI) {
784        return format(s, "kni%d", dm->devices[i].kni_port_id);
785   } else if (dm->devices[i].dev_type == VNET_DPDK_DEV_VHOST_USER) {
786        return format(s, "VirtualEthernet0/0/%d", dm->devices[i].vu_if_id);
787   }
788   switch (dm->devices[i].port_type)
789     {
790     case VNET_DPDK_PORT_TYPE_ETH_1G:
791       device_name = "GigabitEthernet";
792       break;
793
794     case VNET_DPDK_PORT_TYPE_ETH_10G:
795       device_name = "TenGigabitEthernet";
796       break;
797
798     case VNET_DPDK_PORT_TYPE_ETH_40G:
799       device_name = "FortyGigabitEthernet";
800       break;
801
802     case VNET_DPDK_PORT_TYPE_ETH_SWITCH:
803       device_name = "EthernetSwitch";
804       break;
805
806   #ifdef NETMAP
807     case VNET_DPDK_PORT_TYPE_NETMAP:
808         rte_eth_dev_info_get(i, &dev_info);
809         return format(s, "netmap:%s", dev_info.driver_name);
810   #endif
811
812     case VNET_DPDK_PORT_TYPE_AF_PACKET:
813       rte_eth_dev_info_get(i, &dev_info);
814       return format(s, "af_packet%d", dm->devices[i].af_packet_port_id);
815
816     default:
817     case VNET_DPDK_PORT_TYPE_UNKNOWN:
818       device_name = "UnknownEthernet";
819       break;
820     }
821
822   rte_eth_dev_info_get(i, &dev_info);
823   ret = format (s, devname_format, device_name, dev_info.pci_dev->addr.bus,
824                  dev_info.pci_dev->addr.devid,
825                  dev_info.pci_dev->addr.function);
826
827   /* address Chelsio cards which share PCI address */
828         if (dm->devices[i].pmd ==  VNET_DPDK_PMD_CXGBE) {
829     struct rte_eth_dev_info di;
830
831     di.pci_dev = 0;
832     rte_eth_dev_info_get(i+1, &di);
833     if (di.pci_dev && memcmp(&dev_info.pci_dev->addr, &di.pci_dev->addr,
834         sizeof(struct rte_pci_addr)) == 0)
835             return format(ret, "/0");   
836
837     di.pci_dev = 0;
838     rte_eth_dev_info_get(i-1, &di);
839     if (di.pci_dev && memcmp(&dev_info.pci_dev->addr, &di.pci_dev->addr,
840         sizeof(struct rte_pci_addr)) == 0)
841             return format(ret, "/1");   
842         }
843   return ret;
844 }
845
846 static u8 * format_dpdk_device_type (u8 * s, va_list * args)
847 {
848   dpdk_main_t * dm = &dpdk_main;
849   char *dev_type;
850   u32 i = va_arg (*args, u32);
851
852   if (dm->devices[i].dev_type == VNET_DPDK_DEV_KNI) {
853        return format(s, "Kernel NIC Interface");
854   } else if (dm->devices[i].dev_type == VNET_DPDK_DEV_VHOST_USER) {
855        return format(s, "vhost-user interface");
856   }
857
858   switch (dm->devices[i].pmd)
859     {
860     case VNET_DPDK_PMD_E1000EM:
861         dev_type = "Intel 82540EM (e1000)";
862         break;
863
864     case VNET_DPDK_PMD_IGB:
865         dev_type = "Intel e1000";
866         break;
867
868     case VNET_DPDK_PMD_I40E:
869         dev_type = "Intel X710/XL710 Family";
870         break;
871
872     case VNET_DPDK_PMD_I40EVF:
873         dev_type = "Intel X710/XL710 Family VF";
874         break;
875
876     case VNET_DPDK_PMD_FM10K:
877         dev_type = "Intel FM10000 Family Ethernet Switch";
878         break;
879
880     case VNET_DPDK_PMD_IGBVF:
881         dev_type = "Intel e1000 VF";
882         break;
883
884     case VNET_DPDK_PMD_VIRTIO:
885         dev_type = "Red Hat Virtio";
886         break;
887
888     case VNET_DPDK_PMD_IXGBEVF:
889         dev_type = "Intel 82599 VF";
890         break;
891
892     case VNET_DPDK_PMD_IXGBE:
893         dev_type = "Intel 82599";
894         break;
895
896     case VNET_DPDK_PMD_VICE:
897     case VNET_DPDK_PMD_ENIC:
898         dev_type = "Cisco VIC";
899         break;
900
901     case VNET_DPDK_PMD_CXGBE:
902         dev_type = "Chelsio T4/T5";
903         break;
904
905     case VNET_DPDK_PMD_VMXNET3:
906         dev_type = "VMware VMXNET3";
907         break;
908
909 #ifdef NETMAP
910     case VNET_DPDK_PMD_NETMAP:
911         dev_type = "Netmap/Vale";
912         break;
913 #endif
914
915     case VNET_DPDK_PMD_AF_PACKET:
916   dev_type = "af_packet";
917   break;
918
919     default:
920     case VNET_DPDK_PMD_UNKNOWN:
921         dev_type = "### UNKNOWN ###";
922         break;
923     }
924
925   return format (s, dev_type);
926 }
927
928 static u8 * format_dpdk_link_status (u8 * s, va_list * args)
929 {
930   dpdk_device_t * xd = va_arg (*args, dpdk_device_t *);
931   struct rte_eth_link * l = &xd->link;
932   vnet_main_t * vnm = vnet_get_main();
933   vnet_hw_interface_t * hi = vnet_get_hw_interface (vnm, xd->vlib_hw_if_index);
934   
935   s = format (s, "%s ", l->link_status ? "up" : "down");
936   if (l->link_status)
937     {
938       u32 promisc = rte_eth_promiscuous_get (xd->device_index);
939
940       s = format (s, "%s duplex ", (l->link_duplex == ETH_LINK_FULL_DUPLEX) ?
941                   "full" : "half");
942       s = format (s, "speed %u mtu %d %s\n", l->link_speed,
943                   hi->max_packet_bytes, promisc ? " promisc" : "");
944     }
945   else
946     s = format (s, "\n");
947
948   return s;
949 }
950
951 #define _line_len 72
952 #define _(v, str)                                            \
953 if (bitmap & v) {                                            \
954   if (format_get_indent (s) > next_split ) {                 \
955     next_split += _line_len;                                 \
956     s = format(s,"\n%U", format_white_space, indent);        \
957   }                                                          \
958   s = format(s, "%s ", str);                                 \
959 }
960
961 static u8 * format_dpdk_rss_hf_name(u8 * s, va_list * args)
962 {
963   u64 bitmap = va_arg (*args, u64);
964   int next_split = _line_len;
965   int indent = format_get_indent (s);
966
967   if (!bitmap)
968     return format(s, "none");
969
970   foreach_dpdk_rss_hf
971
972   return s;
973 }
974
975 static u8 * format_dpdk_rx_offload_caps(u8 * s, va_list * args)
976 {
977   u32 bitmap = va_arg (*args, u32);
978   int next_split = _line_len;
979   int indent = format_get_indent (s);
980
981   if (!bitmap)
982     return format(s, "none");
983
984   foreach_dpdk_rx_offload_caps
985
986   return s;
987 }
988
989 static u8 * format_dpdk_tx_offload_caps(u8 * s, va_list * args)
990 {
991   u32 bitmap = va_arg (*args, u32);
992   int next_split = _line_len;
993   int indent = format_get_indent (s);
994   if (!bitmap)
995     return format(s, "none");
996
997   foreach_dpdk_tx_offload_caps
998
999   return s;
1000 }
1001
1002 #undef _line_len
1003 #undef _
1004
1005 static u8 * format_dpdk_device (u8 * s, va_list * args)
1006 {
1007   u32 dev_instance = va_arg (*args, u32);
1008   int verbose = va_arg (*args, int);
1009   dpdk_main_t * dm = &dpdk_main;
1010   dpdk_device_t * xd = vec_elt_at_index (dm->devices, dev_instance);
1011   uword indent = format_get_indent (s);
1012   f64 now = vlib_time_now (dm->vlib_main);
1013
1014   dpdk_update_counters (xd, now);
1015   dpdk_update_link_state (xd, now);
1016
1017   s = format (s, "%U\n%Ucarrier %U",
1018               format_dpdk_device_type, xd->device_index,
1019               format_white_space, indent + 2,
1020               format_dpdk_link_status, xd);
1021
1022   if (verbose > 1 && xd->dev_type == VNET_DPDK_DEV_ETH)
1023     {
1024       struct rte_eth_dev_info di;
1025       struct rte_pci_device * pci;
1026       struct rte_eth_rss_conf rss_conf;
1027       int vlan_off;
1028
1029       rss_conf.rss_key = 0;
1030       rte_eth_dev_info_get(xd->device_index, &di);
1031       rte_eth_dev_rss_hash_conf_get(xd->device_index, &rss_conf);
1032       pci = di.pci_dev;
1033
1034       if (pci)
1035         s = format(s, "%Upci id:            device %04x:%04x subsystem %04x:%04x\n"
1036                       "%Upci address:       %04x:%02x:%02x.%02x\n",
1037                    format_white_space, indent + 2,
1038                    pci->id.vendor_id, pci->id.device_id,
1039                    pci->id.subsystem_vendor_id,
1040                    pci->id.subsystem_device_id,
1041                    format_white_space, indent + 2,
1042                    pci->addr.domain, pci->addr.bus,
1043                    pci->addr.devid, pci->addr.function);
1044       s = format(s, "%Umax rx packet len: %d\n",
1045                  format_white_space, indent + 2, di.max_rx_pktlen);
1046       s = format(s, "%Upromiscuous:       unicast %s all-multicast %s\n",
1047                  format_white_space, indent + 2,
1048                  rte_eth_promiscuous_get(xd->device_index) ? "on" : "off",
1049                  rte_eth_promiscuous_get(xd->device_index) ? "on" : "off");
1050       vlan_off = rte_eth_dev_get_vlan_offload(xd->device_index);
1051       s = format(s, "%Uvlan offload:      strip %s filter %s qinq %s\n",
1052                  format_white_space, indent + 2,
1053                  vlan_off & ETH_VLAN_STRIP_OFFLOAD ? "on" : "off",
1054                  vlan_off & ETH_VLAN_FILTER_OFFLOAD ? "on" : "off",
1055                  vlan_off & ETH_VLAN_EXTEND_OFFLOAD ? "on" : "off");
1056       s = format(s, "%Uqueue size (max):  rx %d (%d) tx %d (%d)\n",
1057                  format_white_space, indent + 2,
1058                  xd->rx_q_used, di.max_rx_queues,
1059                  xd->tx_q_used, di.max_tx_queues);
1060       s = format(s, "%Urx offload caps:   %U\n",
1061                  format_white_space, indent + 2,
1062                  format_dpdk_rx_offload_caps, di.rx_offload_capa);
1063       s = format(s, "%Utx offload caps:   %U\n",
1064                  format_white_space, indent + 2,
1065                  format_dpdk_tx_offload_caps, di.tx_offload_capa);
1066       s = format(s, "%Urss active:        %U\n"
1067                     "%Urss supported:     %U\n",
1068                  format_white_space, indent + 2,
1069                  format_dpdk_rss_hf_name, rss_conf.rss_hf,
1070                  format_white_space, indent + 2,
1071                  format_dpdk_rss_hf_name, di.flow_type_rss_offloads);
1072     }
1073
1074   if (xd->cpu_socket > -1)
1075     s = format (s, "%Ucpu socket %d",
1076                 format_white_space, indent + 2,
1077                 xd->cpu_socket);
1078
1079   /* $$$ MIB counters  */
1080
1081   {
1082 #define _(N, V)                                                 \
1083     if (xd->stats.V != 0)                                       \
1084       s = format (s, "\n%U%-40U%16Ld",                          \
1085                   format_white_space, indent + 2,               \
1086                   format_c_identifier, #N, xd->stats.V);
1087     
1088     foreach_dpdk_counter
1089 #undef _
1090   }
1091
1092   u8 * xs = 0;
1093   struct rte_eth_xstats * xstat;
1094
1095   vec_foreach(xstat, xd->xstats)
1096     {
1097       if (xstat->value)
1098         {
1099           /* format_c_identifier don't like c strings inside vector */
1100           u8 * name = format(0,"%s", xstat->name);
1101           xs = format(xs, "\n%U%-38U%16Ld",
1102                       format_white_space, indent + 4,
1103                       format_c_identifier, name, xstat->value);
1104           vec_free(name);
1105         }
1106     }
1107
1108   if (xs)
1109     {
1110       s = format(s, "\n%Uextended stats:%v",
1111                  format_white_space, indent + 2, xs);
1112       vec_free(xs);
1113     }
1114
1115   return s;
1116 }
1117
1118 static u8 * format_dpdk_tx_dma_trace (u8 * s, va_list * va)
1119 {
1120   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
1121   CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
1122   CLIB_UNUSED (vnet_main_t * vnm) = vnet_get_main();
1123   dpdk_tx_dma_trace_t * t = va_arg (*va, dpdk_tx_dma_trace_t *);
1124   dpdk_main_t * dm = &dpdk_main;
1125   dpdk_device_t * xd = vec_elt_at_index (dm->devices, t->device_index);
1126   uword indent = format_get_indent (s);
1127   vnet_sw_interface_t * sw = vnet_get_sw_interface (vnm, xd->vlib_sw_if_index);
1128
1129   s = format (s, "%U tx queue %d",
1130               format_vnet_sw_interface_name, vnm, sw,
1131               t->queue_index);
1132
1133   s = format (s, "\n%Ubuffer 0x%x: %U",
1134               format_white_space, indent,
1135               t->buffer_index,
1136               format_vlib_buffer, &t->buffer);
1137
1138   s = format (s, "\n%U%U", format_white_space, indent,
1139               format_ethernet_header_with_length, t->buffer.pre_data,
1140               sizeof (t->buffer.pre_data));
1141   
1142   return s;
1143 }
1144
1145 static void dpdk_clear_hw_interface_counters (u32 instance)
1146 {
1147   dpdk_main_t * dm = &dpdk_main;
1148   dpdk_device_t * xd = vec_elt_at_index (dm->devices, instance);
1149
1150   /*
1151    * DAW-FIXME: VMXNET3 device stop/start doesn't work, 
1152    * therefore fake the stop in the dpdk driver by
1153    * silently dropping all of the incoming pkts instead of 
1154    * stopping the driver / hardware.
1155    */
1156   if (xd->admin_up != 0xff)
1157     {
1158       rte_eth_stats_reset (xd->device_index);
1159       memset (&xd->last_stats, 0, sizeof (xd->last_stats));
1160       dpdk_update_counters (xd, vlib_time_now (dm->vlib_main));
1161     }
1162   else
1163     {
1164       rte_eth_stats_reset (xd->device_index);
1165       memset(&xd->stats, 0, sizeof(xd->stats));
1166       memset (&xd->last_stats, 0, sizeof (xd->last_stats));
1167     }
1168   rte_eth_xstats_reset(xd->device_index);
1169 }
1170
1171 static int
1172 kni_config_network_if(u8 port_id, u8 if_up)
1173 {
1174   vnet_main_t * vnm = vnet_get_main();
1175   dpdk_main_t * dm = &dpdk_main;
1176   dpdk_device_t * xd;
1177   uword *p;
1178
1179   p = hash_get (dm->dpdk_device_by_kni_port_id, port_id);
1180   if (p == 0) {
1181     clib_warning("unknown interface");
1182     return 0;
1183   } else {
1184     xd = vec_elt_at_index (dm->devices, p[0]);
1185   }
1186
1187   vnet_hw_interface_set_flags (vnm, xd->vlib_hw_if_index,
1188                                if_up ? VNET_HW_INTERFACE_FLAG_LINK_UP |
1189                                ETH_LINK_FULL_DUPLEX : 0);
1190   return 0;
1191 }
1192
1193 static int
1194 kni_change_mtu(u8 port_id, unsigned new_mtu)
1195 {
1196   vnet_main_t * vnm = vnet_get_main();
1197   dpdk_main_t * dm = &dpdk_main;
1198   dpdk_device_t * xd;
1199   uword *p;
1200   vnet_hw_interface_t * hif;
1201
1202   p = hash_get (dm->dpdk_device_by_kni_port_id, port_id);
1203   if (p == 0) {
1204     clib_warning("unknown interface");
1205     return 0;
1206   } else {
1207     xd = vec_elt_at_index (dm->devices, p[0]);
1208   }
1209   hif = vnet_get_hw_interface (vnm, xd->vlib_hw_if_index);
1210
1211   hif->max_packet_bytes = new_mtu;
1212
1213   return 0;
1214 }
1215
1216 static clib_error_t *
1217 dpdk_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
1218 {
1219   vnet_hw_interface_t * hif = vnet_get_hw_interface (vnm, hw_if_index);
1220   uword is_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
1221   dpdk_main_t * dm = &dpdk_main;
1222   dpdk_device_t * xd = vec_elt_at_index (dm->devices, hif->dev_instance);
1223   int rv = 0;
1224
1225   if (xd->dev_type == VNET_DPDK_DEV_KNI)
1226   {
1227       if (is_up)
1228       {
1229           struct rte_kni_conf conf;
1230           struct rte_kni_ops ops;
1231           vlib_main_t * vm = vlib_get_main();
1232           vlib_buffer_main_t * bm = vm->buffer_main;
1233           memset(&conf, 0, sizeof(conf));
1234           snprintf(conf.name, RTE_KNI_NAMESIZE, "vpp%u", xd->kni_port_id);
1235           conf.mbuf_size = MBUF_SIZE;
1236           memset(&ops, 0, sizeof(ops));
1237           ops.port_id = xd->kni_port_id;
1238           ops.change_mtu = kni_change_mtu;
1239           ops.config_network_if = kni_config_network_if;
1240
1241           xd->kni = rte_kni_alloc(bm->pktmbuf_pools[rte_socket_id()], &conf, &ops);
1242           if (!xd->kni)
1243           {
1244             clib_warning("failed to allocate kni interface");
1245           }
1246           else
1247           {
1248             hif->max_packet_bytes = 1500; /* kni interface default value */
1249             xd->admin_up = 1;
1250           }
1251       }
1252       else
1253       {
1254         xd->admin_up = 0;
1255         rte_kni_release(xd->kni);
1256       }
1257       return 0;
1258   }
1259   if (xd->dev_type == VNET_DPDK_DEV_VHOST_USER)
1260     {
1261       if (is_up)
1262         {
1263           if (xd->vu_is_running)
1264             vnet_hw_interface_set_flags (vnm, xd->vlib_hw_if_index,
1265                                  VNET_HW_INTERFACE_FLAG_LINK_UP |
1266                                  ETH_LINK_FULL_DUPLEX );
1267           xd->admin_up = 1;
1268         }
1269       else
1270         {
1271           vnet_hw_interface_set_flags (vnm, xd->vlib_hw_if_index, 0);
1272                               xd->admin_up = 0;
1273         }
1274
1275       return 0;
1276     }
1277
1278
1279   if (is_up)
1280     {
1281       f64 now = vlib_time_now (dm->vlib_main);
1282
1283       /*
1284        * DAW-FIXME: VMXNET3 device stop/start doesn't work, 
1285        * therefore fake the stop in the dpdk driver by
1286        * silently dropping all of the incoming pkts instead of 
1287        * stopping the driver / hardware.
1288        */
1289       if (xd->admin_up == 0)
1290         rv = rte_eth_dev_start (xd->device_index);
1291
1292       if (xd->promisc)
1293           rte_eth_promiscuous_enable(xd->device_index);
1294       else
1295           rte_eth_promiscuous_disable(xd->device_index);
1296
1297       rte_eth_allmulticast_enable (xd->device_index);
1298       xd->admin_up = 1;
1299       dpdk_update_counters (xd, now);
1300       dpdk_update_link_state (xd, now);
1301     }
1302   else
1303     {
1304       rte_eth_allmulticast_disable (xd->device_index);
1305       vnet_hw_interface_set_flags (vnm, xd->vlib_hw_if_index, 0);
1306
1307       /*
1308        * DAW-FIXME: VMXNET3 device stop/start doesn't work, 
1309        * therefore fake the stop in the dpdk driver by
1310        * silently dropping all of the incoming pkts instead of 
1311        * stopping the driver / hardware.
1312        */
1313       if (xd->pmd != VNET_DPDK_PMD_VMXNET3)
1314         {
1315           rte_eth_dev_stop (xd->device_index);
1316           xd->admin_up = 0;
1317         }
1318       else
1319           xd->admin_up = ~0;
1320     }
1321
1322   if (rv < 0)
1323     clib_warning ("rte_eth_dev_%s error: %d", is_up ? "start" : "stop",
1324                   rv);
1325
1326   return /* no error */ 0;
1327 }
1328
1329 /*
1330  * Dynamically redirect all pkts from a specific interface
1331  * to the specified node
1332  */
1333 static void dpdk_set_interface_next_node (vnet_main_t *vnm, u32 hw_if_index,
1334                                           u32 node_index)
1335 {
1336   dpdk_main_t * xm = &dpdk_main;
1337   vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
1338   dpdk_device_t * xd = vec_elt_at_index (xm->devices, hw->dev_instance);
1339   
1340   /* Shut off redirection */
1341   if (node_index == ~0)
1342     {
1343       xd->per_interface_next_index = node_index;
1344       return;
1345     }
1346   
1347   xd->per_interface_next_index = 
1348     vlib_node_add_next (xm->vlib_main, dpdk_input_node.index, node_index);
1349 }
1350
1351
1352 static clib_error_t *
1353 dpdk_subif_add_del_function (vnet_main_t * vnm,
1354                              u32 hw_if_index,
1355                              struct vnet_sw_interface_t * st,
1356                              int is_add)
1357 {
1358   dpdk_main_t * xm = &dpdk_main;
1359   vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
1360   dpdk_device_t * xd = vec_elt_at_index (xm->devices, hw->dev_instance);
1361   vnet_sw_interface_t * t = (vnet_sw_interface_t *) st;
1362   int r, vlan_offload;
1363
1364
1365   if (xd->dev_type != VNET_DPDK_DEV_ETH)
1366         return 0;
1367   /* currently we program VLANS only for IXGBE VF */
1368   if (xd->pmd != VNET_DPDK_PMD_IXGBEVF)
1369         return 0;
1370
1371   if (t->sub.eth.flags.no_tags == 1)
1372         return 0;
1373
1374   if ((t->sub.eth.flags.one_tag != 1) || (t->sub.eth.flags.exact_match != 1 ))
1375         return clib_error_return (0, "unsupported VLAN setup");
1376
1377
1378   vlan_offload = rte_eth_dev_get_vlan_offload(xd->device_index);
1379   vlan_offload |= ETH_VLAN_FILTER_OFFLOAD;
1380
1381   if ((r = rte_eth_dev_set_vlan_offload(xd->device_index, vlan_offload)))
1382         return clib_error_return (0, "rte_eth_dev_set_vlan_offload[%d]: err %d",
1383                                   xd->device_index, r);
1384
1385
1386   if ((r = rte_eth_dev_vlan_filter(xd->device_index, t->sub.eth.outer_vlan_id, is_add)))
1387         return clib_error_return (0, "rte_eth_dev_vlan_filter[%d]: err %d",
1388                                  xd->device_index, r);
1389
1390   return 0;
1391 }
1392
1393 VNET_DEVICE_CLASS (dpdk_device_class) = {
1394   .name = "dpdk",
1395   .tx_function = dpdk_interface_tx,
1396   .tx_function_n_errors = DPDK_TX_FUNC_N_ERROR,
1397   .tx_function_error_strings = dpdk_tx_func_error_strings,
1398   .format_device_name = format_dpdk_device_name,
1399   .format_device = format_dpdk_device,
1400   .format_tx_trace = format_dpdk_tx_dma_trace,
1401   .clear_counters = dpdk_clear_hw_interface_counters,
1402   .admin_up_down_function = dpdk_interface_admin_up_down,
1403   .subif_add_del_function = dpdk_subif_add_del_function,
1404   .rx_redirect_to_node = dpdk_set_interface_next_node,
1405   .no_flatten_output_chains = 1,
1406   .name_renumber = dpdk_device_renumber,
1407 };
1408
1409 void dpdk_set_flowcontrol_callback (vlib_main_t *vm, 
1410                                     dpdk_flowcontrol_callback_t callback)
1411 {
1412   dpdk_main.flowcontrol_callback = callback;
1413 }
1414
1415 #define UP_DOWN_FLAG_EVENT 1
1416
1417
1418 u32 dpdk_get_admin_up_down_in_progress (void)
1419 {
1420   return dpdk_main.admin_up_down_in_progress;
1421 }
1422
1423 static uword
1424 admin_up_down_process (vlib_main_t * vm,
1425                        vlib_node_runtime_t * rt,
1426                        vlib_frame_t * f)
1427 {
1428   clib_error_t * error = 0;
1429   uword event_type;
1430   uword *event_data = 0;
1431   u32 index;
1432   u32 sw_if_index;
1433   u32 flags;
1434
1435   while (1)  
1436     { 
1437       vlib_process_wait_for_event (vm);
1438
1439       event_type = vlib_process_get_events (vm, &event_data);
1440
1441       dpdk_main.admin_up_down_in_progress = 1;
1442
1443       for (index=0; index<vec_len(event_data); index++)
1444         {
1445           sw_if_index = event_data[index] >> 32;
1446           flags = (u32) event_data[index];
1447
1448           switch (event_type) {
1449           case UP_DOWN_FLAG_EVENT:
1450             error = vnet_sw_interface_set_flags (vnet_get_main(), sw_if_index, flags);
1451             clib_error_report(error);
1452             break;
1453           }
1454         }
1455
1456       vec_reset_length (event_data);
1457
1458       dpdk_main.admin_up_down_in_progress = 0;
1459
1460     }
1461   return 0; /* or not */
1462 }
1463
1464 VLIB_REGISTER_NODE (admin_up_down_process_node,static) = {
1465     .function = admin_up_down_process,
1466     .type = VLIB_NODE_TYPE_PROCESS,
1467     .name = "admin-up-down-process",
1468     .process_log2_n_stack_bytes = 17,  // 256KB
1469 };
1470
1471 /*
1472  * Asynchronously invoke vnet_sw_interface_set_flags via the admin_up_down 
1473  * process. Useful for avoiding long blocking delays (>150ms) in the dpdk 
1474  * drivers.
1475  * WARNING: when posting this event, no other interface-related calls should
1476  * be made (e.g. vnet_create_sw_interface()) while the event is being
1477  * processed (admin_up_down_in_progress). This is required in order to avoid 
1478  * race conditions in manipulating interface data structures.
1479  */
1480 void post_sw_interface_set_flags (vlib_main_t *vm, u32 sw_if_index, u32 flags)
1481 {
1482   vlib_process_signal_event
1483       (vm, admin_up_down_process_node.index,
1484        UP_DOWN_FLAG_EVENT, 
1485        (((uword)sw_if_index << 32) | flags));
1486 }
1487
1488 /*
1489  * Called by the dpdk driver's rte_delay_us() function. 
1490  * Return 0 to have the dpdk do a regular delay loop.
1491  * Return 1 if to skip the delay loop because we are suspending
1492  * the calling vlib process instead.
1493  */
1494 int rte_delay_us_override (unsigned us) {
1495   vlib_main_t * vm;
1496
1497   /* Don't bother intercepting for short delays */
1498   if (us < 10) return 0;
1499
1500   /* 
1501    * Only intercept if we are in a vlib process. 
1502    * If we are called from a vlib worker thread or the vlib main
1503    * thread then do not intercept. (Must not be called from an 
1504    * independent pthread).
1505    */
1506   if (os_get_cpu_number() == 0)
1507     {
1508       /* 
1509        * We're in the vlib main thread or a vlib process. Make sure
1510        * the process is running and we're not still initializing.
1511        */
1512       vm = vlib_get_main();
1513       if (vlib_in_process_context(vm))
1514         {
1515           /* Only suspend for the admin_down_process */
1516           vlib_process_t * proc = vlib_get_current_process(vm);
1517           if (!(proc->flags & VLIB_PROCESS_IS_RUNNING) ||
1518               (proc->node_runtime.function != admin_up_down_process))
1519                 return 0;
1520
1521           f64 delay = 1e-6 * us;
1522           vlib_process_suspend(vm, delay);
1523           return 1;
1524         }
1525     }
1526   return 0; // no override
1527 }