|
28 | 28 | #include "fail-open.h"
|
29 | 29 | #include "guarded-list.h"
|
30 | 30 | #include "hmapx.h"
|
| 31 | +#include "openvswitch/json.h" |
31 | 32 | #include "lacp.h"
|
32 | 33 | #include "learn.h"
|
33 | 34 | #include "mac-learning.h"
|
@@ -6519,19 +6520,108 @@ dpif_set_support(struct dpif_backer_support *rt_support,
|
6519 | 6520 | return changed;
|
6520 | 6521 | }
|
6521 | 6522 |
|
| 6523 | +static struct json * |
| 6524 | +dpif_show_backer_json(struct json *backers, const struct dpif_backer *backer) |
| 6525 | +{ |
| 6526 | + struct json *json_backer = json_object_create(); |
| 6527 | + |
| 6528 | + /* Add datapath as new JSON object using its name as key. */ |
| 6529 | + json_object_put(backers, dpif_name(backer->dpif), json_backer); |
| 6530 | + |
| 6531 | + /* Add datapath's stats under "stats" key. */ |
| 6532 | + struct json *json_dp_stats = json_object_create(); |
| 6533 | + struct dpif_dp_stats dp_stats; |
| 6534 | + |
| 6535 | + dpif_get_dp_stats(backer->dpif, &dp_stats); |
| 6536 | + json_object_put_format(json_dp_stats, "hit", "%"PRIu64, dp_stats.n_hit); |
| 6537 | + json_object_put_format(json_dp_stats, "missed", "%"PRIu64, |
| 6538 | + dp_stats.n_missed); |
| 6539 | + json_object_put(json_backer, "stats", json_dp_stats); |
| 6540 | + |
| 6541 | + /* Add datapath's bridges under "bridges" key. */ |
| 6542 | + struct json *json_dp_bridges = json_object_create(); |
| 6543 | + |
| 6544 | + struct shash ofproto_shash = SHASH_INITIALIZER(&ofproto_shash); |
| 6545 | + free(get_ofprotos(&ofproto_shash)); |
| 6546 | + |
| 6547 | + struct shash_node *node; |
| 6548 | + SHASH_FOR_EACH (node, &ofproto_shash) { |
| 6549 | + struct ofproto_dpif *ofproto = node->data; |
| 6550 | + |
| 6551 | + if (ofproto->backer != backer) { |
| 6552 | + continue; |
| 6553 | + } |
| 6554 | + |
| 6555 | + /* Add bridge to "bridges" dictionary using its name as key. */ |
| 6556 | + struct json *json_ofproto = json_object_create(); |
| 6557 | + |
| 6558 | + /* Add bridge ports to the current bridge dictionary. */ |
| 6559 | + const struct shash_node *port; |
| 6560 | + SHASH_FOR_EACH (port, &ofproto->up.port_by_name) { |
| 6561 | + /* Add bridge port to a bridge's dict using port name as key. */ |
| 6562 | + struct json *json_ofproto_port = json_object_create(); |
| 6563 | + struct ofport *ofport = port->data; |
| 6564 | + |
| 6565 | + /* Add OpenFlow port associated with a bridge port. */ |
| 6566 | + json_object_put_format(json_ofproto_port, "ofport", "%"PRIu32, |
| 6567 | + ofport->ofp_port); |
| 6568 | + |
| 6569 | + /* Add bridge port number. */ |
| 6570 | + odp_port_t odp_port = ofp_port_to_odp_port(ofproto, |
| 6571 | + ofport->ofp_port); |
| 6572 | + if (odp_port != ODPP_NONE) { |
| 6573 | + json_object_put_format(json_ofproto_port, "port_no", |
| 6574 | + "%"PRIu32, odp_port); |
| 6575 | + } else { |
| 6576 | + json_object_put_string(json_ofproto_port, "port_no", "none"); |
| 6577 | + } |
| 6578 | + |
| 6579 | + /* Add type of a bridge port. */ |
| 6580 | + json_object_put_string(json_ofproto_port, "type", |
| 6581 | + netdev_get_type(ofport->netdev)); |
| 6582 | + |
| 6583 | + /* Add config entries for a bridge port. */ |
| 6584 | + |
| 6585 | + struct smap config = SMAP_INITIALIZER(&config); |
| 6586 | + |
| 6587 | + if (!netdev_get_config(ofport->netdev, &config) |
| 6588 | + && smap_count(&config)) { |
| 6589 | + struct json *json_port_config = json_object_create(); |
| 6590 | + struct smap_node *cfg_node; |
| 6591 | + |
| 6592 | + SMAP_FOR_EACH (cfg_node, &config) { |
| 6593 | + json_object_put_string(json_port_config, cfg_node->key, |
| 6594 | + cfg_node->value); |
| 6595 | + } |
| 6596 | + json_object_put(json_ofproto_port, "config", json_port_config); |
| 6597 | + } |
| 6598 | + smap_destroy(&config); |
| 6599 | + |
| 6600 | + json_object_put(json_ofproto, netdev_get_name(ofport->netdev), |
| 6601 | + json_ofproto_port); |
| 6602 | + } /* End of bridge port(s). */ |
| 6603 | + |
| 6604 | + json_object_put(json_dp_bridges, ofproto->up.name, json_ofproto); |
| 6605 | + } /* End of bridge(s). */ |
| 6606 | + |
| 6607 | + shash_destroy(&ofproto_shash); |
| 6608 | + |
| 6609 | + json_object_put(json_backer, "bridges", json_dp_bridges); |
| 6610 | + return json_backer; |
| 6611 | +} |
| 6612 | + |
6522 | 6613 | static void
|
6523 |
| -dpif_show_backer(const struct dpif_backer *backer, struct ds *ds) |
| 6614 | +dpif_show_backer_text(const struct dpif_backer *backer, struct ds *ds) |
6524 | 6615 | {
|
| 6616 | + struct shash ofproto_shash = SHASH_INITIALIZER(&ofproto_shash); |
6525 | 6617 | const struct shash_node **ofprotos;
|
6526 | 6618 | struct dpif_dp_stats dp_stats;
|
6527 |
| - struct shash ofproto_shash; |
6528 | 6619 | size_t i;
|
6529 | 6620 |
|
6530 | 6621 | dpif_get_dp_stats(backer->dpif, &dp_stats);
|
6531 | 6622 | ds_put_format(ds, "%s: hit:%"PRIu64" missed:%"PRIu64"\n",
|
6532 | 6623 | dpif_name(backer->dpif), dp_stats.n_hit, dp_stats.n_missed);
|
6533 | 6624 |
|
6534 |
| - shash_init(&ofproto_shash); |
6535 | 6625 | ofprotos = get_ofprotos(&ofproto_shash);
|
6536 | 6626 | for (i = 0; i < shash_count(&ofproto_shash); i++) {
|
6537 | 6627 | struct ofproto_dpif *ofproto = ofprotos[i]->data;
|
@@ -6587,18 +6677,26 @@ static void
|
6587 | 6677 | ofproto_unixctl_dpif_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
|
6588 | 6678 | const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
|
6589 | 6679 | {
|
6590 |
| - struct ds ds = DS_EMPTY_INITIALIZER; |
6591 |
| - const struct shash_node **backers; |
6592 |
| - int i; |
| 6680 | + if (unixctl_command_get_output_format(conn) == UNIXCTL_OUTPUT_FMT_JSON) { |
| 6681 | + struct json *backers = json_object_create(); |
| 6682 | + const struct shash_node *backer; |
6593 | 6683 |
|
6594 |
| - backers = shash_sort(&all_dpif_backers); |
6595 |
| - for (i = 0; i < shash_count(&all_dpif_backers); i++) { |
6596 |
| - dpif_show_backer(backers[i]->data, &ds); |
6597 |
| - } |
6598 |
| - free(backers); |
| 6684 | + SHASH_FOR_EACH (backer, &all_dpif_backers) { |
| 6685 | + dpif_show_backer_json(backers, backer->data); |
| 6686 | + } |
| 6687 | + unixctl_command_reply_json(conn, backers); |
| 6688 | + } else { |
| 6689 | + const struct shash_node **backers = shash_sort(&all_dpif_backers); |
| 6690 | + struct ds ds = DS_EMPTY_INITIALIZER; |
6599 | 6691 |
|
6600 |
| - unixctl_command_reply(conn, ds_cstr(&ds)); |
6601 |
| - ds_destroy(&ds); |
| 6692 | + for (int i = 0; i < shash_count(&all_dpif_backers); i++) { |
| 6693 | + dpif_show_backer_text(backers[i]->data, &ds); |
| 6694 | + } |
| 6695 | + free(backers); |
| 6696 | + |
| 6697 | + unixctl_command_reply(conn, ds_cstr(&ds)); |
| 6698 | + ds_destroy(&ds); |
| 6699 | + } |
6602 | 6700 | }
|
6603 | 6701 |
|
6604 | 6702 | static void
|
|
0 commit comments