+static void
+display_conn_state__(struct ds *s, const char *name,
+ enum dummy_netdev_conn_state state)
+{
+ ds_put_format(s, "%s: ", name);
+
+ switch (state) {
+ case CONN_STATE_CONNECTED:
+ ds_put_cstr(s, "connected\n");
+ break;
+
+ case CONN_STATE_NOT_CONNECTED:
+ ds_put_cstr(s, "disconnected\n");
+ break;
+
+ case CONN_STATE_UNKNOWN:
+ default:
+ ds_put_cstr(s, "unknown\n");
+ break;
+ };
+}
+
+static void
+netdev_dummy_conn_state(struct unixctl_conn *conn, int argc,
+ const char *argv[], void *aux OVS_UNUSED)
+{
+ enum dummy_netdev_conn_state state = CONN_STATE_UNKNOWN;
+ struct ds s;
+
+ ds_init(&s);
+
+ if (argc > 1) {
+ const char *dev_name = argv[1];
+ struct netdev *netdev = netdev_from_name(dev_name);
+
+ if (netdev && is_dummy_class(netdev->netdev_class)) {
+ struct netdev_dummy *dummy_dev = netdev_dummy_cast(netdev);
+
+ ovs_mutex_lock(&dummy_dev->mutex);
+ state = dummy_netdev_get_conn_state(&dummy_dev->conn);
+ ovs_mutex_unlock(&dummy_dev->mutex);
+
+ netdev_close(netdev);
+ }
+ display_conn_state__(&s, dev_name, state);
+ } else {
+ struct netdev_dummy *netdev;
+
+ ovs_mutex_lock(&dummy_list_mutex);
+ LIST_FOR_EACH (netdev, list_node, &dummy_list) {
+ ovs_mutex_lock(&netdev->mutex);
+ state = dummy_netdev_get_conn_state(&netdev->conn);
+ ovs_mutex_unlock(&netdev->mutex);
+ if (state != CONN_STATE_UNKNOWN) {
+ display_conn_state__(&s, netdev->up.name, state);
+ }
+ }
+ ovs_mutex_unlock(&dummy_list_mutex);
+ }
+
+ unixctl_command_reply(conn, ds_cstr(&s));
+ ds_destroy(&s);
+}
+