X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=utilities%2Fovs-dpctl.c;h=499d49451fb5cad1702e19f6ae7b99614f2f81be;hb=7229a773ead96f891b621cd5f3e1219af5f24dd7;hp=0e6c16fa44e1052ac62ca1a2ecf8d6153d53143a;hpb=df2c07f4338faac04f4969f243fe4e8083b309ac;p=openvswitch diff --git a/utilities/ovs-dpctl.c b/utilities/ovs-dpctl.c index 0e6c16fa..499d4945 100644 --- a/utilities/ovs-dpctl.c +++ b/utilities/ovs-dpctl.c @@ -131,12 +131,16 @@ usage(void) " add-dp DP [IFACE...] add new datapath DP (with IFACEs)\n" " del-dp DP delete local datapath DP\n" " add-if DP IFACE... add each IFACE as a port on DP\n" + " set-if DP IFACE... reconfigure each IFACE within DP\n" " del-if DP IFACE... delete each IFACE from DP\n" " dump-dps display names of all datapaths\n" " show show basic info on all datapaths\n" " show DP... show basic info on each DP\n" " dump-flows DP display flows in DP\n" - " del-flows DP delete all flows from DP\n", + " del-flows DP delete all flows from DP\n" + "Each IFACE on add-dp, add-if, and set-if may be followed by\n" + "comma-separated options. See ovs-dpctl(8) for syntax, or the\n" + "Interface table in ovs-vswitchd.conf.db(5) for an options list.\n", program_name, program_name); vlog_usage(); printf("\nOther options:\n" @@ -234,6 +238,7 @@ do_add_if(int argc OVS_UNUSED, char *argv[]) if (!name) { ovs_error(0, "%s is not a valid network device name", argv[i]); + failure = true; continue; } @@ -287,6 +292,99 @@ next: } } +static void +do_set_if(int argc, char *argv[]) +{ + bool failure = false; + struct dpif *dpif; + int i; + + run(parsed_dpif_open(argv[1], false, &dpif), "opening datapath"); + for (i = 2; i < argc; i++) { + struct netdev *netdev = NULL; + struct dpif_port dpif_port; + char *save_ptr = NULL; + char *type = NULL; + const char *name; + struct shash args; + char *option; + int error; + + name = strtok_r(argv[i], ",", &save_ptr); + if (!name) { + ovs_error(0, "%s is not a valid network device name", argv[i]); + failure = true; + continue; + } + + /* Get the port's type from the datapath. */ + error = dpif_port_query_by_name(dpif, name, &dpif_port); + if (error) { + ovs_error(error, "%s: failed to query port in %s", name, argv[1]); + goto next; + } + type = xstrdup(dpif_port.type); + dpif_port_destroy(&dpif_port); + + /* Retrieve its existing configuration. */ + error = netdev_open(name, type, &netdev); + if (error) { + ovs_error(error, "%s: failed to open network device", name); + goto next; + } + + shash_init(&args); + error = netdev_get_config(netdev, &args); + if (error) { + ovs_error(error, "%s: failed to fetch configuration", name); + goto next; + } + + /* Parse changes to configuration. */ + while ((option = strtok_r(NULL, ",", &save_ptr)) != NULL) { + char *save_ptr_2 = NULL; + char *key, *value; + + key = strtok_r(option, "=", &save_ptr_2); + value = strtok_r(NULL, "", &save_ptr_2); + if (!value) { + value = ""; + } + + if (!strcmp(key, "type")) { + if (strcmp(value, type)) { + ovs_error(0, "%s: can't change type from %s to %s", + name, type, value); + failure = true; + } + } else if (value[0] == '\0') { + free(shash_find_and_delete(&args, key)); + } else { + free(shash_replace(&args, key, xstrdup(value))); + } + } + + /* Update configuration. */ + error = netdev_set_config(netdev, &args); + smap_destroy(&args); + if (error) { + ovs_error(error, "%s: failed to configure network device", name); + goto next; + } + +next: + free(type); + netdev_close(netdev); + if (error) { + failure = true; + } + } + dpif_close(dpif); + if (failure) { + exit(EXIT_FAILURE); + } +} + static bool get_port_number(struct dpif *dpif, const char *name, uint16_t *port) { @@ -366,22 +464,19 @@ show_dpif(struct dpif *dpif) { struct dpif_port_dump dump; struct dpif_port dpif_port; - struct ovs_dp_stats stats; + struct dpif_dp_stats stats; + struct netdev *netdev; printf("%s:\n", dpif_name(dpif)); if (!dpif_get_dp_stats(dpif, &stats)) { - printf("\tlookups: frags:%llu, hit:%llu, missed:%llu, lost:%llu\n", - (unsigned long long int) stats.n_frags, - (unsigned long long int) stats.n_hit, - (unsigned long long int) stats.n_missed, - (unsigned long long int) stats.n_lost); - printf("\tflows: %llu\n", (unsigned long long int)stats.n_flows); + printf("\tlookups: hit:%"PRIu64" missed:%"PRIu64" lost:%"PRIu64"\n" + "\tflows: %"PRIu64"\n", + stats.n_hit, stats.n_missed, stats.n_lost, stats.n_flows); } DPIF_PORT_FOR_EACH (&dpif_port, &dump, dpif) { printf("\tport %u: %s", dpif_port.port_no, dpif_port.name); if (strcmp(dpif_port.type, "system")) { - struct netdev *netdev; int error; printf (" (%s", dpif_port.type); @@ -418,29 +513,42 @@ show_dpif(struct dpif *dpif) putchar('\n'); if (print_statistics) { - const struct netdev_stats *s = &dpif_port.stats; + struct netdev_stats s; + int error; + + error = netdev_open(dpif_port.name, dpif_port.type, &netdev); + if (error) { + printf(", open failed (%s)", strerror(error)); + continue; + } + error = netdev_get_stats(netdev, &s); + if (error) { + printf(", could not retrieve stats (%s)", strerror(error)); + continue; + } - print_stat("\t\tRX packets:", s->rx_packets); - print_stat(" errors:", s->rx_errors); - print_stat(" dropped:", s->rx_dropped); - print_stat(" overruns:", s->rx_over_errors); - print_stat(" frame:", s->rx_frame_errors); + netdev_close(netdev); + print_stat("\t\tRX packets:", s.rx_packets); + print_stat(" errors:", s.rx_errors); + print_stat(" dropped:", s.rx_dropped); + print_stat(" overruns:", s.rx_over_errors); + print_stat(" frame:", s.rx_frame_errors); printf("\n"); - print_stat("\t\tTX packets:", s->tx_packets); - print_stat(" errors:", s->tx_errors); - print_stat(" dropped:", s->tx_dropped); - print_stat(" aborted:", s->tx_aborted_errors); - print_stat(" carrier:", s->tx_carrier_errors); + print_stat("\t\tTX packets:", s.tx_packets); + print_stat(" errors:", s.tx_errors); + print_stat(" dropped:", s.tx_dropped); + print_stat(" aborted:", s.tx_aborted_errors); + print_stat(" carrier:", s.tx_carrier_errors); printf("\n"); - print_stat("\t\tcollisions:", s->collisions); + print_stat("\t\tcollisions:", s.collisions); printf("\n"); - print_stat("\t\tRX bytes:", s->rx_bytes); - print_human_size(s->rx_bytes); - print_stat(" TX bytes:", s->tx_bytes); - print_human_size(s->tx_bytes); + print_stat("\t\tRX bytes:", s.rx_bytes); + print_human_size(s.rx_bytes); + print_stat(" TX bytes:", s.tx_bytes); + print_human_size(s.tx_bytes); printf("\n"); } } @@ -590,6 +698,7 @@ static const struct command all_commands[] = { { "del-dp", 1, 1, do_del_dp }, { "add-if", 2, INT_MAX, do_add_if }, { "del-if", 2, INT_MAX, do_del_if }, + { "set-if", 2, INT_MAX, do_set_if }, { "dump-dps", 0, 0, do_dump_dps }, { "show", 0, INT_MAX, do_show }, { "dump-flows", 1, 1, do_dump_flows },