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