diff mbox series

[ovs-dev,v5,6/7] northd: introduce qos_physical_network in port_binding other_config column

Message ID f75c4344e918f111634089b0551d45dd9ed4bd8d.1682447676.git.lorenzo.bianconi@redhat.com
State Changes Requested
Delegated to: Numan Siddique
Headers show
Series Configure OVN QoS thorugh OvS db | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/github-robot-_ovn-kubernetes success github build: passed

Commit Message

Lorenzo Bianconi April 25, 2023, 6:36 p.m. UTC
This patch allows to apply QoS rules on the localnet port related to
logical switch ports running on the same datapath. Considering the
following netowrk configuration:

LSP{0,1} -- LogicalSwitch -- Localnet0

It is possible to apply the following QoS rules on Localnet0 on egress traffic
entering the cluster from LSP{0,1}:
- LSP0: min-rate r0, max_rate R0
- LSP1: min-rate r1, max_rate R1

https://bugzilla.redhat.com/show_bug.cgi?id=2129742
Acked-By: Ihar Hrachyshka <ihrachys@redhat.com>
Tested-by: Rodolfo Alonso <ralonsoh@redhat.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
 controller/binding.c     | 38 +++++++++---------
 northd/northd.c          | 34 +++++++++++++---
 northd/ovn-northd.8.xml  | 12 ++++++
 ovn-sb.xml               |  5 +++
 tests/ovn-northd.at      |  2 +
 tests/ovn-performance.at |  5 ---
 tests/system-ovn.at      | 86 +++++++++++++++++++++++++++++++++++++++-
 7 files changed, 150 insertions(+), 32 deletions(-)
diff mbox series

Patch

diff --git a/controller/binding.c b/controller/binding.c
index d4e1a5fda..b8b12f740 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -196,9 +196,9 @@  get_qos_egress_port_interface(struct shash *bridge_mappings,
                 continue;
             }
 
-            bool is_egress_iface = smap_get_bool(&iface->external_ids,
-                                                 "ovn-egress-iface", false);
-            if (is_egress_iface) {
+            if (smap_get_bool(&iface->external_ids,
+                              "ovn-egress-iface", false) ||
+                !strcmp(iface->type, "")) {
                 return iface;
             }
         }
@@ -457,22 +457,10 @@  add_localnet_egress_interface_mappings(
         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;
-            }
-            smap_replace(egress_ifaces, port_binding->logical_port,
-                         network);
-        }
+    const char *qos_physical_network = smap_get(
+            &port_binding->options, "qos_physical_network");
+    if (qos_physical_network && !strcmp(qos_physical_network, network)) {
+            smap_replace(egress_ifaces, port_binding->logical_port, network);
     }
 }
 
@@ -1497,6 +1485,14 @@  consider_vif_lport_(const struct sbrec_port_binding *pb,
                 tracked_datapath_lport_add(pb, TRACKED_RESOURCE_UPDATED,
                                            b_ctx_out->tracked_dp_bindings);
             }
+
+            const char *qos_physical_network =
+                smap_get(&pb->options, "qos_physical_network");
+            if (qos_physical_network) {
+                smap_replace(b_ctx_out->egress_ifaces, pb->logical_port,
+                             qos_physical_network);
+            }
+
             if (b_lport->lbinding->iface && qos_map && b_ctx_in->ovs_idl_txn) {
                 get_qos_params(pb, qos_map, b_ctx_out->egress_ifaces);
             }
@@ -2947,6 +2943,10 @@  binding_handle_port_binding_changes(struct binding_ctx_in *b_ctx_in,
         } else {
             shash_add(&deleted_other_pbs, pb->logical_port, pb);
         }
+
+        if (smap_get(&pb->options, "qos_physical_network")) {
+            smap_remove(b_ctx_out->egress_ifaces, pb->logical_port);
+        }
     }
 
     struct shash_node *node;
diff --git a/northd/northd.c b/northd/northd.c
index d59a54b32..af12d0030 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -3501,7 +3501,15 @@  ovn_port_update_sbrec(struct ovsdb_idl_txn *ovnsb_txn,
             }
 
             smap_clone(&options, &op->nbsp->options);
+
             if (queue_id) {
+                if (op->od->n_localnet_ports) {
+                    struct ovn_port *port = op->od->localnet_ports[0];
+                    const char *physical_network = smap_get(
+                            &port->nbsp->options, "network_name");
+                    smap_add(&options, "qos_physical_network",
+                             physical_network);
+                }
                 smap_add_format(&options,
                                 "qdisc_queue_id", "%d", queue_id);
             }
