bbaaef
From 9c04a4b62484895dc301875ad9da7c77c17a99c7 Mon Sep 17 00:00:00 2001
bbaaef
Message-Id: <9c04a4b62484895dc301875ad9da7c77c17a99c7.1569932887.git.lorenzo.bianconi@redhat.com>
bbaaef
From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
bbaaef
Date: Tue, 24 Sep 2019 18:39:54 +0200
bbaaef
Subject: [PATCH ovn 1/3] Add egress QoS mapping for non-tunnel interfaces
bbaaef
bbaaef
Introduce add_localnet_egress_interface_mappings routine in order to collect as
bbaaef
egress interfaces all ovs bridge interfaces marked with ovn-egress-iface
bbaaef
in the external_ids column of ovs interface table.
bbaaef
ovn-egress-iface is used to indicate to which localnet ports QoS egress
bbaaef
shaping has to be applied.
bbaaef
Refactor add_bridge_mappings routine
bbaaef
bbaaef
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
bbaaef
Signed-off-by: Mark Michelson <mmichels@redhat.com>
bbaaef
Acked-by: Mark Michelson <mmichels@redhat.com>
bbaaef
Acked-by: Dumitru Ceara <dceara@redhat.com>
bbaaef
---
bbaaef
 ovn/controller/binding.c        | 51 ++++++++++++++++++++++++-
bbaaef
 ovn/controller/binding.h        |  4 ++
bbaaef
 ovn/controller/ovn-controller.c |  3 +-
bbaaef
 ovn/controller/patch.c          | 76 +++++++++++++++++++++----------------
bbaaef
 ovn/controller/patch.h          |  4 ++
bbaaef
 5 files changed, 103 insertions(+), 35 deletions(-)
bbaaef
bbaaef
--- a/ovn/controller/binding.c
bbaaef
+++ b/ovn/controller/binding.c
bbaaef
@@ -18,6 +18,7 @@
bbaaef
 #include "ha-chassis.h"
bbaaef
 #include "lflow.h"
bbaaef
 #include "lport.h"
bbaaef
+#include "patch.h"
bbaaef
 
bbaaef
 #include "lib/bitmap.h"
bbaaef
 #include "openvswitch/poll-loop.h"
