Message ID | 268f4ca004c2a79add59ffe80f02a53060e3dc10.1600952243.git.lorenzo.bianconi@redhat.com |
---|---|
State | Accepted |
Headers | show |
Series | [ovs-dev,v4] binding: fix localnet QoS configuration after I-P | expand |
On Thu, Sep 24, 2020 at 6:37 PM Lorenzo Bianconi < lorenzo.bianconi@redhat.com> wrote: > After the I-P has been introduced in commit 354bdba51a ("ovn-controller: > I-P for SB port binding and OVS interface in runtime_data"), the QoS on > localnet ports is not properly configured if the ovs interface is marked > with "ovn-egress-iface" flag after the related record in the > logical_switch_port table is set. The issue can be triggered with the > following reproducer: > > $ovn-nbctl set Logical_Switch_Port ln-public options:qos_burst=1000 > $ovs-vsctl set interface eth0 external-ids:ovn-egress-iface=true > > Fix the issue triggering a recomputation after qos is configured for ovs > interface > > Fixes: 354bdba51abf ("ovn-controller: I-P for SB port binding and OVS > interface in runtime_data") > > Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> > Thanks Lorenzo. I applied this patch to master and backported to branch-20.09 and branch-20.06. Numan > --- > Changes since v3: > - rely on OVS_WAIT_UNTIL in system-ovn.at > - move external_ids check before iface_id one > > Changes since v2: > - drop patch 1/3 > - patch 2/3 has been applied > - simplify full recomputation check > > Changes since v1: > - move qos_map fix in a separated patch > - add ovn-egress-iface info to binding I-P engine > relying on shash for local_iface_ids > --- > controller/binding.c | 6 ++++ > tests/ovn-performance.at | 13 +++++++++ > tests/system-ovn.at | 60 ++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 79 insertions(+) > > diff --git a/controller/binding.c b/controller/binding.c > index 36fd35009..eb92679ad 100644 > --- a/controller/binding.c > +++ b/controller/binding.c > @@ -1856,6 +1856,12 @@ binding_handle_ovs_interface_changes(struct > binding_ctx_in *b_ctx_in, > break; > } > > + if (smap_get(&iface_rec->external_ids, "ovn-egress-iface") || > + sset_contains(b_ctx_out->egress_ifaces, iface_rec->name)) { > + handled = false; > + break; > + } > + > const char *iface_id = smap_get(&iface_rec->external_ids, > "iface-id"); > const char *old_iface_id = smap_get(b_ctx_out->local_iface_ids, > iface_rec->name); > diff --git a/tests/ovn-performance.at b/tests/ovn-performance.at > index 3010860d5..6cc5b2174 100644 > --- a/tests/ovn-performance.at > +++ b/tests/ovn-performance.at > @@ -247,6 +247,8 @@ for i in 1 2 3; do > ovs-vsctl set open . external_ids:ovn-bridge-mappings="public:br-ex" > j=$((i + 2)) > ovn_attach n1 br-phys 192.168.0.$j > + ip link add vgw$i type dummy > + ovs-vsctl add-port br-ex vgw$i > done > > # Wait for the tunnel ports to be created and up. > @@ -477,6 +479,17 @@ OVN_CONTROLLER_EXPECT_HIT( > [ovn-nbctl --wait=hv lrp-set-gateway-chassis lr1-public gw3 10 && > ovn-nbctl --wait=hv sync] > ) > > +# create QoS rule > +OVN_CONTROLLER_EXPECT_NO_HIT( > + [hv1 hv2 gw1 gw2 gw3], [lflow_run], > + [ovn-nbctl --wait=hv set Logical_Switch_Port ln-public > options:qos_burst=1000] > +) > + > +OVN_CONTROLLER_EXPECT_HIT( > + [gw1], [lflow_run], > + [as gw1 ovs-vsctl set interface vgw1 > external-ids:ovn-egress-iface=true] > +) > + > # Make gw2 master. There is remote possibility that full recompute > # triggers for gw2 after it becomes master. Most of the time > # there will be no recompute. > diff --git a/tests/system-ovn.at b/tests/system-ovn.at > index 4f72754c6..420610f89 100644 > --- a/tests/system-ovn.at > +++ b/tests/system-ovn.at > @@ -5397,3 +5397,63 @@ as > OVS_TRAFFIC_VSWITCHD_STOP(["/.*error receiving.*/d > /.*terminating with signal 15.*/d"]) > AT_CLEANUP > + > +AT_SETUP([ovn -- egress qos]) > +AT_KEYWORDS([ovn-egress-qos]) > + > +ovn_start > +OVS_TRAFFIC_VSWITCHD_START() > + > +ADD_BR([br-int]) > +ADD_BR([br-ext]) > + > +ovs-ofctl add-flow br-ext action=normal > +# Set external-ids in br-int needed for ovn-controller > +ovs-vsctl \ > + -- set Open_vSwitch . external-ids:system-id=hv1 \ > + -- set Open_vSwitch . > external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \ > + -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \ > + -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \ > + -- set bridge br-int fail-mode=secure > other-config:disable-in-band=true > + > +# Start ovn-controller > +start_daemon ovn-controller > + > +ovn-nbctl ls-add sw0 > + > +ADD_NAMESPACES(sw01) > +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(public) > +ADD_VETH(public, public, br-ext, "192.168.2.2/24", "f0:00:00:01:02:05") > + > +AT_CHECK([ovs-vsctl set Open_vSwitch . > external-ids:ovn-bridge-mappings=phynet:br-ext]) > +ovn-nbctl lsp-add sw0 public \ > + -- lsp-set-addresses public unknown \ > + -- lsp-set-type public localnet \ > + -- lsp-set-options public network_name=phynet > + > +AT_CHECK([ovn-nbctl set Logical_Switch_Port public > options:qos_burst=1000]) > +AT_CHECK([ovs-vsctl set interface ovs-public > external-ids:ovn-egress-iface=true]) > +OVS_WAIT_UNTIL([tc qdisc show | grep -q 'htb 1: dev ovs-public']) > + > +AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options > qos_burst=1000]) > +OVS_WAIT_UNTIL([test "$(tc qdisc show | grep 'htb 1: dev ovs-public')" == > ""]) > + > +kill $(pidof ovn-controller) > + > +as ovn-sb > +OVS_APP_EXIT_AND_WAIT([ovsdb-server]) > + > +as ovn-nb > +OVS_APP_EXIT_AND_WAIT([ovsdb-server]) > + > +as northd > +OVS_APP_EXIT_AND_WAIT([ovn-northd]) > + > +as > +OVS_TRAFFIC_VSWITCHD_STOP(["/.*error receiving.*/d > +/.*terminating with signal 15.*/d"]) > +AT_CLEANUP > -- > 2.26.2 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > >
diff --git a/controller/binding.c b/controller/binding.c index 36fd35009..eb92679ad 100644 --- a/controller/binding.c +++ b/controller/binding.c @@ -1856,6 +1856,12 @@ binding_handle_ovs_interface_changes(struct binding_ctx_in *b_ctx_in, break; } + if (smap_get(&iface_rec->external_ids, "ovn-egress-iface") || + sset_contains(b_ctx_out->egress_ifaces, iface_rec->name)) { + handled = false; + break; + } + const char *iface_id = smap_get(&iface_rec->external_ids, "iface-id"); const char *old_iface_id = smap_get(b_ctx_out->local_iface_ids, iface_rec->name); diff --git a/tests/ovn-performance.at b/tests/ovn-performance.at index 3010860d5..6cc5b2174 100644 --- a/tests/ovn-performance.at +++ b/tests/ovn-performance.at @@ -247,6 +247,8 @@ for i in 1 2 3; do ovs-vsctl set open . external_ids:ovn-bridge-mappings="public:br-ex" j=$((i + 2)) ovn_attach n1 br-phys 192.168.0.$j + ip link add vgw$i type dummy + ovs-vsctl add-port br-ex vgw$i done # Wait for the tunnel ports to be created and up. @@ -477,6 +479,17 @@ OVN_CONTROLLER_EXPECT_HIT( [ovn-nbctl --wait=hv lrp-set-gateway-chassis lr1-public gw3 10 && ovn-nbctl --wait=hv sync] ) +# create QoS rule +OVN_CONTROLLER_EXPECT_NO_HIT( + [hv1 hv2 gw1 gw2 gw3], [lflow_run], + [ovn-nbctl --wait=hv set Logical_Switch_Port ln-public options:qos_burst=1000] +) + +OVN_CONTROLLER_EXPECT_HIT( + [gw1], [lflow_run], + [as gw1 ovs-vsctl set interface vgw1 external-ids:ovn-egress-iface=true] +) + # Make gw2 master. There is remote possibility that full recompute # triggers for gw2 after it becomes master. Most of the time # there will be no recompute. diff --git a/tests/system-ovn.at b/tests/system-ovn.at index 4f72754c6..420610f89 100644 --- a/tests/system-ovn.at +++ b/tests/system-ovn.at @@ -5397,3 +5397,63 @@ as OVS_TRAFFIC_VSWITCHD_STOP(["/.*error receiving.*/d /.*terminating with signal 15.*/d"]) AT_CLEANUP + +AT_SETUP([ovn -- egress qos]) +AT_KEYWORDS([ovn-egress-qos]) + +ovn_start +OVS_TRAFFIC_VSWITCHD_START() + +ADD_BR([br-int]) +ADD_BR([br-ext]) + +ovs-ofctl add-flow br-ext action=normal +# Set external-ids in br-int needed for ovn-controller +ovs-vsctl \ + -- set Open_vSwitch . external-ids:system-id=hv1 \ + -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \ + -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \ + -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \ + -- set bridge br-int fail-mode=secure other-config:disable-in-band=true + +# Start ovn-controller +start_daemon ovn-controller + +ovn-nbctl ls-add sw0 + +ADD_NAMESPACES(sw01) +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(public) +ADD_VETH(public, public, br-ext, "192.168.2.2/24", "f0:00:00:01:02:05") + +AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=phynet:br-ext]) +ovn-nbctl lsp-add sw0 public \ + -- lsp-set-addresses public unknown \ + -- lsp-set-type public localnet \ + -- lsp-set-options public network_name=phynet + +AT_CHECK([ovn-nbctl set Logical_Switch_Port public options:qos_burst=1000]) +AT_CHECK([ovs-vsctl set interface ovs-public external-ids:ovn-egress-iface=true]) +OVS_WAIT_UNTIL([tc qdisc show | grep -q 'htb 1: dev ovs-public']) + +AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options qos_burst=1000]) +OVS_WAIT_UNTIL([test "$(tc qdisc show | grep 'htb 1: dev ovs-public')" == ""]) + +kill $(pidof ovn-controller) + +as ovn-sb +OVS_APP_EXIT_AND_WAIT([ovsdb-server]) + +as ovn-nb +OVS_APP_EXIT_AND_WAIT([ovsdb-server]) + +as northd +OVS_APP_EXIT_AND_WAIT([ovn-northd]) + +as +OVS_TRAFFIC_VSWITCHD_STOP(["/.*error receiving.*/d +/.*terminating with signal 15.*/d"]) +AT_CLEANUP
After the I-P has been introduced in commit 354bdba51a ("ovn-controller: I-P for SB port binding and OVS interface in runtime_data"), the QoS on localnet ports is not properly configured if the ovs interface is marked with "ovn-egress-iface" flag after the related record in the logical_switch_port table is set. The issue can be triggered with the following reproducer: $ovn-nbctl set Logical_Switch_Port ln-public options:qos_burst=1000 $ovs-vsctl set interface eth0 external-ids:ovn-egress-iface=true Fix the issue triggering a recomputation after qos is configured for ovs interface Fixes: 354bdba51abf ("ovn-controller: I-P for SB port binding and OVS interface in runtime_data") Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> --- Changes since v3: - rely on OVS_WAIT_UNTIL in system-ovn.at - move external_ids check before iface_id one Changes since v2: - drop patch 1/3 - patch 2/3 has been applied - simplify full recomputation check Changes since v1: - move qos_map fix in a separated patch - add ovn-egress-iface info to binding I-P engine relying on shash for local_iface_ids --- controller/binding.c | 6 ++++ tests/ovn-performance.at | 13 +++++++++ tests/system-ovn.at | 60 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+)