@@ -5788,15 +5796,29 @@  build_lswitch_port_sec_op(struct ovn_port *op, struct hmap *lflows,
                                           ds_cstr(match), ds_cstr(actions),
                                           op->key, &op->nbsp->header_);
 
+        if (!lsp_is_localnet(op->nbsp) && !op->od->n_localnet_ports) {
+            return;
+        }
+
+        ds_clear(actions);
+        ds_put_format(actions, "set_queue(%s); output;", queue_id);
+
+        ds_clear(match);
         if (lsp_is_localnet(op->nbsp)) {
-            ds_clear(match);
-            ds_clear(actions);
             ds_put_format(match, "outport == %s", op->json_key);
-            ds_put_format(actions, "set_queue(%s); output;", queue_id);
             ovn_lflow_add_with_lport_and_hint(lflows, op->od,
-                                            S_SWITCH_OUT_APPLY_PORT_SEC, 100,
-                                            ds_cstr(match), ds_cstr(actions),
-                                            op->key, &op->nbsp->header_);
+                                              S_SWITCH_OUT_APPLY_PORT_SEC, 100,
+                                              ds_cstr(match), ds_cstr(actions),
+                                              op->key, &op->nbsp->header_);
+        } else if (op->od->n_localnet_ports) {
+            ds_put_format(match, "outport == %s && inport == %s",
+                          op->od->localnet_ports[0]->json_key,
+                          op->json_key);
+            ovn_lflow_add_with_lport_and_hint(lflows, op->od,
+                    S_SWITCH_OUT_APPLY_PORT_SEC, 110,
+                    ds_cstr(match), ds_cstr(actions),
+                    op->od->localnet_ports[0]->key,
+                    &op->od->localnet_ports[0]->nbsp->header_);
         }
     }
 }
diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
index 70153dc9e..7da912da3 100644
--- a/northd/ovn-northd.8.xml
+++ b/northd/ovn-northd.8.xml
@@ -2223,6 +2223,18 @@  output;
     </p>
 
     <ul>
+      <li>
+        <p>
+        For each port configured with egress qos in the
+        <ref column="options:qdisc_queue_id" table="Logical_Switch_Port"
+        db="OVN_Northbound"/> column of <ref table="Logical_Switch_Port"
+        db="OVN_Northbound"/>, running a localnet port on the same logical
+        switch, a priority 110 flow is added which matches on the localnet
+        <code>outport</code> and on the port <code>inport</code> and
+        applies the action <code>set_queue(id); output;"</code>.
+        </p>
+      </li>
+
       <li>
         <p>
         For each localnet port configured with egress qos in the
diff --git a/ovn-sb.xml b/ovn-sb.xml
index a77f8f4ef..cd2a7c45f 100644
--- a/ovn-sb.xml
+++ b/ovn-sb.xml
@@ -3655,6 +3655,11 @@  tcp.flags = RST;
         interface, in bits.
       </column>
 
+      <column name="options" key="qos_physical_network">
+        If set, indicates the name of the egress network name where traffic
+        shaping will be applied.
+      </column>
+
       <column name="options" key="qdisc_queue_id"
               type='{"type": "integer", "minInteger": 1, "maxInteger": 61440}'>
         Indicates the queue number on the physical device. This is same as the
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 047b8b6ad..8005c09b8 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -8065,6 +8065,7 @@  sort | sed 's/table=../table=??/' ], [0], [dnl
   table=??(ls_out_check_port_sec), priority=0    , match=(1), action=(reg0[[15]] = check_out_port_sec(); next;)
   table=??(ls_out_check_port_sec), priority=100  , match=(eth.mcast), action=(reg0[[15]] = 0; next;)
   table=??(ls_out_apply_port_sec), priority=0    , match=(1), action=(output;)
+  table=??(ls_out_apply_port_sec), priority=110  , match=(outport == "localnetport" && inport == "sw0p2"), action=(set_queue(10); output;)
   table=??(ls_out_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), action=(drop;)
 ])
 
@@ -8095,6 +8096,7 @@  sort | sed 's/table=../table=??/' ], [0], [dnl
   table=??(ls_out_check_port_sec), priority=100  , match=(eth.mcast), action=(reg0[[15]] = 0; next;)
   table=??(ls_out_apply_port_sec), priority=0    , match=(1), action=(output;)
   table=??(ls_out_apply_port_sec), priority=100  , match=(outport == "localnetport"), action=(set_queue(10); output;)
+  table=??(ls_out_apply_port_sec), priority=110  , match=(outport == "localnetport" && inport == "sw0p2"), action=(set_queue(10); output;)
   table=??(ls_out_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), action=(drop;)
 ])
 
