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