mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 22:35:15 +00:00
lib: New data structure - smap.
A smap is a string to string hash map. It has a cleaner interface than shash's which were traditionally used for the same purpose. This patch implements the data structure, and changes netdev and its providers to use it. Signed-off-by: Ethan Jackson <ethan@nicira.com>
This commit is contained in:
@@ -141,6 +141,8 @@ lib_libopenvswitch_a_SOURCES = \
|
|||||||
lib/simap.h \
|
lib/simap.h \
|
||||||
lib/signals.c \
|
lib/signals.c \
|
||||||
lib/signals.h \
|
lib/signals.h \
|
||||||
|
lib/smap.c \
|
||||||
|
lib/smap.h \
|
||||||
lib/socket-util.c \
|
lib/socket-util.c \
|
||||||
lib/socket-util.h \
|
lib/socket-util.h \
|
||||||
lib/sort.c \
|
lib/sort.c \
|
||||||
|
@@ -181,7 +181,7 @@ struct tc_ops {
|
|||||||
*
|
*
|
||||||
* (This function is null for tc_ops_other, which cannot be installed. For
|
* (This function is null for tc_ops_other, which cannot be installed. For
|
||||||
* other TC classes it should always be nonnull.) */
|
* other TC classes it should always be nonnull.) */
|
||||||
int (*tc_install)(struct netdev *netdev, const struct shash *details);
|
int (*tc_install)(struct netdev *netdev, const struct smap *details);
|
||||||
|
|
||||||
/* Called when the netdev code determines (through a Netlink query) that
|
/* Called when the netdev code determines (through a Netlink query) that
|
||||||
* this TC class's qdisc is installed on 'netdev', but we didn't install
|
* this TC class's qdisc is installed on 'netdev', but we didn't install
|
||||||
@@ -221,7 +221,7 @@ struct tc_ops {
|
|||||||
*
|
*
|
||||||
* This function may be null if 'tc' is not configurable.
|
* This function may be null if 'tc' is not configurable.
|
||||||
*/
|
*/
|
||||||
int (*qdisc_get)(const struct netdev *netdev, struct shash *details);
|
int (*qdisc_get)(const struct netdev *netdev, struct smap *details);
|
||||||
|
|
||||||
/* Reconfigures 'netdev->tc' according to 'details', performing any
|
/* Reconfigures 'netdev->tc' according to 'details', performing any
|
||||||
* required Netlink calls to complete the reconfiguration.
|
* required Netlink calls to complete the reconfiguration.
|
||||||
@@ -232,7 +232,7 @@ struct tc_ops {
|
|||||||
*
|
*
|
||||||
* This function may be null if 'tc' is not configurable.
|
* This function may be null if 'tc' is not configurable.
|
||||||
*/
|
*/
|
||||||
int (*qdisc_set)(struct netdev *, const struct shash *details);
|
int (*qdisc_set)(struct netdev *, const struct smap *details);
|
||||||
|
|
||||||
/* Retrieves details of 'queue' on 'netdev->tc' into 'details'. 'queue' is
|
/* Retrieves details of 'queue' on 'netdev->tc' into 'details'. 'queue' is
|
||||||
* one of the 'struct tc_queue's within 'netdev->tc->queues'.
|
* one of the 'struct tc_queue's within 'netdev->tc->queues'.
|
||||||
@@ -248,7 +248,7 @@ struct tc_ops {
|
|||||||
* This function may be null if 'tc' does not have queues ('n_queues' is
|
* This function may be null if 'tc' does not have queues ('n_queues' is
|
||||||
* 0). */
|
* 0). */
|
||||||
int (*class_get)(const struct netdev *netdev, const struct tc_queue *queue,
|
int (*class_get)(const struct netdev *netdev, const struct tc_queue *queue,
|
||||||
struct shash *details);
|
struct smap *details);
|
||||||
|
|
||||||
/* Configures or reconfigures 'queue_id' on 'netdev->tc' according to
|
/* Configures or reconfigures 'queue_id' on 'netdev->tc' according to
|
||||||
* 'details', perfoming any required Netlink calls to complete the
|
* 'details', perfoming any required Netlink calls to complete the
|
||||||
@@ -262,7 +262,7 @@ struct tc_ops {
|
|||||||
* This function may be null if 'tc' does not have queues or its queues are
|
* This function may be null if 'tc' does not have queues or its queues are
|
||||||
* not configurable. */
|
* not configurable. */
|
||||||
int (*class_set)(struct netdev *, unsigned int queue_id,
|
int (*class_set)(struct netdev *, unsigned int queue_id,
|
||||||
const struct shash *details);
|
const struct smap *details);
|
||||||
|
|
||||||
/* Deletes 'queue' from 'netdev->tc'. 'queue' is one of the 'struct
|
/* Deletes 'queue' from 'netdev->tc'. 'queue' is one of the 'struct
|
||||||
* tc_queue's within 'netdev->tc->queues'.
|
* tc_queue's within 'netdev->tc->queues'.
|
||||||
@@ -1845,7 +1845,7 @@ netdev_linux_get_qos_capabilities(const struct netdev *netdev OVS_UNUSED,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
netdev_linux_get_qos(const struct netdev *netdev,
|
netdev_linux_get_qos(const struct netdev *netdev,
|
||||||
const char **typep, struct shash *details)
|
const char **typep, struct smap *details)
|
||||||
{
|
{
|
||||||
struct netdev_dev_linux *netdev_dev =
|
struct netdev_dev_linux *netdev_dev =
|
||||||
netdev_dev_linux_cast(netdev_get_dev(netdev));
|
netdev_dev_linux_cast(netdev_get_dev(netdev));
|
||||||
@@ -1864,7 +1864,7 @@ netdev_linux_get_qos(const struct netdev *netdev,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
netdev_linux_set_qos(struct netdev *netdev,
|
netdev_linux_set_qos(struct netdev *netdev,
|
||||||
const char *type, const struct shash *details)
|
const char *type, const struct smap *details)
|
||||||
{
|
{
|
||||||
struct netdev_dev_linux *netdev_dev =
|
struct netdev_dev_linux *netdev_dev =
|
||||||
netdev_dev_linux_cast(netdev_get_dev(netdev));
|
netdev_dev_linux_cast(netdev_get_dev(netdev));
|
||||||
@@ -1901,7 +1901,7 @@ netdev_linux_set_qos(struct netdev *netdev,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
netdev_linux_get_queue(const struct netdev *netdev,
|
netdev_linux_get_queue(const struct netdev *netdev,
|
||||||
unsigned int queue_id, struct shash *details)
|
unsigned int queue_id, struct smap *details)
|
||||||
{
|
{
|
||||||
struct netdev_dev_linux *netdev_dev =
|
struct netdev_dev_linux *netdev_dev =
|
||||||
netdev_dev_linux_cast(netdev_get_dev(netdev));
|
netdev_dev_linux_cast(netdev_get_dev(netdev));
|
||||||
@@ -1920,7 +1920,7 @@ netdev_linux_get_queue(const struct netdev *netdev,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
netdev_linux_set_queue(struct netdev *netdev,
|
netdev_linux_set_queue(struct netdev *netdev,
|
||||||
unsigned int queue_id, const struct shash *details)
|
unsigned int queue_id, const struct smap *details)
|
||||||
{
|
{
|
||||||
struct netdev_dev_linux *netdev_dev =
|
struct netdev_dev_linux *netdev_dev =
|
||||||
netdev_dev_linux_cast(netdev_get_dev(netdev));
|
netdev_dev_linux_cast(netdev_get_dev(netdev));
|
||||||
@@ -2002,7 +2002,7 @@ netdev_linux_dump_queues(const struct netdev *netdev,
|
|||||||
struct netdev_dev_linux *netdev_dev =
|
struct netdev_dev_linux *netdev_dev =
|
||||||
netdev_dev_linux_cast(netdev_get_dev(netdev));
|
netdev_dev_linux_cast(netdev_get_dev(netdev));
|
||||||
struct tc_queue *queue, *next_queue;
|
struct tc_queue *queue, *next_queue;
|
||||||
struct shash details;
|
struct smap details;
|
||||||
int last_error;
|
int last_error;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@@ -2014,10 +2014,10 @@ netdev_linux_dump_queues(const struct netdev *netdev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
last_error = 0;
|
last_error = 0;
|
||||||
shash_init(&details);
|
smap_init(&details);
|
||||||
HMAP_FOR_EACH_SAFE (queue, next_queue, hmap_node,
|
HMAP_FOR_EACH_SAFE (queue, next_queue, hmap_node,
|
||||||
&netdev_dev->tc->queues) {
|
&netdev_dev->tc->queues) {
|
||||||
shash_clear(&details);
|
smap_clear(&details);
|
||||||
|
|
||||||
error = netdev_dev->tc->ops->class_get(netdev, queue, &details);
|
error = netdev_dev->tc->ops->class_get(netdev, queue, &details);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
@@ -2026,7 +2026,7 @@ netdev_linux_dump_queues(const struct netdev *netdev,
|
|||||||
last_error = error;
|
last_error = error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
shash_destroy(&details);
|
smap_destroy(&details);
|
||||||
|
|
||||||
return last_error;
|
return last_error;
|
||||||
}
|
}
|
||||||
@@ -2271,7 +2271,7 @@ netdev_linux_get_next_hop(const struct in_addr *host, struct in_addr *next_hop,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
netdev_linux_get_drv_info(const struct netdev *netdev, struct shash *sh)
|
netdev_linux_get_drv_info(const struct netdev *netdev, struct smap *smap)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
struct netdev_dev_linux *netdev_dev =
|
struct netdev_dev_linux *netdev_dev =
|
||||||
@@ -2279,17 +2279,18 @@ netdev_linux_get_drv_info(const struct netdev *netdev, struct shash *sh)
|
|||||||
|
|
||||||
error = netdev_linux_get_drvinfo(netdev_dev);
|
error = netdev_linux_get_drvinfo(netdev_dev);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
shash_add(sh, "driver_name", xstrdup(netdev_dev->drvinfo.driver));
|
smap_add(smap, "driver_name", netdev_dev->drvinfo.driver);
|
||||||
shash_add(sh, "driver_version", xstrdup(netdev_dev->drvinfo.version));
|
smap_add(smap, "driver_version", netdev_dev->drvinfo.version);
|
||||||
shash_add(sh, "firmware_version", xstrdup(netdev_dev->drvinfo.fw_version));
|
smap_add(smap, "firmware_version", netdev_dev->drvinfo.fw_version);
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
netdev_internal_get_drv_info(const struct netdev *netdev OVS_UNUSED, struct shash *sh)
|
netdev_internal_get_drv_info(const struct netdev *netdev OVS_UNUSED,
|
||||||
|
struct smap *smap)
|
||||||
{
|
{
|
||||||
shash_add(sh, "driver_name", xstrdup("openvswitch"));
|
smap_add(smap, "driver_name", "openvswitch");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2651,11 +2652,11 @@ htb_parse_tcmsg__(struct ofpbuf *tcmsg, unsigned int *queue_id,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
htb_parse_qdisc_details__(struct netdev *netdev,
|
htb_parse_qdisc_details__(struct netdev *netdev,
|
||||||
const struct shash *details, struct htb_class *hc)
|
const struct smap *details, struct htb_class *hc)
|
||||||
{
|
{
|
||||||
const char *max_rate_s;
|
const char *max_rate_s;
|
||||||
|
|
||||||
max_rate_s = shash_find_data(details, "max-rate");
|
max_rate_s = smap_get(details, "max-rate");
|
||||||
hc->max_rate = max_rate_s ? strtoull(max_rate_s, NULL, 10) / 8 : 0;
|
hc->max_rate = max_rate_s ? strtoull(max_rate_s, NULL, 10) / 8 : 0;
|
||||||
if (!hc->max_rate) {
|
if (!hc->max_rate) {
|
||||||
enum netdev_features current;
|
enum netdev_features current;
|
||||||
@@ -2670,13 +2671,13 @@ htb_parse_qdisc_details__(struct netdev *netdev,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
htb_parse_class_details__(struct netdev *netdev,
|
htb_parse_class_details__(struct netdev *netdev,
|
||||||
const struct shash *details, struct htb_class *hc)
|
const struct smap *details, struct htb_class *hc)
|
||||||
{
|
{
|
||||||
const struct htb *htb = htb_get__(netdev);
|
const struct htb *htb = htb_get__(netdev);
|
||||||
const char *min_rate_s = shash_find_data(details, "min-rate");
|
const char *min_rate_s = smap_get(details, "min-rate");
|
||||||
const char *max_rate_s = shash_find_data(details, "max-rate");
|
const char *max_rate_s = smap_get(details, "max-rate");
|
||||||
const char *burst_s = shash_find_data(details, "burst");
|
const char *burst_s = smap_get(details, "burst");
|
||||||
const char *priority_s = shash_find_data(details, "priority");
|
const char *priority_s = smap_get(details, "priority");
|
||||||
int mtu, error;
|
int mtu, error;
|
||||||
|
|
||||||
error = netdev_get_mtu(netdev, &mtu);
|
error = netdev_get_mtu(netdev, &mtu);
|
||||||
@@ -2734,7 +2735,7 @@ htb_query_class__(const struct netdev *netdev, unsigned int handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
htb_tc_install(struct netdev *netdev, const struct shash *details)
|
htb_tc_install(struct netdev *netdev, const struct smap *details)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@@ -2826,15 +2827,15 @@ htb_tc_destroy(struct tc *tc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
htb_qdisc_get(const struct netdev *netdev, struct shash *details)
|
htb_qdisc_get(const struct netdev *netdev, struct smap *details)
|
||||||
{
|
{
|
||||||
const struct htb *htb = htb_get__(netdev);
|
const struct htb *htb = htb_get__(netdev);
|
||||||
shash_add(details, "max-rate", xasprintf("%llu", 8ULL * htb->max_rate));
|
smap_add_format(details, "max-rate", "%llu", 8ULL * htb->max_rate);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
htb_qdisc_set(struct netdev *netdev, const struct shash *details)
|
htb_qdisc_set(struct netdev *netdev, const struct smap *details)
|
||||||
{
|
{
|
||||||
struct htb_class hc;
|
struct htb_class hc;
|
||||||
int error;
|
int error;
|
||||||
@@ -2850,24 +2851,24 @@ htb_qdisc_set(struct netdev *netdev, const struct shash *details)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
htb_class_get(const struct netdev *netdev OVS_UNUSED,
|
htb_class_get(const struct netdev *netdev OVS_UNUSED,
|
||||||
const struct tc_queue *queue, struct shash *details)
|
const struct tc_queue *queue, struct smap *details)
|
||||||
{
|
{
|
||||||
const struct htb_class *hc = htb_class_cast__(queue);
|
const struct htb_class *hc = htb_class_cast__(queue);
|
||||||
|
|
||||||
shash_add(details, "min-rate", xasprintf("%llu", 8ULL * hc->min_rate));
|
smap_add_format(details, "min-rate", "%llu", 8ULL * hc->min_rate);
|
||||||
if (hc->min_rate != hc->max_rate) {
|
if (hc->min_rate != hc->max_rate) {
|
||||||
shash_add(details, "max-rate", xasprintf("%llu", 8ULL * hc->max_rate));
|
smap_add_format(details, "max-rate", "%llu", 8ULL * hc->max_rate);
|
||||||
}
|
}
|
||||||
shash_add(details, "burst", xasprintf("%llu", 8ULL * hc->burst));
|
smap_add_format(details, "burst", "%llu", 8ULL * hc->burst);
|
||||||
if (hc->priority) {
|
if (hc->priority) {
|
||||||
shash_add(details, "priority", xasprintf("%u", hc->priority));
|
smap_add_format(details, "priority", "%u", hc->priority);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
htb_class_set(struct netdev *netdev, unsigned int queue_id,
|
htb_class_set(struct netdev *netdev, unsigned int queue_id,
|
||||||
const struct shash *details)
|
const struct smap *details)
|
||||||
{
|
{
|
||||||
struct htb_class hc;
|
struct htb_class hc;
|
||||||
int error;
|
int error;
|
||||||
@@ -3127,13 +3128,13 @@ hfsc_query_class__(const struct netdev *netdev, unsigned int handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hfsc_parse_qdisc_details__(struct netdev *netdev, const struct shash *details,
|
hfsc_parse_qdisc_details__(struct netdev *netdev, const struct smap *details,
|
||||||
struct hfsc_class *class)
|
struct hfsc_class *class)
|
||||||
{
|
{
|
||||||
uint32_t max_rate;
|
uint32_t max_rate;
|
||||||
const char *max_rate_s;
|
const char *max_rate_s;
|
||||||
|
|
||||||
max_rate_s = shash_find_data(details, "max-rate");
|
max_rate_s = smap_get(details, "max-rate");
|
||||||
max_rate = max_rate_s ? strtoull(max_rate_s, NULL, 10) / 8 : 0;
|
max_rate = max_rate_s ? strtoull(max_rate_s, NULL, 10) / 8 : 0;
|
||||||
|
|
||||||
if (!max_rate) {
|
if (!max_rate) {
|
||||||
@@ -3149,7 +3150,7 @@ hfsc_parse_qdisc_details__(struct netdev *netdev, const struct shash *details,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
hfsc_parse_class_details__(struct netdev *netdev,
|
hfsc_parse_class_details__(struct netdev *netdev,
|
||||||
const struct shash *details,
|
const struct smap *details,
|
||||||
struct hfsc_class * class)
|
struct hfsc_class * class)
|
||||||
{
|
{
|
||||||
const struct hfsc *hfsc;
|
const struct hfsc *hfsc;
|
||||||
@@ -3157,8 +3158,8 @@ hfsc_parse_class_details__(struct netdev *netdev,
|
|||||||
const char *min_rate_s, *max_rate_s;
|
const char *min_rate_s, *max_rate_s;
|
||||||
|
|
||||||
hfsc = hfsc_get__(netdev);
|
hfsc = hfsc_get__(netdev);
|
||||||
min_rate_s = shash_find_data(details, "min-rate");
|
min_rate_s = smap_get(details, "min-rate");
|
||||||
max_rate_s = shash_find_data(details, "max-rate");
|
max_rate_s = smap_get(details, "max-rate");
|
||||||
|
|
||||||
min_rate = min_rate_s ? strtoull(min_rate_s, NULL, 10) / 8 : 0;
|
min_rate = min_rate_s ? strtoull(min_rate_s, NULL, 10) / 8 : 0;
|
||||||
min_rate = MAX(min_rate, 1);
|
min_rate = MAX(min_rate, 1);
|
||||||
@@ -3259,7 +3260,7 @@ hfsc_setup_class__(struct netdev *netdev, unsigned int handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
hfsc_tc_install(struct netdev *netdev, const struct shash *details)
|
hfsc_tc_install(struct netdev *netdev, const struct smap *details)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
struct hfsc_class class;
|
struct hfsc_class class;
|
||||||
@@ -3327,16 +3328,16 @@ hfsc_tc_destroy(struct tc *tc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
hfsc_qdisc_get(const struct netdev *netdev, struct shash *details)
|
hfsc_qdisc_get(const struct netdev *netdev, struct smap *details)
|
||||||
{
|
{
|
||||||
const struct hfsc *hfsc;
|
const struct hfsc *hfsc;
|
||||||
hfsc = hfsc_get__(netdev);
|
hfsc = hfsc_get__(netdev);
|
||||||
shash_add(details, "max-rate", xasprintf("%llu", 8ULL * hfsc->max_rate));
|
smap_add_format(details, "max-rate", "%llu", 8ULL * hfsc->max_rate);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
hfsc_qdisc_set(struct netdev *netdev, const struct shash *details)
|
hfsc_qdisc_set(struct netdev *netdev, const struct smap *details)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
struct hfsc_class class;
|
struct hfsc_class class;
|
||||||
@@ -3354,21 +3355,21 @@ hfsc_qdisc_set(struct netdev *netdev, const struct shash *details)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
hfsc_class_get(const struct netdev *netdev OVS_UNUSED,
|
hfsc_class_get(const struct netdev *netdev OVS_UNUSED,
|
||||||
const struct tc_queue *queue, struct shash *details)
|
const struct tc_queue *queue, struct smap *details)
|
||||||
{
|
{
|
||||||
const struct hfsc_class *hc;
|
const struct hfsc_class *hc;
|
||||||
|
|
||||||
hc = hfsc_class_cast__(queue);
|
hc = hfsc_class_cast__(queue);
|
||||||
shash_add(details, "min-rate", xasprintf("%llu", 8ULL * hc->min_rate));
|
smap_add_format(details, "min-rate", "%llu", 8ULL * hc->min_rate);
|
||||||
if (hc->min_rate != hc->max_rate) {
|
if (hc->min_rate != hc->max_rate) {
|
||||||
shash_add(details, "max-rate", xasprintf("%llu", 8ULL * hc->max_rate));
|
smap_add_format(details, "max-rate", "%llu", 8ULL * hc->max_rate);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
hfsc_class_set(struct netdev *netdev, unsigned int queue_id,
|
hfsc_class_set(struct netdev *netdev, unsigned int queue_id,
|
||||||
const struct shash *details)
|
const struct smap *details)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
struct hfsc_class class;
|
struct hfsc_class class;
|
||||||
@@ -3473,7 +3474,7 @@ default_install__(struct netdev *netdev)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
default_tc_install(struct netdev *netdev,
|
default_tc_install(struct netdev *netdev,
|
||||||
const struct shash *details OVS_UNUSED)
|
const struct smap *details OVS_UNUSED)
|
||||||
{
|
{
|
||||||
default_install__(netdev);
|
default_install__(netdev);
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
#include "netdev.h"
|
#include "netdev.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "shash.h"
|
#include "shash.h"
|
||||||
|
#include "smap.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -126,17 +127,17 @@ struct netdev_class {
|
|||||||
void (*destroy)(struct netdev_dev *netdev_dev);
|
void (*destroy)(struct netdev_dev *netdev_dev);
|
||||||
|
|
||||||
/* Fetches the device 'netdev_dev''s configuration, storing it in 'args'.
|
/* Fetches the device 'netdev_dev''s configuration, storing it in 'args'.
|
||||||
* The caller owns 'args' and pre-initializes it to an empty shash.
|
* The caller owns 'args' and pre-initializes it to an empty smap.
|
||||||
*
|
*
|
||||||
* If this netdev class does not have any configuration options, this may
|
* If this netdev class does not have any configuration options, this may
|
||||||
* be a null pointer. */
|
* be a null pointer. */
|
||||||
int (*get_config)(struct netdev_dev *netdev_dev, struct shash *args);
|
int (*get_config)(struct netdev_dev *netdev_dev, struct smap *args);
|
||||||
|
|
||||||
/* Changes the device 'netdev_dev''s configuration to 'args'.
|
/* Changes the device 'netdev_dev''s configuration to 'args'.
|
||||||
*
|
*
|
||||||
* If this netdev class does not support configuration, this may be a null
|
* If this netdev class does not support configuration, this may be a null
|
||||||
* pointer. */
|
* pointer. */
|
||||||
int (*set_config)(struct netdev_dev *netdev_dev, const struct shash *args);
|
int (*set_config)(struct netdev_dev *netdev_dev, const struct smap *args);
|
||||||
|
|
||||||
/* Attempts to open a network device. On success, sets 'netdevp'
|
/* Attempts to open a network device. On success, sets 'netdevp'
|
||||||
* to the new network device. */
|
* to the new network device. */
|
||||||
@@ -381,7 +382,7 @@ struct netdev_class {
|
|||||||
*
|
*
|
||||||
* May be NULL if 'netdev' does not support QoS at all. */
|
* May be NULL if 'netdev' does not support QoS at all. */
|
||||||
int (*get_qos)(const struct netdev *netdev,
|
int (*get_qos)(const struct netdev *netdev,
|
||||||
const char **typep, struct shash *details);
|
const char **typep, struct smap *details);
|
||||||
|
|
||||||
/* Attempts to reconfigure QoS on 'netdev', changing the form of QoS to
|
/* Attempts to reconfigure QoS on 'netdev', changing the form of QoS to
|
||||||
* 'type' with details of configuration from 'details'.
|
* 'type' with details of configuration from 'details'.
|
||||||
@@ -401,7 +402,7 @@ struct netdev_class {
|
|||||||
*
|
*
|
||||||
* May be NULL if 'netdev' does not support QoS at all. */
|
* May be NULL if 'netdev' does not support QoS at all. */
|
||||||
int (*set_qos)(struct netdev *netdev,
|
int (*set_qos)(struct netdev *netdev,
|
||||||
const char *type, const struct shash *details);
|
const char *type, const struct smap *details);
|
||||||
|
|
||||||
/* Queries 'netdev' for information about the queue numbered 'queue_id'.
|
/* Queries 'netdev' for information about the queue numbered 'queue_id'.
|
||||||
* If successful, adds that information as string key-value pairs to
|
* If successful, adds that information as string key-value pairs to
|
||||||
@@ -420,7 +421,7 @@ struct netdev_class {
|
|||||||
* vswitchd/vswitch.xml (which is built as ovs-vswitchd.conf.db(8)).
|
* vswitchd/vswitch.xml (which is built as ovs-vswitchd.conf.db(8)).
|
||||||
*/
|
*/
|
||||||
int (*get_queue)(const struct netdev *netdev,
|
int (*get_queue)(const struct netdev *netdev,
|
||||||
unsigned int queue_id, struct shash *details);
|
unsigned int queue_id, struct smap *details);
|
||||||
|
|
||||||
/* Configures the queue numbered 'queue_id' on 'netdev' with the key-value
|
/* Configures the queue numbered 'queue_id' on 'netdev' with the key-value
|
||||||
* string pairs in 'details'. The contents of 'details' should be
|
* string pairs in 'details'. The contents of 'details' should be
|
||||||
@@ -440,7 +441,7 @@ struct netdev_class {
|
|||||||
*
|
*
|
||||||
* May be NULL if 'netdev' does not support QoS at all. */
|
* May be NULL if 'netdev' does not support QoS at all. */
|
||||||
int (*set_queue)(struct netdev *netdev,
|
int (*set_queue)(struct netdev *netdev,
|
||||||
unsigned int queue_id, const struct shash *details);
|
unsigned int queue_id, const struct smap *details);
|
||||||
|
|
||||||
/* Attempts to delete the queue numbered 'queue_id' from 'netdev'.
|
/* Attempts to delete the queue numbered 'queue_id' from 'netdev'.
|
||||||
*
|
*
|
||||||
@@ -475,7 +476,7 @@ struct netdev_class {
|
|||||||
*/
|
*/
|
||||||
int (*dump_queues)(const struct netdev *netdev,
|
int (*dump_queues)(const struct netdev *netdev,
|
||||||
void (*cb)(unsigned int queue_id,
|
void (*cb)(unsigned int queue_id,
|
||||||
const struct shash *details,
|
const struct smap *details,
|
||||||
void *aux),
|
void *aux),
|
||||||
void *aux);
|
void *aux);
|
||||||
|
|
||||||
@@ -550,12 +551,11 @@ struct netdev_class {
|
|||||||
* representing netdev type specific information. For more information see
|
* representing netdev type specific information. For more information see
|
||||||
* ovs-vswitchd.conf.db(5).
|
* ovs-vswitchd.conf.db(5).
|
||||||
*
|
*
|
||||||
* The data of 'sh' are heap allocated strings which the caller is
|
* The caller is responsible for destroying 'smap' and its data.
|
||||||
* responsible for deallocating.
|
|
||||||
*
|
*
|
||||||
* This function may be set to null if it would always return EOPNOTSUPP
|
* This function may be set to null if it would always return EOPNOTSUPP
|
||||||
* anyhow. */
|
* anyhow. */
|
||||||
int (*get_drv_info)(const struct netdev *netdev, struct shash *sh);
|
int (*get_drv_info)(const struct netdev *netdev, struct smap *smap);
|
||||||
|
|
||||||
/* Looks up the ARP table entry for 'ip' on 'netdev' and stores the
|
/* Looks up the ARP table entry for 'ip' on 'netdev' and stores the
|
||||||
* corresponding MAC address in 'mac'. A return value of ENXIO, in
|
* corresponding MAC address in 'mac'. A return value of ENXIO, in
|
||||||
|
@@ -65,10 +65,10 @@ struct vport_class {
|
|||||||
enum ovs_vport_type type;
|
enum ovs_vport_type type;
|
||||||
struct netdev_class netdev_class;
|
struct netdev_class netdev_class;
|
||||||
int (*parse_config)(const char *name, const char *type,
|
int (*parse_config)(const char *name, const char *type,
|
||||||
const struct shash *args, struct ofpbuf *options);
|
const struct smap *args, struct ofpbuf *options);
|
||||||
int (*unparse_config)(const char *name, const char *type,
|
int (*unparse_config)(const char *name, const char *type,
|
||||||
const struct nlattr *options, size_t options_len,
|
const struct nlattr *options, size_t options_len,
|
||||||
struct shash *args);
|
struct smap *args);
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
|
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
|
||||||
@@ -223,7 +223,7 @@ netdev_vport_close(struct netdev *netdev_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
netdev_vport_get_config(struct netdev_dev *dev_, struct shash *args)
|
netdev_vport_get_config(struct netdev_dev *dev_, struct smap *args)
|
||||||
{
|
{
|
||||||
const struct netdev_class *netdev_class = netdev_dev_get_class(dev_);
|
const struct netdev_class *netdev_class = netdev_dev_get_class(dev_);
|
||||||
const struct vport_class *vport_class = vport_class_cast(netdev_class);
|
const struct vport_class *vport_class = vport_class_cast(netdev_class);
|
||||||
@@ -260,7 +260,7 @@ netdev_vport_get_config(struct netdev_dev *dev_, struct shash *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
netdev_vport_set_config(struct netdev_dev *dev_, const struct shash *args)
|
netdev_vport_set_config(struct netdev_dev *dev_, const struct smap *args)
|
||||||
{
|
{
|
||||||
const struct netdev_class *netdev_class = netdev_dev_get_class(dev_);
|
const struct netdev_class *netdev_class = netdev_dev_get_class(dev_);
|
||||||
const struct vport_class *vport_class = vport_class_cast(netdev_class);
|
const struct vport_class *vport_class = vport_class_cast(netdev_class);
|
||||||
@@ -459,19 +459,18 @@ netdev_vport_set_stats(struct netdev *netdev, const struct netdev_stats *stats)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
netdev_vport_get_drv_info(const struct netdev *netdev, struct shash *sh)
|
netdev_vport_get_drv_info(const struct netdev *netdev, struct smap *smap)
|
||||||
{
|
{
|
||||||
const char *iface = netdev_vport_get_tnl_iface(netdev);
|
const char *iface = netdev_vport_get_tnl_iface(netdev);
|
||||||
|
|
||||||
if (iface) {
|
if (iface) {
|
||||||
struct netdev *egress_netdev;
|
struct netdev *egress_netdev;
|
||||||
|
|
||||||
shash_add(sh, "tunnel_egress_iface", xstrdup(iface));
|
smap_add(smap, "tunnel_egress_iface", iface);
|
||||||
|
|
||||||
if (!netdev_open(iface, "system", &egress_netdev)) {
|
if (!netdev_open(iface, "system", &egress_netdev)) {
|
||||||
shash_add(sh, "tunnel_egress_iface_carrier",
|
smap_add(smap, "tunnel_egress_iface_carrier",
|
||||||
xstrdup(netdev_get_carrier(egress_netdev)
|
netdev_get_carrier(egress_netdev) ? "up" : "down");
|
||||||
? "up" : "down"));
|
|
||||||
netdev_close(egress_netdev);
|
netdev_close(egress_netdev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -551,14 +550,14 @@ netdev_vport_poll_notify(const struct netdev *netdev)
|
|||||||
/* Code specific to individual vport types. */
|
/* Code specific to individual vport types. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_key(const struct shash *args, const char *name, uint16_t type,
|
set_key(const struct smap *args, const char *name, uint16_t type,
|
||||||
struct ofpbuf *options)
|
struct ofpbuf *options)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
s = shash_find_data(args, name);
|
s = smap_get(args, name);
|
||||||
if (!s) {
|
if (!s) {
|
||||||
s = shash_find_data(args, "key");
|
s = smap_get(args, "key");
|
||||||
if (!s) {
|
if (!s) {
|
||||||
s = "0";
|
s = "0";
|
||||||
}
|
}
|
||||||
@@ -573,11 +572,11 @@ set_key(const struct shash *args, const char *name, uint16_t type,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
parse_tunnel_config(const char *name, const char *type,
|
parse_tunnel_config(const char *name, const char *type,
|
||||||
const struct shash *args, struct ofpbuf *options)
|
const struct smap *args, struct ofpbuf *options)
|
||||||
{
|
{
|
||||||
bool is_gre = false;
|
bool is_gre = false;
|
||||||
bool is_ipsec = false;
|
bool is_ipsec = false;
|
||||||
struct shash_node *node;
|
struct smap_node *node;
|
||||||
bool ipsec_mech_set = false;
|
bool ipsec_mech_set = false;
|
||||||
ovs_be32 daddr = htonl(0);
|
ovs_be32 daddr = htonl(0);
|
||||||
ovs_be32 saddr = htonl(0);
|
ovs_be32 saddr = htonl(0);
|
||||||
@@ -593,60 +592,60 @@ parse_tunnel_config(const char *name, const char *type,
|
|||||||
flags &= ~TNL_F_HDR_CACHE;
|
flags &= ~TNL_F_HDR_CACHE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHASH_FOR_EACH (node, args) {
|
SMAP_FOR_EACH (node, args) {
|
||||||
if (!strcmp(node->name, "remote_ip")) {
|
if (!strcmp(node->key, "remote_ip")) {
|
||||||
struct in_addr in_addr;
|
struct in_addr in_addr;
|
||||||
if (lookup_ip(node->data, &in_addr)) {
|
if (lookup_ip(node->value, &in_addr)) {
|
||||||
VLOG_WARN("%s: bad %s 'remote_ip'", name, type);
|
VLOG_WARN("%s: bad %s 'remote_ip'", name, type);
|
||||||
} else {
|
} else {
|
||||||
daddr = in_addr.s_addr;
|
daddr = in_addr.s_addr;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(node->name, "local_ip")) {
|
} else if (!strcmp(node->key, "local_ip")) {
|
||||||
struct in_addr in_addr;
|
struct in_addr in_addr;
|
||||||
if (lookup_ip(node->data, &in_addr)) {
|
if (lookup_ip(node->value, &in_addr)) {
|
||||||
VLOG_WARN("%s: bad %s 'local_ip'", name, type);
|
VLOG_WARN("%s: bad %s 'local_ip'", name, type);
|
||||||
} else {
|
} else {
|
||||||
saddr = in_addr.s_addr;
|
saddr = in_addr.s_addr;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(node->name, "tos")) {
|
} else if (!strcmp(node->key, "tos")) {
|
||||||
if (!strcmp(node->data, "inherit")) {
|
if (!strcmp(node->value, "inherit")) {
|
||||||
flags |= TNL_F_TOS_INHERIT;
|
flags |= TNL_F_TOS_INHERIT;
|
||||||
} else {
|
} else {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
int tos;
|
int tos;
|
||||||
tos = strtol(node->data, &endptr, 0);
|
tos = strtol(node->value, &endptr, 0);
|
||||||
if (*endptr == '\0') {
|
if (*endptr == '\0') {
|
||||||
nl_msg_put_u8(options, OVS_TUNNEL_ATTR_TOS, tos);
|
nl_msg_put_u8(options, OVS_TUNNEL_ATTR_TOS, tos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!strcmp(node->name, "ttl")) {
|
} else if (!strcmp(node->key, "ttl")) {
|
||||||
if (!strcmp(node->data, "inherit")) {
|
if (!strcmp(node->value, "inherit")) {
|
||||||
flags |= TNL_F_TTL_INHERIT;
|
flags |= TNL_F_TTL_INHERIT;
|
||||||
} else {
|
} else {
|
||||||
nl_msg_put_u8(options, OVS_TUNNEL_ATTR_TTL, atoi(node->data));
|
nl_msg_put_u8(options, OVS_TUNNEL_ATTR_TTL, atoi(node->value));
|
||||||
}
|
}
|
||||||
} else if (!strcmp(node->name, "csum") && is_gre) {
|
} else if (!strcmp(node->key, "csum") && is_gre) {
|
||||||
if (!strcmp(node->data, "true")) {
|
if (!strcmp(node->value, "true")) {
|
||||||
flags |= TNL_F_CSUM;
|
flags |= TNL_F_CSUM;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(node->name, "df_inherit")) {
|
} else if (!strcmp(node->key, "df_inherit")) {
|
||||||
if (!strcmp(node->data, "true")) {
|
if (!strcmp(node->value, "true")) {
|
||||||
flags |= TNL_F_DF_INHERIT;
|
flags |= TNL_F_DF_INHERIT;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(node->name, "df_default")) {
|
} else if (!strcmp(node->key, "df_default")) {
|
||||||
if (!strcmp(node->data, "false")) {
|
if (!strcmp(node->value, "false")) {
|
||||||
flags &= ~TNL_F_DF_DEFAULT;
|
flags &= ~TNL_F_DF_DEFAULT;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(node->name, "pmtud")) {
|
} else if (!strcmp(node->key, "pmtud")) {
|
||||||
if (!strcmp(node->data, "false")) {
|
if (!strcmp(node->value, "false")) {
|
||||||
flags &= ~TNL_F_PMTUD;
|
flags &= ~TNL_F_PMTUD;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(node->name, "header_cache")) {
|
} else if (!strcmp(node->key, "header_cache")) {
|
||||||
if (!strcmp(node->data, "false")) {
|
if (!strcmp(node->value, "false")) {
|
||||||
flags &= ~TNL_F_HDR_CACHE;
|
flags &= ~TNL_F_HDR_CACHE;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(node->name, "peer_cert") && is_ipsec) {
|
} else if (!strcmp(node->key, "peer_cert") && is_ipsec) {
|
||||||
if (shash_find(args, "certificate")) {
|
if (smap_get(args, "certificate")) {
|
||||||
ipsec_mech_set = true;
|
ipsec_mech_set = true;
|
||||||
} else {
|
} else {
|
||||||
const char *use_ssl_cert;
|
const char *use_ssl_cert;
|
||||||
@@ -657,7 +656,7 @@ parse_tunnel_config(const char *name, const char *type,
|
|||||||
* will like be removed when multiple SSL configurations
|
* will like be removed when multiple SSL configurations
|
||||||
* are supported by OVS.
|
* are supported by OVS.
|
||||||
*/
|
*/
|
||||||
use_ssl_cert = shash_find_data(args, "use_ssl_cert");
|
use_ssl_cert = smap_get(args, "use_ssl_cert");
|
||||||
if (!use_ssl_cert || strcmp(use_ssl_cert, "true")) {
|
if (!use_ssl_cert || strcmp(use_ssl_cert, "true")) {
|
||||||
VLOG_ERR("%s: 'peer_cert' requires 'certificate' argument",
|
VLOG_ERR("%s: 'peer_cert' requires 'certificate' argument",
|
||||||
name);
|
name);
|
||||||
@@ -665,19 +664,19 @@ parse_tunnel_config(const char *name, const char *type,
|
|||||||
}
|
}
|
||||||
ipsec_mech_set = true;
|
ipsec_mech_set = true;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(node->name, "psk") && is_ipsec) {
|
} else if (!strcmp(node->key, "psk") && is_ipsec) {
|
||||||
ipsec_mech_set = true;
|
ipsec_mech_set = true;
|
||||||
} else if (is_ipsec
|
} else if (is_ipsec
|
||||||
&& (!strcmp(node->name, "certificate")
|
&& (!strcmp(node->key, "certificate")
|
||||||
|| !strcmp(node->name, "private_key")
|
|| !strcmp(node->key, "private_key")
|
||||||
|| !strcmp(node->name, "use_ssl_cert"))) {
|
|| !strcmp(node->key, "use_ssl_cert"))) {
|
||||||
/* Ignore options not used by the netdev. */
|
/* Ignore options not used by the netdev. */
|
||||||
} else if (!strcmp(node->name, "key") ||
|
} else if (!strcmp(node->key, "key") ||
|
||||||
!strcmp(node->name, "in_key") ||
|
!strcmp(node->key, "in_key") ||
|
||||||
!strcmp(node->name, "out_key")) {
|
!strcmp(node->key, "out_key")) {
|
||||||
/* Handled separately below. */
|
/* Handled separately below. */
|
||||||
} else {
|
} else {
|
||||||
VLOG_WARN("%s: unknown %s argument '%s'", name, type, node->name);
|
VLOG_WARN("%s: unknown %s argument '%s'", name, type, node->key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -692,7 +691,7 @@ parse_tunnel_config(const char *name, const char *type,
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shash_find(args, "peer_cert") && shash_find(args, "psk")) {
|
if (smap_get(args, "peer_cert") && smap_get(args, "psk")) {
|
||||||
VLOG_ERR("%s: cannot define both 'peer_cert' and 'psk'", name);
|
VLOG_ERR("%s: cannot define both 'peer_cert' and 'psk'", name);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@@ -759,7 +758,7 @@ get_be64_or_zero(const struct nlattr *a)
|
|||||||
static int
|
static int
|
||||||
unparse_tunnel_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
|
unparse_tunnel_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
|
||||||
const struct nlattr *options, size_t options_len,
|
const struct nlattr *options, size_t options_len,
|
||||||
struct shash *args)
|
struct smap *args)
|
||||||
{
|
{
|
||||||
struct nlattr *a[OVS_TUNNEL_ATTR_MAX + 1];
|
struct nlattr *a[OVS_TUNNEL_ATTR_MAX + 1];
|
||||||
ovs_be32 daddr;
|
ovs_be32 daddr;
|
||||||
@@ -778,11 +777,11 @@ unparse_tunnel_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
daddr = nl_attr_get_be32(a[OVS_TUNNEL_ATTR_DST_IPV4]);
|
daddr = nl_attr_get_be32(a[OVS_TUNNEL_ATTR_DST_IPV4]);
|
||||||
shash_add(args, "remote_ip", xasprintf(IP_FMT, IP_ARGS(&daddr)));
|
smap_add_format(args, "remote_ip", IP_FMT, IP_ARGS(&daddr));
|
||||||
|
|
||||||
if (a[OVS_TUNNEL_ATTR_SRC_IPV4]) {
|
if (a[OVS_TUNNEL_ATTR_SRC_IPV4]) {
|
||||||
ovs_be32 saddr = nl_attr_get_be32(a[OVS_TUNNEL_ATTR_SRC_IPV4]);
|
ovs_be32 saddr = nl_attr_get_be32(a[OVS_TUNNEL_ATTR_SRC_IPV4]);
|
||||||
shash_add(args, "local_ip", xasprintf(IP_FMT, IP_ARGS(&saddr)));
|
smap_add_format(args, "local_ip", IP_FMT, IP_ARGS(&saddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!a[OVS_TUNNEL_ATTR_IN_KEY] && !a[OVS_TUNNEL_ATTR_OUT_KEY]) {
|
if (!a[OVS_TUNNEL_ATTR_IN_KEY] && !a[OVS_TUNNEL_ATTR_OUT_KEY]) {
|
||||||
@@ -792,18 +791,18 @@ unparse_tunnel_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
|
|||||||
uint64_t out_key = get_be64_or_zero(a[OVS_TUNNEL_ATTR_OUT_KEY]);
|
uint64_t out_key = get_be64_or_zero(a[OVS_TUNNEL_ATTR_OUT_KEY]);
|
||||||
|
|
||||||
if (in_key && in_key == out_key) {
|
if (in_key && in_key == out_key) {
|
||||||
shash_add(args, "key", xasprintf("%"PRIu64, in_key));
|
smap_add_format(args, "key", "%"PRIu64, in_key);
|
||||||
} else {
|
} else {
|
||||||
if (!a[OVS_TUNNEL_ATTR_IN_KEY]) {
|
if (!a[OVS_TUNNEL_ATTR_IN_KEY]) {
|
||||||
smap_add(args, "in_key", "flow");
|
smap_add(args, "in_key", "flow");
|
||||||
} else if (in_key) {
|
} else if (in_key) {
|
||||||
shash_add(args, "in_key", xasprintf("%"PRIu64, in_key));
|
smap_add_format(args, "in_key", "%"PRIu64, in_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!a[OVS_TUNNEL_ATTR_OUT_KEY]) {
|
if (!a[OVS_TUNNEL_ATTR_OUT_KEY]) {
|
||||||
smap_add(args, "out_key", "flow");
|
smap_add(args, "out_key", "flow");
|
||||||
} else if (out_key) {
|
} else if (out_key) {
|
||||||
shash_add(args, "out_key", xasprintf("%"PRIu64, out_key));
|
smap_add_format(args, "out_key", "%"PRIu64, out_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -812,14 +811,14 @@ unparse_tunnel_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
|
|||||||
smap_add(args, "tos", "inherit");
|
smap_add(args, "tos", "inherit");
|
||||||
} else if (a[OVS_TUNNEL_ATTR_TTL]) {
|
} else if (a[OVS_TUNNEL_ATTR_TTL]) {
|
||||||
int ttl = nl_attr_get_u8(a[OVS_TUNNEL_ATTR_TTL]);
|
int ttl = nl_attr_get_u8(a[OVS_TUNNEL_ATTR_TTL]);
|
||||||
shash_add(args, "tos", xasprintf("%d", ttl));
|
smap_add_format(args, "tos", "%d", ttl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & TNL_F_TOS_INHERIT) {
|
if (flags & TNL_F_TOS_INHERIT) {
|
||||||
smap_add(args, "tos", "inherit");
|
smap_add(args, "tos", "inherit");
|
||||||
} else if (a[OVS_TUNNEL_ATTR_TOS]) {
|
} else if (a[OVS_TUNNEL_ATTR_TOS]) {
|
||||||
int tos = nl_attr_get_u8(a[OVS_TUNNEL_ATTR_TOS]);
|
int tos = nl_attr_get_u8(a[OVS_TUNNEL_ATTR_TOS]);
|
||||||
shash_add(args, "tos", xasprintf("0x%x", tos));
|
smap_add_format(args, "tos", "0x%x", tos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & TNL_F_CSUM) {
|
if (flags & TNL_F_CSUM) {
|
||||||
@@ -840,17 +839,17 @@ unparse_tunnel_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
parse_patch_config(const char *name, const char *type OVS_UNUSED,
|
parse_patch_config(const char *name, const char *type OVS_UNUSED,
|
||||||
const struct shash *args, struct ofpbuf *options)
|
const struct smap *args, struct ofpbuf *options)
|
||||||
{
|
{
|
||||||
const char *peer;
|
const char *peer;
|
||||||
|
|
||||||
peer = shash_find_data(args, "peer");
|
peer = smap_get(args, "peer");
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
VLOG_ERR("%s: patch type requires valid 'peer' argument", name);
|
VLOG_ERR("%s: patch type requires valid 'peer' argument", name);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shash_count(args) > 1) {
|
if (smap_count(args) > 1) {
|
||||||
VLOG_ERR("%s: patch type takes only a 'peer' argument", name);
|
VLOG_ERR("%s: patch type takes only a 'peer' argument", name);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@@ -873,7 +872,7 @@ parse_patch_config(const char *name, const char *type OVS_UNUSED,
|
|||||||
static int
|
static int
|
||||||
unparse_patch_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
|
unparse_patch_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
|
||||||
const struct nlattr *options, size_t options_len,
|
const struct nlattr *options, size_t options_len,
|
||||||
struct shash *args)
|
struct smap *args)
|
||||||
{
|
{
|
||||||
static const struct nl_policy ovs_patch_policy[] = {
|
static const struct nl_policy ovs_patch_policy[] = {
|
||||||
[OVS_PATCH_ATTR_PEER] = { .type = NL_A_STRING,
|
[OVS_PATCH_ATTR_PEER] = { .type = NL_A_STRING,
|
||||||
|
56
lib/netdev.c
56
lib/netdev.c
@@ -37,6 +37,7 @@
|
|||||||
#include "packets.h"
|
#include "packets.h"
|
||||||
#include "poll-loop.h"
|
#include "poll-loop.h"
|
||||||
#include "shash.h"
|
#include "shash.h"
|
||||||
|
#include "smap.h"
|
||||||
#include "sset.h"
|
#include "sset.h"
|
||||||
#include "svec.h"
|
#include "svec.h"
|
||||||
#include "vlog.h"
|
#include "vlog.h"
|
||||||
@@ -243,15 +244,15 @@ netdev_open(const char *name, const char *type, struct netdev **netdevp)
|
|||||||
/* Reconfigures the device 'netdev' with 'args'. 'args' may be empty
|
/* Reconfigures the device 'netdev' with 'args'. 'args' may be empty
|
||||||
* or NULL if none are needed. */
|
* or NULL if none are needed. */
|
||||||
int
|
int
|
||||||
netdev_set_config(struct netdev *netdev, const struct shash *args)
|
netdev_set_config(struct netdev *netdev, const struct smap *args)
|
||||||
{
|
{
|
||||||
struct netdev_dev *netdev_dev = netdev_get_dev(netdev);
|
struct netdev_dev *netdev_dev = netdev_get_dev(netdev);
|
||||||
|
|
||||||
if (netdev_dev->netdev_class->set_config) {
|
if (netdev_dev->netdev_class->set_config) {
|
||||||
struct shash no_args = SHASH_INITIALIZER(&no_args);
|
struct smap no_args = SMAP_INITIALIZER(&no_args);
|
||||||
return netdev_dev->netdev_class->set_config(netdev_dev,
|
return netdev_dev->netdev_class->set_config(netdev_dev,
|
||||||
args ? args : &no_args);
|
args ? args : &no_args);
|
||||||
} else if (args && !shash_is_empty(args)) {
|
} else if (args && !smap_is_empty(args)) {
|
||||||
VLOG_WARN("%s: arguments provided to device that is not configurable",
|
VLOG_WARN("%s: arguments provided to device that is not configurable",
|
||||||
netdev_get_name(netdev));
|
netdev_get_name(netdev));
|
||||||
}
|
}
|
||||||
@@ -260,23 +261,23 @@ netdev_set_config(struct netdev *netdev, const struct shash *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the current configuration for 'netdev' in 'args'. The caller must
|
/* Returns the current configuration for 'netdev' in 'args'. The caller must
|
||||||
* have already initialized 'args' with shash_init(). Returns 0 on success, in
|
* have already initialized 'args' with smap_init(). Returns 0 on success, in
|
||||||
* which case 'args' will be filled with 'netdev''s configuration. On failure
|
* which case 'args' will be filled with 'netdev''s configuration. On failure
|
||||||
* returns a positive errno value, in which case 'args' will be empty.
|
* returns a positive errno value, in which case 'args' will be empty.
|
||||||
*
|
*
|
||||||
* The caller owns 'args' and its contents and must eventually free them with
|
* The caller owns 'args' and its contents and must eventually free them with
|
||||||
* shash_destroy_free_data(). */
|
* smap_destroy(). */
|
||||||
int
|
int
|
||||||
netdev_get_config(const struct netdev *netdev, struct shash *args)
|
netdev_get_config(const struct netdev *netdev, struct smap *args)
|
||||||
{
|
{
|
||||||
struct netdev_dev *netdev_dev = netdev_get_dev(netdev);
|
struct netdev_dev *netdev_dev = netdev_get_dev(netdev);
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
shash_clear_free_data(args);
|
smap_clear(args);
|
||||||
if (netdev_dev->netdev_class->get_config) {
|
if (netdev_dev->netdev_class->get_config) {
|
||||||
error = netdev_dev->netdev_class->get_config(netdev_dev, args);
|
error = netdev_dev->netdev_class->get_config(netdev_dev, args);
|
||||||
if (error) {
|
if (error) {
|
||||||
shash_clear_free_data(args);
|
smap_clear(args);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error = 0;
|
error = 0;
|
||||||
@@ -759,18 +760,18 @@ netdev_get_next_hop(const struct netdev *netdev,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Populates 'sh' with status information.
|
/* Populates 'smap' with status information.
|
||||||
*
|
*
|
||||||
* Populates 'sh' with 'netdev' specific status information. This information
|
* Populates 'smap' with 'netdev' specific status information. This
|
||||||
* may be used to populate the status column of the Interface table as defined
|
* information may be used to populate the status column of the Interface table
|
||||||
* in ovs-vswitchd.conf.db(5). */
|
* as defined in ovs-vswitchd.conf.db(5). */
|
||||||
int
|
int
|
||||||
netdev_get_drv_info(const struct netdev *netdev, struct shash *sh)
|
netdev_get_drv_info(const struct netdev *netdev, struct smap *smap)
|
||||||
{
|
{
|
||||||
struct netdev_dev *dev = netdev_get_dev(netdev);
|
struct netdev_dev *dev = netdev_get_dev(netdev);
|
||||||
|
|
||||||
return (dev->netdev_class->get_drv_info
|
return (dev->netdev_class->get_drv_info
|
||||||
? dev->netdev_class->get_drv_info(netdev, sh)
|
? dev->netdev_class->get_drv_info(netdev, smap)
|
||||||
: EOPNOTSUPP);
|
: EOPNOTSUPP);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1065,10 +1066,9 @@ netdev_get_n_queues(const struct netdev *netdev,
|
|||||||
*
|
*
|
||||||
* A '*typep' of "" indicates that QoS is currently disabled on 'netdev'.
|
* A '*typep' of "" indicates that QoS is currently disabled on 'netdev'.
|
||||||
*
|
*
|
||||||
* The caller must initialize 'details' as an empty shash (e.g. with
|
* The caller must initialize 'details' as an empty smap (e.g. with
|
||||||
* shash_init()) before calling this function. The caller must free 'details',
|
* smap_init()) before calling this function. The caller must free 'details'
|
||||||
* including 'data' members, when it is no longer needed (e.g. with
|
* when it is no longer needed (e.g. with smap_destroy()).
|
||||||
* shash_destroy_free_data()).
|
|
||||||
*
|
*
|
||||||
* The caller must not modify or free '*typep'.
|
* The caller must not modify or free '*typep'.
|
||||||
*
|
*
|
||||||
@@ -1078,7 +1078,7 @@ netdev_get_n_queues(const struct netdev *netdev,
|
|||||||
* vswitchd/vswitch.xml (which is built as ovs-vswitchd.conf.db(8)). */
|
* vswitchd/vswitch.xml (which is built as ovs-vswitchd.conf.db(8)). */
|
||||||
int
|
int
|
||||||
netdev_get_qos(const struct netdev *netdev,
|
netdev_get_qos(const struct netdev *netdev,
|
||||||
const char **typep, struct shash *details)
|
const char **typep, struct smap *details)
|
||||||
{
|
{
|
||||||
const struct netdev_class *class = netdev_get_dev(netdev)->netdev_class;
|
const struct netdev_class *class = netdev_get_dev(netdev)->netdev_class;
|
||||||
int retval;
|
int retval;
|
||||||
@@ -1087,7 +1087,7 @@ netdev_get_qos(const struct netdev *netdev,
|
|||||||
retval = class->get_qos(netdev, typep, details);
|
retval = class->get_qos(netdev, typep, details);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
*typep = NULL;
|
*typep = NULL;
|
||||||
shash_clear_free_data(details);
|
smap_clear(details);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
} else {
|
} else {
|
||||||
@@ -1117,7 +1117,7 @@ netdev_get_qos(const struct netdev *netdev,
|
|||||||
* details. */
|
* details. */
|
||||||
int
|
int
|
||||||
netdev_set_qos(struct netdev *netdev,
|
netdev_set_qos(struct netdev *netdev,
|
||||||
const char *type, const struct shash *details)
|
const char *type, const struct smap *details)
|
||||||
{
|
{
|
||||||
const struct netdev_class *class = netdev_get_dev(netdev)->netdev_class;
|
const struct netdev_class *class = netdev_get_dev(netdev)->netdev_class;
|
||||||
|
|
||||||
@@ -1127,7 +1127,7 @@ netdev_set_qos(struct netdev *netdev,
|
|||||||
|
|
||||||
if (class->set_qos) {
|
if (class->set_qos) {
|
||||||
if (!details) {
|
if (!details) {
|
||||||
static struct shash empty = SHASH_INITIALIZER(&empty);
|
static struct smap empty = SMAP_INITIALIZER(&empty);
|
||||||
details = ∅
|
details = ∅
|
||||||
}
|
}
|
||||||
return class->set_qos(netdev, type, details);
|
return class->set_qos(netdev, type, details);
|
||||||
@@ -1147,12 +1147,12 @@ netdev_set_qos(struct netdev *netdev,
|
|||||||
* given 'type' in the "other_config" column in the "Queue" table in
|
* given 'type' in the "other_config" column in the "Queue" table in
|
||||||
* vswitchd/vswitch.xml (which is built as ovs-vswitchd.conf.db(8)).
|
* vswitchd/vswitch.xml (which is built as ovs-vswitchd.conf.db(8)).
|
||||||
*
|
*
|
||||||
* The caller must initialize 'details' (e.g. with shash_init()) before calling
|
* The caller must initialize 'details' (e.g. with smap_init()) before calling
|
||||||
* this function. The caller must free 'details', including 'data' members,
|
* this function. The caller must free 'details' when it is no longer needed
|
||||||
* when it is no longer needed (e.g. with shash_destroy_free_data()). */
|
* (e.g. with smap_destroy()). */
|
||||||
int
|
int
|
||||||
netdev_get_queue(const struct netdev *netdev,
|
netdev_get_queue(const struct netdev *netdev,
|
||||||
unsigned int queue_id, struct shash *details)
|
unsigned int queue_id, struct smap *details)
|
||||||
{
|
{
|
||||||
const struct netdev_class *class = netdev_get_dev(netdev)->netdev_class;
|
const struct netdev_class *class = netdev_get_dev(netdev)->netdev_class;
|
||||||
int retval;
|
int retval;
|
||||||
@@ -1161,7 +1161,7 @@ netdev_get_queue(const struct netdev *netdev,
|
|||||||
? class->get_queue(netdev, queue_id, details)
|
? class->get_queue(netdev, queue_id, details)
|
||||||
: EOPNOTSUPP);
|
: EOPNOTSUPP);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
shash_clear_free_data(details);
|
smap_clear(details);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@@ -1180,7 +1180,7 @@ netdev_get_queue(const struct netdev *netdev,
|
|||||||
* it. */
|
* it. */
|
||||||
int
|
int
|
||||||
netdev_set_queue(struct netdev *netdev,
|
netdev_set_queue(struct netdev *netdev,
|
||||||
unsigned int queue_id, const struct shash *details)
|
unsigned int queue_id, const struct smap *details)
|
||||||
{
|
{
|
||||||
const struct netdev_class *class = netdev_get_dev(netdev)->netdev_class;
|
const struct netdev_class *class = netdev_get_dev(netdev)->netdev_class;
|
||||||
return (class->set_queue
|
return (class->set_queue
|
||||||
|
18
lib/netdev.h
18
lib/netdev.h
@@ -35,7 +35,7 @@ extern "C" {
|
|||||||
struct ofpbuf;
|
struct ofpbuf;
|
||||||
struct in_addr;
|
struct in_addr;
|
||||||
struct in6_addr;
|
struct in6_addr;
|
||||||
struct shash;
|
struct smap;
|
||||||
struct sset;
|
struct sset;
|
||||||
|
|
||||||
enum netdev_flags {
|
enum netdev_flags {
|
||||||
@@ -93,8 +93,8 @@ bool netdev_is_open(const char *name);
|
|||||||
void netdev_parse_name(const char *netdev_name, char **name, char **type);
|
void netdev_parse_name(const char *netdev_name, char **name, char **type);
|
||||||
|
|
||||||
/* Options. */
|
/* Options. */
|
||||||
int netdev_set_config(struct netdev *, const struct shash *args);
|
int netdev_set_config(struct netdev *, const struct smap *args);
|
||||||
int netdev_get_config(const struct netdev *, struct shash *);
|
int netdev_get_config(const struct netdev *, struct smap *);
|
||||||
|
|
||||||
/* Basic properties. */
|
/* Basic properties. */
|
||||||
const char *netdev_get_name(const struct netdev *);
|
const char *netdev_get_name(const struct netdev *);
|
||||||
@@ -159,7 +159,7 @@ int netdev_get_in6(const struct netdev *, struct in6_addr *);
|
|||||||
int netdev_add_router(struct netdev *, struct in_addr router);
|
int netdev_add_router(struct netdev *, struct in_addr router);
|
||||||
int netdev_get_next_hop(const struct netdev *, const struct in_addr *host,
|
int netdev_get_next_hop(const struct netdev *, const struct in_addr *host,
|
||||||
struct in_addr *next_hop, char **);
|
struct in_addr *next_hop, char **);
|
||||||
int netdev_get_drv_info(const struct netdev *, struct shash *sh);
|
int netdev_get_drv_info(const struct netdev *, struct smap *);
|
||||||
int netdev_arp_lookup(const struct netdev *, ovs_be32 ip, uint8_t mac[6]);
|
int netdev_arp_lookup(const struct netdev *, ovs_be32 ip, uint8_t mac[6]);
|
||||||
|
|
||||||
int netdev_get_flags(const struct netdev *, enum netdev_flags *);
|
int netdev_get_flags(const struct netdev *, enum netdev_flags *);
|
||||||
@@ -195,20 +195,20 @@ int netdev_get_n_queues(const struct netdev *,
|
|||||||
const char *type, unsigned int *n_queuesp);
|
const char *type, unsigned int *n_queuesp);
|
||||||
|
|
||||||
int netdev_get_qos(const struct netdev *,
|
int netdev_get_qos(const struct netdev *,
|
||||||
const char **typep, struct shash *details);
|
const char **typep, struct smap *details);
|
||||||
int netdev_set_qos(struct netdev *,
|
int netdev_set_qos(struct netdev *,
|
||||||
const char *type, const struct shash *details);
|
const char *type, const struct smap *details);
|
||||||
|
|
||||||
int netdev_get_queue(const struct netdev *,
|
int netdev_get_queue(const struct netdev *,
|
||||||
unsigned int queue_id, struct shash *details);
|
unsigned int queue_id, struct smap *details);
|
||||||
int netdev_set_queue(struct netdev *,
|
int netdev_set_queue(struct netdev *,
|
||||||
unsigned int queue_id, const struct shash *details);
|
unsigned int queue_id, const struct smap *details);
|
||||||
int netdev_delete_queue(struct netdev *, unsigned int queue_id);
|
int netdev_delete_queue(struct netdev *, unsigned int queue_id);
|
||||||
int netdev_get_queue_stats(const struct netdev *, unsigned int queue_id,
|
int netdev_get_queue_stats(const struct netdev *, unsigned int queue_id,
|
||||||
struct netdev_queue_stats *);
|
struct netdev_queue_stats *);
|
||||||
|
|
||||||
typedef void netdev_dump_queues_cb(unsigned int queue_id,
|
typedef void netdev_dump_queues_cb(unsigned int queue_id,
|
||||||
const struct shash *details, void *aux);
|
const struct smap *details, void *aux);
|
||||||
int netdev_dump_queues(const struct netdev *,
|
int netdev_dump_queues(const struct netdev *,
|
||||||
netdev_dump_queues_cb *, void *aux);
|
netdev_dump_queues_cb *, void *aux);
|
||||||
|
|
||||||
|
55
lib/shash.c
55
lib/shash.c
@@ -313,58 +313,3 @@ shash_random_node(struct shash *sh)
|
|||||||
{
|
{
|
||||||
return CONTAINER_OF(hmap_random_node(&sh->map), struct shash_node, node);
|
return CONTAINER_OF(hmap_random_node(&sh->map), struct shash_node, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* String-to-string maps (smaps). */
|
|
||||||
|
|
||||||
/* Frees 'smap', including its keys and string values. */
|
|
||||||
void
|
|
||||||
smap_destroy(struct shash *smap)
|
|
||||||
{
|
|
||||||
shash_destroy_free_data(smap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if string-to-string maps 'a' and 'b' contain the same keys and
|
|
||||||
* values, false otherwise. */
|
|
||||||
bool
|
|
||||||
smap_equal(const struct shash *a, const struct shash *b)
|
|
||||||
{
|
|
||||||
struct shash_node *a_node;
|
|
||||||
|
|
||||||
if (shash_count(a) != shash_count(b)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHASH_FOR_EACH (a_node, a) {
|
|
||||||
uint32_t hash = a_node->node.hash;
|
|
||||||
size_t len = strlen(a_node->name);
|
|
||||||
struct shash_node *b_node = shash_find__(b, a_node->name, len, hash);
|
|
||||||
if (!b_node || strcmp(a_node->data, b_node->data)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initializes 'dst' as a clone of 'src'. */
|
|
||||||
void
|
|
||||||
smap_clone(struct shash *dst, const struct shash *src)
|
|
||||||
{
|
|
||||||
struct shash_node *node;
|
|
||||||
|
|
||||||
shash_init(dst);
|
|
||||||
SHASH_FOR_EACH (node, src) {
|
|
||||||
shash_add_nocopy__(dst, xstrdup(node->name), xstrdup(node->data),
|
|
||||||
node->node.hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adds 'key' with string 'value' to 'smap', making a copy of each.
|
|
||||||
*
|
|
||||||
* It is the caller's responsibility to avoid duplicate names, if that is
|
|
||||||
* desirable. */
|
|
||||||
void
|
|
||||||
smap_add(struct shash *smap, const char *key, const char *value)
|
|
||||||
{
|
|
||||||
shash_add(smap, key, xstrdup(value));
|
|
||||||
}
|
|
||||||
|
@@ -67,12 +67,6 @@ const struct shash_node **shash_sort(const struct shash *);
|
|||||||
bool shash_equal_keys(const struct shash *, const struct shash *);
|
bool shash_equal_keys(const struct shash *, const struct shash *);
|
||||||
struct shash_node *shash_random_node(struct shash *);
|
struct shash_node *shash_random_node(struct shash *);
|
||||||
|
|
||||||
/* Working with "smaps": shashes used as string-to-string maps. */
|
|
||||||
void smap_destroy(struct shash *);
|
|
||||||
bool smap_equal(const struct shash *, const struct shash *);
|
|
||||||
void smap_clone(struct shash *, const struct shash *);
|
|
||||||
void smap_add(struct shash *, const char *key, const char *value);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
269
lib/smap.c
Normal file
269
lib/smap.c
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
/* Copyright (c) 2012 Nicira, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include "smap.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
|
static struct smap_node *smap_add__(struct smap *, char *, void *,
|
||||||
|
size_t hash);
|
||||||
|
static struct smap_node *smap_find__(const struct smap *, const char *key,
|
||||||
|
size_t key_len, size_t hash);
|
||||||
|
static int compare_nodes_by_key(const void *, const void *);
|
||||||
|
|
||||||
|
/* Public Functions. */
|
||||||
|
|
||||||
|
void
|
||||||
|
smap_init(struct smap *smap)
|
||||||
|
{
|
||||||
|
hmap_init(&smap->map);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
smap_destroy(struct smap *smap)
|
||||||
|
{
|
||||||
|
if (smap) {
|
||||||
|
smap_clear(smap);
|
||||||
|
hmap_destroy(&smap->map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adds 'key' paired with 'value' to 'smap'. It is the caller's responsibility
|
||||||
|
* to avoid duplicate keys if desirable. */
|
||||||
|
struct smap_node *
|
||||||
|
smap_add(struct smap *smap, const char *key, const char *value)
|
||||||
|
{
|
||||||
|
size_t key_len = strlen(key);
|
||||||
|
return smap_add__(smap, xmemdup0(key, key_len), xstrdup(value),
|
||||||
|
hash_bytes(key, key_len, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attempts to add 'key' to 'smap' associated with 'value'. If 'key' already
|
||||||
|
* exists in 'smap', does nothing and returns false. Otherwise, performs the
|
||||||
|
* addition and returns true. */
|
||||||
|
bool
|
||||||
|
smap_add_once(struct smap *smap, const char *key, const char *value)
|
||||||
|
{
|
||||||
|
if (!smap_get(smap, key)) {
|
||||||
|
smap_add(smap, key, value);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adds 'key' paired with a value derived from 'format' (similar to printf).
|
||||||
|
* It is the caller's responsibility to avoid duplicate keys if desirable. */
|
||||||
|
void
|
||||||
|
smap_add_format(struct smap *smap, const char *key, const char *format, ...)
|
||||||
|
{
|
||||||
|
size_t key_len;
|
||||||
|
va_list args;
|
||||||
|
char *value;
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
value = xvasprintf(format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
key_len = strlen(key);
|
||||||
|
smap_add__(smap, xmemdup0(key, key_len), value,
|
||||||
|
hash_bytes(key, key_len, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Searches for 'key' in 'smap'. If it does not already exists, adds it.
|
||||||
|
* Otherwise, changes its value to 'value'. */
|
||||||
|
void
|
||||||
|
smap_replace(struct smap *smap, const char *key, const char *value)
|
||||||
|
{
|
||||||
|
size_t key_len = strlen(key);
|
||||||
|
size_t hash = hash_bytes(key, key_len, 0);
|
||||||
|
|
||||||
|
struct smap_node *node;
|
||||||
|
|
||||||
|
node = smap_find__(smap, key, key_len, hash);
|
||||||
|
if (node) {
|
||||||
|
free(node->value);
|
||||||
|
node->value = xstrdup(value);
|
||||||
|
} else {
|
||||||
|
smap_add__(smap, xmemdup0(key, key_len), xstrdup(value), hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If 'key' is in 'smap', removes it. Otherwise does nothing. */
|
||||||
|
void
|
||||||
|
smap_remove(struct smap *smap, const char *key)
|
||||||
|
{
|
||||||
|
struct smap_node *node = smap_get_node(smap, key);
|
||||||
|
|
||||||
|
if (node) {
|
||||||
|
smap_remove_node(smap, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Removes 'node' from 'smap'. */
|
||||||
|
void
|
||||||
|
smap_remove_node(struct smap *smap, struct smap_node *node)
|
||||||
|
{
|
||||||
|
hmap_remove(&smap->map, &node->node);
|
||||||
|
free(node->key);
|
||||||
|
free(node->value);
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Removes all key-value pairs from 'smap'. */
|
||||||
|
void
|
||||||
|
smap_clear(struct smap *smap)
|
||||||
|
{
|
||||||
|
struct smap_node *node, *next;
|
||||||
|
|
||||||
|
SMAP_FOR_EACH_SAFE (node, next, smap) {
|
||||||
|
smap_remove_node(smap, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the value associated with 'key' in 'smap', or NULL. */
|
||||||
|
const char *
|
||||||
|
smap_get(const struct smap *smap, const char *key)
|
||||||
|
{
|
||||||
|
struct smap_node *node = smap_get_node(smap, key);
|
||||||
|
return node ? node->value : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the node associated with 'key' in 'smap', or NULL. */
|
||||||
|
struct smap_node *
|
||||||
|
smap_get_node(const struct smap *smap, const char *key)
|
||||||
|
{
|
||||||
|
size_t key_len = strlen(key);
|
||||||
|
return smap_find__(smap, key, key_len, hash_bytes(key, key_len, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gets the value associated with 'key' in 'smap' and converts it to a boolean.
|
||||||
|
* If 'key' is not in 'smap', or its value is neither "true" nor "false",
|
||||||
|
* returns 'def'. */
|
||||||
|
bool
|
||||||
|
smap_get_bool(const struct smap *smap, const char *key, bool def)
|
||||||
|
{
|
||||||
|
const char *value = smap_get(smap, key);
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (def) {
|
||||||
|
return strcasecmp("false", value) != 0;
|
||||||
|
} else {
|
||||||
|
return !strcasecmp("true", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gets the value associated with 'key' in 'smap' and converts it to an int
|
||||||
|
* using atoi(). If 'key' is not in 'smap', returns 'def'. */
|
||||||
|
int
|
||||||
|
smap_get_int(const struct smap *smap, const char *key, int def)
|
||||||
|
{
|
||||||
|
const char *value = smap_get(smap, key);
|
||||||
|
|
||||||
|
return value ? atoi(value) : def;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns true of there are no elements in 'smap'. */
|
||||||
|
bool
|
||||||
|
smap_is_empty(const struct smap *smap)
|
||||||
|
{
|
||||||
|
return hmap_is_empty(&smap->map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the number of elements in 'smap'. */
|
||||||
|
size_t
|
||||||
|
smap_count(const struct smap *smap)
|
||||||
|
{
|
||||||
|
return hmap_count(&smap->map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initializes 'dst' as a clone of 'src. */
|
||||||
|
void
|
||||||
|
smap_clone(struct smap *dst, struct smap *src)
|
||||||
|
{
|
||||||
|
struct smap_node *node;
|
||||||
|
|
||||||
|
smap_init(dst);
|
||||||
|
SMAP_FOR_EACH (node, src) {
|
||||||
|
smap_add__(dst, xstrdup(node->key), xstrdup(node->value),
|
||||||
|
node->node.hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns an array of nodes sorted on key or NULL if 'smap' is empty. The
|
||||||
|
* caller is responsible for freeing this array. */
|
||||||
|
const struct smap_node **
|
||||||
|
smap_sort(const struct smap *smap)
|
||||||
|
{
|
||||||
|
if (smap_is_empty(smap)) {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
const struct smap_node **nodes;
|
||||||
|
struct smap_node *node;
|
||||||
|
size_t i, n;
|
||||||
|
|
||||||
|
n = smap_count(smap);
|
||||||
|
nodes = xmalloc(n * sizeof *nodes);
|
||||||
|
i = 0;
|
||||||
|
SMAP_FOR_EACH (node, smap) {
|
||||||
|
nodes[i++] = node;
|
||||||
|
}
|
||||||
|
assert(i == n);
|
||||||
|
|
||||||
|
qsort(nodes, n, sizeof *nodes, compare_nodes_by_key);
|
||||||
|
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Private Helpers. */
|
||||||
|
|
||||||
|
static struct smap_node *
|
||||||
|
smap_add__(struct smap *smap, char *key, void *value, size_t hash)
|
||||||
|
{
|
||||||
|
struct smap_node *node = xmalloc(sizeof *node);
|
||||||
|
node->key = key;
|
||||||
|
node->value = value;
|
||||||
|
hmap_insert(&smap->map, &node->node, hash);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct smap_node *
|
||||||
|
smap_find__(const struct smap *smap, const char *key, size_t key_len,
|
||||||
|
size_t hash)
|
||||||
|
{
|
||||||
|
struct smap_node *node;
|
||||||
|
|
||||||
|
HMAP_FOR_EACH_WITH_HASH (node, node, hash, &smap->map) {
|
||||||
|
if (!strncmp(node->key, key, key_len) && !node->key[key_len]) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare_nodes_by_key(const void *a_, const void *b_)
|
||||||
|
{
|
||||||
|
const struct smap_node *const *a = a_;
|
||||||
|
const struct smap_node *const *b = b_;
|
||||||
|
return strcmp((*a)->key, (*b)->key);
|
||||||
|
}
|
63
lib/smap.h
Normal file
63
lib/smap.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/* Copyright (c) 2012 Nicira, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License. */
|
||||||
|
|
||||||
|
#ifndef SMAP_H
|
||||||
|
#define SMAP_H 1
|
||||||
|
|
||||||
|
#include "hmap.h"
|
||||||
|
|
||||||
|
/* A map from string to string. */
|
||||||
|
struct smap {
|
||||||
|
struct hmap map; /* Contains "struct smap_node"s. */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct smap_node {
|
||||||
|
struct hmap_node node; /* In struct smap's 'map' hmap. */
|
||||||
|
char *key;
|
||||||
|
char *value;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SMAP_INITIALIZER(SMAP) { HMAP_INITIALIZER(&(SMAP)->map) }
|
||||||
|
|
||||||
|
#define SMAP_FOR_EACH(SMAP_NODE, SMAP) \
|
||||||
|
HMAP_FOR_EACH (SMAP_NODE, node, &(SMAP)->map)
|
||||||
|
|
||||||
|
#define SMAP_FOR_EACH_SAFE(SMAP_NODE, NEXT, SMAP) \
|
||||||
|
HMAP_FOR_EACH_SAFE (SMAP_NODE, NEXT, node, &(SMAP)->map)
|
||||||
|
|
||||||
|
void smap_init(struct smap *);
|
||||||
|
void smap_destroy(struct smap *);
|
||||||
|
|
||||||
|
struct smap_node *smap_add(struct smap *, const char *, const char *);
|
||||||
|
bool smap_add_once(struct smap *, const char *, const char *);
|
||||||
|
void smap_add_format(struct smap *, const char *key, const char *, ...)
|
||||||
|
PRINTF_FORMAT(3, 4);
|
||||||
|
void smap_replace(struct smap *, const char *, const char *);
|
||||||
|
|
||||||
|
void smap_remove(struct smap *, const char *);
|
||||||
|
void smap_remove_node(struct smap *smap, struct smap_node *);
|
||||||
|
void smap_clear(struct smap *);
|
||||||
|
|
||||||
|
const char *smap_get(const struct smap *, const char *);
|
||||||
|
struct smap_node *smap_get_node(const struct smap *, const char *);
|
||||||
|
bool smap_get_bool(const struct smap *smap, const char *key, bool def);
|
||||||
|
int smap_get_int(const struct smap *smap, const char *key, int def);
|
||||||
|
|
||||||
|
bool smap_is_empty(const struct smap *);
|
||||||
|
size_t smap_count(const struct smap *);
|
||||||
|
|
||||||
|
void smap_clone(struct smap *dst, struct smap *src);
|
||||||
|
const struct smap_node **smap_sort(const struct smap *);
|
||||||
|
|
||||||
|
#endif /* smap.h */
|
@@ -44,6 +44,7 @@
|
|||||||
#include "packets.h"
|
#include "packets.h"
|
||||||
#include "shash.h"
|
#include "shash.h"
|
||||||
#include "simap.h"
|
#include "simap.h"
|
||||||
|
#include "smap.h"
|
||||||
#include "sset.h"
|
#include "sset.h"
|
||||||
#include "timeval.h"
|
#include "timeval.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@@ -246,7 +247,7 @@ do_add_if(int argc OVS_UNUSED, char *argv[])
|
|||||||
const char *name, *type;
|
const char *name, *type;
|
||||||
char *save_ptr = NULL;
|
char *save_ptr = NULL;
|
||||||
struct netdev *netdev = NULL;
|
struct netdev *netdev = NULL;
|
||||||
struct shash args;
|
struct smap args;
|
||||||
char *option;
|
char *option;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@@ -259,7 +260,7 @@ do_add_if(int argc OVS_UNUSED, char *argv[])
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
shash_init(&args);
|
smap_init(&args);
|
||||||
while ((option = strtok_r(NULL, ",", &save_ptr)) != NULL) {
|
while ((option = strtok_r(NULL, ",", &save_ptr)) != NULL) {
|
||||||
char *save_ptr_2 = NULL;
|
char *save_ptr_2 = NULL;
|
||||||
char *key, *value;
|
char *key, *value;
|
||||||
@@ -272,7 +273,7 @@ do_add_if(int argc OVS_UNUSED, char *argv[])
|
|||||||
|
|
||||||
if (!strcmp(key, "type")) {
|
if (!strcmp(key, "type")) {
|
||||||
type = value;
|
type = value;
|
||||||
} else if (!shash_add_once(&args, key, value)) {
|
} else if (!smap_add_once(&args, key, value)) {
|
||||||
ovs_error(0, "duplicate \"%s\" option", key);
|
ovs_error(0, "duplicate \"%s\" option", key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -323,7 +324,7 @@ do_set_if(int argc, char *argv[])
|
|||||||
char *save_ptr = NULL;
|
char *save_ptr = NULL;
|
||||||
char *type = NULL;
|
char *type = NULL;
|
||||||
const char *name;
|
const char *name;
|
||||||
struct shash args;
|
struct smap args;
|
||||||
char *option;
|
char *option;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@@ -350,7 +351,7 @@ do_set_if(int argc, char *argv[])
|
|||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
shash_init(&args);
|
smap_init(&args);
|
||||||
error = netdev_get_config(netdev, &args);
|
error = netdev_get_config(netdev, &args);
|
||||||
if (error) {
|
if (error) {
|
||||||
ovs_error(error, "%s: failed to fetch configuration", name);
|
ovs_error(error, "%s: failed to fetch configuration", name);
|
||||||
@@ -375,9 +376,9 @@ do_set_if(int argc, char *argv[])
|
|||||||
failure = true;
|
failure = true;
|
||||||
}
|
}
|
||||||
} else if (value[0] == '\0') {
|
} else if (value[0] == '\0') {
|
||||||
free(shash_find_and_delete(&args, key));
|
smap_remove(&args, key);
|
||||||
} else {
|
} else {
|
||||||
free(shash_replace(&args, key, xstrdup(value)));
|
smap_replace(&args, key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,26 +501,26 @@ show_dpif(struct dpif *dpif)
|
|||||||
|
|
||||||
error = netdev_open(dpif_port.name, dpif_port.type, &netdev);
|
error = netdev_open(dpif_port.name, dpif_port.type, &netdev);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
struct shash config;
|
struct smap config;
|
||||||
|
|
||||||
shash_init(&config);
|
smap_init(&config);
|
||||||
error = netdev_get_config(netdev, &config);
|
error = netdev_get_config(netdev, &config);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
const struct shash_node **nodes;
|
const struct smap_node **nodes;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
nodes = shash_sort(&config);
|
nodes = smap_sort(&config);
|
||||||
for (i = 0; i < shash_count(&config); i++) {
|
for (i = 0; i < smap_count(&config); i++) {
|
||||||
const struct shash_node *node = nodes[i];
|
const struct smap_node *node = nodes[i];
|
||||||
printf("%c %s=%s", i ? ',' : ':',
|
printf("%c %s=%s", i ? ',' : ':', node->key,
|
||||||
node->name, (char *) node->data);
|
node->value);
|
||||||
}
|
}
|
||||||
free(nodes);
|
free(nodes);
|
||||||
} else {
|
} else {
|
||||||
printf(", could not retrieve configuration (%s)",
|
printf(", could not retrieve configuration (%s)",
|
||||||
strerror(error));
|
strerror(error));
|
||||||
}
|
}
|
||||||
shash_destroy_free_data(&config);
|
smap_destroy(&config);
|
||||||
|
|
||||||
netdev_close(netdev);
|
netdev_close(netdev);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -3936,7 +3936,7 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
|
|||||||
table_destroy(c->table);
|
table_destroy(c->table);
|
||||||
free(c->table);
|
free(c->table);
|
||||||
|
|
||||||
smap_destroy(&c->options);
|
shash_destroy_free_data(&c->options);
|
||||||
}
|
}
|
||||||
free(commands);
|
free(commands);
|
||||||
|
|
||||||
|
@@ -41,6 +41,7 @@
|
|||||||
#include "poll-loop.h"
|
#include "poll-loop.h"
|
||||||
#include "sha1.h"
|
#include "sha1.h"
|
||||||
#include "shash.h"
|
#include "shash.h"
|
||||||
|
#include "smap.h"
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "stream-ssl.h"
|
#include "stream-ssl.h"
|
||||||
@@ -245,10 +246,10 @@ static void iface_refresh_cfm_stats(struct iface *);
|
|||||||
static void iface_refresh_stats(struct iface *);
|
static void iface_refresh_stats(struct iface *);
|
||||||
static void iface_refresh_status(struct iface *);
|
static void iface_refresh_status(struct iface *);
|
||||||
static bool iface_is_synthetic(const struct iface *);
|
static bool iface_is_synthetic(const struct iface *);
|
||||||
static void shash_from_ovs_idl_map(char **keys, char **values, size_t n,
|
static void smap_from_ovs_idl_map(char **keys, char **values, size_t n,
|
||||||
struct shash *);
|
struct smap *);
|
||||||
static void shash_to_ovs_idl_map(struct shash *,
|
static void smap_to_ovs_idl_map(struct smap *,
|
||||||
char ***keys, char ***values, size_t *n);
|
char ***keys, char ***values, size_t *n);
|
||||||
|
|
||||||
/* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.)
|
/* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.)
|
||||||
*
|
*
|
||||||
@@ -1150,15 +1151,15 @@ static int
|
|||||||
iface_set_netdev_config(const struct ovsrec_interface *iface_cfg,
|
iface_set_netdev_config(const struct ovsrec_interface *iface_cfg,
|
||||||
struct netdev *netdev)
|
struct netdev *netdev)
|
||||||
{
|
{
|
||||||
struct shash args;
|
struct smap args;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
shash_init(&args);
|
smap_init(&args);
|
||||||
shash_from_ovs_idl_map(iface_cfg->key_options,
|
smap_from_ovs_idl_map(iface_cfg->key_options,
|
||||||
iface_cfg->value_options,
|
iface_cfg->value_options,
|
||||||
iface_cfg->n_options, &args);
|
iface_cfg->n_options, &args);
|
||||||
error = netdev_set_config(netdev, &args);
|
error = netdev_set_config(netdev, &args);
|
||||||
shash_destroy(&args);
|
smap_destroy(&args);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
VLOG_WARN("could not configure network device %s (%s)",
|
VLOG_WARN("could not configure network device %s (%s)",
|
||||||
@@ -1650,7 +1651,7 @@ dpid_from_hash(const void *data, size_t n)
|
|||||||
static void
|
static void
|
||||||
iface_refresh_status(struct iface *iface)
|
iface_refresh_status(struct iface *iface)
|
||||||
{
|
{
|
||||||
struct shash sh;
|
struct smap smap;
|
||||||
|
|
||||||
enum netdev_features current;
|
enum netdev_features current;
|
||||||
enum netdev_flags flags;
|
enum netdev_flags flags;
|
||||||
@@ -1663,13 +1664,13 @@ iface_refresh_status(struct iface *iface)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
shash_init(&sh);
|
smap_init(&smap);
|
||||||
|
|
||||||
if (!netdev_get_drv_info(iface->netdev, &sh)) {
|
if (!netdev_get_drv_info(iface->netdev, &smap)) {
|
||||||
size_t n;
|
size_t n;
|
||||||
char **keys, **values;
|
char **keys, **values;
|
||||||
|
|
||||||
shash_to_ovs_idl_map(&sh, &keys, &values, &n);
|
smap_to_ovs_idl_map(&smap, &keys, &values, &n);
|
||||||
ovsrec_interface_set_status(iface->cfg, keys, values, n);
|
ovsrec_interface_set_status(iface->cfg, keys, values, n);
|
||||||
|
|
||||||
free(keys);
|
free(keys);
|
||||||
@@ -1678,7 +1679,7 @@ iface_refresh_status(struct iface *iface)
|
|||||||
ovsrec_interface_set_status(iface->cfg, NULL, NULL, 0);
|
ovsrec_interface_set_status(iface->cfg, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
shash_destroy_free_data(&sh);
|
smap_destroy(&smap);
|
||||||
|
|
||||||
error = netdev_get_flags(iface->netdev, &flags);
|
error = netdev_get_flags(iface->netdev, &flags);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
@@ -2250,14 +2251,14 @@ struct qos_unixctl_show_cbdata {
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
qos_unixctl_show_cb(unsigned int queue_id,
|
qos_unixctl_show_cb(unsigned int queue_id,
|
||||||
const struct shash *details,
|
const struct smap *details,
|
||||||
void *aux)
|
void *aux)
|
||||||
{
|
{
|
||||||
struct qos_unixctl_show_cbdata *data = aux;
|
struct qos_unixctl_show_cbdata *data = aux;
|
||||||
struct ds *ds = data->ds;
|
struct ds *ds = data->ds;
|
||||||
struct iface *iface = data->iface;
|
struct iface *iface = data->iface;
|
||||||
struct netdev_queue_stats stats;
|
struct netdev_queue_stats stats;
|
||||||
struct shash_node *node;
|
struct smap_node *node;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
ds_put_cstr(ds, "\n");
|
ds_put_cstr(ds, "\n");
|
||||||
@@ -2267,8 +2268,8 @@ qos_unixctl_show_cb(unsigned int queue_id,
|
|||||||
ds_put_cstr(ds, "Default:\n");
|
ds_put_cstr(ds, "Default:\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
SHASH_FOR_EACH (node, details) {
|
SMAP_FOR_EACH (node, details) {
|
||||||
ds_put_format(ds, "\t%s: %s\n", node->name, (char *)node->data);
|
ds_put_format(ds, "\t%s: %s\n", node->key, node->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
error = netdev_get_queue_stats(iface->netdev, queue_id, &stats);
|
error = netdev_get_queue_stats(iface->netdev, queue_id, &stats);
|
||||||
@@ -2295,10 +2296,10 @@ qos_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
|
|||||||
const char *argv[], void *aux OVS_UNUSED)
|
const char *argv[], void *aux OVS_UNUSED)
|
||||||
{
|
{
|
||||||
struct ds ds = DS_EMPTY_INITIALIZER;
|
struct ds ds = DS_EMPTY_INITIALIZER;
|
||||||
struct shash sh = SHASH_INITIALIZER(&sh);
|
struct smap smap = SMAP_INITIALIZER(&smap);
|
||||||
struct iface *iface;
|
struct iface *iface;
|
||||||
const char *type;
|
const char *type;
|
||||||
struct shash_node *node;
|
struct smap_node *node;
|
||||||
struct qos_unixctl_show_cbdata data;
|
struct qos_unixctl_show_cbdata data;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@@ -2308,13 +2309,13 @@ qos_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
netdev_get_qos(iface->netdev, &type, &sh);
|
netdev_get_qos(iface->netdev, &type, &smap);
|
||||||
|
|
||||||
if (*type != '\0') {
|
if (*type != '\0') {
|
||||||
ds_put_format(&ds, "QoS: %s %s\n", iface->name, type);
|
ds_put_format(&ds, "QoS: %s %s\n", iface->name, type);
|
||||||
|
|
||||||
SHASH_FOR_EACH (node, &sh) {
|
SMAP_FOR_EACH (node, &smap) {
|
||||||
ds_put_format(&ds, "%s: %s\n", node->name, (char *)node->data);
|
ds_put_format(&ds, "%s: %s\n", node->key, node->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
data.ds = &ds;
|
data.ds = &ds;
|
||||||
@@ -2330,7 +2331,7 @@ qos_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
|
|||||||
unixctl_command_reply_error(conn, ds_cstr(&ds));
|
unixctl_command_reply_error(conn, ds_cstr(&ds));
|
||||||
}
|
}
|
||||||
|
|
||||||
shash_destroy_free_data(&sh);
|
smap_destroy(&smap);
|
||||||
ds_destroy(&ds);
|
ds_destroy(&ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3273,46 +3274,42 @@ iface_clear_db_record(const struct ovsrec_interface *if_cfg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adds the 'n' key-value pairs in 'keys' in 'values' to 'shash'.
|
/* Adds the 'n' key-value pairs in 'keys' in 'values' to 'shash'. */
|
||||||
*
|
|
||||||
* The value strings in '*shash' are taken directly from values[], not copied,
|
|
||||||
* so the caller should not modify or free them. */
|
|
||||||
static void
|
static void
|
||||||
shash_from_ovs_idl_map(char **keys, char **values, size_t n,
|
smap_from_ovs_idl_map(char **keys, char **values, size_t n, struct smap *smap)
|
||||||
struct shash *shash)
|
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
shash_init(shash);
|
smap_init(smap);
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
shash_add(shash, keys[i], values[i]);
|
smap_add(smap, keys[i], values[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Creates 'keys' and 'values' arrays from 'shash'.
|
/* Creates 'keys' and 'values' arrays from 'shash'.
|
||||||
*
|
*
|
||||||
* Sets 'keys' and 'values' to heap allocated arrays representing the key-value
|
* Sets 'keys' and 'values' to heap allocated arrays representing the key-value
|
||||||
* pairs in 'shash'. The caller takes ownership of 'keys' and 'values'. They
|
* pairs in 'smap'. The caller takes ownership of 'keys' and 'values'. They
|
||||||
* are populated with with strings taken directly from 'shash' and thus have
|
* are populated with with strings taken directly from 'shash' and thus have
|
||||||
* the same ownership of the key-value pairs in shash.
|
* the same ownership of the key-value pairs in shash.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
shash_to_ovs_idl_map(struct shash *shash,
|
smap_to_ovs_idl_map(struct smap *smap,
|
||||||
char ***keys, char ***values, size_t *n)
|
char ***keys, char ***values, size_t *n)
|
||||||
{
|
{
|
||||||
size_t i, count;
|
size_t i, count;
|
||||||
char **k, **v;
|
char **k, **v;
|
||||||
struct shash_node *sn;
|
struct smap_node *sn;
|
||||||
|
|
||||||
count = shash_count(shash);
|
count = smap_count(smap);
|
||||||
|
|
||||||
k = xmalloc(count * sizeof *k);
|
k = xmalloc(count * sizeof *k);
|
||||||
v = xmalloc(count * sizeof *v);
|
v = xmalloc(count * sizeof *v);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
SHASH_FOR_EACH(sn, shash) {
|
SMAP_FOR_EACH(sn, smap) {
|
||||||
k[i] = sn->name;
|
k[i] = sn->key;
|
||||||
v[i] = sn->data;
|
v[i] = sn->value;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3337,7 +3334,7 @@ queue_ids_include(const struct ovsdb_datum *queues, int64_t target)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
iface_delete_queues(unsigned int queue_id,
|
iface_delete_queues(unsigned int queue_id,
|
||||||
const struct shash *details OVS_UNUSED, void *cbdata_)
|
const struct smap *details OVS_UNUSED, void *cbdata_)
|
||||||
{
|
{
|
||||||
struct iface_delete_queues_cbdata *cbdata = cbdata_;
|
struct iface_delete_queues_cbdata *cbdata = cbdata_;
|
||||||
|
|
||||||
@@ -3357,15 +3354,15 @@ iface_configure_qos(struct iface *iface, const struct ovsrec_qos *qos)
|
|||||||
netdev_set_qos(iface->netdev, NULL, NULL);
|
netdev_set_qos(iface->netdev, NULL, NULL);
|
||||||
} else {
|
} else {
|
||||||
struct iface_delete_queues_cbdata cbdata;
|
struct iface_delete_queues_cbdata cbdata;
|
||||||
struct shash details;
|
struct smap details;
|
||||||
bool queue_zero;
|
bool queue_zero;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
/* Configure top-level Qos for 'iface'. */
|
/* Configure top-level Qos for 'iface'. */
|
||||||
shash_from_ovs_idl_map(qos->key_other_config, qos->value_other_config,
|
smap_from_ovs_idl_map(qos->key_other_config, qos->value_other_config,
|
||||||
qos->n_other_config, &details);
|
qos->n_other_config, &details);
|
||||||
netdev_set_qos(iface->netdev, qos->type, &details);
|
netdev_set_qos(iface->netdev, qos->type, &details);
|
||||||
shash_destroy(&details);
|
smap_destroy(&details);
|
||||||
|
|
||||||
/* Deconfigure queues that were deleted. */
|
/* Deconfigure queues that were deleted. */
|
||||||
cbdata.netdev = iface->netdev;
|
cbdata.netdev = iface->netdev;
|
||||||
@@ -3392,16 +3389,16 @@ iface_configure_qos(struct iface *iface, const struct ovsrec_qos *qos)
|
|||||||
port_queue->dscp = queue->dscp[0];
|
port_queue->dscp = queue->dscp[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
shash_from_ovs_idl_map(queue->key_other_config,
|
smap_from_ovs_idl_map(queue->key_other_config,
|
||||||
queue->value_other_config,
|
queue->value_other_config,
|
||||||
queue->n_other_config, &details);
|
queue->n_other_config, &details);
|
||||||
netdev_set_queue(iface->netdev, queue_id, &details);
|
netdev_set_queue(iface->netdev, queue_id, &details);
|
||||||
shash_destroy(&details);
|
smap_destroy(&details);
|
||||||
}
|
}
|
||||||
if (!queue_zero) {
|
if (!queue_zero) {
|
||||||
shash_init(&details);
|
smap_init(&details);
|
||||||
netdev_set_queue(iface->netdev, 0, &details);
|
netdev_set_queue(iface->netdev, 0, &details);
|
||||||
shash_destroy(&details);
|
smap_destroy(&details);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user