ovs-numa: Introduce function to set current thread affinity.
[cascardo/ovs.git] / lib / netdev-dummy.c
1 /*
2  * Copyright (c) 2010, 2011, 2012, 2013, 2015, 2016 Nicira, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18
19 #include "dummy.h"
20
21 #include <errno.h>
22
23 #include "dp-packet.h"
24 #include "dpif-netdev.h"
25 #include "flow.h"
26 #include "netdev-provider.h"
27 #include "netdev-vport.h"
28 #include "odp-util.h"
29 #include "openvswitch/dynamic-string.h"
30 #include "openvswitch/list.h"
31 #include "openvswitch/ofp-print.h"
32 #include "openvswitch/ofpbuf.h"
33 #include "openvswitch/vlog.h"
34 #include "ovs-atomic.h"
35 #include "packets.h"
36 #include "pcap-file.h"
37 #include "poll-loop.h"
38 #include "shash.h"
39 #include "sset.h"
40 #include "stream.h"
41 #include "unaligned.h"
42 #include "timeval.h"
43 #include "unixctl.h"
44 #include "reconnect.h"
45
46 VLOG_DEFINE_THIS_MODULE(netdev_dummy);
47
48 struct reconnect;
49
50 struct dummy_packet_stream {
51     struct stream *stream;
52     struct dp_packet rxbuf;
53     struct ovs_list txq;
54 };
55
56 enum dummy_packet_conn_type {
57     NONE,       /* No connection is configured. */
58     PASSIVE,    /* Listener. */
59     ACTIVE      /* Connect to listener. */
60 };
61
62 enum dummy_netdev_conn_state {
63     CONN_STATE_CONNECTED,      /* Listener connected. */
64     CONN_STATE_NOT_CONNECTED,  /* Listener not connected.  */
65     CONN_STATE_UNKNOWN,        /* No relavent information.  */
66 };
67
68 struct dummy_packet_pconn {
69     struct pstream *pstream;
70     struct dummy_packet_stream *streams;
71     size_t n_streams;
72 };
73
74 struct dummy_packet_rconn {
75     struct dummy_packet_stream *rstream;
76     struct reconnect *reconnect;
77 };
78
79 struct dummy_packet_conn {
80     enum dummy_packet_conn_type type;
81     union {
82         struct dummy_packet_pconn pconn;
83         struct dummy_packet_rconn rconn;
84     } u;
85 };
86
87 struct pkt_list_node {
88     struct dp_packet *pkt;
89     struct ovs_list list_node;
90 };
91
92 /* Protects 'dummy_list'. */
93 static struct ovs_mutex dummy_list_mutex = OVS_MUTEX_INITIALIZER;
94
95 /* Contains all 'struct dummy_dev's. */
96 static struct ovs_list dummy_list OVS_GUARDED_BY(dummy_list_mutex)
97     = OVS_LIST_INITIALIZER(&dummy_list);
98
99 struct netdev_dummy {
100     struct netdev up;
101
102     /* In dummy_list. */
103     struct ovs_list list_node OVS_GUARDED_BY(dummy_list_mutex);
104
105     /* Protects all members below. */
106     struct ovs_mutex mutex OVS_ACQ_AFTER(dummy_list_mutex);
107
108     struct eth_addr hwaddr OVS_GUARDED;
109     int mtu OVS_GUARDED;
110     struct netdev_stats stats OVS_GUARDED;
111     enum netdev_flags flags OVS_GUARDED;
112     int ifindex OVS_GUARDED;
113
114     struct dummy_packet_conn conn OVS_GUARDED;
115
116     FILE *tx_pcap, *rxq_pcap OVS_GUARDED;
117
118     struct in_addr address, netmask;
119     struct in6_addr ipv6, ipv6_mask;
120     struct ovs_list rxes OVS_GUARDED; /* List of child "netdev_rxq_dummy"s. */
121
122     /* The following properties are for dummy-pmd and they cannot be changed
123      * when a device is running, so we remember the request and update them
124      * next time netdev_dummy_reconfigure() is called. */
125     int requested_n_txq;
126     int requested_n_rxq;
127 };
128
129 /* Max 'recv_queue_len' in struct netdev_dummy. */
130 #define NETDEV_DUMMY_MAX_QUEUE 100
131
132 struct netdev_rxq_dummy {
133     struct netdev_rxq up;
134     struct ovs_list node;       /* In netdev_dummy's "rxes" list. */
135     struct ovs_list recv_queue;
136     int recv_queue_len;         /* ovs_list_size(&recv_queue). */
137     struct seq *seq;            /* Reports newly queued packets. */
138 };
139
140 static unixctl_cb_func netdev_dummy_set_admin_state;
141 static int netdev_dummy_construct(struct netdev *);
142 static void netdev_dummy_queue_packet(struct netdev_dummy *,
143                                       struct dp_packet *, int);
144
145 static void dummy_packet_stream_close(struct dummy_packet_stream *);
146
147 static void pkt_list_delete(struct ovs_list *);
148
149 static bool
150 is_dummy_class(const struct netdev_class *class)
151 {
152     return class->construct == netdev_dummy_construct;
153 }
154
155 static struct netdev_dummy *
156 netdev_dummy_cast(const struct netdev *netdev)
157 {
158     ovs_assert(is_dummy_class(netdev_get_class(netdev)));
159     return CONTAINER_OF(netdev, struct netdev_dummy, up);
160 }
161
162 static struct netdev_rxq_dummy *
163 netdev_rxq_dummy_cast(const struct netdev_rxq *rx)
164 {
165     ovs_assert(is_dummy_class(netdev_get_class(rx->netdev)));
166     return CONTAINER_OF(rx, struct netdev_rxq_dummy, up);
167 }
168
169 static void
170 dummy_packet_stream_init(struct dummy_packet_stream *s, struct stream *stream)
171 {
172     int rxbuf_size = stream ? 2048 : 0;
173     s->stream = stream;
174     dp_packet_init(&s->rxbuf, rxbuf_size);
175     ovs_list_init(&s->txq);
176 }
177
178 static struct dummy_packet_stream *
179 dummy_packet_stream_create(struct stream *stream)
180 {
181     struct dummy_packet_stream *s;
182
183     s = xzalloc(sizeof *s);
184     dummy_packet_stream_init(s, stream);
185
186     return s;
187 }
188
189 static void
190 dummy_packet_stream_wait(struct dummy_packet_stream *s)
191 {
192     stream_run_wait(s->stream);
193     if (!ovs_list_is_empty(&s->txq)) {
194         stream_send_wait(s->stream);
195     }
196     stream_recv_wait(s->stream);
197 }
198
199 static void
200 dummy_packet_stream_send(struct dummy_packet_stream *s, const void *buffer, size_t size)
201 {
202     if (ovs_list_size(&s->txq) < NETDEV_DUMMY_MAX_QUEUE) {
203         struct dp_packet *b;
204         struct pkt_list_node *node;
205
206         b = dp_packet_clone_data_with_headroom(buffer, size, 2);
207         put_unaligned_be16(dp_packet_push_uninit(b, 2), htons(size));
208
209         node = xmalloc(sizeof *node);
210         node->pkt = b;
211         ovs_list_push_back(&s->txq, &node->list_node);
212     }
213 }
214
215 static int
216 dummy_packet_stream_run(struct netdev_dummy *dev, struct dummy_packet_stream *s)
217 {
218     int error = 0;
219     size_t n;
220
221     stream_run(s->stream);
222
223     if (!ovs_list_is_empty(&s->txq)) {
224         struct pkt_list_node *txbuf_node;
225         struct dp_packet *txbuf;
226         int retval;
227
228         ASSIGN_CONTAINER(txbuf_node, ovs_list_front(&s->txq), list_node);
229         txbuf = txbuf_node->pkt;
230         retval = stream_send(s->stream, dp_packet_data(txbuf), dp_packet_size(txbuf));
231
232         if (retval > 0) {
233             dp_packet_pull(txbuf, retval);
234             if (!dp_packet_size(txbuf)) {
235                 ovs_list_remove(&txbuf_node->list_node);
236                 free(txbuf_node);
237                 dp_packet_delete(txbuf);
238             }
239         } else if (retval != -EAGAIN) {
240             error = -retval;
241         }
242     }
243
244     if (!error) {
245         if (dp_packet_size(&s->rxbuf) < 2) {
246             n = 2 - dp_packet_size(&s->rxbuf);
247         } else {
248             uint16_t frame_len;
249
250             frame_len = ntohs(get_unaligned_be16(dp_packet_data(&s->rxbuf)));
251             if (frame_len < ETH_HEADER_LEN) {
252                 error = EPROTO;
253                 n = 0;
254             } else {
255                 n = (2 + frame_len) - dp_packet_size(&s->rxbuf);
256             }
257         }
258     }
259     if (!error) {
260         int retval;
261
262         dp_packet_prealloc_tailroom(&s->rxbuf, n);
263         retval = stream_recv(s->stream, dp_packet_tail(&s->rxbuf), n);
264
265         if (retval > 0) {
266             dp_packet_set_size(&s->rxbuf, dp_packet_size(&s->rxbuf) + retval);
267             if (retval == n && dp_packet_size(&s->rxbuf) > 2) {
268                 dp_packet_pull(&s->rxbuf, 2);
269                 netdev_dummy_queue_packet(dev,
270                                           dp_packet_clone(&s->rxbuf), 0);
271                 dp_packet_clear(&s->rxbuf);
272             }
273         } else if (retval != -EAGAIN) {
274             error = (retval < 0 ? -retval
275                      : dp_packet_size(&s->rxbuf) ? EPROTO
276                      : EOF);
277         }
278     }
279
280     return error;
281 }
282
283 static void
284 dummy_packet_stream_close(struct dummy_packet_stream *s)
285 {
286     stream_close(s->stream);
287     dp_packet_uninit(&s->rxbuf);
288     pkt_list_delete(&s->txq);
289 }
290
291 static void
292 dummy_packet_conn_init(struct dummy_packet_conn *conn)
293 {
294     memset(conn, 0, sizeof *conn);
295     conn->type = NONE;
296 }
297
298 static void
299 dummy_packet_conn_get_config(struct dummy_packet_conn *conn, struct smap *args)
300 {
301
302     switch (conn->type) {
303     case PASSIVE:
304         smap_add(args, "pstream", pstream_get_name(conn->u.pconn.pstream));
305         break;
306
307     case ACTIVE:
308         smap_add(args, "stream", stream_get_name(conn->u.rconn.rstream->stream));
309         break;
310
311     case NONE:
312     default:
313         break;
314     }
315 }
316
317 static void
318 dummy_packet_conn_close(struct dummy_packet_conn *conn)
319 {
320     int i;
321     struct dummy_packet_pconn *pconn = &conn->u.pconn;
322     struct dummy_packet_rconn *rconn = &conn->u.rconn;
323
324     switch (conn->type) {
325     case PASSIVE:
326         pstream_close(pconn->pstream);
327         for (i = 0; i < pconn->n_streams; i++) {
328             dummy_packet_stream_close(&pconn->streams[i]);
329         }
330         free(pconn->streams);
331         pconn->pstream = NULL;
332         pconn->streams = NULL;
333         break;
334
335     case ACTIVE:
336         dummy_packet_stream_close(rconn->rstream);
337         free(rconn->rstream);
338         rconn->rstream = NULL;
339         reconnect_destroy(rconn->reconnect);
340         rconn->reconnect = NULL;
341         break;
342
343     case NONE:
344     default:
345         break;
346     }
347
348     conn->type = NONE;
349     memset(conn, 0, sizeof *conn);
350 }
351
352 static void
353 dummy_packet_conn_set_config(struct dummy_packet_conn *conn,
354                              const struct smap *args)
355 {
356     const char *pstream = smap_get(args, "pstream");
357     const char *stream = smap_get(args, "stream");
358
359     if (pstream && stream) {
360          VLOG_WARN("Open failed: both %s and %s are configured",
361                    pstream, stream);
362          return;
363     }
364
365     switch (conn->type) {
366     case PASSIVE:
367         if (pstream &&
368             !strcmp(pstream_get_name(conn->u.pconn.pstream), pstream)) {
369             return;
370         }
371         dummy_packet_conn_close(conn);
372         break;
373     case ACTIVE:
374         if (stream &&
375             !strcmp(stream_get_name(conn->u.rconn.rstream->stream), stream)) {
376             return;
377         }
378         dummy_packet_conn_close(conn);
379         break;
380     case NONE:
381     default:
382         break;
383     }
384
385     if (pstream) {
386         int error;
387
388         error = pstream_open(pstream, &conn->u.pconn.pstream, DSCP_DEFAULT);
389         if (error) {
390             VLOG_WARN("%s: open failed (%s)", pstream, ovs_strerror(error));
391         } else {
392             conn->type = PASSIVE;
393         }
394     }
395
396     if (stream) {
397         int error;
398         struct stream *active_stream;
399         struct reconnect *reconnect;
400
401         reconnect = reconnect_create(time_msec());
402         reconnect_set_name(reconnect, stream);
403         reconnect_set_passive(reconnect, false, time_msec());
404         reconnect_enable(reconnect, time_msec());
405         reconnect_set_backoff(reconnect, 100, INT_MAX);
406         reconnect_set_probe_interval(reconnect, 0);
407         conn->u.rconn.reconnect = reconnect;
408         conn->type = ACTIVE;
409
410         error = stream_open(stream, &active_stream, DSCP_DEFAULT);
411         conn->u.rconn.rstream = dummy_packet_stream_create(active_stream);
412
413         switch (error) {
414         case 0:
415             reconnect_connected(reconnect, time_msec());
416             break;
417
418         case EAGAIN:
419             reconnect_connecting(reconnect, time_msec());
420             break;
421
422         default:
423             reconnect_connect_failed(reconnect, time_msec(), error);
424             stream_close(active_stream);
425             conn->u.rconn.rstream->stream = NULL;
426             break;
427         }
428     }
429 }
430
431 static void
432 dummy_pconn_run(struct netdev_dummy *dev)
433     OVS_REQUIRES(dev->mutex)
434 {
435     struct stream *new_stream;
436     struct dummy_packet_pconn *pconn = &dev->conn.u.pconn;
437     int error;
438     size_t i;
439
440     error = pstream_accept(pconn->pstream, &new_stream);
441     if (!error) {
442         struct dummy_packet_stream *s;
443
444         pconn->streams = xrealloc(pconn->streams,
445                                 ((pconn->n_streams + 1)
446                                  * sizeof *s));
447         s = &pconn->streams[pconn->n_streams++];
448         dummy_packet_stream_init(s, new_stream);
449     } else if (error != EAGAIN) {
450         VLOG_WARN("%s: accept failed (%s)",
451                   pstream_get_name(pconn->pstream), ovs_strerror(error));
452         pstream_close(pconn->pstream);
453         pconn->pstream = NULL;
454         dev->conn.type = NONE;
455     }
456
457     for (i = 0; i < pconn->n_streams; i++) {
458         struct dummy_packet_stream *s = &pconn->streams[i];
459
460         error = dummy_packet_stream_run(dev, s);
461         if (error) {
462             VLOG_DBG("%s: closing connection (%s)",
463                      stream_get_name(s->stream),
464                      ovs_retval_to_string(error));
465             dummy_packet_stream_close(s);
466             pconn->streams[i] = pconn->streams[--pconn->n_streams];
467         }
468     }
469 }
470
471 static void
472 dummy_rconn_run(struct netdev_dummy *dev)
473 OVS_REQUIRES(dev->mutex)
474 {
475     struct dummy_packet_rconn *rconn = &dev->conn.u.rconn;
476
477     switch (reconnect_run(rconn->reconnect, time_msec())) {
478     case RECONNECT_CONNECT:
479         {
480             int error;
481
482             if (rconn->rstream->stream) {
483                 error = stream_connect(rconn->rstream->stream);
484             } else {
485                 error = stream_open(reconnect_get_name(rconn->reconnect),
486                                     &rconn->rstream->stream, DSCP_DEFAULT);
487             }
488
489             switch (error) {
490             case 0:
491                 reconnect_connected(rconn->reconnect, time_msec());
492                 break;
493
494             case EAGAIN:
495                 reconnect_connecting(rconn->reconnect, time_msec());
496                 break;
497
498             default:
499                 reconnect_connect_failed(rconn->reconnect, time_msec(), error);
500                 stream_close(rconn->rstream->stream);
501                 rconn->rstream->stream = NULL;
502                 break;
503             }
504         }
505         break;
506
507     case RECONNECT_DISCONNECT:
508     case RECONNECT_PROBE:
509     default:
510         break;
511     }
512
513     if (reconnect_is_connected(rconn->reconnect)) {
514         int err;
515
516         err = dummy_packet_stream_run(dev, rconn->rstream);
517
518         if (err) {
519             reconnect_disconnected(rconn->reconnect, time_msec(), err);
520             stream_close(rconn->rstream->stream);
521             rconn->rstream->stream = NULL;
522         }
523     }
524 }
525
526 static void
527 dummy_packet_conn_run(struct netdev_dummy *dev)
528     OVS_REQUIRES(dev->mutex)
529 {
530     switch (dev->conn.type) {
531     case PASSIVE:
532         dummy_pconn_run(dev);
533         break;
534
535     case ACTIVE:
536         dummy_rconn_run(dev);
537         break;
538
539     case NONE:
540     default:
541         break;
542     }
543 }
544
545 static void
546 dummy_packet_conn_wait(struct dummy_packet_conn *conn)
547 {
548     int i;
549     switch (conn->type) {
550     case PASSIVE:
551         pstream_wait(conn->u.pconn.pstream);
552         for (i = 0; i < conn->u.pconn.n_streams; i++) {
553             struct dummy_packet_stream *s = &conn->u.pconn.streams[i];
554             dummy_packet_stream_wait(s);
555         }
556         break;
557     case ACTIVE:
558         if (reconnect_is_connected(conn->u.rconn.reconnect)) {
559             dummy_packet_stream_wait(conn->u.rconn.rstream);
560         }
561         break;
562
563     case NONE:
564     default:
565         break;
566     }
567 }
568
569 static void
570 dummy_packet_conn_send(struct dummy_packet_conn *conn,
571                        const void *buffer, size_t size)
572 {
573     int i;
574
575     switch (conn->type) {
576     case PASSIVE:
577         for (i = 0; i < conn->u.pconn.n_streams; i++) {
578             struct dummy_packet_stream *s = &conn->u.pconn.streams[i];
579
580             dummy_packet_stream_send(s, buffer, size);
581             pstream_wait(conn->u.pconn.pstream);
582         }
583         break;
584
585     case ACTIVE:
586         if (reconnect_is_connected(conn->u.rconn.reconnect)) {
587             dummy_packet_stream_send(conn->u.rconn.rstream, buffer, size);
588             dummy_packet_stream_wait(conn->u.rconn.rstream);
589         }
590         break;
591
592     case NONE:
593     default:
594         break;
595     }
596 }
597
598 static enum dummy_netdev_conn_state
599 dummy_netdev_get_conn_state(struct dummy_packet_conn *conn)
600 {
601     enum dummy_netdev_conn_state state;
602
603     if (conn->type == ACTIVE) {
604         if (reconnect_is_connected(conn->u.rconn.reconnect)) {
605             state = CONN_STATE_CONNECTED;
606         } else {
607             state = CONN_STATE_NOT_CONNECTED;
608         }
609     } else {
610         state = CONN_STATE_UNKNOWN;
611     }
612
613     return state;
614 }
615
616 static void
617 netdev_dummy_run(void)
618 {
619     struct netdev_dummy *dev;
620
621     ovs_mutex_lock(&dummy_list_mutex);
622     LIST_FOR_EACH (dev, list_node, &dummy_list) {
623         ovs_mutex_lock(&dev->mutex);
624         dummy_packet_conn_run(dev);
625         ovs_mutex_unlock(&dev->mutex);
626     }
627     ovs_mutex_unlock(&dummy_list_mutex);
628 }
629
630 static void
631 netdev_dummy_wait(void)
632 {
633     struct netdev_dummy *dev;
634
635     ovs_mutex_lock(&dummy_list_mutex);
636     LIST_FOR_EACH (dev, list_node, &dummy_list) {
637         ovs_mutex_lock(&dev->mutex);
638         dummy_packet_conn_wait(&dev->conn);
639         ovs_mutex_unlock(&dev->mutex);
640     }
641     ovs_mutex_unlock(&dummy_list_mutex);
642 }
643
644 static struct netdev *
645 netdev_dummy_alloc(void)
646 {
647     struct netdev_dummy *netdev = xzalloc(sizeof *netdev);
648     return &netdev->up;
649 }
650
651 static int
652 netdev_dummy_construct(struct netdev *netdev_)
653 {
654     static atomic_count next_n = ATOMIC_COUNT_INIT(0xaa550000);
655     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
656     unsigned int n;
657
658     n = atomic_count_inc(&next_n);
659
660     ovs_mutex_init(&netdev->mutex);
661     ovs_mutex_lock(&netdev->mutex);
662     netdev->hwaddr.ea[0] = 0xaa;
663     netdev->hwaddr.ea[1] = 0x55;
664     netdev->hwaddr.ea[2] = n >> 24;
665     netdev->hwaddr.ea[3] = n >> 16;
666     netdev->hwaddr.ea[4] = n >> 8;
667     netdev->hwaddr.ea[5] = n;
668     netdev->mtu = 1500;
669     netdev->flags = 0;
670     netdev->ifindex = -EOPNOTSUPP;
671     netdev->requested_n_rxq = netdev_->n_rxq;
672     netdev->requested_n_txq = netdev_->n_txq;
673
674     dummy_packet_conn_init(&netdev->conn);
675
676     ovs_list_init(&netdev->rxes);
677     ovs_mutex_unlock(&netdev->mutex);
678
679     ovs_mutex_lock(&dummy_list_mutex);
680     ovs_list_push_back(&dummy_list, &netdev->list_node);
681     ovs_mutex_unlock(&dummy_list_mutex);
682
683     return 0;
684 }
685
686 static void
687 netdev_dummy_destruct(struct netdev *netdev_)
688 {
689     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
690
691     ovs_mutex_lock(&dummy_list_mutex);
692     ovs_list_remove(&netdev->list_node);
693     ovs_mutex_unlock(&dummy_list_mutex);
694
695     ovs_mutex_lock(&netdev->mutex);
696     dummy_packet_conn_close(&netdev->conn);
697     netdev->conn.type = NONE;
698
699     ovs_mutex_unlock(&netdev->mutex);
700     ovs_mutex_destroy(&netdev->mutex);
701 }
702
703 static void
704 netdev_dummy_dealloc(struct netdev *netdev_)
705 {
706     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
707
708     free(netdev);
709 }
710
711 static int
712 netdev_dummy_get_config(const struct netdev *dev, struct smap *args)
713 {
714     struct netdev_dummy *netdev = netdev_dummy_cast(dev);
715
716     ovs_mutex_lock(&netdev->mutex);
717
718     if (netdev->ifindex >= 0) {
719         smap_add_format(args, "ifindex", "%d", netdev->ifindex);
720     }
721
722     dummy_packet_conn_get_config(&netdev->conn, args);
723
724     /* 'dummy-pmd' specific config. */
725     if (!netdev_is_pmd(dev)) {
726         goto exit;
727     }
728     smap_add_format(args, "requested_rx_queues", "%d", netdev->requested_n_rxq);
729     smap_add_format(args, "configured_rx_queues", "%d", dev->n_rxq);
730     smap_add_format(args, "requested_tx_queues", "%d", netdev->requested_n_txq);
731     smap_add_format(args, "configured_tx_queues", "%d", dev->n_txq);
732
733 exit:
734     ovs_mutex_unlock(&netdev->mutex);
735     return 0;
736 }
737
738 static int
739 netdev_dummy_get_addr_list(const struct netdev *netdev_, struct in6_addr **paddr,
740                            struct in6_addr **pmask, int *n_addr)
741 {
742     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
743     int cnt = 0, i = 0, err = 0;
744     struct in6_addr *addr, *mask;
745
746     ovs_mutex_lock(&netdev->mutex);
747     if (netdev->address.s_addr != INADDR_ANY) {
748         cnt++;
749     }
750
751     if (ipv6_addr_is_set(&netdev->ipv6)) {
752         cnt++;
753     }
754     if (!cnt) {
755         err = EADDRNOTAVAIL;
756         goto out;
757     }
758     addr = xmalloc(sizeof *addr * cnt);
759     mask = xmalloc(sizeof *mask * cnt);
760     if (netdev->address.s_addr != INADDR_ANY) {
761         in6_addr_set_mapped_ipv4(&addr[i], netdev->address.s_addr);
762         in6_addr_set_mapped_ipv4(&mask[i], netdev->netmask.s_addr);
763         i++;
764     }
765
766     if (ipv6_addr_is_set(&netdev->ipv6)) {
767         memcpy(&addr[i], &netdev->ipv6, sizeof *addr);
768         memcpy(&mask[i], &netdev->ipv6_mask, sizeof *mask);
769         i++;
770     }
771     if (paddr) {
772         *paddr = addr;
773         *pmask = mask;
774         *n_addr = cnt;
775     } else {
776         free(addr);
777         free(mask);
778     }
779 out:
780     ovs_mutex_unlock(&netdev->mutex);
781
782     return err;
783 }
784
785 static int
786 netdev_dummy_set_in4(struct netdev *netdev_, struct in_addr address,
787                      struct in_addr netmask)
788 {
789     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
790
791     ovs_mutex_lock(&netdev->mutex);
792     netdev->address = address;
793     netdev->netmask = netmask;
794     netdev_change_seq_changed(netdev_);
795     ovs_mutex_unlock(&netdev->mutex);
796
797     return 0;
798 }
799
800 static int
801 netdev_dummy_set_in6(struct netdev *netdev_, struct in6_addr *in6,
802                      struct in6_addr *mask)
803 {
804     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
805
806     ovs_mutex_lock(&netdev->mutex);
807     netdev->ipv6 = *in6;
808     netdev->ipv6_mask = *mask;
809     netdev_change_seq_changed(netdev_);
810     ovs_mutex_unlock(&netdev->mutex);
811
812     return 0;
813 }
814
815 static int
816 netdev_dummy_set_config(struct netdev *netdev_, const struct smap *args)
817 {
818     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
819     const char *pcap;
820     int new_n_rxq;
821
822     ovs_mutex_lock(&netdev->mutex);
823     netdev->ifindex = smap_get_int(args, "ifindex", -EOPNOTSUPP);
824
825     dummy_packet_conn_set_config(&netdev->conn, args);
826
827     if (netdev->rxq_pcap) {
828         fclose(netdev->rxq_pcap);
829     }
830     if (netdev->tx_pcap && netdev->tx_pcap != netdev->rxq_pcap) {
831         fclose(netdev->tx_pcap);
832     }
833     netdev->rxq_pcap = netdev->tx_pcap = NULL;
834     pcap = smap_get(args, "pcap");
835     if (pcap) {
836         netdev->rxq_pcap = netdev->tx_pcap = ovs_pcap_open(pcap, "ab");
837     } else {
838         const char *rxq_pcap = smap_get(args, "rxq_pcap");
839         const char *tx_pcap = smap_get(args, "tx_pcap");
840
841         if (rxq_pcap) {
842             netdev->rxq_pcap = ovs_pcap_open(rxq_pcap, "ab");
843         }
844         if (tx_pcap) {
845             netdev->tx_pcap = ovs_pcap_open(tx_pcap, "ab");
846         }
847     }
848
849     netdev_change_seq_changed(netdev_);
850
851     /* 'dummy-pmd' specific config. */
852     if (!netdev_->netdev_class->is_pmd) {
853         goto exit;
854     }
855
856     new_n_rxq = MAX(smap_get_int(args, "n_rxq", netdev->requested_n_rxq), 1);
857     if (new_n_rxq != netdev->requested_n_rxq) {
858         netdev->requested_n_rxq = new_n_rxq;
859         netdev_request_reconfigure(netdev_);
860     }
861
862 exit:
863     ovs_mutex_unlock(&netdev->mutex);
864     return 0;
865 }
866
867 static int
868 netdev_dummy_get_numa_id(const struct netdev *netdev_ OVS_UNUSED)
869 {
870     return 0;
871 }
872
873 /* Requests the number of tx queues for the dummy PMD interface. */
874 static int
875 netdev_dummy_set_tx_multiq(struct netdev *netdev_, unsigned int n_txq)
876 {
877     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
878
879     ovs_mutex_lock(&netdev->mutex);
880
881     if (netdev_->n_txq == n_txq) {
882         goto out;
883     }
884
885     netdev->requested_n_txq = n_txq;
886     netdev_request_reconfigure(netdev_);
887
888 out:
889     ovs_mutex_unlock(&netdev->mutex);
890     return 0;
891 }
892
893 /* Sets the number of tx queues and rx queues for the dummy PMD interface. */
894 static int
895 netdev_dummy_reconfigure(struct netdev *netdev_)
896 {
897     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
898
899     ovs_mutex_lock(&netdev->mutex);
900
901     netdev_->n_txq = netdev->requested_n_txq;
902     netdev_->n_rxq = netdev->requested_n_rxq;
903
904     ovs_mutex_unlock(&netdev->mutex);
905     return 0;
906 }
907
908 static struct netdev_rxq *
909 netdev_dummy_rxq_alloc(void)
910 {
911     struct netdev_rxq_dummy *rx = xzalloc(sizeof *rx);
912     return &rx->up;
913 }
914
915 static int
916 netdev_dummy_rxq_construct(struct netdev_rxq *rxq_)
917 {
918     struct netdev_rxq_dummy *rx = netdev_rxq_dummy_cast(rxq_);
919     struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev);
920
921     ovs_mutex_lock(&netdev->mutex);
922     ovs_list_push_back(&netdev->rxes, &rx->node);
923     ovs_list_init(&rx->recv_queue);
924     rx->recv_queue_len = 0;
925     rx->seq = seq_create();
926     ovs_mutex_unlock(&netdev->mutex);
927
928     return 0;
929 }
930
931 static void
932 netdev_dummy_rxq_destruct(struct netdev_rxq *rxq_)
933 {
934     struct netdev_rxq_dummy *rx = netdev_rxq_dummy_cast(rxq_);
935     struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev);
936
937     ovs_mutex_lock(&netdev->mutex);
938     ovs_list_remove(&rx->node);
939     pkt_list_delete(&rx->recv_queue);
940     ovs_mutex_unlock(&netdev->mutex);
941     seq_destroy(rx->seq);
942 }
943
944 static void
945 netdev_dummy_rxq_dealloc(struct netdev_rxq *rxq_)
946 {
947     struct netdev_rxq_dummy *rx = netdev_rxq_dummy_cast(rxq_);
948
949     free(rx);
950 }
951
952 static int
953 netdev_dummy_rxq_recv(struct netdev_rxq *rxq_, struct dp_packet **arr,
954                       int *c)
955 {
956     struct netdev_rxq_dummy *rx = netdev_rxq_dummy_cast(rxq_);
957     struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev);
958     struct dp_packet *packet;
959
960     ovs_mutex_lock(&netdev->mutex);
961     if (!ovs_list_is_empty(&rx->recv_queue)) {
962         struct pkt_list_node *pkt_node;
963
964         ASSIGN_CONTAINER(pkt_node, ovs_list_pop_front(&rx->recv_queue), list_node);
965         packet = pkt_node->pkt;
966         free(pkt_node);
967         rx->recv_queue_len--;
968     } else {
969         packet = NULL;
970     }
971     ovs_mutex_unlock(&netdev->mutex);
972
973     if (!packet) {
974         return EAGAIN;
975     }
976     ovs_mutex_lock(&netdev->mutex);
977     netdev->stats.rx_packets++;
978     netdev->stats.rx_bytes += dp_packet_size(packet);
979     ovs_mutex_unlock(&netdev->mutex);
980
981     dp_packet_pad(packet);
982
983     arr[0] = packet;
984     *c = 1;
985     return 0;
986 }
987
988 static void
989 netdev_dummy_rxq_wait(struct netdev_rxq *rxq_)
990 {
991     struct netdev_rxq_dummy *rx = netdev_rxq_dummy_cast(rxq_);
992     struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev);
993     uint64_t seq = seq_read(rx->seq);
994
995     ovs_mutex_lock(&netdev->mutex);
996     if (!ovs_list_is_empty(&rx->recv_queue)) {
997         poll_immediate_wake();
998     } else {
999         seq_wait(rx->seq, seq);
1000     }
1001     ovs_mutex_unlock(&netdev->mutex);
1002 }
1003
1004 static int
1005 netdev_dummy_rxq_drain(struct netdev_rxq *rxq_)
1006 {
1007     struct netdev_rxq_dummy *rx = netdev_rxq_dummy_cast(rxq_);
1008     struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev);
1009
1010     ovs_mutex_lock(&netdev->mutex);
1011     pkt_list_delete(&rx->recv_queue);
1012     rx->recv_queue_len = 0;
1013     ovs_mutex_unlock(&netdev->mutex);
1014
1015     seq_change(rx->seq);
1016
1017     return 0;
1018 }
1019
1020 static int
1021 netdev_dummy_send(struct netdev *netdev, int qid OVS_UNUSED,
1022                   struct dp_packet **pkts, int cnt, bool may_steal)
1023 {
1024     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
1025     int error = 0;
1026     int i;
1027
1028     for (i = 0; i < cnt; i++) {
1029         const void *buffer = dp_packet_data(pkts[i]);
1030         size_t size = dp_packet_size(pkts[i]);
1031
1032         if (size < ETH_HEADER_LEN) {
1033             error = EMSGSIZE;
1034             break;
1035         } else {
1036             const struct eth_header *eth = buffer;
1037             int max_size;
1038
1039             ovs_mutex_lock(&dev->mutex);
1040             max_size = dev->mtu + ETH_HEADER_LEN;
1041             ovs_mutex_unlock(&dev->mutex);
1042
1043             if (eth->eth_type == htons(ETH_TYPE_VLAN)) {
1044                 max_size += VLAN_HEADER_LEN;
1045             }
1046             if (size > max_size) {
1047                 error = EMSGSIZE;
1048                 break;
1049             }
1050         }
1051
1052         ovs_mutex_lock(&dev->mutex);
1053         dev->stats.tx_packets++;
1054         dev->stats.tx_bytes += size;
1055
1056         dummy_packet_conn_send(&dev->conn, buffer, size);
1057
1058         /* Reply to ARP requests for 'dev''s assigned IP address. */
1059         if (dev->address.s_addr) {
1060             struct dp_packet packet;
1061             struct flow flow;
1062
1063             dp_packet_use_const(&packet, buffer, size);
1064             flow_extract(&packet, &flow);
1065             if (flow.dl_type == htons(ETH_TYPE_ARP)
1066                 && flow.nw_proto == ARP_OP_REQUEST
1067                 && flow.nw_dst == dev->address.s_addr) {
1068                 struct dp_packet *reply = dp_packet_new(0);
1069                 compose_arp(reply, ARP_OP_REPLY, dev->hwaddr, flow.dl_src,
1070                             false, flow.nw_dst, flow.nw_src);
1071                 netdev_dummy_queue_packet(dev, reply, 0);
1072             }
1073         }
1074
1075         if (dev->tx_pcap) {
1076             struct dp_packet packet;
1077
1078             dp_packet_use_const(&packet, buffer, size);
1079             ovs_pcap_write(dev->tx_pcap, &packet);
1080             fflush(dev->tx_pcap);
1081         }
1082
1083         ovs_mutex_unlock(&dev->mutex);
1084     }
1085
1086     if (may_steal) {
1087         for (i = 0; i < cnt; i++) {
1088             dp_packet_delete(pkts[i]);
1089         }
1090     }
1091
1092     return error;
1093 }
1094
1095 static int
1096 netdev_dummy_set_etheraddr(struct netdev *netdev, const struct eth_addr mac)
1097 {
1098     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
1099
1100     ovs_mutex_lock(&dev->mutex);
1101     if (!eth_addr_equals(dev->hwaddr, mac)) {
1102         dev->hwaddr = mac;
1103         netdev_change_seq_changed(netdev);
1104     }
1105     ovs_mutex_unlock(&dev->mutex);
1106
1107     return 0;
1108 }
1109
1110 static int
1111 netdev_dummy_get_etheraddr(const struct netdev *netdev, struct eth_addr *mac)
1112 {
1113     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
1114
1115     ovs_mutex_lock(&dev->mutex);
1116     *mac = dev->hwaddr;
1117     ovs_mutex_unlock(&dev->mutex);
1118
1119     return 0;
1120 }
1121
1122 static int
1123 netdev_dummy_get_mtu(const struct netdev *netdev, int *mtup)
1124 {
1125     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
1126
1127     ovs_mutex_lock(&dev->mutex);
1128     *mtup = dev->mtu;
1129     ovs_mutex_unlock(&dev->mutex);
1130
1131     return 0;
1132 }
1133
1134 static int
1135 netdev_dummy_set_mtu(const struct netdev *netdev, int mtu)
1136 {
1137     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
1138
1139     ovs_mutex_lock(&dev->mutex);
1140     dev->mtu = mtu;
1141     ovs_mutex_unlock(&dev->mutex);
1142
1143     return 0;
1144 }
1145
1146 static int
1147 netdev_dummy_get_stats(const struct netdev *netdev, struct netdev_stats *stats)
1148 {
1149     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
1150
1151     ovs_mutex_lock(&dev->mutex);
1152     /* Passing only collected counters */
1153     stats->tx_packets = dev->stats.tx_packets;
1154     stats->tx_bytes = dev->stats.tx_bytes;
1155     stats->rx_packets = dev->stats.rx_packets;
1156     stats->rx_bytes = dev->stats.rx_bytes;
1157     ovs_mutex_unlock(&dev->mutex);
1158
1159     return 0;
1160 }
1161
1162 static int
1163 netdev_dummy_get_queue(const struct netdev *netdev OVS_UNUSED,
1164                        unsigned int queue_id, struct smap *details OVS_UNUSED)
1165 {
1166     if (queue_id == 0) {
1167         return 0;
1168     } else {
1169         return EINVAL;
1170     }
1171 }
1172
1173 static void
1174 netdev_dummy_init_queue_stats(struct netdev_queue_stats *stats)
1175 {
1176     *stats = (struct netdev_queue_stats) {
1177         .tx_bytes = UINT64_MAX,
1178         .tx_packets = UINT64_MAX,
1179         .tx_errors = UINT64_MAX,
1180         .created = LLONG_MIN,
1181     };
1182 }
1183
1184 static int
1185 netdev_dummy_get_queue_stats(const struct netdev *netdev OVS_UNUSED,
1186                              unsigned int queue_id,
1187                              struct netdev_queue_stats *stats)
1188 {
1189     if (queue_id == 0) {
1190         netdev_dummy_init_queue_stats(stats);
1191         return 0;
1192     } else {
1193         return EINVAL;
1194     }
1195 }
1196
1197 struct netdev_dummy_queue_state {
1198     unsigned int next_queue;
1199 };
1200
1201 static int
1202 netdev_dummy_queue_dump_start(const struct netdev *netdev OVS_UNUSED,
1203                               void **statep)
1204 {
1205     struct netdev_dummy_queue_state *state = xmalloc(sizeof *state);
1206     state->next_queue = 0;
1207     *statep = state;
1208     return 0;
1209 }
1210
1211 static int
1212 netdev_dummy_queue_dump_next(const struct netdev *netdev OVS_UNUSED,
1213                              void *state_,
1214                              unsigned int *queue_id,
1215                              struct smap *details OVS_UNUSED)
1216 {
1217     struct netdev_dummy_queue_state *state = state_;
1218     if (state->next_queue == 0) {
1219         *queue_id = 0;
1220         state->next_queue++;
1221         return 0;
1222     } else {
1223         return EOF;
1224     }
1225 }
1226
1227 static int
1228 netdev_dummy_queue_dump_done(const struct netdev *netdev OVS_UNUSED,
1229                              void *state)
1230 {
1231     free(state);
1232     return 0;
1233 }
1234
1235 static int
1236 netdev_dummy_dump_queue_stats(const struct netdev *netdev OVS_UNUSED,
1237                               void (*cb)(unsigned int queue_id,
1238                                          struct netdev_queue_stats *,
1239                                          void *aux),
1240                               void *aux)
1241 {
1242     struct netdev_queue_stats stats;
1243     netdev_dummy_init_queue_stats(&stats);
1244     cb(0, &stats, aux);
1245     return 0;
1246 }
1247
1248 static int
1249 netdev_dummy_get_ifindex(const struct netdev *netdev)
1250 {
1251     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
1252     int ifindex;
1253
1254     ovs_mutex_lock(&dev->mutex);
1255     ifindex = dev->ifindex;
1256     ovs_mutex_unlock(&dev->mutex);
1257
1258     return ifindex;
1259 }
1260
1261 static int
1262 netdev_dummy_update_flags__(struct netdev_dummy *netdev,
1263                             enum netdev_flags off, enum netdev_flags on,
1264                             enum netdev_flags *old_flagsp)
1265     OVS_REQUIRES(netdev->mutex)
1266 {
1267     if ((off | on) & ~(NETDEV_UP | NETDEV_PROMISC)) {
1268         return EINVAL;
1269     }
1270
1271     *old_flagsp = netdev->flags;
1272     netdev->flags |= on;
1273     netdev->flags &= ~off;
1274     if (*old_flagsp != netdev->flags) {
1275         netdev_change_seq_changed(&netdev->up);
1276     }
1277
1278     return 0;
1279 }
1280
1281 static int
1282 netdev_dummy_update_flags(struct netdev *netdev_,
1283                           enum netdev_flags off, enum netdev_flags on,
1284                           enum netdev_flags *old_flagsp)
1285 {
1286     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
1287     int error;
1288
1289     ovs_mutex_lock(&netdev->mutex);
1290     error = netdev_dummy_update_flags__(netdev, off, on, old_flagsp);
1291     ovs_mutex_unlock(&netdev->mutex);
1292
1293     return error;
1294 }
1295 \f
1296 /* Helper functions. */
1297
1298 #define NETDEV_DUMMY_CLASS(NAME, PMD, TX_MULTIQ, RECOFIGURE)       \
1299 {                                                               \
1300     NAME,                                                       \
1301     PMD,                        /* is_pmd */                    \
1302     NULL,                       /* init */                      \
1303     netdev_dummy_run,                                           \
1304     netdev_dummy_wait,                                          \
1305                                                                 \
1306     netdev_dummy_alloc,                                         \
1307     netdev_dummy_construct,                                     \
1308     netdev_dummy_destruct,                                      \
1309     netdev_dummy_dealloc,                                       \
1310     netdev_dummy_get_config,                                    \
1311     netdev_dummy_set_config,                                    \
1312     NULL,                       /* get_tunnel_config */         \
1313     NULL,                       /* build header */              \
1314     NULL,                       /* push header */               \
1315     NULL,                       /* pop header */                \
1316     netdev_dummy_get_numa_id,                                   \
1317     TX_MULTIQ,                                                  \
1318                                                                 \
1319     netdev_dummy_send,          /* send */                      \
1320     NULL,                       /* send_wait */                 \
1321                                                                 \
1322     netdev_dummy_set_etheraddr,                                 \
1323     netdev_dummy_get_etheraddr,                                 \
1324     netdev_dummy_get_mtu,                                       \
1325     netdev_dummy_set_mtu,                                       \
1326     netdev_dummy_get_ifindex,                                   \
1327     NULL,                       /* get_carrier */               \
1328     NULL,                       /* get_carrier_resets */        \
1329     NULL,                       /* get_miimon */                \
1330     netdev_dummy_get_stats,                                     \
1331                                                                 \
1332     NULL,                       /* get_features */              \
1333     NULL,                       /* set_advertisements */        \
1334                                                                 \
1335     NULL,                       /* set_policing */              \
1336     NULL,                       /* get_qos_types */             \
1337     NULL,                       /* get_qos_capabilities */      \
1338     NULL,                       /* get_qos */                   \
1339     NULL,                       /* set_qos */                   \
1340     netdev_dummy_get_queue,                                     \
1341     NULL,                       /* set_queue */                 \
1342     NULL,                       /* delete_queue */              \
1343     netdev_dummy_get_queue_stats,                               \
1344     netdev_dummy_queue_dump_start,                              \
1345     netdev_dummy_queue_dump_next,                               \
1346     netdev_dummy_queue_dump_done,                               \
1347     netdev_dummy_dump_queue_stats,                              \
1348                                                                 \
1349     NULL,                       /* set_in4 */                   \
1350     netdev_dummy_get_addr_list,                                 \
1351     NULL,                       /* add_router */                \
1352     NULL,                       /* get_next_hop */              \
1353     NULL,                       /* get_status */                \
1354     NULL,                       /* arp_lookup */                \
1355                                                                 \
1356     netdev_dummy_update_flags,                                  \
1357     RECOFIGURE,                                                 \
1358                                                                 \
1359     netdev_dummy_rxq_alloc,                                     \
1360     netdev_dummy_rxq_construct,                                 \
1361     netdev_dummy_rxq_destruct,                                  \
1362     netdev_dummy_rxq_dealloc,                                   \
1363     netdev_dummy_rxq_recv,                                      \
1364     netdev_dummy_rxq_wait,                                      \
1365     netdev_dummy_rxq_drain,                                     \
1366 }
1367
1368 static const struct netdev_class dummy_class =
1369     NETDEV_DUMMY_CLASS("dummy", false, NULL, NULL);
1370
1371 static const struct netdev_class dummy_pmd_class =
1372     NETDEV_DUMMY_CLASS("dummy-pmd", true,
1373                        netdev_dummy_set_tx_multiq,
1374                        netdev_dummy_reconfigure);
1375
1376 static void
1377 pkt_list_delete(struct ovs_list *l)
1378 {
1379     struct pkt_list_node *pkt;
1380
1381     LIST_FOR_EACH_POP(pkt, list_node, l) {
1382         dp_packet_delete(pkt->pkt);
1383         free(pkt);
1384     }
1385 }
1386
1387 static struct dp_packet *
1388 eth_from_packet_or_flow(const char *s)
1389 {
1390     enum odp_key_fitness fitness;
1391     struct dp_packet *packet;
1392     struct ofpbuf odp_key;
1393     struct flow flow;
1394     int error;
1395
1396     if (!eth_from_hex(s, &packet)) {
1397         return packet;
1398     }
1399
1400     /* Convert string to datapath key.
1401      *
1402      * It would actually be nicer to parse an OpenFlow-like flow key here, but
1403      * the code for that currently calls exit() on parse error.  We have to
1404      * settle for parsing a datapath key for now.
1405      */
1406     ofpbuf_init(&odp_key, 0);
1407     error = odp_flow_from_string(s, NULL, &odp_key, NULL);
1408     if (error) {
1409         ofpbuf_uninit(&odp_key);
1410         return NULL;
1411     }
1412
1413     /* Convert odp_key to flow. */
1414     fitness = odp_flow_key_to_flow(odp_key.data, odp_key.size, &flow);
1415     if (fitness == ODP_FIT_ERROR) {
1416         ofpbuf_uninit(&odp_key);
1417         return NULL;
1418     }
1419
1420     packet = dp_packet_new(0);
1421     flow_compose(packet, &flow);
1422
1423     ofpbuf_uninit(&odp_key);
1424     return packet;
1425 }
1426
1427 static void
1428 netdev_dummy_queue_packet__(struct netdev_rxq_dummy *rx, struct dp_packet *packet)
1429 {
1430     struct pkt_list_node *pkt_node = xmalloc(sizeof *pkt_node);
1431
1432     pkt_node->pkt = packet;
1433     ovs_list_push_back(&rx->recv_queue, &pkt_node->list_node);
1434     rx->recv_queue_len++;
1435     seq_change(rx->seq);
1436 }
1437
1438 static void
1439 netdev_dummy_queue_packet(struct netdev_dummy *dummy, struct dp_packet *packet,
1440                           int queue_id)
1441     OVS_REQUIRES(dummy->mutex)
1442 {
1443     struct netdev_rxq_dummy *rx, *prev;
1444
1445     if (dummy->rxq_pcap) {
1446         ovs_pcap_write(dummy->rxq_pcap, packet);
1447         fflush(dummy->rxq_pcap);
1448     }
1449     prev = NULL;
1450     LIST_FOR_EACH (rx, node, &dummy->rxes) {
1451         if (rx->up.queue_id == queue_id &&
1452             rx->recv_queue_len < NETDEV_DUMMY_MAX_QUEUE) {
1453             if (prev) {
1454                 netdev_dummy_queue_packet__(prev, dp_packet_clone(packet));
1455             }
1456             prev = rx;
1457         }
1458     }
1459     if (prev) {
1460         netdev_dummy_queue_packet__(prev, packet);
1461     } else {
1462         dp_packet_delete(packet);
1463     }
1464 }
1465
1466 static void
1467 netdev_dummy_receive(struct unixctl_conn *conn,
1468                      int argc, const char *argv[], void *aux OVS_UNUSED)
1469 {
1470     struct netdev_dummy *dummy_dev;
1471     struct netdev *netdev;
1472     int i, k = 1, rx_qid = 0;
1473
1474     netdev = netdev_from_name(argv[k++]);
1475     if (!netdev || !is_dummy_class(netdev->netdev_class)) {
1476         unixctl_command_reply_error(conn, "no such dummy netdev");
1477         goto exit_netdev;
1478     }
1479     dummy_dev = netdev_dummy_cast(netdev);
1480
1481     ovs_mutex_lock(&dummy_dev->mutex);
1482
1483     if (argc > k + 1 && !strcmp(argv[k], "--qid")) {
1484         rx_qid = strtol(argv[k + 1], NULL, 10);
1485         if (rx_qid < 0 || rx_qid >= netdev->n_rxq) {
1486             unixctl_command_reply_error(conn, "bad rx queue id.");
1487             goto exit;
1488         }
1489         k += 2;
1490     }
1491
1492     for (i = k; i < argc; i++) {
1493         struct dp_packet *packet;
1494
1495         packet = eth_from_packet_or_flow(argv[i]);
1496         if (!packet) {
1497             unixctl_command_reply_error(conn, "bad packet syntax");
1498             goto exit;
1499         }
1500
1501         netdev_dummy_queue_packet(dummy_dev, packet, rx_qid);
1502     }
1503
1504     unixctl_command_reply(conn, NULL);
1505
1506 exit:
1507     ovs_mutex_unlock(&dummy_dev->mutex);
1508 exit_netdev:
1509     netdev_close(netdev);
1510 }
1511
1512 static void
1513 netdev_dummy_set_admin_state__(struct netdev_dummy *dev, bool admin_state)
1514     OVS_REQUIRES(dev->mutex)
1515 {
1516     enum netdev_flags old_flags;
1517
1518     if (admin_state) {
1519         netdev_dummy_update_flags__(dev, 0, NETDEV_UP, &old_flags);
1520     } else {
1521         netdev_dummy_update_flags__(dev, NETDEV_UP, 0, &old_flags);
1522     }
1523 }
1524
1525 static void
1526 netdev_dummy_set_admin_state(struct unixctl_conn *conn, int argc,
1527                              const char *argv[], void *aux OVS_UNUSED)
1528 {
1529     bool up;
1530
1531     if (!strcasecmp(argv[argc - 1], "up")) {
1532         up = true;
1533     } else if ( !strcasecmp(argv[argc - 1], "down")) {
1534         up = false;
1535     } else {
1536         unixctl_command_reply_error(conn, "Invalid Admin State");
1537         return;
1538     }
1539
1540     if (argc > 2) {
1541         struct netdev *netdev = netdev_from_name(argv[1]);
1542         if (netdev && is_dummy_class(netdev->netdev_class)) {
1543             struct netdev_dummy *dummy_dev = netdev_dummy_cast(netdev);
1544
1545             ovs_mutex_lock(&dummy_dev->mutex);
1546             netdev_dummy_set_admin_state__(dummy_dev, up);
1547             ovs_mutex_unlock(&dummy_dev->mutex);
1548
1549             netdev_close(netdev);
1550         } else {
1551             unixctl_command_reply_error(conn, "Unknown Dummy Interface");
1552             netdev_close(netdev);
1553             return;
1554         }
1555     } else {
1556         struct netdev_dummy *netdev;
1557
1558         ovs_mutex_lock(&dummy_list_mutex);
1559         LIST_FOR_EACH (netdev, list_node, &dummy_list) {
1560             ovs_mutex_lock(&netdev->mutex);
1561             netdev_dummy_set_admin_state__(netdev, up);
1562             ovs_mutex_unlock(&netdev->mutex);
1563         }
1564         ovs_mutex_unlock(&dummy_list_mutex);
1565     }
1566     unixctl_command_reply(conn, "OK");
1567 }
1568
1569 static void
1570 display_conn_state__(struct ds *s, const char *name,
1571                      enum dummy_netdev_conn_state state)
1572 {
1573     ds_put_format(s, "%s: ", name);
1574
1575     switch (state) {
1576     case CONN_STATE_CONNECTED:
1577         ds_put_cstr(s, "connected\n");
1578         break;
1579
1580     case CONN_STATE_NOT_CONNECTED:
1581         ds_put_cstr(s, "disconnected\n");
1582         break;
1583
1584     case CONN_STATE_UNKNOWN:
1585     default:
1586         ds_put_cstr(s, "unknown\n");
1587         break;
1588     };
1589 }
1590
1591 static void
1592 netdev_dummy_conn_state(struct unixctl_conn *conn, int argc,
1593                         const char *argv[], void *aux OVS_UNUSED)
1594 {
1595     enum dummy_netdev_conn_state state = CONN_STATE_UNKNOWN;
1596     struct ds s;
1597
1598     ds_init(&s);
1599
1600     if (argc > 1) {
1601         const char *dev_name = argv[1];
1602         struct netdev *netdev = netdev_from_name(dev_name);
1603
1604         if (netdev && is_dummy_class(netdev->netdev_class)) {
1605             struct netdev_dummy *dummy_dev = netdev_dummy_cast(netdev);
1606
1607             ovs_mutex_lock(&dummy_dev->mutex);
1608             state = dummy_netdev_get_conn_state(&dummy_dev->conn);
1609             ovs_mutex_unlock(&dummy_dev->mutex);
1610
1611             netdev_close(netdev);
1612         }
1613         display_conn_state__(&s, dev_name, state);
1614     } else {
1615         struct netdev_dummy *netdev;
1616
1617         ovs_mutex_lock(&dummy_list_mutex);
1618         LIST_FOR_EACH (netdev, list_node, &dummy_list) {
1619             ovs_mutex_lock(&netdev->mutex);
1620             state = dummy_netdev_get_conn_state(&netdev->conn);
1621             ovs_mutex_unlock(&netdev->mutex);
1622             if (state != CONN_STATE_UNKNOWN) {
1623                 display_conn_state__(&s, netdev->up.name, state);
1624             }
1625         }
1626         ovs_mutex_unlock(&dummy_list_mutex);
1627     }
1628
1629     unixctl_command_reply(conn, ds_cstr(&s));
1630     ds_destroy(&s);
1631 }
1632
1633 static void
1634 netdev_dummy_ip4addr(struct unixctl_conn *conn, int argc OVS_UNUSED,
1635                      const char *argv[], void *aux OVS_UNUSED)
1636 {
1637     struct netdev *netdev = netdev_from_name(argv[1]);
1638
1639     if (netdev && is_dummy_class(netdev->netdev_class)) {
1640         struct in_addr ip, mask;
1641         char *error;
1642
1643         error = ip_parse_masked(argv[2], &ip.s_addr, &mask.s_addr);
1644         if (!error) {
1645             netdev_dummy_set_in4(netdev, ip, mask);
1646             unixctl_command_reply(conn, "OK");
1647         } else {
1648             unixctl_command_reply_error(conn, error);
1649             free(error);
1650         }
1651     } else {
1652         unixctl_command_reply_error(conn, "Unknown Dummy Interface");
1653     }
1654
1655     netdev_close(netdev);
1656 }
1657
1658 static void
1659 netdev_dummy_ip6addr(struct unixctl_conn *conn, int argc OVS_UNUSED,
1660                      const char *argv[], void *aux OVS_UNUSED)
1661 {
1662     struct netdev *netdev = netdev_from_name(argv[1]);
1663
1664     if (netdev && is_dummy_class(netdev->netdev_class)) {
1665         struct in6_addr ip6;
1666         char *error;
1667         uint32_t plen;
1668
1669         error = ipv6_parse_cidr(argv[2], &ip6, &plen);
1670         if (!error) {
1671             struct in6_addr mask;
1672
1673             mask = ipv6_create_mask(plen);
1674             netdev_dummy_set_in6(netdev, &ip6, &mask);
1675             unixctl_command_reply(conn, "OK");
1676         } else {
1677             unixctl_command_reply_error(conn, error);
1678             free(error);
1679         }
1680         netdev_close(netdev);
1681     } else {
1682         unixctl_command_reply_error(conn, "Unknown Dummy Interface");
1683     }
1684
1685     netdev_close(netdev);
1686 }
1687
1688
1689 static void
1690 netdev_dummy_override(const char *type)
1691 {
1692     if (!netdev_unregister_provider(type)) {
1693         struct netdev_class *class;
1694         int error;
1695
1696         class = xmemdup(&dummy_class, sizeof dummy_class);
1697         class->type = xstrdup(type);
1698         error = netdev_register_provider(class);
1699         if (error) {
1700             VLOG_ERR("%s: failed to register netdev provider (%s)",
1701                      type, ovs_strerror(error));
1702             free(CONST_CAST(char *, class->type));
1703             free(class);
1704         }
1705     }
1706 }
1707
1708 void
1709 netdev_dummy_register(enum dummy_level level)
1710 {
1711     unixctl_command_register("netdev-dummy/receive",
1712                              "name [--qid queue_id] packet|flow...",
1713                              2, INT_MAX, netdev_dummy_receive, NULL);
1714     unixctl_command_register("netdev-dummy/set-admin-state",
1715                              "[netdev] up|down", 1, 2,
1716                              netdev_dummy_set_admin_state, NULL);
1717     unixctl_command_register("netdev-dummy/conn-state",
1718                              "[netdev]", 0, 1,
1719                              netdev_dummy_conn_state, NULL);
1720     unixctl_command_register("netdev-dummy/ip4addr",
1721                              "[netdev] ipaddr/mask-prefix-len", 2, 2,
1722                              netdev_dummy_ip4addr, NULL);
1723     unixctl_command_register("netdev-dummy/ip6addr",
1724                              "[netdev] ip6addr", 2, 2,
1725                              netdev_dummy_ip6addr, NULL);
1726
1727     if (level == DUMMY_OVERRIDE_ALL) {
1728         struct sset types;
1729         const char *type;
1730
1731         sset_init(&types);
1732         netdev_enumerate_types(&types);
1733         SSET_FOR_EACH (type, &types) {
1734             if (strcmp(type, "patch")) {
1735                 netdev_dummy_override(type);
1736             }
1737         }
1738         sset_destroy(&types);
1739     } else if (level == DUMMY_OVERRIDE_SYSTEM) {
1740         netdev_dummy_override("system");
1741     }
1742     netdev_register_provider(&dummy_class);
1743     netdev_register_provider(&dummy_pmd_class);
1744
1745     netdev_vport_tunnel_register();
1746 }