- if (stats.tx_bytes != UINT64_MAX) {
- ds_put_format(ds, "\ttx_bytes: %"PRIu64"\n", stats.tx_bytes);
- }
-
- if (stats.tx_errors != UINT64_MAX) {
- ds_put_format(ds, "\ttx_errors: %"PRIu64"\n", stats.tx_errors);
- }
- } else {
- ds_put_format(ds, "\tFailed to get statistics for queue %u: %s",
- queue_id, strerror(error));
- }
-}
-
-static void
-qos_unixctl_show(struct unixctl_conn *conn,
- const char *args, void *aux OVS_UNUSED)
-{
- struct ds ds = DS_EMPTY_INITIALIZER;
- struct shash sh = SHASH_INITIALIZER(&sh);
- struct iface *iface;
- const char *type;
- struct shash_node *node;
- struct qos_unixctl_show_cbdata data;
- int error;
-
- iface = iface_find(args);
- if (!iface) {
- unixctl_command_reply(conn, 501, "no such interface");
- return;
- }
-
- netdev_get_qos(iface->netdev, &type, &sh);
-
- if (*type != '\0') {
- ds_put_format(&ds, "QoS: %s %s\n", iface->name, type);
-
- SHASH_FOR_EACH (node, &sh) {
- ds_put_format(&ds, "%s: %s\n", node->name, (char *)node->data);
- }
-
- data.ds = &ds;
- data.iface = iface;
- error = netdev_dump_queues(iface->netdev, qos_unixctl_show_cb, &data);
-
- if (error) {
- ds_put_format(&ds, "failed to dump queues: %s", strerror(error));
- }
- unixctl_command_reply(conn, 200, ds_cstr(&ds));
- } else {
- ds_put_format(&ds, "QoS not configured on %s\n", iface->name);
- unixctl_command_reply(conn, 501, ds_cstr(&ds));
- }
-
- shash_destroy_free_data(&sh);
- ds_destroy(&ds);
-}
-\f
-/* Bridge reconfiguration functions. */
-static struct bridge *
-bridge_create(const struct ovsrec_bridge *br_cfg)
-{
- struct bridge *br;
- int error;
-
- assert(!bridge_lookup(br_cfg->name));
- br = xzalloc(sizeof *br);
-
- error = dpif_create_and_open(br_cfg->name, br_cfg->datapath_type,
- &br->dpif);
- if (error) {
- free(br);
- return NULL;
- }
- dpif_flow_flush(br->dpif);
-
- error = ofproto_create(br_cfg->name, br_cfg->datapath_type, &bridge_ofhooks,
- br, &br->ofproto);
- if (error) {
- VLOG_ERR("failed to create switch %s: %s", br_cfg->name,
- strerror(error));
- dpif_delete(br->dpif);
- dpif_close(br->dpif);
- free(br);
- return NULL;
- }
-
- br->name = xstrdup(br_cfg->name);
- br->cfg = br_cfg;
- br->ml = mac_learning_create();
- eth_addr_nicira_random(br->default_ea);
-
- hmap_init(&br->ifaces);
-
- shash_init(&br->port_by_name);
- shash_init(&br->iface_by_name);
-
- br->flush = false;
-
- list_push_back(&all_bridges, &br->node);
-
- VLOG_INFO("created bridge %s on %s", br->name, dpif_name(br->dpif));
-
- return br;
-}
-
-static void
-bridge_destroy(struct bridge *br)
-{
- if (br) {
- int error;
-
- while (br->n_ports > 0) {
- port_destroy(br->ports[br->n_ports - 1]);
- }
- list_remove(&br->node);
- error = dpif_delete(br->dpif);
- if (error && error != ENOENT) {
- VLOG_ERR("failed to delete %s: %s",
- dpif_name(br->dpif), strerror(error));
- }
- dpif_close(br->dpif);
- ofproto_destroy(br->ofproto);
- mac_learning_destroy(br->ml);
- hmap_destroy(&br->ifaces);
- shash_destroy(&br->port_by_name);
- shash_destroy(&br->iface_by_name);
- free(br->ports);
- free(br->name);
- free(br);
- }
-}
-
-static struct bridge *
-bridge_lookup(const char *name)
-{
- struct bridge *br;
-
- LIST_FOR_EACH (br, node, &all_bridges) {
- if (!strcmp(br->name, name)) {
- return br;
- }
- }
- return NULL;
-}
-
-/* Handle requests for a listing of all flows known by the OpenFlow
- * stack, including those normally hidden. */
-static void
-bridge_unixctl_dump_flows(struct unixctl_conn *conn,
- const char *args, void *aux OVS_UNUSED)
-{
- struct bridge *br;
- struct ds results;
-
- br = bridge_lookup(args);
- if (!br) {
- unixctl_command_reply(conn, 501, "Unknown bridge");
- return;
- }
-
- ds_init(&results);
- ofproto_get_all_flows(br->ofproto, &results);
-
- unixctl_command_reply(conn, 200, ds_cstr(&results));
- ds_destroy(&results);
-}
-
-/* "bridge/reconnect [BRIDGE]": makes BRIDGE drop all of its controller
- * connections and reconnect. If BRIDGE is not specified, then all bridges
- * drop their controller connections and reconnect. */
-static void
-bridge_unixctl_reconnect(struct unixctl_conn *conn,
- const char *args, void *aux OVS_UNUSED)
-{
- struct bridge *br;
- if (args[0] != '\0') {
- br = bridge_lookup(args);
- if (!br) {
- unixctl_command_reply(conn, 501, "Unknown bridge");
- return;
- }
- ofproto_reconnect_controllers(br->ofproto);
- } else {
- LIST_FOR_EACH (br, node, &all_bridges) {
- ofproto_reconnect_controllers(br->ofproto);
- }
- }
- unixctl_command_reply(conn, 200, NULL);
-}
-
-static int
-bridge_run_one(struct bridge *br)
-{
- size_t i;
- int error;
-
- error = ofproto_run1(br->ofproto);
- if (error) {
- return error;
- }
-
- mac_learning_run(br->ml, ofproto_get_revalidate_set(br->ofproto));
-
- for (i = 0; i < br->n_ports; i++) {
- port_run(br->ports[i]);
- }
-
- error = ofproto_run2(br->ofproto, br->flush);
- br->flush = false;
-
- return error;
-}
-
-static size_t
-bridge_get_controllers(const struct bridge *br,
- struct ovsrec_controller ***controllersp)
-{
- struct ovsrec_controller **controllers;
- size_t n_controllers;
-
- controllers = br->cfg->controller;
- n_controllers = br->cfg->n_controller;
-
- if (n_controllers == 1 && !strcmp(controllers[0]->target, "none")) {
- controllers = NULL;
- n_controllers = 0;
- }
-
- if (controllersp) {
- *controllersp = controllers;
- }
- return n_controllers;
-}
-
-static void
-bridge_reconfigure_one(struct bridge *br)
-{
- struct shash old_ports, new_ports;
- struct svec snoops, old_snoops;
- struct shash_node *node;
- enum ofproto_fail_mode fail_mode;
- size_t i;
-
- /* Collect old ports. */
- shash_init(&old_ports);
- for (i = 0; i < br->n_ports; i++) {
- shash_add(&old_ports, br->ports[i]->name, br->ports[i]);
- }
-
- /* Collect new ports. */
- shash_init(&new_ports);
- for (i = 0; i < br->cfg->n_ports; i++) {
- const char *name = br->cfg->ports[i]->name;
- if (!shash_add_once(&new_ports, name, br->cfg->ports[i])) {
- VLOG_WARN("bridge %s: %s specified twice as bridge port",
- br->name, name);
- }
- }
-
- /* If we have a controller, then we need a local port. Complain if the
- * user didn't specify one.
- *
- * XXX perhaps we should synthesize a port ourselves in this case. */
- if (bridge_get_controllers(br, NULL)) {
- char local_name[IF_NAMESIZE];
- int error;