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