[ovs-dev] [PATCH 1/3] ovn: ovn-controller changes for qos settings
bschanmu at redhat.com
bschanmu at redhat.com
Tue Jan 5 14:03:17 UTC 2016
The qos settings are managed using the 'options' fields in the
"Port_Binding" table.
Signed-off-by: Babu Shanmugam <bschanmu at redhat.com>
---
ovn/controller/binding.c | 116 +++++++++++++++++++++++++++++++++++++++-
ovn/controller/ovn-controller.c | 4 ++
2 files changed, 118 insertions(+), 2 deletions(-)
diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c
index 1854ff4..0556662 100644
--- a/ovn/controller/binding.c
+++ b/ovn/controller/binding.c
@@ -19,6 +19,8 @@
#include "lib/bitmap.h"
#include "lib/sset.h"
#include "lib/util.h"
+#include "lib/hmap.h"
+#include "lib/hash.h"
#include "lib/vswitch-idl.h"
#include "openvswitch/vlog.h"
#include "ovn/lib/ovn-sb-idl.h"
@@ -26,6 +28,13 @@
VLOG_DEFINE_THIS_MODULE(binding);
+struct iface_qos {
+ struct hmap_node hmap_node;
+ const char *iface_id;
+ uint32_t policing_rate;
+ uint32_t policing_burst;
+};
+
void
binding_register_ovs_idl(struct ovsdb_idl *ovs_idl)
{
@@ -46,7 +55,8 @@ binding_register_ovs_idl(struct ovsdb_idl *ovs_idl)
}
static void
-get_local_iface_ids(const struct ovsrec_bridge *br_int, struct sset *lports)
+get_local_iface_ids(const struct ovsrec_bridge *br_int, struct sset *lports,
+ struct hmap *iface_qos)
{
int i;
@@ -68,6 +78,101 @@ get_local_iface_ids(const struct ovsrec_bridge *br_int, struct sset *lports)
continue;
}
sset_add(lports, iface_id);
+ if (iface_rec->ingress_policing_rate > 0) {
+ struct iface_qos *qos = xmalloc(sizeof (*qos));
+
+ hmap_insert(iface_qos, &qos->hmap_node,
+ hash_string(iface_id, 0));
+ qos->iface_id = iface_id;
+ qos->policing_rate = iface_rec->ingress_policing_rate;
+ qos->policing_burst = iface_rec->ingress_policing_burst;
+ }
+ }
+ }
+}
+
+static struct iface_qos *
+iface_qos_find(struct hmap *iface_qos, const char *iface_id)
+{
+ struct iface_qos *qos;
+
+ HMAP_FOR_EACH_WITH_HASH(qos, hmap_node, hash_string(iface_id, 0),
+ iface_qos) {
+ if (!strcmp(qos->iface_id, iface_id)) {
+ return qos;
+ }
+ }
+ return NULL;
+}
+
+static void
+update_qos_map(const struct sbrec_port_binding *binding_rec,
+ struct hmap *iface_qos)
+{
+ struct iface_qos *qos;
+ bool is_vif = (strlen(binding_rec->type) == 0);
+
+ qos = iface_qos_find(iface_qos, binding_rec->logical_port);
+
+ uint32_t rate =
+ (uint32_t) smap_get_int(&binding_rec->options, "policing_rate", 0);
+ uint32_t burst =
+ (uint32_t) smap_get_int(&binding_rec->options, "policing_burst", 0);
+
+ if (qos) {
+ if ((qos->policing_burst == burst && qos->policing_rate == rate) ||
+ !is_vif) {
+ /* Remove this node, as there are no updates */
+ hmap_remove(iface_qos, &qos->hmap_node);
+ } else {
+ /* Update */
+ qos->policing_rate = rate;
+ qos->policing_burst = burst;
+ }
+ } else if (rate > 0 && is_vif) {
+ /* New setting */
+ qos = xmalloc(sizeof (*qos));
+
+ hmap_insert(iface_qos, &qos->hmap_node,
+ hash_string(binding_rec->logical_port, 0));
+ qos->iface_id = binding_rec->logical_port;
+ qos->policing_rate = rate;
+ qos->policing_burst = burst;
+ }
+}
+
+static void
+update_qos_interface_table(const struct ovsrec_bridge *br_int,
+ struct hmap *iface_qos)
+{
+ int i;
+
+ for (i = 0; i < br_int->n_ports; i++) {
+ const struct ovsrec_port *port_rec = br_int->ports[i];
+ const char *iface_id;
+ int j;
+
+ if (!strcmp(port_rec->name, br_int->name)) {
+ continue;
+ }
+
+ for (j = 0; j < port_rec->n_interfaces; j++) {
+ struct ovsrec_interface *iface_rec;
+
+ iface_rec = port_rec->interfaces[j];
+ iface_id = smap_get(&iface_rec->external_ids, "iface-id");
+ if (!iface_id) {
+ continue;
+ }
+ struct iface_qos *qos = iface_qos_find(iface_qos, iface_id);
+
+ if (!qos) {
+ continue;
+ }
+ ovsrec_interface_set_ingress_policing_rate(iface_rec,
+ qos->policing_rate);
+ ovsrec_interface_set_ingress_policing_burst(iface_rec,
+ qos->policing_burst);
}
}
}
@@ -125,6 +230,7 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
const struct sbrec_chassis *chassis_rec;
const struct sbrec_port_binding *binding_rec;
struct sset lports, all_lports;
+ struct hmap iface_qos = HMAP_INITIALIZER(&iface_qos);
const char *name;
if (!ctx->ovnsb_idl_txn) {
@@ -139,7 +245,7 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
sset_init(&lports);
sset_init(&all_lports);
if (br_int) {
- get_local_iface_ids(br_int, &lports);
+ get_local_iface_ids(br_int, &lports, &iface_qos);
} else {
/* We have no integration bridge, therefore no local logical ports.
* We'll remove our chassis from all port binding records below. */
@@ -161,6 +267,7 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
/* Add child logical port to the set of all local ports. */
sset_add(&all_lports, binding_rec->logical_port);
}
+ update_qos_map(binding_rec, &iface_qos);
if (binding_rec->chassis == chassis_rec) {
continue;
}
@@ -182,6 +289,11 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
update_ct_zones(&all_lports, ct_zones, ct_zone_bitmap);
+ if (br_int) {
+ update_qos_interface_table(br_int, &iface_qos);
+ }
+
+ hmap_destroy(&iface_qos);
sset_destroy(&lports);
sset_destroy(&all_lports);
}
diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
index 02ecb3e..8b7eb64 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -239,6 +239,10 @@ main(int argc, char *argv[])
ovsdb_idl_add_column(ovs_idl_loop.idl, &ovsrec_interface_col_name);
ovsdb_idl_add_column(ovs_idl_loop.idl, &ovsrec_interface_col_type);
ovsdb_idl_add_column(ovs_idl_loop.idl, &ovsrec_interface_col_options);
+ ovsdb_idl_add_column(ovs_idl_loop.idl,
+ &ovsrec_interface_col_ingress_policing_rate);
+ ovsdb_idl_add_column(ovs_idl_loop.idl,
+ &ovsrec_interface_col_ingress_policing_burst);
ovsdb_idl_add_table(ovs_idl_loop.idl, &ovsrec_table_port);
ovsdb_idl_add_column(ovs_idl_loop.idl, &ovsrec_port_col_name);
ovsdb_idl_add_column(ovs_idl_loop.idl, &ovsrec_port_col_interfaces);
--
1.9.1
More information about the dev
mailing list