[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