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