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