diff --git a/tests/ovn-performance.at b/tests/ovn-performance.at
index 8ac0a392c..ba329f0f6 100644
--- a/tests/ovn-performance.at
+++ b/tests/ovn-performance.at
@@ -559,11 +559,6 @@  OVN_CONTROLLER_EXPECT_NO_HIT(
     [ovn-nbctl --wait=hv set Logical_Switch_Port ln-public options:qos_burst=1000]
 )
 
-OVN_CONTROLLER_EXPECT_HIT(
-    [hv3], [lflow_run],
-    [as hv3 ovs-vsctl set interface vgw3 external-ids:ovn-egress-iface=true]
-)
-
 ovn-nbctl --wait=hv meter-add meter0 drop 100 pktps 10
 
 OVN_CONTROLLER_EXPECT_NO_HIT(
diff --git a/tests/system-ovn.at b/tests/system-ovn.at
index 6fec55a4a..54a7b0f42 100644
--- a/tests/system-ovn.at
+++ b/tests/system-ovn.at
@@ -6556,6 +6556,11 @@  ADD_VETH(sw01, sw01, br-int, "192.168.1.2/24", "f0:00:00:01:02:03")
 ovn-nbctl lsp-add sw0 sw01 \
     -- lsp-set-addresses sw01 "f0:00:00:01:02:03 192.168.1.2"
 
+ADD_NAMESPACES(sw02)
+ADD_VETH(sw02, sw02, br-int, "192.168.1.3/24", "f0:00:00:01:02:44")
+ovn-nbctl lsp-add sw0 sw02 \
+    -- lsp-set-addresses sw02 "f0:00:00:01:02:44 192.168.1.3"
+
 ovn-nbctl ls-add sw1
 
 ADD_NAMESPACES(sw11)
@@ -6563,6 +6568,11 @@  ADD_VETH(sw11, sw11, br-int, "192.168.4.2/24", "f0:00:00:01:04:03")
 ovn-nbctl lsp-add sw1 sw11 \
     -- lsp-set-addresses sw11 "f0:00:00:01:04:03 192.168.4.2"
 
+ADD_NAMESPACES(sw12)
+ADD_VETH(sw12, sw12, br-int, "192.168.4.3/24", "f0:00:00:03:04:03")
+ovn-nbctl lsp-add sw1 sw12 \
+    -- lsp-set-addresses sw11 "f0:00:00:03:04:03 192.168.4.3"
+
 ADD_NAMESPACES(public)
 ADD_VETH(public, public, br-public, "192.168.2.2/24", "f0:00:00:01:02:05")
 AT_CHECK([ovs-vsctl remove interface ovs-public external-ids iface-id=public])
@@ -6585,12 +6595,10 @@  ovn-nbctl lsp-add sw1 ext \
 AT_CHECK([ovn-nbctl set Logical_Switch_Port public options:qos_min_rate=200000])
 AT_CHECK([ovn-nbctl set Logical_Switch_Port public options:qos_max_rate=300000])
 AT_CHECK([ovn-nbctl set Logical_Switch_Port public options:qos_burst=3000000])
-AT_CHECK([ovs-vsctl set interface ovs-public external-ids:ovn-egress-iface=true])
 
 AT_CHECK([ovn-nbctl set Logical_Switch_Port ext options:qos_min_rate=400000])
 AT_CHECK([ovn-nbctl set Logical_Switch_Port ext options:qos_max_rate=600000])
 AT_CHECK([ovn-nbctl set Logical_Switch_Port ext options:qos_burst=6000000])
-AT_CHECK([ovs-vsctl set interface ovs-ext external-ids:ovn-egress-iface=true])
 
 OVS_WAIT_UNTIL([tc qdisc show | grep -q 'htb 1: dev ovs-public'])
 OVS_WAIT_UNTIL([tc class show dev ovs-public | \
@@ -6637,6 +6645,80 @@  AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options qos_burst=6000000]
 
 OVS_WAIT_UNTIL([test "$(tc qdisc show | grep 'htb 1: dev ovs-public')" = ""])
 
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw01 options:qos_min_rate=200000])
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw01 options:qos_max_rate=350000])
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw01 options:qos_burst=3000000])
+
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw11 options:qos_min_rate=400000])
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw11 options:qos_max_rate=700000])
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw11 options:qos_burst=6000000])
+
+OVS_WAIT_UNTIL([tc qdisc show | grep -q 'htb 1: dev ovs-public'])
+OVS_WAIT_UNTIL([tc class show dev ovs-public | \
+                grep -q 'class htb .* rate 200Kbit ceil 350Kbit burst 375000b cburst 374999b'])
+
+OVS_WAIT_UNTIL([tc qdisc show | grep -q 'htb 1: dev ovs-ext'])
+OVS_WAIT_UNTIL([tc class show dev ovs-ext | \
+                grep -q 'class htb .* prio 0 rate 400Kbit ceil 700Kbit burst 750000b cburst 749999b'])
+
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw02 options:qos_min_rate=300000])
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw02 options:qos_max_rate=500000])
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw02 options:qos_burst=3000000])
+
+OVS_WAIT_UNTIL([tc class show dev ovs-public | \
+                grep -q 'class htb .* prio 0 rate 300Kbit ceil 500Kbit burst 375000b cburst 375000b'])
+
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw12 options:qos_min_rate=400000])
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw12 options:qos_max_rate=500000])
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw12 options:qos_burst=3000000])
+
+OVS_WAIT_UNTIL([tc class show dev ovs-ext | \
+                grep -q 'class htb .* prio 0 rate 400Kbit ceil 500Kbit burst 375000b cburst 375000b'])
+
+AT_CHECK([ovn-nbctl remove Logical_Switch_Port sw02 options qos_min_rate=300000])
+AT_CHECK([ovn-nbctl remove Logical_Switch_Port sw02 options qos_max_rate=500000])
+AT_CHECK([ovn-nbctl remove Logical_Switch_Port sw02 options qos_burst=3000000])
+
+OVS_WAIT_UNTIL([tc qdisc show | grep -q 'htb 1: dev ovs-public'])
+OVS_WAIT_UNTIL([tc class show dev ovs-public | \
+                grep -q 'class htb .* rate 200Kbit ceil 350Kbit burst 375000b cburst 374999b'])
+OVS_WAIT_UNTIL([test "$(tc class show dev ovs-public | \
+                grep 'class htb .* prio 0 rate 300Kbit ceil 500Kbit burst 375000b cburst 375000b')" = ""])
+
+AT_CHECK([ovn-nbctl remove Logical_Switch_Port sw01 options qos_min_rate=200000])
+AT_CHECK([ovn-nbctl remove Logical_Switch_Port sw01 options qos_max_rate=350000])
+AT_CHECK([ovn-nbctl remove Logical_Switch_Port sw01 options qos_burst=3000000])
+OVS_WAIT_UNTIL([test "$(tc qdisc show | grep 'htb 1: dev ovs-public')" = ""])
+
+OVS_WAIT_UNTIL([tc qdisc show | grep -q 'htb 1: dev ovs-ext'])
+OVS_WAIT_UNTIL([tc class show dev ovs-ext | \
+                grep -q 'class htb .* prio 0 rate 400Kbit ceil 700Kbit burst 750000b cburst 749999b'])
+OVS_WAIT_UNTIL([tc class show dev ovs-ext | \
+                grep -q 'class htb .* prio 0 rate 400Kbit ceil 500Kbit burst 375000b cburst 375000b'])
+
+AT_CHECK([ovn-nbctl remove Logical_Switch_Port sw11 options qos_min_rate=400000])
+AT_CHECK([ovn-nbctl remove Logical_Switch_Port sw11 options qos_max_rate=700000])
+AT_CHECK([ovn-nbctl remove Logical_Switch_Port sw11 options qos_burst=6000000])
+
+OVS_WAIT_UNTIL([tc qdisc show | grep -q 'htb 1: dev ovs-ext'])
+OVS_WAIT_UNTIL([test "$(tc class show dev ovs-ext | \
+                grep 'class htb .* prio 0 rate 400Kbit ceil 700Kbit burst 750000b cburst 749999b')" = ""])
+OVS_WAIT_UNTIL([tc class show dev ovs-ext | \
+                grep -q 'class htb .* prio 0 rate 400Kbit ceil 500Kbit burst 375000b cburst 375000b'])
+
+AT_CHECK([ovn-nbctl remove Logical_Switch_Port sw12 options qos_min_rate=400000])
+AT_CHECK([ovn-nbctl remove Logical_Switch_Port sw12 options qos_max_rate=500000])
+AT_CHECK([ovn-nbctl remove Logical_Switch_Port sw12 options qos_burst=3000000])
+
+OVS_WAIT_UNTIL([test "$(tc qdisc show | grep 'htb 1: dev ovs-ext')" = ""])
+
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw02 options:qos_min_rate=5000000000])
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw02 options:qos_max_rate=6000000000])
+AT_CHECK([ovn-nbctl set Logical_Switch_Port sw02 options:qos_burst=1000000])
+
+OVS_WAIT_UNTIL([tc class show dev ovs-public | \
+                grep -q 'class htb .* prio 0 rate 5Gbit ceil 6Gbit burst 125000b cburst 124500b'])
+
 kill $(pidof ovn-controller)
 
 as ovn-sb