bbaaef
@@ -521,6 +522,9 @@ consider_local_datapath(struct ovsdb_idl
bbaaef
         /* Add all localnet ports to local_lports so that we allocate ct zones
bbaaef
          * for them. */
bbaaef
         sset_add(local_lports, binding_rec->logical_port);
bbaaef
+        if (qos_map && ovs_idl_txn) {
bbaaef
+            get_qos_params(binding_rec, qos_map);
bbaaef
+        }
bbaaef
     } else if (!strcmp(binding_rec->type, "external")) {
bbaaef
         if (ha_chassis_group_contains(binding_rec->ha_chassis_group,
bbaaef
                                       chassis_rec)) {
bbaaef
@@ -609,9 +613,47 @@ consider_local_datapath(struct ovsdb_idl
bbaaef
 }
bbaaef
 
bbaaef
 static void
bbaaef
+add_localnet_egress_interface_mappings(
bbaaef
+        const struct sbrec_port_binding *port_binding,
bbaaef
+        struct shash *bridge_mappings, struct sset *egress_ifaces)
bbaaef
+{
bbaaef
+    const char *network = smap_get(&port_binding->options, "network_name");
bbaaef
+    if (!network) {
bbaaef
+        return;
bbaaef
+    }
bbaaef
+
bbaaef
+    struct ovsrec_bridge *br_ln = shash_find_data(bridge_mappings, network);
bbaaef
+    if (!br_ln) {
bbaaef
+        return;
bbaaef
+    }
bbaaef
+
bbaaef
+    /* Add egress-ifaces from the connected bridge */
bbaaef
+    for (size_t i = 0; i < br_ln->n_ports; i++) {
bbaaef
+        const struct ovsrec_port *port_rec = br_ln->ports[i];
bbaaef
+
bbaaef
+        for (size_t j = 0; j < port_rec->n_interfaces; j++) {
bbaaef
+            const struct ovsrec_interface *iface_rec;
bbaaef
+
bbaaef
+            iface_rec = port_rec->interfaces[j];
bbaaef
+            bool is_egress_iface = smap_get_bool(&iface_rec->external_ids,
bbaaef
+                                                 "ovn-egress-iface", false);
bbaaef
+            if (!is_egress_iface) {
bbaaef
+                continue;
bbaaef
+            }
bbaaef
+            sset_add(egress_ifaces, iface_rec->name);
bbaaef
+        }
bbaaef
+    }
bbaaef
+}
bbaaef
+
bbaaef
+static void
bbaaef
 consider_localnet_port(const struct sbrec_port_binding *binding_rec,
bbaaef
+                       struct shash *bridge_mappings,
bbaaef
+                       struct sset *egress_ifaces,
bbaaef
                        struct hmap *local_datapaths)
bbaaef
 {
bbaaef
+    add_localnet_egress_interface_mappings(binding_rec,
bbaaef
+            bridge_mappings, egress_ifaces);
bbaaef
+
bbaaef
     struct local_datapath *ld
bbaaef
         = get_local_datapath(local_datapaths,
bbaaef
                              binding_rec->datapath->tunnel_key);
bbaaef
@@ -644,6 +686,8 @@ binding_run(struct ovsdb_idl_txn *ovnsb_
bbaaef
             const struct ovsrec_bridge *br_int,
bbaaef
             const struct sbrec_chassis *chassis_rec,
bbaaef
             const struct sset *active_tunnels,
bbaaef
+            const struct ovsrec_bridge_table *bridge_table,
bbaaef
+            const struct ovsrec_open_vswitch_table *ovs_table,
bbaaef
             struct hmap *local_datapaths, struct sset *local_lports,
bbaaef
             struct sset *local_lport_ids)
bbaaef
 {
bbaaef
@@ -652,6 +696,7 @@ binding_run(struct ovsdb_idl_txn *ovnsb_
bbaaef
     }
bbaaef
 
bbaaef
     const struct sbrec_port_binding *binding_rec;
bbaaef
+    struct shash bridge_mappings = SHASH_INITIALIZER(&bridge_mappings);
bbaaef
     struct shash lport_to_iface = SHASH_INITIALIZER(&lport_to_iface);
bbaaef
     struct sset egress_ifaces = SSET_INITIALIZER(&egress_ifaces);
bbaaef
     struct hmap qos_map;
bbaaef
@@ -677,14 +722,18 @@ binding_run(struct ovsdb_idl_txn *ovnsb_
bbaaef
 
bbaaef
     }
bbaaef
 
bbaaef
+    add_ovs_bridge_mappings(ovs_table, bridge_table, &bridge_mappings);
bbaaef
+
bbaaef
     /* Run through each binding record to see if it is a localnet port
bbaaef
      * on local datapaths discovered from above loop, and update the
bbaaef
      * corresponding local datapath accordingly. */
bbaaef
     SBREC_PORT_BINDING_TABLE_FOR_EACH (binding_rec, port_binding_table) {
bbaaef
         if (!strcmp(binding_rec->type, "localnet")) {
bbaaef
-            consider_localnet_port(binding_rec, local_datapaths);
bbaaef
+            consider_localnet_port(binding_rec, &bridge_mappings,
bbaaef
+                                   &egress_ifaces, local_datapaths);
bbaaef
         }
bbaaef
     }
bbaaef
+    shash_destroy(&bridge_mappings);
bbaaef
 
bbaaef
     if (!sset_is_empty(&egress_ifaces)
bbaaef
         && set_noop_qos(ovs_idl_txn, port_table, qos_table, &egress_ifaces)) {
bbaaef
--- a/ovn/controller/binding.h
bbaaef
+++ b/ovn/controller/binding.h
bbaaef
@@ -26,6 +26,8 @@ struct ovsdb_idl_txn;
bbaaef
 struct ovsrec_bridge;
bbaaef
 struct ovsrec_port_table;
bbaaef
 struct ovsrec_qos_table;
bbaaef
+struct ovsrec_bridge_table;
bbaaef
+struct ovsrec_open_vswitch_table;
bbaaef
 struct sbrec_chassis;
bbaaef
 struct sbrec_port_binding_table;
bbaaef
 struct sset;
bbaaef
@@ -42,6 +44,8 @@ void binding_run(struct ovsdb_idl_txn *o
bbaaef
                  const struct ovsrec_bridge *br_int,
bbaaef
                  const struct sbrec_chassis *,
bbaaef
                  const struct sset *active_tunnels,
bbaaef
+                 const struct ovsrec_bridge_table *bridge_table,
bbaaef
+                 const struct ovsrec_open_vswitch_table *ovs_table,
bbaaef
                  struct hmap *local_datapaths,
bbaaef
                  struct sset *local_lports, struct sset *local_lport_ids);
bbaaef
 bool binding_cleanup(struct ovsdb_idl_txn *ovnsb_idl_txn,
bbaaef
--- a/ovn/controller/ovn-controller.c
bbaaef
+++ b/ovn/controller/ovn-controller.c
bbaaef
@@ -1045,7 +1045,8 @@ en_runtime_data_run(struct engine_node *
bbaaef
                 sbrec_port_binding_by_name,
bbaaef
                 port_table, qos_table, pb_table,
bbaaef
                 br_int, chassis,
bbaaef
-                active_tunnels, local_datapaths,
bbaaef
+                active_tunnels, bridge_table,
bbaaef
+                ovs_table, local_datapaths,
bbaaef
                 local_lports, local_lport_ids);
bbaaef
 
bbaaef
     update_ct_zones(local_lports, local_datapaths, ct_zones,
bbaaef
--- a/ovn/controller/patch.c
bbaaef
+++ b/ovn/controller/patch.c
bbaaef
@@ -129,6 +129,48 @@ remove_port(const struct ovsrec_bridge_t
bbaaef
     }
bbaaef
 }
bbaaef
 
bbaaef
+void
bbaaef
+add_ovs_bridge_mappings(const struct ovsrec_open_vswitch_table *ovs_table,
bbaaef
+                        const struct ovsrec_bridge_table *bridge_table,
bbaaef
+                        struct shash *bridge_mappings)
bbaaef
+{
bbaaef
+    const struct ovsrec_open_vswitch *cfg;
bbaaef
+
bbaaef
+    cfg = ovsrec_open_vswitch_table_first(ovs_table);
bbaaef
+    if (cfg) {
bbaaef
+        const char *mappings_cfg;
bbaaef
+        char *cur, *next, *start;
bbaaef
+
bbaaef
+        mappings_cfg = smap_get(&cfg->external_ids, "ovn-bridge-mappings");
bbaaef
+        if (!mappings_cfg || !mappings_cfg[0]) {
bbaaef
+            return;
bbaaef
+        }
bbaaef
+
bbaaef
+        next = start = xstrdup(mappings_cfg);
bbaaef
+        while ((cur = strsep(&next, ",")) && *cur) {
bbaaef
+            const struct ovsrec_bridge *ovs_bridge;
bbaaef
+            char *network, *bridge = cur;
bbaaef
+
bbaaef
+            network = strsep(&bridge, ":");
bbaaef
+            if (!bridge || !*network || !*bridge) {
bbaaef
+                VLOG_ERR("Invalid ovn-bridge-mappings configuration: '%s'",
bbaaef
+                         mappings_cfg);
bbaaef
+                break;
bbaaef
+            }
bbaaef
+
bbaaef
+            ovs_bridge = get_bridge(bridge_table, bridge);
bbaaef
+            if (!ovs_bridge) {
bbaaef
+                VLOG_WARN("Bridge '%s' not found for network '%s'",
bbaaef
+                          bridge, network);
bbaaef
+                continue;
bbaaef
+            }
bbaaef
+
bbaaef
+            shash_add(bridge_mappings, network, ovs_bridge);
bbaaef
+        }
bbaaef
+        free(start);
bbaaef
+    }
bbaaef
+}
bbaaef
+
bbaaef
 /* Obtains external-ids:ovn-bridge-mappings from OVSDB and adds patch ports for
bbaaef
  * the local bridge mappings.  Removes any patch ports for bridge mappings that
bbaaef
  * already existed from 'existing_ports'. */
bbaaef
@@ -142,41 +184,9 @@ add_bridge_mappings(struct ovsdb_idl_txn
bbaaef
                     const struct sbrec_chassis *chassis)
bbaaef
 {
bbaaef
     /* Get ovn-bridge-mappings. */
bbaaef
-    const char *mappings_cfg = "";
bbaaef
-    const struct ovsrec_open_vswitch *cfg;
bbaaef
-    cfg = ovsrec_open_vswitch_table_first(ovs_table);
bbaaef
-    if (cfg) {
bbaaef
-        mappings_cfg = smap_get(&cfg->external_ids, "ovn-bridge-mappings");
bbaaef
-        if (!mappings_cfg || !mappings_cfg[0]) {
bbaaef
-            return;
bbaaef
-        }
bbaaef
-    }
bbaaef
-
bbaaef
-    /* Parse bridge mappings. */
bbaaef
     struct shash bridge_mappings = SHASH_INITIALIZER(&bridge_mappings);
bbaaef
-    char *cur, *next, *start;
bbaaef
-    next = start = xstrdup(mappings_cfg);
bbaaef
-    while ((cur = strsep(&next, ",")) && *cur) {
bbaaef
-        char *network, *bridge = cur;
bbaaef
-        const struct ovsrec_bridge *ovs_bridge;
bbaaef
-
bbaaef
-        network = strsep(&bridge, ":");
bbaaef
-        if (!bridge || !*network || !*bridge) {
bbaaef
-            VLOG_ERR("Invalid ovn-bridge-mappings configuration: '%s'",
bbaaef
-                    mappings_cfg);
bbaaef
-            break;
bbaaef
-        }
bbaaef
 
bbaaef
-        ovs_bridge = get_bridge(bridge_table, bridge);
bbaaef
-        if (!ovs_bridge) {
bbaaef
-            VLOG_WARN("Bridge '%s' not found for network '%s'",
bbaaef
-                    bridge, network);
bbaaef
-            continue;
bbaaef
-        }
bbaaef
-
bbaaef
-        shash_add(&bridge_mappings, network, ovs_bridge);
bbaaef
-    }
bbaaef
-    free(start);
bbaaef
+    add_ovs_bridge_mappings(ovs_table, bridge_table, &bridge_mappings);
bbaaef
 
bbaaef
     const struct sbrec_port_binding *binding;
bbaaef
     SBREC_PORT_BINDING_TABLE_FOR_EACH (binding, port_binding_table) {
bbaaef
--- a/ovn/controller/patch.h
bbaaef
+++ b/ovn/controller/patch.h
bbaaef
@@ -30,7 +30,11 @@ struct ovsrec_open_vswitch_table;
bbaaef
 struct ovsrec_port_table;
bbaaef
 struct sbrec_port_binding_table;
bbaaef
 struct sbrec_chassis;
bbaaef
+struct shash;
bbaaef
 
bbaaef
+void add_ovs_bridge_mappings(const struct ovsrec_open_vswitch_table *ovs_table,
bbaaef
+                             const struct ovsrec_bridge_table *bridge_table,
bbaaef
+                             struct shash *bridge_mappings);
bbaaef
 void patch_run(struct ovsdb_idl_txn *ovs_idl_txn,
bbaaef
                const struct ovsrec_bridge_table *,
bbaaef
                const struct ovsrec_open_vswitch_table *,