f23fc9fd33f25f8093e661b25a13411bff5e8bfb
[sliver-openvswitch.git] / lib / netdev-dummy.c
1 /*
2  * Copyright (c) 2010, 2011, 2012, 2013 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 "connectivity.h"
24 #include "flow.h"
25 #include "list.h"
26 #include "netdev-provider.h"
27 #include "netdev-vport.h"
28 #include "odp-util.h"
29 #include "ofp-print.h"
30 #include "ofpbuf.h"
31 #include "packets.h"
32 #include "pcap-file.h"
33 #include "poll-loop.h"
34 #include "seq.h"
35 #include "shash.h"
36 #include "sset.h"
37 #include "stream.h"
38 #include "unaligned.h"
39 #include "timeval.h"
40 #include "unixctl.h"
41 #include "reconnect.h"
42 #include "vlog.h"
43
44 VLOG_DEFINE_THIS_MODULE(netdev_dummy);
45
46 struct reconnect;
47
48 struct dummy_packet_stream {
49     struct stream *stream;
50     struct ofpbuf rxbuf;
51     struct list txq;
52 };
53
54 enum dummy_packet_conn_type {
55     NONE,       /* No connection is configured. */
56     PASSIVE,    /* Listener. */
57     ACTIVE      /* Connect to listener. */
58 };
59
60 struct dummy_packet_pconn {
61     struct pstream *pstream;
62     struct dummy_packet_stream *streams;
63     size_t n_streams;
64 };
65
66 struct dummy_packet_rconn {
67     struct dummy_packet_stream *rstream;
68     struct reconnect *reconnect;
69 };
70
71 struct dummy_packet_conn {
72     enum dummy_packet_conn_type type;
73     union {
74         struct dummy_packet_pconn pconn;
75         struct dummy_packet_rconn rconn;
76     } u;
77 };
78
79 /* Protects 'dummy_list'. */
80 static struct ovs_mutex dummy_list_mutex = OVS_MUTEX_INITIALIZER;
81
82 /* Contains all 'struct dummy_dev's. */
83 static struct list dummy_list OVS_GUARDED_BY(dummy_list_mutex)
84     = LIST_INITIALIZER(&dummy_list);
85
86 struct netdev_dummy {
87     struct netdev up;
88
89     /* In dummy_list. */
90     struct list list_node OVS_GUARDED_BY(dummy_list_mutex);
91
92     /* Protects all members below. */
93     struct ovs_mutex mutex OVS_ACQ_AFTER(dummy_list_mutex);
94
95     uint8_t hwaddr[ETH_ADDR_LEN] OVS_GUARDED;
96     int mtu OVS_GUARDED;
97     struct netdev_stats stats OVS_GUARDED;
98     enum netdev_flags flags OVS_GUARDED;
99     int ifindex OVS_GUARDED;
100
101     struct dummy_packet_conn conn OVS_GUARDED;
102
103     FILE *tx_pcap, *rx_pcap OVS_GUARDED;
104
105     struct list rxes OVS_GUARDED; /* List of child "netdev_rx_dummy"s. */
106 };
107
108 /* Max 'recv_queue_len' in struct netdev_dummy. */
109 #define NETDEV_DUMMY_MAX_QUEUE 100
110
111 struct netdev_rx_dummy {
112     struct netdev_rx up;
113     struct list node;           /* In netdev_dummy's "rxes" list. */
114     struct list recv_queue;
115     int recv_queue_len;         /* list_size(&recv_queue). */
116     struct seq *seq;            /* Reports newly queued packets. */
117 };
118
119 static unixctl_cb_func netdev_dummy_set_admin_state;
120 static int netdev_dummy_construct(struct netdev *);
121 static void netdev_dummy_queue_packet(struct netdev_dummy *, struct ofpbuf *);
122
123 static void dummy_packet_stream_close(struct dummy_packet_stream *);
124
125 static bool
126 is_dummy_class(const struct netdev_class *class)
127 {
128     return class->construct == netdev_dummy_construct;
129 }
130
131 static struct netdev_dummy *
132 netdev_dummy_cast(const struct netdev *netdev)
133 {
134     ovs_assert(is_dummy_class(netdev_get_class(netdev)));
135     return CONTAINER_OF(netdev, struct netdev_dummy, up);
136 }
137
138 static struct netdev_rx_dummy *
139 netdev_rx_dummy_cast(const struct netdev_rx *rx)
140 {
141     ovs_assert(is_dummy_class(netdev_get_class(rx->netdev)));
142     return CONTAINER_OF(rx, struct netdev_rx_dummy, up);
143 }
144
145 static void
146 dummy_packet_stream_init(struct dummy_packet_stream *s, struct stream *stream)
147 {
148     int rxbuf_size = stream ? 2048 : 0;
149     s->stream = stream;
150     ofpbuf_init(&s->rxbuf, rxbuf_size);
151     list_init(&s->txq);
152 }
153
154 static struct dummy_packet_stream *
155 dummy_packet_stream_create(struct stream *stream)
156 {
157     struct dummy_packet_stream *s;
158
159     s = xzalloc(sizeof *s);
160     dummy_packet_stream_init(s, stream);
161
162     return s;
163 }
164
165 static void
166 dummy_packet_stream_wait(struct dummy_packet_stream *s)
167 {
168     stream_run_wait(s->stream);
169     if (!list_is_empty(&s->txq)) {
170         stream_send_wait(s->stream);
171     }
172     stream_recv_wait(s->stream);
173 }
174
175 static void
176 dummy_packet_stream_send(struct dummy_packet_stream *s, const void *buffer, size_t size)
177 {
178     if (list_size(&s->txq) < NETDEV_DUMMY_MAX_QUEUE) {
179         struct ofpbuf *b;
180
181         b = ofpbuf_clone_data_with_headroom(buffer, size, 2);
182         put_unaligned_be16(ofpbuf_push_uninit(b, 2), htons(size));
183         list_push_back(&s->txq, &b->list_node);
184     }
185 }
186
187 static int
188 dummy_packet_stream_run(struct netdev_dummy *dev, struct dummy_packet_stream *s)
189 {
190     int error = 0;
191     size_t n;
192
193     stream_run(s->stream);
194
195     if (!list_is_empty(&s->txq)) {
196         struct ofpbuf *txbuf;
197         int retval;
198
199         txbuf = ofpbuf_from_list(list_front(&s->txq));
200         retval = stream_send(s->stream, txbuf->data, txbuf->size);
201
202         if (retval > 0) {
203             ofpbuf_pull(txbuf, retval);
204             if (!txbuf->size) {
205                 list_remove(&txbuf->list_node);
206                 ofpbuf_delete(txbuf);
207             }
208         } else if (retval != -EAGAIN) {
209             error = -retval;
210         }
211     }
212
213     if (!error) {
214         if (s->rxbuf.size < 2) {
215             n = 2 - s->rxbuf.size;
216         } else {
217             uint16_t frame_len;
218
219             frame_len = ntohs(get_unaligned_be16(s->rxbuf.data));
220             if (frame_len < ETH_HEADER_LEN) {
221                 error = EPROTO;
222                 n = 0;
223             } else {
224                 n = (2 + frame_len) - s->rxbuf.size;
225             }
226         }
227     }
228     if (!error) {
229         int retval;
230
231         ofpbuf_prealloc_tailroom(&s->rxbuf, n);
232         retval = stream_recv(s->stream, ofpbuf_tail(&s->rxbuf), n);
233
234         if (retval > 0) {
235             s->rxbuf.size += retval;
236             if (retval == n && s->rxbuf.size > 2) {
237                 ofpbuf_pull(&s->rxbuf, 2);
238                 netdev_dummy_queue_packet(dev,
239                                           ofpbuf_clone(&s->rxbuf));
240                 ofpbuf_clear(&s->rxbuf);
241             }
242         } else if (retval != -EAGAIN) {
243             error = (retval < 0 ? -retval
244                      : s->rxbuf.size ? EPROTO
245                      : EOF);
246         }
247     }
248
249     return error;
250 }
251
252 static void
253 dummy_packet_stream_close(struct dummy_packet_stream *s)
254 {
255     stream_close(s->stream);
256     ofpbuf_uninit(&s->rxbuf);
257     ofpbuf_list_delete(&s->txq);
258 }
259
260 static void
261 dummy_packet_conn_init(struct dummy_packet_conn *conn)
262 {
263     memset(conn, 0, sizeof *conn);
264     conn->type = NONE;
265 }
266
267 static void
268 dummy_packet_conn_get_config(struct dummy_packet_conn *conn, struct smap *args)
269 {
270
271     switch (conn->type) {
272     case PASSIVE:
273         smap_add(args, "pstream", pstream_get_name(conn->u.pconn.pstream));
274         break;
275
276     case ACTIVE:
277         smap_add(args, "stream", stream_get_name(conn->u.rconn.rstream->stream));
278         break;
279
280     case NONE:
281     default:
282         break;
283     }
284 }
285
286 static void
287 dummy_packet_conn_close(struct dummy_packet_conn *conn)
288 {
289     int i;
290     struct dummy_packet_pconn *pconn = &conn->u.pconn;
291     struct dummy_packet_rconn *rconn = &conn->u.rconn;
292
293     switch (conn->type) {
294     case PASSIVE:
295         pstream_close(pconn->pstream);
296         for (i = 0; i < pconn->n_streams; i++) {
297             dummy_packet_stream_close(&pconn->streams[i]);
298         }
299         free(pconn->streams);
300         pconn->pstream = NULL;
301         pconn->streams = NULL;
302         break;
303
304     case ACTIVE:
305         dummy_packet_stream_close(rconn->rstream);
306         free(rconn->rstream);
307         rconn->rstream = NULL;
308         reconnect_destroy(rconn->reconnect);
309         rconn->reconnect = NULL;
310         break;
311
312     case NONE:
313     default:
314         break;
315     }
316
317     conn->type = NONE;
318     memset(conn, 0, sizeof *conn);
319 }
320
321 static void
322 dummy_packet_conn_set_config(struct dummy_packet_conn *conn,
323                              const struct smap *args)
324 {
325     const char *pstream = smap_get(args, "pstream");
326     const char *stream = smap_get(args, "stream");
327
328     if (pstream && stream) {
329          VLOG_WARN("Open failed: both %s and %s are configured",
330                    pstream, stream);
331          return;
332     }
333
334     switch (conn->type) {
335     case PASSIVE:
336         if (!strcmp(pstream_get_name(conn->u.pconn.pstream), pstream)) {
337             return;
338         }
339         dummy_packet_conn_close(conn);
340         break;
341     case ACTIVE:
342         if (!strcmp(stream_get_name(conn->u.rconn.rstream->stream), stream)) {
343             return;
344         }
345         dummy_packet_conn_close(conn);
346         break;
347     case NONE:
348     default:
349         break;
350     }
351
352     if (pstream) {
353         int error;
354
355         error = pstream_open(pstream, &conn->u.pconn.pstream, DSCP_DEFAULT);
356         if (error) {
357             VLOG_WARN("%s: open failed (%s)", pstream, ovs_strerror(error));
358         } else {
359             conn->type = PASSIVE;
360         }
361     }
362
363     if (stream) {
364         int error;
365         struct stream *active_stream;
366         struct reconnect *reconnect;;
367
368         reconnect = reconnect_create(time_msec());
369         reconnect_set_name(reconnect, stream);
370         reconnect_set_passive(reconnect, false, time_msec());
371         reconnect_enable(reconnect, time_msec());
372         reconnect_set_backoff(reconnect, 100, INT_MAX);
373         reconnect_set_probe_interval(reconnect, 0);
374         conn->u.rconn.reconnect = reconnect;
375         conn->type = ACTIVE;
376
377         error = stream_open(stream, &active_stream, DSCP_DEFAULT);
378         conn->u.rconn.rstream = dummy_packet_stream_create(active_stream);
379
380         switch (error) {
381         case 0:
382             reconnect_connected(reconnect, time_msec());
383             break;
384
385         case EAGAIN:
386             reconnect_connecting(reconnect, time_msec());
387             break;
388
389         default:
390             reconnect_connect_failed(reconnect, time_msec(), error);
391             stream_close(active_stream);
392             conn->u.rconn.rstream->stream = NULL;
393             break;
394         }
395     }
396 }
397
398 static void
399 dummy_pconn_run(struct netdev_dummy *dev)
400     OVS_REQUIRES(dev->mutex)
401 {
402     struct stream *new_stream;
403     struct dummy_packet_pconn *pconn = &dev->conn.u.pconn;
404     int error;
405     size_t i;
406
407     error = pstream_accept(pconn->pstream, &new_stream);
408     if (!error) {
409         struct dummy_packet_stream *s;
410
411         pconn->streams = xrealloc(pconn->streams,
412                                 ((pconn->n_streams + 1)
413                                  * sizeof *s));
414         s = &pconn->streams[pconn->n_streams++];
415         dummy_packet_stream_init(s, new_stream);
416     } else if (error != EAGAIN) {
417         VLOG_WARN("%s: accept failed (%s)",
418                   pstream_get_name(pconn->pstream), ovs_strerror(error));
419         pstream_close(pconn->pstream);
420         pconn->pstream = NULL;
421         dev->conn.type = NONE;
422     }
423
424     for (i = 0; i < pconn->n_streams; i++) {
425         struct dummy_packet_stream *s = &pconn->streams[i];
426
427         error = dummy_packet_stream_run(dev, s);
428         if (error) {
429             VLOG_DBG("%s: closing connection (%s)",
430                      stream_get_name(s->stream),
431                      ovs_retval_to_string(error));
432             dummy_packet_stream_close(s);
433             pconn->streams[i] = pconn->streams[--pconn->n_streams];
434         }
435     }
436 }
437
438 static void
439 dummy_rconn_run(struct netdev_dummy *dev)
440 OVS_REQUIRES(dev->mutex)
441 {
442     struct dummy_packet_rconn *rconn = &dev->conn.u.rconn;
443
444     switch (reconnect_run(rconn->reconnect, time_msec())) {
445     case RECONNECT_CONNECT:
446         {
447             int error;
448
449             if (rconn->rstream->stream) {
450                 error = stream_connect(rconn->rstream->stream);
451             } else {
452                 error = stream_open(reconnect_get_name(rconn->reconnect),
453                                     &rconn->rstream->stream, DSCP_DEFAULT);
454             }
455
456             switch (error) {
457             case 0:
458                 reconnect_connected(rconn->reconnect, time_msec());
459                 break;
460
461             case EAGAIN:
462                 reconnect_connecting(rconn->reconnect, time_msec());
463                 break;
464
465             default:
466                 reconnect_connect_failed(rconn->reconnect, time_msec(), error);
467                 stream_close(rconn->rstream->stream);
468                 rconn->rstream->stream = NULL;
469                 break;
470             }
471         }
472         break;
473
474     case RECONNECT_DISCONNECT:
475     case RECONNECT_PROBE:
476     default:
477         break;
478     }
479
480     if (reconnect_is_connected(rconn->reconnect)) {
481         int err;
482
483         err = dummy_packet_stream_run(dev, rconn->rstream);
484
485         if (err) {
486             reconnect_disconnected(rconn->reconnect, time_msec(), err);
487             stream_close(rconn->rstream->stream);
488             rconn->rstream->stream = NULL;
489         }
490     }
491 }
492
493 static void
494 dummy_packet_conn_run(struct netdev_dummy *dev)
495     OVS_REQUIRES(dev->mutex)
496 {
497     switch (dev->conn.type) {
498     case PASSIVE:
499         dummy_pconn_run(dev);
500         break;
501
502     case ACTIVE:
503         dummy_rconn_run(dev);
504         break;
505
506     case NONE:
507     default:
508         break;
509     }
510 }
511
512 static void
513 dummy_packet_conn_wait(struct dummy_packet_conn *conn)
514 {
515     int i;
516     switch (conn->type) {
517     case PASSIVE:
518         pstream_wait(conn->u.pconn.pstream);
519         for (i = 0; i < conn->u.pconn.n_streams; i++) {
520             struct dummy_packet_stream *s = &conn->u.pconn.streams[i];
521             dummy_packet_stream_wait(s);
522         }
523         break;
524     case ACTIVE:
525         if (reconnect_is_connected(conn->u.rconn.reconnect)) {
526             dummy_packet_stream_wait(conn->u.rconn.rstream);
527         }
528         break;
529
530     case NONE:
531     default:
532         break;
533     }
534 }
535
536 static void
537 dummy_packet_conn_send(struct dummy_packet_conn *conn,
538                        const void *buffer, size_t size)
539 {
540     int i;
541
542     switch (conn->type) {
543     case PASSIVE:
544         for (i = 0; i < conn->u.pconn.n_streams; i++) {
545             struct dummy_packet_stream *s = &conn->u.pconn.streams[i];
546
547             dummy_packet_stream_send(s, buffer, size);
548             pstream_wait(conn->u.pconn.pstream);
549         }
550         break;
551
552     case ACTIVE:
553         if (reconnect_is_connected(conn->u.rconn.reconnect)) {
554             dummy_packet_stream_send(conn->u.rconn.rstream, buffer, size);
555             dummy_packet_stream_wait(conn->u.rconn.rstream);
556         }
557         break;
558
559     case NONE:
560     default:
561         break;
562     }
563 }
564
565 static void
566 netdev_dummy_run(void)
567 {
568     struct netdev_dummy *dev;
569
570     ovs_mutex_lock(&dummy_list_mutex);
571     LIST_FOR_EACH (dev, list_node, &dummy_list) {
572         ovs_mutex_lock(&dev->mutex);
573         dummy_packet_conn_run(dev);
574         ovs_mutex_unlock(&dev->mutex);
575     }
576     ovs_mutex_unlock(&dummy_list_mutex);
577 }
578
579 static void
580 netdev_dummy_wait(void)
581 {
582     struct netdev_dummy *dev;
583
584     ovs_mutex_lock(&dummy_list_mutex);
585     LIST_FOR_EACH (dev, list_node, &dummy_list) {
586         ovs_mutex_lock(&dev->mutex);
587         dummy_packet_conn_wait(&dev->conn);
588         ovs_mutex_unlock(&dev->mutex);
589     }
590     ovs_mutex_unlock(&dummy_list_mutex);
591 }
592
593 static struct netdev *
594 netdev_dummy_alloc(void)
595 {
596     struct netdev_dummy *netdev = xzalloc(sizeof *netdev);
597     return &netdev->up;
598 }
599
600 static int
601 netdev_dummy_construct(struct netdev *netdev_)
602 {
603     static atomic_uint next_n = ATOMIC_VAR_INIT(0xaa550000);
604     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
605     unsigned int n;
606
607     atomic_add(&next_n, 1, &n);
608
609     ovs_mutex_init(&netdev->mutex);
610     ovs_mutex_lock(&netdev->mutex);
611     netdev->hwaddr[0] = 0xaa;
612     netdev->hwaddr[1] = 0x55;
613     netdev->hwaddr[2] = n >> 24;
614     netdev->hwaddr[3] = n >> 16;
615     netdev->hwaddr[4] = n >> 8;
616     netdev->hwaddr[5] = n;
617     netdev->mtu = 1500;
618     netdev->flags = 0;
619     netdev->ifindex = -EOPNOTSUPP;
620
621     dummy_packet_conn_init(&netdev->conn);
622
623     list_init(&netdev->rxes);
624     ovs_mutex_unlock(&netdev->mutex);
625
626     ovs_mutex_lock(&dummy_list_mutex);
627     list_push_back(&dummy_list, &netdev->list_node);
628     ovs_mutex_unlock(&dummy_list_mutex);
629
630     return 0;
631 }
632
633 static void
634 netdev_dummy_destruct(struct netdev *netdev_)
635 {
636     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
637
638     ovs_mutex_lock(&dummy_list_mutex);
639     list_remove(&netdev->list_node);
640     ovs_mutex_unlock(&dummy_list_mutex);
641
642     ovs_mutex_lock(&netdev->mutex);
643     dummy_packet_conn_close(&netdev->conn);
644     netdev->conn.type = NONE;
645
646     ovs_mutex_unlock(&netdev->mutex);
647     ovs_mutex_destroy(&netdev->mutex);
648 }
649
650 static void
651 netdev_dummy_dealloc(struct netdev *netdev_)
652 {
653     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
654
655     free(netdev);
656 }
657
658 static int
659 netdev_dummy_get_config(const struct netdev *netdev_, struct smap *args)
660 {
661     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
662
663     ovs_mutex_lock(&netdev->mutex);
664
665     if (netdev->ifindex >= 0) {
666         smap_add_format(args, "ifindex", "%d", netdev->ifindex);
667     }
668
669     dummy_packet_conn_get_config(&netdev->conn, args);
670
671     ovs_mutex_unlock(&netdev->mutex);
672     return 0;
673 }
674
675 static int
676 netdev_dummy_set_config(struct netdev *netdev_, const struct smap *args)
677 {
678     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
679     const char *pcap;
680
681     ovs_mutex_lock(&netdev->mutex);
682     netdev->ifindex = smap_get_int(args, "ifindex", -EOPNOTSUPP);
683
684     dummy_packet_conn_set_config(&netdev->conn, args);
685
686     if (netdev->rx_pcap) {
687         fclose(netdev->rx_pcap);
688     }
689     if (netdev->tx_pcap && netdev->tx_pcap != netdev->rx_pcap) {
690         fclose(netdev->tx_pcap);
691     }
692     netdev->rx_pcap = netdev->tx_pcap = NULL;
693     pcap = smap_get(args, "pcap");
694     if (pcap) {
695         netdev->rx_pcap = netdev->tx_pcap = ovs_pcap_open(pcap, "ab");
696     } else {
697         const char *rx_pcap = smap_get(args, "rx_pcap");
698         const char *tx_pcap = smap_get(args, "tx_pcap");
699
700         if (rx_pcap) {
701             netdev->rx_pcap = ovs_pcap_open(rx_pcap, "ab");
702         }
703         if (tx_pcap) {
704             netdev->tx_pcap = ovs_pcap_open(tx_pcap, "ab");
705         }
706     }
707
708     ovs_mutex_unlock(&netdev->mutex);
709
710     return 0;
711 }
712
713 static struct netdev_rx *
714 netdev_dummy_rx_alloc(void)
715 {
716     struct netdev_rx_dummy *rx = xzalloc(sizeof *rx);
717     return &rx->up;
718 }
719
720 static int
721 netdev_dummy_rx_construct(struct netdev_rx *rx_)
722 {
723     struct netdev_rx_dummy *rx = netdev_rx_dummy_cast(rx_);
724     struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev);
725
726     ovs_mutex_lock(&netdev->mutex);
727     list_push_back(&netdev->rxes, &rx->node);
728     list_init(&rx->recv_queue);
729     rx->recv_queue_len = 0;
730     rx->seq = seq_create();
731     ovs_mutex_unlock(&netdev->mutex);
732
733     return 0;
734 }
735
736 static void
737 netdev_dummy_rx_destruct(struct netdev_rx *rx_)
738 {
739     struct netdev_rx_dummy *rx = netdev_rx_dummy_cast(rx_);
740     struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev);
741
742     ovs_mutex_lock(&netdev->mutex);
743     list_remove(&rx->node);
744     ofpbuf_list_delete(&rx->recv_queue);
745     ovs_mutex_unlock(&netdev->mutex);
746     seq_destroy(rx->seq);
747 }
748
749 static void
750 netdev_dummy_rx_dealloc(struct netdev_rx *rx_)
751 {
752     struct netdev_rx_dummy *rx = netdev_rx_dummy_cast(rx_);
753
754     free(rx);
755 }
756
757 static int
758 netdev_dummy_rx_recv(struct netdev_rx *rx_, struct ofpbuf *buffer)
759 {
760     struct netdev_rx_dummy *rx = netdev_rx_dummy_cast(rx_);
761     struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev);
762     struct ofpbuf *packet;
763     int retval;
764
765     ovs_mutex_lock(&netdev->mutex);
766     if (!list_is_empty(&rx->recv_queue)) {
767         packet = ofpbuf_from_list(list_pop_front(&rx->recv_queue));
768         rx->recv_queue_len--;
769     } else {
770         packet = NULL;
771     }
772     ovs_mutex_unlock(&netdev->mutex);
773
774     if (!packet) {
775         return EAGAIN;
776     }
777
778     if (packet->size <= ofpbuf_tailroom(buffer)) {
779         memcpy(buffer->data, packet->data, packet->size);
780         buffer->size += packet->size;
781         retval = 0;
782
783         ovs_mutex_lock(&netdev->mutex);
784         netdev->stats.rx_packets++;
785         netdev->stats.rx_bytes += packet->size;
786         ovs_mutex_unlock(&netdev->mutex);
787     } else {
788         retval = EMSGSIZE;
789     }
790     ofpbuf_delete(packet);
791
792     return retval;
793 }
794
795 static void
796 netdev_dummy_rx_wait(struct netdev_rx *rx_)
797 {
798     struct netdev_rx_dummy *rx = netdev_rx_dummy_cast(rx_);
799     struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev);
800     uint64_t seq = seq_read(rx->seq);
801
802     ovs_mutex_lock(&netdev->mutex);
803     if (!list_is_empty(&rx->recv_queue)) {
804         poll_immediate_wake();
805     } else {
806         seq_wait(rx->seq, seq);
807     }
808     ovs_mutex_unlock(&netdev->mutex);
809 }
810
811 static int
812 netdev_dummy_rx_drain(struct netdev_rx *rx_)
813 {
814     struct netdev_rx_dummy *rx = netdev_rx_dummy_cast(rx_);
815     struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev);
816
817     ovs_mutex_lock(&netdev->mutex);
818     ofpbuf_list_delete(&rx->recv_queue);
819     rx->recv_queue_len = 0;
820     ovs_mutex_unlock(&netdev->mutex);
821
822     seq_change(rx->seq);
823
824     return 0;
825 }
826
827 static int
828 netdev_dummy_send(struct netdev *netdev, const void *buffer, size_t size)
829 {
830     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
831
832     if (size < ETH_HEADER_LEN) {
833         return EMSGSIZE;
834     } else {
835         const struct eth_header *eth = buffer;
836         int max_size;
837
838         ovs_mutex_lock(&dev->mutex);
839         max_size = dev->mtu + ETH_HEADER_LEN;
840         ovs_mutex_unlock(&dev->mutex);
841
842         if (eth->eth_type == htons(ETH_TYPE_VLAN)) {
843             max_size += VLAN_HEADER_LEN;
844         }
845         if (size > max_size) {
846             return EMSGSIZE;
847         }
848     }
849
850     ovs_mutex_lock(&dev->mutex);
851     dev->stats.tx_packets++;
852     dev->stats.tx_bytes += size;
853
854     dummy_packet_conn_send(&dev->conn, buffer, size);
855
856     if (dev->tx_pcap) {
857         struct ofpbuf packet;
858
859         ofpbuf_use_const(&packet, buffer, size);
860         ovs_pcap_write(dev->tx_pcap, &packet);
861         fflush(dev->tx_pcap);
862     }
863
864     ovs_mutex_unlock(&dev->mutex);
865
866     return 0;
867 }
868
869 static int
870 netdev_dummy_set_etheraddr(struct netdev *netdev,
871                            const uint8_t mac[ETH_ADDR_LEN])
872 {
873     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
874
875     ovs_mutex_lock(&dev->mutex);
876     if (!eth_addr_equals(dev->hwaddr, mac)) {
877         memcpy(dev->hwaddr, mac, ETH_ADDR_LEN);
878         seq_change(connectivity_seq_get());
879     }
880     ovs_mutex_unlock(&dev->mutex);
881
882     return 0;
883 }
884
885 static int
886 netdev_dummy_get_etheraddr(const struct netdev *netdev,
887                            uint8_t mac[ETH_ADDR_LEN])
888 {
889     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
890
891     ovs_mutex_lock(&dev->mutex);
892     memcpy(mac, dev->hwaddr, ETH_ADDR_LEN);
893     ovs_mutex_unlock(&dev->mutex);
894
895     return 0;
896 }
897
898 static int
899 netdev_dummy_get_mtu(const struct netdev *netdev, int *mtup)
900 {
901     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
902
903     ovs_mutex_lock(&dev->mutex);
904     *mtup = dev->mtu;
905     ovs_mutex_unlock(&dev->mutex);
906
907     return 0;
908 }
909
910 static int
911 netdev_dummy_set_mtu(const struct netdev *netdev, int mtu)
912 {
913     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
914
915     ovs_mutex_lock(&dev->mutex);
916     dev->mtu = mtu;
917     ovs_mutex_unlock(&dev->mutex);
918
919     return 0;
920 }
921
922 static int
923 netdev_dummy_get_stats(const struct netdev *netdev, struct netdev_stats *stats)
924 {
925     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
926
927     ovs_mutex_lock(&dev->mutex);
928     *stats = dev->stats;
929     ovs_mutex_unlock(&dev->mutex);
930
931     return 0;
932 }
933
934 static int
935 netdev_dummy_set_stats(struct netdev *netdev, const struct netdev_stats *stats)
936 {
937     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
938
939     ovs_mutex_lock(&dev->mutex);
940     dev->stats = *stats;
941     ovs_mutex_unlock(&dev->mutex);
942
943     return 0;
944 }
945
946 static int
947 netdev_dummy_get_ifindex(const struct netdev *netdev)
948 {
949     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
950     int ifindex;
951
952     ovs_mutex_lock(&dev->mutex);
953     ifindex = dev->ifindex;
954     ovs_mutex_unlock(&dev->mutex);
955
956     return ifindex;
957 }
958
959 static int
960 netdev_dummy_update_flags__(struct netdev_dummy *netdev,
961                             enum netdev_flags off, enum netdev_flags on,
962                             enum netdev_flags *old_flagsp)
963     OVS_REQUIRES(netdev->mutex)
964 {
965     if ((off | on) & ~(NETDEV_UP | NETDEV_PROMISC)) {
966         return EINVAL;
967     }
968
969     *old_flagsp = netdev->flags;
970     netdev->flags |= on;
971     netdev->flags &= ~off;
972     if (*old_flagsp != netdev->flags) {
973         seq_change(connectivity_seq_get());
974     }
975
976     return 0;
977 }
978
979 static int
980 netdev_dummy_update_flags(struct netdev *netdev_,
981                           enum netdev_flags off, enum netdev_flags on,
982                           enum netdev_flags *old_flagsp)
983 {
984     struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
985     int error;
986
987     ovs_mutex_lock(&netdev->mutex);
988     error = netdev_dummy_update_flags__(netdev, off, on, old_flagsp);
989     ovs_mutex_unlock(&netdev->mutex);
990
991     return error;
992 }
993 \f
994 /* Helper functions. */
995
996 static const struct netdev_class dummy_class = {
997     "dummy",
998     NULL,                       /* init */
999     netdev_dummy_run,
1000     netdev_dummy_wait,
1001
1002     netdev_dummy_alloc,
1003     netdev_dummy_construct,
1004     netdev_dummy_destruct,
1005     netdev_dummy_dealloc,
1006     netdev_dummy_get_config,
1007     netdev_dummy_set_config,
1008     NULL,                       /* get_tunnel_config */
1009
1010     netdev_dummy_send,          /* send */
1011     NULL,                       /* send_wait */
1012
1013     netdev_dummy_set_etheraddr,
1014     netdev_dummy_get_etheraddr,
1015     netdev_dummy_get_mtu,
1016     netdev_dummy_set_mtu,
1017     netdev_dummy_get_ifindex,
1018     NULL,                       /* get_carrier */
1019     NULL,                       /* get_carrier_resets */
1020     NULL,                       /* get_miimon */
1021     netdev_dummy_get_stats,
1022     netdev_dummy_set_stats,
1023
1024     NULL,                       /* get_features */
1025     NULL,                       /* set_advertisements */
1026
1027     NULL,                       /* set_policing */
1028     NULL,                       /* get_qos_types */
1029     NULL,                       /* get_qos_capabilities */
1030     NULL,                       /* get_qos */
1031     NULL,                       /* set_qos */
1032     NULL,                       /* get_queue */
1033     NULL,                       /* set_queue */
1034     NULL,                       /* delete_queue */
1035     NULL,                       /* get_queue_stats */
1036     NULL,                       /* queue_dump_start */
1037     NULL,                       /* queue_dump_next */
1038     NULL,                       /* queue_dump_done */
1039     NULL,                       /* dump_queue_stats */
1040
1041     NULL,                       /* get_in4 */
1042     NULL,                       /* set_in4 */
1043     NULL,                       /* get_in6 */
1044     NULL,                       /* add_router */
1045     NULL,                       /* get_next_hop */
1046     NULL,                       /* get_status */
1047     NULL,                       /* arp_lookup */
1048
1049     netdev_dummy_update_flags,
1050
1051     netdev_dummy_rx_alloc,
1052     netdev_dummy_rx_construct,
1053     netdev_dummy_rx_destruct,
1054     netdev_dummy_rx_dealloc,
1055     netdev_dummy_rx_recv,
1056     netdev_dummy_rx_wait,
1057     netdev_dummy_rx_drain,
1058 };
1059
1060 static struct ofpbuf *
1061 eth_from_packet_or_flow(const char *s)
1062 {
1063     enum odp_key_fitness fitness;
1064     struct ofpbuf *packet;
1065     struct ofpbuf odp_key;
1066     struct flow flow;
1067     int error;
1068
1069     if (!eth_from_hex(s, &packet)) {
1070         return packet;
1071     }
1072
1073     /* Convert string to datapath key.
1074      *
1075      * It would actually be nicer to parse an OpenFlow-like flow key here, but
1076      * the code for that currently calls exit() on parse error.  We have to
1077      * settle for parsing a datapath key for now.
1078      */
1079     ofpbuf_init(&odp_key, 0);
1080     error = odp_flow_from_string(s, NULL, &odp_key, NULL);
1081     if (error) {
1082         ofpbuf_uninit(&odp_key);
1083         return NULL;
1084     }
1085
1086     /* Convert odp_key to flow. */
1087     fitness = odp_flow_key_to_flow(odp_key.data, odp_key.size, &flow);
1088     if (fitness == ODP_FIT_ERROR) {
1089         ofpbuf_uninit(&odp_key);
1090         return NULL;
1091     }
1092
1093     packet = ofpbuf_new(0);
1094     flow_compose(packet, &flow);
1095
1096     ofpbuf_uninit(&odp_key);
1097     return packet;
1098 }
1099
1100 static void
1101 netdev_dummy_queue_packet__(struct netdev_rx_dummy *rx, struct ofpbuf *packet)
1102 {
1103     list_push_back(&rx->recv_queue, &packet->list_node);
1104     rx->recv_queue_len++;
1105     seq_change(rx->seq);
1106 }
1107
1108 static void
1109 netdev_dummy_queue_packet(struct netdev_dummy *dummy, struct ofpbuf *packet)
1110     OVS_REQUIRES(dummy->mutex)
1111 {
1112     struct netdev_rx_dummy *rx, *prev;
1113
1114     if (dummy->rx_pcap) {
1115         ovs_pcap_write(dummy->rx_pcap, packet);
1116         fflush(dummy->rx_pcap);
1117     }
1118     prev = NULL;
1119     LIST_FOR_EACH (rx, node, &dummy->rxes) {
1120         if (rx->recv_queue_len < NETDEV_DUMMY_MAX_QUEUE) {
1121             if (prev) {
1122                 netdev_dummy_queue_packet__(prev, ofpbuf_clone(packet));
1123             }
1124             prev = rx;
1125         }
1126     }
1127     if (prev) {
1128         netdev_dummy_queue_packet__(prev, packet);
1129     } else {
1130         ofpbuf_delete(packet);
1131     }
1132 }
1133
1134 static void
1135 netdev_dummy_receive(struct unixctl_conn *conn,
1136                      int argc, const char *argv[], void *aux OVS_UNUSED)
1137 {
1138     struct netdev_dummy *dummy_dev;
1139     struct netdev *netdev;
1140     int i;
1141
1142     netdev = netdev_from_name(argv[1]);
1143     if (!netdev || !is_dummy_class(netdev->netdev_class)) {
1144         unixctl_command_reply_error(conn, "no such dummy netdev");
1145         goto exit;
1146     }
1147     dummy_dev = netdev_dummy_cast(netdev);
1148
1149     for (i = 2; i < argc; i++) {
1150         struct ofpbuf *packet;
1151
1152         packet = eth_from_packet_or_flow(argv[i]);
1153         if (!packet) {
1154             unixctl_command_reply_error(conn, "bad packet syntax");
1155             goto exit;
1156         }
1157
1158         ovs_mutex_lock(&dummy_dev->mutex);
1159         netdev_dummy_queue_packet(dummy_dev, packet);
1160         ovs_mutex_unlock(&dummy_dev->mutex);
1161     }
1162
1163     unixctl_command_reply(conn, NULL);
1164
1165 exit:
1166     netdev_close(netdev);
1167 }
1168
1169 static void
1170 netdev_dummy_set_admin_state__(struct netdev_dummy *dev, bool admin_state)
1171     OVS_REQUIRES(dev->mutex)
1172 {
1173     enum netdev_flags old_flags;
1174
1175     if (admin_state) {
1176         netdev_dummy_update_flags__(dev, 0, NETDEV_UP, &old_flags);
1177     } else {
1178         netdev_dummy_update_flags__(dev, NETDEV_UP, 0, &old_flags);
1179     }
1180 }
1181
1182 static void
1183 netdev_dummy_set_admin_state(struct unixctl_conn *conn, int argc,
1184                              const char *argv[], void *aux OVS_UNUSED)
1185 {
1186     bool up;
1187
1188     if (!strcasecmp(argv[argc - 1], "up")) {
1189         up = true;
1190     } else if ( !strcasecmp(argv[argc - 1], "down")) {
1191         up = false;
1192     } else {
1193         unixctl_command_reply_error(conn, "Invalid Admin State");
1194         return;
1195     }
1196
1197     if (argc > 2) {
1198         struct netdev *netdev = netdev_from_name(argv[1]);
1199         if (netdev && is_dummy_class(netdev->netdev_class)) {
1200             struct netdev_dummy *dummy_dev = netdev_dummy_cast(netdev);
1201
1202             ovs_mutex_lock(&dummy_dev->mutex);
1203             netdev_dummy_set_admin_state__(dummy_dev, up);
1204             ovs_mutex_unlock(&dummy_dev->mutex);
1205
1206             netdev_close(netdev);
1207         } else {
1208             unixctl_command_reply_error(conn, "Unknown Dummy Interface");
1209             netdev_close(netdev);
1210             return;
1211         }
1212     } else {
1213         struct netdev_dummy *netdev;
1214
1215         ovs_mutex_lock(&dummy_list_mutex);
1216         LIST_FOR_EACH (netdev, list_node, &dummy_list) {
1217             ovs_mutex_lock(&netdev->mutex);
1218             netdev_dummy_set_admin_state__(netdev, up);
1219             ovs_mutex_unlock(&netdev->mutex);
1220         }
1221         ovs_mutex_unlock(&dummy_list_mutex);
1222     }
1223     unixctl_command_reply(conn, "OK");
1224 }
1225
1226 void
1227 netdev_dummy_register(bool override)
1228 {
1229     unixctl_command_register("netdev-dummy/receive", "NAME PACKET|FLOW...",
1230                              2, INT_MAX, netdev_dummy_receive, NULL);
1231     unixctl_command_register("netdev-dummy/set-admin-state",
1232                              "[netdev] up|down", 1, 2,
1233                              netdev_dummy_set_admin_state, NULL);
1234
1235     if (override) {
1236         struct sset types;
1237         const char *type;
1238
1239         sset_init(&types);
1240         netdev_enumerate_types(&types);
1241         SSET_FOR_EACH (type, &types) {
1242             if (!strcmp(type, "patch")) {
1243                 continue;
1244             }
1245             if (!netdev_unregister_provider(type)) {
1246                 struct netdev_class *class;
1247                 int error;
1248
1249                 class = xmemdup(&dummy_class, sizeof dummy_class);
1250                 class->type = xstrdup(type);
1251                 error = netdev_register_provider(class);
1252                 if (error) {
1253                     VLOG_ERR("%s: failed to register netdev provider (%s)",
1254                              type, ovs_strerror(error));
1255                     free(CONST_CAST(char *, class->type));
1256                     free(class);
1257                 }
1258             }
1259         }
1260         sset_destroy(&types);
1261     }
1262     netdev_register_provider(&dummy_class);
1263
1264     netdev_vport_tunnel_register();
1265 }